aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2013-01-22 05:26:32 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-08 08:14:40 -0500
commita0d2642e9296882cda3ad03ff3d9a6649cd70439 (patch)
tree4c3f4a29ba904a357789cd7c2286eb035fa16340 /drivers/spi
parentb833172fd8f44fb56e0b3cb810155a6baecc65dc (diff)
spi/pxa2xx: add support for Intel Low Power Subsystem SPI
Intel LPSS SPI is pretty much the same as the PXA27xx SPI except that it has few additional features over the original: o FIFO depth is 256 entries o RX FIFO has one watermark o TX FIFO has two watermarks, low and high o chip select can be controlled by writing to a register The new FIFO registers follow immediately the PXA27xx registers but then there are some additional LPSS private registers at offset 1k or 2k from the base address. For these private registers we add new accessors that take advantage of drv_data->lpss_base once it is resolved. We add a new type LPSS_SSP that can be used to distinguish the LPSS devices from others. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Tested-by: Lu Cao <lucao@marvell.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-pxa2xx.c133
-rw-r--r--drivers/spi/spi-pxa2xx.h6
2 files changed, 135 insertions, 4 deletions
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 8a5ba0aa095a..4bd6b729f710 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs 2 * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
3 * Copyright (C) 2013, Intel Corporation
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -61,6 +62,98 @@ MODULE_ALIAS("platform:pxa2xx-spi");
61 | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ 62 | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \
62 | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) 63 | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
63 64
65#define LPSS_RX_THRESH_DFLT 64
66#define LPSS_TX_LOTHRESH_DFLT 160
67#define LPSS_TX_HITHRESH_DFLT 224
68
69/* Offset from drv_data->lpss_base */
70#define SPI_CS_CONTROL 0x18
71#define SPI_CS_CONTROL_SW_MODE BIT(0)
72#define SPI_CS_CONTROL_CS_HIGH BIT(1)
73
74static bool is_lpss_ssp(const struct driver_data *drv_data)
75{
76 return drv_data->ssp_type == LPSS_SSP;
77}
78
79/*
80 * Read and write LPSS SSP private registers. Caller must first check that
81 * is_lpss_ssp() returns true before these can be called.
82 */
83static u32 __lpss_ssp_read_priv(struct driver_data *drv_data, unsigned offset)
84{
85 WARN_ON(!drv_data->lpss_base);
86 return readl(drv_data->lpss_base + offset);
87}
88
89static void __lpss_ssp_write_priv(struct driver_data *drv_data,
90 unsigned offset, u32 value)
91{
92 WARN_ON(!drv_data->lpss_base);
93 writel(value, drv_data->lpss_base + offset);
94}
95
96/*
97 * lpss_ssp_setup - perform LPSS SSP specific setup
98 * @drv_data: pointer to the driver private data
99 *
100 * Perform LPSS SSP specific setup. This function must be called first if
101 * one is going to use LPSS SSP private registers.
102 */
103static void lpss_ssp_setup(struct driver_data *drv_data)
104{
105 unsigned offset = 0x400;
106 u32 value, orig;
107
108 if (!is_lpss_ssp(drv_data))
109 return;
110
111 /*
112 * Perform auto-detection of the LPSS SSP private registers. They
113 * can be either at 1k or 2k offset from the base address.
114 */
115 orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
116
117 value = orig | SPI_CS_CONTROL_SW_MODE;
118 writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
119 value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
120 if (value != (orig | SPI_CS_CONTROL_SW_MODE)) {
121 offset = 0x800;
122 goto detection_done;
123 }
124
125 value &= ~SPI_CS_CONTROL_SW_MODE;
126 writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
127 value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
128 if (value != orig) {
129 offset = 0x800;
130 goto detection_done;
131 }
132
133detection_done:
134 /* Now set the LPSS base */
135 drv_data->lpss_base = drv_data->ioaddr + offset;
136
137 /* Enable software chip select control */
138 value = SPI_CS_CONTROL_SW_MODE | SPI_CS_CONTROL_CS_HIGH;
139 __lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);
140}
141
142static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)
143{
144 u32 value;
145
146 if (!is_lpss_ssp(drv_data))
147 return;
148
149 value = __lpss_ssp_read_priv(drv_data, SPI_CS_CONTROL);
150 if (enable)
151 value &= ~SPI_CS_CONTROL_CS_HIGH;
152 else
153 value |= SPI_CS_CONTROL_CS_HIGH;
154 __lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);
155}
156
64static void cs_assert(struct driver_data *drv_data) 157static void cs_assert(struct driver_data *drv_data)
65{ 158{
66 struct chip_data *chip = drv_data->cur_chip; 159 struct chip_data *chip = drv_data->cur_chip;
@@ -75,8 +168,12 @@ static void cs_assert(struct driver_data *drv_data)
75 return; 168 return;
76 } 169 }
77 170
78 if (gpio_is_valid(chip->gpio_cs)) 171 if (gpio_is_valid(chip->gpio_cs)) {
79 gpio_set_value(chip->gpio_cs, chip->gpio_cs_inverted); 172 gpio_set_value(chip->gpio_cs, chip->gpio_cs_inverted);
173 return;
174 }
175
176 lpss_ssp_cs_control(drv_data, true);
80} 177}
81 178
82static void cs_deassert(struct driver_data *drv_data) 179static void cs_deassert(struct driver_data *drv_data)
@@ -91,8 +188,12 @@ static void cs_deassert(struct driver_data *drv_data)
91 return; 188 return;
92 } 189 }
93 190
94 if (gpio_is_valid(chip->gpio_cs)) 191 if (gpio_is_valid(chip->gpio_cs)) {
95 gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted); 192 gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted);
193 return;
194 }
195
196 lpss_ssp_cs_control(drv_data, false);
96} 197}
97 198
98int pxa2xx_spi_flush(struct driver_data *drv_data) 199int pxa2xx_spi_flush(struct driver_data *drv_data)
@@ -642,6 +743,13 @@ static void pump_transfers(unsigned long data)
642 write_SSSR_CS(drv_data, drv_data->clear_sr); 743 write_SSSR_CS(drv_data, drv_data->clear_sr);
643 } 744 }
644 745
746 if (is_lpss_ssp(drv_data)) {
747 if ((read_SSIRF(reg) & 0xff) != chip->lpss_rx_threshold)
748 write_SSIRF(chip->lpss_rx_threshold, reg);
749 if ((read_SSITF(reg) & 0xffff) != chip->lpss_tx_threshold)
750 write_SSITF(chip->lpss_tx_threshold, reg);
751 }
752
645 /* see if we need to reload the config registers */ 753 /* see if we need to reload the config registers */
646 if ((read_SSCR0(reg) != cr0) 754 if ((read_SSCR0(reg) != cr0)
647 || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != 755 || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) !=
@@ -754,8 +862,17 @@ static int setup(struct spi_device *spi)
754 struct chip_data *chip; 862 struct chip_data *chip;
755 struct driver_data *drv_data = spi_master_get_devdata(spi->master); 863 struct driver_data *drv_data = spi_master_get_devdata(spi->master);
756 unsigned int clk_div; 864 unsigned int clk_div;
757 uint tx_thres = TX_THRESH_DFLT; 865 uint tx_thres, tx_hi_thres, rx_thres;
758 uint rx_thres = RX_THRESH_DFLT; 866
867 if (is_lpss_ssp(drv_data)) {
868 tx_thres = LPSS_TX_LOTHRESH_DFLT;
869 tx_hi_thres = LPSS_TX_HITHRESH_DFLT;
870 rx_thres = LPSS_RX_THRESH_DFLT;
871 } else {
872 tx_thres = TX_THRESH_DFLT;
873 tx_hi_thres = 0;
874 rx_thres = RX_THRESH_DFLT;
875 }
759 876
760 if (!pxa25x_ssp_comp(drv_data) 877 if (!pxa25x_ssp_comp(drv_data)
761 && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) { 878 && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) {
@@ -808,6 +925,8 @@ static int setup(struct spi_device *spi)
808 chip->timeout = chip_info->timeout; 925 chip->timeout = chip_info->timeout;
809 if (chip_info->tx_threshold) 926 if (chip_info->tx_threshold)
810 tx_thres = chip_info->tx_threshold; 927 tx_thres = chip_info->tx_threshold;
928 if (chip_info->tx_hi_threshold)
929 tx_hi_thres = chip_info->tx_hi_threshold;
811 if (chip_info->rx_threshold) 930 if (chip_info->rx_threshold)
812 rx_thres = chip_info->rx_threshold; 931 rx_thres = chip_info->rx_threshold;
813 chip->enable_dma = drv_data->master_info->enable_dma; 932 chip->enable_dma = drv_data->master_info->enable_dma;
@@ -819,6 +938,10 @@ static int setup(struct spi_device *spi)
819 chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) | 938 chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
820 (SSCR1_TxTresh(tx_thres) & SSCR1_TFT); 939 (SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
821 940
941 chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres);
942 chip->lpss_tx_threshold = SSITF_TxLoThresh(tx_thres)
943 | SSITF_TxHiThresh(tx_hi_thres);
944
822 /* set dma burst and threshold outside of chip_info path so that if 945 /* set dma burst and threshold outside of chip_info path so that if
823 * chip_info goes away after setting chip->enable_dma, the 946 * chip_info goes away after setting chip->enable_dma, the
824 * burst and threshold can still respond to changes in bits_per_word */ 947 * burst and threshold can still respond to changes in bits_per_word */
@@ -1006,6 +1129,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
1006 write_SSTO(0, drv_data->ioaddr); 1129 write_SSTO(0, drv_data->ioaddr);
1007 write_SSPSP(0, drv_data->ioaddr); 1130 write_SSPSP(0, drv_data->ioaddr);
1008 1131
1132 lpss_ssp_setup(drv_data);
1133
1009 tasklet_init(&drv_data->pump_transfers, pump_transfers, 1134 tasklet_init(&drv_data->pump_transfers, pump_transfers,
1010 (unsigned long)drv_data); 1135 (unsigned long)drv_data);
1011 1136
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h
index 97ff4717e6ac..5adc2a11c7bc 100644
--- a/drivers/spi/spi-pxa2xx.h
+++ b/drivers/spi/spi-pxa2xx.h
@@ -86,6 +86,8 @@ struct driver_data {
86 int (*read)(struct driver_data *drv_data); 86 int (*read)(struct driver_data *drv_data);
87 irqreturn_t (*transfer_handler)(struct driver_data *drv_data); 87 irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
88 void (*cs_control)(u32 command); 88 void (*cs_control)(u32 command);
89
90 void __iomem *lpss_base;
89}; 91};
90 92
91struct chip_data { 93struct chip_data {
@@ -97,6 +99,8 @@ struct chip_data {
97 u32 dma_burst_size; 99 u32 dma_burst_size;
98 u32 threshold; 100 u32 threshold;
99 u32 dma_threshold; 101 u32 dma_threshold;
102 u16 lpss_rx_threshold;
103 u16 lpss_tx_threshold;
100 u8 enable_dma; 104 u8 enable_dma;
101 u8 bits_per_word; 105 u8 bits_per_word;
102 u32 speed_hz; 106 u32 speed_hz;
@@ -124,6 +128,8 @@ DEFINE_SSP_REG(SSITR, 0x0c)
124DEFINE_SSP_REG(SSDR, 0x10) 128DEFINE_SSP_REG(SSDR, 0x10)
125DEFINE_SSP_REG(SSTO, 0x28) 129DEFINE_SSP_REG(SSTO, 0x28)
126DEFINE_SSP_REG(SSPSP, 0x2c) 130DEFINE_SSP_REG(SSPSP, 0x2c)
131DEFINE_SSP_REG(SSITF, SSITF)
132DEFINE_SSP_REG(SSIRF, SSIRF)
127 133
128#define START_STATE ((void *)0) 134#define START_STATE ((void *)0)
129#define RUNNING_STATE ((void *)1) 135#define RUNNING_STATE ((void *)1)