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:
- samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
- samsung,s3c6410-spi: for s3c6410 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
region.
......
......@@ -459,7 +459,7 @@ config SPI_S3C24XX_FIQ
config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI"
depends on PLAT_SAMSUNG
depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
select S3C64XX_PL080 if ARCH_S3C64XX
help
SPI driver for Samsung S3C64XX and newer SoCs.
......
......@@ -182,7 +182,6 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
int min, ret;
u32 ctrl0;
struct page *vm_page;
void *sg_buf;
struct {
u32 pio[4];
struct scatterlist sg;
......@@ -232,13 +231,14 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
ret = -ENOMEM;
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 {
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,
(flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
......@@ -511,7 +511,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
init_completion(&spi->c);
ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0,
DRIVER_NAME, ssp);
dev_name(&pdev->dev), ssp);
if (ret)
goto out_master_free;
......
......@@ -19,6 +19,7 @@ enum {
PORT_BSW0,
PORT_BSW1,
PORT_BSW2,
PORT_QUARK_X1000,
};
struct pxa_spi_info {
......@@ -92,6 +93,12 @@ static struct pxa_spi_info spi_info_configs[] = {
.tx_param = &bsw2_tx_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,
......@@ -191,6 +198,7 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev)
static const struct pci_device_id pxa2xx_spi_pci_devices[] = {
{ PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 },
{ PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 },
{ PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT },
{ PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 },
{ PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 },
......
This diff is collapsed.
......@@ -93,6 +93,7 @@ struct driver_data {
struct chip_data {
u32 cr0;
u32 cr1;
u32 dds_rate;
u32 psp;
u32 timeout;
u8 n_bytes;
......@@ -126,6 +127,7 @@ DEFINE_SSP_REG(SSCR1, 0x04)
DEFINE_SSP_REG(SSSR, 0x08)
DEFINE_SSP_REG(SSITR, 0x0c)
DEFINE_SSP_REG(SSDR, 0x10)
DEFINE_SSP_REG(DDS_RATE, 0x28) /* DDS Clock Rate */
DEFINE_SSP_REG(SSTO, 0x28)
DEFINE_SSP_REG(SSPSP, 0x2c)
DEFINE_SSP_REG(SSITF, SSITF)
......@@ -141,18 +143,22 @@ DEFINE_SSP_REG(SSIRF, SSIRF)
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;
if (drv_data->ssp_type == CE4100_SSP)
return 1;
return 0;
default:
return 0;
}
}
static inline void write_SSSR_CS(struct driver_data *drv_data, u32 val)
{
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;
write_SSSR(val, reg);
......
......@@ -749,8 +749,6 @@ static int rockchip_spi_remove(struct platform_device *pdev)
if (rs->dma_rx.ch)
dma_release_channel(rs->dma_rx.ch);
spi_master_put(master);
return 0;
}
......
......@@ -33,8 +33,9 @@
#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_CS_AUTO (1 << 1)
/* Registers and bit-fields */
......@@ -78,6 +79,7 @@
#define S3C64XX_SPI_SLAVE_AUTO (1<<1)
#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_RX_OVERRUN_EN (1<<5)
......@@ -344,16 +346,8 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
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;
out_tx:
dma_release_channel(sdd->tx_dma.ch);
out_rx:
dma_release_channel(sdd->rx_dma.ch);
out:
......@@ -370,7 +364,6 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
dma_release_channel(sdd->tx_dma.ch);
}
pm_runtime_put(&sdd->pdev->dev);
return 0;
}
......@@ -717,7 +710,12 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
enable_datapath(sdd, spi, xfer, use_dma);
/* 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);
......@@ -866,13 +864,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
}
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;
setup_exit:
pm_runtime_put(&sdd->pdev->dev);
/* 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))
gpio_free(spi->cs_gpio);
......@@ -946,7 +946,8 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
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 */
writel(0, regs + S3C64XX_SPI_INT_EN);
......@@ -1341,6 +1342,15 @@ static struct s3c64xx_spi_port_config exynos5440_spi_port_config = {
.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[] = {
{
.name = "s3c2443-spi",
......@@ -1374,6 +1384,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
{ .compatible = "samsung,exynos5440-spi",
.data = (void *)&exynos5440_spi_port_config,
},
{ .compatible = "samsung,exynos7-spi",
.data = (void *)&exynos7_spi_port_config,
},
{ },
};
MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
......
......@@ -23,6 +23,7 @@
#include <linux/dmaengine.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
#include <linux/reset.h>
#define DRIVER_NAME "sirfsoc_spi"
......@@ -134,6 +135,7 @@
ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE))
#define SIRFSOC_MAX_CMD_BYTES 4
#define SIRFSOC_SPI_DEFAULT_FRQ 1000000
struct sirfsoc_spi {
struct spi_bitbang bitbang;
......@@ -629,9 +631,6 @@ static int spi_sirfsoc_setup(struct spi_device *spi)
{
struct sirfsoc_spi *sspi;
if (!spi->max_speed_hz)
return -EINVAL;
sspi = spi_master_get_devdata(spi->master);
if (spi->cs_gpio == -ENOENT)
......@@ -649,6 +648,12 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
int irq;
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));
if (!master) {
dev_err(&pdev->dev, "Unable to allocate SPI master\n");
......@@ -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->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) |
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;
/* request DMA channels */
......
......@@ -108,6 +108,25 @@
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */
#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 */
#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */
#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */
......@@ -175,6 +194,7 @@ enum pxa_ssp_type {
PXA910_SSP,
CE4100_SSP,
LPSS_SSP,
QUARK_X1000_SSP,
};
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