xref: /openbmc/linux/drivers/soc/fsl/qe/ucc.c (revision 22d55f02)
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/irq.h>
19 #include <asm/io.h>
20 #include <soc/fsl/qe/immap_qe.h>
21 #include <soc/fsl/qe/qe.h>
22 #include <soc/fsl/qe/ucc.h>
23 
24 #define UCC_TDM_NUM 8
25 #define RX_SYNC_SHIFT_BASE 30
26 #define TX_SYNC_SHIFT_BASE 14
27 #define RX_CLK_SHIFT_BASE 28
28 #define TX_CLK_SHIFT_BASE 12
29 
30 int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
31 {
32 	unsigned long flags;
33 
34 	if (ucc_num > UCC_MAX_NUM - 1)
35 		return -EINVAL;
36 
37 	spin_lock_irqsave(&cmxgcr_lock, flags);
38 	clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
39 		ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
40 	spin_unlock_irqrestore(&cmxgcr_lock, flags);
41 
42 	return 0;
43 }
44 EXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
45 
46 /* Configure the UCC to either Slow or Fast.
47  *
48  * A given UCC can be figured to support either "slow" devices (e.g. UART)
49  * or "fast" devices (e.g. Ethernet).
50  *
51  * 'ucc_num' is the UCC number, from 0 - 7.
52  *
53  * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit
54  * must always be set to 1.
55  */
56 int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
57 {
58 	u8 __iomem *guemr;
59 
60 	/* The GUEMR register is at the same location for both slow and fast
61 	   devices, so we just use uccX.slow.guemr. */
62 	switch (ucc_num) {
63 	case 0: guemr = &qe_immr->ucc1.slow.guemr;
64 		break;
65 	case 1: guemr = &qe_immr->ucc2.slow.guemr;
66 		break;
67 	case 2: guemr = &qe_immr->ucc3.slow.guemr;
68 		break;
69 	case 3: guemr = &qe_immr->ucc4.slow.guemr;
70 		break;
71 	case 4: guemr = &qe_immr->ucc5.slow.guemr;
72 		break;
73 	case 5: guemr = &qe_immr->ucc6.slow.guemr;
74 		break;
75 	case 6: guemr = &qe_immr->ucc7.slow.guemr;
76 		break;
77 	case 7: guemr = &qe_immr->ucc8.slow.guemr;
78 		break;
79 	default:
80 		return -EINVAL;
81 	}
82 
83 	clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
84 		UCC_GUEMR_SET_RESERVED3 | speed);
85 
86 	return 0;
87 }
88 
89 static void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr,
90 	unsigned int *reg_num, unsigned int *shift)
91 {
92 	unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3);
93 
94 	*reg_num = cmx + 1;
95 	*cmxucr = &qe_immr->qmx.cmxucr[cmx];
96 	*shift = 16 - 8 * (ucc_num & 2);
97 }
98 
99 int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
100 {
101 	__be32 __iomem *cmxucr;
102 	unsigned int reg_num;
103 	unsigned int shift;
104 
105 	/* check if the UCC number is in range. */
106 	if (ucc_num > UCC_MAX_NUM - 1)
107 		return -EINVAL;
108 
109 	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
110 
111 	if (set)
112 		setbits32(cmxucr, mask << shift);
113 	else
114 		clrbits32(cmxucr, mask << shift);
115 
116 	return 0;
117 }
118 
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 	clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
211 		clock_bits << shift);
212 
213 	return 0;
214 }
215 
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 
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 
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 */
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 
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 
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 || tdm_num < 0)
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_clrsetbits32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
544 			clock_bits << shift);
545 
546 	return 0;
547 }
548 
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 
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 
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 *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_clrsetbits32(&qe_mux_reg->cmxsi1syr,
654 			QE_CMXUCR_TX_CLK_SRC_MASK << shift,
655 			source << shift);
656 
657 	return 0;
658 }
659