blob: 00848a1a37d7b252b363bb20baa451a2bd0c5a77 [file] [log] [blame]
Heiko Schocher41b64a82020-02-06 09:48:16 +01001// 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
Heiko Schocher41b64a82020-02-06 09:48:16 +01009#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, &reg_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}