1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 08:42:12 +02:00
- Enable DM_SPI on siemens omap boards (Jagan)
- Dropped some non-dm supported omap3 boards (Jagan)
- Dropped non-dm code in omap3 spi driver (Jagan)
- Dropped non-dm code in kirkwood spi driver (Bhargav)
This commit is contained in:
Tom Rini
2020-07-11 17:40:00 -04:00
101 changed files with 107 additions and 7887 deletions

View File

@@ -162,6 +162,12 @@ config ICH_SPI
access the SPI NOR flash on platforms embedding this Intel
ICH IP core.
config KIRKWOOD_SPI
bool "Marvell Kirkwood SPI Driver"
help
Enable support for SPI on various Marvell SoCs, such as
Kirkwood and Armada 375.
config MESON_SPIFC
bool "Amlogic Meson SPI Flash Controller driver"
depends on ARCH_MESON
@@ -226,6 +232,13 @@ config NXP_FSPI
Enable the NXP FlexSPI (FSPI) driver. This driver can be used to
access the SPI NOR flash on platforms embedding this NXP IP core.
config OMAP3_SPI
bool "McSPI driver for OMAP"
help
SPI master controller for OMAP24XX and later Multichannel SPI
(McSPI). This driver be used to access SPI chips on platforms
embedding this OMAP3 McSPI IP core.
config PIC32_SPI
bool "Microchip PIC32 SPI driver"
depends on MACH_PIC32
@@ -417,23 +430,10 @@ config SH_QSPI
Enable the Renesas Quad SPI controller driver. This driver can be
used on Renesas SoCs.
config KIRKWOOD_SPI
bool "Marvell Kirkwood SPI Driver"
help
Enable support for SPI on various Marvell SoCs, such as
Kirkwood and Armada 375.
config MXC_SPI
bool "MXC SPI Driver"
help
Enable the MXC SPI controller driver. This driver can be used
on various i.MX SoCs such as i.MX31/35/51/6/7.
config OMAP3_SPI
bool "McSPI driver for OMAP"
help
SPI master controller for OMAP24XX and later Multichannel SPI
(McSPI). This driver be used to access SPI chips on platforms
embedding this OMAP3 McSPI IP core.
endif # menu "SPI Support"

View File

@@ -19,6 +19,19 @@
#endif
#include <asm/arch-mvebu/spi.h>
struct mvebu_spi_dev {
bool is_errata_50mhz_ac;
};
struct mvebu_spi_platdata {
struct kwspi_registers *spireg;
bool is_errata_50mhz_ac;
};
struct mvebu_spi_priv {
struct kwspi_registers *spireg;
};
static void _spi_cs_activate(struct kwspi_registers *reg)
{
setbits_le32(&reg->ctrl, KWSPI_CSN_ACT);
@@ -94,128 +107,6 @@ static int _spi_xfer(struct kwspi_registers *reg, unsigned int bitlen,
return 0;
}
#if !CONFIG_IS_ENABLED(DM_SPI)
static struct kwspi_registers *spireg =
(struct kwspi_registers *)MVEBU_SPI_BASE;
#ifdef CONFIG_ARCH_KIRKWOOD
static u32 cs_spi_mpp_back[2];
#endif
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
struct spi_slave *slave;
u32 data;
#ifdef CONFIG_ARCH_KIRKWOOD
static const u32 kwspi_mpp_config[2][2] = {
{ MPP0_SPI_SCn, 0 }, /* if cs == 0 */
{ MPP7_SPI_SCn, 0 } /* if cs != 0 */
};
#endif
if (!spi_cs_is_valid(bus, cs))
return NULL;
slave = spi_alloc_slave_base(bus, cs);
if (!slave)
return NULL;
writel(KWSPI_SMEMRDY, &spireg->ctrl);
/* calculate spi clock prescaller using max_hz */
data = ((CONFIG_SYS_TCLK / 2) / max_hz) + 0x10;
data = data < KWSPI_CLKPRESCL_MIN ? KWSPI_CLKPRESCL_MIN : data;
data = data > KWSPI_CLKPRESCL_MASK ? KWSPI_CLKPRESCL_MASK : data;
/* program spi clock prescaller using max_hz */
writel(KWSPI_ADRLEN_3BYTE | data, &spireg->cfg);
debug("data = 0x%08x\n", data);
writel(KWSPI_SMEMRDIRQ, &spireg->irq_cause);
writel(KWSPI_IRQMASK, &spireg->irq_mask);
#ifdef CONFIG_ARCH_KIRKWOOD
/* program mpp registers to select SPI_CSn */
kirkwood_mpp_conf(kwspi_mpp_config[cs ? 1 : 0], cs_spi_mpp_back);
#endif
return slave;
}
void spi_free_slave(struct spi_slave *slave)
{
#ifdef CONFIG_ARCH_KIRKWOOD
kirkwood_mpp_conf(cs_spi_mpp_back, NULL);
#endif
free(slave);
}
__attribute__((weak)) int board_spi_claim_bus(struct spi_slave *slave)
{
return 0;
}
int spi_claim_bus(struct spi_slave *slave)
{
return board_spi_claim_bus(slave);
}
__attribute__((weak)) void board_spi_release_bus(struct spi_slave *slave)
{
}
void spi_release_bus(struct spi_slave *slave)
{
board_spi_release_bus(slave);
}
#ifndef CONFIG_SPI_CS_IS_VALID
/*
* you can define this function board specific
* define above CONFIG in board specific config file and
* provide the function in board specific src file
*/
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
return bus == 0 && (cs == 0 || cs == 1);
}
#endif
void spi_cs_activate(struct spi_slave *slave)
{
_spi_cs_activate(spireg);
}
void spi_cs_deactivate(struct spi_slave *slave)
{
_spi_cs_deactivate(spireg);
}
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
return _spi_xfer(spireg, bitlen, dout, din, flags);
}
#else
/* Here now the DM part */
struct mvebu_spi_dev {
bool is_errata_50mhz_ac;
};
struct mvebu_spi_platdata {
struct kwspi_registers *spireg;
bool is_errata_50mhz_ac;
};
struct mvebu_spi_priv {
struct kwspi_registers *spireg;
};
static int mvebu_spi_set_speed(struct udevice *bus, uint hz)
{
struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
@@ -409,4 +300,3 @@ U_BOOT_DRIVER(mvebu_spi) = {
.priv_auto_alloc_size = sizeof(struct mvebu_spi_priv),
.probe = mvebu_spi_probe,
};
#endif

View File

@@ -25,16 +25,6 @@
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_AM33XX) || defined(CONFIG_AM43XX)
#define OMAP3_MCSPI1_BASE 0x48030100
#define OMAP3_MCSPI2_BASE 0x481A0100
#else
#define OMAP3_MCSPI1_BASE 0x48098000
#define OMAP3_MCSPI2_BASE 0x4809A000
#define OMAP3_MCSPI3_BASE 0x480B8000
#define OMAP3_MCSPI4_BASE 0x480BA000
#endif
#define OMAP4_MCSPI_REG_OFFSET 0x100
struct omap2_mcspi_platform_config {
@@ -109,9 +99,6 @@ struct mcspi {
};
struct omap3_spi_priv {
#if !CONFIG_IS_ENABLED(DM_SPI)
struct spi_slave slave;
#endif
struct mcspi *regs;
unsigned int cs;
unsigned int freq;
@@ -455,128 +442,6 @@ static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
writel(conf, &priv->regs->modulctrl);
}
#if !CONFIG_IS_ENABLED(DM_SPI)
static inline struct omap3_spi_priv *to_omap3_spi(struct spi_slave *slave)
{
return container_of(slave, struct omap3_spi_priv, slave);
}
void spi_free_slave(struct spi_slave *slave)
{
struct omap3_spi_priv *priv = to_omap3_spi(slave);
free(priv);
}
int spi_claim_bus(struct spi_slave *slave)
{
struct omap3_spi_priv *priv = to_omap3_spi(slave);
spi_reset(priv->regs);
_omap3_spi_claim_bus(priv);
_omap3_spi_set_wordlen(priv);
_omap3_spi_set_mode(priv);
_omap3_spi_set_speed(priv);
return 0;
}
void spi_release_bus(struct spi_slave *slave)
{
struct omap3_spi_priv *priv = to_omap3_spi(slave);
writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
}
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
struct omap3_spi_priv *priv;
struct mcspi *regs;
/*
* OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules)
* with different number of chip selects (CS, channels):
* McSPI1 has 4 CS (bus 0, cs 0 - 3)
* McSPI2 has 2 CS (bus 1, cs 0 - 1)
* McSPI3 has 2 CS (bus 2, cs 0 - 1)
* McSPI4 has 1 CS (bus 3, cs 0)
*/
switch (bus) {
case 0:
regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
break;
#ifdef OMAP3_MCSPI2_BASE
case 1:
regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
break;
#endif
#ifdef OMAP3_MCSPI3_BASE
case 2:
regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
break;
#endif
#ifdef OMAP3_MCSPI4_BASE
case 3:
regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
break;
#endif
default:
printf("SPI error: unsupported bus %i. Supported busses 0 - 3\n", bus);
return NULL;
}
if (((bus == 0) && (cs > 3)) ||
((bus == 1) && (cs > 1)) ||
((bus == 2) && (cs > 1)) ||
((bus == 3) && (cs > 0))) {
printf("SPI error: unsupported chip select %i on bus %i\n", cs, bus);
return NULL;
}
if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
printf("SPI error: unsupported frequency %i Hz. Max frequency is 48 MHz\n",
max_hz);
return NULL;
}
if (mode > SPI_MODE_3) {
printf("SPI error: unsupported SPI mode %i\n", mode);
return NULL;
}
priv = spi_alloc_slave(struct omap3_spi_priv, bus, cs);
if (!priv) {
printf("SPI error: malloc of SPI structure failed\n");
return NULL;
}
priv->regs = regs;
priv->cs = cs;
priv->freq = max_hz;
priv->mode = mode;
priv->wordlen = priv->slave.wordlen;
#if 0
/* Please migrate to DM_SPI support for this feature. */
priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
#endif
return &priv->slave;
}
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
struct omap3_spi_priv *priv = to_omap3_spi(slave);
return _spi_xfer(priv, bitlen, dout, din, flags);
}
#else
static int omap3_spi_claim_bus(struct udevice *dev)
{
struct udevice *bus = dev->parent;
@@ -701,4 +566,3 @@ U_BOOT_DRIVER(omap3_spi) = {
.ops = &omap3_spi_ops,
.priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
};
#endif

View File

@@ -61,10 +61,12 @@ static int soft_spi_sda(struct udevice *dev, int bit)
static int soft_spi_cs_activate(struct udevice *dev)
{
struct udevice *bus = dev_get_parent(dev);
struct soft_spi_priv *priv = dev_get_priv(bus);
struct soft_spi_platdata *plat = dev_get_platdata(bus);
int cidle = !!(priv->mode & SPI_CPOL);
dm_gpio_set_value(&plat->cs, 0);
dm_gpio_set_value(&plat->sclk, 0);
dm_gpio_set_value(&plat->sclk, cidle); /* to idle */
dm_gpio_set_value(&plat->cs, 1);
return 0;
@@ -82,11 +84,14 @@ static int soft_spi_cs_deactivate(struct udevice *dev)
static int soft_spi_claim_bus(struct udevice *dev)
{
struct udevice *bus = dev_get_parent(dev);
struct soft_spi_priv *priv = dev_get_priv(bus);
int cidle = !!(priv->mode & SPI_CPOL);
/*
* Make sure the SPI clock is in idle state as defined for
* this slave.
*/
return soft_spi_scl(dev, 0);
return soft_spi_scl(dev, cidle);
}
static int soft_spi_release_bus(struct udevice *dev)
@@ -117,7 +122,8 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
uchar tmpdout = 0;
const u8 *txd = dout;
u8 *rxd = din;
int cpha = priv->mode & SPI_CPHA;
int cpha = !!(priv->mode & SPI_CPHA);
int cidle = !!(priv->mode & SPI_CPOL);
unsigned int j;
debug("spi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
@@ -143,22 +149,42 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
tmpdin = 0;
}
if (!cpha)
soft_spi_scl(dev, 0);
/*
* CPOL 0: idle is low (0), active is high (1)
* CPOL 1: idle is high (1), active is low (0)
*/
/*
* drive bit
* CPHA 1: CLK from idle to active
*/
if (cpha)
soft_spi_scl(dev, !cidle);
if ((plat->flags & SPI_MASTER_NO_TX) == 0)
soft_spi_sda(dev, !!(tmpdout & 0x80));
udelay(plat->spi_delay_us);
if (cpha)
soft_spi_scl(dev, 0);
/*
* sample bit
* CPHA 0: CLK from idle to active
* CPHA 1: CLK from active to idle
*/
if (!cpha)
soft_spi_scl(dev, !cidle);
else
soft_spi_scl(dev, 1);
soft_spi_scl(dev, cidle);
tmpdin <<= 1;
if ((plat->flags & SPI_MASTER_NO_RX) == 0)
tmpdin |= dm_gpio_get_value(&plat->miso);
tmpdout <<= 1;
udelay(plat->spi_delay_us);
if (cpha)
soft_spi_scl(dev, 1);
/*
* drive bit
* CPHA 0: CLK from active to idle
*/
if (!cpha)
soft_spi_scl(dev, cidle);
}
/*
* If the number of bits isn't a multiple of 8, shift the last
@@ -179,7 +205,7 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
static int soft_spi_set_speed(struct udevice *dev, unsigned int speed)
{
/* Accept any speed */
/* Ignore any speed settings. Speed is implemented via "spi-delay-us" */
return 0;
}