xref: /linux/drivers/soc/fsl/qe/ucc.c (revision f86fd32d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * arch/powerpc/sysdev/qe_lib/ucc.c
4  *
5  * QE UCC API Set - UCC specific routines implementations.
6  *
7  * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
8  *
9  * Authors: 	Shlomi Gridish <gridish@freescale.com>
10  * 		Li Yang <leoli@freescale.com>
11  */
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/stddef.h>
15 #include <linux/spinlock.h>
16 #include <linux/export.h>
17 
18 #include <asm/io.h>
19 #include <soc/fsl/qe/immap_qe.h>
20 #include <soc/fsl/qe/qe.h>
21 #include <soc/fsl/qe/ucc.h>
22 
23 #define UCC_TDM_NUM 8
24 #define RX_SYNC_SHIFT_BASE 30
25 #define TX_SYNC_SHIFT_BASE 14
26 #define RX_CLK_SHIFT_BASE 28
27 #define TX_CLK_SHIFT_BASE 12
28 
29 int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
30 {
31 	unsigned long flags;
32 
33 	if (ucc_num > UCC_MAX_NUM - 1)
34 		return -EINVAL;
35 
36 	spin_lock_irqsave(&cmxgcr_lock, flags);
37 	qe_clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
38 			   ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
39 	spin_unlock_irqrestore(&cmxgcr_lock, flags);
40 
41 	return 0;
42 }
43 EXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
44 
45 /* Configure the UCC to either Slow or Fast.
46  *
47  * A given UCC can be figured to support either "slow" devices (e.g. UART)
48  * or "fast" devices (e.g. Ethernet).
49  *
50  * 'ucc_num' is the UCC number, from 0 - 7.
51  *
52  * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit
53  * must always be set to 1.
54  */
55 int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
56 {
57 	u8 __iomem *guemr;
58 
59 	/* The GUEMR register is at the same location for both slow and fast
60 	   devices, so we just use uccX.slow.guemr. */
61 	switch (ucc_num) {
62 	case 0: guemr = &qe_immr->ucc1.slow.guemr;
63 		break;
64 	case 1: guemr = &qe_immr->ucc2.slow.guemr;
65 		break;
66 	case 2: guemr = &qe_immr->ucc3.slow.guemr;
67 		break;
68 	case 3: guemr = &qe_immr->ucc4.slow.guemr;
69 		break;
70 	case 4: guemr = &qe_immr->ucc5.slow.guemr;
71 		break;
72 	case 5: guemr = &qe_immr->ucc6.slow.guemr;
73 		break;
74 	case 6: guemr = &qe_immr->ucc7.slow.guemr;
75 		break;
76 	case 7: guemr = &qe_immr->ucc8.slow.guemr;
77 		break;
78 	default:
79 		return -EINVAL;
80 	}
81 
82 	qe_clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
83 			UCC_GUEMR_SET_RESERVED3 | speed);
84 
85 	return 0;
86 }
87 
88 static void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr,
89 	unsigned int *reg_num, unsigned int *shift)
90 {
91 	unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3);
92 
93 	*reg_num = cmx + 1;
94 	*cmxucr = &qe_immr->qmx.cmxucr[cmx];
95 	*shift = 16 - 8 * (ucc_num & 2);
96 }
97 
98 int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
99 {
100 	__be32 __iomem *cmxucr;
101 	unsigned int reg_num;
102 	unsigned int shift;
103 
104 	/* check if the UCC number is in range. */
105 	if (ucc_num > UCC_MAX_NUM - 1)
106 		return -EINVAL;
107 
108 	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
109 
110 	if (set)
111 		qe_setbits_be32(cmxucr, mask << shift);
112 	else
113 		qe_clrbits_be32(cmxucr, mask << shift);
114 
115 	return 0;
116 }
117 
118 int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
119 	enum comm_dir mode)
120 {
121 	__be32 __iomem *cmxucr;
122 	unsigned int reg_num;
123 	unsigned int shift;
124 	u32 clock_bits = 0;
125 
126 	/* check if the UCC number is in range. */
127 	if (ucc_num > UCC_MAX_NUM - 1)
128 		return -EINVAL;
129 
130 	/* The communications direction must be RX or TX */
131 	if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
132 		return -EINVAL;
133 
134 	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
135 
136 	switch (reg_num) {
137 	case 1:
138 		switch (clock) {
139 		case QE_BRG1:	clock_bits = 1; break;
140 		case QE_BRG2:	clock_bits = 2; break;
141 		case QE_BRG7:	clock_bits = 3; break;
142 		case QE_BRG8:	clock_bits = 4; break;
143 		case QE_CLK9:	clock_bits = 5; break;
144 		case QE_CLK10:	clock_bits = 6; break;
145 		case QE_CLK11:	clock_bits = 7; break;
146 		case QE_CLK12:	clock_bits = 8; break;
147 		case QE_CLK15:	clock_bits = 9; break;
148 		case QE_CLK16:	clock_bits = 10; break;
149 		default: break;
150 		}
151 		break;
152 	case 2:
153 		switch (clock) {
154 		case QE_BRG5:	clock_bits = 1; break;
155 		case QE_BRG6:	clock_bits = 2; break;
156 		case QE_BRG7:	clock_bits = 3; break;
157 		case QE_BRG8:	clock_bits = 4; break;
158 		case QE_CLK13:	clock_bits = 5; break;
159 		case QE_CLK14:	clock_bits = 6; break;
160 		case QE_CLK19:	clock_bits = 7; break;
161 		case QE_CLK20:	clock_bits = 8; break;
162 		case QE_CLK15:	clock_bits = 9; break;
163 		case QE_CLK16:	clock_bits = 10; break;
164 		default: break;
165 		}
166 		break;
167 	case 3:
168 		switch (clock) {
169 		case QE_BRG9:	clock_bits = 1; break;
170 		case QE_BRG10:	clock_bits = 2; break;
171 		case QE_BRG15:	clock_bits = 3; break;
172 		case QE_BRG16:	clock_bits = 4; break;
173 		case QE_CLK3:	clock_bits = 5; break;
174 		case QE_CLK4:	clock_bits = 6; break;
175 		case QE_CLK17:	clock_bits = 7; break;
176 		case QE_CLK18:	clock_bits = 8; break;
177 		case QE_CLK7:	clock_bits = 9; break;
178 		case QE_CLK8:	clock_bits = 10; break;
179 		case QE_CLK16:	clock_bits = 11; break;
180 		default: break;
181 		}
182 		break;
183 	case 4:
184 		switch (clock) {
185 		case QE_BRG13:	clock_bits = 1; break;
186 		case QE_BRG14:	clock_bits = 2; break;
187 		case QE_BRG15:	clock_bits = 3; break;
188 		case QE_BRG16:	clock_bits = 4; break;
189 		case QE_CLK5:	clock_bits = 5; break;
190 		case QE_CLK6:	clock_bits = 6; break;
191 		case QE_CLK21:	clock_bits = 7; break;
192 		case QE_CLK22:	clock_bits = 8; break;
193 		case QE_CLK7:	clock_bits = 9; break;
194 		case QE_CLK8:	clock_bits = 10; break;
195 		case QE_CLK16:	clock_bits = 11; break;
196 		default: break;
197 		}
198 		break;
199 	default: break;
200 	}
201 
202 	/* Check for invalid combination of clock and UCC number */
203 	if (!clock_bits)
204 		return -ENOENT;
205 
206 	if (mode == COMM_DIR_RX)
207 		shift += 4;
208 
209 	qe_clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
210 			   clock_bits << shift);
211 
212 	return 0;
213 }
214 
215 static int ucc_get_tdm_common_clk(u32 tdm_num, enum qe_clock clock)
216 {
217 	int clock_bits = -EINVAL;
218 
219 	/*
220 	 * for TDM[0, 1, 2, 3], TX and RX use  common
221 	 * clock source BRG3,4 and CLK1,2
222 	 * for TDM[4, 5, 6, 7], TX and RX use  common
223 	 * clock source BRG12,13 and CLK23,24
224 	 */
225 	switch (tdm_num) {
226 	case 0:
227 	case 1:
228 	case 2:
229 	case 3:
230 		switch (clock) {
231 		case QE_BRG3:
232 			clock_bits = 1;
233 			break;
234 		case QE_BRG4:
235 			clock_bits = 2;
236 			break;
237 		case QE_CLK1:
238 			clock_bits = 4;
239 			break;
240 		case QE_CLK2:
241 			clock_bits = 5;
242 			break;
243 		default:
244 			break;
245 		}
246 		break;
247 	case 4:
248 	case 5:
249 	case 6:
250 	case 7:
251 		switch (clock) {
252 		case QE_BRG12:
253 			clock_bits = 1;
254 			break;
255 		case QE_BRG13:
256 			clock_bits = 2;
257 			break;
258 		case QE_CLK23:
259 			clock_bits = 4;
260 			break;
261 		case QE_CLK24:
262 			clock_bits = 5;
263 			break;
264 		default:
265 			break;
266 		}
267 		break;
268 	default:
269 		break;
270 	}
271 
272 	return clock_bits;
273 }
274 
275 static int ucc_get_tdm_rx_clk(u32 tdm_num, enum qe_clock clock)
276 {
277 	int clock_bits = -EINVAL;
278 
279 	switch (tdm_num) {
280 	case 0:
281 		switch (clock) {
282 		case QE_CLK3:
283 			clock_bits = 6;
284 			break;
285 		case QE_CLK8:
286 			clock_bits = 7;
287 			break;
288 		default:
289 			break;
290 		}
291 		break;
292 	case 1:
293 		switch (clock) {
294 		case QE_CLK5:
295 			clock_bits = 6;
296 			break;
297 		case QE_CLK10:
298 			clock_bits = 7;
299 			break;
300 		default:
301 			break;
302 		}
303 		break;
304 	case 2:
305 		switch (clock) {
306 		case QE_CLK7:
307 			clock_bits = 6;
308 			break;
309 		case QE_CLK12:
310 			clock_bits = 7;
311 			break;
312 		default:
313 			break;
314 		}
315 		break;
316 	case 3:
317 		switch (clock) {
318 		case QE_CLK9:
319 			clock_bits = 6;
320 			break;
321 		case QE_CLK14:
322 			clock_bits = 7;
323 			break;
324 		default:
325 			break;
326 		}
327 		break;
328 	case 4:
329 		switch (clock) {
330 		case QE_CLK11:
331 			clock_bits = 6;
332 			break;
333 		case QE_CLK16:
334 			clock_bits = 7;
335 			break;
336 		default:
337 			break;
338 		}
339 		break;
340 	case 5:
341 		switch (clock) {
342 		case QE_CLK13:
343 			clock_bits = 6;
344 			break;
345 		case QE_CLK18:
346 			clock_bits = 7;
347 			break;
348 		default:
349 			break;
350 		}
351 		break;
352 	case 6:
353 		switch (clock) {
354 		case QE_CLK15:
355 			clock_bits = 6;
356 			break;
357 		case QE_CLK20:
358 			clock_bits = 7;
359 			break;
360 		default:
361 			break;
362 		}
363 		break;
364 	case 7:
365 		switch (clock) {
366 		case QE_CLK17:
367 			clock_bits = 6;
368 			break;
369 		case QE_CLK22:
370 			clock_bits = 7;
371 			break;
372 		default:
373 			break;
374 		}
375 		break;
376 	}
377 
378 	return clock_bits;
379 }
380 
381 static int ucc_get_tdm_tx_clk(u32 tdm_num, enum qe_clock clock)
382 {
383 	int clock_bits = -EINVAL;
384 
385 	switch (tdm_num) {
386 	case 0:
387 		switch (clock) {
388 		case QE_CLK4:
389 			clock_bits = 6;
390 			break;
391 		case QE_CLK9:
392 			clock_bits = 7;
393 			break;
394 		default:
395 			break;
396 		}
397 		break;
398 	case 1:
399 		switch (clock) {
400 		case QE_CLK6:
401 			clock_bits = 6;
402 			break;
403 		case QE_CLK11:
404 			clock_bits = 7;
405 			break;
406 		default:
407 			break;
408 		}
409 		break;
410 	case 2:
411 		switch (clock) {
412 		case QE_CLK8:
413 			clock_bits = 6;
414 			break;
415 		case QE_CLK13:
416 			clock_bits = 7;
417 			break;
418 		default:
419 			break;
420 		}
421 		break;
422 	case 3:
423 		switch (clock) {
424 		case QE_CLK10:
425 			clock_bits = 6;
426 			break;
427 		case QE_CLK15:
428 			clock_bits = 7;
429 			break;
430 		default:
431 			break;
432 		}
433 		break;
434 	case 4:
435 		switch (clock) {
436 		case QE_CLK12:
437 			clock_bits = 6;
438 			break;
439 		case QE_CLK17:
440 			clock_bits = 7;
441 			break;
442 		default:
443 			break;
444 		}
445 		break;
446 	case 5:
447 		switch (clock) {
448 		case QE_CLK14:
449 			clock_bits = 6;
450 			break;
451 		case QE_CLK19:
452 			clock_bits = 7;
453 			break;
454 		default:
455 			break;
456 		}
457 		break;
458 	case 6:
459 		switch (clock) {
460 		case QE_CLK16:
461 			clock_bits = 6;
462 			break;
463 		case QE_CLK21:
464 			clock_bits = 7;
465 			break;
466 		default:
467 			break;
468 		}
469 		break;
470 	case 7:
471 		switch (clock) {
472 		case QE_CLK18:
473 			clock_bits = 6;
474 			break;
475 		case QE_CLK3:
476 			clock_bits = 7;
477 			break;
478 		default:
479 			break;
480 		}
481 		break;
482 	}
483 
484 	return clock_bits;
485 }
486 
487 /* tdm_num: TDM A-H port num is 0-7 */
488 static int ucc_get_tdm_rxtx_clk(enum comm_dir mode, u32 tdm_num,
489 				enum qe_clock clock)
490 {
491 	int clock_bits;
492 
493 	clock_bits = ucc_get_tdm_common_clk(tdm_num, clock);
494 	if (clock_bits > 0)
495 		return clock_bits;
496 	if (mode == COMM_DIR_RX)
497 		clock_bits = ucc_get_tdm_rx_clk(tdm_num, clock);
498 	if (mode == COMM_DIR_TX)
499 		clock_bits = ucc_get_tdm_tx_clk(tdm_num, clock);
500 	return clock_bits;
501 }
502 
503 static u32 ucc_get_tdm_clk_shift(enum comm_dir mode, u32 tdm_num)
504 {
505 	u32 shift;
506 
507 	shift = (mode == COMM_DIR_RX) ? RX_CLK_SHIFT_BASE : TX_CLK_SHIFT_BASE;
508 	if (tdm_num < 4)
509 		shift -= tdm_num * 4;
510 	else
511 		shift -= (tdm_num - 4) * 4;
512 
513 	return shift;
514 }
515 
516 int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
517 			 enum comm_dir mode)
518 {
519 	int clock_bits;
520 	u32 shift;
521 	struct qe_mux __iomem *qe_mux_reg;
522 	 __be32 __iomem *cmxs1cr;
523 
524 	qe_mux_reg = &qe_immr->qmx;
525 
526 	if (tdm_num > 7 || tdm_num < 0)
527 		return -EINVAL;
528 
529 	/* The communications direction must be RX or TX */
530 	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
531 		return -EINVAL;
532 
533 	clock_bits = ucc_get_tdm_rxtx_clk(mode, tdm_num, clock);
534 	if (clock_bits < 0)
535 		return -EINVAL;
536 
537 	shift = ucc_get_tdm_clk_shift(mode, tdm_num);
538 
539 	cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l :
540 				  &qe_mux_reg->cmxsi1cr_h;
541 
542 	qe_clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
543 			   clock_bits << shift);
544 
545 	return 0;
546 }
547 
548 static int ucc_get_tdm_sync_source(u32 tdm_num, enum qe_clock clock,
549 				   enum comm_dir mode)
550 {
551 	int source = -EINVAL;
552 
553 	if (mode == COMM_DIR_RX && clock == QE_RSYNC_PIN) {
554 		source = 0;
555 		return source;
556 	}
557 	if (mode == COMM_DIR_TX && clock == QE_TSYNC_PIN) {
558 		source = 0;
559 		return source;
560 	}
561 
562 	switch (tdm_num) {
563 	case 0:
564 	case 1:
565 		switch (clock) {
566 		case QE_BRG9:
567 			source = 1;
568 			break;
569 		case QE_BRG10:
570 			source = 2;
571 			break;
572 		default:
573 			break;
574 		}
575 		break;
576 	case 2:
577 	case 3:
578 		switch (clock) {
579 		case QE_BRG9:
580 			source = 1;
581 			break;
582 		case QE_BRG11:
583 			source = 2;
584 			break;
585 		default:
586 			break;
587 		}
588 		break;
589 	case 4:
590 	case 5:
591 		switch (clock) {
592 		case QE_BRG13:
593 			source = 1;
594 			break;
595 		case QE_BRG14:
596 			source = 2;
597 			break;
598 		default:
599 			break;
600 		}
601 		break;
602 	case 6:
603 	case 7:
604 		switch (clock) {
605 		case QE_BRG13:
606 			source = 1;
607 			break;
608 		case QE_BRG15:
609 			source = 2;
610 			break;
611 		default:
612 			break;
613 		}
614 		break;
615 	}
616 
617 	return source;
618 }
619 
620 static u32 ucc_get_tdm_sync_shift(enum comm_dir mode, u32 tdm_num)
621 {
622 	u32 shift;
623 
624 	shift = (mode == COMM_DIR_RX) ? RX_SYNC_SHIFT_BASE : TX_SYNC_SHIFT_BASE;
625 	shift -= tdm_num * 2;
626 
627 	return shift;
628 }
629 
630 int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
631 			  enum comm_dir mode)
632 {
633 	int source;
634 	u32 shift;
635 	struct qe_mux *qe_mux_reg;
636 
637 	qe_mux_reg = &qe_immr->qmx;
638 
639 	if (tdm_num >= UCC_TDM_NUM)
640 		return -EINVAL;
641 
642 	/* The communications direction must be RX or TX */
643 	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
644 		return -EINVAL;
645 
646 	source = ucc_get_tdm_sync_source(tdm_num, clock, mode);
647 	if (source < 0)
648 		return -EINVAL;
649 
650 	shift = ucc_get_tdm_sync_shift(mode, tdm_num);
651 
652 	qe_clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
653 			   QE_CMXUCR_TX_CLK_SRC_MASK << shift,
654 			   source << shift);
655 
656 	return 0;
657 }
658