]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'u-boot/master' into 'u-boot-arm/master'
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>
Thu, 28 Mar 2013 17:50:01 +0000 (18:50 +0100)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Thu, 28 Mar 2013 17:50:01 +0000 (18:50 +0100)
Conflicts:
drivers/spi/tegra20_sflash.c
include/fdtdec.h
lib/fdtdec.c

1  2 
MAINTAINERS
drivers/mtd/spi/winbond.c
drivers/spi/Makefile
drivers/spi/tegra20_sflash.c
drivers/spi/tegra20_slink.c
include/fdtdec.h
lib/fdtdec.c

diff --combined MAINTAINERS
index bb556501bd0e15352e38c45da8051113fd278032,646997327e24f6f0d3a8f7554415718d1cb5ebaa..1614b913bdfe709925e853445139bc08b1f123be
@@@ -688,10 -688,6 +688,10 @@@ Stefan Herbrechtsmeier <stefan@code.her
  
        dns325          ARM926EJS (Kirkwood SoC)
  
 +Lauri Hintsala <lauri.hintsala@bluegiga.com>
 +
 +      apx4devkit      i.MX28
 +
  Vaibhav Hiremath <hvaibhav@ti.com>
  
        am3517_evm      ARM ARMV7 (AM35x SoC)
@@@ -810,6 -806,10 +810,6 @@@ Linus Walleij <linus.walleij@linaro.org
        integratorap    various
        integratorcp    various
  
 -Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
 -
 -      apx4devkit      i.MX28
 -
  Luka Perkov <luka@openwrt.org>
  
        ib62x0          ARM926EJS
@@@ -833,6 -833,10 +833,10 @@@ Stelian Pop <stelian@popies.net
        at91sam9263ek   ARM926EJS (AT91SAM9263 SoC)
        at91sam9rlek    ARM926EJS (AT91SAM9RL SoC)
  
+ Matt Porter <mporter@ti.com>
+       ti814x_evm      ARM ARMV7 (TI814x Soc)
  Dave Purdy <david.c.purdy@gmail.com>
  
        pogo_e02        ARM926EJS (Kirkwood SoC)
@@@ -910,6 -914,10 +914,10 @@@ Matt Sealey <matt@genesi-usa.com
  Bo Shen <voice.shen@atmel.com>
        at91sam9x5ek            ARM926EJS (AT91SAM9G15,G25,G35,X25,X35 SoC)
  
+ Rajeshwari Shinde <rajeshwari.s@samsung.com>
+       snow                    ARM ARMV7 (EXYNOS5250 SoC)
  Michal Simek <monstr@monstr.eu>
  
        zynq            ARM ARMV7 (Zynq SoC)
index 05dc6449263d69aca7e5d7c582439b6c5b3dd304,3560fcb6ba9a0e776af208caa8fb79920105768a..27162091c5ac69e4cfe8af4fc7d4f4944391c0a5
@@@ -67,6 -67,11 +67,11 @@@ static const struct winbond_spi_flash_p
                .nr_blocks              = 128,
                .name                   = "W25Q80",
        },
+       {
+               .id                     = 0x6016,
+               .nr_blocks              = 512,
+               .name                   = "W25Q32DW",
+       },
        {
                .id                     = 0x6017,
                .nr_blocks              = 128,
@@@ -92,12 -97,18 +97,12 @@@ struct spi_flash *spi_flash_probe_winbo
                return NULL;
        }
  
 -      flash = malloc(sizeof(*flash));
 +      flash = spi_flash_alloc_base(spi, params->name);
        if (!flash) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
  
 -      flash->spi = spi;
 -      flash->name = params->name;
 -
 -      flash->write = spi_flash_cmd_write_multi;
 -      flash->erase = spi_flash_cmd_erase;
 -      flash->read = spi_flash_cmd_read_fast;
        flash->page_size = 256;
        flash->sector_size = 4096;
        flash->size = 4096 * 16 * params->nr_blocks;
diff --combined drivers/spi/Makefile
index 42685955dcdce4c5518cfaa069a6be38383586ca,46e8fa3bef7e5153f360f66415517084f6999320..d08609effe1ace437a87c06a9dd66744d7a3a642
@@@ -25,9 -25,6 +25,9 @@@ include $(TOPDIR)/config.m
  
  LIB   := $(obj)libspi.o
  
 +# There are many options which enable SPI, so make this library available
 +COBJS-y += spi.o
 +
  COBJS-$(CONFIG_ALTERA_SPI) += altera_spi.o
  COBJS-$(CONFIG_ANDES_SPI) += andes_spi.o
  COBJS-$(CONFIG_ARMADA100_SPI) += armada100_spi.o
@@@ -39,7 -36,6 +39,7 @@@ COBJS-$(CONFIG_CF_SPI) += cf_spi.
  COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
  COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
  COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
 +COBJS-$(CONFIG_ICH_SPI) +=  ich.o
  COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
  COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
  COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
@@@ -50,8 -46,10 +50,10 @@@ COBJS-$(CONFIG_OMAP3_SPI) += omap3_spi.
  COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
  COBJS-$(CONFIG_SH_SPI) += sh_spi.o
  COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o
- COBJS-$(CONFIG_TEGRA_SPI) += tegra_spi.o
- COBJS-$(CONFIG_TEGRA_SLINK) += tegra_slink.o
+ COBJS-$(CONFIG_FDT_SPI) += fdt_spi.o
+ COBJS-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
+ COBJS-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+ COBJS-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
  COBJS-$(CONFIG_XILINX_SPI) += xilinx_spi.o
  
  COBJS := $(COBJS-y)
index 05027af3bc61478452640c016267fc0f5ba94dc3,a4e6c9aa3f24485a91d07066b663a5f0969a3a13..9322ce7f64102b61100039feb071716f243ab65e
@@@ -1,5 -1,5 +1,5 @@@
  /*
-  * Copyright (c) 2010-2012 NVIDIA Corporation
+  * Copyright (c) 2010-2013 NVIDIA Corporation
   * With help from the mpc8xxx SPI driver
   * With more help from omap3_spi SPI driver
   *
  #include <asm/gpio.h>
  #include <asm/arch/clock.h>
  #include <asm/arch/pinmux.h>
- #include <asm/arch/uart-spi-switch.h>
  #include <asm/arch-tegra/clk_rst.h>
- #include <asm/arch-tegra/tegra_spi.h>
+ #include <asm/arch-tegra20/tegra20_sflash.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);
- #else
-  #define corrupt_delay()
- #endif
+ #define SPI_CMD_GO                    (1 << 30)
+ #define SPI_CMD_ACTIVE_SCLK_SHIFT     26
+ #define SPI_CMD_ACTIVE_SCLK_MASK      (3 << SPI_CMD_ACTIVE_SCLK_SHIFT)
+ #define SPI_CMD_CK_SDA                        (1 << 21)
+ #define SPI_CMD_ACTIVE_SDA_SHIFT      18
+ #define SPI_CMD_ACTIVE_SDA_MASK               (3 << SPI_CMD_ACTIVE_SDA_SHIFT)
+ #define SPI_CMD_CS_POL                        (1 << 16)
+ #define SPI_CMD_TXEN                  (1 << 15)
+ #define SPI_CMD_RXEN                  (1 << 14)
+ #define SPI_CMD_CS_VAL                        (1 << 13)
+ #define SPI_CMD_CS_SOFT                       (1 << 12)
+ #define SPI_CMD_CS_DELAY              (1 << 9)
+ #define SPI_CMD_CS3_EN                        (1 << 8)
+ #define SPI_CMD_CS2_EN                        (1 << 7)
+ #define SPI_CMD_CS1_EN                        (1 << 6)
+ #define SPI_CMD_CS0_EN                        (1 << 5)
+ #define SPI_CMD_BIT_LENGTH            (1 << 4)
+ #define SPI_CMD_BIT_LENGTH_MASK               0x0000001F
  
- struct tegra_spi_slave {
-       struct spi_slave slave;
-       struct spi_tegra *regs;
+ #define SPI_STAT_BSY                  (1 << 31)
+ #define SPI_STAT_RDY                  (1 << 30)
+ #define SPI_STAT_RXF_FLUSH            (1 << 29)
+ #define SPI_STAT_TXF_FLUSH            (1 << 28)
+ #define SPI_STAT_RXF_UNR              (1 << 27)
+ #define SPI_STAT_TXF_OVF              (1 << 26)
+ #define SPI_STAT_RXF_EMPTY            (1 << 25)
+ #define SPI_STAT_RXF_FULL             (1 << 24)
+ #define SPI_STAT_TXF_EMPTY            (1 << 23)
+ #define SPI_STAT_TXF_FULL             (1 << 22)
+ #define SPI_STAT_SEL_TXRX_N           (1 << 16)
+ #define SPI_STAT_CUR_BLKCNT           (1 << 15)
+ #define SPI_TIMEOUT           1000
+ #define TEGRA_SPI_MAX_FREQ    52000000
+ struct spi_regs {
+       u32 command;    /* SPI_COMMAND_0 register  */
+       u32 status;     /* SPI_STATUS_0 register */
+       u32 rx_cmp;     /* SPI_RX_CMP_0 register  */
+       u32 dma_ctl;    /* SPI_DMA_CTL_0 register */
+       u32 tx_fifo;    /* SPI_TX_FIFO_0 register */
+       u32 rsvd[3];    /* offsets 0x14 to 0x1F reserved */
+       u32 rx_fifo;    /* SPI_RX_FIFO_0 register */
+ };
+ struct tegra_spi_ctrl {
+       struct spi_regs *regs;
        unsigned int freq;
        unsigned int mode;
        int periph_id;
+       int valid;
+ };
+ struct tegra_spi_slave {
+       struct spi_slave slave;
+       struct tegra_spi_ctrl *ctrl;
  };
  
+ /* tegra20 only supports one SFLASH controller */
+ static struct tegra_spi_ctrl spi_ctrls[1];
  static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
  {
        return container_of(slave, struct tegra_spi_slave, slave);
  }
  
- int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+ int tegra20_spi_cs_is_valid(unsigned int bus, unsigned int cs)
  {
        /* Tegra20 SPI-Flash - only 1 device ('bus/cs') */
        if (bus != 0 || cs != 0)
                return 1;
  }
  
- struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
+ struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode)
  {
        struct tegra_spi_slave *spi;
  
                return NULL;
        }
  
 -      spi = malloc(sizeof(struct tegra_spi_slave));
 +      spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
        if (!spi) {
                printf("SPI error: malloc of SPI structure failed\n");
                return NULL;
        }
- #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__);
+       spi->slave.bus = bus;
+       spi->slave.cs = cs;
+       spi->ctrl = &spi_ctrls[bus];
+       if (!spi->ctrl) {
+               printf("SPI error: could not find controller for bus %d\n",
+                      bus);
                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) {
+       if (max_hz < spi->ctrl->freq) {
                debug("%s: limiting frequency from %u to %u\n", __func__,
-                     spi->freq, max_hz);
-               spi->freq = max_hz;
+                     spi->ctrl->freq, max_hz);
+               spi->ctrl->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;
+       spi->ctrl->mode = mode;
  
        return &spi->slave;
  }
  
- void spi_free_slave(struct spi_slave *slave)
+ void tegra20_spi_free_slave(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
  
        free(spi);
  }
  
void spi_init(void)
int tegra20_spi_init(int *node_list, int count)
  {
-       /* do nothing */
+       struct tegra_spi_ctrl *ctrl;
+       int i;
+       int node = 0;
+       int found = 0;
+       for (i = 0; i < count; i++) {
+               ctrl = &spi_ctrls[i];
+               node = node_list[i];
+               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
+                                                               node, "reg");
+               if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
+                       debug("%s: no slink register found\n", __func__);
+                       continue;
+               }
+               ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
+                                           "spi-max-frequency", 0);
+               if (!ctrl->freq) {
+                       debug("%s: no slink max frequency found\n", __func__);
+                       continue;
+               }
+               ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
+               if (ctrl->periph_id == PERIPH_ID_NONE) {
+                       debug("%s: could not decode periph id\n", __func__);
+                       continue;
+               }
+               ctrl->valid = 1;
+               found = 1;
+               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
+                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
+       }
+       return !found;
  }
  
- int spi_claim_bus(struct spi_slave *slave)
+ int tegra20_spi_claim_bus(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_tegra *regs = spi->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg;
  
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
-       clock_start_periph_pll(spi->periph_id, CLOCK_ID_PERIPH, spi->freq);
+       clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
+                              spi->ctrl->freq);
  
        /* Clear stale status here */
        reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \
                SPI_STAT_RXF_UNR | SPI_STAT_TXF_OVF;
        writel(reg, &regs->status);
-       debug("spi_init: STATUS = %08x\n", readl(&regs->status));
+       debug("%s: STATUS = %08x\n", __func__, readl(&regs->status));
  
        /*
         * Use sw-controlled CS, so we can clock in data after ReadID, etc.
         */
-       reg = (spi->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT;
-       if (spi->mode & 2)
+       reg = (spi->ctrl->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT;
+       if (spi->ctrl->mode & 2)
                reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT;
        clrsetbits_le32(&regs->command, SPI_CMD_ACTIVE_SCLK_MASK |
                SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg);
-       debug("spi_init: COMMAND = %08x\n", readl(&regs->command));
+       debug("%s: COMMAND = %08x\n", __func__, readl(&regs->command));
  
        /*
         * SPI pins on Tegra20 are muxed - change pinmux later due to UART
         */
        pinmux_set_func(PINGRP_GMD, PMUX_FUNC_SFLASH);
        pinmux_tristate_disable(PINGRP_LSPI);
+       pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH);
  
- #ifndef CONFIG_SPI_UART_SWITCH
-       /*
-        * NOTE:
-        * Only set PinMux bits 3:2 to SPI here on boards that don't have the
-        * SPI UART switch or subsequent UART data won't go out!  See
-        * spi_uart_switch().
-        */
-       /* TODO: pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH); */
- #endif
        return 0;
  }
  
- void spi_release_bus(struct spi_slave *slave)
- {
-       /*
-        * We can't release UART_DISABLE and set pinmux to UART4 here since
-        * some code (e,g, spi_flash_probe) uses printf() while the SPI
-        * bus is held. That is arguably bad, but it has the advantage of
-        * already being in the source tree.
-        */
- }
- void spi_cs_activate(struct spi_slave *slave)
+ void tegra20_spi_cs_activate(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       pinmux_select_spi();
+       struct spi_regs *regs = spi->ctrl->regs;
  
        /* CS is negated on Tegra, so drive a 1 to get a 0 */
-       setbits_le32(&spi->regs->command, SPI_CMD_CS_VAL);
-       corrupt_delay();                /* Let UART settle */
+       setbits_le32(&regs->command, SPI_CMD_CS_VAL);
  }
  
- void spi_cs_deactivate(struct spi_slave *slave)
+ void tegra20_spi_cs_deactivate(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       pinmux_select_uart();
+       struct spi_regs *regs = spi->ctrl->regs;
  
        /* CS is negated on Tegra, so drive a 0 to get a 1 */
-       clrbits_le32(&spi->regs->command, SPI_CMD_CS_VAL);
-       corrupt_delay();                /* Let SPI settle */
+       clrbits_le32(&regs->command, SPI_CMD_CS_VAL);
  }
  
- int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                const void *data_out, void *data_in, unsigned long flags)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_tegra *regs = spi->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg, tmpdout, tmpdin = 0;
        const u8 *dout = data_out;
        u8 *din = data_in;
index 9da58774dbc26da86d18e5b88615e89c89143bfd,2ef2eb8495e2d1a3a1264db49ec604db11fc74c6..664de6e916613f4571fadb9fbd46497a32131fce
  #include <asm/gpio.h>
  #include <asm/arch/clock.h>
  #include <asm/arch-tegra/clk_rst.h>
- #include <asm/arch-tegra/tegra_slink.h>
+ #include <asm/arch-tegra20/tegra20_slink.h>
  #include <spi.h>
  #include <fdtdec.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
+ /* COMMAND */
+ #define SLINK_CMD_ENB                 (1 << 31)
+ #define SLINK_CMD_GO                  (1 << 30)
+ #define SLINK_CMD_M_S                 (1 << 28)
+ #define SLINK_CMD_CK_SDA              (1 << 21)
+ #define SLINK_CMD_CS_POL              (1 << 13)
+ #define SLINK_CMD_CS_VAL              (1 << 12)
+ #define SLINK_CMD_CS_SOFT             (1 << 11)
+ #define SLINK_CMD_BIT_LENGTH          (1 << 4)
+ #define SLINK_CMD_BIT_LENGTH_MASK     0x0000001F
+ /* COMMAND2 */
+ #define SLINK_CMD2_TXEN                       (1 << 30)
+ #define SLINK_CMD2_RXEN                       (1 << 31)
+ #define SLINK_CMD2_SS_EN              (1 << 18)
+ #define SLINK_CMD2_SS_EN_SHIFT                18
+ #define SLINK_CMD2_SS_EN_MASK         0x000C0000
+ #define SLINK_CMD2_CS_ACTIVE_BETWEEN  (1 << 17)
+ /* STATUS */
+ #define SLINK_STAT_BSY                        (1 << 31)
+ #define SLINK_STAT_RDY                        (1 << 30)
+ #define SLINK_STAT_ERR                        (1 << 29)
+ #define SLINK_STAT_RXF_FLUSH          (1 << 27)
+ #define SLINK_STAT_TXF_FLUSH          (1 << 26)
+ #define SLINK_STAT_RXF_OVF            (1 << 25)
+ #define SLINK_STAT_TXF_UNR            (1 << 24)
+ #define SLINK_STAT_RXF_EMPTY          (1 << 23)
+ #define SLINK_STAT_RXF_FULL           (1 << 22)
+ #define SLINK_STAT_TXF_EMPTY          (1 << 21)
+ #define SLINK_STAT_TXF_FULL           (1 << 20)
+ #define SLINK_STAT_TXF_OVF            (1 << 19)
+ #define SLINK_STAT_RXF_UNR            (1 << 18)
+ #define SLINK_STAT_CUR_BLKCNT         (1 << 15)
+ /* STATUS2 */
+ #define SLINK_STAT2_RXF_FULL_CNT      (1 << 16)
+ #define SLINK_STAT2_TXF_FULL_CNT      (1 << 0)
+ #define SPI_TIMEOUT           1000
+ #define TEGRA_SPI_MAX_FREQ    52000000
+ struct spi_regs {
+       u32 command;    /* SLINK_COMMAND_0 register  */
+       u32 command2;   /* SLINK_COMMAND2_0 reg */
+       u32 status;     /* SLINK_STATUS_0 register */
+       u32 reserved;   /* Reserved offset 0C */
+       u32 mas_data;   /* SLINK_MAS_DATA_0 reg */
+       u32 slav_data;  /* SLINK_SLAVE_DATA_0 reg */
+       u32 dma_ctl;    /* SLINK_DMA_CTL_0 register */
+       u32 status2;    /* SLINK_STATUS2_0 reg */
+       u32 rsvd[56];   /* 0x20 to 0xFF reserved */
+       u32 tx_fifo;    /* SLINK_TX_FIFO_0 reg off 100h */
+       u32 rsvd2[31];  /* 0x104 to 0x17F reserved */
+       u32 rx_fifo;    /* SLINK_RX_FIFO_0 reg off 180h */
+ };
  struct tegra_spi_ctrl {
-       struct slink_tegra *regs;
+       struct spi_regs *regs;
        unsigned int freq;
        unsigned int mode;
        int periph_id;
@@@ -53,7 -107,7 +107,7 @@@ static inline struct tegra_spi_slave *t
        return container_of(slave, struct tegra_spi_slave, slave);
  }
  
- int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+ int tegra30_spi_cs_is_valid(unsigned int bus, unsigned int cs)
  {
        if (bus >= CONFIG_TEGRA_SLINK_CTRLS || cs > 3 || !spi_ctrls[bus].valid)
                return 0;
                return 1;
  }
  
- struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ struct spi_slave *tegra30_spi_setup_slave(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int mode)
  {
        struct tegra_spi_slave *spi;
                return NULL;
        }
  
 -      spi = malloc(sizeof(struct tegra_spi_slave));
 +      spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
        if (!spi) {
                printf("SPI error: malloc of SPI structure failed\n");
                return NULL;
        }
 -      spi->slave.bus = bus;
 -      spi->slave.cs = cs;
        spi->ctrl = &spi_ctrls[bus];
        if (!spi->ctrl) {
                printf("SPI error: could not find controller for bus %d\n",
        return &spi->slave;
  }
  
- void spi_free_slave(struct spi_slave *slave)
+ void tegra30_spi_free_slave(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
  
        free(spi);
  }
  
void spi_init(void)
int tegra30_spi_init(int *node_list, int count)
  {
        struct tegra_spi_ctrl *ctrl;
        int i;
- #ifdef CONFIG_OF_CONTROL
        int node = 0;
-       int count;
-       int node_list[CONFIG_TEGRA_SLINK_CTRLS];
+       int found = 0;
  
-       count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi",
-                                          COMPAT_NVIDIA_TEGRA20_SLINK,
-                                          node_list,
-                                          CONFIG_TEGRA_SLINK_CTRLS);
        for (i = 0; i < count; i++) {
                ctrl = &spi_ctrls[i];
                node = node_list[i];
  
-               ctrl->regs = (struct slink_tegra *)fdtdec_get_addr(gd->fdt_blob,
-                                                                  node, "reg");
+               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
+                                                               node, "reg");
                if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
                        debug("%s: no slink register found\n", __func__);
                        continue;
                        continue;
                }
                ctrl->valid = 1;
+               found = 1;
  
                debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
                      __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
        }
- #else
-       for (i = 0; i < CONFIG_TEGRA_SLINK_CTRLS; i++) {
-               ctrl = &spi_ctrls[i];
-               u32 base_regs[] = {
-                       NV_PA_SLINK1_BASE,
-                       NV_PA_SLINK2_BASE,
-                       NV_PA_SLINK3_BASE,
-                       NV_PA_SLINK4_BASE,
-                       NV_PA_SLINK5_BASE,
-                       NV_PA_SLINK6_BASE,
-               };
-               int periph_ids[] = {
-                       PERIPH_ID_SBC1,
-                       PERIPH_ID_SBC2,
-                       PERIPH_ID_SBC3,
-                       PERIPH_ID_SBC4,
-                       PERIPH_ID_SBC5,
-                       PERIPH_ID_SBC6,
-               };
-               ctrl->regs = (struct slink_tegra *)base_regs[i];
-               ctrl->freq = TEGRA_SPI_MAX_FREQ;
-               ctrl->periph_id = periph_ids[i];
-               ctrl->valid = 1;
-               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
-                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
-       }
- #endif
+       return !found;
  }
  
- int spi_claim_bus(struct spi_slave *slave)
+ int tegra30_spi_claim_bus(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg;
  
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
        return 0;
  }
  
- void spi_release_bus(struct spi_slave *slave)
- {
- }
- void spi_cs_activate(struct spi_slave *slave)
+ void tegra30_spi_cs_activate(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
  
        /* CS is negated on Tegra, so drive a 1 to get a 0 */
        setbits_le32(&regs->command, SLINK_CMD_CS_VAL);
  }
  
- void spi_cs_deactivate(struct spi_slave *slave)
+ void tegra30_spi_cs_deactivate(struct spi_slave *slave)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
  
        /* CS is negated on Tegra, so drive a 0 to get a 1 */
        clrbits_le32(&regs->command, SLINK_CMD_CS_VAL);
  }
  
- int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                const void *data_out, void *data_in, unsigned long flags)
  {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg, tmpdout, tmpdin = 0;
        const u8 *dout = data_out;
        u8 *din = data_in;
diff --combined include/fdtdec.h
index 3b363be036acbf6999a7cda4be3cbbbfde2149c7,cb520a69187269d978f25c702a90345f952f430c..e7e3ff9e0384f10157a671ff36ee153654ae34bf
   */
  #ifdef CONFIG_PHYS_64BIT
  typedef u64 fdt_addr_t;
 +typedef u64 fdt_size_t;
  #define FDT_ADDR_T_NONE (-1ULL)
  #define fdt_addr_to_cpu(reg) be64_to_cpu(reg)
  #define fdt_size_to_cpu(reg) be64_to_cpu(reg)
  #else
  typedef u32 fdt_addr_t;
 +typedef u32 fdt_size_t;
  #define FDT_ADDR_T_NONE (-1U)
  #define fdt_addr_to_cpu(reg) be32_to_cpu(reg)
  #define fdt_size_to_cpu(reg) be32_to_cpu(reg)
@@@ -77,6 -75,7 +77,7 @@@ enum fdt_compat_id 
        COMPAT_NVIDIA_TEGRA20_SDMMC,    /* Tegra20 SDMMC controller */
        COMPAT_NVIDIA_TEGRA20_SFLASH,   /* Tegra 2 SPI flash controller */
        COMPAT_NVIDIA_TEGRA20_SLINK,    /* Tegra 2 SPI SLINK controller */
+       COMPAT_NVIDIA_TEGRA114_SPI,     /* Tegra 114 SPI controller */
        COMPAT_SMSC_LAN9215,            /* SMSC 10/100 Ethernet LAN9215 */
        COMPAT_SAMSUNG_EXYNOS5_SROMC,   /* Exynos5 SROMC */
        COMPAT_SAMSUNG_S3C2440_I2C,     /* Exynos I2C Controller */
        COMPAT_SAMSUNG_EXYNOS_SPI,      /* Exynos SPI */
        COMPAT_SAMSUNG_EXYNOS_EHCI,     /* Exynos EHCI controller */
        COMPAT_SAMSUNG_EXYNOS_USB_PHY,  /* Exynos phy controller for usb2.0 */
+       COMPAT_SAMSUNG_EXYNOS_TMU,      /* Exynos TMU */
        COMPAT_MAXIM_MAX77686_PMIC,     /* MAX77686 PMIC */
 +      COMPAT_GENERIC_SPI_FLASH,       /* Generic SPI Flash chip */
+       COMPAT_MAXIM_98095_CODEC,       /* MAX98095 Codec */
  
        COMPAT_COUNT,
  };
@@@ -202,19 -202,6 +205,19 @@@ int fdtdec_next_compatible_subnode(cons
  fdt_addr_t fdtdec_get_addr(const void *blob, int node,
                const char *prop_name);
  
 +/**
 + * Look up an address property in a node and return it as an address.
 + * The property must hold one address with a length. This is only tested
 + * on 32-bit machines.
 + *
 + * @param blob        FDT blob
 + * @param node        node to examine
 + * @param prop_name   name of property to find
 + * @return address, if found, or FDT_ADDR_T_NONE if not
 + */
 +fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
 +              const char *prop_name, fdt_size_t *sizep);
 +
  /**
   * Look up a 32-bit integer property in a node and return it. The property
   * must have at least 4 bytes of data. The value of the first cell is
diff --combined lib/fdtdec.c
index c95c2c28fa8ad114300f0707ec4a36ddd67c9b48,d2166e66323cba31796387d1bd37c8198ecc05e0..e17dd001ca2a0c6b578c88ce76c90251e89ea0d3
@@@ -50,6 -50,7 +50,7 @@@ static const char * const compat_names[
        COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
        COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
        COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"),
+       COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"),
        COMPAT(SMSC_LAN9215, "smsc,lan9215"),
        COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
        COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
        COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"),
        COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
        COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
+       COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
        COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
 +      COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
+       COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
  };
  
  const char *fdtdec_get_compatible(enum fdt_compat_id id)
        return compat_names[id];
  }
  
 -fdt_addr_t fdtdec_get_addr(const void *blob, int node,
 -              const char *prop_name)
 +fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
 +              const char *prop_name, fdt_size_t *sizep)
  {
        const fdt_addr_t *cell;
        int len;
  
        debug("%s: %s: ", __func__, prop_name);
        cell = fdt_getprop(blob, node, prop_name, &len);
 -      if (cell && (len == sizeof(fdt_addr_t) ||
 -                      len == sizeof(fdt_addr_t) * 2)) {
 +      if (cell && ((!sizep && len == sizeof(fdt_addr_t)) ||
 +                   len == sizeof(fdt_addr_t) * 2)) {
                fdt_addr_t addr = fdt_addr_to_cpu(*cell);
 +              if (sizep) {
 +                      const fdt_size_t *size;
  
 -              debug("%p\n", (void *)addr);
 +                      size = (fdt_size_t *)((char *)cell +
 +                                      sizeof(fdt_addr_t));
 +                      *sizep = fdt_size_to_cpu(*size);
 +                      debug("addr=%p, size=%p\n", (void *)addr,
 +                            (void *)*sizep);
 +              } else {
 +                      debug("%p\n", (void *)addr);
 +              }
                return addr;
        }
        debug("(not found)\n");
        return FDT_ADDR_T_NONE;
  }
  
 +fdt_addr_t fdtdec_get_addr(const void *blob, int node,
 +              const char *prop_name)
 +{
 +      return fdtdec_get_addr_size(blob, node, prop_name, NULL);
 +}
 +
  s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
                s32 default_val)
  {