2 * Copyright (C) 2006 Freescale Semiconductor, Inc.
4 * Dave Liu <daveliu@freescale.com>
5 * based on source code of Shlomi Gridish
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 #include "asm/errno.h"
27 #include "asm/immap_qe.h"
31 #if defined(CONFIG_QE)
32 void ucc_fast_transmit_on_demand(ucc_fast_private_t
*uccf
)
34 out_be16(&uccf
->uf_regs
->utodr
, UCC_FAST_TOD
);
37 u32
ucc_fast_get_qe_cr_subblock(int ucc_num
)
40 case 0: return QE_CR_SUBBLOCK_UCCFAST1
;
41 case 1: return QE_CR_SUBBLOCK_UCCFAST2
;
42 case 2: return QE_CR_SUBBLOCK_UCCFAST3
;
43 case 3: return QE_CR_SUBBLOCK_UCCFAST4
;
44 case 4: return QE_CR_SUBBLOCK_UCCFAST5
;
45 case 5: return QE_CR_SUBBLOCK_UCCFAST6
;
46 case 6: return QE_CR_SUBBLOCK_UCCFAST7
;
47 case 7: return QE_CR_SUBBLOCK_UCCFAST8
;
48 default: return QE_CR_SUBBLOCK_INVALID
;
52 static void ucc_get_cmxucr_reg(int ucc_num
, volatile u32
**p_cmxucr
,
53 u8
*reg_num
, u8
*shift
)
57 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr1
);
62 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr1
);
67 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr2
);
72 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr2
);
77 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr3
);
82 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr3
);
87 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr4
);
92 *p_cmxucr
= &(qe_immr
->qmx
.cmxucr4
);
101 static int ucc_set_clk_src(int ucc_num
, qe_clock_e clock
, comm_dir_e mode
)
103 volatile u32
*p_cmxucr
= NULL
;
110 /* check if the UCC number is in range. */
111 if ((ucc_num
> UCC_MAX_NUM
- 1) || (ucc_num
< 0))
114 if (! ((mode
== COMM_DIR_RX
) || (mode
== COMM_DIR_TX
))) {
115 printf("%s: bad comm mode type passed\n", __FUNCTION__
);
119 ucc_get_cmxucr_reg(ucc_num
, &p_cmxucr
, ®_num
, &shift
);
124 case QE_BRG1
: source
= 1; break;
125 case QE_BRG2
: source
= 2; break;
126 case QE_BRG7
: source
= 3; break;
127 case QE_BRG8
: source
= 4; break;
128 case QE_CLK9
: source
= 5; break;
129 case QE_CLK10
: source
= 6; break;
130 case QE_CLK11
: source
= 7; break;
131 case QE_CLK12
: source
= 8; break;
132 case QE_CLK15
: source
= 9; break;
133 case QE_CLK16
: source
= 10; break;
134 default: source
= -1; break;
139 case QE_BRG5
: source
= 1; break;
140 case QE_BRG6
: source
= 2; break;
141 case QE_BRG7
: source
= 3; break;
142 case QE_BRG8
: source
= 4; break;
143 case QE_CLK13
: source
= 5; break;
144 case QE_CLK14
: source
= 6; break;
145 case QE_CLK19
: source
= 7; break;
146 case QE_CLK20
: source
= 8; break;
147 case QE_CLK15
: source
= 9; break;
148 case QE_CLK16
: source
= 10; break;
149 default: source
= -1; break;
154 case QE_BRG9
: source
= 1; break;
155 case QE_BRG10
: source
= 2; break;
156 case QE_BRG15
: source
= 3; break;
157 case QE_BRG16
: source
= 4; break;
158 case QE_CLK3
: source
= 5; break;
159 case QE_CLK4
: source
= 6; break;
160 case QE_CLK17
: source
= 7; break;
161 case QE_CLK18
: source
= 8; break;
162 case QE_CLK7
: source
= 9; break;
163 case QE_CLK8
: source
= 10; break;
164 case QE_CLK16
: source
= 11; break;
165 default: source
= -1; break;
170 case QE_BRG13
: source
= 1; break;
171 case QE_BRG14
: source
= 2; break;
172 case QE_BRG15
: source
= 3; break;
173 case QE_BRG16
: source
= 4; break;
174 case QE_CLK5
: source
= 5; break;
175 case QE_CLK6
: source
= 6; break;
176 case QE_CLK21
: source
= 7; break;
177 case QE_CLK22
: source
= 8; break;
178 case QE_CLK7
: source
= 9; break;
179 case QE_CLK8
: source
= 10; break;
180 case QE_CLK16
: source
= 11; break;
181 default: source
= -1; break;
190 printf("%s: Bad combination of clock and UCC\n", __FUNCTION__
);
194 clockBits
= (u32
) source
;
195 clockMask
= QE_CMXUCR_TX_CLK_SRC_MASK
;
196 if (mode
== COMM_DIR_RX
) {
197 clockBits
<<= 4; /* Rx field is 4 bits to left of Tx field */
198 clockMask
<<= 4; /* Rx field is 4 bits to left of Tx field */
203 out_be32(p_cmxucr
, (in_be32(p_cmxucr
) & ~clockMask
) | clockBits
);
208 static uint
ucc_get_reg_baseaddr(int ucc_num
)
212 /* check if the UCC number is in range */
213 if ((ucc_num
> UCC_MAX_NUM
- 1) || (ucc_num
< 0)) {
214 printf("%s: the UCC num not in ranges\n", __FUNCTION__
);
219 case 0: base
= 0x00002000; break;
220 case 1: base
= 0x00003000; break;
221 case 2: base
= 0x00002200; break;
222 case 3: base
= 0x00003200; break;
223 case 4: base
= 0x00002400; break;
224 case 5: base
= 0x00003400; break;
225 case 6: base
= 0x00002600; break;
226 case 7: base
= 0x00003600; break;
230 base
= (uint
)qe_immr
+ base
;
234 void ucc_fast_enable(ucc_fast_private_t
*uccf
, comm_dir_e mode
)
239 uf_regs
= uccf
->uf_regs
;
241 /* Enable reception and/or transmission on this UCC. */
242 gumr
= in_be32(&uf_regs
->gumr
);
243 if (mode
& COMM_DIR_TX
) {
244 gumr
|= UCC_FAST_GUMR_ENT
;
245 uccf
->enabled_tx
= 1;
247 if (mode
& COMM_DIR_RX
) {
248 gumr
|= UCC_FAST_GUMR_ENR
;
249 uccf
->enabled_rx
= 1;
251 out_be32(&uf_regs
->gumr
, gumr
);
254 void ucc_fast_disable(ucc_fast_private_t
*uccf
, comm_dir_e mode
)
259 uf_regs
= uccf
->uf_regs
;
261 /* Disable reception and/or transmission on this UCC. */
262 gumr
= in_be32(&uf_regs
->gumr
);
263 if (mode
& COMM_DIR_TX
) {
264 gumr
&= ~UCC_FAST_GUMR_ENT
;
265 uccf
->enabled_tx
= 0;
267 if (mode
& COMM_DIR_RX
) {
268 gumr
&= ~UCC_FAST_GUMR_ENR
;
269 uccf
->enabled_rx
= 0;
271 out_be32(&uf_regs
->gumr
, gumr
);
274 int ucc_fast_init(ucc_fast_info_t
*uf_info
, ucc_fast_private_t
**uccf_ret
)
276 ucc_fast_private_t
*uccf
;
282 if ((uf_info
->ucc_num
< 0) || (uf_info
->ucc_num
> UCC_MAX_NUM
- 1)) {
283 printf("%s: Illagal UCC number!\n", __FUNCTION__
);
287 uccf
= (ucc_fast_private_t
*)malloc(sizeof(ucc_fast_private_t
));
289 printf("%s: No memory for UCC fast data structure!\n",
293 memset(uccf
, 0, sizeof(ucc_fast_private_t
));
295 /* Save fast UCC structure */
296 uccf
->uf_info
= uf_info
;
297 uccf
->uf_regs
= (ucc_fast_t
*)ucc_get_reg_baseaddr(uf_info
->ucc_num
);
299 if (uccf
->uf_regs
== NULL
) {
300 printf("%s: No memory map for UCC fast controller!\n",
305 uccf
->enabled_tx
= 0;
306 uccf
->enabled_rx
= 0;
308 uf_regs
= uccf
->uf_regs
;
309 uccf
->p_ucce
= (u32
*) &(uf_regs
->ucce
);
310 uccf
->p_uccm
= (u32
*) &(uf_regs
->uccm
);
312 /* Init GUEMR register, UCC both Rx and Tx is Fast protocol */
313 out_8(&uf_regs
->guemr
, UCC_GUEMR_SET_RESERVED3
| UCC_GUEMR_MODE_FAST_RX
314 | UCC_GUEMR_MODE_FAST_TX
);
316 /* Set GUMR, disable UCC both Rx and Tx, Ethernet protocol */
317 out_be32(&uf_regs
->gumr
, UCC_FAST_GUMR_ETH
);
319 /* Set the Giga ethernet VFIFO stuff */
320 if (uf_info
->eth_type
== GIGA_ETH
) {
321 /* Allocate memory for Tx Virtual Fifo */
322 uccf
->ucc_fast_tx_virtual_fifo_base_offset
=
323 qe_muram_alloc(UCC_GETH_UTFS_GIGA_INIT
,
324 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
326 /* Allocate memory for Rx Virtual Fifo */
327 uccf
->ucc_fast_rx_virtual_fifo_base_offset
=
328 qe_muram_alloc(UCC_GETH_URFS_GIGA_INIT
+
329 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD
,
330 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
332 /* utfb, urfb are offsets from MURAM base */
333 out_be32(&uf_regs
->utfb
,
334 uccf
->ucc_fast_tx_virtual_fifo_base_offset
);
335 out_be32(&uf_regs
->urfb
,
336 uccf
->ucc_fast_rx_virtual_fifo_base_offset
);
338 /* Set Virtual Fifo registers */
339 out_be16(&uf_regs
->urfs
, UCC_GETH_URFS_GIGA_INIT
);
340 out_be16(&uf_regs
->urfet
, UCC_GETH_URFET_GIGA_INIT
);
341 out_be16(&uf_regs
->urfset
, UCC_GETH_URFSET_GIGA_INIT
);
342 out_be16(&uf_regs
->utfs
, UCC_GETH_UTFS_GIGA_INIT
);
343 out_be16(&uf_regs
->utfet
, UCC_GETH_UTFET_GIGA_INIT
);
344 out_be16(&uf_regs
->utftt
, UCC_GETH_UTFTT_GIGA_INIT
);
347 /* Set the Fast ethernet VFIFO stuff */
348 if (uf_info
->eth_type
== FAST_ETH
) {
349 /* Allocate memory for Tx Virtual Fifo */
350 uccf
->ucc_fast_tx_virtual_fifo_base_offset
=
351 qe_muram_alloc(UCC_GETH_UTFS_INIT
,
352 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
354 /* Allocate memory for Rx Virtual Fifo */
355 uccf
->ucc_fast_rx_virtual_fifo_base_offset
=
356 qe_muram_alloc(UCC_GETH_URFS_INIT
+
357 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD
,
358 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT
);
360 /* utfb, urfb are offsets from MURAM base */
361 out_be32(&uf_regs
->utfb
,
362 uccf
->ucc_fast_tx_virtual_fifo_base_offset
);
363 out_be32(&uf_regs
->urfb
,
364 uccf
->ucc_fast_rx_virtual_fifo_base_offset
);
366 /* Set Virtual Fifo registers */
367 out_be16(&uf_regs
->urfs
, UCC_GETH_URFS_INIT
);
368 out_be16(&uf_regs
->urfet
, UCC_GETH_URFET_INIT
);
369 out_be16(&uf_regs
->urfset
, UCC_GETH_URFSET_INIT
);
370 out_be16(&uf_regs
->utfs
, UCC_GETH_UTFS_INIT
);
371 out_be16(&uf_regs
->utfet
, UCC_GETH_UTFET_INIT
);
372 out_be16(&uf_regs
->utftt
, UCC_GETH_UTFTT_INIT
);
375 /* Rx clock routing */
376 if (uf_info
->rx_clock
!= QE_CLK_NONE
) {
377 if (ucc_set_clk_src(uf_info
->ucc_num
,
378 uf_info
->rx_clock
, COMM_DIR_RX
)) {
379 printf("%s: Illegal value for parameter 'RxClock'.\n",
385 /* Tx clock routing */
386 if (uf_info
->tx_clock
!= QE_CLK_NONE
) {
387 if (ucc_set_clk_src(uf_info
->ucc_num
,
388 uf_info
->tx_clock
, COMM_DIR_TX
)) {
389 printf("%s: Illegal value for parameter 'TxClock'.\n",
395 /* Clear interrupt mask register to disable all of interrupts */
396 out_be32(&uf_regs
->uccm
, 0x0);
398 /* Writing '1' to clear all of envents */
399 out_be32(&uf_regs
->ucce
, 0xffffffff);
404 #endif /* CONFIG_QE */