Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * arch/powerpc/sysdev/qe_lib/ucc.c
0004  *
0005  * QE UCC API Set - UCC specific routines implementations.
0006  *
0007  * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
0008  *
0009  * Authors:     Shlomi Gridish <gridish@freescale.com>
0010  *      Li Yang <leoli@freescale.com>
0011  */
0012 #include <linux/kernel.h>
0013 #include <linux/errno.h>
0014 #include <linux/stddef.h>
0015 #include <linux/spinlock.h>
0016 #include <linux/export.h>
0017 
0018 #include <asm/io.h>
0019 #include <soc/fsl/qe/immap_qe.h>
0020 #include <soc/fsl/qe/qe.h>
0021 #include <soc/fsl/qe/ucc.h>
0022 
0023 #define UCC_TDM_NUM 8
0024 #define RX_SYNC_SHIFT_BASE 30
0025 #define TX_SYNC_SHIFT_BASE 14
0026 #define RX_CLK_SHIFT_BASE 28
0027 #define TX_CLK_SHIFT_BASE 12
0028 
0029 int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
0030 {
0031     unsigned long flags;
0032 
0033     if (ucc_num > UCC_MAX_NUM - 1)
0034         return -EINVAL;
0035 
0036     spin_lock_irqsave(&cmxgcr_lock, flags);
0037     qe_clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
0038                ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
0039     spin_unlock_irqrestore(&cmxgcr_lock, flags);
0040 
0041     return 0;
0042 }
0043 EXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
0044 
0045 /* Configure the UCC to either Slow or Fast.
0046  *
0047  * A given UCC can be figured to support either "slow" devices (e.g. UART)
0048  * or "fast" devices (e.g. Ethernet).
0049  *
0050  * 'ucc_num' is the UCC number, from 0 - 7.
0051  *
0052  * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit
0053  * must always be set to 1.
0054  */
0055 int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
0056 {
0057     u8 __iomem *guemr;
0058 
0059     /* The GUEMR register is at the same location for both slow and fast
0060        devices, so we just use uccX.slow.guemr. */
0061     switch (ucc_num) {
0062     case 0: guemr = &qe_immr->ucc1.slow.guemr;
0063         break;
0064     case 1: guemr = &qe_immr->ucc2.slow.guemr;
0065         break;
0066     case 2: guemr = &qe_immr->ucc3.slow.guemr;
0067         break;
0068     case 3: guemr = &qe_immr->ucc4.slow.guemr;
0069         break;
0070     case 4: guemr = &qe_immr->ucc5.slow.guemr;
0071         break;
0072     case 5: guemr = &qe_immr->ucc6.slow.guemr;
0073         break;
0074     case 6: guemr = &qe_immr->ucc7.slow.guemr;
0075         break;
0076     case 7: guemr = &qe_immr->ucc8.slow.guemr;
0077         break;
0078     default:
0079         return -EINVAL;
0080     }
0081 
0082     qe_clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
0083             UCC_GUEMR_SET_RESERVED3 | speed);
0084 
0085     return 0;
0086 }
0087 
0088 static void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr,
0089     unsigned int *reg_num, unsigned int *shift)
0090 {
0091     unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3);
0092 
0093     *reg_num = cmx + 1;
0094     *cmxucr = &qe_immr->qmx.cmxucr[cmx];
0095     *shift = 16 - 8 * (ucc_num & 2);
0096 }
0097 
0098 int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
0099 {
0100     __be32 __iomem *cmxucr;
0101     unsigned int reg_num;
0102     unsigned int shift;
0103 
0104     /* check if the UCC number is in range. */
0105     if (ucc_num > UCC_MAX_NUM - 1)
0106         return -EINVAL;
0107 
0108     get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
0109 
0110     if (set)
0111         qe_setbits_be32(cmxucr, mask << shift);
0112     else
0113         qe_clrbits_be32(cmxucr, mask << shift);
0114 
0115     return 0;
0116 }
0117 
0118 int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
0119     enum comm_dir mode)
0120 {
0121     __be32 __iomem *cmxucr;
0122     unsigned int reg_num;
0123     unsigned int shift;
0124     u32 clock_bits = 0;
0125 
0126     /* check if the UCC number is in range. */
0127     if (ucc_num > UCC_MAX_NUM - 1)
0128         return -EINVAL;
0129 
0130     /* The communications direction must be RX or TX */
0131     if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
0132         return -EINVAL;
0133 
0134     get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
0135 
0136     switch (reg_num) {
0137     case 1:
0138         switch (clock) {
0139         case QE_BRG1:   clock_bits = 1; break;
0140         case QE_BRG2:   clock_bits = 2; break;
0141         case QE_BRG7:   clock_bits = 3; break;
0142         case QE_BRG8:   clock_bits = 4; break;
0143         case QE_CLK9:   clock_bits = 5; break;
0144         case QE_CLK10:  clock_bits = 6; break;
0145         case QE_CLK11:  clock_bits = 7; break;
0146         case QE_CLK12:  clock_bits = 8; break;
0147         case QE_CLK15:  clock_bits = 9; break;
0148         case QE_CLK16:  clock_bits = 10; break;
0149         default: break;
0150         }
0151         break;
0152     case 2:
0153         switch (clock) {
0154         case QE_BRG5:   clock_bits = 1; break;
0155         case QE_BRG6:   clock_bits = 2; break;
0156         case QE_BRG7:   clock_bits = 3; break;
0157         case QE_BRG8:   clock_bits = 4; break;
0158         case QE_CLK13:  clock_bits = 5; break;
0159         case QE_CLK14:  clock_bits = 6; break;
0160         case QE_CLK19:  clock_bits = 7; break;
0161         case QE_CLK20:  clock_bits = 8; break;
0162         case QE_CLK15:  clock_bits = 9; break;
0163         case QE_CLK16:  clock_bits = 10; break;
0164         default: break;
0165         }
0166         break;
0167     case 3:
0168         switch (clock) {
0169         case QE_BRG9:   clock_bits = 1; break;
0170         case QE_BRG10:  clock_bits = 2; break;
0171         case QE_BRG15:  clock_bits = 3; break;
0172         case QE_BRG16:  clock_bits = 4; break;
0173         case QE_CLK3:   clock_bits = 5; break;
0174         case QE_CLK4:   clock_bits = 6; break;
0175         case QE_CLK17:  clock_bits = 7; break;
0176         case QE_CLK18:  clock_bits = 8; break;
0177         case QE_CLK7:   clock_bits = 9; break;
0178         case QE_CLK8:   clock_bits = 10; break;
0179         case QE_CLK16:  clock_bits = 11; break;
0180         default: break;
0181         }
0182         break;
0183     case 4:
0184         switch (clock) {
0185         case QE_BRG13:  clock_bits = 1; break;
0186         case QE_BRG14:  clock_bits = 2; break;
0187         case QE_BRG15:  clock_bits = 3; break;
0188         case QE_BRG16:  clock_bits = 4; break;
0189         case QE_CLK5:   clock_bits = 5; break;
0190         case QE_CLK6:   clock_bits = 6; break;
0191         case QE_CLK21:  clock_bits = 7; break;
0192         case QE_CLK22:  clock_bits = 8; break;
0193         case QE_CLK7:   clock_bits = 9; break;
0194         case QE_CLK8:   clock_bits = 10; break;
0195         case QE_CLK16:  clock_bits = 11; break;
0196         default: break;
0197         }
0198         break;
0199     default: break;
0200     }
0201 
0202     /* Check for invalid combination of clock and UCC number */
0203     if (!clock_bits)
0204         return -ENOENT;
0205 
0206     if (mode == COMM_DIR_RX)
0207         shift += 4;
0208 
0209     qe_clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
0210                clock_bits << shift);
0211 
0212     return 0;
0213 }
0214 
0215 static int ucc_get_tdm_common_clk(u32 tdm_num, enum qe_clock clock)
0216 {
0217     int clock_bits = -EINVAL;
0218 
0219     /*
0220      * for TDM[0, 1, 2, 3], TX and RX use  common
0221      * clock source BRG3,4 and CLK1,2
0222      * for TDM[4, 5, 6, 7], TX and RX use  common
0223      * clock source BRG12,13 and CLK23,24
0224      */
0225     switch (tdm_num) {
0226     case 0:
0227     case 1:
0228     case 2:
0229     case 3:
0230         switch (clock) {
0231         case QE_BRG3:
0232             clock_bits = 1;
0233             break;
0234         case QE_BRG4:
0235             clock_bits = 2;
0236             break;
0237         case QE_CLK1:
0238             clock_bits = 4;
0239             break;
0240         case QE_CLK2:
0241             clock_bits = 5;
0242             break;
0243         default:
0244             break;
0245         }
0246         break;
0247     case 4:
0248     case 5:
0249     case 6:
0250     case 7:
0251         switch (clock) {
0252         case QE_BRG12:
0253             clock_bits = 1;
0254             break;
0255         case QE_BRG13:
0256             clock_bits = 2;
0257             break;
0258         case QE_CLK23:
0259             clock_bits = 4;
0260             break;
0261         case QE_CLK24:
0262             clock_bits = 5;
0263             break;
0264         default:
0265             break;
0266         }
0267         break;
0268     default:
0269         break;
0270     }
0271 
0272     return clock_bits;
0273 }
0274 
0275 static int ucc_get_tdm_rx_clk(u32 tdm_num, enum qe_clock clock)
0276 {
0277     int clock_bits = -EINVAL;
0278 
0279     switch (tdm_num) {
0280     case 0:
0281         switch (clock) {
0282         case QE_CLK3:
0283             clock_bits = 6;
0284             break;
0285         case QE_CLK8:
0286             clock_bits = 7;
0287             break;
0288         default:
0289             break;
0290         }
0291         break;
0292     case 1:
0293         switch (clock) {
0294         case QE_CLK5:
0295             clock_bits = 6;
0296             break;
0297         case QE_CLK10:
0298             clock_bits = 7;
0299             break;
0300         default:
0301             break;
0302         }
0303         break;
0304     case 2:
0305         switch (clock) {
0306         case QE_CLK7:
0307             clock_bits = 6;
0308             break;
0309         case QE_CLK12:
0310             clock_bits = 7;
0311             break;
0312         default:
0313             break;
0314         }
0315         break;
0316     case 3:
0317         switch (clock) {
0318         case QE_CLK9:
0319             clock_bits = 6;
0320             break;
0321         case QE_CLK14:
0322             clock_bits = 7;
0323             break;
0324         default:
0325             break;
0326         }
0327         break;
0328     case 4:
0329         switch (clock) {
0330         case QE_CLK11:
0331             clock_bits = 6;
0332             break;
0333         case QE_CLK16:
0334             clock_bits = 7;
0335             break;
0336         default:
0337             break;
0338         }
0339         break;
0340     case 5:
0341         switch (clock) {
0342         case QE_CLK13:
0343             clock_bits = 6;
0344             break;
0345         case QE_CLK18:
0346             clock_bits = 7;
0347             break;
0348         default:
0349             break;
0350         }
0351         break;
0352     case 6:
0353         switch (clock) {
0354         case QE_CLK15:
0355             clock_bits = 6;
0356             break;
0357         case QE_CLK20:
0358             clock_bits = 7;
0359             break;
0360         default:
0361             break;
0362         }
0363         break;
0364     case 7:
0365         switch (clock) {
0366         case QE_CLK17:
0367             clock_bits = 6;
0368             break;
0369         case QE_CLK22:
0370             clock_bits = 7;
0371             break;
0372         default:
0373             break;
0374         }
0375         break;
0376     }
0377 
0378     return clock_bits;
0379 }
0380 
0381 static int ucc_get_tdm_tx_clk(u32 tdm_num, enum qe_clock clock)
0382 {
0383     int clock_bits = -EINVAL;
0384 
0385     switch (tdm_num) {
0386     case 0:
0387         switch (clock) {
0388         case QE_CLK4:
0389             clock_bits = 6;
0390             break;
0391         case QE_CLK9:
0392             clock_bits = 7;
0393             break;
0394         default:
0395             break;
0396         }
0397         break;
0398     case 1:
0399         switch (clock) {
0400         case QE_CLK6:
0401             clock_bits = 6;
0402             break;
0403         case QE_CLK11:
0404             clock_bits = 7;
0405             break;
0406         default:
0407             break;
0408         }
0409         break;
0410     case 2:
0411         switch (clock) {
0412         case QE_CLK8:
0413             clock_bits = 6;
0414             break;
0415         case QE_CLK13:
0416             clock_bits = 7;
0417             break;
0418         default:
0419             break;
0420         }
0421         break;
0422     case 3:
0423         switch (clock) {
0424         case QE_CLK10:
0425             clock_bits = 6;
0426             break;
0427         case QE_CLK15:
0428             clock_bits = 7;
0429             break;
0430         default:
0431             break;
0432         }
0433         break;
0434     case 4:
0435         switch (clock) {
0436         case QE_CLK12:
0437             clock_bits = 6;
0438             break;
0439         case QE_CLK17:
0440             clock_bits = 7;
0441             break;
0442         default:
0443             break;
0444         }
0445         break;
0446     case 5:
0447         switch (clock) {
0448         case QE_CLK14:
0449             clock_bits = 6;
0450             break;
0451         case QE_CLK19:
0452             clock_bits = 7;
0453             break;
0454         default:
0455             break;
0456         }
0457         break;
0458     case 6:
0459         switch (clock) {
0460         case QE_CLK16:
0461             clock_bits = 6;
0462             break;
0463         case QE_CLK21:
0464             clock_bits = 7;
0465             break;
0466         default:
0467             break;
0468         }
0469         break;
0470     case 7:
0471         switch (clock) {
0472         case QE_CLK18:
0473             clock_bits = 6;
0474             break;
0475         case QE_CLK3:
0476             clock_bits = 7;
0477             break;
0478         default:
0479             break;
0480         }
0481         break;
0482     }
0483 
0484     return clock_bits;
0485 }
0486 
0487 /* tdm_num: TDM A-H port num is 0-7 */
0488 static int ucc_get_tdm_rxtx_clk(enum comm_dir mode, u32 tdm_num,
0489                 enum qe_clock clock)
0490 {
0491     int clock_bits;
0492 
0493     clock_bits = ucc_get_tdm_common_clk(tdm_num, clock);
0494     if (clock_bits > 0)
0495         return clock_bits;
0496     if (mode == COMM_DIR_RX)
0497         clock_bits = ucc_get_tdm_rx_clk(tdm_num, clock);
0498     if (mode == COMM_DIR_TX)
0499         clock_bits = ucc_get_tdm_tx_clk(tdm_num, clock);
0500     return clock_bits;
0501 }
0502 
0503 static u32 ucc_get_tdm_clk_shift(enum comm_dir mode, u32 tdm_num)
0504 {
0505     u32 shift;
0506 
0507     shift = (mode == COMM_DIR_RX) ? RX_CLK_SHIFT_BASE : TX_CLK_SHIFT_BASE;
0508     if (tdm_num < 4)
0509         shift -= tdm_num * 4;
0510     else
0511         shift -= (tdm_num - 4) * 4;
0512 
0513     return shift;
0514 }
0515 
0516 int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
0517              enum comm_dir mode)
0518 {
0519     int clock_bits;
0520     u32 shift;
0521     struct qe_mux __iomem *qe_mux_reg;
0522     __be32 __iomem *cmxs1cr;
0523 
0524     qe_mux_reg = &qe_immr->qmx;
0525 
0526     if (tdm_num > 7)
0527         return -EINVAL;
0528 
0529     /* The communications direction must be RX or TX */
0530     if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
0531         return -EINVAL;
0532 
0533     clock_bits = ucc_get_tdm_rxtx_clk(mode, tdm_num, clock);
0534     if (clock_bits < 0)
0535         return -EINVAL;
0536 
0537     shift = ucc_get_tdm_clk_shift(mode, tdm_num);
0538 
0539     cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l :
0540                   &qe_mux_reg->cmxsi1cr_h;
0541 
0542     qe_clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
0543                clock_bits << shift);
0544 
0545     return 0;
0546 }
0547 
0548 static int ucc_get_tdm_sync_source(u32 tdm_num, enum qe_clock clock,
0549                    enum comm_dir mode)
0550 {
0551     int source = -EINVAL;
0552 
0553     if (mode == COMM_DIR_RX && clock == QE_RSYNC_PIN) {
0554         source = 0;
0555         return source;
0556     }
0557     if (mode == COMM_DIR_TX && clock == QE_TSYNC_PIN) {
0558         source = 0;
0559         return source;
0560     }
0561 
0562     switch (tdm_num) {
0563     case 0:
0564     case 1:
0565         switch (clock) {
0566         case QE_BRG9:
0567             source = 1;
0568             break;
0569         case QE_BRG10:
0570             source = 2;
0571             break;
0572         default:
0573             break;
0574         }
0575         break;
0576     case 2:
0577     case 3:
0578         switch (clock) {
0579         case QE_BRG9:
0580             source = 1;
0581             break;
0582         case QE_BRG11:
0583             source = 2;
0584             break;
0585         default:
0586             break;
0587         }
0588         break;
0589     case 4:
0590     case 5:
0591         switch (clock) {
0592         case QE_BRG13:
0593             source = 1;
0594             break;
0595         case QE_BRG14:
0596             source = 2;
0597             break;
0598         default:
0599             break;
0600         }
0601         break;
0602     case 6:
0603     case 7:
0604         switch (clock) {
0605         case QE_BRG13:
0606             source = 1;
0607             break;
0608         case QE_BRG15:
0609             source = 2;
0610             break;
0611         default:
0612             break;
0613         }
0614         break;
0615     }
0616 
0617     return source;
0618 }
0619 
0620 static u32 ucc_get_tdm_sync_shift(enum comm_dir mode, u32 tdm_num)
0621 {
0622     u32 shift;
0623 
0624     shift = (mode == COMM_DIR_RX) ? RX_SYNC_SHIFT_BASE : TX_SYNC_SHIFT_BASE;
0625     shift -= tdm_num * 2;
0626 
0627     return shift;
0628 }
0629 
0630 int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
0631               enum comm_dir mode)
0632 {
0633     int source;
0634     u32 shift;
0635     struct qe_mux __iomem *qe_mux_reg;
0636 
0637     qe_mux_reg = &qe_immr->qmx;
0638 
0639     if (tdm_num >= UCC_TDM_NUM)
0640         return -EINVAL;
0641 
0642     /* The communications direction must be RX or TX */
0643     if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
0644         return -EINVAL;
0645 
0646     source = ucc_get_tdm_sync_source(tdm_num, clock, mode);
0647     if (source < 0)
0648         return -EINVAL;
0649 
0650     shift = ucc_get_tdm_sync_shift(mode, tdm_num);
0651 
0652     qe_clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
0653                QE_CMXUCR_TX_CLK_SRC_MASK << shift,
0654                source << shift);
0655 
0656     return 0;
0657 }