* Copyright (C) 2013, Texas Instruments, Incorporated
*/
-#include <common.h>
+#include <cpu_func.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/arch/omap.h>
#include <malloc.h>
#include <asm/omap_gpio.h>
#include <asm/omap_common.h>
#include <asm/ti-common/ti-edma3.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
#include <linux/kernel.h>
#include <regmap.h>
#include <syscon.h>
/* ti qpsi register bit masks */
#define QSPI_TIMEOUT 2000000
-#define QSPI_FCLK 192000000
+/* AM4372: QSPI gets SPI_GCLK from PRCM unit as PER_CLKOUTM2 divided by 4. */
+#define QSPI_FCLK (192000000 / 4)
#define QSPI_DRA7XX_FCLK 76800000
#define QSPI_WLEN_MAX_BITS 128
#define QSPI_WLEN_MAX_BYTES (QSPI_WLEN_MAX_BITS >> 3)
#define QSPI_SETUP0_ADDR_SHIFT (8)
#define QSPI_SETUP0_DBITS_SHIFT (10)
+#define TI_QSPI_SETUP_REG(priv, cs) (&(priv)->base->setup0 + (cs))
+
/* ti qspi register set */
struct ti_qspi_regs {
u32 pid;
static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
- struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
+ struct dm_spi_slave_plat *slave = dev_get_parent_plat(dev);
struct ti_qspi_priv *priv;
struct udevice *bus;
uint words = bitlen >> 3; /* fixed 8-bit word length */
*((unsigned int *)offset) += len;
}
-static void ti_qspi_setup_mmap_read(struct ti_qspi_priv *priv, u8 opcode,
- u8 data_nbits, u8 addr_width,
+static void ti_qspi_setup_mmap_read(struct ti_qspi_priv *priv, int cs,
+ u8 opcode, u8 data_nbits, u8 addr_width,
u8 dummy_bytes)
{
u32 memval = opcode;
memval |= ((addr_width - 1) << QSPI_SETUP0_ADDR_SHIFT |
dummy_bytes << QSPI_SETUP0_DBITS_SHIFT);
- writel(memval, &priv->base->setup0);
+ writel(memval, TI_QSPI_SETUP_REG(priv, cs));
}
static int ti_qspi_set_mode(struct udevice *bus, uint mode)
static int ti_qspi_exec_mem_op(struct spi_slave *slave,
const struct spi_mem_op *op)
{
+ struct dm_spi_slave_plat *slave_plat;
struct ti_qspi_priv *priv;
struct udevice *bus;
+ u32 from = 0;
+ int ret = 0;
bus = slave->dev->parent;
priv = dev_get_priv(bus);
- u32 from = 0;
- int ret = 0;
+ slave_plat = dev_get_parent_plat(slave->dev);
/* Only optimize read path. */
if (!op->data.nbytes || op->data.dir != SPI_MEM_DATA_IN ||
if (from + op->data.nbytes > priv->mmap_size)
return -ENOTSUPP;
- ti_qspi_setup_mmap_read(priv, op->cmd.opcode, op->data.buswidth,
- op->addr.nbytes, op->dummy.nbytes);
+ ti_qspi_setup_mmap_read(priv, slave_plat->cs, op->cmd.opcode,
+ op->data.buswidth, op->addr.nbytes,
+ op->dummy.nbytes);
ti_qspi_copy_mmap((void *)op->data.buf.in,
(void *)priv->memory_map + from, op->data.nbytes);
static int ti_qspi_claim_bus(struct udevice *dev)
{
- struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+ struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
struct ti_qspi_priv *priv;
struct udevice *bus;
static int ti_qspi_release_bus(struct udevice *dev)
{
- struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+ struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
struct ti_qspi_priv *priv;
struct udevice *bus;
writel(0, &priv->base->dc);
writel(0, &priv->base->cmd);
writel(0, &priv->base->data);
- writel(0, &priv->base->setup0);
+ writel(0, TI_QSPI_SETUP_REG(priv, slave_plat->cs));
return 0;
}
#endif
}
-static int ti_qspi_ofdata_to_platdata(struct udevice *bus)
+static int ti_qspi_of_to_plat(struct udevice *bus)
{
struct ti_qspi_priv *priv = dev_get_priv(bus);
const void *blob = gd->fdt_blob;
fdt_addr_t mmap_size;
priv->ctrl_mod_mmap = map_syscon_chipselects(bus);
- priv->base = map_physmem(devfdt_get_addr(bus),
+ priv->base = map_physmem(dev_read_addr(bus),
sizeof(struct ti_qspi_regs), MAP_NOCACHE);
mmap_addr = devfdt_get_addr_size_index(bus, 1, &mmap_size);
priv->memory_map = map_physmem(mmap_addr, mmap_size, MAP_NOCACHE);
priv->mmap_size = mmap_size;
- priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1);
- if (priv->max_hz < 0) {
+ priv->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
+ if (!priv->max_hz) {
debug("Error: Max frequency missing\n");
return -ENODEV;
}
.id = UCLASS_SPI,
.of_match = ti_qspi_ids,
.ops = &ti_qspi_ops,
- .ofdata_to_platdata = ti_qspi_ofdata_to_platdata,
- .priv_auto_alloc_size = sizeof(struct ti_qspi_priv),
+ .of_to_plat = ti_qspi_of_to_plat,
+ .priv_auto = sizeof(struct ti_qspi_priv),
.probe = ti_qspi_probe,
};