xref: /linux/drivers/soc/fsl/qe/ucc.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
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 
ucc_set_qe_mux_mii_mng(unsigned int ucc_num)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  */
ucc_set_type(unsigned int ucc_num,enum ucc_speed_type speed)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 
get_cmxucr_reg(unsigned int ucc_num,__be32 __iomem ** cmxucr,unsigned int * reg_num,unsigned int * shift)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 
ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num,int set,u32 mask)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 EXPORT_SYMBOL(ucc_mux_set_grant_tsa_bkpt);
118 
ucc_set_qe_mux_rxtx(unsigned int ucc_num,enum qe_clock clock,enum comm_dir mode)119 int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
120 	enum comm_dir mode)
121 {
122 	__be32 __iomem *cmxucr;
123 	unsigned int reg_num;
124 	unsigned int shift;
125 	u32 clock_bits = 0;
126 
127 	/* check if the UCC number is in range. */
128 	if (ucc_num > UCC_MAX_NUM - 1)
129 		return -EINVAL;
130 
131 	/* The communications direction must be RX or TX */
132 	if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
133 		return -EINVAL;
134 
135 	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
136 
137 	switch (reg_num) {
138 	case 1:
139 		switch (clock) {
140 		case QE_BRG1:	clock_bits = 1; break;
141 		case QE_BRG2:	clock_bits = 2; break;
142 		case QE_BRG7:	clock_bits = 3; break;
143 		case QE_BRG8:	clock_bits = 4; break;
144 		case QE_CLK9:	clock_bits = 5; break;
145 		case QE_CLK10:	clock_bits = 6; break;
146 		case QE_CLK11:	clock_bits = 7; break;
147 		case QE_CLK12:	clock_bits = 8; break;
148 		case QE_CLK15:	clock_bits = 9; break;
149 		case QE_CLK16:	clock_bits = 10; break;
150 		default: break;
151 		}
152 		break;
153 	case 2:
154 		switch (clock) {
155 		case QE_BRG5:	clock_bits = 1; break;
156 		case QE_BRG6:	clock_bits = 2; break;
157 		case QE_BRG7:	clock_bits = 3; break;
158 		case QE_BRG8:	clock_bits = 4; break;
159 		case QE_CLK13:	clock_bits = 5; break;
160 		case QE_CLK14:	clock_bits = 6; break;
161 		case QE_CLK19:	clock_bits = 7; break;
162 		case QE_CLK20:	clock_bits = 8; break;
163 		case QE_CLK15:	clock_bits = 9; break;
164 		case QE_CLK16:	clock_bits = 10; break;
165 		default: break;
166 		}
167 		break;
168 	case 3:
169 		switch (clock) {
170 		case QE_BRG9:	clock_bits = 1; break;
171 		case QE_BRG10:	clock_bits = 2; break;
172 		case QE_BRG15:	clock_bits = 3; break;
173 		case QE_BRG16:	clock_bits = 4; break;
174 		case QE_CLK3:	clock_bits = 5; break;
175 		case QE_CLK4:	clock_bits = 6; break;
176 		case QE_CLK17:	clock_bits = 7; break;
177 		case QE_CLK18:	clock_bits = 8; break;
178 		case QE_CLK7:	clock_bits = 9; break;
179 		case QE_CLK8:	clock_bits = 10; break;
180 		case QE_CLK16:	clock_bits = 11; break;
181 		default: break;
182 		}
183 		break;
184 	case 4:
185 		switch (clock) {
186 		case QE_BRG13:	clock_bits = 1; break;
187 		case QE_BRG14:	clock_bits = 2; break;
188 		case QE_BRG15:	clock_bits = 3; break;
189 		case QE_BRG16:	clock_bits = 4; break;
190 		case QE_CLK5:	clock_bits = 5; break;
191 		case QE_CLK6:	clock_bits = 6; break;
192 		case QE_CLK21:	clock_bits = 7; break;
193 		case QE_CLK22:	clock_bits = 8; break;
194 		case QE_CLK7:	clock_bits = 9; break;
195 		case QE_CLK8:	clock_bits = 10; break;
196 		case QE_CLK16:	clock_bits = 11; break;
197 		default: break;
198 		}
199 		break;
200 	default: break;
201 	}
202 
203 	/* Check for invalid combination of clock and UCC number */
204 	if (!clock_bits)
205 		return -ENOENT;
206 
207 	if (mode == COMM_DIR_RX)
208 		shift += 4;
209 
210 	qe_clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
211 			   clock_bits << shift);
212 
213 	return 0;
214 }
215 
ucc_get_tdm_common_clk(u32 tdm_num,enum qe_clock clock)216 static int ucc_get_tdm_common_clk(u32 tdm_num, enum qe_clock clock)
217 {
218 	int clock_bits = -EINVAL;
219 
220 	/*
221 	 * for TDM[0, 1, 2, 3], TX and RX use  common
222 	 * clock source BRG3,4 and CLK1,2
223 	 * for TDM[4, 5, 6, 7], TX and RX use  common
224 	 * clock source BRG12,13 and CLK23,24
225 	 */
226 	switch (tdm_num) {
227 	case 0:
228 	case 1:
229 	case 2:
230 	case 3:
231 		switch (clock) {
232 		case QE_BRG3:
233 			clock_bits = 1;
234 			break;
235 		case QE_BRG4:
236 			clock_bits = 2;
237 			break;
238 		case QE_CLK1:
239 			clock_bits = 4;
240 			break;
241 		case QE_CLK2:
242 			clock_bits = 5;
243 			break;
244 		default:
245 			break;
246 		}
247 		break;
248 	case 4:
249 	case 5:
250 	case 6:
251 	case 7:
252 		switch (clock) {
253 		case QE_BRG12:
254 			clock_bits = 1;
255 			break;
256 		case QE_BRG13:
257 			clock_bits = 2;
258 			break;
259 		case QE_CLK23:
260 			clock_bits = 4;
261 			break;
262 		case QE_CLK24:
263 			clock_bits = 5;
264 			break;
265 		default:
266 			break;
267 		}
268 		break;
269 	default:
270 		break;
271 	}
272 
273 	return clock_bits;
274 }
275 
ucc_get_tdm_rx_clk(u32 tdm_num,enum qe_clock clock)276 static int ucc_get_tdm_rx_clk(u32 tdm_num, enum qe_clock clock)
277 {
278 	int clock_bits = -EINVAL;
279 
280 	switch (tdm_num) {
281 	case 0:
282 		switch (clock) {
283 		case QE_CLK3:
284 			clock_bits = 6;
285 			break;
286 		case QE_CLK8:
287 			clock_bits = 7;
288 			break;
289 		default:
290 			break;
291 		}
292 		break;
293 	case 1:
294 		switch (clock) {
295 		case QE_CLK5:
296 			clock_bits = 6;
297 			break;
298 		case QE_CLK10:
299 			clock_bits = 7;
300 			break;
301 		default:
302 			break;
303 		}
304 		break;
305 	case 2:
306 		switch (clock) {
307 		case QE_CLK7:
308 			clock_bits = 6;
309 			break;
310 		case QE_CLK12:
311 			clock_bits = 7;
312 			break;
313 		default:
314 			break;
315 		}
316 		break;
317 	case 3:
318 		switch (clock) {
319 		case QE_CLK9:
320 			clock_bits = 6;
321 			break;
322 		case QE_CLK14:
323 			clock_bits = 7;
324 			break;
325 		default:
326 			break;
327 		}
328 		break;
329 	case 4:
330 		switch (clock) {
331 		case QE_CLK11:
332 			clock_bits = 6;
333 			break;
334 		case QE_CLK16:
335 			clock_bits = 7;
336 			break;
337 		default:
338 			break;
339 		}
340 		break;
341 	case 5:
342 		switch (clock) {
343 		case QE_CLK13:
344 			clock_bits = 6;
345 			break;
346 		case QE_CLK18:
347 			clock_bits = 7;
348 			break;
349 		default:
350 			break;
351 		}
352 		break;
353 	case 6:
354 		switch (clock) {
355 		case QE_CLK15:
356 			clock_bits = 6;
357 			break;
358 		case QE_CLK20:
359 			clock_bits = 7;
360 			break;
361 		default:
362 			break;
363 		}
364 		break;
365 	case 7:
366 		switch (clock) {
367 		case QE_CLK17:
368 			clock_bits = 6;
369 			break;
370 		case QE_CLK22:
371 			clock_bits = 7;
372 			break;
373 		default:
374 			break;
375 		}
376 		break;
377 	}
378 
379 	return clock_bits;
380 }
381 
ucc_get_tdm_tx_clk(u32 tdm_num,enum qe_clock clock)382 static int ucc_get_tdm_tx_clk(u32 tdm_num, enum qe_clock clock)
383 {
384 	int clock_bits = -EINVAL;
385 
386 	switch (tdm_num) {
387 	case 0:
388 		switch (clock) {
389 		case QE_CLK4:
390 			clock_bits = 6;
391 			break;
392 		case QE_CLK9:
393 			clock_bits = 7;
394 			break;
395 		default:
396 			break;
397 		}
398 		break;
399 	case 1:
400 		switch (clock) {
401 		case QE_CLK6:
402 			clock_bits = 6;
403 			break;
404 		case QE_CLK11:
405 			clock_bits = 7;
406 			break;
407 		default:
408 			break;
409 		}
410 		break;
411 	case 2:
412 		switch (clock) {
413 		case QE_CLK8:
414 			clock_bits = 6;
415 			break;
416 		case QE_CLK13:
417 			clock_bits = 7;
418 			break;
419 		default:
420 			break;
421 		}
422 		break;
423 	case 3:
424 		switch (clock) {
425 		case QE_CLK10:
426 			clock_bits = 6;
427 			break;
428 		case QE_CLK15:
429 			clock_bits = 7;
430 			break;
431 		default:
432 			break;
433 		}
434 		break;
435 	case 4:
436 		switch (clock) {
437 		case QE_CLK12:
438 			clock_bits = 6;
439 			break;
440 		case QE_CLK17:
441 			clock_bits = 7;
442 			break;
443 		default:
444 			break;
445 		}
446 		break;
447 	case 5:
448 		switch (clock) {
449 		case QE_CLK14:
450 			clock_bits = 6;
451 			break;
452 		case QE_CLK19:
453 			clock_bits = 7;
454 			break;
455 		default:
456 			break;
457 		}
458 		break;
459 	case 6:
460 		switch (clock) {
461 		case QE_CLK16:
462 			clock_bits = 6;
463 			break;
464 		case QE_CLK21:
465 			clock_bits = 7;
466 			break;
467 		default:
468 			break;
469 		}
470 		break;
471 	case 7:
472 		switch (clock) {
473 		case QE_CLK18:
474 			clock_bits = 6;
475 			break;
476 		case QE_CLK3:
477 			clock_bits = 7;
478 			break;
479 		default:
480 			break;
481 		}
482 		break;
483 	}
484 
485 	return clock_bits;
486 }
487 
488 /* tdm_num: TDM A-H port num is 0-7 */
ucc_get_tdm_rxtx_clk(enum comm_dir mode,u32 tdm_num,enum qe_clock clock)489 static int ucc_get_tdm_rxtx_clk(enum comm_dir mode, u32 tdm_num,
490 				enum qe_clock clock)
491 {
492 	int clock_bits;
493 
494 	clock_bits = ucc_get_tdm_common_clk(tdm_num, clock);
495 	if (clock_bits > 0)
496 		return clock_bits;
497 	if (mode == COMM_DIR_RX)
498 		clock_bits = ucc_get_tdm_rx_clk(tdm_num, clock);
499 	if (mode == COMM_DIR_TX)
500 		clock_bits = ucc_get_tdm_tx_clk(tdm_num, clock);
501 	return clock_bits;
502 }
503 
ucc_get_tdm_clk_shift(enum comm_dir mode,u32 tdm_num)504 static u32 ucc_get_tdm_clk_shift(enum comm_dir mode, u32 tdm_num)
505 {
506 	u32 shift;
507 
508 	shift = (mode == COMM_DIR_RX) ? RX_CLK_SHIFT_BASE : TX_CLK_SHIFT_BASE;
509 	if (tdm_num < 4)
510 		shift -= tdm_num * 4;
511 	else
512 		shift -= (tdm_num - 4) * 4;
513 
514 	return shift;
515 }
516 
ucc_set_tdm_rxtx_clk(u32 tdm_num,enum qe_clock clock,enum comm_dir mode)517 int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
518 			 enum comm_dir mode)
519 {
520 	int clock_bits;
521 	u32 shift;
522 	struct qe_mux __iomem *qe_mux_reg;
523 	__be32 __iomem *cmxs1cr;
524 
525 	qe_mux_reg = &qe_immr->qmx;
526 
527 	if (tdm_num > 7)
528 		return -EINVAL;
529 
530 	/* The communications direction must be RX or TX */
531 	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
532 		return -EINVAL;
533 
534 	clock_bits = ucc_get_tdm_rxtx_clk(mode, tdm_num, clock);
535 	if (clock_bits < 0)
536 		return -EINVAL;
537 
538 	shift = ucc_get_tdm_clk_shift(mode, tdm_num);
539 
540 	cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l :
541 				  &qe_mux_reg->cmxsi1cr_h;
542 
543 	qe_clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
544 			   clock_bits << shift);
545 
546 	return 0;
547 }
548 
ucc_get_tdm_sync_source(u32 tdm_num,enum qe_clock clock,enum comm_dir mode)549 static int ucc_get_tdm_sync_source(u32 tdm_num, enum qe_clock clock,
550 				   enum comm_dir mode)
551 {
552 	int source = -EINVAL;
553 
554 	if (mode == COMM_DIR_RX && clock == QE_RSYNC_PIN) {
555 		source = 0;
556 		return source;
557 	}
558 	if (mode == COMM_DIR_TX && clock == QE_TSYNC_PIN) {
559 		source = 0;
560 		return source;
561 	}
562 
563 	switch (tdm_num) {
564 	case 0:
565 	case 1:
566 		switch (clock) {
567 		case QE_BRG9:
568 			source = 1;
569 			break;
570 		case QE_BRG10:
571 			source = 2;
572 			break;
573 		default:
574 			break;
575 		}
576 		break;
577 	case 2:
578 	case 3:
579 		switch (clock) {
580 		case QE_BRG9:
581 			source = 1;
582 			break;
583 		case QE_BRG11:
584 			source = 2;
585 			break;
586 		default:
587 			break;
588 		}
589 		break;
590 	case 4:
591 	case 5:
592 		switch (clock) {
593 		case QE_BRG13:
594 			source = 1;
595 			break;
596 		case QE_BRG14:
597 			source = 2;
598 			break;
599 		default:
600 			break;
601 		}
602 		break;
603 	case 6:
604 	case 7:
605 		switch (clock) {
606 		case QE_BRG13:
607 			source = 1;
608 			break;
609 		case QE_BRG15:
610 			source = 2;
611 			break;
612 		default:
613 			break;
614 		}
615 		break;
616 	}
617 
618 	return source;
619 }
620 
ucc_get_tdm_sync_shift(enum comm_dir mode,u32 tdm_num)621 static u32 ucc_get_tdm_sync_shift(enum comm_dir mode, u32 tdm_num)
622 {
623 	u32 shift;
624 
625 	shift = (mode == COMM_DIR_RX) ? RX_SYNC_SHIFT_BASE : TX_SYNC_SHIFT_BASE;
626 	shift -= tdm_num * 2;
627 
628 	return shift;
629 }
630 
ucc_set_tdm_rxtx_sync(u32 tdm_num,enum qe_clock clock,enum comm_dir mode)631 int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
632 			  enum comm_dir mode)
633 {
634 	int source;
635 	u32 shift;
636 	struct qe_mux __iomem *qe_mux_reg;
637 
638 	qe_mux_reg = &qe_immr->qmx;
639 
640 	if (tdm_num >= UCC_TDM_NUM)
641 		return -EINVAL;
642 
643 	/* The communications direction must be RX or TX */
644 	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
645 		return -EINVAL;
646 
647 	source = ucc_get_tdm_sync_source(tdm_num, clock, mode);
648 	if (source < 0)
649 		return -EINVAL;
650 
651 	shift = ucc_get_tdm_sync_shift(mode, tdm_num);
652 
653 	qe_clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
654 			   QE_CMXUCR_TX_CLK_SRC_MASK << shift,
655 			   source << shift);
656 
657 	return 0;
658 }
659