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