xref: /optee_os/core/drivers/pl022_spi.c (revision 12941fdcbaa31bd0c6ab241022a7eba66c801467)
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 (read8(pd->base + SSPSR) & SSPSR_TNF) {
155 				/* tx 1 packet */
156 				write8(wdat[i++], pd->base + SSPDR);
157 			}
158 
159 			if (rdat)
160 				if (read8(pd->base + SSPSR) & SSPSR_RNE) {
161 					/* rx 1 packet */
162 					rdat[j++] = read8(pd->base + SSPDR);
163 				}
164 		}
165 
166 	/* Capture remaining rdat not read above */
167 	if (rdat) {
168 		while ((j < num_pkts) &&
169 			(read8(pd->base + SSPSR) & SSPSR_BSY))
170 			if (read8(pd->base + SSPSR) & SSPSR_RNE) {
171 				/* rx 1 packet */
172 				rdat[j++] = 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 
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 (read8(pd->base + SSPSR) & SSPSR_TNF) {
201 				/* tx 1 packet */
202 				write16(wdat[i++], pd->base + SSPDR);
203 			}
204 
205 			if (rdat)
206 				if (read8(pd->base + SSPSR) & SSPSR_RNE) {
207 					/* rx 1 packet */
208 					rdat[j++] = read16(pd->base + SSPDR);
209 				}
210 		}
211 
212 	/* Capture remaining rdat not read above */
213 	if (rdat) {
214 		while ((j < num_pkts) &&
215 			(read8(pd->base + SSPSR) & SSPSR_BSY))
216 			if (read8(pd->base + SSPSR) & SSPSR_RNE) {
217 				/* rx 1 packet */
218 				rdat[j++] = read16(pd->base + SSPDR);
219 			}
220 
221 		if (j < num_pkts) {
222 			EMSG("Packets requested %zu, received %zu",
223 				num_pkts, j);
224 			return SPI_ERR_PKTCNT;
225 		}
226 	}
227 
228 	return SPI_OK;
229 }
230 
231 static void pl022_print_peri_id(struct pl022_data *pd __maybe_unused)
232 {
233 	DMSG("Expected: 0x 22 10 ?4 00");
234 	DMSG("Read: 0x %02x %02x %02x %02x",
235 		read32(pd->base + SSPPeriphID0),
236 		read32(pd->base + SSPPeriphID1),
237 		read32(pd->base + SSPPeriphID2),
238 		read32(pd->base + SSPPeriphID3));
239 }
240 
241 static void pl022_print_cell_id(struct pl022_data *pd __maybe_unused)
242 {
243 	DMSG("Expected: 0x 0d f0 05 b1");
244 	DMSG("Read: 0x %02x %02x %02x %02x",
245 		read32(pd->base + SSPPCellID0),
246 		read32(pd->base + SSPPCellID1),
247 		read32(pd->base + SSPPCellID2),
248 		read32(pd->base + SSPPCellID3));
249 }
250 
251 static void pl022_sanity_check(struct pl022_data *pd)
252 {
253 	assert(pd);
254 	assert(pd->chip.ops);
255 	assert(pd->cs_control <= PL022_CS_CTRL_MANUAL);
256 	switch (pd->cs_control) {
257 	case PL022_CS_CTRL_AUTO_GPIO:
258 		assert(pd->cs_data.gpio_data.chip);
259 		assert(pd->cs_data.gpio_data.chip->ops);
260 		break;
261 	case PL022_CS_CTRL_CB:
262 		assert(pd->cs_data.cs_cb);
263 		break;
264 	default:
265 		break;
266 	}
267 	assert(pd->clk_hz);
268 	assert(pd->speed_hz && pd->speed_hz <= pd->clk_hz/2);
269 	assert(pd->mode <= SPI_MODE3);
270 	assert(pd->data_size_bits == 8 || pd->data_size_bits == 16);
271 
272 	#ifdef PLATFORM_hikey
273 	DMSG("SSPB2BTRANS: Expected: 0x2. Read: 0x%x",
274 		read32(pd->base + SSPB2BTRANS));
275 	#endif
276 	pl022_print_peri_id(pd);
277 	pl022_print_cell_id(pd);
278 }
279 
280 static inline uint32_t pl022_calc_freq(struct pl022_data *pd,
281 	uint8_t cpsdvr, uint8_t scr)
282 {
283 	return pd->clk_hz / (cpsdvr * (1 + scr));
284 }
285 
286 static void pl022_control_cs(struct spi_chip *chip, enum gpio_level value)
287 {
288 	struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
289 
290 	switch (pd->cs_control) {
291 	case PL022_CS_CTRL_AUTO_GPIO:
292 		if (read8(pd->base + SSPSR) & SSPSR_BSY)
293 			DMSG("pl022 busy - do NOT set CS!");
294 		while (read8(pd->base + SSPSR) & SSPSR_BSY)
295 			;
296 		DMSG("pl022 done - set CS!");
297 
298 		pd->cs_data.gpio_data.chip->ops->set_value(
299 			pd->cs_data.gpio_data.pin_num, value);
300 		break;
301 	case PL022_CS_CTRL_CB:
302 		pd->cs_data.cs_cb(value);
303 		break;
304 	default:
305 		break;
306 	}
307 }
308 
309 static void pl022_calc_clk_divisors(struct pl022_data *pd,
310 	uint8_t *cpsdvr, uint8_t *scr)
311 {
312 	unsigned int freq1 = 0;
313 	unsigned int freq2 = 0;
314 	uint8_t tmp_cpsdvr1;
315 	uint8_t tmp_scr1;
316 	uint8_t tmp_cpsdvr2 = 0;
317 	uint8_t tmp_scr2 = 0;
318 
319 	for (tmp_scr1 = SSP_SCR_MIN; tmp_scr1 < SSP_SCR_MAX; tmp_scr1++) {
320 		for (tmp_cpsdvr1 = SSP_CPSDVR_MIN; tmp_cpsdvr1 < SSP_CPSDVR_MAX;
321 			tmp_cpsdvr1++) {
322 			freq1 = pl022_calc_freq(pd, tmp_cpsdvr1, tmp_scr1);
323 			if (freq1 == pd->speed_hz)
324 				goto done;
325 			else if (freq1 < pd->speed_hz)
326 				goto stage2;
327 		}
328 	}
329 
330 stage2:
331 	for (tmp_cpsdvr2 = SSP_CPSDVR_MIN; tmp_cpsdvr2 < SSP_CPSDVR_MAX;
332 		tmp_cpsdvr2++) {
333 		for (tmp_scr2 = SSP_SCR_MIN; tmp_scr2 < SSP_SCR_MAX;
334 			tmp_scr2++) {
335 			freq2 = pl022_calc_freq(pd, tmp_cpsdvr2, tmp_scr2);
336 			if (freq2 <= pd->speed_hz)
337 				goto done;
338 		}
339 	}
340 
341 done:
342 	if (freq1 >= freq2) {
343 		*cpsdvr = tmp_cpsdvr1;
344 		*scr = tmp_scr1;
345 		DMSG("speed: requested: %u, closest1: %u",
346 			pd->speed_hz, freq1);
347 	} else {
348 		*cpsdvr = tmp_cpsdvr2;
349 		*scr = tmp_scr2;
350 		DMSG("speed: requested: %u, closest2: %u",
351 			pd->speed_hz, freq2);
352 	}
353 	DMSG("CPSDVR: %u (0x%x), SCR: %u (0x%x)",
354 		*cpsdvr, *cpsdvr, *scr, *scr);
355 }
356 
357 static void pl022_flush_fifo(struct pl022_data *pd)
358 {
359 	uint32_t __maybe_unused rdat;
360 
361 	do {
362 		while (read32(pd->base + SSPSR) & SSPSR_RNE) {
363 			rdat = read32(pd->base + SSPDR);
364 			DMSG("rdat: 0x%x", rdat);
365 		}
366 	} while (read32(pd->base + SSPSR) & SSPSR_BSY);
367 }
368 
369 static void pl022_configure(struct spi_chip *chip)
370 {
371 	uint16_t mode;
372 	uint16_t data_size;
373 	uint8_t cpsdvr;
374 	uint8_t scr;
375 	uint8_t lbm;
376 	struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
377 
378 	pl022_sanity_check(pd);
379 
380 	switch (pd->cs_control) {
381 	case PL022_CS_CTRL_AUTO_GPIO:
382 		DMSG("Use auto GPIO CS control");
383 		DMSG("Mask/disable interrupt for CS GPIO");
384 		pd->cs_data.gpio_data.chip->ops->set_interrupt(
385 			pd->cs_data.gpio_data.pin_num,
386 			GPIO_INTERRUPT_DISABLE);
387 		DMSG("Set CS GPIO dir to out");
388 		pd->cs_data.gpio_data.chip->ops->set_direction(
389 			pd->cs_data.gpio_data.pin_num,
390 			GPIO_DIR_OUT);
391 		break;
392 	case PL022_CS_CTRL_CB:
393 		DMSG("Use registered CS callback");
394 		break;
395 	case PL022_CS_CTRL_MANUAL:
396 		DMSG("Use manual CS control");
397 		break;
398 	default:
399 		EMSG("Invalid CS control type: %d", pd->cs_control);
400 		panic();
401 	}
402 
403 	DMSG("Pull CS high");
404 	pl022_control_cs(chip, GPIO_LEVEL_HIGH);
405 
406 	pl022_calc_clk_divisors(pd, &cpsdvr, &scr);
407 
408 	/* configure ssp based on platform settings */
409 	switch (pd->mode) {
410 	case SPI_MODE0:
411 		DMSG("SPI mode 0");
412 		mode = SSPCR0_SPO0 | SSPCR0_SPH0;
413 		break;
414 	case SPI_MODE1:
415 		DMSG("SPI mode 1");
416 		mode = SSPCR0_SPO0 | SSPCR0_SPH1;
417 		break;
418 	case SPI_MODE2:
419 		DMSG("SPI mode 2");
420 		mode = SSPCR0_SPO1 | SSPCR0_SPH0;
421 		break;
422 	case SPI_MODE3:
423 		DMSG("SPI mode 3");
424 		mode = SSPCR0_SPO1 | SSPCR0_SPH1;
425 		break;
426 	default:
427 		EMSG("Invalid SPI mode: %u", pd->mode);
428 		panic();
429 	}
430 
431 	switch (pd->data_size_bits) {
432 	case 8:
433 		DMSG("Data size: 8");
434 		data_size = SSPCR0_DSS_8BIT;
435 		break;
436 	case 16:
437 		DMSG("Data size: 16");
438 		data_size = SSPCR0_DSS_16BIT;
439 		break;
440 	default:
441 		EMSG("Unsupported data size: %u bits", pd->data_size_bits);
442 		panic();
443 	}
444 
445 	if (pd->loopback) {
446 		DMSG("Starting in loopback mode!");
447 		lbm = SSPCR1_LBM_YES;
448 	} else {
449 		DMSG("Starting in regular (non-loopback) mode!");
450 		lbm = SSPCR1_LBM_NO;
451 	}
452 
453 	DMSG("Set Serial Clock Rate (SCR), SPI mode (phase and clock)");
454 	DMSG("Set frame format (SPI) and data size (8- or 16-bit)");
455 	io_mask16(pd->base + SSPCR0, SHIFT_U32(scr, 8) | mode | SSPCR0_FRF_SPI |
456 		data_size, MASK_16);
457 
458 	DMSG("Set master mode, disable SSP, set loopback mode");
459 	io_mask8(pd->base + SSPCR1, SSPCR1_SOD_DISABLE | SSPCR1_MS_MASTER |
460 		SSPCR1_SSE_DISABLE | lbm, MASK_4);
461 
462 	DMSG("Set clock prescale");
463 	io_mask8(pd->base + SSPCPSR, cpsdvr, SSPCPSR_CPSDVR);
464 
465 	DMSG("Disable interrupts");
466 	io_mask8(pd->base + SSPIMSC, 0, MASK_4);
467 
468 	DMSG("Clear interrupts");
469 	io_mask8(pd->base + SSPICR, SSPICR_RORIC | SSPICR_RTIC,
470 		SSPICR_RORIC | SSPICR_RTIC);
471 
472 	DMSG("Empty FIFO before starting");
473 	pl022_flush_fifo(pd);
474 }
475 
476 static void pl022_start(struct spi_chip *chip)
477 {
478 	struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
479 
480 	DMSG("Enable SSP");
481 	io_mask8(pd->base + SSPCR1, SSPCR1_SSE_ENABLE, SSPCR1_SSE);
482 
483 	pl022_control_cs(chip, GPIO_LEVEL_LOW);
484 }
485 
486 static void pl022_end(struct spi_chip *chip)
487 {
488 	struct pl022_data *pd = container_of(chip, struct pl022_data, chip);
489 
490 	pl022_control_cs(chip, GPIO_LEVEL_HIGH);
491 
492 	DMSG("Disable SSP");
493 	io_mask8(pd->base + SSPCR1, SSPCR1_SSE_DISABLE, SSPCR1_SSE);
494 }
495 
496 static const struct spi_ops pl022_ops = {
497 	.configure = pl022_configure,
498 	.start = pl022_start,
499 	.txrx8 = pl022_txrx8,
500 	.txrx16 = pl022_txrx16,
501 	.end = pl022_end,
502 };
503 
504 void pl022_init(struct pl022_data *pd)
505 {
506 	assert(pd);
507 	pd->chip.ops = &pl022_ops;
508 }
509