root/drivers/soc/fsl/qe/ucc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ucc_set_qe_mux_mii_mng
  2. ucc_set_type
  3. get_cmxucr_reg
  4. ucc_mux_set_grant_tsa_bkpt
  5. ucc_set_qe_mux_rxtx
  6. ucc_get_tdm_common_clk
  7. ucc_get_tdm_rx_clk
  8. ucc_get_tdm_tx_clk
  9. ucc_get_tdm_rxtx_clk
  10. ucc_get_tdm_clk_shift
  11. ucc_set_tdm_rxtx_clk
  12. ucc_get_tdm_sync_source
  13. ucc_get_tdm_sync_shift
  14. ucc_set_tdm_rxtx_sync

   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 }

/* [<][>][^][v][top][bottom][index][help] */