1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2016, Linaro Limited
4 *
5 */
6
7 #include <assert.h>
8 #include <drivers/pl022_spi.h>
9 #include <initcall.h>
10 #include <io.h>
11 #include <keep.h>
12 #include <kernel/panic.h>
13 #include <kernel/tee_time.h>
14 #include <platform_config.h>
15 #include <trace.h>
16 #include <util.h>
17
18 /* SPI register offsets */
19 #define SSPCR0 0x000
20 #define SSPCR1 0x004
21 #define SSPDR 0x008
22 #define SSPSR 0x00C
23 #define SSPCPSR 0x010
24 #define SSPIMSC 0x014
25 #define SSPRIS 0x018
26 #define SSPMIS 0x01C
27 #define SSPICR 0x020
28 #define SSPDMACR 0x024
29
30 #ifdef PLATFORM_hikey
31 /* HiKey extensions */
32 #define SSPTXFIFOCR 0x028
33 #define SSPRXFIFOCR 0x02C
34 #define SSPB2BTRANS 0x030
35 #endif
36
37 /* test registers */
38 #define SSPTCR 0x080
39 #define SSPITIP 0x084
40 #define SSPITOP 0x088
41 #define SSPTDR 0x08C
42
43 #define SSPPeriphID0 0xFE0
44 #define SSPPeriphID1 0xFE4
45 #define SSPPeriphID2 0xFE8
46 #define SSPPeriphID3 0xFEC
47
48 #define SSPPCellID0 0xFF0
49 #define SSPPCellID1 0xFF4
50 #define SSPPCellID2 0xFF8
51 #define SSPPCellID3 0xFFC
52
53 /* SPI register masks */
54 #define SSPCR0_SCR SHIFT_U32(0xFF, 8)
55 #define SSPCR0_SPH SHIFT_U32(1, 7)
56 #define SSPCR0_SPH1 SHIFT_U32(1, 7)
57 #define SSPCR0_SPH0 SHIFT_U32(0, 7)
58 #define SSPCR0_SPO SHIFT_U32(1, 6)
59 #define SSPCR0_SPO1 SHIFT_U32(1, 6)
60 #define SSPCR0_SPO0 SHIFT_U32(0, 6)
61 #define SSPCR0_FRF SHIFT_U32(3, 4)
62 #define SSPCR0_FRF_SPI SHIFT_U32(0, 4)
63 #define SSPCR0_DSS SHIFT_U32(0xFF, 0)
64 #define SSPCR0_DSS_16BIT SHIFT_U32(0xF, 0)
65 #define SSPCR0_DSS_8BIT SHIFT_U32(7, 0)
66
67 #define SSPCR1_SOD SHIFT_U32(1, 3)
68 #define SSPCR1_SOD_ENABLE SHIFT_U32(1, 3)
69 #define SSPCR1_SOD_DISABLE SHIFT_U32(0, 3)
70 #define SSPCR1_MS SHIFT_U32(1, 2)
71 #define SSPCR1_MS_SLAVE SHIFT_U32(1, 2)
72 #define SSPCR1_MS_MASTER SHIFT_U32(0, 2)
73 #define SSPCR1_SSE SHIFT_U32(1, 1)
74 #define SSPCR1_SSE_ENABLE SHIFT_U32(1, 1)
75 #define SSPCR1_SSE_DISABLE SHIFT_U32(0, 1)
76 #define SSPCR1_LBM SHIFT_U32(1, 0)
77 #define SSPCR1_LBM_YES SHIFT_U32(1, 0)
78 #define SSPCR1_LBM_NO SHIFT_U32(0, 0)
79
80 #define SSPDR_DATA SHIFT_U32(0xFFFF, 0)
81
82 #define SSPSR_BSY SHIFT_U32(1, 4)
83 #define SSPSR_RNF SHIFT_U32(1, 3)
84 #define SSPSR_RNE SHIFT_U32(1, 2)
85 #define SSPSR_TNF SHIFT_U32(1, 1)
86 #define SSPSR_TFE SHIFT_U32(1, 0)
87
88 #define SSPCPSR_CPSDVR SHIFT_U32(0xFF, 0)
89
90 #define SSPIMSC_TXIM SHIFT_U32(1, 3)
91 #define SSPIMSC_RXIM SHIFT_U32(1, 2)
92 #define SSPIMSC_RTIM SHIFT_U32(1, 1)
93 #define SSPIMSC_RORIM SHIFT_U32(1, 0)
94
95 #define SSPRIS_TXRIS SHIFT_U32(1, 3)
96 #define SSPRIS_RXRIS SHIFT_U32(1, 2)
97 #define SSPRIS_RTRIS SHIFT_U32(1, 1)
98 #define SSPRIS_RORRIS SHIFT_U32(1, 0)
99
100 #define SSPMIS_TXMIS SHIFT_U32(1, 3)
101 #define SSPMIS_RXMIS SHIFT_U32(1, 2)
102 #define SSPMIS_RTMIS SHIFT_U32(1, 1)
103 #define SSPMIS_RORMIS SHIFT_U32(1, 0)
104
105 #define SSPICR_RTIC SHIFT_U32(1, 1)
106 #define SSPICR_RORIC SHIFT_U32(1, 0)
107
108 #define SSPDMACR_TXDMAE SHIFT_U32(1, 1)
109 #define SSPDMACR_RXDMAE SHIFT_U32(1, 0)
110
111 #define SSPPeriphID0_PartNumber0 SHIFT_U32(0xFF, 0) /* 0x22 */
112 #define SSPPeriphID1_Designer0 SHIFT_U32(0xF, 4) /* 0x1 */
113 #define SSPPeriphID1_PartNumber1 SHIFT_U32(0xF, 0) /* 0x0 */
114 #define SSPPeriphID2_Revision SHIFT_U32(0xF, 4)
115 #define SSPPeriphID2_Designer1 SHIFT_U32(0xF, 0) /* 0x4 */
116 #define SSPPeriphID3_Configuration SHIFT_U32(0xFF, 0) /* 0x00 */
117
118 #define SSPPCellID_0 SHIFT_U32(0xFF, 0) /* 0x0D */
119 #define SSPPCellID_1 SHIFT_U32(0xFF, 0) /* 0xF0 */
120 #define SSPPPCellID_2 SHIFT_U32(0xFF, 0) /* 0x05 */
121 #define SSPPPCellID_3 SHIFT_U32(0xFF, 0) /* 0xB1 */
122
123 #define MASK_32 0xFFFFFFFF
124 #define MASK_28 0xFFFFFFF
125 #define MASK_24 0xFFFFFF
126 #define MASK_20 0xFFFFF
127 #define MASK_16 0xFFFF
128 #define MASK_12 0xFFF
129 #define MASK_8 0xFF
130 #define MASK_4 0xF
131 /* SPI register masks */
132
133 #define SSP_CPSDVR_MAX 254
134 #define SSP_CPSDVR_MIN 2
135 #define SSP_SCR_MAX 255
136 #define SSP_SCR_MIN 0
137 #define SSP_DATASIZE_MAX 16
138
pl022_txrx8(struct spi_chip * chip,uint8_t * wdat,uint8_t * rdat,size_t num_pkts)139 static enum spi_result pl022_txrx8(struct spi_chip *chip, uint8_t *wdat,
140 uint8_t *rdat, size_t num_pkts)
141 {
142 size_t i = 0;
143 size_t j = 0;
144 struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
145
146
147 if (pd->data_size_bits != 8) {
148 EMSG("data_size_bits should be 8, not %u",
149 pd->data_size_bits);
150 return SPI_ERR_CFG;
151 }
152
153 if (wdat)
154 while (i < num_pkts) {
155 if (io_read8(pd->base + SSPSR) & SSPSR_TNF) {
156 /* tx 1 packet */
157 io_write8(pd->base + SSPDR, wdat[i++]);
158 }
159
160 if (rdat)
161 if (io_read8(pd->base + SSPSR) & SSPSR_RNE) {
162 /* rx 1 packet */
163 rdat[j++] = io_read8(pd->base + SSPDR);
164 }
165 }
166
167 /* Capture remaining rdat not read above */
168 if (rdat) {
169 while ((j < num_pkts) &&
170 (io_read8(pd->base + SSPSR) & SSPSR_RNE)) {
171 /* rx 1 packet */
172 rdat[j++] = io_read8(pd->base + SSPDR);
173 }
174
175 if (j < num_pkts) {
176 EMSG("Packets requested %zu, received %zu",
177 num_pkts, j);
178 return SPI_ERR_PKTCNT;
179 }
180 }
181
182 return SPI_OK;
183 }
184
pl022_txrx16(struct spi_chip * chip,uint16_t * wdat,uint16_t * rdat,size_t num_pkts)185 static enum spi_result pl022_txrx16(struct spi_chip *chip, uint16_t *wdat,
186 uint16_t *rdat, size_t num_pkts)
187 {
188 size_t i = 0;
189 size_t j = 0;
190 struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
191
192 if (pd->data_size_bits != 16) {
193 EMSG("data_size_bits should be 16, not %u",
194 pd->data_size_bits);
195 return SPI_ERR_CFG;
196 }
197
198 if (wdat)
199 while (i < num_pkts) {
200 if (io_read8(pd->base + SSPSR) & SSPSR_TNF) {
201 /* tx 1 packet */
202 io_write16(pd->base + SSPDR, wdat[i++]);
203 }
204
205 if (rdat)
206 if (io_read8(pd->base + SSPSR) & SSPSR_RNE) {
207 /* rx 1 packet */
208 rdat[j++] = io_read16(pd->base + SSPDR);
209 }
210 }
211
212 /* Capture remaining rdat not read above */
213 if (rdat) {
214 while ((j < num_pkts) &&
215 (io_read8(pd->base + SSPSR) & SSPSR_RNE)) {
216 /* rx 1 packet */
217 rdat[j++] = io_read16(pd->base + SSPDR);
218 }
219
220 if (j < num_pkts) {
221 EMSG("Packets requested %zu, received %zu",
222 num_pkts, j);
223 return SPI_ERR_PKTCNT;
224 }
225 }
226
227 return SPI_OK;
228 }
229
pl022_print_peri_id(struct pl022_data * pd __maybe_unused)230 static void pl022_print_peri_id(struct pl022_data *pd __maybe_unused)
231 {
232 DMSG("Expected: 0x 22 10 ?4 00");
233 DMSG("Read: 0x %02x %02x %02x %02x",
234 io_read8(pd->base + SSPPeriphID0),
235 io_read8(pd->base + SSPPeriphID1),
236 io_read8(pd->base + SSPPeriphID2),
237 io_read8(pd->base + SSPPeriphID3));
238 }
239
pl022_print_cell_id(struct pl022_data * pd __maybe_unused)240 static void pl022_print_cell_id(struct pl022_data *pd __maybe_unused)
241 {
242 DMSG("Expected: 0x 0d f0 05 b1");
243 DMSG("Read: 0x %02x %02x %02x %02x",
244 io_read8(pd->base + SSPPCellID0),
245 io_read8(pd->base + SSPPCellID1),
246 io_read8(pd->base + SSPPCellID2),
247 io_read8(pd->base + SSPPCellID3));
248 }
249
pl022_sanity_check(struct pl022_data * pd)250 static void pl022_sanity_check(struct pl022_data *pd)
251 {
252 assert(pd);
253 assert(pd->chip.ops);
254 assert(pd->cs_control <= PL022_CS_CTRL_MANUAL);
255 switch (pd->cs_control) {
256 case PL022_CS_CTRL_AUTO_GPIO:
257 assert(pd->cs_data.gpio_data.chip);
258 assert(pd->cs_data.gpio_data.chip->ops);
259 break;
260 case PL022_CS_CTRL_CB:
261 assert(pd->cs_data.cs_cb);
262 break;
263 default:
264 break;
265 }
266 assert(pd->clk_hz);
267 assert(pd->speed_hz && pd->speed_hz <= pd->clk_hz/2);
268 assert(pd->mode <= SPI_MODE3);
269 assert(pd->data_size_bits == 8 || pd->data_size_bits == 16);
270
271 #ifdef PLATFORM_hikey
272 DMSG("SSPB2BTRANS: Expected: 0x2. Read: 0x%x",
273 io_read8(pd->base + SSPB2BTRANS));
274 #endif
275 pl022_print_peri_id(pd);
276 pl022_print_cell_id(pd);
277 }
278
pl022_calc_freq(struct pl022_data * pd,uint8_t cpsdvr,uint8_t scr)279 static inline uint32_t pl022_calc_freq(struct pl022_data *pd,
280 uint8_t cpsdvr, uint8_t scr)
281 {
282 return pd->clk_hz / (cpsdvr * (1 + scr));
283 }
284
pl022_control_cs(struct spi_chip * chip,enum gpio_level value)285 static void pl022_control_cs(struct spi_chip *chip, enum gpio_level value)
286 {
287 struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
288
289 switch (pd->cs_control) {
290 case PL022_CS_CTRL_AUTO_GPIO:
291 if (io_read8(pd->base + SSPSR) & SSPSR_BSY)
292 DMSG("pl022 busy - do NOT set CS!");
293 while (io_read8(pd->base + SSPSR) & SSPSR_BSY)
294 ;
295 DMSG("pl022 done - set CS!");
296
297 pd->cs_data.gpio_data.chip->ops->set_value(NULL,
298 pd->cs_data.gpio_data.pin_num, value);
299 break;
300 case PL022_CS_CTRL_CB:
301 pd->cs_data.cs_cb(value);
302 break;
303 default:
304 break;
305 }
306 }
307
pl022_calc_clk_divisors(struct pl022_data * pd,uint8_t * cpsdvr,uint8_t * scr)308 static void pl022_calc_clk_divisors(struct pl022_data *pd,
309 uint8_t *cpsdvr, uint8_t *scr)
310 {
311 unsigned int freq1 = 0;
312 unsigned int freq2 = 0;
313 uint8_t tmp_cpsdvr1;
314 uint8_t tmp_scr1;
315 uint8_t tmp_cpsdvr2 = 0;
316 uint8_t tmp_scr2 = 0;
317
318 for (tmp_scr1 = SSP_SCR_MIN; tmp_scr1 < SSP_SCR_MAX; tmp_scr1++) {
319 for (tmp_cpsdvr1 = SSP_CPSDVR_MIN; tmp_cpsdvr1 < SSP_CPSDVR_MAX;
320 tmp_cpsdvr1++) {
321 freq1 = pl022_calc_freq(pd, tmp_cpsdvr1, tmp_scr1);
322 if (freq1 == pd->speed_hz)
323 goto done;
324 else if (freq1 < pd->speed_hz)
325 goto stage2;
326 }
327 }
328
329 stage2:
330 for (tmp_cpsdvr2 = SSP_CPSDVR_MIN; tmp_cpsdvr2 < SSP_CPSDVR_MAX;
331 tmp_cpsdvr2++) {
332 for (tmp_scr2 = SSP_SCR_MIN; tmp_scr2 < SSP_SCR_MAX;
333 tmp_scr2++) {
334 freq2 = pl022_calc_freq(pd, tmp_cpsdvr2, tmp_scr2);
335 if (freq2 <= pd->speed_hz)
336 goto done;
337 }
338 }
339
340 done:
341 if (freq1 >= freq2) {
342 *cpsdvr = tmp_cpsdvr1;
343 *scr = tmp_scr1;
344 DMSG("speed: requested: %u, closest1: %u",
345 pd->speed_hz, freq1);
346 } else {
347 *cpsdvr = tmp_cpsdvr2;
348 *scr = tmp_scr2;
349 DMSG("speed: requested: %u, closest2: %u",
350 pd->speed_hz, freq2);
351 }
352 DMSG("CPSDVR: %u (0x%x), SCR: %u (0x%x)",
353 *cpsdvr, *cpsdvr, *scr, *scr);
354 }
355
pl022_flush_fifo(struct spi_chip * chip)356 static void pl022_flush_fifo(struct spi_chip *chip)
357 {
358 uint32_t __maybe_unused rdat;
359 struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
360 do {
361 while (io_read32(pd->base + SSPSR) & SSPSR_RNE) {
362 rdat = io_read32(pd->base + SSPDR);
363 DMSG("rdat: 0x%x", rdat);
364 }
365 } while (io_read32(pd->base + SSPSR) & SSPSR_BSY);
366 }
367
pl022_configure(struct spi_chip * chip)368 static void pl022_configure(struct spi_chip *chip)
369 {
370 uint16_t mode;
371 uint16_t data_size;
372 uint8_t cpsdvr;
373 uint8_t scr;
374 uint8_t lbm;
375 struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
376
377 pl022_sanity_check(pd);
378
379 switch (pd->cs_control) {
380 case PL022_CS_CTRL_AUTO_GPIO:
381 DMSG("Use auto GPIO CS control");
382 DMSG("Mask/disable interrupt for CS GPIO");
383 pd->cs_data.gpio_data.chip->ops->set_interrupt(NULL,
384 pd->cs_data.gpio_data.pin_num,
385 GPIO_INTERRUPT_DISABLE);
386 DMSG("Set CS GPIO dir to out");
387 pd->cs_data.gpio_data.chip->ops->set_direction(NULL,
388 pd->cs_data.gpio_data.pin_num,
389 GPIO_DIR_OUT);
390 break;
391 case PL022_CS_CTRL_CB:
392 DMSG("Use registered CS callback");
393 break;
394 case PL022_CS_CTRL_MANUAL:
395 DMSG("Use manual CS control");
396 break;
397 default:
398 EMSG("Invalid CS control type: %d", pd->cs_control);
399 panic();
400 }
401
402 DMSG("Pull CS high");
403 pl022_control_cs(chip, GPIO_LEVEL_HIGH);
404
405 pl022_calc_clk_divisors(pd, &cpsdvr, &scr);
406
407 /* configure ssp based on platform settings */
408 switch (pd->mode) {
409 case SPI_MODE0:
410 DMSG("SPI mode 0");
411 mode = SSPCR0_SPO0 | SSPCR0_SPH0;
412 break;
413 case SPI_MODE1:
414 DMSG("SPI mode 1");
415 mode = SSPCR0_SPO0 | SSPCR0_SPH1;
416 break;
417 case SPI_MODE2:
418 DMSG("SPI mode 2");
419 mode = SSPCR0_SPO1 | SSPCR0_SPH0;
420 break;
421 case SPI_MODE3:
422 DMSG("SPI mode 3");
423 mode = SSPCR0_SPO1 | SSPCR0_SPH1;
424 break;
425 default:
426 EMSG("Invalid SPI mode: %u", pd->mode);
427 panic();
428 }
429
430 switch (pd->data_size_bits) {
431 case 8:
432 DMSG("Data size: 8");
433 data_size = SSPCR0_DSS_8BIT;
434 break;
435 case 16:
436 DMSG("Data size: 16");
437 data_size = SSPCR0_DSS_16BIT;
438 break;
439 default:
440 EMSG("Unsupported data size: %u bits", pd->data_size_bits);
441 panic();
442 }
443
444 if (pd->loopback) {
445 DMSG("Starting in loopback mode!");
446 lbm = SSPCR1_LBM_YES;
447 } else {
448 DMSG("Starting in regular (non-loopback) mode!");
449 lbm = SSPCR1_LBM_NO;
450 }
451
452 DMSG("Set Serial Clock Rate (SCR), SPI mode (phase and clock)");
453 DMSG("Set frame format (SPI) and data size (8- or 16-bit)");
454 io_mask16(pd->base + SSPCR0, SHIFT_U32(scr, 8) | mode | SSPCR0_FRF_SPI |
455 data_size, MASK_16);
456
457 DMSG("Set master mode, disable SSP, set loopback mode");
458 io_mask8(pd->base + SSPCR1, SSPCR1_SOD_DISABLE | SSPCR1_MS_MASTER |
459 SSPCR1_SSE_DISABLE | lbm, MASK_4);
460
461 DMSG("Set clock prescale");
462 io_mask8(pd->base + SSPCPSR, cpsdvr, SSPCPSR_CPSDVR);
463
464 DMSG("Disable interrupts");
465 io_mask8(pd->base + SSPIMSC, 0, MASK_4);
466
467 DMSG("Clear interrupts");
468 io_mask8(pd->base + SSPICR, SSPICR_RORIC | SSPICR_RTIC,
469 SSPICR_RORIC | SSPICR_RTIC);
470
471 DMSG("Empty FIFO before starting");
472 pl022_flush_fifo(chip);
473 }
474
pl022_start(struct spi_chip * chip)475 static void pl022_start(struct spi_chip *chip)
476 {
477 struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
478
479 DMSG("Enable SSP");
480 io_mask8(pd->base + SSPCR1, SSPCR1_SSE_ENABLE, SSPCR1_SSE);
481
482 pl022_control_cs(chip, GPIO_LEVEL_LOW);
483 }
484
pl022_end(struct spi_chip * chip)485 static void pl022_end(struct spi_chip *chip)
486 {
487 struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
488
489 pl022_control_cs(chip, GPIO_LEVEL_HIGH);
490
491 DMSG("Disable SSP");
492 io_mask8(pd->base + SSPCR1, SSPCR1_SSE_DISABLE, SSPCR1_SSE);
493 }
494
495 static const struct spi_ops pl022_ops = {
496 .configure = pl022_configure,
497 .start = pl022_start,
498 .txrx8 = pl022_txrx8,
499 .txrx16 = pl022_txrx16,
500 .end = pl022_end,
501 .flushfifo = pl022_flush_fifo,
502 };
503 DECLARE_KEEP_PAGER(pl022_ops);
504
pl022_init(struct pl022_data * pd)505 void pl022_init(struct pl022_data *pd)
506 {
507 assert(pd);
508 pd->chip.ops = &pl022_ops;
509 }
510