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