Merge git://git.denx.de/u-boot-dm
authorTom Rini <trini@konsulko.com>
Tue, 17 May 2016 17:58:27 +0000 (13:58 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 17 May 2016 17:58:27 +0000 (13:58 -0400)
68 files changed:
README
arch/arm/cpu/armv7/mx7/clock_slice.c
arch/arm/imx-common/cpu.c
arch/arm/include/asm/arch-mx6/mx6sl_pins.h
arch/arm/include/asm/arch-mx7/mx7d_pins.h
arch/m68k/include/asm/fsl_i2c.h
arch/powerpc/include/asm/fsl_i2c.h
arch/powerpc/include/asm/immap_85xx.h
arch/powerpc/include/asm/immap_86xx.h
board/keymile/km83xx/km83xx_i2c.c
common/spl/spl.c
common/spl/spl_ext.c
common/spl/spl_fat.c
common/spl/spl_mmc.c
common/spl/spl_nand.c
common/spl/spl_net.c
common/spl/spl_nor.c
common/spl/spl_onenand.c
common/spl/spl_ymodem.c
configs/axs101_defconfig
configs/axs103_defconfig
configs/socfpga_arria5_defconfig
configs/socfpga_cyclone5_defconfig
configs/socfpga_de0_nano_soc_defconfig
configs/socfpga_mcvevk_defconfig
configs/socfpga_sockit_defconfig
configs/socfpga_socrates_defconfig
configs/socfpga_sr1500_defconfig
configs/spear300_defconfig
configs/spear300_nand_defconfig
configs/spear300_usbtty_defconfig
configs/spear300_usbtty_nand_defconfig
configs/spear310_defconfig
configs/spear310_nand_defconfig
configs/spear310_pnor_defconfig
configs/spear310_usbtty_defconfig
configs/spear310_usbtty_nand_defconfig
configs/spear310_usbtty_pnor_defconfig
configs/spear320_defconfig
configs/spear320_nand_defconfig
configs/spear320_pnor_defconfig
configs/spear320_usbtty_defconfig
configs/spear320_usbtty_nand_defconfig
configs/spear320_usbtty_pnor_defconfig
configs/spear600_defconfig
configs/spear600_nand_defconfig
configs/spear600_usbtty_defconfig
configs/spear600_usbtty_nand_defconfig
configs/x600_defconfig
drivers/i2c/Kconfig
drivers/i2c/designware_i2c.c
drivers/i2c/fsl_i2c.c
drivers/i2c/i2c-cdns.c
drivers/i2c/muxes/Kconfig
drivers/i2c/muxes/Makefile
drivers/i2c/muxes/pca954x.c [new file with mode: 0644]
drivers/i2c/mvtwsi.c
drivers/mtd/spi/spi_spl_load.c
drivers/video/ipu_common.c
include/configs/axs101.h
include/configs/imx6_spl.h
include/configs/novena.h
include/configs/socfpga_common.h
include/configs/spear-common.h
include/configs/tqma6.h
include/configs/x600.h
include/spl.h
tools/imximage.c

diff --git a/README b/README
index 33dc788474401ee4f5bf8893242d4b8aad329939..94e9943b0460f5a41fab1994e745864e4ff92836 100644 (file)
--- a/README
+++ b/README
@@ -3487,6 +3487,10 @@ FIT uImage format:
                consider that a completely unreadable NAND block is bad,
                and thus should be skipped silently.
 
+               CONFIG_SPL_ABORT_ON_RAW_IMAGE
+               When defined, SPL will proceed to another boot method
+               if the image it has loaded does not have a signature.
+
                CONFIG_SPL_RELOC_STACK
                Adress of the start of the stack SPL will use after
                relocation.  If unspecified, this is equal to
index ad5d504d28ef0ccd19af89a37d6ab42092d6db83..1665df92adc82df91237401a4e4948f4f3434504 100644 (file)
@@ -55,7 +55,7 @@ static struct clk_root_map root_array[] = {
          PLL_ENET_MAIN_250M_CLK, PLL_AUDIO_MAIN_CLK}
        },
        {AHB_CLK_ROOT, CCM_AHB_CHANNEL,
-        {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_DRAM_MAIN_533M_CLK,
+        {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK,
          PLL_SYS_PFD0_392M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK,
          PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK}
        },
index 5fb3ed840f8dd933637ef5cb9ca17b7341e2e949..42231872611caddf50b165fd55e066e67009141a 100644 (file)
@@ -138,7 +138,7 @@ const char *get_imx_type(u32 imxtype)
 {
        switch (imxtype) {
        case MXC_CPU_MX7S:
-               return "7SOLO"; /* Single-core version of the mx7 */
+               return "7S";    /* Single-core version of the mx7 */
        case MXC_CPU_MX7D:
                return "7D";    /* Dual-core version of the mx7 */
        case MXC_CPU_MX6QP:
index 6ba1034b2e3cabbf39aa957e86f109016171615d..919d83dd90cf6ac53d204d7e40a063d37a60dd51 100644 (file)
@@ -22,6 +22,7 @@ enum {
        MX6_PAD_SD1_DAT3__USDHC1_DAT3                           = IOMUX_PAD(0x0548, 0x0240, 0, 0x0000, 0, 0),
        MX6_PAD_SD1_DAT4__USDHC1_DAT4                           = IOMUX_PAD(0x054C, 0x0244, 0, 0x0000, 0, 0),
        MX6_PAD_SD1_DAT5__USDHC1_DAT5                           = IOMUX_PAD(0x0550, 0x0248, 0, 0x0000, 0, 0),
+       MX6_PAD_SD1_DAT5__GPIO_5_9                              = IOMUX_PAD(0x0550, 0x0248, 5, 0x0000, 0, 0),
        MX6_PAD_SD1_DAT6__USDHC1_DAT6                           = IOMUX_PAD(0x0554, 0x024C, 0, 0x0000, 0, 0),
        MX6_PAD_SD1_DAT7__USDHC1_DAT7                           = IOMUX_PAD(0x0558, 0x0250, 0, 0x0000, 0, 0),
        MX6_PAD_KEY_ROW7__GPIO_4_7                                      = IOMUX_PAD(0x04B0, 0x01A8, 5, 0x0000, 0, 0),
index d8b409726299755d368810fa2c52ae0f8920a221..0ab1246de85219eda30db3a40bbbf2e6fb9e1eed 100644 (file)
@@ -635,7 +635,7 @@ enum {
        MX7D_PAD_LCD_DATA23__GPIO3_IO28                          = IOMUX_PAD(0x0394, 0x0124, 5, 0x0000, 0, 0),
        MX7D_PAD_LCD_DATA23__I2C4_SDA                            = IOMUX_PAD(0x0394, 0x0124, IOMUX_CONFIG_SION | 6, 0x05F0, 1, 0),
 
-       MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX                     = IOMUX_PAD(0x0398, 0x0128, 0, 0x0000, 0, 0),
+       MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX                     = IOMUX_PAD(0x0398, 0x0128, 0, 0x06F4, 0, 0),
 
        MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX                     = IOMUX_PAD(0x0398, 0x0128, 0, 0x0000, 0, 0),
        MX7D_PAD_UART1_RX_DATA__I2C1_SCL                         = IOMUX_PAD(0x0398, 0x0128, IOMUX_CONFIG_SION | 1, 0x0000, 0, 0),
@@ -655,7 +655,7 @@ enum {
        MX7D_PAD_UART1_TX_DATA__GPIO4_IO1                        = IOMUX_PAD(0x039C, 0x012C, 5, 0x0000, 0, 0),
        MX7D_PAD_UART1_TX_DATA__ENET1_MDC                        = IOMUX_PAD(0x039C, 0x012C, 6, 0x0000, 0, 0),
 
-       MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX                     = IOMUX_PAD(0x03A0, 0x0130, 0, 0x0000, 0, 0),
+       MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX                     = IOMUX_PAD(0x03A0, 0x0130, 0, 0x06FC, 2, 0),
 
        MX7D_PAD_UART2_RX_DATA__UART2_DTE_TX                     = IOMUX_PAD(0x03A0, 0x0130, 0, 0x0000, 0, 0),
        MX7D_PAD_UART2_RX_DATA__I2C2_SCL                         = IOMUX_PAD(0x03A0, 0x0130, IOMUX_CONFIG_SION | 1, 0x0000, 0, 0),
@@ -667,7 +667,7 @@ enum {
 
        MX7D_PAD_UART2_TX_DATA__UART2_DCE_TX                     = IOMUX_PAD(0x03A4, 0x0134, 0, 0x0000, 0, 0),
 
-       MX7D_PAD_UART2_TX_DATA__UART2_DTE_RX                     = IOMUX_PAD(0x03A4, 0x0134, 0, 0x0000, 0, 0),
+       MX7D_PAD_UART2_TX_DATA__UART2_DTE_RX                     = IOMUX_PAD(0x03A4, 0x0134, 0, 0x06FC, 3, 0),
        MX7D_PAD_UART2_TX_DATA__I2C2_SDA                         = IOMUX_PAD(0x03A4, 0x0134, IOMUX_CONFIG_SION | 1, 0x05E0, 0, 0),
        MX7D_PAD_UART2_TX_DATA__SAI3_RX_DATA0                    = IOMUX_PAD(0x03A4, 0x0134, 2, 0x06C8, 0, 0),
        MX7D_PAD_UART2_TX_DATA__ECSPI1_RDY                       = IOMUX_PAD(0x03A4, 0x0134, 3, 0x0000, 0, 0),
@@ -695,7 +695,7 @@ enum {
        MX7D_PAD_UART3_TX_DATA__GPIO4_IO5                        = IOMUX_PAD(0x03AC, 0x013C, 5, 0x0000, 0, 0),
        MX7D_PAD_UART3_TX_DATA__SD2_LCTL                         = IOMUX_PAD(0x03AC, 0x013C, 6, 0x0000, 0, 0),
 
-       MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS                      = IOMUX_PAD(0x03B0, 0x0140, 0, 0x0000, 0, 0),
+       MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS                      = IOMUX_PAD(0x03B0, 0x0140, 0, 0x0700, 2, 0),
 
        MX7D_PAD_UART3_RTS_B__UART3_DTE_CTS                      = IOMUX_PAD(0x03B0, 0x0140, 0, 0x0000, 0, 0),
        MX7D_PAD_UART3_RTS_B__USB_OTG2_OC                        = IOMUX_PAD(0x03B0, 0x0140, 1, 0x0000, 0, 0),
index 1b1c25ef8990da1fbcc797f4be04d512ec30cbf5..c7d2aa33e8597904208d6132390b1d716e06560f 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <asm/types.h>
 
-typedef struct fsl_i2c {
+typedef struct fsl_i2c_base {
 
        u8 adr;         /* I2C slave address */
        u8 res0[3];
index cbbc8342735946436abfaef674887c98d9d95d7b..d2586f94f51fc1e68f2ce449b421cb9637980174 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <asm/types.h>
 
-typedef struct fsl_i2c {
+typedef struct fsl_i2c_base {
 
        u8 adr;         /* I2C slave address */
        u8 res0[3];
@@ -68,4 +68,14 @@ typedef struct fsl_i2c {
        u8 res6[0xE8];
 } fsl_i2c_t;
 
+#ifdef CONFIG_DM_I2C
+struct fsl_i2c_dev {
+       struct fsl_i2c_base __iomem *base;      /* register base */
+       u32 i2c_clk;
+       u32 index;
+       u8 slaveadd;
+       uint speed;
+};
+#endif
+
 #endif /* _ASM_I2C_H_ */
index 53ca6d94d644b93bc553bc6f02c811db232a15a0..07d2adf71f1d8777107ee57bdaca84e39246a46e 100644 (file)
@@ -120,8 +120,8 @@ typedef struct ccsr_local_ecm {
 
 /* I2C Registers */
 typedef struct ccsr_i2c {
-       struct fsl_i2c  i2c[1];
-       u8      res[4096 - 1 * sizeof(struct fsl_i2c)];
+       struct fsl_i2c_base     i2c[1];
+       u8      res[4096 - 1 * sizeof(struct fsl_i2c_base)];
 } ccsr_i2c_t;
 
 #if defined(CONFIG_MPC8540) \
index 177918b7f967e7302bcbe0efffef71611f9e1871..b078569c45ebe824be7f16802242e40e1aac82e4 100644 (file)
@@ -92,8 +92,8 @@ typedef struct ccsr_local_mcm {
 
 /* Daul I2C Registers(0x3000-0x4000) */
 typedef struct ccsr_i2c {
-       struct fsl_i2c  i2c[2];
-       u8      res[4096 - 2 * sizeof(struct fsl_i2c)];
+       struct fsl_i2c_base     i2c[2];
+       u8      res[4096 - 2 * sizeof(struct fsl_i2c_base)];
 } ccsr_i2c_t;
 
 /* DUART Registers(0x4000-0x5000) */
index c961937530ac6945bb33e1021004b5f7a40cc5f6..f0b528d1c8ffdd2d7b96627ac72cb93e706dbd84 100644 (file)
 
 static void i2c_write_start_seq(void)
 {
-       struct fsl_i2c *dev;
-       dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
+       struct fsl_i2c_base *base;
+       base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +
+                       CONFIG_SYS_I2C_OFFSET);
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+       out_8(&base->cr, (I2C_CR_MEN | I2C_CR_MSTA));
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN));
+       out_8(&base->cr, (I2C_CR_MEN));
 }
 
 int i2c_make_abort(void)
 {
-       struct fsl_i2c *dev;
-       dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
+       struct fsl_i2c_base *base;
+       base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +
+                       CONFIG_SYS_I2C_OFFSET);
        uchar   last;
        int     nbr_read = 0;
        int     i = 0;
        int         ret = 0;
 
        /* wait after each operation to finsh with a delay */
-       out_8(&dev->cr, (I2C_CR_MSTA));
+       out_8(&base->cr, (I2C_CR_MSTA));
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+       out_8(&base->cr, (I2C_CR_MEN | I2C_CR_MSTA));
        udelay(DELAY_ABORT_SEQ);
-       in_8(&dev->dr);
+       in_8(&base->dr);
        udelay(DELAY_ABORT_SEQ);
-       last = in_8(&dev->dr);
+       last = in_8(&base->dr);
        nbr_read++;
 
        /*
@@ -47,7 +49,7 @@ int i2c_make_abort(void)
        while (((last & 0x01) != 0x01) &&
                (nbr_read < CONFIG_SYS_IVM_EEPROM_MAX_LEN)) {
                udelay(DELAY_ABORT_SEQ);
-               last = in_8(&dev->dr);
+               last = in_8(&base->dr);
                nbr_read++;
        }
        if ((last & 0x01) != 0x01)
@@ -56,10 +58,10 @@ int i2c_make_abort(void)
                printf("[INFO] i2c abort after %d bytes (0x%02x)\n",
                        nbr_read, last);
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN));
+       out_8(&base->cr, (I2C_CR_MEN));
        udelay(DELAY_ABORT_SEQ);
        /* clear status reg */
-       out_8(&dev->sr, 0);
+       out_8(&base->sr, 0);
 
        for (i = 0; i < 5; i++)
                i2c_write_start_seq();
index 82e7f58e80f028f7517ec52bd0d73566dae82d28..93f9bd13fcd9b4995c2d69fa3293180f3a48bedc 100644 (file)
@@ -73,7 +73,7 @@ void spl_set_header_raw_uboot(void)
        spl_image.name = "U-Boot";
 }
 
-void spl_parse_image_header(const struct image_header *header)
+int spl_parse_image_header(const struct image_header *header)
 {
        u32 header_size = sizeof(struct image_header);
 
@@ -111,6 +111,9 @@ void spl_parse_image_header(const struct image_header *header)
                 * is bad, and thus should be skipped silently.
                 */
                panic("** no mkimage signature but raw image not supported");
+#elif defined(CONFIG_SPL_ABORT_ON_RAW_IMAGE)
+               /* Signature not found, proceed to other boot methods. */
+               return -EINVAL;
 #else
                /* Signature not found - assume u-boot.bin */
                debug("mkimage signature not found - ih_magic = %x\n",
@@ -118,6 +121,7 @@ void spl_parse_image_header(const struct image_header *header)
                spl_set_header_raw_uboot();
 #endif
        }
+       return 0;
 }
 
 __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
index b77dbf4d0ca11b8235629e8d6d4b85dfaaaf1a1a..ade5496600930c4f2a84ac76d1a9467576dcb3fa 100644 (file)
@@ -48,7 +48,11 @@ int spl_load_image_ext(struct blk_desc *block_dev,
                goto end;
        }
 
-       spl_parse_image_header(header);
+       err = spl_parse_image_header(header);
+       if (err < 0) {
+               puts("spl: ext4fs_read failed\n");
+               goto end;
+       }
 
        err = ext4fs_read((char *)spl_image.load_addr, filelen, &actlen);
 
index d761b264c139aba5c0229af4d02139e6626660eb..338ea2f092b8dc9b250626efc91d44e68716e199 100644 (file)
@@ -57,7 +57,9 @@ int spl_load_image_fat(struct blk_desc *block_dev,
        if (err <= 0)
                goto end;
 
-       spl_parse_image_header(header);
+       err = spl_parse_image_header(header);
+       if (err <= 0)
+               goto end;
 
        err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
 
index cf527da9f22b455e10879f3c418498d1156a817f..5676acdde3f282da8062d0c679c02116d590b969 100644 (file)
@@ -23,8 +23,12 @@ static int mmc_load_legacy(struct mmc *mmc, ulong sector,
 {
        u32 image_size_sectors;
        unsigned long count;
+       int ret;
+
+       ret = spl_parse_image_header(header);
+       if (ret)
+               return ret;
 
-       spl_parse_image_header(header);
        /* convert size to sectors - round up */
        image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
                             mmc->read_bl_len;
index 79388ff326a828f89eea814edf66e7b03d7ac5a2..bbd95469870f29ee07edfbf860349d598991ed3f 100644 (file)
@@ -32,7 +32,10 @@ static int spl_nand_load_element(int offset, struct image_header *header)
        if (err)
                return err;
 
-       spl_parse_image_header(header);
+       err = spl_parse_image_header(header);
+       if (err)
+               return err;
+
        return nand_spl_load_image(offset, spl_image.size,
                                   (void *)(unsigned long)spl_image.load_addr);
 }
@@ -77,7 +80,9 @@ int spl_nand_load_image(void)
                /* load linux */
                nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
                        sizeof(*header), (void *)header);
-               spl_parse_image_header(header);
+               err = spl_parse_image_header(header);
+               if (err)
+                       return err;
                if (header->ih_os == IH_OS_LINUX) {
                        /* happy - was a linux */
                        err = nand_spl_load_image(
index 63b20d820008eee3febf7b6065712c3f43e8eff5..ae71d26f0a61e730d88f6c0e93fc1358a6c5ec5a 100644 (file)
@@ -34,7 +34,5 @@ int spl_net_load_image(const char *device)
                printf("Problem booting with BOOTP\n");
                return rv;
        }
-       spl_parse_image_header((struct image_header *)load_addr);
-
-       return 0;
+       return spl_parse_image_header((struct image_header *)load_addr);
 }
index d0bd0b05333ba3bcb993f9bd9908efb5c9a16dc0..da2422f30515ac07d1af7161ac7ae906783de3f7 100644 (file)
@@ -9,6 +9,7 @@
 
 int spl_nor_load_image(void)
 {
+       int ret;
        /*
         * Loading of the payload to SDRAM is done with skipping of
         * the mkimage header in this SPL NOR driver
@@ -28,7 +29,9 @@ int spl_nor_load_image(void)
                if (image_get_os(header) == IH_OS_LINUX) {
                        /* happy - was a Linux */
 
-                       spl_parse_image_header(header);
+                       ret = spl_parse_image_header(header);
+                       if (ret)
+                               return ret;
 
                        memcpy((void *)spl_image.load_addr,
                               (void *)(CONFIG_SYS_OS_BASE +
@@ -56,8 +59,10 @@ int spl_nor_load_image(void)
         * Load real U-Boot from its location in NOR flash to its
         * defined location in SDRAM
         */
-       spl_parse_image_header(
+       ret = spl_parse_image_header(
                        (const struct image_header *)CONFIG_SYS_UBOOT_BASE);
+       if (ret)
+               return ret;
 
        memcpy((void *)(unsigned long)spl_image.load_addr,
               (void *)(CONFIG_SYS_UBOOT_BASE + sizeof(struct image_header)),
index af7d82eb62f39959c1a2b194ec879e11fb0c9bb5..1a28a84e4407a252706a2a3eb4870dd72b39503f 100644 (file)
@@ -17,6 +17,7 @@
 int spl_onenand_load_image(void)
 {
        struct image_header *header;
+       int ret;
 
        debug("spl: onenand\n");
 
@@ -25,7 +26,9 @@ int spl_onenand_load_image(void)
        /* Load u-boot */
        onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS,
                CONFIG_SYS_ONENAND_PAGE_SIZE, (void *)header);
-       spl_parse_image_header(header);
+       ret = spl_parse_image_header(header);
+       if (ret)
+               return ret;
        onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS,
                spl_image.size, (void *)spl_image.load_addr);
 
index 380d8ddf52831a0b175a10838fcc2274d6190e48..4f26ea5d21d94dc9a24858fd66780325ebb534b3 100644 (file)
@@ -40,8 +40,11 @@ int spl_ymodem_load_image(void)
        if (!ret) {
                while ((res =
                        xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
-                       if (addr == 0)
-                               spl_parse_image_header((struct image_header *)buf);
+                       if (addr == 0) {
+                               ret = spl_parse_image_header((struct image_header *)buf);
+                               if (ret)
+                                       return ret;
+                       }
                        store_addr = addr + spl_image.load_addr;
                        size += res;
                        addr += res;
index 85af09eeb65ccc1d7a0f16abffbe3ca5e0f3d8d1..07a6a1855e7cecab985f94abf93212aa02054ca1 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_CLK=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SYS_NS16550=y
index aa9bf336b14fd65405d0f60b9d71530d6aad4af4..01a51432ace6d45e1ee60b1f62b85c8621958ce1 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_CLK=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SYS_NS16550=y
index 9a7c0915697d4e61989f4da96efa4a55954c4875..a662e72cc7a835f771c47cc37c1da548bea88159 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index ac81854f4062b422f9d2545a5803a22fea408e99..b2933f778a0bd0c043ecf643c5b35c4c8e09722f 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index 405d9d407932f0ac70ed00c56b5fbcc513bdf6da..f197b6d2b008b2a6e2efba418fe0da5d03adf7f9 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
index 36154901aa4deb3f3996b7e394b151197d86bd3d..6624f9e07d0badea706f1396ca6aa67d4c8b762f 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
index bdc8e6b26d9581effdcec701237de71ba58df2b5..c6414f8be5397af92922b29806d3dcbe74ff8e1d 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index a17e9d0fd981459b2440f6e05ce3096631060dfd..b47a5602b80a04873996ec3ed42746162ec3ebfd 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index c4b215ad1f855b22565adbdc9cc4aaa746515e69..aab4498973666da8c79e224c4e863a68c16b516c 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index af2f54486a86559dc92a9ee5cfe70b49cfe50089..db3b6ea6c507c804fb060d650b418ca8784e2aae 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 6c53e1f0b5970b5a87b7ba757bb5afec7ec92f91..ea4e8d772a3b7c18d65b1ba283cd94095989848e 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 6827701ce34c06aa86f34cf9f0144d41e2b933b3..a2b56f384a0faafd5078293746827bbeb563311f 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 477a22603355add34e29e129b6b74f4a9d120c76..173848959d6b8cfad972089df9858f3babe0b5ac 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 0991f8ecb6611a1f7c1d71ce4bcb67bcc80319ce..a6064a5d90df1261e4e1db2b9b3a82f09e8ca767 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index ef30a6785baa99d4229cf369072e08723383272a..85944c68f15ab053e66444cc8e2002558b138f65 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 6cfe22088cb66672903992b308e66fee181c17d2..48efe3d948fca128c3e04f3f8ad8b0b9fb65210d 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index c0d8edffea836872a19b49857f35db537ca691bb..8edbe0c257aceb90e4b1a66151e6ae28e6b5efa4 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index e9d14cec140a7415e94c80ef982c9e1cd1a8f306..b622f742dbfcbcb2a46c5c51ac86801000039bc7 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 2e46e641831b7cd703890b5e57ca57e361acd684..241a72acf538d73745d4b774836f4c4c09c70d90 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 8dba79ad84153056fc5ab673ca6e6e23678ce386..49d7c0439577888c211c5838678585c4bd55e090 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 7f33c78fedbca131bd84787e85ae8ae1a4aa2edb..70b3025fc52811c76b885a66d1f52337646eb0b0 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index f7d37253e0793bf3e8323da246ac71c1faae59b0..5ced0e17bd46f5b4414039493af2dd9c15844021 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 9e4125374d3e16806f3339148e9a69ced44a9aab..de75b17df51df5dc56b9a5f0817368a705092f4a 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index e61c74e5b367cc2de19fc13397bbd6af32012d68..2202d2eaf41b9d4faf1237f0c93ed048101c5bf6 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 741009349a17f61e4c4dd10bee7318aec9f82a2b..35bb0364af6790f3d26b3c8466047facb7ff786e 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index f0e041fdda4aa2e88bd511d34758f508874692f7..f54083984b28b212dc9b6d57a78a3cd69103d566 100644 (file)
@@ -9,5 +9,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index cc4067d1c3a0888cf5f15599a66e383c6134364c..de416d91a8f93eaa6e34c657d98bf6c398f8a19a 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index df2135577752d8e441a8baa0ae6c196cdf17c19c..8b6e0d0acd5a51740785bf95e0de60b5ca70907d 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 48140aa467e95c60331970221e34de1c88ec66bd..e8b4b0a6590c8ff2090ed74d7827f3db0d82b6e0 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 1a07b9d536ca26d07182768710fa42b9699f9d42..ace620ba3a63c328215475d033536fb13ad13156 100644 (file)
@@ -17,6 +17,7 @@ CONFIG_CMD_PING=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_USE_TINY_PRINTF=y
index 9324c6c9e5f3aecfe65f6dc92b2e33d2b17f5e89..6e22bbadff2d54d24fd34f8500896ce970cec325 100644 (file)
@@ -58,6 +58,13 @@ config DM_I2C_GPIO
          bindings are supported.
          Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
 
+config SYS_I2C_FSL
+       bool "Freescale I2C bus driver"
+       depends on DM_I2C
+       help
+         Add support for Freescale I2C busses as used on MPC8240, MPC8245, and
+         MPC85xx processors.
+
 config SYS_I2C_CADENCE
        tristate "Cadence I2C Controller"
        depends on DM_I2C && (ARCH_ZYNQ || ARM64)
@@ -65,6 +72,24 @@ config SYS_I2C_CADENCE
          Say yes here to select Cadence I2C Host Controller. This controller is
          e.g. used by Xilinx Zynq.
 
+config SYS_I2C_DW
+       bool "Designware I2C Controller"
+       default n
+       help
+         Say yes here to select the Designware I2C Host Controller. This
+         controller is used in various SoCs, e.g. the ST SPEAr, Altera
+         SoCFPGA, Synopsys ARC700 and some Intel x86 SoCs.
+
+config SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
+       bool "DW I2C Enable Status Register not supported"
+       depends on SYS_I2C_DW && (TARGET_SPEAR300 || TARGET_SPEAR310 || \
+               TARGET_SPEAR320 || TARGET_SPEAR600 || TARGET_X600)
+       default y
+       help
+         Some versions of the Designware I2C controller do not support the
+         enable status register. This config option can be enabled in such
+         cases.
+
 config SYS_I2C_INTEL
        bool "Intel I2C/SMBUS driver"
        depends on DM_I2C
index 0c7cd0ba727921e2dc49acaf761036bc7e511a86..e60fd0a41903b811a98f0bcc88bf6ac8ae9519de 100644 (file)
@@ -36,6 +36,14 @@ struct dw_i2c {
        struct dw_scl_sda_cfg *scl_sda_cfg;
 };
 
+#ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
+static void dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
+{
+       u32 ena = enable ? IC_ENABLE_0B : 0;
+
+       writel(ena, &i2c_base->ic_enable);
+}
+#else
 static void dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 {
        u32 ena = enable ? IC_ENABLE_0B : 0;
@@ -56,6 +64,7 @@ static void dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 
        printf("timeout in %sabling I2C adapter\n", enable ? "en" : "dis");
 }
+#endif
 
 /*
  * i2c_set_bus_speed - Set the i2c speed
index b56a1c2541d7165fbd2cc0ac7db7affe61c640d0..b8cc647bd3900c4375dea5dbf8277556f81bf969 100644 (file)
@@ -12,6 +12,8 @@
 #include <i2c.h>               /* Functional interface */
 #include <asm/io.h>
 #include <asm/fsl_i2c.h>       /* HW definitions */
+#include <dm.h>
+#include <mapmem.h>
 
 /* The maximum number of microseconds we will wait until another master has
  * released the bus.  If not defined in the board header file, then use a
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const struct fsl_i2c *i2c_dev[4] = {
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET),
+#ifndef CONFIG_DM_I2C
+static const struct fsl_i2c_base *i2c_base[4] = {
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET),
 #ifdef CONFIG_SYS_FSL_I2C2_OFFSET
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET),
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET),
 #endif
 #ifdef CONFIG_SYS_FSL_I2C3_OFFSET
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C3_OFFSET),
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C3_OFFSET),
 #endif
 #ifdef CONFIG_SYS_FSL_I2C4_OFFSET
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C4_OFFSET)
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C4_OFFSET)
 #endif
 };
+#endif
 
 /* I2C speed map for a DFSR value of 1 */
 
@@ -104,7 +108,7 @@ static const struct {
 /**
  * Set the I2C bus speed for a given I2C device
  *
- * @param dev: the I2C device
+ * @param base: the I2C device registers
  * @i2c_clk: I2C bus clock frequency
  * @speed: the desired speed of the bus
  *
@@ -112,7 +116,7 @@ static const struct {
  *
  * The return value is the actual bus speed that is set.
  */
-static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
+static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
        unsigned int i2c_clk, unsigned int speed)
 {
        unsigned short divider = min(i2c_clk / speed, (unsigned int)USHRT_MAX);
@@ -173,8 +177,8 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
        debug("divider:%d, est_div:%ld, DFSR:%d\n", divider, est_div, dfsr);
        debug("FDR:0x%.2x, speed:%d\n", fdr, speed);
 #endif
-       writeb(dfsr, &dev->dfsrr);      /* set default filter */
-       writeb(fdr, &dev->fdr);         /* set bus speed */
+       writeb(dfsr, &base->dfsrr);     /* set default filter */
+       writeb(fdr, &base->fdr);        /* set bus speed */
 #else
        unsigned int i;
 
@@ -184,7 +188,7 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
 
                        fdr = fsl_i2c_speed_map[i].fdr;
                        speed = i2c_clk / fsl_i2c_speed_map[i].divider;
-                       writeb(fdr, &dev->fdr);         /* set bus speed */
+                       writeb(fdr, &base->fdr);        /* set bus speed */
 
                        break;
                }
@@ -192,6 +196,7 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
        return speed;
 }
 
+#ifndef CONFIG_DM_I2C
 static unsigned int get_i2c_clock(int bus)
 {
        if (bus)
@@ -199,8 +204,9 @@ static unsigned int get_i2c_clock(int bus)
        else
                return gd->arch.i2c1_clk;       /* I2C1 clock */
 }
+#endif
 
-static int fsl_i2c_fixup(const struct fsl_i2c *dev)
+static int fsl_i2c_fixup(const struct fsl_i2c_base *base)
 {
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
        unsigned long long timeval = 0;
@@ -214,42 +220,42 @@ static int fsl_i2c_fixup(const struct fsl_i2c *dev)
                flags = I2C_CR_BIT6;
 #endif
 
-       writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+       writeb(I2C_CR_MEN | I2C_CR_MSTA, &base->cr);
 
        timeval = get_ticks();
-       while (!(readb(&dev->sr) & I2C_SR_MBB)) {
+       while (!(readb(&base->sr) & I2C_SR_MBB)) {
                if ((get_ticks() - timeval) > timeout)
                        goto err;
        }
 
-       if (readb(&dev->sr) & I2C_SR_MAL) {
+       if (readb(&base->sr) & I2C_SR_MAL) {
                /* SDA is stuck low */
-               writeb(0, &dev->cr);
+               writeb(0, &base->cr);
                udelay(100);
-               writeb(I2C_CR_MSTA | flags, &dev->cr);
-               writeb(I2C_CR_MEN | I2C_CR_MSTA | flags, &dev->cr);
+               writeb(I2C_CR_MSTA | flags, &base->cr);
+               writeb(I2C_CR_MEN | I2C_CR_MSTA | flags, &base->cr);
        }
 
-       readb(&dev->dr);
+       readb(&base->dr);
 
        timeval = get_ticks();
-       while (!(readb(&dev->sr) & I2C_SR_MIF)) {
+       while (!(readb(&base->sr) & I2C_SR_MIF)) {
                if ((get_ticks() - timeval) > timeout)
                        goto err;
        }
        ret = 0;
 
 err:
-       writeb(I2C_CR_MEN | flags, &dev->cr);
-       writeb(0, &dev->sr);
+       writeb(I2C_CR_MEN | flags, &base->cr);
+       writeb(0, &base->sr);
        udelay(100);
 
        return ret;
 }
 
-static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+static void __i2c_init(const struct fsl_i2c_base *base, int speed, int
+                      slaveadd, int i2c_clk, int busnum)
 {
-       const struct fsl_i2c *dev;
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
        unsigned long long timeval;
 
@@ -260,23 +266,21 @@ static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
        */
        i2c_init_board();
 #endif
-       dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-
-       writeb(0, &dev->cr);            /* stop I2C controller */
+       writeb(0, &base->cr);           /* stop I2C controller */
        udelay(5);                      /* let it shutdown in peace */
-       set_i2c_bus_speed(dev, get_i2c_clock(adap->hwadapnr), speed);
-       writeb(slaveadd << 1, &dev->adr);/* write slave address */
-       writeb(0x0, &dev->sr);          /* clear status register */
-       writeb(I2C_CR_MEN, &dev->cr);   /* start I2C controller */
+       set_i2c_bus_speed(base, i2c_clk, speed);
+       writeb(slaveadd << 1, &base->adr);/* write slave address */
+       writeb(0x0, &base->sr);         /* clear status register */
+       writeb(I2C_CR_MEN, &base->cr);  /* start I2C controller */
 
        timeval = get_ticks();
-       while (readb(&dev->sr) & I2C_SR_MBB) {
+       while (readb(&base->sr) & I2C_SR_MBB) {
                if ((get_ticks() - timeval) < timeout)
                        continue;
 
-               if (fsl_i2c_fixup(dev))
+               if (fsl_i2c_fixup(base))
                        debug("i2c_init: BUS#%d failed to init\n",
-                             adap->hwadapnr);
+                             busnum);
 
                break;
        }
@@ -292,13 +296,12 @@ static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 }
 
 static int
-i2c_wait4bus(struct i2c_adapter *adap)
+i2c_wait4bus(const struct fsl_i2c_base *base)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        unsigned long long timeval = get_ticks();
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
 
-       while (readb(&dev->sr) & I2C_SR_MBB) {
+       while (readb(&base->sr) & I2C_SR_MBB) {
                if ((get_ticks() - timeval) > timeout)
                        return -1;
        }
@@ -306,22 +309,21 @@ i2c_wait4bus(struct i2c_adapter *adap)
        return 0;
 }
 
-static __inline__ int
-i2c_wait(struct i2c_adapter *adap, int write)
+static inline int
+i2c_wait(const struct fsl_i2c_base *base, int write)
 {
        u32 csr;
        unsigned long long timeval = get_ticks();
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_TIMEOUT);
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
 
        do {
-               csr = readb(&dev->sr);
+               csr = readb(&base->sr);
                if (!(csr & I2C_SR_MIF))
                        continue;
                /* Read again to allow register to stabilise */
-               csr = readb(&dev->sr);
+               csr = readb(&base->sr);
 
-               writeb(0x0, &dev->sr);
+               writeb(0x0, &base->sr);
 
                if (csr & I2C_SR_MAL) {
                        debug("i2c_wait: MAL\n");
@@ -345,203 +347,318 @@ i2c_wait(struct i2c_adapter *adap, int write)
        return -1;
 }
 
-static __inline__ int
-i2c_write_addr(struct i2c_adapter *adap, u8 dev, u8 dir, int rsta)
+static inline int
+i2c_write_addr(const struct fsl_i2c_base *base, u8 dev, u8 dir, int rsta)
 {
-       struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-
        writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
               | (rsta ? I2C_CR_RSTA : 0),
-              &device->cr);
+              &base->cr);
 
-       writeb((dev << 1) | dir, &device->dr);
+       writeb((dev << 1) | dir, &base->dr);
 
-       if (i2c_wait(adap, I2C_WRITE_BIT) < 0)
+       if (i2c_wait(base, I2C_WRITE_BIT) < 0)
                return 0;
 
        return 1;
 }
 
-static __inline__ int
-__i2c_write(struct i2c_adapter *adap, u8 *data, int length)
+static inline int
+__i2c_write_data(const struct fsl_i2c_base *base, u8 *data, int length)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        int i;
 
        for (i = 0; i < length; i++) {
-               writeb(data[i], &dev->dr);
+               writeb(data[i], &base->dr);
 
-               if (i2c_wait(adap, I2C_WRITE_BIT) < 0)
+               if (i2c_wait(base, I2C_WRITE_BIT) < 0)
                        break;
        }
 
        return i;
 }
 
-static __inline__ int
-__i2c_read(struct i2c_adapter *adap, u8 *data, int length)
+static inline int
+__i2c_read_data(const struct fsl_i2c_base *base, u8 *data, int length)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        int i;
 
        writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
-              &dev->cr);
+              &base->cr);
 
        /* dummy read */
-       readb(&dev->dr);
+       readb(&base->dr);
 
        for (i = 0; i < length; i++) {
-               if (i2c_wait(adap, I2C_READ_BIT) < 0)
+               if (i2c_wait(base, I2C_READ_BIT) < 0)
                        break;
 
                /* Generate ack on last next to last byte */
                if (i == length - 2)
                        writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
-                              &dev->cr);
+                              &base->cr);
 
                /* Do not generate stop on last byte */
                if (i == length - 1)
                        writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
-                              &dev->cr);
+                              &base->cr);
 
-               data[i] = readb(&dev->dr);
+               data[i] = readb(&base->dr);
        }
 
        return i;
 }
 
 static int
-fsl_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data,
-            int length)
+__i2c_read(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
+          u8 *data, int dlen)
 {
-       struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-       int i = -1; /* signal error */
-       u8 *a = (u8*)&addr;
-       int len = alen * -1;
+       int ret = -1; /* signal error */
 
-       if (i2c_wait4bus(adap) < 0)
+       if (i2c_wait4bus(base) < 0)
                return -1;
 
-       /* To handle the need of I2C devices that require to write few bytes
-        * (more than 4 bytes of address as in the case of else part)
-        * of data before reading, Negative equivalent of length(bytes to write)
-        * is passed, but used the +ve part of len for writing data
+       /* Some drivers use offset lengths in excess of 4 bytes. These drivers
+        * adhere to the following convention:
+        * - the offset length is passed as negative (that is, the absolute
+        *   value of olen is the actual offset length)
+        * - the offset itself is passed in data, which is overwritten by the
+        *   subsequent read operation
         */
-       if (alen < 0) {
-               /* Generate a START and send the Address and
-                * the Tx Bytes to the slave.
-                * "START: Address: Write bytes data[len]"
-                * IF part supports writing any number of bytes in contrast
-                * to the else part, which supports writing address offset
-                * of upto 4 bytes only.
-                * bytes that need to be written are passed in
-                * "data", which will eventually keep the data READ,
-                * after writing the len bytes out of it
-                */
-               if (i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0)
-                       i = __i2c_write(adap, data, len);
-
-               if (i != len)
+       if (olen < 0) {
+               if (i2c_write_addr(base, chip_addr, I2C_WRITE_BIT, 0) != 0)
+                       ret = __i2c_write_data(base, data, -olen);
+
+               if (ret != -olen)
                        return -1;
 
-               if (length && i2c_write_addr(adap, dev, I2C_READ_BIT, 1) != 0)
-                       i = __i2c_read(adap, data, length);
+               if (dlen && i2c_write_addr(base, chip_addr,
+                                          I2C_READ_BIT, 1) != 0)
+                       ret = __i2c_read_data(base, data, dlen);
        } else {
-               if ((!length || alen > 0) &&
-                   i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0  &&
-                   __i2c_write(adap, &a[4 - alen], alen) == alen)
-                       i = 0; /* No error so far */
-
-               if (length &&
-                   i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
-                       i = __i2c_read(adap, data, length);
+               if ((!dlen || olen > 0) &&
+                   i2c_write_addr(base, chip_addr, I2C_WRITE_BIT, 0) != 0  &&
+                   __i2c_write_data(base, offset, olen) == olen)
+                       ret = 0; /* No error so far */
+
+               if (dlen && i2c_write_addr(base, chip_addr, I2C_READ_BIT,
+                                          olen ? 1 : 0) != 0)
+                       ret = __i2c_read_data(base, data, dlen);
        }
 
-       writeb(I2C_CR_MEN, &device->cr);
+       writeb(I2C_CR_MEN, &base->cr);
 
-       if (i2c_wait4bus(adap)) /* Wait until STOP */
+       if (i2c_wait4bus(base)) /* Wait until STOP */
                debug("i2c_read: wait4bus timed out\n");
 
-       if (i == length)
-           return 0;
+       if (ret == dlen)
+               return 0;
 
        return -1;
 }
 
 static int
-fsl_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, int alen,
-             u8 *data, int length)
+__i2c_write(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
+           u8 *data, int dlen)
 {
-       struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-       int i = -1; /* signal error */
-       u8 *a = (u8*)&addr;
+       int ret = -1; /* signal error */
 
-       if (i2c_wait4bus(adap) < 0)
+       if (i2c_wait4bus(base) < 0)
                return -1;
 
-       if (i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0 &&
-           __i2c_write(adap, &a[4 - alen], alen) == alen) {
-               i = __i2c_write(adap, data, length);
+       if (i2c_write_addr(base, chip_addr, I2C_WRITE_BIT, 0) != 0 &&
+           __i2c_write_data(base, offset, olen) == olen) {
+               ret = __i2c_write_data(base, data, dlen);
        }
 
-       writeb(I2C_CR_MEN, &device->cr);
-       if (i2c_wait4bus(adap)) /* Wait until STOP */
+       writeb(I2C_CR_MEN, &base->cr);
+       if (i2c_wait4bus(base)) /* Wait until STOP */
                debug("i2c_write: wait4bus timed out\n");
 
-       if (i == length)
-           return 0;
+       if (ret == dlen)
+               return 0;
 
        return -1;
 }
 
 static int
-fsl_i2c_probe(struct i2c_adapter *adap, uchar chip)
+__i2c_probe_chip(const struct fsl_i2c_base *base, uchar chip)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        /* For unknow reason the controller will ACK when
         * probing for a slave with the same address, so skip
         * it.
         */
-       if (chip == (readb(&dev->adr) >> 1))
+       if (chip == (readb(&base->adr) >> 1))
                return -1;
 
-       return fsl_i2c_read(adap, chip, 0, 0, NULL, 0);
+       return __i2c_read(base, chip, 0, 0, NULL, 0);
 }
 
-static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,
-                       unsigned int speed)
+static unsigned int __i2c_set_bus_speed(const struct fsl_i2c_base *base,
+                       unsigned int speed, int i2c_clk)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-
-       writeb(0, &dev->cr);            /* stop controller */
-       set_i2c_bus_speed(dev, get_i2c_clock(adap->hwadapnr), speed);
-       writeb(I2C_CR_MEN, &dev->cr);   /* start controller */
+       writeb(0, &base->cr);           /* stop controller */
+       set_i2c_bus_speed(base, i2c_clk, speed);
+       writeb(I2C_CR_MEN, &base->cr);  /* start controller */
 
        return 0;
 }
 
+#ifndef CONFIG_DM_I2C
+static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+{
+       __i2c_init(i2c_base[adap->hwadapnr], speed, slaveadd,
+                  get_i2c_clock(adap->hwadapnr), adap->hwadapnr);
+}
+
+static int
+fsl_i2c_probe_chip(struct i2c_adapter *adap, uchar chip)
+{
+       return __i2c_probe_chip(i2c_base[adap->hwadapnr], chip);
+}
+
+static int
+fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,
+            u8 *data, int dlen)
+{
+       u8 *o = (u8 *)&offset;
+       return __i2c_read(i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen],
+                         olen, data, dlen);
+}
+
+static int
+fsl_i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,
+             u8 *data, int dlen)
+{
+       u8 *o = (u8 *)&offset;
+       return __i2c_write(i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen],
+                          olen, data, dlen);
+}
+
+static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,
+                                         unsigned int speed)
+{
+       return __i2c_set_bus_speed(i2c_base[adap->hwadapnr], speed,
+                                  get_i2c_clock(adap->hwadapnr));
+}
+
 /*
  * Register fsl i2c adapters
  */
-U_BOOT_I2C_ADAP_COMPLETE(fsl_0, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_0, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C_SPEED, CONFIG_SYS_FSL_I2C_SLAVE,
                         0)
 #ifdef CONFIG_SYS_FSL_I2C2_OFFSET
-U_BOOT_I2C_ADAP_COMPLETE(fsl_1, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_1, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C2_SPEED, CONFIG_SYS_FSL_I2C2_SLAVE,
                         1)
 #endif
 #ifdef CONFIG_SYS_FSL_I2C3_OFFSET
-U_BOOT_I2C_ADAP_COMPLETE(fsl_2, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_2, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C3_SPEED, CONFIG_SYS_FSL_I2C3_SLAVE,
                         2)
 #endif
 #ifdef CONFIG_SYS_FSL_I2C4_OFFSET
-U_BOOT_I2C_ADAP_COMPLETE(fsl_3, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_3, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C4_SPEED, CONFIG_SYS_FSL_I2C4_SLAVE,
                         3)
 #endif
+#else /* CONFIG_DM_I2C */
+static int fsl_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
+                             u32 chip_flags)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       return __i2c_probe_chip(dev->base, chip_addr);
+}
+
+static int fsl_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       return __i2c_set_bus_speed(dev->base, speed, dev->i2c_clk);
+}
+
+static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       u64 reg;
+       u32 addr, size;
+
+       reg = fdtdec_get_addr(gd->fdt_blob, bus->of_offset, "reg");
+       addr = reg >> 32;
+       size = reg & 0xFFFFFFFF;
+
+       dev->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
+
+       if (!dev->base)
+               return -ENOMEM;
+
+       dev->index = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                   "cell-index", -1);
+       dev->slaveadd = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                      "u-boot,i2c-slave-addr", 0x7f);
+       dev->speed = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                   "clock-frequency", 400000);
+
+       dev->i2c_clk = dev->index ? gd->arch.i2c2_clk : gd->arch.i2c1_clk;
+
+       return 0;
+}
+
+static int fsl_i2c_probe(struct udevice *bus)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       __i2c_init(dev->base, dev->speed, dev->slaveadd, dev->i2c_clk,
+                  dev->index);
+       return 0;
+}
+
+static int fsl_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       struct i2c_msg *dmsg, *omsg, dummy;
+
+       memset(&dummy, 0, sizeof(struct i2c_msg));
+
+       /* We expect either two messages (one with an offset and one with the
+        * actucal data) or one message (just data) */
+       if (nmsgs > 2 || nmsgs == 0) {
+               debug("%s: Only one or two messages are supported.", __func__);
+               return -1;
+       }
+
+       omsg = nmsgs == 1 ? &dummy : msg;
+       dmsg = nmsgs == 1 ? msg : msg + 1;
+
+       if (dmsg->flags & I2C_M_RD)
+               return __i2c_read(dev->base, dmsg->addr, omsg->buf, omsg->len,
+                                 dmsg->buf, dmsg->len);
+       else
+               return __i2c_write(dev->base, dmsg->addr, omsg->buf, omsg->len,
+                                  dmsg->buf, dmsg->len);
+}
+
+static const struct dm_i2c_ops fsl_i2c_ops = {
+       .xfer           = fsl_i2c_xfer,
+       .probe_chip     = fsl_i2c_probe_chip,
+       .set_bus_speed  = fsl_i2c_set_bus_speed,
+};
+
+static const struct udevice_id fsl_i2c_ids[] = {
+       { .compatible = "fsl-i2c", },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(i2c_fsl) = {
+       .name = "i2c_fsl",
+       .id = UCLASS_I2C,
+       .of_match = fsl_i2c_ids,
+       .probe = fsl_i2c_probe,
+       .ofdata_to_platdata = fsl_i2c_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct fsl_i2c_dev),
+       .ops = &fsl_i2c_ops,
+};
+
+#endif /* CONFIG_DM_I2C */
index 909cea24182efe4fd20cafba076b7b87bf6605fb..5642cd91fe2ee68bb1407f59b224d94bea302200 100644 (file)
@@ -112,48 +112,10 @@ static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c)
 
 struct i2c_cdns_bus {
        int id;
+       unsigned int input_freq;
        struct cdns_i2c_regs __iomem *regs;     /* register base */
 };
 
-
-/** cdns_i2c_probe() - Probe method
- * @dev: udevice pointer
- *
- * DM callback called when device is probed
- */
-static int cdns_i2c_probe(struct udevice *dev)
-{
-       struct i2c_cdns_bus *bus = dev_get_priv(dev);
-
-       bus->regs = (struct cdns_i2c_regs *)dev_get_addr(dev);
-       if (!bus->regs)
-               return -ENOMEM;
-
-       /* TODO: Calculate dividers based on CPU_CLK_1X */
-       /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */
-       writel((16 << CDNS_I2C_CONTROL_DIV_B_SHIFT) |
-               (2 << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control);
-
-       /* Enable master mode, ack, and 7-bit addressing */
-       setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS |
-               CDNS_I2C_CONTROL_ACKEN | CDNS_I2C_CONTROL_NEA);
-
-       debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
-
-       return 0;
-}
-
-static int cdns_i2c_remove(struct udevice *dev)
-{
-       struct i2c_cdns_bus *bus = dev_get_priv(dev);
-
-       debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
-
-       unmap_sysmem(bus->regs);
-
-       return 0;
-}
-
 /* Wait for an interrupt */
 static u32 cdns_i2c_wait(struct cdns_i2c_regs *cdns_i2c, u32 mask)
 {
@@ -172,14 +134,84 @@ static u32 cdns_i2c_wait(struct cdns_i2c_regs *cdns_i2c, u32 mask)
        return int_status & mask;
 }
 
+#define CDNS_I2C_DIVA_MAX      4
+#define CDNS_I2C_DIVB_MAX      64
+
+static int cdns_i2c_calc_divs(unsigned long *f, unsigned long input_clk,
+               unsigned int *a, unsigned int *b)
+{
+       unsigned long fscl = *f, best_fscl = *f, actual_fscl, temp;
+       unsigned int div_a, div_b, calc_div_a = 0, calc_div_b = 0;
+       unsigned int last_error, current_error;
+
+       /* calculate (divisor_a+1) x (divisor_b+1) */
+       temp = input_clk / (22 * fscl);
+
+       /*
+        * If the calculated value is negative or 0CDNS_I2C_DIVA_MAX,
+        * the fscl input is out of range. Return error.
+        */
+       if (!temp || (temp > (CDNS_I2C_DIVA_MAX * CDNS_I2C_DIVB_MAX)))
+               return -EINVAL;
+
+       last_error = -1;
+       for (div_a = 0; div_a < CDNS_I2C_DIVA_MAX; div_a++) {
+               div_b = DIV_ROUND_UP(input_clk, 22 * fscl * (div_a + 1));
+
+               if ((div_b < 1) || (div_b > CDNS_I2C_DIVB_MAX))
+                       continue;
+               div_b--;
+
+               actual_fscl = input_clk / (22 * (div_a + 1) * (div_b + 1));
+
+               if (actual_fscl > fscl)
+                       continue;
+
+               current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) :
+                                                       (fscl - actual_fscl));
+
+               if (last_error > current_error) {
+                       calc_div_a = div_a;
+                       calc_div_b = div_b;
+                       best_fscl = actual_fscl;
+                       last_error = current_error;
+               }
+       }
+
+       *a = calc_div_a;
+       *b = calc_div_b;
+       *f = best_fscl;
+
+       return 0;
+}
+
 static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
 {
-       if (speed != 100000) {
-               printf("%s, failed to set clock speed to %u\n", __func__,
-                      speed);
+       struct i2c_cdns_bus *bus = dev_get_priv(dev);
+       u32 div_a = 0, div_b = 0;
+       unsigned long speed_p = speed;
+       int ret = 0;
+
+       if (speed > 400000) {
+               debug("%s, failed to set clock speed to %u\n", __func__,
+                     speed);
                return -EINVAL;
        }
 
+       ret = cdns_i2c_calc_divs(&speed_p, bus->input_freq, &div_a, &div_b);
+       if (ret)
+               return ret;
+
+       debug("%s: div_a: %d, div_b: %d, input freq: %d, speed: %d/%ld\n",
+             __func__, div_a, div_b, bus->input_freq, speed, speed_p);
+
+       writel((div_b << CDNS_I2C_CONTROL_DIV_B_SHIFT) |
+              (div_a << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control);
+
+       /* Enable master mode, ack, and 7-bit addressing */
+       setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS |
+               CDNS_I2C_CONTROL_ACKEN | CDNS_I2C_CONTROL_NEA);
+
        return 0;
 }
 
@@ -313,6 +345,19 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
        return 0;
 }
 
+static int cdns_i2c_ofdata_to_platdata(struct udevice *dev)
+{
+       struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev);
+
+       i2c_bus->regs = (struct cdns_i2c_regs *)dev_get_addr(dev);
+       if (!i2c_bus->regs)
+               return -ENOMEM;
+
+       i2c_bus->input_freq = 100000000; /* TODO hardcode input freq for now */
+
+       return 0;
+}
+
 static const struct dm_i2c_ops cdns_i2c_ops = {
        .xfer = cdns_i2c_xfer,
        .probe_chip = cdns_i2c_probe_chip,
@@ -328,8 +373,7 @@ U_BOOT_DRIVER(cdns_i2c) = {
        .name = "i2c-cdns",
        .id = UCLASS_I2C,
        .of_match = cdns_i2c_of_match,
-       .probe = cdns_i2c_probe,
-       .remove = cdns_i2c_remove,
+       .ofdata_to_platdata = cdns_i2c_ofdata_to_platdata,
        .priv_auto_alloc_size = sizeof(struct i2c_cdns_bus),
        .ops = &cdns_i2c_ops,
 };
index f959d9de9e8b0de2883f5174bd097aaf5576a544..48900ed2afc5c36428a6c4ce798dfe9ec2c12ccf 100644 (file)
@@ -24,3 +24,13 @@ config I2C_ARB_GPIO_CHALLENGE
          I2C multimaster arbitration scheme using GPIOs and a challenge &
          response mechanism where masters have to claim the bus by asserting
          a GPIO.
+
+config I2C_MUX_PCA954x
+       tristate "TI PCA954x I2C Mux/switches"
+       depends on I2C_MUX
+       help
+         If you say yes here you get support for the TI PCA954x
+         I2C mux/switch devices. It is x width I2C multiplexer which enables to
+         paritioning I2C bus and connect multiple devices with the same address
+         to the same I2C controller where driver handles proper routing to
+         target i2c device. PCA9544 and PCA9548 are supported.
index 47c1240d7e9ef26b041450f994a4663201315fbc..0811add4216e6e728e58176752ccac970770f717 100644 (file)
@@ -5,3 +5,4 @@
 #
 obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE) += i2c-arb-gpio-challenge.o
 obj-$(CONFIG_$(SPL_)I2C_MUX) += i2c-mux-uclass.o
+obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o
diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c
new file mode 100644 (file)
index 0000000..7e0d2da
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 - 2016 Xilinx, Inc.
+ * Written by Michal Simek
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+#include <asm/gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pca954x_priv {
+       u32 addr; /* I2C mux address */
+       u32 width; /* I2C mux width - number of busses */
+};
+
+static int pca954x_deselect(struct udevice *mux, struct udevice *bus,
+                           uint channel)
+{
+       struct pca954x_priv *priv = dev_get_priv(mux);
+       uchar byte = 0;
+
+       return dm_i2c_write(mux, priv->addr, &byte, 1);
+}
+
+static int pca954x_select(struct udevice *mux, struct udevice *bus,
+                         uint channel)
+{
+       struct pca954x_priv *priv = dev_get_priv(mux);
+       uchar byte = 1 << channel;
+
+       return dm_i2c_write(mux, priv->addr, &byte, 1);
+}
+
+static const struct i2c_mux_ops pca954x_ops = {
+       .select = pca954x_select,
+       .deselect = pca954x_deselect,
+};
+
+static const struct udevice_id pca954x_ids[] = {
+       { .compatible = "nxp,pca9548", .data = (ulong)8 },
+       { .compatible = "nxp,pca9544", .data = (ulong)4 },
+       { }
+};
+
+static int pca954x_ofdata_to_platdata(struct udevice *dev)
+{
+       struct pca954x_priv *priv = dev_get_priv(dev);
+
+       priv->addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
+       if (!priv->addr) {
+               debug("MUX not found\n");
+               return -ENODEV;
+       }
+       priv->width = dev_get_driver_data(dev);
+
+       if (!priv->width) {
+               debug("No I2C MUX width specified\n");
+               return -EINVAL;
+       }
+
+       debug("Device %s at 0x%x with width %d\n",
+             dev->name, priv->addr, priv->width);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(pca954x) = {
+       .name = "pca954x",
+       .id = UCLASS_I2C_MUX,
+       .of_match = pca954x_ids,
+       .ops = &pca954x_ops,
+       .ofdata_to_platdata = pca954x_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct pca954x_priv),
+};
index 221ff4fe7afa02b39c56a5cd12a1cf359ae975ac..bf4443287fd2977fe3a61f3f653327ab3e013323 100644 (file)
@@ -184,27 +184,18 @@ static int twsi_wait(struct i2c_adapter *adap, int expected_status)
                MVTWSI_ERROR_TIMEOUT, control, status, expected_status);
 }
 
-/*
- * These flags are ORed to any write to the control register
- * They allow global setting of TWSIEN and ACK.
- * By default none are set.
- * twsi_start() sets TWSIEN (in case the controller was disabled)
- * twsi_recv() sets ACK or resets it depending on expected status.
- */
-static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
-
 /*
  * Assert the START condition, either in a single I2C transaction
  * or inside back-to-back ones (repeated starts).
  */
-static int twsi_start(struct i2c_adapter *adap, int expected_status)
+static int twsi_start(struct i2c_adapter *adap, int expected_status, u8 *flags)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
 
        /* globally set TWSIEN in case it was not */
-       twsi_control_flags |= MVTWSI_CONTROL_TWSIEN;
+       *flags |= MVTWSI_CONTROL_TWSIEN;
        /* assert START */
-       writel(twsi_control_flags | MVTWSI_CONTROL_START |
+       writel(*flags | MVTWSI_CONTROL_START |
                                    MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
        /* wait for controller to process START */
        return twsi_wait(adap, expected_status);
@@ -213,14 +204,15 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status)
 /*
  * Send a byte (i2c address or data).
  */
-static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
+static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status,
+                    u8 *flags)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
 
        /* put byte in data register for sending */
        writel(byte, &twsi->data);
        /* clear any pending interrupt -- that'll cause sending */
-       writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+       writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
        /* wait for controller to receive byte and check ACK */
        return twsi_wait(adap, expected_status);
 }
@@ -229,18 +221,18 @@ static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
  * Receive a byte.
  * Global mvtwsi_control_flags variable says if we should ack or nak.
  */
-static int twsi_recv(struct i2c_adapter *adap, u8 *byte)
+static int twsi_recv(struct i2c_adapter *adap, u8 *byte, u8 *flags)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
        int expected_status, status;
 
        /* compute expected status based on ACK bit in global control flags */
-       if (twsi_control_flags & MVTWSI_CONTROL_ACK)
+       if (*flags & MVTWSI_CONTROL_ACK)
                expected_status = MVTWSI_STATUS_DATA_R_ACK;
        else
                expected_status = MVTWSI_STATUS_DATA_R_NAK;
        /* acknowledge *previous state* and launch receive */
-       writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+       writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
        /* wait for controller to receive byte and assert ACK or NAK */
        status = twsi_wait(adap, expected_status);
        /* if we did receive expected byte then store it */
@@ -296,8 +288,7 @@ static unsigned int twsi_calc_freq(const int n, const int m)
 static void twsi_reset(struct i2c_adapter *adap)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
-       /* ensure controller will be enabled by any twsi*() function */
-       twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
+
        /* reset controller */
        writel(0, &twsi->soft_reset);
        /* wait 2 ms -- this is what the Marvell LSP does */
@@ -353,7 +344,7 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
  * Expected address status will derive from direction bit (bit 0) in addr.
  */
 static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
-                    u8 addr)
+                    u8 addr, u8 *flags)
 {
        int status, expected_addr_status;
 
@@ -363,10 +354,11 @@ static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
        else /* writing */
                expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
        /* assert START */
-       status = twsi_start(adap, expected_start_status);
+       status = twsi_start(adap, expected_start_status, flags);
        /* send out the address if the start went well */
        if (status == 0)
-               status = twsi_send(adap, addr, expected_addr_status);
+               status = twsi_send(adap, addr, expected_addr_status,
+                                  flags);
        /* return ok or status of first failure to caller */
        return status;
 }
@@ -378,13 +370,14 @@ static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
 static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
 {
        u8 dummy_byte;
+       u8 flags = 0;
        int status;
 
        /* begin i2c read */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1);
+       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1, &flags);
        /* dummy read was accepted: receive byte but NAK it. */
        if (status == 0)
-               status = twsi_recv(adap, &dummy_byte);
+               status = twsi_recv(adap, &dummy_byte, &flags);
        /* Stop transaction */
        twsi_stop(adap, 0);
        /* return 0 or status of first failure */
@@ -405,27 +398,28 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                        int alen, uchar *data, int length)
 {
        int status;
+       u8 flags = 0;
 
        /* begin i2c write to send the address bytes */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
+       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
        /* send addr bytes */
        while ((status == 0) && alen--)
                status = twsi_send(adap, addr >> (8*alen),
-                       MVTWSI_STATUS_DATA_W_ACK);
+                       MVTWSI_STATUS_DATA_W_ACK, &flags);
        /* begin i2c read to receive eeprom data bytes */
        if (status == 0)
                status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
-                                  (chip << 1) | 1);
+                                  (chip << 1) | 1, &flags);
        /* prepare ACK if at least one byte must be received */
        if (length > 0)
-               twsi_control_flags |= MVTWSI_CONTROL_ACK;
+               flags |= MVTWSI_CONTROL_ACK;
        /* now receive actual bytes */
        while ((status == 0) && length--) {
                /* reset NAK if we if no more to read now */
                if (length == 0)
-                       twsi_control_flags &= ~MVTWSI_CONTROL_ACK;
+                       flags &= ~MVTWSI_CONTROL_ACK;
                /* read current byte */
-               status = twsi_recv(adap, data++);
+               status = twsi_recv(adap, data++, &flags);
        }
        /* Stop transaction */
        status = twsi_stop(adap, status);
@@ -441,16 +435,18 @@ static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
                        int alen, uchar *data, int length)
 {
        int status;
+       u8 flags = 0;
 
        /* begin i2c write to send the eeprom adress bytes then data bytes */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
+       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
        /* send addr bytes */
        while ((status == 0) && alen--)
                status = twsi_send(adap, addr >> (8*alen),
-                       MVTWSI_STATUS_DATA_W_ACK);
+                       MVTWSI_STATUS_DATA_W_ACK, &flags);
        /* send data bytes */
        while ((status == 0) && (length-- > 0))
-               status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK);
+               status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK,
+                                  &flags);
        /* Stop transaction */
        status = twsi_stop(adap, status);
        /* return 0 or status of first failure */
index ca56fe9015834ed71e7e92d6725c5325505105ad..46c98a9ceead26be3fca6eb8195f2a448fa1fb58 100644 (file)
@@ -23,6 +23,8 @@
 static int spi_load_image_os(struct spi_flash *flash,
                             struct image_header *header)
 {
+       int err;
+
        /* Read for a header, parse or error out. */
        spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
                       (void *)header);
@@ -30,7 +32,9 @@ static int spi_load_image_os(struct spi_flash *flash,
        if (image_get_magic(header) != IH_MAGIC)
                return -1;
 
-       spl_parse_image_header(header);
+       err = spl_parse_image_header(header);
+       if (err)
+               return err;
 
        spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
                       spl_image.size, (void *)spl_image.load_addr);
@@ -81,7 +85,9 @@ int spl_spi_load_image(void)
                if (err)
                        return err;
 
-               spl_parse_image_header(header);
+               err = spl_parse_image_header(header);
+               if (err)
+                       return err;
                err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
                               spl_image.size, (void *)spl_image.load_addr);
        }
index 36d4b23bfeb1a8d5c21713ff4837913fa8d3937b..5676a0f083b6b33ada21910348c0f3dc8c79d56c 100644 (file)
@@ -352,7 +352,9 @@ static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
         */
        __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));
 
-       clk->rate = (u64)(clk->parent->rate * 16) / div;
+       do_div(parent_rate, div);
+
+       clk->rate = parent_rate;
 
        return 0;
 }
index 1bd472969fdba87f230488ab99be418928e45695..05d2d45b251ac5f48915deb6d0365d1a56e061a3 100644 (file)
@@ -59,7 +59,6 @@
  * I2C configuration
  */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #define CONFIG_I2C_ENV_EEPROM_BUS      2
 #define CONFIG_SYS_I2C_SPEED           100000
 #define CONFIG_SYS_I2C_SPEED1          100000
index 68d3fd7384498b6cffdc953c6c5743c953fe49b9..9bd9f6e3e410ee3b580221b9cdcf6dc73c00e46b 100644 (file)
 #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS     800 /* 400 KB */
 #define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION     1
 #define CONFIG_SYS_MONITOR_LEN  (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS/2*1024)
+#define CONFIG_SPL_ABORT_ON_RAW_IMAGE
+#define CONFIG_SPL_EXT_SUPPORT
 #endif
 
 /* SATA support */
 #if defined(CONFIG_SPL_SATA_SUPPORT)
 #define CONFIG_SPL_SATA_BOOT_DEVICE            0
 #define CONFIG_SYS_SATA_FAT_BOOT_PARTITION     1
+#define CONFIG_SPL_ABORT_ON_RAW_IMAGE
+#define CONFIG_SPL_EXT_SUPPORT
 #endif
 
 /* Define the payload for FAT/EXT support */
index cfb92d6356460a39c41c1ca0d8613b9010bc3dff..23829518739395c53f1f1b8038c9c77603a58a71 100644 (file)
@@ -75,7 +75,6 @@
 
 /* SPL */
 #define CONFIG_SPL_FAT_SUPPORT
-#define CONFIG_SPL_EXT_SUPPORT
 #define CONFIG_SPL_MMC_SUPPORT
 #include "imx6_spl.h"                  /* common IMX6 SPL configuration */
 
 #define CONFIG_USB_EHCI_MX6
 #define CONFIG_USB_STORAGE
 #define CONFIG_USB_KEYBOARD
+#define CONFIG_SYS_STDIO_DEREGISTER
 #define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_ASIX
index 4fdc09a3ce7cc263a71af051c738260d7f72f056..f6577668a1dd6f31fc94fe794d2914604c13b12f 100644 (file)
  * I2C support
  */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #define CONFIG_SYS_I2C_BUS_MAX         4
 #define CONFIG_SYS_I2C_BASE            SOCFPGA_I2C0_ADDRESS
 #define CONFIG_SYS_I2C_BASE1           SOCFPGA_I2C1_ADDRESS
index c4b6234096e134a60d1eb6200fee111584181424..7b2d262b4bb71f83ea52a6dabfc78ef8ffdaccba 100644 (file)
@@ -35,7 +35,6 @@
 
 /* I2C driver configuration */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #if defined(CONFIG_SPEAR600)
 #define CONFIG_SYS_I2C_BASE                    0xD0200000
 #elif defined(CONFIG_SPEAR300)
index badb955241d18815ea88c3fdabe037c6fac1f58a..77ced7179a0cfc04f1489184ffa5bf32a0ffaf9d 100644 (file)
@@ -16,7 +16,6 @@
 #define CONFIG_SPL_MMC_SUPPORT
 #define CONFIG_SPL_SPI_SUPPORT
 #define CONFIG_SPL_FAT_SUPPORT
-#define CONFIG_SPL_EXT_SUPPORT
 
 /* common IMX6 SPL configuration */
 #include "imx6_spl.h"
index d7da0b295b6b7ae61d7414c06722380091e12689..5fdd2bee049e7927fd3a3ff6944b767cb35f68f1 100644 (file)
@@ -85,7 +85,6 @@
 
 /* I2C config options */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #define CONFIG_SYS_I2C_BASE                    0xD0200000
 #define CONFIG_SYS_I2C_SPEED                   400000
 #define CONFIG_SYS_I2C_SLAVE                   0x02
index de4f70a377313bec73e9cee638d67a1ce09b61e4..7edfab46dcd1ea44b039fb2172fe9c17ea173d18 100644 (file)
@@ -56,7 +56,7 @@ void preloader_console_init(void);
 u32 spl_boot_device(void);
 u32 spl_boot_mode(void);
 void spl_set_header_raw_uboot(void);
-void spl_parse_image_header(const struct image_header *header);
+int spl_parse_image_header(const struct image_header *header);
 void spl_board_prepare_for_linux(void);
 void __noreturn jump_to_image_linux(void *arg);
 int spl_start_uboot(void);
index 7c219222e9f4cd73e06d57cb69c66bfebeba0f88..092d550002a4030978859f06226059ed2404b4ec 100644 (file)
@@ -209,7 +209,7 @@ static void set_dcd_param_v2(struct imx_header *imxhdr, uint32_t dcd_len,
                d = d2;
                d->write_dcd_command.tag = DCD_CHECK_DATA_COMMAND_TAG;
                d->write_dcd_command.length = cpu_to_be16(4);
-               d->write_dcd_command.param = DCD_CHECK_BITS_SET_PARAM;
+               d->write_dcd_command.param = DCD_CHECK_BITS_CLR_PARAM;
                break;
        default:
                break;