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