blob: bbe8dee681a5d2b9a503d7f59b22e79d7a3e9014 [file] [log] [blame]
Jan Engelhardt96de0e22007-10-19 23:21:04 +02001PXA2xx SPI on SSP driver HOWTO
Stephen Streete0c99052006-03-07 23:53:24 -08002===================================================
3This a mini howto on the pxa2xx_spi driver. The driver turns a PXA2xx
4synchronous serial port into a SPI master controller
5(see Documentation/spi/spi_summary). The driver has the following features
6
7- Support for any PXA2xx SSP
8- SSP PIO and SSP DMA data transfers.
9- External and Internal (SSPFRM) chip selects.
10- Per slave device (chip) configuration.
11- Full suspend, freeze, resume support.
12
13The driver is built around a "spi_message" fifo serviced by workqueue and a
14tasklet. The workqueue, "pump_messages", drives message fifo and the tasklet
15(pump_transfer) is responsible for queuing SPI transactions and setting up and
16launching the dma/interrupt driven transfers.
17
18Declaring PXA2xx Master Controllers
19-----------------------------------
20Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a
21"platform device". The master configuration is passed to the driver via a table
Russell Kinga09e64f2008-08-05 16:14:15 +010022found in arch/arm/mach-pxa/include/mach/pxa2xx_spi.h:
Stephen Streete0c99052006-03-07 23:53:24 -080023
24struct pxa2xx_spi_master {
25 enum pxa_ssp_type ssp_type;
26 u32 clock_enable;
27 u16 num_chipselect;
28 u8 enable_dma;
29};
30
31The "pxa2xx_spi_master.ssp_type" field must have a value between 1 and 3 and
32informs the driver which features a particular SSP supports.
33
34The "pxa2xx_spi_master.clock_enable" field is used to enable/disable the
35corresponding SSP peripheral block in the "Clock Enable Register (CKEN"). See
36the "PXA2xx Developer Manual" section "Clocks and Power Management".
37
38The "pxa2xx_spi_master.num_chipselect" field is used to determine the number of
39slave device (chips) attached to this SPI master.
40
41The "pxa2xx_spi_master.enable_dma" field informs the driver that SSP DMA should
42be used. This caused the driver to acquire two DMA channels: rx_channel and
43tx_channel. The rx_channel has a higher DMA service priority the tx_channel.
44See the "PXA2xx Developer Manual" section "DMA Controller".
45
46NSSP MASTER SAMPLE
47------------------
48Below is a sample configuration using the PXA255 NSSP.
49
50static struct resource pxa_spi_nssp_resources[] = {
51 [0] = {
52 .start = __PREG(SSCR0_P(2)), /* Start address of NSSP */
53 .end = __PREG(SSCR0_P(2)) + 0x2c, /* Range of registers */
54 .flags = IORESOURCE_MEM,
55 },
56 [1] = {
57 .start = IRQ_NSSP, /* NSSP IRQ */
58 .end = IRQ_NSSP,
59 .flags = IORESOURCE_IRQ,
60 },
61};
62
63static struct pxa2xx_spi_master pxa_nssp_master_info = {
64 .ssp_type = PXA25x_NSSP, /* Type of SSP */
Eric Miao7053acb2007-04-05 04:07:20 +010065 .clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */
Stephen Streete0c99052006-03-07 23:53:24 -080066 .num_chipselect = 1, /* Matches the number of chips attached to NSSP */
67 .enable_dma = 1, /* Enables NSSP DMA */
68};
69
70static struct platform_device pxa_spi_nssp = {
71 .name = "pxa2xx-spi", /* MUST BE THIS VALUE, so device match driver */
72 .id = 2, /* Bus number, MUST MATCH SSP number 1..n */
73 .resource = pxa_spi_nssp_resources,
74 .num_resources = ARRAY_SIZE(pxa_spi_nssp_resources),
75 .dev = {
76 .platform_data = &pxa_nssp_master_info, /* Passed to driver */
77 },
78};
79
80static struct platform_device *devices[] __initdata = {
81 &pxa_spi_nssp,
82};
83
84static void __init board_init(void)
85{
86 (void)platform_add_device(devices, ARRAY_SIZE(devices));
87}
88
89Declaring Slave Devices
90-----------------------
91Typically each SPI slave (chip) is defined in the arch/.../mach-*/board-*.c
92using the "spi_board_info" structure found in "linux/spi/spi.h". See
93"Documentation/spi/spi_summary" for additional information.
94
95Each slave device attached to the PXA must provide slave specific configuration
96information via the structure "pxa2xx_spi_chip" found in
Russell Kinga09e64f2008-08-05 16:14:15 +010097"arch/arm/mach-pxa/include/mach/pxa2xx_spi.h". The pxa2xx_spi master controller driver
Stephen Streete0c99052006-03-07 23:53:24 -080098will uses the configuration whenever the driver communicates with the slave
99device.
100
101struct pxa2xx_spi_chip {
102 u8 tx_threshold;
103 u8 rx_threshold;
104 u8 dma_burst_size;
Stephen Street8d94cc52006-12-10 02:18:54 -0800105 u32 timeout;
Stephen Streete0c99052006-03-07 23:53:24 -0800106 u8 enable_loopback;
107 void (*cs_control)(u32 command);
108};
109
110The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are
111used to configure the SSP hardware fifo. These fields are critical to the
112performance of pxa2xx_spi driver and misconfiguration will result in rx
113fifo overruns (especially in PIO mode transfers). Good default values are
114
115 .tx_threshold = 12,
116 .rx_threshold = 4,
117
118The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA
119engine and is related the "spi_device.bits_per_word" field. Read and understand
120the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers
121to determine the correct value. An SSP configured for byte-wide transfers would
122use a value of 8.
123
Stephen Street8d94cc52006-12-10 02:18:54 -0800124The "pxa2xx_spi_chip.timeout" fields is used to efficiently handle
Stephen Streete0c99052006-03-07 23:53:24 -0800125trailing bytes in the SSP receiver fifo. The correct value for this field is
126dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific
Paolo Ornati670e9f32006-10-03 22:57:56 +0200127slave device. Please note that the PXA2xx SSP 1 does not support trailing byte
Stephen Streete0c99052006-03-07 23:53:24 -0800128timeouts and must busy-wait any trailing bytes.
129
130The "pxa2xx_spi_chip.enable_loopback" field is used to place the SSP porting
131into internal loopback mode. In this mode the SSP controller internally
Paolo Ornati670e9f32006-10-03 22:57:56 +0200132connects the SSPTX pin to the SSPRX pin. This is useful for initial setup
Stephen Streete0c99052006-03-07 23:53:24 -0800133testing.
134
135The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific
136function for asserting/deasserting a slave device chip select. If the field is
137NULL, the pxa2xx_spi master controller driver assumes that the SSP port is
138configured to use SSPFRM instead.
139
140NSSP SALVE SAMPLE
141-----------------
142The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the
143"spi_board_info.controller_data" field. Below is a sample configuration using
144the PXA255 NSSP.
145
146/* Chip Select control for the CS8415A SPI slave device */
147static void cs8415a_cs_control(u32 command)
148{
149 if (command & PXA2XX_CS_ASSERT)
150 GPCR(2) = GPIO_bit(2);
151 else
152 GPSR(2) = GPIO_bit(2);
153}
154
155/* Chip Select control for the CS8405A SPI slave device */
156static void cs8405a_cs_control(u32 command)
157{
158 if (command & PXA2XX_CS_ASSERT)
159 GPCR(3) = GPIO_bit(3);
160 else
161 GPSR(3) = GPIO_bit(3);
162}
163
164static struct pxa2xx_spi_chip cs8415a_chip_info = {
Stephen Street8d94cc52006-12-10 02:18:54 -0800165 .tx_threshold = 8, /* SSP hardward FIFO threshold */
166 .rx_threshold = 8, /* SSP hardward FIFO threshold */
Stephen Streete0c99052006-03-07 23:53:24 -0800167 .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
Stephen Street8d94cc52006-12-10 02:18:54 -0800168 .timeout = 235, /* See Intel documentation */
Stephen Streete0c99052006-03-07 23:53:24 -0800169 .cs_control = cs8415a_cs_control, /* Use external chip select */
170};
171
172static struct pxa2xx_spi_chip cs8405a_chip_info = {
Stephen Street8d94cc52006-12-10 02:18:54 -0800173 .tx_threshold = 8, /* SSP hardward FIFO threshold */
174 .rx_threshold = 8, /* SSP hardward FIFO threshold */
Stephen Streete0c99052006-03-07 23:53:24 -0800175 .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
Stephen Street8d94cc52006-12-10 02:18:54 -0800176 .timeout = 235, /* See Intel documentation */
Stephen Streete0c99052006-03-07 23:53:24 -0800177 .cs_control = cs8405a_cs_control, /* Use external chip select */
178};
179
180static struct spi_board_info streetracer_spi_board_info[] __initdata = {
181 {
182 .modalias = "cs8415a", /* Name of spi_driver for this device */
183 .max_speed_hz = 3686400, /* Run SSP as fast a possbile */
184 .bus_num = 2, /* Framework bus number */
185 .chip_select = 0, /* Framework chip select */
186 .platform_data = NULL; /* No spi_driver specific config */
187 .controller_data = &cs8415a_chip_info, /* Master chip config */
188 .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */
189 },
190 {
191 .modalias = "cs8405a", /* Name of spi_driver for this device */
192 .max_speed_hz = 3686400, /* Run SSP as fast a possbile */
193 .bus_num = 2, /* Framework bus number */
194 .chip_select = 1, /* Framework chip select */
195 .controller_data = &cs8405a_chip_info, /* Master chip config */
196 .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */
197 },
198};
199
200static void __init streetracer_init(void)
201{
202 spi_register_board_info(streetracer_spi_board_info,
203 ARRAY_SIZE(streetracer_spi_board_info));
204}
205
206
207DMA and PIO I/O Support
208-----------------------
209The pxa2xx_spi driver support both DMA and interrupt driven PIO message
210transfers. The driver defaults to PIO mode and DMA transfers must enabled by
Paolo Ornati670e9f32006-10-03 22:57:56 +0200211setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and
Stephen Streete0c99052006-03-07 23:53:24 -0800212ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero. The DMA
213mode support both coherent and stream based DMA mappings.
214
215The following logic is used to determine the type of I/O to be used on
216a per "spi_transfer" basis:
217
218if !enable_dma or dma_burst_size == 0 then
219 always use PIO transfers
220
221if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then
222 use coherent DMA mode
223
224if rx_buf and tx_buf are aligned on 8 byte boundary then
225 use streaming DMA mode
226
227otherwise
228 use PIO transfer
229
230THANKS TO
231---------
232
233David Brownell and others for mentoring the development of this driver.
234