[U-Boot] [PATCH 0/4 V2] EXYNOS5: Add FDT support to SPI

This patch set adds FDT support to SPI driver.
This patch set is based on top of "EXYNOS5: FDT support for Sound"
Changes in V2: - Added Device nodes for SPI3 and SPI4.
Rajeshwari Shinde (4): EXYNOS5: FDT: Add compatible strings for SPI EXYNOS5 : FDT: Add Aliases for SPI device EXYNOS5: FDT: Add SPI device node data SPI: EXYNOS: Add FDT support to driver.
arch/arm/dts/exynos5250.dtsi | 41 +++++++++++ board/samsung/dts/exynos5250-smdk5250.dts | 5 ++ doc/device-tree-bindings/exynos/isp-spi.txt | 22 ++++++ drivers/spi/exynos_spi.c | 96 +++++++++++++++++++++++++-- include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 6 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 doc/device-tree-bindings/exynos/isp-spi.txt

Add required compatible information for SPI driver.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes since V2: - None. include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index 0c195f3..d1279f4 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -72,6 +72,7 @@ enum fdt_compat_id { COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */ COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */ COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */ + COMPAT_SAMSUNG_EXYNOS_SPI, /* Exynos SPI */
COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 29766dc..1dbb892 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -49,6 +49,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"), COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"), COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"), + COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"), };
const char *fdtdec_get_compatible(enum fdt_compat_id id)

This patch adds aliases for SPI.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - Added aliases for SPI3 and SPI4. board/samsung/dts/exynos5250-smdk5250.dts | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts index 1562721..be57fde 100644 --- a/board/samsung/dts/exynos5250-smdk5250.dts +++ b/board/samsung/dts/exynos5250-smdk5250.dts @@ -25,6 +25,11 @@ i2c5 = "/i2c@12cb0000"; i2c6 = "/i2c@12cc0000"; i2c7 = "/i2c@12cd0000"; + spi0 = "/spi@12d20000"; + spi1 = "/spi@12d30000"; + spi2 = "/spi@12d40000"; + spi3 = "/spi@131a0000"; + spi4 = "/spi@131b0000"; };
sromc@12250000 {

On Wed, Dec 5, 2012 at 2:38 AM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch adds aliases for SPI.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Acked-by: Simon Glass sjg@chromium.org
Changes in V2: - Added aliases for SPI3 and SPI4. board/samsung/dts/exynos5250-smdk5250.dts | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts index 1562721..be57fde 100644 --- a/board/samsung/dts/exynos5250-smdk5250.dts +++ b/board/samsung/dts/exynos5250-smdk5250.dts @@ -25,6 +25,11 @@ i2c5 = "/i2c@12cb0000"; i2c6 = "/i2c@12cc0000"; i2c7 = "/i2c@12cd0000";
spi0 = "/spi@12d20000";
spi1 = "/spi@12d30000";
spi2 = "/spi@12d40000";
spi3 = "/spi@131a0000";
spi4 = "/spi@131b0000"; }; sromc@12250000 {
-- 1.7.4.4

Add SPI device node data for exynos.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - Added device node for ISP-SPI channels and documentation for same. arch/arm/dts/exynos5250.dtsi | 41 +++++++++++++++++++++++++++ doc/device-tree-bindings/exynos/isp-spi.txt | 22 ++++++++++++++ 2 files changed, 63 insertions(+), 0 deletions(-) create mode 100644 doc/device-tree-bindings/exynos/isp-spi.txt
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi index 3f750f0..2073ef2 100644 --- a/arch/arm/dts/exynos5250.dtsi +++ b/arch/arm/dts/exynos5250.dtsi @@ -102,4 +102,45 @@ compatible = "samsung,exynos-sound"; reg = <0x12d60000 0x20>; }; + + spi@12d20000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x12d20000 0x30>; + interrupts = <0 68 0>; + }; + + spi@12d30000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x12d30000 0x30>; + interrupts = <0 69 0>; + }; + + spi@12d40000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x12d40000 0x30>; + clock-frequency = <50000000>; + interrupts = <0 70 0>; + }; + + spi@131a0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x131a0000 0x30>; + interrupts = <0 129 0>; + }; + + spi@131b0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x131b0000 0x30>; + interrupts = <0 130 0>; + }; }; diff --git a/doc/device-tree-bindings/exynos/isp-spi.txt b/doc/device-tree-bindings/exynos/isp-spi.txt new file mode 100644 index 0000000..b8086e8 --- /dev/null +++ b/doc/device-tree-bindings/exynos/isp-spi.txt @@ -0,0 +1,22 @@ +Exynos ISP SPI Subsystem + +The device node for ISP SPI subsytem. +Since Peripheral id in EXYNOS is decoded based on Interrupts, currently +ISP SPI have no individual interrupts hence we add ad dummy interrupt node +which will have a value beyond the maximum number of interrupts exynos5 can +support. + +Required properties : + - compatible : Should be "samsung,exynos-spi" for spi. + - reg : Base adrress of the the subsystem. + - interrupts : A value which is beyond the maximum number of interrupts +exynos5 can support. + +Example: +spi@131a0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x131a0000 0x30>; + interrupts = <0 129 0>; +};

On Wed, Dec 5, 2012 at 2:38 AM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
Add SPI device node data for exynos.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
I was wondering about the ISP SPI interrupts - that answers the question. Is there really no way to get an interrupt? It doesn't matter for U-Boot, but might for Linux.
Acked-by: Simon Glass sjg@chromium.org
Changes in V2: - Added device node for ISP-SPI channels and documentation for same. arch/arm/dts/exynos5250.dtsi | 41 +++++++++++++++++++++++++++ doc/device-tree-bindings/exynos/isp-spi.txt | 22 ++++++++++++++ 2 files changed, 63 insertions(+), 0 deletions(-) create mode 100644 doc/device-tree-bindings/exynos/isp-spi.txt

This patch adds FDT support to the SPI driver.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None. drivers/spi/exynos_spi.c | 96 +++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 90 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 3e6c18f..7ecc566 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -20,6 +20,7 @@ #include <common.h> #include <malloc.h> #include <spi.h> +#include <fdtdec.h> #include <asm/arch/clk.h> #include <asm/arch/clock.h> #include <asm/arch/cpu.h> @@ -28,16 +29,20 @@ #include <asm/arch-exynos/spi.h> #include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR; + /* Information about each SPI controller */ struct spi_bus { enum periph_id periph_id; s32 frequency; /* Default clock frequency, -1 for none */ struct exynos_spi *regs; int inited; /* 1 if this bus is ready for use */ + int node; };
/* A list of spi buses that we know about */ static struct spi_bus spi_bus[EXYNOS5_SPI_NUM_CONTROLLERS]; +static unsigned int bus_count;
struct exynos_spi_slave { struct spi_slave slave; @@ -50,7 +55,7 @@ struct exynos_spi_slave {
static struct spi_bus *spi_get_bus(unsigned dev_index) { - if (dev_index < EXYNOS5_SPI_NUM_CONTROLLERS) + if (dev_index < bus_count) return &spi_bus[dev_index]; debug("%s: invalid bus %d", __func__, dev_index);
@@ -347,21 +352,100 @@ static inline struct exynos_spi *get_spi_base(int dev_index) (dev_index - 3); }
+/* + * Read the SPI config from the device tree node. + * + * @param blob FDT blob to read from + * @param node Node offset to read from + * @param bus SPI bus structure to fill with information + * @return 0 if ok, or -FDT_ERR_NOTFOUND if something was missing + */ +static int spi_get_config(const void *blob, int node, struct spi_bus *bus) +{ + bus->node = node; + bus->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg"); + bus->periph_id = pinmux_decode_periph_id(blob, node); + if (bus->periph_id == PERIPH_ID_NONE) { + debug("%s: Invalid peripheral ID %d\n", __func__, + bus->periph_id); + return -FDT_ERR_NOTFOUND; + } + + /* Use 500KHz as a suitable default */ + bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", + 500000); + + return 0; +} + + +/* + * Process a list of nodes, adding them to our list of SPI ports. + * + * @param blob fdt blob + * @param node_list list of nodes to process (any <=0 are ignored) + * @param count number of nodes to process + * @param is_dvc 1 if these are DVC ports, 0 if standard I2C + * @return 0 if ok, -1 on error + */ +static int process_nodes(const void *blob, int node_list[], int count) +{ + int i; + + /* build the i2c_controllers[] for each controller */ + for (i = 0; i < count; i++) { + int node = node_list[i]; + struct spi_bus *bus; + + if (node <= 0) + continue; + + bus = &spi_bus[i]; + if (spi_get_config(blob, node, bus)) { + printf("exynos spi_init: failed to decode bus %d\n", + i); + return -1; + } + + debug("spi: controller bus %d at %p, periph_id %d\n", + i, bus->regs, bus->periph_id); + bus->inited = 1; + bus_count++; + } + + return 0; +} + /* Sadly there is no error return from this function */ void spi_init(void) { - int i; + int count; + +#ifdef CONFIG_OF_CONTROL + int node_list[EXYNOS5_SPI_NUM_CONTROLLERS]; + const void *blob = gd->fdt_blob; + + count = fdtdec_find_aliases_for_id(blob, "spi", + COMPAT_SAMSUNG_EXYNOS_SPI, node_list, + EXYNOS5_SPI_NUM_CONTROLLERS); + if (process_nodes(blob, node_list, count)) + return; + +#else struct spi_bus *bus;
- for (i = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) { - bus = &spi_bus[i]; - bus->regs = get_spi_base(i); - bus->periph_id = PERIPH_ID_SPI0 + i; + for (count = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) { + bus = &spi_bus[count]; + bus->regs = get_spi_base(count); + bus->periph_id = PERIPH_ID_SPI0 + count;
/* Although Exynos5 supports upto 50Mhz speed, * we are setting it to 10Mhz for safe side */ bus->frequency = 10000000; bus->inited = 1; + bus->node = 0; + bus_count = EXYNOS5_SPI_NUM_CONTROLLERS; } +#endif }

On Wed, Dec 5, 2012 at 2:38 AM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch adds FDT support to the SPI driver.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Acked-by: Simon Glass sjg@chromium.org
Changes in V2: - None. drivers/spi/exynos_spi.c | 96 +++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 90 insertions(+), 6 deletions(-)
participants (2)
-
Rajeshwari Shinde
-
Simon Glass