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