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, ®_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, ®_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