Commit f56be67b authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/mxs', 'spi/topic/pxa',...

Merge remote-tracking branches 'spi/topic/mxs', 'spi/topic/pxa', 'spi/topic/rockchip', 'spi/topic/samsung' and 'spi/topic/sirf' into spi-next
...@@ -9,7 +9,7 @@ Required SoC Specific Properties: ...@@ -9,7 +9,7 @@ Required SoC Specific Properties:
- samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
- samsung,s3c6410-spi: for s3c6410 platforms - samsung,s3c6410-spi: for s3c6410 platforms
- samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
- samsung,exynos4210-spi: for exynos4 and exynos5 platforms - samsung,exynos7-spi: for exynos7 platforms
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
......
...@@ -459,7 +459,7 @@ config SPI_S3C24XX_FIQ ...@@ -459,7 +459,7 @@ config SPI_S3C24XX_FIQ
config SPI_S3C64XX config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI" tristate "Samsung S3C64XX series type SPI"
depends on PLAT_SAMSUNG depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
select S3C64XX_PL080 if ARCH_S3C64XX select S3C64XX_PL080 if ARCH_S3C64XX
help help
SPI driver for Samsung S3C64XX and newer SoCs. SPI driver for Samsung S3C64XX and newer SoCs.
......
...@@ -182,7 +182,6 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, ...@@ -182,7 +182,6 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
int min, ret; int min, ret;
u32 ctrl0; u32 ctrl0;
struct page *vm_page; struct page *vm_page;
void *sg_buf;
struct { struct {
u32 pio[4]; u32 pio[4];
struct scatterlist sg; struct scatterlist sg;
...@@ -232,13 +231,14 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, ...@@ -232,13 +231,14 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
ret = -ENOMEM; ret = -ENOMEM;
goto err_vmalloc; goto err_vmalloc;
} }
sg_buf = page_address(vm_page) +
((size_t)buf & ~PAGE_MASK); sg_init_table(&dma_xfer[sg_count].sg, 1);
sg_set_page(&dma_xfer[sg_count].sg, vm_page,
min, offset_in_page(buf));
} else { } else {
sg_buf = buf; sg_init_one(&dma_xfer[sg_count].sg, buf, min);
} }
sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min);
ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
(flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
...@@ -511,7 +511,7 @@ static int mxs_spi_probe(struct platform_device *pdev) ...@@ -511,7 +511,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
init_completion(&spi->c); init_completion(&spi->c);
ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0, ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0,
DRIVER_NAME, ssp); dev_name(&pdev->dev), ssp);
if (ret) if (ret)
goto out_master_free; goto out_master_free;
......
...@@ -19,6 +19,7 @@ enum { ...@@ -19,6 +19,7 @@ enum {
PORT_BSW0, PORT_BSW0,
PORT_BSW1, PORT_BSW1,
PORT_BSW2, PORT_BSW2,
PORT_QUARK_X1000,
}; };
struct pxa_spi_info { struct pxa_spi_info {
...@@ -92,6 +93,12 @@ static struct pxa_spi_info spi_info_configs[] = { ...@@ -92,6 +93,12 @@ static struct pxa_spi_info spi_info_configs[] = {
.tx_param = &bsw2_tx_param, .tx_param = &bsw2_tx_param,
.rx_param = &bsw2_rx_param, .rx_param = &bsw2_rx_param,
}, },
[PORT_QUARK_X1000] = {
.type = QUARK_X1000_SSP,
.port_id = -1,
.num_chipselect = 1,
.max_clk_rate = 50000000,
},
}; };
static int pxa2xx_spi_pci_probe(struct pci_dev *dev, static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
...@@ -191,6 +198,7 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev) ...@@ -191,6 +198,7 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev)
static const struct pci_device_id pxa2xx_spi_pci_devices[] = { static const struct pci_device_id pxa2xx_spi_pci_devices[] = {
{ PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 },
{ PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 },
{ PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT },
{ PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 }, { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 },
{ PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 },
......
This diff is collapsed.
...@@ -93,6 +93,7 @@ struct driver_data { ...@@ -93,6 +93,7 @@ struct driver_data {
struct chip_data { struct chip_data {
u32 cr0; u32 cr0;
u32 cr1; u32 cr1;
u32 dds_rate;
u32 psp; u32 psp;
u32 timeout; u32 timeout;
u8 n_bytes; u8 n_bytes;
...@@ -126,6 +127,7 @@ DEFINE_SSP_REG(SSCR1, 0x04) ...@@ -126,6 +127,7 @@ DEFINE_SSP_REG(SSCR1, 0x04)
DEFINE_SSP_REG(SSSR, 0x08) DEFINE_SSP_REG(SSSR, 0x08)
DEFINE_SSP_REG(SSITR, 0x0c) DEFINE_SSP_REG(SSITR, 0x0c)
DEFINE_SSP_REG(SSDR, 0x10) DEFINE_SSP_REG(SSDR, 0x10)
DEFINE_SSP_REG(DDS_RATE, 0x28) /* DDS Clock Rate */
DEFINE_SSP_REG(SSTO, 0x28) DEFINE_SSP_REG(SSTO, 0x28)
DEFINE_SSP_REG(SSPSP, 0x2c) DEFINE_SSP_REG(SSPSP, 0x2c)
DEFINE_SSP_REG(SSITF, SSITF) DEFINE_SSP_REG(SSITF, SSITF)
...@@ -141,18 +143,22 @@ DEFINE_SSP_REG(SSIRF, SSIRF) ...@@ -141,18 +143,22 @@ DEFINE_SSP_REG(SSIRF, SSIRF)
static inline int pxa25x_ssp_comp(struct driver_data *drv_data) static inline int pxa25x_ssp_comp(struct driver_data *drv_data)
{ {
if (drv_data->ssp_type == PXA25x_SSP) switch (drv_data->ssp_type) {
case PXA25x_SSP:
case CE4100_SSP:
case QUARK_X1000_SSP:
return 1; return 1;
if (drv_data->ssp_type == CE4100_SSP) default:
return 1; return 0;
return 0; }
} }
static inline void write_SSSR_CS(struct driver_data *drv_data, u32 val) static inline void write_SSSR_CS(struct driver_data *drv_data, u32 val)
{ {
void __iomem *reg = drv_data->ioaddr; void __iomem *reg = drv_data->ioaddr;
if (drv_data->ssp_type == CE4100_SSP) if (drv_data->ssp_type == CE4100_SSP ||
drv_data->ssp_type == QUARK_X1000_SSP)
val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK; val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK;
write_SSSR(val, reg); write_SSSR(val, reg);
......
...@@ -749,8 +749,6 @@ static int rockchip_spi_remove(struct platform_device *pdev) ...@@ -749,8 +749,6 @@ static int rockchip_spi_remove(struct platform_device *pdev)
if (rs->dma_rx.ch) if (rs->dma_rx.ch)
dma_release_channel(rs->dma_rx.ch); dma_release_channel(rs->dma_rx.ch);
spi_master_put(master);
return 0; return 0;
} }
......
...@@ -33,8 +33,9 @@ ...@@ -33,8 +33,9 @@
#include <linux/platform_data/spi-s3c64xx.h> #include <linux/platform_data/spi-s3c64xx.h>
#define MAX_SPI_PORTS 3 #define MAX_SPI_PORTS 6
#define S3C64XX_SPI_QUIRK_POLL (1 << 0) #define S3C64XX_SPI_QUIRK_POLL (1 << 0)
#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
/* Registers and bit-fields */ /* Registers and bit-fields */
...@@ -78,6 +79,7 @@ ...@@ -78,6 +79,7 @@
#define S3C64XX_SPI_SLAVE_AUTO (1<<1) #define S3C64XX_SPI_SLAVE_AUTO (1<<1)
#define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0) #define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0)
#define S3C64XX_SPI_SLAVE_NSC_CNT_2 (2<<4)
#define S3C64XX_SPI_INT_TRAILING_EN (1<<6) #define S3C64XX_SPI_INT_TRAILING_EN (1<<6)
#define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5) #define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5)
...@@ -344,16 +346,8 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) ...@@ -344,16 +346,8 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
spi->dma_tx = sdd->tx_dma.ch; spi->dma_tx = sdd->tx_dma.ch;
} }
ret = pm_runtime_get_sync(&sdd->pdev->dev);
if (ret < 0) {
dev_err(dev, "Failed to enable device: %d\n", ret);
goto out_tx;
}
return 0; return 0;
out_tx:
dma_release_channel(sdd->tx_dma.ch);
out_rx: out_rx:
dma_release_channel(sdd->rx_dma.ch); dma_release_channel(sdd->rx_dma.ch);
out: out:
...@@ -370,7 +364,6 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) ...@@ -370,7 +364,6 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
dma_release_channel(sdd->tx_dma.ch); dma_release_channel(sdd->tx_dma.ch);
} }
pm_runtime_put(&sdd->pdev->dev);
return 0; return 0;
} }
...@@ -717,7 +710,12 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master, ...@@ -717,7 +710,12 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
enable_datapath(sdd, spi, xfer, use_dma); enable_datapath(sdd, spi, xfer, use_dma);
/* Start the signals */ /* Start the signals */
writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
else
writel(readl(sdd->regs + S3C64XX_SPI_SLAVE_SEL)
| S3C64XX_SPI_SLAVE_AUTO | S3C64XX_SPI_SLAVE_NSC_CNT_2,
sdd->regs + S3C64XX_SPI_SLAVE_SEL);
spin_unlock_irqrestore(&sdd->lock, flags); spin_unlock_irqrestore(&sdd->lock, flags);
...@@ -866,13 +864,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi) ...@@ -866,13 +864,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
} }
pm_runtime_put(&sdd->pdev->dev); pm_runtime_put(&sdd->pdev->dev);
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
return 0; return 0;
setup_exit: setup_exit:
pm_runtime_put(&sdd->pdev->dev); pm_runtime_put(&sdd->pdev->dev);
/* setup() returns with device de-selected */ /* setup() returns with device de-selected */
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
if (gpio_is_valid(spi->cs_gpio)) if (gpio_is_valid(spi->cs_gpio))
gpio_free(spi->cs_gpio); gpio_free(spi->cs_gpio);
...@@ -946,7 +946,8 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) ...@@ -946,7 +946,8 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
sdd->cur_speed = 0; sdd->cur_speed = 0;
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
/* Disable Interrupts - we use Polling if not DMA mode */ /* Disable Interrupts - we use Polling if not DMA mode */
writel(0, regs + S3C64XX_SPI_INT_EN); writel(0, regs + S3C64XX_SPI_INT_EN);
...@@ -1341,6 +1342,15 @@ static struct s3c64xx_spi_port_config exynos5440_spi_port_config = { ...@@ -1341,6 +1342,15 @@ static struct s3c64xx_spi_port_config exynos5440_spi_port_config = {
.quirks = S3C64XX_SPI_QUIRK_POLL, .quirks = S3C64XX_SPI_QUIRK_POLL,
}; };
static struct s3c64xx_spi_port_config exynos7_spi_port_config = {
.fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F, 0x7F, 0x7F, 0x1ff},
.rx_lvl_offset = 15,
.tx_st_done = 25,
.high_speed = true,
.clk_from_cmu = true,
.quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
};
static struct platform_device_id s3c64xx_spi_driver_ids[] = { static struct platform_device_id s3c64xx_spi_driver_ids[] = {
{ {
.name = "s3c2443-spi", .name = "s3c2443-spi",
...@@ -1374,6 +1384,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = { ...@@ -1374,6 +1384,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
{ .compatible = "samsung,exynos5440-spi", { .compatible = "samsung,exynos5440-spi",
.data = (void *)&exynos5440_spi_port_config, .data = (void *)&exynos5440_spi_port_config,
}, },
{ .compatible = "samsung,exynos7-spi",
.data = (void *)&exynos7_spi_port_config,
},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match); MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/dma-direction.h> #include <linux/dma-direction.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/reset.h>
#define DRIVER_NAME "sirfsoc_spi" #define DRIVER_NAME "sirfsoc_spi"
...@@ -134,6 +135,7 @@ ...@@ -134,6 +135,7 @@
ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE)) ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE))
#define SIRFSOC_MAX_CMD_BYTES 4 #define SIRFSOC_MAX_CMD_BYTES 4
#define SIRFSOC_SPI_DEFAULT_FRQ 1000000
struct sirfsoc_spi { struct sirfsoc_spi {
struct spi_bitbang bitbang; struct spi_bitbang bitbang;
...@@ -629,9 +631,6 @@ static int spi_sirfsoc_setup(struct spi_device *spi) ...@@ -629,9 +631,6 @@ static int spi_sirfsoc_setup(struct spi_device *spi)
{ {
struct sirfsoc_spi *sspi; struct sirfsoc_spi *sspi;
if (!spi->max_speed_hz)
return -EINVAL;
sspi = spi_master_get_devdata(spi->master); sspi = spi_master_get_devdata(spi->master);
if (spi->cs_gpio == -ENOENT) if (spi->cs_gpio == -ENOENT)
...@@ -649,6 +648,12 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) ...@@ -649,6 +648,12 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
int irq; int irq;
int i, ret; int i, ret;
ret = device_reset(&pdev->dev);
if (ret) {
dev_err(&pdev->dev, "SPI reset failed!\n");
return ret;
}
master = spi_alloc_master(&pdev->dev, sizeof(*sspi)); master = spi_alloc_master(&pdev->dev, sizeof(*sspi));
if (!master) { if (!master) {
dev_err(&pdev->dev, "Unable to allocate SPI master\n"); dev_err(&pdev->dev, "Unable to allocate SPI master\n");
...@@ -683,6 +688,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) ...@@ -683,6 +688,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) | master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) |
SPI_BPW_MASK(16) | SPI_BPW_MASK(32); SPI_BPW_MASK(16) | SPI_BPW_MASK(32);
master->max_speed_hz = SIRFSOC_SPI_DEFAULT_FRQ;
sspi->bitbang.master->dev.of_node = pdev->dev.of_node; sspi->bitbang.master->dev.of_node = pdev->dev.of_node;
/* request DMA channels */ /* request DMA channels */
......
...@@ -108,6 +108,25 @@ ...@@ -108,6 +108,25 @@
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */
#endif #endif
/* QUARK_X1000 SSCR0 bit definition */
#define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */
#define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */
#define QUARK_X1000_SSCR0_FRF (0x3 << 5) /* FRame Format (mask) */
#define QUARK_X1000_SSCR0_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */
#define RX_THRESH_QUARK_X1000_DFLT 1
#define TX_THRESH_QUARK_X1000_DFLT 16
#define QUARK_X1000_SSSR_TFL_MASK (0x1F << 8) /* Transmit FIFO Level mask */
#define QUARK_X1000_SSSR_RFL_MASK (0x1F << 13) /* Receive FIFO Level mask */
#define QUARK_X1000_SSCR1_TFT (0x1F << 6) /* Transmit FIFO Threshold (mask) */
#define QUARK_X1000_SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..32] */
#define QUARK_X1000_SSCR1_RFT (0x1F << 11) /* Receive FIFO Threshold (mask) */
#define QUARK_X1000_SSCR1_RxTresh(x) (((x) - 1) << 11) /* level [1..32] */
#define QUARK_X1000_SSCR1_STRF (1 << 17) /* Select FIFO or EFWR */
#define QUARK_X1000_SSCR1_EFWR (1 << 16) /* Enable FIFO Write/Read */
/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ /* extra bits in PXA255, PXA26x and PXA27x SSP ports */
#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */
#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ #define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */
...@@ -175,6 +194,7 @@ enum pxa_ssp_type { ...@@ -175,6 +194,7 @@ enum pxa_ssp_type {
PXA910_SSP, PXA910_SSP,
CE4100_SSP, CE4100_SSP,
LPSS_SSP, LPSS_SSP,
QUARK_X1000_SSP,
}; };
struct ssp_device { struct ssp_device {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment