tegra: spi: add fdt support to tegra SPI SFLASH driver
authorAllen Martin <amartin@nvidia.com>
Tue, 29 Jan 2013 13:51:24 +0000 (13:51 +0000)
committerTom Warren <twarren@nvidia.com>
Mon, 11 Feb 2013 17:35:24 +0000 (10:35 -0700)
Add support for configuring tegra SPI driver from devicetree.
Support is keyed off CONFIG_OF_CONTROL.  Add entry in seaboard dts
file for spi controller to describe seaboard spi.

Signed-off-by: Allen Martin <amartin@nvidia.com>
Signed-off-by: Tom Warren <twarren@nvidia.com>
drivers/spi/tegra_spi.c
include/fdtdec.h
lib/fdtdec.c

index 9bb34e29381f7a452717854b0d6dcc4edc5a879b..ce19095af03d931f5db46094289a48d79f464ebf 100644 (file)
@@ -32,6 +32,9 @@
 #include <asm/arch-tegra/clk_rst.h>
 #include <asm/arch-tegra/tegra_spi.h>
 #include <spi.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_SPI_CORRUPTS_UART)
  #define corrupt_delay()       udelay(CONFIG_SPI_CORRUPTS_UART_DLY);
@@ -44,6 +47,7 @@ struct tegra_spi_slave {
        struct spi_tegra *regs;
        unsigned int freq;
        unsigned int mode;
+       int periph_id;
 };
 
 static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
@@ -84,8 +88,45 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        }
        spi->slave.bus = bus;
        spi->slave.cs = cs;
-       spi->freq = max_hz;
+#ifdef CONFIG_OF_CONTROL
+       int node = fdtdec_next_compatible(gd->fdt_blob, 0,
+                                         COMPAT_NVIDIA_TEGRA20_SFLASH);
+       if (node < 0) {
+               debug("%s: cannot locate sflash node\n", __func__);
+               return NULL;
+       }
+       if (!fdtdec_get_is_enabled(gd->fdt_blob, node)) {
+               debug("%s: sflash is disabled\n", __func__);
+               return NULL;
+       }
+       spi->regs = (struct spi_tegra *)fdtdec_get_addr(gd->fdt_blob,
+                                                       node, "reg");
+       if ((fdt_addr_t)spi->regs == FDT_ADDR_T_NONE) {
+               debug("%s: no sflash register found\n", __func__);
+               return NULL;
+       }
+       spi->freq = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency", 0);
+       if (!spi->freq) {
+               debug("%s: no sflash max frequency found\n", __func__);
+               return NULL;
+       }
+       spi->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
+       if (spi->periph_id == PERIPH_ID_NONE) {
+               debug("%s: could not decode periph id\n", __func__);
+               return NULL;
+       }
+#else
        spi->regs = (struct spi_tegra *)NV_PA_SPI_BASE;
+       spi->freq = TEGRA_SPI_MAX_FREQ;
+       spi->periph_id = PERIPH_ID_SPI1;
+#endif
+       if (max_hz < spi->freq) {
+               debug("%s: limiting frequency from %u to %u\n", __func__,
+                     spi->freq, max_hz);
+               spi->freq = max_hz;
+       }
+       debug("%s: controller initialized at %p, freq = %u, periph_id = %d\n",
+             __func__, spi->regs, spi->freq, spi->periph_id);
        spi->mode = mode;
 
        return &spi->slave;
@@ -110,7 +151,7 @@ int spi_claim_bus(struct spi_slave *slave)
        u32 reg;
 
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
-       clock_start_periph_pll(PERIPH_ID_SPI1, CLOCK_ID_PERIPH, spi->freq);
+       clock_start_periph_pll(spi->periph_id, CLOCK_ID_PERIPH, spi->freq);
 
        /* Clear stale status here */
        reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \
index f77d195630bc088a6d2c82d62f2ee6e3ebb24162..5b67a770d3f94cad7ce59ce2c541e50e8e13bd66 100644 (file)
@@ -70,6 +70,7 @@ enum fdt_compat_id {
        COMPAT_NVIDIA_TEGRA20_NAND,     /* Tegra2 NAND controller */
        COMPAT_NVIDIA_TEGRA20_PWM,      /* Tegra 2 PWM controller */
        COMPAT_NVIDIA_TEGRA20_DC,       /* Tegra 2 Display controller */
+       COMPAT_NVIDIA_TEGRA20_SFLASH,   /* Tegra 2 SPI flash controller */
        COMPAT_SMSC_LAN9215,            /* SMSC 10/100 Ethernet LAN9215 */
        COMPAT_SAMSUNG_EXYNOS5_SROMC,   /* Exynos5 SROMC */
        COMPAT_SAMSUNG_S3C2440_I2C,     /* Exynos I2C Controller */
index 16921e14c9c3ce31b2510cb1f66a16c755d886ef..385e0e5a38a5c48650103e075d3198c3e747441e 100644 (file)
@@ -45,6 +45,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(NVIDIA_TEGRA20_NAND, "nvidia,tegra20-nand"),
        COMPAT(NVIDIA_TEGRA20_PWM, "nvidia,tegra20-pwm"),
        COMPAT(NVIDIA_TEGRA20_DC, "nvidia,tegra20-dc"),
+       COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
        COMPAT(SMSC_LAN9215, "smsc,lan9215"),
        COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
        COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),