1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2006 Freescale Semiconductor, Inc. 4 * 5 * Dave Liu <daveliu@freescale.com> 6 * based on source code of Shlomi Gridish 7 */ 8 9#include <malloc.h> 10#include <linux/errno.h> 11#include <asm/io.h> 12#include <linux/immap_qe.h> 13#include "uccf.h" 14#include <fsl_qe.h> 15 16void ucc_fast_transmit_on_demand(struct ucc_fast_priv *uccf) 17{ 18 out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD); 19} 20 21u32 ucc_fast_get_qe_cr_subblock(int ucc_num) 22{ 23 switch (ucc_num) { 24 case 0: 25 return QE_CR_SUBBLOCK_UCCFAST1; 26 case 1: 27 return QE_CR_SUBBLOCK_UCCFAST2; 28 case 2: 29 return QE_CR_SUBBLOCK_UCCFAST3; 30 case 3: 31 return QE_CR_SUBBLOCK_UCCFAST4; 32 case 4: 33 return QE_CR_SUBBLOCK_UCCFAST5; 34 case 5: 35 return QE_CR_SUBBLOCK_UCCFAST6; 36 case 6: 37 return QE_CR_SUBBLOCK_UCCFAST7; 38 case 7: 39 return QE_CR_SUBBLOCK_UCCFAST8; 40 default: 41 return QE_CR_SUBBLOCK_INVALID; 42 } 43} 44 45static void ucc_get_cmxucr_reg(int ucc_num, u32 **p_cmxucr, 46 u8 *reg_num, u8 *shift) 47{ 48 switch (ucc_num) { 49 case 0: /* UCC1 */ 50 *p_cmxucr = &qe_immr->qmx.cmxucr1; 51 *reg_num = 1; 52 *shift = 16; 53 break; 54 case 2: /* UCC3 */ 55 *p_cmxucr = &qe_immr->qmx.cmxucr1; 56 *reg_num = 1; 57 *shift = 0; 58 break; 59 case 4: /* UCC5 */ 60 *p_cmxucr = &qe_immr->qmx.cmxucr2; 61 *reg_num = 2; 62 *shift = 16; 63 break; 64 case 6: /* UCC7 */ 65 *p_cmxucr = &qe_immr->qmx.cmxucr2; 66 *reg_num = 2; 67 *shift = 0; 68 break; 69 case 1: /* UCC2 */ 70 *p_cmxucr = &qe_immr->qmx.cmxucr3; 71 *reg_num = 3; 72 *shift = 16; 73 break; 74 case 3: /* UCC4 */ 75 *p_cmxucr = &qe_immr->qmx.cmxucr3; 76 *reg_num = 3; 77 *shift = 0; 78 break; 79 case 5: /* UCC6 */ 80 *p_cmxucr = &qe_immr->qmx.cmxucr4; 81 *reg_num = 4; 82 *shift = 16; 83 break; 84 case 7: /* UCC8 */ 85 *p_cmxucr = &qe_immr->qmx.cmxucr4; 86 *reg_num = 4; 87 *shift = 0; 88 break; 89 default: 90 break; 91 } 92} 93 94static int ucc_set_clk_src(int ucc_num, qe_clock_e clock, comm_dir_e mode) 95{ 96 u32 *p_cmxucr = NULL; 97 u8 reg_num = 0; 98 u8 shift = 0; 99 u32 clk_bits; 100 u32 clk_mask; 101 int source = -1; 102 103 /* check if the UCC number is in range. */ 104 if ((ucc_num > UCC_MAX_NUM - 1) || ucc_num < 0) 105 return -EINVAL; 106 107 if (!(mode == COMM_DIR_RX || mode == COMM_DIR_TX)) { 108 printf("%s: bad comm mode type passed\n", __func__); 109 return -EINVAL; 110 } 111 112 ucc_get_cmxucr_reg(ucc_num, &p_cmxucr, ®_num, &shift); 113 114 switch (reg_num) { 115 case 1: 116 switch (clock) { 117 case QE_BRG1: 118 source = 1; 119 break; 120 case QE_BRG2: 121 source = 2; 122 break; 123 case QE_BRG7: 124 source = 3; 125 break; 126 case QE_BRG8: 127 source = 4; 128 break; 129 case QE_CLK9: 130 source = 5; 131 break; 132 case QE_CLK10: 133 source = 6; 134 break; 135 case QE_CLK11: 136 source = 7; 137 break; 138 case QE_CLK12: 139 source = 8; 140 break; 141 case QE_CLK15: 142 source = 9; 143 break; 144 case QE_CLK16: 145 source = 10; 146 break; 147 default: 148 source = -1; 149 break; 150 } 151 break; 152 case 2: 153 switch (clock) { 154 case QE_BRG5: 155 source = 1; 156 break; 157 case QE_BRG6: 158 source = 2; 159 break; 160 case QE_BRG7: 161 source = 3; 162 break; 163 case QE_BRG8: 164 source = 4; 165 break; 166 case QE_CLK13: 167 source = 5; 168 break; 169 case QE_CLK14: 170 source = 6; 171 break; 172 case QE_CLK19: 173 source = 7; 174 break; 175 case QE_CLK20: 176 source = 8; 177 break; 178 case QE_CLK15: 179 source = 9; 180 break; 181 case QE_CLK16: 182 source = 10; 183 break; 184 default: 185 source = -1; 186 break; 187 } 188 break; 189 case 3: 190 switch (clock) { 191 case QE_BRG9: 192 source = 1; 193 break; 194 case QE_BRG10: 195 source = 2; 196 break; 197 case QE_BRG15: 198 source = 3; 199 break; 200 case QE_BRG16: 201 source = 4; 202 break; 203 case QE_CLK3: 204 source = 5; 205 break; 206 case QE_CLK4: 207 source = 6; 208 break; 209 case QE_CLK17: 210 source = 7; 211 break; 212 case QE_CLK18: 213 source = 8; 214 break; 215 case QE_CLK7: 216 source = 9; 217 break; 218 case QE_CLK8: 219 source = 10; 220 break; 221 case QE_CLK16: 222 source = 11; 223 break; 224 default: 225 source = -1; 226 break; 227 } 228 break; 229 case 4: 230 switch (clock) { 231 case QE_BRG13: 232 source = 1; 233 break; 234 case QE_BRG14: 235 source = 2; 236 break; 237 case QE_BRG15: 238 source = 3; 239 break; 240 case QE_BRG16: 241 source = 4; 242 break; 243 case QE_CLK5: 244 source = 5; 245 break; 246 case QE_CLK6: 247 source = 6; 248 break; 249 case QE_CLK21: 250 source = 7; 251 break; 252 case QE_CLK22: 253 source = 8; 254 break; 255 case QE_CLK7: 256 source = 9; 257 break; 258 case QE_CLK8: 259 source = 10; 260 break; 261 case QE_CLK16: 262 source = 11; 263 break; 264 default: 265 source = -1; 266 break; 267 } 268 break; 269 default: 270 source = -1; 271 break; 272 } 273 274 if (source == -1) { 275 printf("%s: Bad combination of clock and UCC\n", __func__); 276 return -ENOENT; 277 } 278 279 clk_bits = (u32)source; 280 clk_mask = QE_CMXUCR_TX_CLK_SRC_MASK; 281 if (mode == COMM_DIR_RX) { 282 clk_bits <<= 4; /* Rx field is 4 bits to left of Tx field */ 283 clk_mask <<= 4; /* Rx field is 4 bits to left of Tx field */ 284 } 285 clk_bits <<= shift; 286 clk_mask <<= shift; 287 288 out_be32(p_cmxucr, (in_be32(p_cmxucr) & ~clk_mask) | clk_bits); 289 290 return 0; 291} 292 293static uint ucc_get_reg_baseaddr(int ucc_num) 294{ 295 uint base = 0; 296 297 /* check if the UCC number is in range */ 298 if ((ucc_num > UCC_MAX_NUM - 1) || ucc_num < 0) { 299 printf("%s: the UCC num not in ranges\n", __func__); 300 return 0; 301 } 302 303 switch (ucc_num) { 304 case 0: 305 base = 0x00002000; 306 break; 307 case 1: 308 base = 0x00003000; 309 break; 310 case 2: 311 base = 0x00002200; 312 break; 313 case 3: 314 base = 0x00003200; 315 break; 316 case 4: 317 base = 0x00002400; 318 break; 319 case 5: 320 base = 0x00003400; 321 break; 322 case 6: 323 base = 0x00002600; 324 break; 325 case 7: 326 base = 0x00003600; 327 break; 328 default: 329 break; 330 } 331 332 base = (uint)qe_immr + base; 333 return base; 334} 335 336void ucc_fast_enable(struct ucc_fast_priv *uccf, comm_dir_e mode) 337{ 338 ucc_fast_t *uf_regs; 339 u32 gumr; 340 341 uf_regs = uccf->uf_regs; 342 343 /* Enable reception and/or transmission on this UCC. */ 344 gumr = in_be32(&uf_regs->gumr); 345 if (mode & COMM_DIR_TX) { 346 gumr |= UCC_FAST_GUMR_ENT; 347 uccf->enabled_tx = 1; 348 } 349 if (mode & COMM_DIR_RX) { 350 gumr |= UCC_FAST_GUMR_ENR; 351 uccf->enabled_rx = 1; 352 } 353 out_be32(&uf_regs->gumr, gumr); 354} 355 356void ucc_fast_disable(struct ucc_fast_priv *uccf, comm_dir_e mode) 357{ 358 ucc_fast_t *uf_regs; 359 u32 gumr; 360 361 uf_regs = uccf->uf_regs; 362 363 /* Disable reception and/or transmission on this UCC. */ 364 gumr = in_be32(&uf_regs->gumr); 365 if (mode & COMM_DIR_TX) { 366 gumr &= ~UCC_FAST_GUMR_ENT; 367 uccf->enabled_tx = 0; 368 } 369 if (mode & COMM_DIR_RX) { 370 gumr &= ~UCC_FAST_GUMR_ENR; 371 uccf->enabled_rx = 0; 372 } 373 out_be32(&uf_regs->gumr, gumr); 374} 375 376int ucc_fast_init(struct ucc_fast_inf *uf_info, 377 struct ucc_fast_priv **uccf_ret) 378{ 379 struct ucc_fast_priv *uccf; 380 ucc_fast_t *uf_regs; 381 382 if (!uf_info) 383 return -EINVAL; 384 385 if (uf_info->ucc_num < 0 || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { 386 printf("%s: Illagal UCC number!\n", __func__); 387 return -EINVAL; 388 } 389 390 uccf = (struct ucc_fast_priv *)malloc(sizeof(struct ucc_fast_priv)); 391 if (!uccf) { 392 printf("%s: No memory for UCC fast data structure!\n", 393 __func__); 394 return -ENOMEM; 395 } 396 memset(uccf, 0, sizeof(struct ucc_fast_priv)); 397 398 /* Save fast UCC structure */ 399 uccf->uf_info = uf_info; 400 uccf->uf_regs = (ucc_fast_t *)ucc_get_reg_baseaddr(uf_info->ucc_num); 401 402 if (!uccf->uf_regs) { 403 printf("%s: No memory map for UCC fast controller!\n", 404 __func__); 405 return -ENOMEM; 406 } 407 408 uccf->enabled_tx = 0; 409 uccf->enabled_rx = 0; 410 411 uf_regs = uccf->uf_regs; 412 uccf->p_ucce = (u32 *)&uf_regs->ucce; 413 uccf->p_uccm = (u32 *)&uf_regs->uccm; 414 415 /* Init GUEMR register, UCC both Rx and Tx is Fast protocol */ 416 out_8(&uf_regs->guemr, UCC_GUEMR_SET_RESERVED3 | UCC_GUEMR_MODE_FAST_RX 417 | UCC_GUEMR_MODE_FAST_TX); 418 419 /* Set GUMR, disable UCC both Rx and Tx, Ethernet protocol */ 420 out_be32(&uf_regs->gumr, UCC_FAST_GUMR_ETH); 421 422 /* Set the Giga ethernet VFIFO stuff */ 423 if (uf_info->eth_type == GIGA_ETH) { 424 /* Allocate memory for Tx Virtual Fifo */ 425 uccf->ucc_fast_tx_virtual_fifo_base_offset = 426 qe_muram_alloc(UCC_GETH_UTFS_GIGA_INIT, 427 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); 428 429 /* Allocate memory for Rx Virtual Fifo */ 430 uccf->ucc_fast_rx_virtual_fifo_base_offset = 431 qe_muram_alloc(UCC_GETH_URFS_GIGA_INIT + 432 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD, 433 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); 434 435 /* utfb, urfb are offsets from MURAM base */ 436 out_be32(&uf_regs->utfb, 437 uccf->ucc_fast_tx_virtual_fifo_base_offset); 438 out_be32(&uf_regs->urfb, 439 uccf->ucc_fast_rx_virtual_fifo_base_offset); 440 441 /* Set Virtual Fifo registers */ 442 out_be16(&uf_regs->urfs, UCC_GETH_URFS_GIGA_INIT); 443 out_be16(&uf_regs->urfet, UCC_GETH_URFET_GIGA_INIT); 444 out_be16(&uf_regs->urfset, UCC_GETH_URFSET_GIGA_INIT); 445 out_be16(&uf_regs->utfs, UCC_GETH_UTFS_GIGA_INIT); 446 out_be16(&uf_regs->utfet, UCC_GETH_UTFET_GIGA_INIT); 447 out_be16(&uf_regs->utftt, UCC_GETH_UTFTT_GIGA_INIT); 448 } 449 450 /* Set the Fast ethernet VFIFO stuff */ 451 if (uf_info->eth_type == FAST_ETH) { 452 /* Allocate memory for Tx Virtual Fifo */ 453 uccf->ucc_fast_tx_virtual_fifo_base_offset = 454 qe_muram_alloc(UCC_GETH_UTFS_INIT, 455 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); 456 457 /* Allocate memory for Rx Virtual Fifo */ 458 uccf->ucc_fast_rx_virtual_fifo_base_offset = 459 qe_muram_alloc(UCC_GETH_URFS_INIT + 460 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD, 461 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); 462 463 /* utfb, urfb are offsets from MURAM base */ 464 out_be32(&uf_regs->utfb, 465 uccf->ucc_fast_tx_virtual_fifo_base_offset); 466 out_be32(&uf_regs->urfb, 467 uccf->ucc_fast_rx_virtual_fifo_base_offset); 468 469 /* Set Virtual Fifo registers */ 470 out_be16(&uf_regs->urfs, UCC_GETH_URFS_INIT); 471 out_be16(&uf_regs->urfet, UCC_GETH_URFET_INIT); 472 out_be16(&uf_regs->urfset, UCC_GETH_URFSET_INIT); 473 out_be16(&uf_regs->utfs, UCC_GETH_UTFS_INIT); 474 out_be16(&uf_regs->utfet, UCC_GETH_UTFET_INIT); 475 out_be16(&uf_regs->utftt, UCC_GETH_UTFTT_INIT); 476 } 477 478 /* Rx clock routing */ 479 if (uf_info->rx_clock != QE_CLK_NONE) { 480 if (ucc_set_clk_src(uf_info->ucc_num, 481 uf_info->rx_clock, COMM_DIR_RX)) { 482 printf("%s: Illegal value for parameter 'RxClock'.\n", 483 __func__); 484 return -EINVAL; 485 } 486 } 487 488 /* Tx clock routing */ 489 if (uf_info->tx_clock != QE_CLK_NONE) { 490 if (ucc_set_clk_src(uf_info->ucc_num, 491 uf_info->tx_clock, COMM_DIR_TX)) { 492 printf("%s: Illegal value for parameter 'TxClock'.\n", 493 __func__); 494 return -EINVAL; 495 } 496 } 497 498 /* Clear interrupt mask register to disable all of interrupts */ 499 out_be32(&uf_regs->uccm, 0x0); 500 501 /* Writing '1' to clear all of envents */ 502 out_be32(&uf_regs->ucce, 0xffffffff); 503 504 *uccf_ret = uccf; 505 return 0; 506} 507