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