2 * Copyright (C) 2006 Freescale Semiconductor, Inc.
4 * Dave Liu <daveliu@freescale.com>
5 * based on source code of Shlomi Gridish
7 * SPDX-License-Identifier: GPL-2.0+
12 #include <linux/errno.h>
14 #include <linux/immap_qe.h>
18 void ucc_fast_transmit_on_demand(ucc_fast_private_t
*uccf
)
20 out_be16(&uccf
->uf_regs
->utodr
, UCC_FAST_TOD
);
23 u32
ucc_fast_get_qe_cr_subblock(int ucc_num
)
26 case 0: return QE_CR_SUBBLOCK_UCCFAST1
;
27 case 1: return QE_CR_SUBBLOCK_UCCFAST2
;
28 case 2: return QE_CR_SUBBLOCK_UCCFAST3
;
29 case 3: return QE_CR_SUBBLOCK_UCCFAST4
;
30 case 4: return QE_CR_SUBBLOCK_UCCFAST5
;
31 case 5: return QE_CR_SUBBLOCK_UCCFAST6
;
32 case 6: return QE_CR_SUBBLOCK_UCCFAST7
;
33 case 7: return QE_CR_SUBBLOCK_UCCFAST8
;
34 default: return QE_CR_SUBBLOCK_INVALID
;
38 static void ucc_get_cmxucr_reg(int ucc_num
, volatile u32
**p_cmxucr
,
39 u8
*reg_num
, u8
*shift
)
43 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr1
);
48 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr1
);
53 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr2
);
58 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr2
);
63 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr3
);
68 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr3
);
73 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr4
);
78 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr4
);
87 static int ucc_set_clk_src(int ucc_num
, qe_clock_e clock
, comm_dir_e mode
)
89 volatile u32
*p_cmxucr
= NULL
;
96 /* check if the UCC number is in range. */
97 if ((ucc_num
> UCC_MAX_NUM
- 1) || (ucc_num
< 0))
100 if (! ((mode
== COMM_DIR_RX
) || (mode
== COMM_DIR_TX
))) {
101 printf("%s: bad comm mode type passed\n", __FUNCTION__
);
105 ucc_get_cmxucr_reg(ucc_num
, &p_cmxucr
, ®_num
, &shift
);
110 case QE_BRG1
: source
= 1; break;
111 case QE_BRG2
: source
= 2; break;
112 case QE_BRG7
: source
= 3; break;
113 case QE_BRG8
: source
= 4; break;
114 case QE_CLK9
: source
= 5; break;
115 case QE_CLK10
: source
= 6; break;
116 case QE_CLK11
: source
= 7; break;
117 case QE_CLK12
: source
= 8; break;
118 case QE_CLK15
: source
= 9; break;
119 case QE_CLK16
: source
= 10; break;
120 default: source
= -1; break;
125 case QE_BRG5
: source
= 1; break;
126 case QE_BRG6
: source
= 2; break;
127 case QE_BRG7
: source
= 3; break;
128 case QE_BRG8
: source
= 4; break;
129 case QE_CLK13
: source
= 5; break;
130 case QE_CLK14
: source
= 6; break;
131 case QE_CLK19
: source
= 7; break;
132 case QE_CLK20
: source
= 8; break;
133 case QE_CLK15
: source
= 9; break;
134 case QE_CLK16
: source
= 10; break;
135 default: source
= -1; break;
140 case QE_BRG9
: source
= 1; break;
141 case QE_BRG10
: source
= 2; break;
142 case QE_BRG15
: source
= 3; break;
143 case QE_BRG16
: source
= 4; break;
144 case QE_CLK3
: source
= 5; break;
145 case QE_CLK4
: source
= 6; break;
146 case QE_CLK17
: source
= 7; break;
147 case QE_CLK18
: source
= 8; break;
148 case QE_CLK7
: source
= 9; break;
149 case QE_CLK8
: source
= 10; break;
150 case QE_CLK16
: source
= 11; break;
151 default: source
= -1; break;
156 case QE_BRG13
: source
= 1; break;
157 case QE_BRG14
: source
= 2; break;
158 case QE_BRG15
: source
= 3; break;
159 case QE_BRG16
: source
= 4; break;
160 case QE_CLK5
: source
= 5; break;
161 case QE_CLK6
: source
= 6; break;
162 case QE_CLK21
: source
= 7; break;
163 case QE_CLK22
: source
= 8; break;
164 case QE_CLK7
: source
= 9; break;
165 case QE_CLK8
: source
= 10; break;
166 case QE_CLK16
: source
= 11; break;
167 default: source
= -1; break;
176 printf("%s: Bad combination of clock and UCC\n", __FUNCTION__
);
180 clockBits
= (u32
) source
;
181 clockMask
= QE_CMXUCR_TX_CLK_SRC_MASK
;
182 if (mode
== COMM_DIR_RX
) {
183 clockBits
<<= 4; /* Rx field is 4 bits to left of Tx field */
184 clockMask
<<= 4; /* Rx field is 4 bits to left of Tx field */
189 out_be32(p_cmxucr
, (in_be32(p_cmxucr
) & ~clockMask
) | clockBits
);
194 static uint
ucc_get_reg_baseaddr(int ucc_num
)
198 /* check if the UCC number is in range */
199 if ((ucc_num
> UCC_MAX_NUM
- 1) || (ucc_num
< 0)) {
200 printf("%s: the UCC num not in ranges\n", __FUNCTION__
);
205 case 0: base
= 0x00002000; break;
206 case 1: base
= 0x00003000; break;
207 case 2: base
= 0x00002200; break;
208 case 3: base
= 0x00003200; break;
209 case 4: base
= 0x00002400; break;
210 case 5: base
= 0x00003400; break;
211 case 6: base
= 0x00002600; break;
212 case 7: base
= 0x00003600; break;
216 base
= (uint
)qe_immr
+ base
;
220 void ucc_fast_enable(ucc_fast_private_t
*uccf
, comm_dir_e mode
)
225 uf_regs
= uccf
->uf_regs
;
227 /* Enable reception and/or transmission on this UCC. */
228 gumr
= in_be32(&uf_regs
->gumr
);
229 if (mode
& COMM_DIR_TX
) {
230 gumr
|= UCC_FAST_GUMR_ENT
;
231 uccf
->enabled_tx
= 1;
233 if (mode
& COMM_DIR_RX
) {
234 gumr
|= UCC_FAST_GUMR_ENR
;
235 uccf
->enabled_rx
= 1;
237 out_be32(&uf_regs
->gumr
, gumr
);
240 void ucc_fast_disable(ucc_fast_private_t
*uccf
, comm_dir_e mode
)
245 uf_regs
= uccf
->uf_regs
;
247 /* Disable reception and/or transmission on this UCC. */
248 gumr
= in_be32(&uf_regs
->gumr
);
249 if (mode
& COMM_DIR_TX
) {
250 gumr
&= ~UCC_FAST_GUMR_ENT
;
251 uccf
->enabled_tx
= 0;
253 if (mode
& COMM_DIR_RX
) {
254 gumr
&= ~UCC_FAST_GUMR_ENR
;
255 uccf
->enabled_rx
= 0;
257 out_be32(&uf_regs
->gumr
, gumr
);
260 int ucc_fast_init(ucc_fast_info_t
*uf_info
, ucc_fast_private_t
**uccf_ret
)
262 ucc_fast_private_t
*uccf
;
268 if ((uf_info
->ucc_num
< 0) || (uf_info
->ucc_num
> UCC_MAX_NUM
- 1)) {
269 printf("%s: Illagal UCC number!\n", __FUNCTION__
);
273 uccf
= (ucc_fast_private_t
*)malloc(sizeof(ucc_fast_private_t
));
275 printf("%s: No memory for UCC fast data structure!\n",
279 memset(uccf
, 0, sizeof(ucc_fast_private_t
));
281 /* Save fast UCC structure */
282 uccf
->uf_info
= uf_info
;
283 uccf
->uf_regs
= (ucc_fast_t
*)ucc_get_reg_baseaddr(uf_info
->ucc_num
);
285 if (uccf
->uf_regs
== NULL
) {
286 printf("%s: No memory map for UCC fast controller!\n",
291 uccf
->enabled_tx
= 0;
292 uccf
->enabled_rx
= 0;
294 uf_regs
= uccf
->uf_regs
;
295 uccf
->p_ucce
= (u32
*) &(uf_regs
->ucce
);
296 uccf
->p_uccm
= (u32
*) &(uf_regs
->uccm
);
298 /* Init GUEMR register, UCC both Rx and Tx is Fast protocol */
299 out_8(&uf_regs
->guemr
, UCC_GUEMR_SET_RESERVED3
| UCC_GUEMR_MODE_FAST_RX
300 | UCC_GUEMR_MODE_FAST_TX
);
302 /* Set GUMR, disable UCC both Rx and Tx, Ethernet protocol */
303 out_be32(&uf_regs
->gumr
, UCC_FAST_GUMR_ETH
);
305 /* Set the Giga ethernet VFIFO stuff */
306 if (uf_info
->eth_type
== GIGA_ETH
) {
307 /* Allocate memory for Tx Virtual Fifo */
308 uccf
->ucc_fast_tx_virtual_fifo_base_offset
=
309 qe_muram_alloc(UCC_GETH_UTFS_GIGA_INIT
,
310 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
312 /* Allocate memory for Rx Virtual Fifo */
313 uccf
->ucc_fast_rx_virtual_fifo_base_offset
=
314 qe_muram_alloc(UCC_GETH_URFS_GIGA_INIT
+
315 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD
,
316 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
318 /* utfb, urfb are offsets from MURAM base */
319 out_be32(&uf_regs
->utfb
,
320 uccf
->ucc_fast_tx_virtual_fifo_base_offset
);
321 out_be32(&uf_regs
->urfb
,
322 uccf
->ucc_fast_rx_virtual_fifo_base_offset
);
324 /* Set Virtual Fifo registers */
325 out_be16(&uf_regs
->urfs
, UCC_GETH_URFS_GIGA_INIT
);
326 out_be16(&uf_regs
->urfet
, UCC_GETH_URFET_GIGA_INIT
);
327 out_be16(&uf_regs
->urfset
, UCC_GETH_URFSET_GIGA_INIT
);
328 out_be16(&uf_regs
->utfs
, UCC_GETH_UTFS_GIGA_INIT
);
329 out_be16(&uf_regs
->utfet
, UCC_GETH_UTFET_GIGA_INIT
);
330 out_be16(&uf_regs
->utftt
, UCC_GETH_UTFTT_GIGA_INIT
);
333 /* Set the Fast ethernet VFIFO stuff */
334 if (uf_info
->eth_type
== FAST_ETH
) {
335 /* Allocate memory for Tx Virtual Fifo */
336 uccf
->ucc_fast_tx_virtual_fifo_base_offset
=
337 qe_muram_alloc(UCC_GETH_UTFS_INIT
,
338 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
340 /* Allocate memory for Rx Virtual Fifo */
341 uccf
->ucc_fast_rx_virtual_fifo_base_offset
=
342 qe_muram_alloc(UCC_GETH_URFS_INIT
+
343 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD
,
344 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
346 /* utfb, urfb are offsets from MURAM base */
347 out_be32(&uf_regs
->utfb
,
348 uccf
->ucc_fast_tx_virtual_fifo_base_offset
);
349 out_be32(&uf_regs
->urfb
,
350 uccf
->ucc_fast_rx_virtual_fifo_base_offset
);
352 /* Set Virtual Fifo registers */
353 out_be16(&uf_regs
->urfs
, UCC_GETH_URFS_INIT
);
354 out_be16(&uf_regs
->urfet
, UCC_GETH_URFET_INIT
);
355 out_be16(&uf_regs
->urfset
, UCC_GETH_URFSET_INIT
);
356 out_be16(&uf_regs
->utfs
, UCC_GETH_UTFS_INIT
);
357 out_be16(&uf_regs
->utfet
, UCC_GETH_UTFET_INIT
);
358 out_be16(&uf_regs
->utftt
, UCC_GETH_UTFTT_INIT
);
361 /* Rx clock routing */
362 if (uf_info
->rx_clock
!= QE_CLK_NONE
) {
363 if (ucc_set_clk_src(uf_info
->ucc_num
,
364 uf_info
->rx_clock
, COMM_DIR_RX
)) {
365 printf("%s: Illegal value for parameter 'RxClock'.\n",
371 /* Tx clock routing */
372 if (uf_info
->tx_clock
!= QE_CLK_NONE
) {
373 if (ucc_set_clk_src(uf_info
->ucc_num
,
374 uf_info
->tx_clock
, COMM_DIR_TX
)) {
375 printf("%s: Illegal value for parameter 'TxClock'.\n",
381 /* Clear interrupt mask register to disable all of interrupts */
382 out_be32(&uf_regs
->uccm
, 0x0);
384 /* Writing '1' to clear all of envents */
385 out_be32(&uf_regs
->ucce
, 0xffffffff);