]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-arm
authorTom Rini <trini@ti.com>
Tue, 10 Dec 2013 22:15:18 +0000 (17:15 -0500)
committerTom Rini <trini@ti.com>
Tue, 10 Dec 2013 22:15:18 +0000 (17:15 -0500)
Conflicts:
board/samsung/trats2/trats2.c
include/configs/exynos5250-dt.h

Signed-off-by: Tom Rini <trini@ti.com>
68 files changed:
Makefile
README
arch/blackfin/cpu/.gitignore
arch/blackfin/cpu/Makefile
arch/blackfin/cpu/bootrom-asm-offsets.awk [deleted file]
arch/blackfin/cpu/bootrom-asm-offsets.c.in [deleted file]
arch/blackfin/cpu/gpio.c
arch/blackfin/include/asm/gpio.h
arch/powerpc/cpu/mpc83xx/Makefile
arch/powerpc/cpu/mpc85xx/speed.c
arch/powerpc/cpu/mpc85xx/start.S
arch/sandbox/cpu/os.c
arch/sandbox/cpu/start.c
arch/sandbox/include/asm/config.h
arch/sandbox/include/asm/getopt.h
arch/sandbox/include/asm/sections.h
arch/sandbox/include/asm/spi.h [new file with mode: 0644]
arch/sandbox/include/asm/state.h
board/freescale/c29xpcie/ddr.c
board/samsung/smdk5250/exynos5-dt.c
board/samsung/trats/trats.c
board/samsung/trats2/trats2.c
board/sandbox/sandbox/README.sandbox
common/cmd_eeprom.c
doc/SPI/README.sandbox-spi [new file with mode: 0644]
doc/device-tree-bindings/spi/spi-bus.txt [new file with mode: 0644]
drivers/i2c/Makefile
drivers/i2c/fti2c010.c
drivers/i2c/omap24xx_i2c.c
drivers/i2c/s3c24x0_i2c.c
drivers/misc/cros_ec_spi.c
drivers/mmc/Makefile
drivers/mmc/dw_mmc.c
drivers/mmc/exynos_dw_mmc.c
drivers/mmc/fsl_esdhc_spl.c
drivers/mmc/ftsdc021_sdhci.c [new file with mode: 0644]
drivers/mtd/spi/Makefile
drivers/mtd/spi/fsl_espi_spl.c
drivers/mtd/spi/sandbox.c [new file with mode: 0644]
drivers/mtd/spi/sf_internal.h
drivers/mtd/spi/sf_probe.c
drivers/spi/Makefile
drivers/spi/bfin_spi.c
drivers/spi/bfin_spi6xx.c
drivers/spi/exynos_spi.c
drivers/spi/sandbox_spi.c [new file with mode: 0644]
drivers/spi/spi.c
include/configs/MPC8349EMDS.h
include/configs/P1010RDB.h
include/configs/T2080QDS.h
include/configs/VCMA9.h
include/configs/arndale.h
include/configs/bf506f-ezkit.h
include/configs/bf525-ucr2.h
include/configs/bf533-stamp.h
include/configs/bf537-minotaur.h
include/configs/bf537-srv1.h
include/configs/blackstamp.h
include/configs/cm-bf548.h
include/configs/dnp5370.h
include/configs/exynos5250-dt.h
include/configs/sandbox.h
include/configs/trats.h
include/configs/trats2.h
include/dwmmc.h
include/faraday/ftsdc021.h [new file with mode: 0644]
include/spi.h
include/spi_flash.h

index 607d1dcbbc67ad42939869262a09bb253c5132b5..7310c4ef0af4e6da4a27fa2b5f5ba39e9e69f602 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -807,7 +807,6 @@ clean:
               $(obj)board/matrix_vision/*/bootscript.img                 \
               $(obj)board/voiceblue/eeprom                               \
               $(obj)u-boot.lds                                           \
-              $(obj)arch/blackfin/cpu/bootrom-asm-offsets.[chs]          \
               $(obj)arch/blackfin/cpu/init.{lds,elf}
        @rm -f $(obj)include/bmp_logo.h
        @rm -f $(obj)include/bmp_logo_data.h
diff --git a/README b/README
index 1130b4f3291628019b86aaf71183a2c6701888d0..8f0b38cbf38b16de6f2a9d8707cde096f3b52b51 100644 (file)
--- a/README
+++ b/README
@@ -2141,6 +2141,12 @@ CBFS (Coreboot Filesystem) support
                  - set CONFIG_SYS_I2C_ZYNQ_SPEED for speed setting
                  - set CONFIG_SYS_I2C_ZYNQ_SLAVE for slave addr
 
+               - drivers/i2c/s3c24x0_i2c.c:
+                 - activate this driver with CONFIG_SYS_I2C_S3C24X0
+                 - This driver adds i2c buses (11 for Exynos5250, Exynos5420
+                   9 i2c buses for Exynos4 and 1 for S3C24X0 SoCs from Samsung)
+                   with a fix speed from 100000 and the slave addr 0!
+
                additional defines:
 
                CONFIG_SYS_NUM_I2C_BUSES
index ba986d8ba87d49120e558f00820d37e9e9729568..3df1fa21c958ff1f1d5948a0f363cd776c32f339 100644 (file)
@@ -1,4 +1,2 @@
-bootrom-asm-offsets.[chs]
-
 init.lds
 init.elf
index 243dc22a0c61470e9c01ca8542f0884168eafc89..a61594ab72a9c94c6a4791b651a31e4703abf5b0 100644 (file)
@@ -23,16 +23,6 @@ obj-y  += traps.o
 
 extra-y += check_initcode
 
-extra-y += bootrom-asm-offsets.h
-$(obj)bootrom-asm-offsets.c: bootrom-asm-offsets.c.in bootrom-asm-offsets.awk
-       echo '#include <asm/mach-common/bits/bootrom.h>' | $(CPP) $(CPPFLAGS) - | gawk -f ./bootrom-asm-offsets.awk > $@.tmp
-       mv $@.tmp $@
-$(obj)bootrom-asm-offsets.s: $(obj)bootrom-asm-offsets.c
-       $(CC) $(CFLAGS) -S $^ -o $@.tmp
-       mv $@.tmp $@
-$(obj)bootrom-asm-offsets.h: $(obj)bootrom-asm-offsets.s
-       sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}" $^ > $@
-
 # make sure our initcode (which goes into LDR) does not
 # have relocs or external references
 $(obj)initcode.o: CFLAGS += -fno-function-sections -fno-data-sections
diff --git a/arch/blackfin/cpu/bootrom-asm-offsets.awk b/arch/blackfin/cpu/bootrom-asm-offsets.awk
deleted file mode 100644 (file)
index 1d61824..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/gawk -f
-BEGIN {
-       print "/* DO NOT EDIT: AUTOMATICALLY GENERATED"
-       print " * Input files: bootrom-asm-offsets.awk bootrom-asm-offsets.c.in"
-       print " * DO NOT EDIT: AUTOMATICALLY GENERATED"
-       print " */"
-       print ""
-       system("cat bootrom-asm-offsets.c.in")
-       print "{"
-}
-
-{
-       /* find a structure definition */
-       if ($0 ~ /typedef struct .* {/) {
-               delete members;
-               i = 0;
-
-               /* extract each member of the structure */
-               while (1) {
-                       getline
-                       if ($1 == "}")
-                               break;
-                       gsub(/[*;]/, "");
-                       members[i++] = $NF;
-               }
-
-               /* grab the structure's name */
-               struct = $NF;
-               sub(/;$/, "", struct);
-
-               /* output the DEFINE() macros */
-               while (i-- > 0)
-                       print "\tDEFINE(" struct ", " members[i] ");"
-               print ""
-       }
-}
-
-END {
-       print "\treturn 0;"
-       print "}"
-}
diff --git a/arch/blackfin/cpu/bootrom-asm-offsets.c.in b/arch/blackfin/cpu/bootrom-asm-offsets.c.in
deleted file mode 100644 (file)
index 64c2f24..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* A little trick taken from the kernel asm-offsets.h where we convert
- * the C structures automatically into a bunch of defines for use in
- * the assembly files.
- */
-
-#include <linux/stddef.h>
-#include <asm/mach-common/bits/bootrom.h>
-
-#define _DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-#define DEFINE(s, m) _DEFINE(offset_##s##_##m, offsetof(s, m))
-
-int main(int argc, char * const argv[])
index 5e9c68af85ac0460ace557d867a3414d5455bb57..86da706f08d2164349b485c47c988b566916d2c5 100644 (file)
@@ -12,7 +12,7 @@
 #include <asm/gpio.h>
 #include <asm/portmux.h>
 
-#ifdef CONFIG_ADI_GPIO1
+#ifndef CONFIG_ADI_GPIO2
 #if ANOMALY_05000311 || ANOMALY_05000323
 enum {
        AWA_data = SYSCR,
index 376ec02b650897fa8a52b15ff38f8cc8abf1a48d..6ebcf01aff87303a25557316ae05bf5e20768514 100644 (file)
@@ -72,7 +72,7 @@
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_ADI_GPIO1
+#ifndef CONFIG_ADI_GPIO2
 void set_gpio_dir(unsigned, unsigned short);
 void set_gpio_inen(unsigned, unsigned short);
 void set_gpio_polar(unsigned, unsigned short);
index c345dd6ae64f915d264637c59e0c099ceda0fffe..cf9116274d43ffb739313b34f46ba7d9d246178e 100644 (file)
@@ -38,9 +38,7 @@ obj-$(CONFIG_OF_LIBFDT) += fdt.o
 # Stub implementations of cache management functions for USB
 obj-y += cache.o
 
-ifdef CONFIG_SYS_FSL_DDR2
-obj-$(CONFIG_MPC8349) += $(SRCTREE)/drivers/ddr/fsl/mpc85xx_ddr_gen2.o
-else
+ifndef CONFIG_SYS_FSL_DDRC_GEN2
 obj-y += spd_sdram.o
 endif
 obj-$(CONFIG_SYS_FSL_DDR2) += law.o
index 1a58a194f99c6fd1ea2be9046ccbc37aa1549185..46ae80c4d819b244de758d60a28a09cd6095d4a5 100644 (file)
@@ -86,6 +86,14 @@ void get_sys_info(sys_info_t *sys_info)
        mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
                        FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT)
                        & FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
+       /* T4240/T4160 Rev2.0 MEM_PLL_RAT uses a value which is half of
+        * T4240/T4160 Rev1.0. eg. It's 12 in Rev1.0, however, for Rev2.0
+        * it uses 6.
+        */
+#if defined(CONFIG_PPC_T4240) || defined(CONFIG_PPC_T4160)
+       if (SVR_MAJ(get_svr()) >= 2)
+               mem_pll_rat *= 2;
+#endif
        if (mem_pll_rat > 2)
                sys_info->freq_ddrbus *= mem_pll_rat;
        else
index 6a81fa73e4bed59f306da48696ae99ec55d536c8..db84d10c5bf2a9ad695a9a5644df3812f20d1fa8 100644 (file)
@@ -886,7 +886,11 @@ delete_ccsr_l2_tlb:
        erratum_set_dcsr 0xb0008 0x00900000
        erratum_set_dcsr 0xb0e40 0xe00a0000
        erratum_set_ccsr 0x18600 CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY
+#ifdef  CONFIG_RAMBOOT_PBL
+       erratum_set_ccsr 0x10f00 0x495e5000
+#else
        erratum_set_ccsr 0x10f00 0x415e5000
+#endif
        erratum_set_ccsr 0x11f00 0x415e5000
 
        /* Make temp mapping uncacheable again, if it was initially */
index db66fd31f254cd733abaadb7db0a0b4c5390dc43..26f44cb597ef14cd8f05376e0b96fd2ab2522ae1 100644 (file)
@@ -161,7 +161,7 @@ static struct option *long_opts;
 
 int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
 {
-       struct sb_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
+       struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
        size_t num_options = __u_boot_sandbox_option_count();
        size_t i;
 
index f1cb7930b1083aa15b712e1466f6de21f9557abb..1b1545478470c48bbfe4a9275fb4853d4aa1813a 100644 (file)
@@ -13,7 +13,7 @@
 int sandbox_early_getopt_check(void)
 {
        struct sandbox_state *state = state_get_current();
-       struct sb_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
+       struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
        size_t num_options = __u_boot_sandbox_option_count();
        size_t i;
        int max_arg_len, max_noarg_len;
@@ -40,7 +40,7 @@ int sandbox_early_getopt_check(void)
        max_noarg_len = max_arg_len + 7;
 
        for (i = 0; i < num_options; ++i) {
-               struct sb_cmdline_option *opt = sb_opt[i];
+               struct sandbox_cmdline_option *opt = sb_opt[i];
 
                /* first output the short flag if it has one */
                if (opt->flag_short >= 0x100)
@@ -61,12 +61,12 @@ int sandbox_early_getopt_check(void)
        os_exit(0);
 }
 
-static int sb_cmdline_cb_help(struct sandbox_state *state, const char *arg)
+static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)
 {
        /* just flag to sandbox_early_getopt_check to show usage */
        return 1;
 }
-SB_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
+SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
 
 int sandbox_main_loop_init(void)
 {
@@ -81,19 +81,20 @@ int sandbox_main_loop_init(void)
        return 0;
 }
 
-static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg)
+static int sandbox_cmdline_cb_command(struct sandbox_state *state,
+                                     const char *arg)
 {
        state->cmd = arg;
        return 0;
 }
-SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
+SANDBOX_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
 
-static int sb_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
+static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
 {
        state->fdt_fname = arg;
        return 0;
 }
-SB_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
+SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
 
 int main(int argc, char *argv[])
 {
index 7755a4defffb8326985f40256602f2a5e985db79..ec7729eb4ccbf44a5d74e0c220c22e46897208ae 100644 (file)
@@ -9,4 +9,12 @@
 
 #define CONFIG_SANDBOX_ARCH
 
+/* Used by drivers/spi/sandbox_spi.c and arch/sandbox/include/asm/state.h */
+#ifndef CONFIG_SANDBOX_SPI_MAX_BUS
+#define CONFIG_SANDBOX_SPI_MAX_BUS 1
+#endif
+#ifndef CONFIG_SANDBOX_SPI_MAX_CS
+#define CONFIG_SANDBOX_SPI_MAX_CS 10
+#endif
+
 #endif
index 685883cd3f6449dfb9ed6d8e0713a545c94be4b5..3048c2cc30ba9bac1f6013df9f82a23ad347084f 100644 (file)
@@ -18,7 +18,7 @@ struct sandbox_state;
  * consumer code should focus on the macros below and
  * the callback function.
  */
-struct sb_cmdline_option {
+struct sandbox_cmdline_option {
        /* The long flag name: "help" for "--help" */
        const char *flag;
        /* The (optional) short flag name: "h" for "-h" */
@@ -35,18 +35,19 @@ struct sb_cmdline_option {
  * Internal macro to expand the lower macros into the necessary
  * magic junk that makes this all work.
  */
-#define _SB_CMDLINE_OPT(f, s, ha, h) \
-       static struct sb_cmdline_option sb_cmdline_option_##f = { \
+#define _SANDBOX_CMDLINE_OPT(f, s, ha, h) \
+       static struct sandbox_cmdline_option sandbox_cmdline_option_##f = { \
                .flag = #f, \
                .flag_short = s, \
                .help = h, \
                .has_arg = ha, \
-               .callback = sb_cmdline_cb_##f, \
+               .callback = sandbox_cmdline_cb_##f, \
        }; \
        /* Ppointer to the struct in a special section for the linker script */ \
        static __attribute__((section(".u_boot_sandbox_getopt"), used)) \
-               struct sb_cmdline_option *sb_cmdline_option_##f##_ptr = \
-               &sb_cmdline_option_##f
+               struct sandbox_cmdline_option \
+                       *sandbox_cmdline_option_##f##_ptr = \
+                       &sandbox_cmdline_option_##f
 
 /**
  * Macros for end code to declare new command line flags.
@@ -56,16 +57,16 @@ struct sb_cmdline_option {
  * @param h   The help string displayed when showing --help
  *
  * This invocation:
- *   SB_CMDLINE_OPT(foo, 0, "The foo arg");
+ *   SANDBOX_CMDLINE_OPT(foo, 0, "The foo arg");
  * Will create a new flag named "--foo" (no short option) that takes
  * no argument.  If the user specifies "--foo", then the callback func
- * sb_cmdline_cb_foo() will automatically be called.
+ * sandbox_cmdline_cb_foo() will automatically be called.
  */
-#define SB_CMDLINE_OPT(f, ha, h) _SB_CMDLINE_OPT(f, 0, ha, h)
+#define SANDBOX_CMDLINE_OPT(f, ha, h) _SANDBOX_CMDLINE_OPT(f, 0, ha, h)
 /*
  * Same as above, but @s is used to specify a short flag e.g.
- *   SB_CMDLINE_OPT(foo, 'f', 0, "The foo arg");
+ *   SANDBOX_CMDLINE_OPT(foo, 'f', 0, "The foo arg");
  */
-#define SB_CMDLINE_OPT_SHORT(f, s, ha, h) _SB_CMDLINE_OPT(f, s, ha, h)
+#define SANDBOX_CMDLINE_OPT_SHORT(f, s, ha, h) _SANDBOX_CMDLINE_OPT(f, s, ha, h)
 
 #endif
index 4c378600b0f383382d86a4af5f4767e9393e5d0d..fbc1bd11a34162d58fd82b5cdab6ff791dabfea3 100644 (file)
@@ -11,9 +11,9 @@
 
 #include <asm-generic/sections.h>
 
-struct sb_cmdline_option;
+struct sandbox_cmdline_option;
 
-extern struct sb_cmdline_option *__u_boot_sandbox_option_start[],
+extern struct sandbox_cmdline_option *__u_boot_sandbox_option_start[],
        *__u_boot_sandbox_option_end[];
 
 static inline size_t __u_boot_sandbox_option_count(void)
diff --git a/arch/sandbox/include/asm/spi.h b/arch/sandbox/include/asm/spi.h
new file mode 100644 (file)
index 0000000..49b4a0f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Simulate a SPI port and clients (see README.sandbox for details)
+ *
+ * Copyright (c) 2011-2013 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_SPI_H__
+#define __ASM_SPI_H__
+
+#include <linux/types.h>
+
+/*
+ * The interface between the SPI bus and the SPI client.  The bus will
+ * instantiate a client, and that then call into it via these entry
+ * points.  These should be enough for the client to emulate the SPI
+ * device just like the real hardware.
+ */
+struct sandbox_spi_emu_ops {
+       /* The bus wants to instantiate a new client, so setup everything */
+       int (*setup)(void **priv, const char *spec);
+       /* The bus is done with us, so break things down */
+       void (*free)(void *priv);
+       /* The CS has been "activated" -- we won't worry about low/high */
+       void (*cs_activate)(void *priv);
+       /* The CS has been "deactivated" -- we won't worry about low/high */
+       void (*cs_deactivate)(void *priv);
+       /* The client is rx-ing bytes from the bus, so it should tx some */
+       int (*xfer)(void *priv, const u8 *rx, u8 *tx, uint bytes);
+};
+
+/*
+ * There are times when the data lines are allowed to tristate.  What
+ * is actually sensed on the line depends on the hardware.  It could
+ * always be 0xFF/0x00 (if there are pull ups/downs), or things could
+ * float and so we'd get garbage back.  This func encapsulates that
+ * scenario so we can worry about the details here.
+ */
+static inline void sandbox_spi_tristate(u8 *buf, uint len)
+{
+       /* XXX: make this into a user config option ? */
+       memset(buf, 0xff, len);
+}
+
+/*
+ * Extract the bus/cs from the spi spec and return the start of the spi
+ * client spec.  If the bus/cs are invalid for the current config, then
+ * it returns NULL.
+ *
+ * Example: arg="0:1:foo" will set bus to 0, cs to 1, and return "foo"
+ */
+const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus,
+                                  unsigned long *cs);
+
+#endif
index 093c81d91816170c50d751fd354495b08aeb1c38..a38820bdeeb919180497b1d73d8078c12cd56edc 100644 (file)
@@ -15,6 +15,11 @@ enum exit_type_id {
        STATE_EXIT_POWER_OFF,
 };
 
+struct sandbox_spi_info {
+       const char *spec;
+       const struct sandbox_spi_emu_ops *ops;
+};
+
 /* The complete state of the test system */
 struct sandbox_state {
        const char *cmd;                /* Command to execute */
@@ -23,6 +28,10 @@ struct sandbox_state {
        const char *parse_err;          /* Error to report from parsing */
        int argc;                       /* Program arguments */
        char **argv;
+
+       /* Pointer to information for each SPI bus/cs */
+       struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
+                                       [CONFIG_SANDBOX_SPI_MAX_CS];
 };
 
 /**
index 968655c1b3474454e5f5b78eb9b9b6abbd6287e8..7c915b036f35303ad2b2e0b49c3dc7f842c86691 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <i2c.h>
 #include <asm/fsl_law.h>
 #include <fsl_ddr_sdram.h>
 #include <fsl_ddr_dimm_params.h>
@@ -92,3 +93,15 @@ void fsl_ddr_board_options(memctl_options_t *popts,
                popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;
        }
 }
+
+void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
+{
+       int ret = i2c_read(i2c_address, 0, 2, (uint8_t *)spd,
+                               sizeof(generic_spd_eeprom_t));
+
+       if (ret) {
+               printf("DDR: failed to read SPD from address %u\n",
+                               i2c_address);
+               memset(spd, 0, sizeof(generic_spd_eeprom_t));
+       }
+}
index 6bcc883b100c5212ee40e932eb0d656fd0dec718..6aa0509823cda08eb563334c1d2011ad46c19ad7 100644 (file)
@@ -150,8 +150,6 @@ int power_init_board(void)
 
        set_ps_hold_ctrl();
 
-       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-
        if (pmic_init(I2C_PMIC))
                return -1;
 
index 6bd106ed502d6eb4d7d923ebc37d7bd38c9c7f0b..8aba51c009fd2175f2f36e7b92b52708ca48b74a 100644 (file)
@@ -57,15 +57,18 @@ int board_init(void)
 
 void i2c_init_board(void)
 {
-       struct exynos4_gpio_part1 *gpio1 =
-               (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
+       int err;
        struct exynos4_gpio_part2 *gpio2 =
                (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
 
-       /* I2C_5 -> PMIC -> Adapter 0 */
-       s5p_gpio_direction_output(&gpio1->b, 7, 1);
-       s5p_gpio_direction_output(&gpio1->b, 6, 1);
-       /* I2C_9 -> FG -> Adapter 1 */
+       /* I2C_5 -> PMIC */
+       err = exynos_pinmux_config(PERIPH_ID_I2C5, PINMUX_FLAG_NONE);
+       if (err) {
+               debug("I2C%d not configured\n", (I2C_5));
+               return;
+       }
+
+       /* I2C_8 -> FG */
        s5p_gpio_direction_output(&gpio2->y4, 0, 1);
        s5p_gpio_direction_output(&gpio2->y4, 1, 1);
 }
@@ -290,10 +293,10 @@ int power_init_board(void)
         * The FUEL_GAUGE is marked as I2C9 on the schematic, but connected
         * to logical I2C adapter 1
         */
-       ret = pmic_init(I2C_0);
+       ret = pmic_init(I2C_5);
        ret |= pmic_init_max8997();
-       ret |= power_fg_init(I2C_1);
-       ret |= power_muic_init(I2C_0);
+       ret |= power_fg_init(I2C_8);
+       ret |= power_muic_init(I2C_5);
        ret |= power_bat_init(0);
        if (ret)
                return ret;
index 9552522001cc84a77235fba532b6685ecfebf58c..147de179cc60accfc785aeb9e4f60c1f6b77f2bc 100644 (file)
@@ -118,12 +118,17 @@ static void board_external_gpio_init(void)
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 static void board_init_i2c(void)
 {
+       int err;
+
        gpio1 = (struct exynos4x12_gpio_part1 *)samsung_get_base_gpio_part1();
        gpio2 = (struct exynos4x12_gpio_part2 *)samsung_get_base_gpio_part2();
 
        /* I2C_7 */
-       s5p_gpio_direction_output(&gpio1->d0, 2, 1);
-       s5p_gpio_direction_output(&gpio1->d0, 3, 1);
+       err = exynos_pinmux_config(PERIPH_ID_I2C7, PINMUX_FLAG_NONE);
+       if (err) {
+               debug("I2C%d not configured\n", (I2C_7));
+               return;
+       }
 
        /* I2C_8 */
        s5p_gpio_direction_output(&gpio1->f1, 4, 1);
@@ -135,6 +140,24 @@ static void board_init_i2c(void)
 }
 #endif
 
+#ifdef CONFIG_SYS_I2C_SOFT
+int get_soft_i2c_scl_pin(void)
+{
+       if (I2C_ADAP_HWNR)
+               return exynos4x12_gpio_part2_get_nr(m2, 1); /* I2C9 */
+       else
+               return exynos4x12_gpio_part1_get_nr(f1, 4); /* I2C8 */
+}
+
+int get_soft_i2c_sda_pin(void)
+{
+       if (I2C_ADAP_HWNR)
+               return exynos4x12_gpio_part2_get_nr(m2, 0); /* I2C9 */
+       else
+               return exynos4x12_gpio_part1_get_nr(f1, 5); /* I2C8 */
+}
+#endif
+
 int board_early_init_f(void)
 {
        check_hw_revision();
@@ -170,11 +193,11 @@ int power_init_board(void)
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
        board_init_i2c();
 #endif
-       pmic_init(I2C_0);               /* I2C adapter 0 - bus name I2C_5 */
+       pmic_init(I2C_7);               /* I2C adapter 7 - bus name s3c24x0_7 */
        pmic_init_max77686();
-       pmic_init_max77693(I2C_2);      /* I2C adapter 2 - bus name I2C_10 */
-       power_muic_init(I2C_2);         /* I2C adapter 2 - bus name I2C_10 */
-       power_fg_init(I2C_1);           /* I2C adapter 1 - bus name I2C_9 */
+       pmic_init_max77693(I2C_9);      /* I2C adapter 9 - bus name soft1 */
+       power_muic_init(I2C_9);         /* I2C adapter 9 - bus name soft1 */
+       power_fg_init(I2C_8);           /* I2C adapter 8 - bus name soft0 */
        power_bat_init(0);
 
        p_chrg = pmic_get("MAX77693_PMIC");
index 30b05416a7681bbf89037bc3c8229733af75bea7..69895574ffd5af74481ce39fb4ef108bec7c50d5 100644 (file)
@@ -31,6 +31,60 @@ the console. It does not set the terminal into raw mode, so cursor keys and
 history will not work yet.
 
 
+SPI Emulation
+-------------
+
+Sandbox supports SPI and SPI flash emulation.
+
+This is controlled by the spi_sf argument, the format of which is:
+
+   bus:cs:device:file
+
+   bus    - SPI bus number
+   cs     - SPI chip select number
+   device - SPI device emulation name
+   file   - File on disk containing the data
+
+For example:
+
+ dd if=/dev/zero of=spi.bin bs=1M count=4
+ ./u-boot --spi_sf 0:0:M25P16:spi.bin
+
+With this setup you can issue SPI flash commands as normal:
+
+=>sf probe
+SF: Detected M25P16 with page size 64 KiB, total 2 MiB
+=>sf read 0 0 10000
+SF: 65536 bytes @ 0x0 Read: OK
+=>
+
+Since this is a full SPI emulation (rather than just flash), you can
+also use low-level SPI commands:
+
+=>sspi 0:0 32 9f
+FF202015
+
+This is issuing a READ_ID command and getting back 20 (ST Micro) part
+0x2015 (the M25P16).
+
+Drivers are connected to a particular bus/cs using sandbox's state
+structure (see the 'spi' member). A set of operations must be provided
+for each driver.
+
+
+Configuration settings for the curious are:
+
+CONFIG_SANDBOX_SPI_MAX_BUS
+       The maximum number of SPI buses supported by the driver (default 1).
+
+CONFIG_SANDBOX_SPI_MAX_CS
+       The maximum number of chip selects supported by the driver
+       (default 10).
+
+CONFIG_SPI_IDLE_VAL
+       The idle value on the SPI bus
+
+
 Tests
 -----
 
index 02539c40a005793efc18cadaf1722fa8b7aec78e..39248054f8d4e2dc22b65bc1b7da33e9e4d6ccf3 100644 (file)
@@ -161,7 +161,7 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt
 #if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
                spi_read (addr, alen, buffer, len);
 #else
-               if (i2c_read (addr[0], addr[1], alen-1, buffer, len) != 0)
+               if (i2c_read(addr[0], offset, alen - 1, buffer, len))
                        rcode = 1;
 #endif
                buffer += len;
@@ -339,7 +339,7 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
                /* Write is enabled ... now write eeprom value.
                 */
 #endif
-               if (i2c_write (addr[0], addr[1], alen-1, buffer, len) != 0)
+               if (i2c_write(addr[0], offset, alen - 1, buffer, len))
                        rcode = 1;
 
 #endif
diff --git a/doc/SPI/README.sandbox-spi b/doc/SPI/README.sandbox-spi
new file mode 100644 (file)
index 0000000..bb73eaf
--- /dev/null
@@ -0,0 +1,64 @@
+Sandbox SPI/SPI Flash Implementation
+====================================
+
+U-Boot supports SPI and SPI flash emuation in sandbox. This must be enabled
+using the --spi_sf paramter when starting U-Boot.
+
+For example:
+
+$ make O=sandbox sandbox_config
+$ make O=sandbox
+$ ./sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin
+
+The four parameters to spi_sf are:
+
+   SPI bus number (typically 0)
+   SPI chip select number (typically 0)
+   SPI chip to emulate
+   File containing emulated data
+
+Supported chips are W25Q16 (2MB), W25Q32 (4MB) and W25Q128 (16MB). Once
+U-Boot it started you can use 'sf' commands as normal. For example:
+
+$ ./b/sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin \
+       -c "sf probe; sf test 0 100000; sf read 0 1000 1000; \
+               sf erase 1000 1000; sf write 0 1000 1000"
+
+
+U-Boot 2013.10-00237-gd4e0fdb (Nov 07 2013 - 20:08:15)
+
+DRAM:  128 MiB
+Using default environment
+
+In:    serial
+Out:   serial
+Err:   serial
+SF: Detected W25Q128BV with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+SPI flash test:
+0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
+1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
+2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
+3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
+Test passed
+0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
+1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
+2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
+3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
+SF: 4096 bytes @ 0x1000 Read: OK
+SF: 4096 bytes @ 0x1000 Erased: OK
+SF: 4096 bytes @ 0x1000 Written: OK
+
+
+Since the SPI bus is fully implemented as well as the SPI flash connected to
+it, you can also use low-level SPI commands to access the flash. For example
+this reads the device ID from the emulated chip:
+
+=> sspi 0 32 9f
+FFEF4018
+
+
+Simon Glass
+sjg@chromium.org
+7/11/2013
+Note that the sandbox SPI implementation was written by Mike Frysinger
+<vapier@gentoo.org>.
diff --git a/doc/device-tree-bindings/spi/spi-bus.txt b/doc/device-tree-bindings/spi/spi-bus.txt
new file mode 100644 (file)
index 0000000..800dafe
--- /dev/null
@@ -0,0 +1,92 @@
+SPI (Serial Peripheral Interface) busses
+
+SPI busses can be described with a node for the SPI master device
+and a set of child nodes for each SPI slave on the bus.  For this
+discussion, it is assumed that the system's SPI controller is in
+SPI master mode.  This binding does not describe SPI controllers
+in slave mode.
+
+The SPI master node requires the following properties:
+- #address-cells  - number of cells required to define a chip select
+               address on the SPI bus.
+- #size-cells     - should be zero.
+- compatible      - name of SPI bus controller following generic names
+               recommended practice.
+- cs-gpios       - (optional) gpios chip select.
+No other properties are required in the SPI bus node.  It is assumed
+that a driver for an SPI bus device will understand that it is an SPI bus.
+However, the binding does not attempt to define the specific method for
+assigning chip select numbers.  Since SPI chip select configuration is
+flexible and non-standardized, it is left out of this binding with the
+assumption that board specific platform code will be used to manage
+chip selects.  Individual drivers can define additional properties to
+support describing the chip select layout.
+
+Optional property:
+- num-cs : total number of chipselects
+
+If cs-gpios is used the number of chip select will automatically increased
+with max(cs-gpios > hw cs)
+
+So if for example the controller has 2 CS lines, and the cs-gpios
+property looks like this:
+
+cs-gpios = <&gpio1 0 0> <0> <&gpio1 1 0> <&gpio1 2 0>;
+
+Then it should be configured so that num_chipselect = 4 with the
+following mapping:
+
+cs0 : &gpio1 0 0
+cs1 : native
+cs2 : &gpio1 1 0
+cs3 : &gpio1 2 0
+
+SPI slave nodes must be children of the SPI master node and can
+contain the following properties.
+- reg             - (required) chip select address of device.
+- compatible      - (required) name of SPI device following generic names
+               recommended practice
+- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz
+- spi-cpol        - (optional) Empty property indicating device requires
+               inverse clock polarity (CPOL) mode
+- spi-cpha        - (optional) Empty property indicating device requires
+               shifted clock phase (CPHA) mode
+- spi-cs-high     - (optional) Empty property indicating device requires
+               chip select active high
+- spi-3wire       - (optional) Empty property indicating device requires
+                   3-wire mode.
+- spi-tx-bus-width - (optional) The bus width(number of data wires) that
+                      used for MOSI. Defaults to 1 if not present.
+- spi-rx-bus-width - (optional) The bus width(number of data wires) that
+                      used for MISO. Defaults to 1 if not present.
+
+Some SPI controllers and devices support Dual and Quad SPI transfer mode.
+It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD).
+Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is
+only 1(SINGLE), 2(DUAL) and 4(QUAD).
+Dual/Quad mode is not allowed when 3-wire mode is used.
+
+If a gpio chipselect is used for the SPI slave the gpio number will be passed
+via the cs_gpio
+
+SPI example for an MPC5200 SPI bus:
+       spi@f00 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
+               reg = <0xf00 0x20>;
+               interrupts = <2 13 0 2 14 0>;
+               interrupt-parent = <&mpc5200_pic>;
+
+               ethernet-switch@0 {
+                       compatible = "micrel,ks8995m";
+                       spi-max-frequency = <1000000>;
+                       reg = <0>;
+               };
+
+               codec@1 {
+                       compatible = "ti,tlv320aic26";
+                       spi-max-frequency = <100000>;
+                       reg = <1>;
+               };
+       };
index 553b519cca37de74419d6a91b20e2414be106ef2..fa3a875705b83c0216de2e08079d2cfb78e6d0d6 100644 (file)
@@ -12,7 +12,6 @@ obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 obj-$(CONFIG_I2C_MV) += mv_i2c.o
 obj-$(CONFIG_I2C_MXS) += mxs_i2c.o
 obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
-obj-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o
 obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
 obj-$(CONFIG_U8500_I2C) += u8500_i2c.o
 obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
@@ -24,6 +23,7 @@ obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o
 obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o
 obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o
 obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o
+obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
 obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
 obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
index ddeb941fafbc81b981b17006ab4848ce0c99b592..fb9fa353d108c48e145e567f1d25a14d0f8d9341 100644 (file)
 
 #include "fti2c010.h"
 
-#ifndef CONFIG_HARD_I2C
-#error "fti2c010: CONFIG_HARD_I2C is not defined"
+#ifndef CONFIG_SYS_I2C_SPEED
+#define CONFIG_SYS_I2C_SPEED    5000
 #endif
 
-#ifndef CONFIG_SYS_I2C_SPEED
-#define CONFIG_SYS_I2C_SPEED    50000
+#ifndef CONFIG_SYS_I2C_SLAVE
+#define CONFIG_SYS_I2C_SLAVE    0
 #endif
 
-#ifndef CONFIG_FTI2C010_FREQ
-#define CONFIG_FTI2C010_FREQ    clk_get_rate("I2C")
+#ifndef CONFIG_FTI2C010_CLOCK
+#define CONFIG_FTI2C010_CLOCK   clk_get_rate("I2C")
 #endif
 
-/* command timeout */
-#define CFG_CMD_TIMEOUT         10 /* ms */
+#ifndef CONFIG_FTI2C010_TIMEOUT
+#define CONFIG_FTI2C010_TIMEOUT 10 /* ms */
+#endif
 
-/* 7-bit chip address + 1-bit read/write */
-#define I2C_RD(chip)            ((((chip) << 1) & 0xff) | 1)
-#define I2C_WR(chip)            (((chip) << 1) & 0xff)
+/* 7-bit dev address + 1-bit read/write */
+#define I2C_RD(dev)             ((((dev) << 1) & 0xfe) | 1)
+#define I2C_WR(dev)             (((dev) << 1) & 0xfe)
 
 struct fti2c010_chip {
-       void __iomem *regs;
-       uint bus;
-       uint speed;
+       struct fti2c010_regs *regs;
 };
 
 static struct fti2c010_chip chip_list[] = {
        {
-               .bus  = 0,
-               .regs = (void __iomem *)CONFIG_FTI2C010_BASE,
+               .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE,
        },
-#ifdef CONFIG_I2C_MULTI_BUS
-# ifdef CONFIG_FTI2C010_BASE1
+#ifdef CONFIG_FTI2C010_BASE1
        {
-               .bus  = 1,
-               .regs = (void __iomem *)CONFIG_FTI2C010_BASE1,
+               .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE1,
        },
-# endif
-# ifdef CONFIG_FTI2C010_BASE2
+#endif
+#ifdef CONFIG_FTI2C010_BASE2
        {
-               .bus  = 2,
-               .regs = (void __iomem *)CONFIG_FTI2C010_BASE2,
+               .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE2,
        },
-# endif
-# ifdef CONFIG_FTI2C010_BASE3
+#endif
+#ifdef CONFIG_FTI2C010_BASE3
        {
-               .bus  = 3,
-               .regs = (void __iomem *)CONFIG_FTI2C010_BASE3,
+               .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE3,
        },
-# endif
-#endif  /* #ifdef CONFIG_I2C_MULTI_BUS */
+#endif
 };
 
-static struct fti2c010_chip *curr = chip_list;
+static int fti2c010_reset(struct fti2c010_chip *chip)
+{
+       ulong ts;
+       int ret = -1;
+       struct fti2c010_regs *regs = chip->regs;
+
+       writel(CR_I2CRST, &regs->cr);
+       for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) {
+               if (!(readl(&regs->cr) & CR_I2CRST)) {
+                       ret = 0;
+                       break;
+               }
+       }
 
-static int fti2c010_wait(uint32_t mask)
+       if (ret)
+               printf("fti2c010: reset timeout\n");
+
+       return ret;
+}
+
+static int fti2c010_wait(struct fti2c010_chip *chip, uint32_t mask)
 {
        int ret = -1;
        uint32_t stat, ts;
-       struct fti2c010_regs *regs = curr->regs;
+       struct fti2c010_regs *regs = chip->regs;
 
-       for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
+       for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) {
                stat = readl(&regs->sr);
                if ((stat & mask) == mask) {
                        ret = 0;
@@ -84,88 +95,124 @@ static int fti2c010_wait(uint32_t mask)
        return ret;
 }
 
-/*
- * u-boot I2C API
- */
+static unsigned int set_i2c_bus_speed(struct fti2c010_chip *chip,
+       unsigned int speed)
+{
+       struct fti2c010_regs *regs = chip->regs;
+       unsigned int clk = CONFIG_FTI2C010_CLOCK;
+       unsigned int gsr = 0;
+       unsigned int tsr = 32;
+       unsigned int div, rate;
+
+       for (div = 0; div < 0x3ffff; ++div) {
+               /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */
+               rate = clk / (2 * (div + 2) + gsr);
+               if (rate <= speed)
+                       break;
+       }
+
+       writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), &regs->tgsr);
+       writel(CDR_DIV(div), &regs->cdr);
+
+       return rate;
+}
 
 /*
  * Initialization, must be called once on start up, may be called
  * repeatedly to change the speed and slave addresses.
  */
-void i2c_init(int speed, int slaveaddr)
+static void fti2c010_init(struct i2c_adapter *adap, int speed, int slaveaddr)
 {
-       if (speed || !curr->speed)
-               i2c_set_bus_speed(speed);
+       struct fti2c010_chip *chip = chip_list + adap->hwadapnr;
 
-       /* if slave mode disabled */
-       if (!slaveaddr)
+       if (adap->init_done)
                return;
 
-       /*
-        * TODO:
-        * Implement slave mode, but is it really necessary?
-        */
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+       /* Call board specific i2c bus reset routine before accessing the
+        * environment, which might be in a chip on that bus. For details
+        * about this problem see doc/I2C_Edge_Conditions.
+       */
+       i2c_init_board();
+#endif
+
+       /* master init */
+
+       fti2c010_reset(chip);
+
+       set_i2c_bus_speed(chip, speed);
+
+       /* slave init, don't care */
+
+#ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT
+       /* Call board specific i2c bus reset routine AFTER the bus has been
+        * initialized. Use either this callpoint or i2c_init_board;
+        * which is called before fti2c010_init operations.
+        * For details about this problem see doc/I2C_Edge_Conditions.
+       */
+       i2c_board_late_init();
+#endif
 }
 
 /*
  * Probe the given I2C chip address.  Returns 0 if a chip responded,
  * not 0 on failure.
  */
-int i2c_probe(uchar chip)
+static int fti2c010_probe(struct i2c_adapter *adap, u8 dev)
 {
+       struct fti2c010_chip *chip = chip_list + adap->hwadapnr;
+       struct fti2c010_regs *regs = chip->regs;
        int ret;
-       struct fti2c010_regs *regs = curr->regs;
-
-       i2c_init(0, 0);
 
        /* 1. Select slave device (7bits Address + 1bit R/W) */
-       writel(I2C_WR(chip), &regs->dr);
+       writel(I2C_WR(dev), &regs->dr);
        writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
-       ret = fti2c010_wait(SR_DT);
+       ret = fti2c010_wait(chip, SR_DT);
        if (ret)
                return ret;
 
        /* 2. Select device register */
        writel(0, &regs->dr);
        writel(CR_ENABLE | CR_TBEN, &regs->cr);
-       ret = fti2c010_wait(SR_DT);
+       ret = fti2c010_wait(chip, SR_DT);
 
        return ret;
 }
 
-/*
- * Read/Write interface:
- *   chip:    I2C chip address, range 0..127
- *   addr:    Memory (register) address within the chip
- *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
- *              memories, 0 for register type devices with only one
- *              register)
- *   buffer:  Where to read/write the data
- *   len:     How many bytes to read/write
- *
- *   Returns: 0 on success, not 0 on failure
- */
-int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+static void to_i2c_addr(u8 *buf, uint32_t addr, int alen)
+{
+       int i, shift;
+
+       if (!buf || alen <= 0)
+               return;
+
+       /* MSB first */
+       i = 0;
+       shift = (alen - 1) * 8;
+       while (alen-- > 0) {
+               buf[i] = (u8)(addr >> shift);
+               shift -= 8;
+       }
+}
+
+static int fti2c010_read(struct i2c_adapter *adap,
+                       u8 dev, uint addr, int alen, uchar *buf, int len)
 {
+       struct fti2c010_chip *chip = chip_list + adap->hwadapnr;
+       struct fti2c010_regs *regs = chip->regs;
        int ret, pos;
        uchar paddr[4];
-       struct fti2c010_regs *regs = curr->regs;
 
-       i2c_init(0, 0);
-
-       paddr[0] = (addr >> 0)  & 0xFF;
-       paddr[1] = (addr >> 8)  & 0xFF;
-       paddr[2] = (addr >> 16) & 0xFF;
-       paddr[3] = (addr >> 24) & 0xFF;
+       to_i2c_addr(paddr, addr, alen);
 
        /*
         * Phase A. Set register address
         */
 
        /* A.1 Select slave device (7bits Address + 1bit R/W) */
-       writel(I2C_WR(chip), &regs->dr);
+       writel(I2C_WR(dev), &regs->dr);
        writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
-       ret = fti2c010_wait(SR_DT);
+       ret = fti2c010_wait(chip, SR_DT);
        if (ret)
                return ret;
 
@@ -175,7 +222,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 
                writel(paddr[pos], &regs->dr);
                writel(ctrl, &regs->cr);
-               ret = fti2c010_wait(SR_DT);
+               ret = fti2c010_wait(chip, SR_DT);
                if (ret)
                        return ret;
        }
@@ -185,9 +232,9 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
         */
 
        /* B.1 Select slave device (7bits Address + 1bit R/W) */
-       writel(I2C_RD(chip), &regs->dr);
+       writel(I2C_RD(dev), &regs->dr);
        writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
-       ret = fti2c010_wait(SR_DT);
+       ret = fti2c010_wait(chip, SR_DT);
        if (ret)
                return ret;
 
@@ -201,7 +248,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
                        stat |= SR_ACK;
                }
                writel(ctrl, &regs->cr);
-               ret = fti2c010_wait(stat);
+               ret = fti2c010_wait(chip, stat);
                if (ret)
                        break;
                buf[pos] = (uchar)(readl(&regs->dr) & 0xFF);
@@ -210,39 +257,24 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
        return ret;
 }
 
-/*
- * Read/Write interface:
- *   chip:    I2C chip address, range 0..127
- *   addr:    Memory (register) address within the chip
- *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
- *              memories, 0 for register type devices with only one
- *              register)
- *   buffer:  Where to read/write the data
- *   len:     How many bytes to read/write
- *
- *   Returns: 0 on success, not 0 on failure
- */
-int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
+static int fti2c010_write(struct i2c_adapter *adap,
+                       u8 dev, uint addr, int alen, u8 *buf, int len)
 {
+       struct fti2c010_chip *chip = chip_list + adap->hwadapnr;
+       struct fti2c010_regs *regs = chip->regs;
        int ret, pos;
        uchar paddr[4];
-       struct fti2c010_regs *regs = curr->regs;
 
-       i2c_init(0, 0);
-
-       paddr[0] = (addr >> 0)  & 0xFF;
-       paddr[1] = (addr >> 8)  & 0xFF;
-       paddr[2] = (addr >> 16) & 0xFF;
-       paddr[3] = (addr >> 24) & 0xFF;
+       to_i2c_addr(paddr, addr, alen);
 
        /*
         * Phase A. Set register address
         *
         * A.1 Select slave device (7bits Address + 1bit R/W)
         */
-       writel(I2C_WR(chip), &regs->dr);
+       writel(I2C_WR(dev), &regs->dr);
        writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
-       ret = fti2c010_wait(SR_DT);
+       ret = fti2c010_wait(chip, SR_DT);
        if (ret)
                return ret;
 
@@ -252,7 +284,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 
                writel(paddr[pos], &regs->dr);
                writel(ctrl, &regs->cr);
-               ret = fti2c010_wait(SR_DT);
+               ret = fti2c010_wait(chip, SR_DT);
                if (ret)
                        return ret;
        }
@@ -267,7 +299,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
                        ctrl |= CR_STOP;
                writel(buf[pos], &regs->dr);
                writel(ctrl, &regs->cr);
-               ret = fti2c010_wait(SR_DT);
+               ret = fti2c010_wait(chip, SR_DT);
                if (ret)
                        break;
        }
@@ -275,94 +307,40 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
        return ret;
 }
 
-/*
- * Functions for setting the current I2C bus and its speed
- */
-#ifdef CONFIG_I2C_MULTI_BUS
-
-/*
- * i2c_set_bus_num:
- *
- *  Change the active I2C bus.  Subsequent read/write calls will
- *  go to this one.
- *
- *    bus - bus index, zero based
- *
- *    Returns: 0 on success, not 0 on failure
- */
-int i2c_set_bus_num(uint bus)
-{
-       if (bus >= ARRAY_SIZE(chip_list))
-               return -1;
-       curr = chip_list + bus;
-       i2c_init(0, 0);
-       return 0;
-}
-
-/*
- * i2c_get_bus_num:
- *
- *  Returns index of currently active I2C bus.  Zero-based.
- */
-
-uint i2c_get_bus_num(void)
-{
-       return curr->bus;
-}
-
-#endif    /* #ifdef CONFIG_I2C_MULTI_BUS */
-
-/*
- * i2c_set_bus_speed:
- *
- *  Change the speed of the active I2C bus
- *
- *    speed - bus speed in Hz
- *
- *    Returns: 0 on success, not 0 on failure
- */
-int i2c_set_bus_speed(uint speed)
+static unsigned int fti2c010_set_bus_speed(struct i2c_adapter *adap,
+                       unsigned int speed)
 {
-       struct fti2c010_regs *regs = curr->regs;
-       uint clk = CONFIG_FTI2C010_FREQ;
-       uint gsr = 0, tsr = 32;
-       uint spd, div;
-
-       if (!speed)
-               speed = CONFIG_SYS_I2C_SPEED;
-
-       for (div = 0; div < 0x3ffff; ++div) {
-               /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */
-               spd = clk / (2 * (div + 2) + gsr);
-               if (spd <= speed)
-                       break;
-       }
-
-       if (curr->speed == spd)
-               return 0;
-
-       writel(CR_I2CRST, &regs->cr);
-       mdelay(100);
-       if (readl(&regs->cr) & CR_I2CRST) {
-               printf("fti2c010: reset timeout\n");
-               return -1;
-       }
+       struct fti2c010_chip *chip = chip_list + adap->hwadapnr;
+       int ret;
 
-       curr->speed = spd;
+       fti2c010_reset(chip);
+       ret = set_i2c_bus_speed(chip, speed);
 
-       writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), &regs->tgsr);
-       writel(CDR_DIV(div), &regs->cdr);
-
-       return 0;
+       return ret;
 }
 
 /*
- * i2c_get_bus_speed:
- *
- *  Returns speed of currently active I2C bus in Hz
+ * Register i2c adapters
  */
-
-uint i2c_get_bus_speed(void)
-{
-       return curr->speed;
-}
+U_BOOT_I2C_ADAP_COMPLETE(i2c_0, fti2c010_init, fti2c010_probe, fti2c010_read,
+                       fti2c010_write, fti2c010_set_bus_speed,
+                       CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
+                       0)
+#ifdef CONFIG_FTI2C010_BASE1
+U_BOOT_I2C_ADAP_COMPLETE(i2c_1, fti2c010_init, fti2c010_probe, fti2c010_read,
+                       fti2c010_write, fti2c010_set_bus_speed,
+                       CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
+                       1)
+#endif
+#ifdef CONFIG_FTI2C010_BASE2
+U_BOOT_I2C_ADAP_COMPLETE(i2c_2, fti2c010_init, fti2c010_probe, fti2c010_read,
+                       fti2c010_write, fti2c010_set_bus_speed,
+                       CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
+                       2)
+#endif
+#ifdef CONFIG_FTI2C010_BASE3
+U_BOOT_I2C_ADAP_COMPLETE(i2c_3, fti2c010_init, fti2c010_probe, fti2c010_read,
+                       fti2c010_write, fti2c010_set_bus_speed,
+                       CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
+                       3)
+#endif
index 3d38c035b67e5953507d509e928fc83acbe823f7..c7840049b11c707d1eaa9c90899f3d3120d22e2d 100644 (file)
@@ -158,7 +158,6 @@ static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
        udelay(1000);
        flush_fifo(adap);
        writew(0xFFFF, &i2c_base->stat);
-       writew(0, &i2c_base->cnt);
 }
 
 static void flush_fifo(struct i2c_adapter *adap)
@@ -198,8 +197,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
                return res;
 
        /* No data transfer, slave addr only */
-       writew(0, &i2c_base->cnt);
-       /* Set slave address */
        writew(chip, &i2c_base->sa);
        /* Stop bit needed here */
        writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
@@ -234,7 +231,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
 pr_exit:
        flush_fifo(adap);
        writew(0xFFFF, &i2c_base->stat);
-       writew(0, &i2c_base->cnt);
        return res;
 }
 
@@ -372,7 +368,6 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 rd_exit:
        flush_fifo(adap);
        writew(0xFFFF, &i2c_base->stat);
-       writew(0, &i2c_base->cnt);
        return i2c_error;
 }
 
@@ -473,7 +468,6 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 wr_exit:
        flush_fifo(adap);
        writew(0xFFFF, &i2c_base->stat);
-       writew(0, &i2c_base->cnt);
        return i2c_error;
 }
 
index f77a9d1a1ffd888a12dcc654e6e0ede940c25647..fd328f054940f3beb2214b76c4f103c9b06377a3 100644 (file)
@@ -23,8 +23,6 @@
 #include <i2c.h>
 #include "s3c24x0_i2c.h"
 
-#ifdef CONFIG_HARD_I2C
-
 #define        I2C_WRITE       0
 #define I2C_READ       1
 
  * For SPL boot some boards need i2c before SDRAM is initialised so force
  * variables to live in SRAM
  */
-static unsigned int g_current_bus __attribute__((section(".data")));
 static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
                        __attribute__((section(".data")));
 
@@ -254,17 +251,17 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c)
        writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon);
 }
 
-static struct s3c24x0_i2c *get_base_i2c(void)
+static struct s3c24x0_i2c *get_base_i2c(int bus)
 {
 #ifdef CONFIG_EXYNOS4
        struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()
                                                        + (EXYNOS4_I2C_SPACING
-                                                       * g_current_bus));
+                                                       * bus));
        return i2c;
 #elif defined CONFIG_EXYNOS5
        struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()
                                                        + (EXYNOS5_I2C_SPACING
-                                                       * g_current_bus));
+                                                       * bus));
        return i2c;
 #else
        return s3c24x0_get_base_i2c();
@@ -298,7 +295,6 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
        writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
 }
 
-#ifdef CONFIG_I2C_MULTI_BUS
 static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)
 {
        struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
@@ -307,8 +303,10 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)
        unsigned int i = 0, utemp0 = 0, utemp1 = 0;
        unsigned int t_ftl_cycle;
 
-#if defined CONFIG_EXYNOS5
+#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
        clkin = get_i2c_clk();
+#else
+       clkin = get_PCLK();
 #endif
        /* FPCLK / FI2C =
         * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
@@ -330,7 +328,6 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)
        }
        return -1;
 }
-#endif
 
 static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus)
 {
@@ -401,49 +398,18 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus)
        hsi2c_ch_init(i2c_bus);
 }
 
-/*
- * MULTI BUS I2C support
- */
-
-#ifdef CONFIG_I2C_MULTI_BUS
-int i2c_set_bus_num(unsigned int bus)
-{
-       struct s3c24x0_i2c_bus *i2c_bus;
-
-       i2c_bus = get_bus(bus);
-       if (!i2c_bus)
-               return -1;
-       g_current_bus = bus;
-
-       if (i2c_bus->is_highspeed) {
-               if (hsi2c_get_clk_details(i2c_bus))
-                       return -1;
-               hsi2c_ch_init(i2c_bus);
-       } else {
-               i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
-                                               CONFIG_SYS_I2C_SLAVE);
-       }
-
-       return 0;
-}
-
-unsigned int i2c_get_bus_num(void)
-{
-       return g_current_bus;
-}
-#endif
-
-void i2c_init(int speed, int slaveadd)
+static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 {
        struct s3c24x0_i2c *i2c;
+       struct s3c24x0_i2c_bus *bus;
+
 #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
        struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
 #endif
        ulong start_time = get_timer(0);
 
        /* By default i2c channel 0 is the current bus */
-       g_current_bus = 0;
-       i2c = get_base_i2c();
+       i2c = get_base_i2c(adap->hwadapnr);
 
        /*
         * In case the previous transfer is still going, wait to give it a
@@ -505,6 +471,10 @@ void i2c_init(int speed, int slaveadd)
        }
 #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
        i2c_ch_init(i2c, speed, slaveadd);
+
+       bus = &i2c_bus[adap->hwadapnr];
+       bus->active = true;
+       bus->regs = i2c;
 }
 
 /*
@@ -728,6 +698,40 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c,
        return rv;
 }
 
+static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap,
+                                         unsigned int speed)
+{
+       struct s3c24x0_i2c_bus *i2c_bus;
+
+       i2c_bus = get_bus(adap->hwadapnr);
+       if (!i2c_bus)
+               return -1;
+
+       i2c_bus->clock_frequency = speed;
+
+       if (i2c_bus->is_highspeed) {
+               if (hsi2c_get_clk_details(i2c_bus))
+                       return -1;
+               hsi2c_ch_init(i2c_bus);
+       } else {
+               i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
+                           CONFIG_SYS_I2C_S3C24X0_SLAVE);
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_EXYNOS5
+static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
+{
+       /* This will override the speed selected in the fdt for that port */
+       debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
+       if (i2c_set_bus_speed(speed))
+               printf("i2c_init: failed to init bus %d for speed = %d\n",
+                                               adap->hwadapnr, speed);
+}
+#endif
+
 /*
  * cmd_type is 0 for write, 1 for read.
  *
@@ -840,13 +844,13 @@ bailout:
        return result;
 }
 
-int i2c_probe(uchar chip)
+static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)
 {
        struct s3c24x0_i2c_bus *i2c_bus;
        uchar buf[1];
        int ret;
 
-       i2c_bus = get_bus(g_current_bus);
+       i2c_bus = get_bus(adap->hwadapnr);
        if (!i2c_bus)
                return -1;
        buf[0] = 0;
@@ -864,11 +868,11 @@ int i2c_probe(uchar chip)
                                I2C_READ, chip << 1, 0, 0, buf, 1);
        }
 
-
        return ret != I2C_OK;
 }
 
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
+                           int alen, uchar *buffer, int len)
 {
        struct s3c24x0_i2c_bus *i2c_bus;
        uchar xaddr[4];
@@ -902,7 +906,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
                chip |= ((addr >> (alen * 8)) &
                         CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
 #endif
-       i2c_bus = get_bus(g_current_bus);
+       i2c_bus = get_bus(adap->hwadapnr);
        if (!i2c_bus)
                return -1;
 
@@ -922,7 +926,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
        return 0;
 }
 
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
+                        int alen, uchar *buffer, int len)
 {
        struct s3c24x0_i2c_bus *i2c_bus;
        uchar xaddr[4];
@@ -955,7 +960,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
                chip |= ((addr >> (alen * 8)) &
                         CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
 #endif
-       i2c_bus = get_bus(g_current_bus);
+       i2c_bus = get_bus(adap->hwadapnr);
        if (!i2c_bus)
                return -1;
 
@@ -1001,8 +1006,8 @@ static void process_nodes(const void *blob, int node_list[], int count,
 
                bus->id = pinmux_decode_periph_id(blob, node);
                bus->clock_frequency = fdtdec_get_int(blob, node,
-                                                     "clock-frequency",
-                                                     CONFIG_SYS_I2C_SPEED);
+                                               "clock-frequency",
+                                               CONFIG_SYS_I2C_S3C24X0_SPEED);
                bus->node = node;
                bus->bus_num = i;
                exynos_pinmux_config(bus->id, 0);
@@ -1044,7 +1049,6 @@ int i2c_get_bus_num_fdt(int node)
        return -1;
 }
 
-#ifdef CONFIG_I2C_MULTI_BUS
 int i2c_reset_port_fdt(const void *blob, int node)
 {
        struct s3c24x0_i2c_bus *i2c_bus;
@@ -1068,12 +1072,178 @@ int i2c_reset_port_fdt(const void *blob, int node)
                hsi2c_ch_init(i2c_bus);
        } else {
                i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
-                                               CONFIG_SYS_I2C_SLAVE);
+                           CONFIG_SYS_I2C_S3C24X0_SLAVE);
        }
 
        return 0;
 }
 #endif
-#endif
 
-#endif /* CONFIG_HARD_I2C */
+/*
+ * Register s3c24x0 i2c adapters
+ */
+#if defined(CONFIG_EXYNOS5420)
+U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
+U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 1)
+U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 2)
+U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 3)
+U_BOOT_I2C_ADAP_COMPLETE(i2c04, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 4)
+U_BOOT_I2C_ADAP_COMPLETE(i2c05, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 5)
+U_BOOT_I2C_ADAP_COMPLETE(i2c06, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 6)
+U_BOOT_I2C_ADAP_COMPLETE(i2c07, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 7)
+U_BOOT_I2C_ADAP_COMPLETE(i2c08, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 8)
+U_BOOT_I2C_ADAP_COMPLETE(i2c09, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 9)
+U_BOOT_I2C_ADAP_COMPLETE(i2c10, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 10)
+#elif defined(CONFIG_EXYNOS5250)
+U_BOOT_I2C_ADAP_COMPLETE(i2c00, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
+U_BOOT_I2C_ADAP_COMPLETE(i2c01, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 1)
+U_BOOT_I2C_ADAP_COMPLETE(i2c02, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 2)
+U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 3)
+U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 4)
+U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 5)
+U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 6)
+U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 7)
+U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 8)
+U_BOOT_I2C_ADAP_COMPLETE(i2c09, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 9)
+U_BOOT_I2C_ADAP_COMPLETE(s3c10, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 10)
+#elif defined(CONFIG_EXYNOS4)
+U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
+U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 1)
+U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 2)
+U_BOOT_I2C_ADAP_COMPLETE(i2c03, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 3)
+U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 4)
+U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 5)
+U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 6)
+U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 7)
+U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 8)
+#else
+U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe,
+                       s3c24x0_i2c_read, s3c24x0_i2c_write,
+                       s3c24x0_i2c_set_bus_speed,
+                       CONFIG_SYS_I2C_S3C24X0_SPEED,
+                       CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
+#endif
index 202acf258b8d75de6ed328bd346262f230716f7b..2fc911025eeb5e01c76b9a9ace2eeabc6dbdc149 100644 (file)
@@ -135,8 +135,7 @@ int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob)
  */
 int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob)
 {
-       dev->spi = spi_setup_slave_fdt(blob, dev->parent_node,
-                                      dev->cs, dev->max_frequency, 0);
+       dev->spi = spi_setup_slave_fdt(blob, dev->parent_node, dev->node);
        if (!dev->spi) {
                debug("%s: Could not setup SPI slave\n", __func__);
                return -1;
index a7ae38dadcb35138f385e4bde274806ac7e6df0d..1ed26cab34f463c37c4f60dd3f749f43fd68e09e 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o
 obj-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o
 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
 obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
 obj-$(CONFIG_MMC_SPI) += mmc_spi.o
index 1e0f72bbe7dcb75bfeeb5ed0a035b3945bf463e3..19d9b0b899c83dd2470a9d03b10000e16149bc1e 100644 (file)
@@ -11,7 +11,6 @@
 #include <mmc.h>
 #include <dwmmc.h>
 #include <asm-generic/errno.h>
-#include <asm/arch/dwmmc.h>
 
 #define PAGE_SIZE 4096
 
@@ -300,17 +299,9 @@ static void dwmci_set_ios(struct mmc *mmc)
 static int dwmci_init(struct mmc *mmc)
 {
        struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
-       u32 fifo_size;
-
-       if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) {
-               dwmci_writel(host, EMMCP_MPSBEGIN0, 0);
-               dwmci_writel(host, EMMCP_SEND0, 0);
-               dwmci_writel(host, EMMCP_CTRL0,
-                            MPSCTRL_SECURE_READ_BIT |
-                            MPSCTRL_SECURE_WRITE_BIT |
-                            MPSCTRL_NON_SECURE_READ_BIT |
-                            MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID);
-       }
+
+       if (host->board_init)
+               host->board_init(host);
 
        dwmci_writel(host, DWMCI_PWREN, 1);
 
@@ -330,13 +321,9 @@ static int dwmci_init(struct mmc *mmc)
        dwmci_writel(host, DWMCI_IDINTEN, 0);
        dwmci_writel(host, DWMCI_BMOD, 1);
 
-       if (!host->fifoth_val) {
-               fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
-               fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
-               host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
-                       TX_WMARK(fifo_size / 2);
+       if (host->fifoth_val) {
+               dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
        }
-       dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
 
        dwmci_writel(host, DWMCI_CLKENA, 0);
        dwmci_writel(host, DWMCI_CLKSRC, 0);
index a0f1511cb6f308de404defef63383016bfd2d932..b3e5c5e5e09b5db5d04bfac1b8bd3093b9d3d655 100644 (file)
@@ -34,6 +34,19 @@ unsigned int exynos_dwmci_get_clk(int dev_index)
        return get_mmc_clk(dev_index);
 }
 
+static void exynos_dwmci_board_init(struct dwmci_host *host)
+{
+       if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) {
+               dwmci_writel(host, EMMCP_MPSBEGIN0, 0);
+               dwmci_writel(host, EMMCP_SEND0, 0);
+               dwmci_writel(host, EMMCP_CTRL0,
+                            MPSCTRL_SECURE_READ_BIT |
+                            MPSCTRL_SECURE_WRITE_BIT |
+                            MPSCTRL_NON_SECURE_READ_BIT |
+                            MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID);
+       }
+}
+
 /*
  * This function adds the mmc channel to be registered with mmc core.
  * index -     mmc channel number.
@@ -65,6 +78,7 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
 #ifdef CONFIG_EXYNOS5420
        host->quirks = DWMCI_QUIRK_DISABLE_SMU;
 #endif
+       host->board_init = exynos_dwmci_board_init;
 
        if (clksel) {
                host->clksel_val = clksel;
index 65c52a22db7f23af5fe584477093612179cf566b..8fc263f4f40b864d8c9c8090c88896a7995a2a87 100644 (file)
@@ -42,6 +42,10 @@ void __noreturn mmc_boot(void)
                hang();
        }
 
+#ifdef CONFIG_FSL_CORENET
+       offset = CONFIG_SYS_MMC_U_BOOT_OFFS;
+       code_len = CONFIG_SYS_MMC_U_BOOT_SIZE;
+#else
        blklen = mmc->read_bl_len;
        tmp_buf = malloc(blklen);
        if (!tmp_buf) {
@@ -91,6 +95,7 @@ void __noreturn mmc_boot(void)
        /*
        * Load U-Boot image from mmc into RAM
        */
+#endif
        blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
        blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len;
        err = mmc->block_dev.block_read(0, blk_start, blk_cnt,
diff --git a/drivers/mmc/ftsdc021_sdhci.c b/drivers/mmc/ftsdc021_sdhci.c
new file mode 100644 (file)
index 0000000..1f6cdba
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2013 Faraday Technology
+ * Kuo-Jung Su <dantesu@faraday-tech.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <sdhci.h>
+
+#ifndef CONFIG_FTSDC021_CLOCK
+#define CONFIG_FTSDC021_CLOCK   clk_get_rate("MMC")
+#endif
+
+int ftsdc021_sdhci_init(u32 regbase)
+{
+       struct sdhci_host *host = NULL;
+       uint32_t freq = CONFIG_FTSDC021_CLOCK;
+
+       host = calloc(1, sizeof(struct sdhci_host));
+       if (!host) {
+               puts("sdh_host malloc fail!\n");
+               return 1;
+       }
+
+       host->name = "FTSDC021";
+       host->ioaddr = (void __iomem *)regbase;
+       host->quirks = 0;
+       add_sdhci(host, freq, 0);
+
+       return 0;
+}
index 1bbeb7da3b802173f5a920604212b9052e19170f..26483a23f791e645fca8e81e3c1237286d3e87d4 100644 (file)
@@ -13,4 +13,5 @@ endif
 obj-$(CONFIG_CMD_SF)        += sf.o
 obj-$(CONFIG_SPI_FLASH) += sf_probe.o sf_ops.o
 obj-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.o
+obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
 obj-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
index 6263d8c2217e5385bce3f3778b6c774215c0002b..e5ac79b9520db5e975575229e74266015f099997 100644 (file)
@@ -31,6 +31,10 @@ void spi_boot(void)
                hang();
        }
 
+#ifdef CONFIG_FSL_CORENET
+       offset = CONFIG_SYS_SPI_FLASH_U_BOOT_OFFS;
+       code_len = CONFIG_SYS_SPI_FLASH_U_BOOT_SIZE;
+#else
        /*
        * Load U-Boot image from SPI flash into RAM
        */
@@ -50,6 +54,7 @@ void spi_boot(void)
        code_len = *(u32 *)(buf + ESPI_BOOT_IMAGE_SIZE);
        /* Skip spl code */
        code_len = code_len - CONFIG_SPL_MAX_SIZE;
+#endif
        /* copy code to DDR */
        spi_flash_read(flash, offset, code_len,
                       (void *)CONFIG_SYS_SPI_FLASH_U_BOOT_DST);
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
new file mode 100644 (file)
index 0000000..a62ef4c
--- /dev/null
@@ -0,0 +1,483 @@
+/*
+ * Simulate a SPI flash
+ *
+ * Copyright (c) 2011-2013 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+#include <os.h>
+
+#include <spi_flash.h>
+#include "sf_internal.h"
+
+#include <asm/getopt.h>
+#include <asm/spi.h>
+#include <asm/state.h>
+
+/*
+ * The different states that our SPI flash transitions between.
+ * We need to keep track of this across multiple xfer calls since
+ * the SPI bus could possibly call down into us multiple times.
+ */
+enum sandbox_sf_state {
+       SF_CMD,   /* default state -- we're awaiting a command */
+       SF_ID,    /* read the flash's (jedec) ID code */
+       SF_ADDR,  /* processing the offset in the flash to read/etc... */
+       SF_READ,  /* reading data from the flash */
+       SF_WRITE, /* writing data to the flash, i.e. page programming */
+       SF_ERASE, /* erase the flash */
+       SF_READ_STATUS, /* read the flash's status register */
+       SF_READ_STATUS1, /* read the flash's status register upper 8 bits*/
+};
+
+static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
+{
+       static const char * const states[] = {
+               "CMD", "ID", "ADDR", "READ", "WRITE", "ERASE", "READ_STATUS",
+       };
+       return states[state];
+}
+
+/* Bits for the status register */
+#define STAT_WIP       (1 << 0)
+#define STAT_WEL       (1 << 1)
+
+/* Assume all SPI flashes have 3 byte addresses since they do atm */
+#define SF_ADDR_LEN    3
+
+struct sandbox_spi_flash_erase_commands {
+       u8 cmd;
+       u32 size;
+};
+#define IDCODE_LEN 5
+#define MAX_ERASE_CMDS 3
+struct sandbox_spi_flash_data {
+       const char *name;
+       u8 idcode[IDCODE_LEN];
+       u32 size;
+       const struct sandbox_spi_flash_erase_commands
+                                               erase_cmds[MAX_ERASE_CMDS];
+};
+
+/* Structure describing all the flashes we know how to emulate */
+static const struct sandbox_spi_flash_data sandbox_sf_flashes[] = {
+       {
+               "M25P16", { 0x20, 0x20, 0x15 }, (2 << 20),
+               {       /* erase commands */
+                       { 0xd8, (64 << 10), }, /* sector */
+                       { 0xc7, (2 << 20), }, /* bulk */
+               },
+       },
+       {
+               "W25Q32", { 0xef, 0x40, 0x16 }, (4 << 20),
+               {       /* erase commands */
+                       { 0x20, (4 << 10), }, /* 4KB */
+                       { 0xd8, (64 << 10), }, /* sector */
+                       { 0xc7, (4 << 20), }, /* bulk */
+               },
+       },
+       {
+               "W25Q128", { 0xef, 0x40, 0x18 }, (16 << 20),
+               {       /* erase commands */
+                       { 0x20, (4 << 10), }, /* 4KB */
+                       { 0xd8, (64 << 10), }, /* sector */
+                       { 0xc7, (16 << 20), }, /* bulk */
+               },
+       },
+};
+
+/* Used to quickly bulk erase backing store */
+static u8 sandbox_sf_0xff[0x1000];
+
+/* Internal state data for each SPI flash */
+struct sandbox_spi_flash {
+       /*
+        * As we receive data over the SPI bus, our flash transitions
+        * between states.  For example, we start off in the SF_CMD
+        * state where the first byte tells us what operation to perform
+        * (such as read or write the flash).  But the operation itself
+        * can go through a few states such as first reading in the
+        * offset in the flash to perform the requested operation.
+        * Thus "state" stores the exact state that our machine is in
+        * while "cmd" stores the overall command we're processing.
+        */
+       enum sandbox_sf_state state;
+       uint cmd;
+       const void *cmd_data;
+       /* Current position in the flash; used when reading/writing/etc... */
+       uint off;
+       /* How many address bytes we've consumed */
+       uint addr_bytes, pad_addr_bytes;
+       /* The current flash status (see STAT_XXX defines above) */
+       u16 status;
+       /* Data describing the flash we're emulating */
+       const struct sandbox_spi_flash_data *data;
+       /* The file on disk to serv up data from */
+       int fd;
+};
+
+static int sandbox_sf_setup(void **priv, const char *spec)
+{
+       /* spec = idcode:file */
+       struct sandbox_spi_flash *sbsf;
+       const char *file;
+       size_t i, len, idname_len;
+       const struct sandbox_spi_flash_data *data;
+
+       file = strchr(spec, ':');
+       if (!file) {
+               printf("sandbox_sf: unable to parse file\n");
+               goto error;
+       }
+       idname_len = file - spec;
+       ++file;
+
+       for (i = 0; i < ARRAY_SIZE(sandbox_sf_flashes); ++i) {
+               data = &sandbox_sf_flashes[i];
+               len = strlen(data->name);
+               if (idname_len != len)
+                       continue;
+               if (!memcmp(spec, data->name, len))
+                       break;
+       }
+       if (i == ARRAY_SIZE(sandbox_sf_flashes)) {
+               printf("sandbox_sf: unknown flash '%*s'\n", (int)idname_len,
+                      spec);
+               goto error;
+       }
+
+       if (sandbox_sf_0xff[0] == 0x00)
+               memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff));
+
+       sbsf = calloc(sizeof(*sbsf), 1);
+       if (!sbsf) {
+               printf("sandbox_sf: out of memory\n");
+               goto error;
+       }
+
+       sbsf->fd = os_open(file, 02);
+       if (sbsf->fd == -1) {
+               free(sbsf);
+               printf("sandbox_sf: unable to open file '%s'\n", file);
+               goto error;
+       }
+
+       sbsf->data = data;
+
+       *priv = sbsf;
+       return 0;
+
+ error:
+       return 1;
+}
+
+static void sandbox_sf_free(void *priv)
+{
+       struct sandbox_spi_flash *sbsf = priv;
+
+       os_close(sbsf->fd);
+       free(sbsf);
+}
+
+static void sandbox_sf_cs_activate(void *priv)
+{
+       struct sandbox_spi_flash *sbsf = priv;
+
+       debug("sandbox_sf: CS activated; state is fresh!\n");
+
+       /* CS is asserted, so reset state */
+       sbsf->off = 0;
+       sbsf->addr_bytes = 0;
+       sbsf->pad_addr_bytes = 0;
+       sbsf->state = SF_CMD;
+       sbsf->cmd = SF_CMD;
+}
+
+static void sandbox_sf_cs_deactivate(void *priv)
+{
+       debug("sandbox_sf: CS deactivated; cmd done processing!\n");
+}
+
+/* Figure out what command this stream is telling us to do */
+static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx,
+                                 u8 *tx)
+{
+       enum sandbox_sf_state oldstate = sbsf->state;
+
+       /* We need to output a byte for the cmd byte we just ate */
+       sandbox_spi_tristate(tx, 1);
+
+       sbsf->cmd = rx[0];
+       switch (sbsf->cmd) {
+       case CMD_READ_ID:
+               sbsf->state = SF_ID;
+               sbsf->cmd = SF_ID;
+               break;
+       case CMD_READ_ARRAY_FAST:
+               sbsf->pad_addr_bytes = 1;
+       case CMD_READ_ARRAY_SLOW:
+       case CMD_PAGE_PROGRAM:
+ state_addr:
+               sbsf->state = SF_ADDR;
+               break;
+       case CMD_WRITE_DISABLE:
+               debug(" write disabled\n");
+               sbsf->status &= ~STAT_WEL;
+               break;
+       case CMD_READ_STATUS:
+               sbsf->state = SF_READ_STATUS;
+               break;
+       case CMD_READ_STATUS1:
+               sbsf->state = SF_READ_STATUS1;
+               break;
+       case CMD_WRITE_ENABLE:
+               debug(" write enabled\n");
+               sbsf->status |= STAT_WEL;
+               break;
+       default: {
+               size_t i;
+
+               /* handle erase commands first */
+               for (i = 0; i < MAX_ERASE_CMDS; ++i) {
+                       const struct sandbox_spi_flash_erase_commands *
+                               erase_cmd = &sbsf->data->erase_cmds[i];
+
+                       if (erase_cmd->cmd == 0x00)
+                               continue;
+                       if (sbsf->cmd != erase_cmd->cmd)
+                               continue;
+
+                       sbsf->cmd_data = erase_cmd;
+                       goto state_addr;
+               }
+
+               debug(" cmd unknown: %#x\n", sbsf->cmd);
+               return 1;
+       }
+       }
+
+       if (oldstate != sbsf->state)
+               debug(" cmd: transition to %s state\n",
+                     sandbox_sf_state_name(sbsf->state));
+
+       return 0;
+}
+
+int sandbox_erase_part(struct sandbox_spi_flash *sbsf, int size)
+{
+       int todo;
+       int ret;
+
+       while (size > 0) {
+               todo = min(size, sizeof(sandbox_sf_0xff));
+               ret = os_write(sbsf->fd, sandbox_sf_0xff, todo);
+               if (ret != todo)
+                       return ret;
+               size -= todo;
+       }
+
+       return 0;
+}
+
+static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
+               uint bytes)
+{
+       struct sandbox_spi_flash *sbsf = priv;
+       uint cnt, pos = 0;
+       int ret;
+
+       debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state,
+             sandbox_sf_state_name(sbsf->state), bytes);
+
+       if (sbsf->state == SF_CMD) {
+               /* Figure out the initial state */
+               if (sandbox_sf_process_cmd(sbsf, rx, tx))
+                       return 1;
+               ++pos;
+       }
+
+       /* Process the remaining data */
+       while (pos < bytes) {
+               switch (sbsf->state) {
+               case SF_ID: {
+                       u8 id;
+
+                       debug(" id: off:%u tx:", sbsf->off);
+                       if (sbsf->off < IDCODE_LEN)
+                               id = sbsf->data->idcode[sbsf->off];
+                       else
+                               id = 0;
+                       debug("%02x\n", id);
+                       tx[pos++] = id;
+                       ++sbsf->off;
+                       break;
+               }
+               case SF_ADDR:
+                       debug(" addr: bytes:%u rx:%02x ", sbsf->addr_bytes,
+                             rx[pos]);
+
+                       if (sbsf->addr_bytes++ < SF_ADDR_LEN)
+                               sbsf->off = (sbsf->off << 8) | rx[pos];
+                       debug("addr:%06x\n", sbsf->off);
+
+                       sandbox_spi_tristate(&tx[pos++], 1);
+
+                       /* See if we're done processing */
+                       if (sbsf->addr_bytes <
+                                       SF_ADDR_LEN + sbsf->pad_addr_bytes)
+                               break;
+
+                       /* Next state! */
+                       if (os_lseek(sbsf->fd, sbsf->off, OS_SEEK_SET) < 0) {
+                               puts("sandbox_sf: os_lseek() failed");
+                               return 1;
+                       }
+                       switch (sbsf->cmd) {
+                       case CMD_READ_ARRAY_FAST:
+                       case CMD_READ_ARRAY_SLOW:
+                               sbsf->state = SF_READ;
+                               break;
+                       case CMD_PAGE_PROGRAM:
+                               sbsf->state = SF_WRITE;
+                               break;
+                       default:
+                               /* assume erase state ... */
+                               sbsf->state = SF_ERASE;
+                               goto case_sf_erase;
+                       }
+                       debug(" cmd: transition to %s state\n",
+                             sandbox_sf_state_name(sbsf->state));
+                       break;
+               case SF_READ:
+                       /*
+                        * XXX: need to handle exotic behavior:
+                        *      - reading past end of device
+                        */
+
+                       cnt = bytes - pos;
+                       debug(" tx: read(%u)\n", cnt);
+                       ret = os_read(sbsf->fd, tx + pos, cnt);
+                       if (ret < 0) {
+                               puts("sandbox_spi: os_read() failed\n");
+                               return 1;
+                       }
+                       pos += ret;
+                       break;
+               case SF_READ_STATUS:
+                       debug(" read status: %#x\n", sbsf->status);
+                       cnt = bytes - pos;
+                       memset(tx + pos, sbsf->status, cnt);
+                       pos += cnt;
+                       break;
+               case SF_READ_STATUS1:
+                       debug(" read status: %#x\n", sbsf->status);
+                       cnt = bytes - pos;
+                       memset(tx + pos, sbsf->status >> 8, cnt);
+                       pos += cnt;
+                       break;
+               case SF_WRITE:
+                       /*
+                        * XXX: need to handle exotic behavior:
+                        *      - unaligned addresses
+                        *      - more than a page (256) worth of data
+                        *      - reading past end of device
+                        */
+                       if (!(sbsf->status & STAT_WEL)) {
+                               puts("sandbox_sf: write enable not set before write\n");
+                               goto done;
+                       }
+
+                       cnt = bytes - pos;
+                       debug(" rx: write(%u)\n", cnt);
+                       sandbox_spi_tristate(&tx[pos], cnt);
+                       ret = os_write(sbsf->fd, rx + pos, cnt);
+                       if (ret < 0) {
+                               puts("sandbox_spi: os_write() failed\n");
+                               return 1;
+                       }
+                       pos += ret;
+                       sbsf->status &= ~STAT_WEL;
+                       break;
+               case SF_ERASE:
+ case_sf_erase: {
+                       const struct sandbox_spi_flash_erase_commands *
+                                               erase_cmd = sbsf->cmd_data;
+
+                       if (!(sbsf->status & STAT_WEL)) {
+                               puts("sandbox_sf: write enable not set before erase\n");
+                               goto done;
+                       }
+
+                       /* verify address is aligned */
+                       if (sbsf->off & (erase_cmd->size - 1)) {
+                               debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n",
+                                     erase_cmd->cmd, erase_cmd->size,
+                                     sbsf->off);
+                               sbsf->status &= ~STAT_WEL;
+                               goto done;
+                       }
+
+                       debug(" sector erase addr: %u\n", sbsf->off);
+
+                       cnt = bytes - pos;
+                       sandbox_spi_tristate(&tx[pos], cnt);
+                       pos += cnt;
+
+                       /*
+                        * TODO(vapier@gentoo.org): latch WIP in status, and
+                        * delay before clearing it ?
+                        */
+                       ret = sandbox_erase_part(sbsf, erase_cmd->size);
+                       sbsf->status &= ~STAT_WEL;
+                       if (ret) {
+                               debug("sandbox_sf: Erase failed\n");
+                               goto done;
+                       }
+                       goto done;
+               }
+               default:
+                       debug(" ??? no idea what to do ???\n");
+                       goto done;
+               }
+       }
+
+ done:
+       return pos == bytes ? 0 : 1;
+}
+
+static const struct sandbox_spi_emu_ops sandbox_sf_ops = {
+       .setup         = sandbox_sf_setup,
+       .free          = sandbox_sf_free,
+       .cs_activate   = sandbox_sf_cs_activate,
+       .cs_deactivate = sandbox_sf_cs_deactivate,
+       .xfer          = sandbox_sf_xfer,
+};
+
+static int sandbox_cmdline_cb_spi_sf(struct sandbox_state *state,
+                                    const char *arg)
+{
+       unsigned long bus, cs;
+       const char *spec = sandbox_spi_parse_spec(arg, &bus, &cs);
+
+       if (!spec)
+               return 1;
+
+       /*
+        * It is safe to not make a copy of 'spec' because it comes from the
+        * command line.
+        *
+        * TODO(sjg@chromium.org): It would be nice if we could parse the
+        * spec here, but the problem is that no U-Boot init has been done
+        * yet. Perhaps we can figure something out.
+        */
+       state->spi[bus][cs].ops = &sandbox_sf_ops;
+       state->spi[bus][cs].spec = spec;
+       return 0;
+}
+SANDBOX_CMDLINE_OPT(spi_sf, 1, "connect a SPI flash: <bus>:<cs>:<id>:<file>");
index 732ddf836dffc1a97ec6302b74ca119ffe51e509..d291746ed4a41238a41d18296e3517363f4f91a5 100644 (file)
@@ -28,6 +28,7 @@
 #define CMD_PAGE_PROGRAM               0x02
 #define CMD_WRITE_DISABLE              0x04
 #define CMD_READ_STATUS                        0x05
+#define CMD_READ_STATUS1               0x35
 #define CMD_WRITE_ENABLE               0x06
 #define CMD_READ_CONFIG                        0x35
 #define CMD_FLAG_STATUS                        0x70
index 5eb8ffe843e07eb1dd128a37f23fc93312e37dd0..c1eb7548983355f19ce5596941ed6472f11fd1d0 100644 (file)
@@ -13,6 +13,7 @@
 #include <malloc.h>
 #include <spi.h>
 #include <spi_flash.h>
+#include <asm/io.h>
 
 #include "sf_internal.h"
 
@@ -279,22 +280,19 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
                debug("%s: Memory map must cover entire device\n", __func__);
                return -1;
        }
-       flash->memory_map = (void *)addr;
+       flash->memory_map = map_sysmem(addr, size);
 
        return 0;
 }
 #endif /* CONFIG_OF_CONTROL */
 
-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int spi_mode)
+static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
 {
-       struct spi_slave *spi;
        struct spi_flash *flash = NULL;
        u8 idcode[5];
        int ret;
 
        /* Setup spi_slave */
-       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
        if (!spi) {
                printf("SF: Failed to set up slave\n");
                return NULL;
@@ -358,6 +356,26 @@ err_claim_bus:
        return NULL;
 }
 
+struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int spi_mode)
+{
+       struct spi_slave *spi;
+
+       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+       return spi_flash_probe_slave(spi);
+}
+
+#ifdef CONFIG_OF_SPI_FLASH
+struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
+                                     int spi_node)
+{
+       struct spi_slave *spi;
+
+       spi = spi_setup_slave_fdt(blob, slave_node, spi_node);
+       return spi_flash_probe_slave(spi);
+}
+#endif
+
 void spi_flash_free(struct spi_flash *flash)
 {
        spi_free_slave(flash->spi);
index 27902fe394ebac1d7c3e53db1950b26a1c483b81..ed4ecd754b4fe2a1d723214254f3aee8dfe7c3f1 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_MXC_SPI) += mxc_spi.o
 obj-$(CONFIG_MXS_SPI) += mxs_spi.o
 obj-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o
 obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
+obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
 obj-$(CONFIG_SOFT_SPI) += soft_spi.o
 obj-$(CONFIG_SH_SPI) += sh_spi.o
 obj-$(CONFIG_FSL_ESPI) += fsl_espi.o
index bb88f3008a8b5ad899da0a0d0c037f05d912284d..aa89d89a32afa3c9e2710ff0214f50050a23f60e 100644 (file)
@@ -162,21 +162,22 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       if (bus >= ARRAY_SIZE(pins) || pins[bus] == NULL) {
-               debug("%s: invalid bus %u\n", __func__, bus);
-               return NULL;
-       }
        switch (bus) {
 #ifdef SPI0_CTL
-               case 0: mmr_base = SPI0_CTL; break;
+       case 0:
+               mmr_base = SPI0_CTL; break;
 #endif
 #ifdef SPI1_CTL
-               case 1: mmr_base = SPI1_CTL; break;
+       case 1:
+               mmr_base = SPI1_CTL; break;
 #endif
 #ifdef SPI2_CTL
-               case 2: mmr_base = SPI2_CTL; break;
+       case 2:
+               mmr_base = SPI2_CTL; break;
 #endif
-               default: return NULL;
+       default:
+               debug("%s: invalid bus %u\n", __func__, bus);
+               return NULL;
        }
 
        bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
index c25c4a9aeab5550d34b9b544a22b9d64bfc185ad..07b833d3a3de22b134b6d9ee4b1ffc6b422034f8 100644 (file)
@@ -154,10 +154,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       if (bus >= ARRAY_SIZE(pins) || pins[bus] == NULL) {
-               debug("%s: invalid bus %u\n", __func__, bus);
-               return NULL;
-       }
        switch (bus) {
 #ifdef SPI0_REGBASE
        case 0:
@@ -175,6 +171,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                break;
 #endif
        default:
+               debug("%s: invalid bus %u\n", __func__, bus);
                return NULL;
        }
 
index 699c57eb6d99209a2180dd171224fa7be3f8d0fa..4d5def2d3190fb5e5f15564362c27ac89ea5068d 100644 (file)
@@ -529,18 +529,18 @@ static int process_nodes(const void *blob, int node_list[], int count)
  * @param node         SPI peripheral node to use
  * @return 0 if ok, -1 on error
  */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
-               unsigned int cs, unsigned int max_hz, unsigned int mode)
+struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
+                                     int spi_node)
 {
        struct spi_bus *bus;
        unsigned int i;
 
        for (i = 0, bus = spi_bus; i < bus_count; i++, bus++) {
-               if (bus->node == node)
-                       return spi_setup_slave(i, cs, max_hz, mode);
+               if (bus->node == spi_node)
+                       return spi_base_setup_slave_fdt(blob, i, slave_node);
        }
 
-       debug("%s: Failed to find bus node %d\n", __func__, node);
+       debug("%s: Failed to find bus node %d\n", __func__, spi_node);
        return NULL;
 }
 
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
new file mode 100644 (file)
index 0000000..7895305
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Simulate a SPI port
+ *
+ * Copyright (c) 2011-2013 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+#include <os.h>
+
+#include <asm/errno.h>
+#include <asm/spi.h>
+#include <asm/state.h>
+
+#ifndef CONFIG_SPI_IDLE_VAL
+# define CONFIG_SPI_IDLE_VAL 0xFF
+#endif
+
+struct sandbox_spi_slave {
+       struct spi_slave slave;
+       const struct sandbox_spi_emu_ops *ops;
+       void *priv;
+};
+
+#define to_sandbox_spi_slave(s) container_of(s, struct sandbox_spi_slave, slave)
+
+const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus,
+                                  unsigned long *cs)
+{
+       char *endp;
+
+       *bus = simple_strtoul(arg, &endp, 0);
+       if (*endp != ':' || *bus >= CONFIG_SANDBOX_SPI_MAX_BUS)
+               return NULL;
+
+       *cs = simple_strtoul(endp + 1, &endp, 0);
+       if (*endp != ':' || *cs >= CONFIG_SANDBOX_SPI_MAX_CS)
+               return NULL;
+
+       return endp + 1;
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       return bus < CONFIG_SANDBOX_SPI_MAX_BUS &&
+               cs < CONFIG_SANDBOX_SPI_MAX_CS;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
+
+       debug("sandbox_spi: activating CS\n");
+       if (sss->ops->cs_activate)
+               sss->ops->cs_activate(sss->priv);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
+
+       debug("sandbox_spi: deactivating CS\n");
+       if (sss->ops->cs_deactivate)
+               sss->ops->cs_deactivate(sss->priv);
+}
+
+void spi_init(void)
+{
+}
+
+void spi_set_speed(struct spi_slave *slave, uint hz)
+{
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int mode)
+{
+       struct sandbox_spi_slave *sss;
+       struct sandbox_state *state = state_get_current();
+       const char *spec;
+
+       if (!spi_cs_is_valid(bus, cs)) {
+               debug("sandbox_spi: Invalid SPI bus/cs\n");
+               return NULL;
+       }
+
+       sss = spi_alloc_slave(struct sandbox_spi_slave, bus, cs);
+       if (!sss) {
+               debug("sandbox_spi: Out of memory\n");
+               return NULL;
+       }
+
+       spec = state->spi[bus][cs].spec;
+       sss->ops = state->spi[bus][cs].ops;
+       if (!spec || !sss->ops || sss->ops->setup(&sss->priv, spec)) {
+               free(sss);
+               printf("sandbox_spi: unable to locate a slave client\n");
+               return NULL;
+       }
+
+       return &sss->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
+
+       debug("sandbox_spi: releasing slave\n");
+
+       if (sss->ops->free)
+               sss->ops->free(sss->priv);
+
+       free(sss);
+}
+
+static int spi_bus_claim_cnt[CONFIG_SANDBOX_SPI_MAX_BUS];
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       if (spi_bus_claim_cnt[slave->bus]++) {
+               printf("sandbox_spi: error: bus already claimed: %d!\n",
+                      spi_bus_claim_cnt[slave->bus]);
+       }
+
+       return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       if (--spi_bus_claim_cnt[slave->bus]) {
+               printf("sandbox_spi: error: bus freed too often: %d!\n",
+                      spi_bus_claim_cnt[slave->bus]);
+       }
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+               void *din, unsigned long flags)
+{
+       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
+       uint bytes = bitlen / 8, i;
+       int ret = 0;
+       u8 *tx = (void *)dout, *rx = din;
+
+       if (bitlen == 0)
+               goto done;
+
+       /* we can only do 8 bit transfers */
+       if (bitlen % 8) {
+               printf("sandbox_spi: xfer: invalid bitlen size %u; needs to be 8bit\n",
+                      bitlen);
+               flags |= SPI_XFER_END;
+               goto done;
+       }
+
+       if (flags & SPI_XFER_BEGIN)
+               spi_cs_activate(slave);
+
+       /* make sure rx/tx buffers are full so clients can assume */
+       if (!tx) {
+               debug("sandbox_spi: xfer: auto-allocating tx scratch buffer\n");
+               tx = malloc(bytes);
+               if (!tx) {
+                       debug("sandbox_spi: Out of memory\n");
+                       return -ENOMEM;
+               }
+       }
+       if (!rx) {
+               debug("sandbox_spi: xfer: auto-allocating rx scratch buffer\n");
+               rx = malloc(bytes);
+               if (!rx) {
+                       debug("sandbox_spi: Out of memory\n");
+                       return -ENOMEM;
+               }
+       }
+
+       debug("sandbox_spi: xfer: bytes = %u\n tx:", bytes);
+       for (i = 0; i < bytes; ++i)
+               debug(" %u:%02x", i, tx[i]);
+       debug("\n");
+
+       ret = sss->ops->xfer(sss->priv, tx, rx, bytes);
+
+       debug("sandbox_spi: xfer: got back %i (that's %s)\n rx:",
+             ret, ret ? "bad" : "good");
+       for (i = 0; i < bytes; ++i)
+               debug(" %u:%02x", i, rx[i]);
+       debug("\n");
+
+       if (tx != dout)
+               free(tx);
+       if (rx != din)
+               free(rx);
+
+ done:
+       if (flags & SPI_XFER_END)
+               spi_cs_deactivate(slave);
+
+       return ret;
+}
index b76a26cef053fea6528098db03172f113d87b007..7ddea9b026a969b4207792f1cfe9e39240e7fc48 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <fdtdec.h>
 #include <malloc.h>
 #include <spi.h>
 
@@ -37,3 +38,21 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
 
        return ptr;
 }
+
+#ifdef CONFIG_OF_SPI
+struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
+                                          int node)
+{
+       int cs, max_hz, mode = 0;
+
+       cs = fdtdec_get_int(blob, node, "reg", -1);
+       max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 100000);
+       if (fdtdec_get_bool(blob, node, "spi-cpol"))
+               mode |= SPI_CPOL;
+       if (fdtdec_get_bool(blob, node, "spi-cpha"))
+               mode |= SPI_CPHA;
+       if (fdtdec_get_bool(blob, node, "spi-cs-high"))
+               mode |= SPI_CS_HIGH;
+       return spi_setup_slave(busnum, cs, max_hz, mode);
+}
+#endif
index a80a6966bf6a0368ce7b5b0fc216bb6d3dc42087..037484104fcfaff6db17d360b70af1f85de3c698 100644 (file)
@@ -67,6 +67,7 @@
  */
 #define CONFIG_SYS_FSL_DDR2
 #ifdef CONFIG_SYS_FSL_DDR2
+#define CONFIG_SYS_FSL_DDRC_GEN2
 #define CONFIG_SYS_SPD_BUS_NUM 0
 #define SPD_EEPROM_ADDRESS1    0x52
 #define SPD_EEPROM_ADDRESS2    0x51
index eab386add43709122bf421037e457d4fe38277ce..1ed5e1df21f3dff8e3809657643919440dd98de0 100644 (file)
 #define CONFIG_SYS_NUM_ADDR_MAP                16      /* number of TLB1 entries */
 #endif
 
-#define CONFIG_SYS_MEMTEST_START       0x00000000      /* memtest works on */
+#define CONFIG_SYS_MEMTEST_START       0x00200000      /* memtest works on */
 #define CONFIG_SYS_MEMTEST_END         0x1fffffff
 #define CONFIG_PANIC_HANG              /* do not reset board on panic */
 
index ad09816974021d6b994e57c6c610150047f9b03e..bff001f4335bd70ce966f6ca442564bb7d368889 100644 (file)
@@ -155,7 +155,7 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_CHIP_SELECTS_PER_CTRL   (4 * CONFIG_DIMM_SLOTS_PER_CTLR)
 #define CONFIG_DDR_SPD
 #define CONFIG_SYS_FSL_DDR3
-#define CONFIG_FSL_DDR_INTERACTIVE
+#undef CONFIG_FSL_DDR_INTERACTIVE
 #define CONFIG_SYS_SPD_BUS_NUM 0
 #define CONFIG_SYS_SDRAM_SIZE  2048    /* for fixed parameter use */
 #define SPD_EEPROM_ADDRESS1    0x51
index 79a6079370394faf549e19d2a5bfaf5953e20787..57b620d4810743d81da20194898977ea7111c6a0 100644 (file)
  * the MPL VCMA9 is equipped with an ATMEL 24C256 EEPROM at
  * address 0x50 with 16bit addressing
  */
-#define CONFIG_HARD_I2C                                /* I2C with hardware support */
-#define CONFIG_SYS_I2C_SPEED           100000  /* I2C speed */
-#define CONFIG_SYS_I2C_SLAVE           0x7F    /* I2C slave addr */
+#define CONFIG_SYS_I2C
 
 /* we use the built-in I2C controller */
-#define CONFIG_DRIVER_S3C24X0_I2C
+#define CONFIG_SYS_I2C_S3C24X0
+#define CONFIG_SYS_I2C_S3C24X0_SPEED    100000 /* I2C speed */
+#define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x7F   /* I2C slave addr */
 
 #define CONFIG_SYS_I2C_EEPROM_ADDR     0x50
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
index f0b9f944e8181f7c5b686d2d2ba9eb8b89ff6741..a3cb56b8bf2de3690f45c265257344ab2b36146f 100644 (file)
 
 /* I2C */
 #define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C
 #define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C_SPEED   100000          /* 100 Kbps */
-#define CONFIG_DRIVER_S3C24X0_I2C
-#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_S3C24X0_SPEED   100000          /* 100 Kbps */
+#define CONFIG_SYS_I2C_S3C24X0
 #define CONFIG_MAX_I2C_NUM     8
-#define CONFIG_SYS_I2C_SLAVE    0x0
+#define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x0
 #define CONFIG_I2C_EDID
 
 /* PMIC */
index 77b6735a7079f20cd1d53d35747fec2b66a28921..5ad3ee70d445a22b497ed254e70dd7d29f80f476 100644 (file)
@@ -94,6 +94,7 @@
 #define CONFIG_DCACHE_OFF
 #define CONFIG_UART_CONSOLE    0
 #define CONFIG_BAUDRATE 115200
+#define CONFIG_BFIN_SERIAL
 
 #define CONFIG_CMD_MEMORY
 #undef CONFIG_GZIP
index 1f65130f6cd862066a46db2187aca270af07244c..008f4b5ec8c1c799af6cbedfef97e19a6410609a 100644 (file)
@@ -85,6 +85,7 @@
 #define CONFIG_UART_CONSOLE    0
 
 #define CONFIG_BAUDRATE                115200
+#define CONFIG_BFIN_SERIAL
 #define CONFIG_BOOTARGS                "root=/dev/mtdblock0 rw"
 #define CONFIG_BOOTCOMMAND     "run sfboot"
 #define CONFIG_BOOTDELAY       5
index a22c868422178f8e002c93a68c7ccb31ad7254ca..f5b9658294387e3ebc89cf38c1e719b30c4a5800 100644 (file)
 /*
  * Software (bit-bang) I2C driver configuration
  */
-#define PF_SCL                 PF3
-#define PF_SDA                 PF2
-#define I2C_INIT               (*pFIO_DIR |=  PF_SCL); asm("ssync;")
-#define I2C_ACTIVE             (*pFIO_DIR |=  PF_SDA); \
-                               *pFIO_INEN &= ~PF_SDA; asm("ssync;")
-#define I2C_TRISTATE           (*pFIO_DIR &= ~PF_SDA); \
-                               *pFIO_INEN |= PF_SDA; asm("ssync;")
-#define I2C_READ               ((volatile)(*pFIO_FLAG_D & PF_SDA) != 0); \
-                               asm("ssync;")
-#define I2C_SDA(bit)   if (bit) { \
-                               *pFIO_FLAG_S = PF_SDA; \
-                               asm("ssync;"); \
-                               } \
-                       else    { \
-                               *pFIO_FLAG_C = PF_SDA; \
-                               asm("ssync;"); \
-                               }
-#define I2C_SCL(bit)   if (bit) { \
-                               *pFIO_FLAG_S = PF_SCL; \
-                               asm("ssync;"); \
-                               } \
-                       else    { \
-                               *pFIO_FLAG_C = PF_SCL; \
-                               asm("ssync;"); \
-                               }
-#define I2C_DELAY              udelay(5)       /* 1/4 I2C clock duration */
-
+#define CONFIG_SOFT_I2C_GPIO_SCL       GPIO_PF3
+#define CONFIG_SOFT_I2C_GPIO_SDA       GPIO_PF2
 
 /*
  * Flash Settings
index feb9d7344ac3a69224a98ebf03c1a0fb74dd3ad5..156eeabb06d5f7488b350f0b30ba3704f77ea020 100644 (file)
 
 #define CONFIG_BAUDRATE                57600
 #define CONFIG_UART_CONSOLE    0
+#define CONFIG_BFIN_SERIAL
 
 #define CONFIG_PANIC_HANG      1
 #define CONFIG_RTC_BFIN                1
index 1de8ffe2dfc8b290e1e1cf9054cb4f4ff99c8832..e12d761a24516653e6aec7f65f033f8191e7efd3 100644 (file)
 
 #define CONFIG_BAUDRATE                115200
 #define CONFIG_UART_CONSOLE    0
+#define CONFIG_BFIN_SERIAL
 
 #define CONFIG_PANIC_HANG      1
 #define CONFIG_RTC_BFIN                1
index 5b3aac795492915cd1d9ff6d2a90116e4000bb29..7de425349fb46be5b00ffb9f1bd590f49d423f13 100644 (file)
 #define CONFIG_BAUDRATE                57600
 #define CONFIG_LOADS_ECHO      1
 #define CONFIG_UART_CONSOLE    0
+#define CONFIG_BFIN_SERIAL
 
 /*
  * I2C settings
index 3c9eeb58a39f536fff57e8193c62c163919c0842..7f27eda416da7ecf3e4a8de60434f798cab8bf0f 100644 (file)
 #define CONFIG_BOOTCOMMAND     "run flashboot"
 #define FLASHBOOT_ENV_SETTINGS "flashboot=bootm 0x20040000\0"
 
+#define CONFIG_ADI_GPIO2
+
 #ifndef __ADSPBF542__
 /* Don't waste time transferring a logo over the UART */
 # if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART)
index d0e72e3e13447ef36d88f44e450fcfedc702858c..4f2c742a5d1a5c779a2904523c7e85bb0bce1870 100644 (file)
 #define CONFIG_DNP5370_EXT_WD_DISABLE 1
 
 #define CONFIG_UART_CONSOLE 0
+#define CONFIG_BFIN_SERIAL
 #define CONFIG_BAUDRATE     115200
 #define CONFIG_BOOTCOMMAND  "bootm 0x20030000"
 #define CONFIG_BOOTARGS     "console=ttyBF0,115200 root=/dev/mtdblock3 rootfstype=ext2"
index dee18a750cc04d0620dbca8b0f977f495ff33330..8fb904cddf45f12e4f48ff40a2d9b740a8e18666 100644 (file)
 
 /* I2C */
 #define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C
 #define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C_SPEED   100000          /* 100 Kbps */
-#define CONFIG_DRIVER_S3C24X0_I2C
+#define CONFIG_SYS_I2C_S3C24X0_SPEED   100000          /* 100 Kbps */
+#define CONFIG_SYS_I2C_S3C24X0
 #define CONFIG_I2C_MULTI_BUS
 #define CONFIG_MAX_I2C_NUM     8
-#define CONFIG_SYS_I2C_SLAVE   0x0
+#define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x0
 #define CONFIG_I2C_EDID
 
 /* PMIC */
 #define CONFIG_SF_DEFAULT_MODE         SPI_MODE_0
 #define CONFIG_SF_DEFAULT_SPEED                50000000
 #define EXYNOS5_SPI_NUM_CONTROLLERS    5
+#define CONFIG_OF_SPI
 #endif
 
 #ifdef CONFIG_ENV_IS_IN_SPI_FLASH
index a4edc624bc6ae048c5af5384b8ea2d883d269340..7e78a231d7adc6e34793b079b40f9a8bdabeb773 100644 (file)
 #define CONFIG_ENV_SIZE                8192
 #define CONFIG_ENV_IS_NOWHERE
 
+/* SPI */
+#define CONFIG_SANDBOX_SPI
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SF_TEST
+#define CONFIG_CMD_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_SANDBOX
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SPI_FLASH_WINBOND
+
 /* Memory things - we don't really want a memory test */
 #define CONFIG_SYS_LOAD_ADDR           0x00000000
 #define CONFIG_SYS_MEMTEST_START       0x00100000
index 8ff9800b195736793a324c26d6d7ea3ca5a0cc29..08771422ec42598c168641165488f5891c6749b1 100644 (file)
@@ -16,6 +16,7 @@
  */
 #define CONFIG_SAMSUNG         /* in a SAMSUNG core */
 #define CONFIG_S5P             /* which is in a S5P Family */
+#define CONFIG_EXYNOS4         /* which is in a EXYNOS4XXX */
 #define CONFIG_EXYNOS4210      /* which is in a EXYNOS4210 */
 #define CONFIG_TRATS           /* working with TRATS */
 #define CONFIG_TIZEN           /* TIZEN lib */
 #define CONFIG_SYS_CACHELINE_SIZE       32
 
 #define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_S3C24X0
+#define CONFIG_SYS_I2C_S3C24X0_SPEED   100000
+#define CONFIG_SYS_I2C_S3C24X0_SLAVE   0xFE
+#define CONFIG_MAX_I2C_NUM             8
 #define CONFIG_SYS_I2C_SOFT            /* I2C bit-banged */
 #define CONFIG_SYS_I2C_SOFT_SPEED      50000
-#define CONFIG_SYS_I2C_SOFT_SLAVE      0xFE
-#define I2C_SOFT_DECLARATIONS2
-#define CONFIG_SYS_I2C_SOFT_SPEED_2     50000
-#define CONFIG_SYS_I2C_SOFT_SLAVE_2     0x7F
+#define CONFIG_SYS_I2C_SOFT_SLAVE      0x7F
 #define CONFIG_SOFT_I2C_READ_REPEATED_START
 #define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_I2C_MULTI_BUS
-#define CONFIG_SOFT_I2C_MULTI_BUS
-#define CONFIG_SYS_MAX_I2C_BUS 15
 
 #include <asm/arch/gpio.h>
 
-/* I2C PMIC */
-#define CONFIG_SOFT_I2C_I2C5_SCL exynos4_gpio_part1_get_nr(b, 7)
-#define CONFIG_SOFT_I2C_I2C5_SDA exynos4_gpio_part1_get_nr(b, 6)
-
 /* I2C FG */
-#define CONFIG_SOFT_I2C_I2C9_SCL exynos4_gpio_part2_get_nr(y4, 1)
-#define CONFIG_SOFT_I2C_I2C9_SDA exynos4_gpio_part2_get_nr(y4, 0)
-
-#define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin()
-#define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin()
-#define I2C_INIT multi_i2c_init()
+#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part2_get_nr(y4, 1)
+#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part2_get_nr(y4, 0)
 
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
index c49a969e35e63f419649e27772db60f07828c34b..5d86a3d4e355a1b7aab1bb0d414e2dca99d7eddc 100644 (file)
 #include <asm/arch/gpio.h>
 
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_SOFT            /* I2C bit-banged */
+#define CONFIG_SYS_I2C_S3C24X0
+#define CONFIG_SYS_I2C_S3C24X0_SPEED   100000
+#define CONFIG_SYS_I2C_S3C24X0_SLAVE   0
+#define CONFIG_MAX_I2C_NUM             8
+#define CONFIG_SYS_I2C_SOFT
 #define CONFIG_SYS_I2C_SOFT_SPEED      50000
 #define CONFIG_SYS_I2C_SOFT_SLAVE      0x00
 #define I2C_SOFT_DECLARATIONS2
 #define CONFIG_SYS_I2C_SOFT_SPEED_2     50000
 #define CONFIG_SYS_I2C_SOFT_SLAVE_2     0x00
-#define I2C_SOFT_DECLARATIONS3
-#define CONFIG_SYS_I2C_SOFT_SPEED_3     50000
-#define CONFIG_SYS_I2C_SOFT_SLAVE_3     0x00
 #define CONFIG_SOFT_I2C_READ_REPEATED_START
 #define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_I2C_MULTI_BUS
-#define CONFIG_SOFT_I2C_MULTI_BUS
-#define CONFIG_SYS_MAX_I2C_BUS         15
-
-#define CONFIG_SOFT_I2C_I2C5_SCL exynos4x12_gpio_part1_get_nr(d0, 3)
-#define CONFIG_SOFT_I2C_I2C5_SDA exynos4x12_gpio_part1_get_nr(d0, 2)
-#define CONFIG_SOFT_I2C_I2C9_SCL exynos4x12_gpio_part1_get_nr(f1, 4)
-#define CONFIG_SOFT_I2C_I2C9_SDA exynos4x12_gpio_part1_get_nr(f1, 5)
-#define CONFIG_SOFT_I2C_I2C10_SCL exynos4x12_gpio_part2_get_nr(m2, 1)
-#define CONFIG_SOFT_I2C_I2C10_SDA exynos4x12_gpio_part2_get_nr(m2, 0)
-#define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin()
-#define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin()
-#define I2C_INIT multi_i2c_init()
+
+#ifndef __ASSEMBLY__
+int get_soft_i2c_scl_pin(void);
+int get_soft_i2c_sda_pin(void);
+#endif
+#define CONFIG_SOFT_I2C_GPIO_SCL       get_soft_i2c_scl_pin()
+#define CONFIG_SOFT_I2C_GPIO_SDA       get_soft_i2c_sda_pin()
 
 /* POWER */
 #define CONFIG_POWER
index 6c91143e96e37b5dd45594087fceaa277057e70d..a02dd67c1370f05cdc5b6571d2070ec5dc0e66cb 100644 (file)
@@ -141,6 +141,7 @@ struct dwmci_host {
        struct mmc *mmc;
 
        void (*clksel)(struct dwmci_host *host);
+       void (*board_init)(struct dwmci_host *host);
        unsigned int (*get_mmc_clk)(int dev_index);
 };
 
diff --git a/include/faraday/ftsdc021.h b/include/faraday/ftsdc021.h
new file mode 100644 (file)
index 0000000..de8e250
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __FTSDC021_H
+#define __FTSDC021_H
+
+int ftsdc021_sdhci_init(u32 regbase);
+
+#endif /* __FTSDC021_H */
index e2563c99f24f7260f79182ed45dbde4ff7a0f9ed..aba792244a86249e7373932fdd2f233d011eafcf 100644 (file)
@@ -259,13 +259,24 @@ static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte)
  * spi_free_slave() to free it later.
  *
  * @param blob:                Device tree blob
- * @param node:                SPI peripheral node to use
- * @param cs:          Chip select to use
- * @param max_hz:      Maximum SCK rate in Hz (0 for default)
- * @param mode:                Clock polarity, clock phase and other parameters
+ * @param slave_node:  Slave node to use
+ * @param spi_node:    SPI peripheral node to use
  * @return pointer to new spi_slave structure
  */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
-               unsigned int cs, unsigned int max_hz, unsigned int mode);
+struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
+                                     int spi_node);
+
+/**
+ * spi_base_setup_slave_fdt() - helper function to set up a SPI slace
+ *
+ * This decodes SPI properties from the slave node to determine the
+ * chip select and SPI parameters.
+ *
+ * @blob:      Device tree blob
+ * @busnum:    Bus number to use
+ * @node:      Device tree node for the SPI bus
+ */
+struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
+                                          int node);
 
 #endif /* _SPI_H_ */
index 25ca8f177b3452329e277c83dd357946ce6749ba..afc3a5809eac7ee4b1f31dda895f02042bc322fa 100644 (file)
@@ -67,6 +67,19 @@ struct spi_flash {
 
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int spi_mode);
+
+/**
+ * Set up a new SPI flash from an fdt node
+ *
+ * @param blob         Device tree blob
+ * @param slave_node   Pointer to this SPI slave node in the device tree
+ * @param spi_node     Cached pointer to the SPI interface this node belongs
+ *                     to
+ * @return 0 if ok, -1 on error
+ */
+struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
+                                     int spi_node);
+
 void spi_flash_free(struct spi_flash *flash);
 
 static inline int spi_flash_read(struct spi_flash *flash, u32 offset,