2 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
4 * Authors: Shlomi Gridish <gridish@freescale.com>
5 * Li Yang <leoli@freescale.com>
8 * QE UCC Slow API Set - UCC Slow specific routines implementations.
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/errno.h>
18 #include <linux/slab.h>
19 #include <linux/stddef.h>
20 #include <linux/interrupt.h>
21 #include <linux/err.h>
22 #include <linux/module.h>
25 #include <asm/immap_qe.h>
29 #include <asm/ucc_slow.h>
31 u32
ucc_slow_get_qe_cr_subblock(int uccs_num
)
34 case 0: return QE_CR_SUBBLOCK_UCCSLOW1
;
35 case 1: return QE_CR_SUBBLOCK_UCCSLOW2
;
36 case 2: return QE_CR_SUBBLOCK_UCCSLOW3
;
37 case 3: return QE_CR_SUBBLOCK_UCCSLOW4
;
38 case 4: return QE_CR_SUBBLOCK_UCCSLOW5
;
39 case 5: return QE_CR_SUBBLOCK_UCCSLOW6
;
40 case 6: return QE_CR_SUBBLOCK_UCCSLOW7
;
41 case 7: return QE_CR_SUBBLOCK_UCCSLOW8
;
42 default: return QE_CR_SUBBLOCK_INVALID
;
45 EXPORT_SYMBOL(ucc_slow_get_qe_cr_subblock
);
47 void ucc_slow_poll_transmitter_now(struct ucc_slow_private
* uccs
)
49 out_be16(&uccs
->us_regs
->utodr
, UCC_SLOW_TOD
);
52 void ucc_slow_graceful_stop_tx(struct ucc_slow_private
* uccs
)
54 struct ucc_slow_info
*us_info
= uccs
->us_info
;
57 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
58 qe_issue_cmd(QE_GRACEFUL_STOP_TX
, id
,
59 QE_CR_PROTOCOL_UNSPECIFIED
, 0);
61 EXPORT_SYMBOL(ucc_slow_graceful_stop_tx
);
63 void ucc_slow_stop_tx(struct ucc_slow_private
* uccs
)
65 struct ucc_slow_info
*us_info
= uccs
->us_info
;
68 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
69 qe_issue_cmd(QE_STOP_TX
, id
, QE_CR_PROTOCOL_UNSPECIFIED
, 0);
71 EXPORT_SYMBOL(ucc_slow_stop_tx
);
73 void ucc_slow_restart_tx(struct ucc_slow_private
* uccs
)
75 struct ucc_slow_info
*us_info
= uccs
->us_info
;
78 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
79 qe_issue_cmd(QE_RESTART_TX
, id
, QE_CR_PROTOCOL_UNSPECIFIED
, 0);
81 EXPORT_SYMBOL(ucc_slow_restart_tx
);
83 void ucc_slow_enable(struct ucc_slow_private
* uccs
, enum comm_dir mode
)
85 struct ucc_slow
*us_regs
;
88 us_regs
= uccs
->us_regs
;
90 /* Enable reception and/or transmission on this UCC. */
91 gumr_l
= in_be32(&us_regs
->gumr_l
);
92 if (mode
& COMM_DIR_TX
) {
93 gumr_l
|= UCC_SLOW_GUMR_L_ENT
;
96 if (mode
& COMM_DIR_RX
) {
97 gumr_l
|= UCC_SLOW_GUMR_L_ENR
;
100 out_be32(&us_regs
->gumr_l
, gumr_l
);
102 EXPORT_SYMBOL(ucc_slow_enable
);
104 void ucc_slow_disable(struct ucc_slow_private
* uccs
, enum comm_dir mode
)
106 struct ucc_slow
*us_regs
;
109 us_regs
= uccs
->us_regs
;
111 /* Disable reception and/or transmission on this UCC. */
112 gumr_l
= in_be32(&us_regs
->gumr_l
);
113 if (mode
& COMM_DIR_TX
) {
114 gumr_l
&= ~UCC_SLOW_GUMR_L_ENT
;
115 uccs
->enabled_tx
= 0;
117 if (mode
& COMM_DIR_RX
) {
118 gumr_l
&= ~UCC_SLOW_GUMR_L_ENR
;
119 uccs
->enabled_rx
= 0;
121 out_be32(&us_regs
->gumr_l
, gumr_l
);
123 EXPORT_SYMBOL(ucc_slow_disable
);
125 /* Initialize the UCC for Slow operations
127 * The caller should initialize the following us_info
129 int ucc_slow_init(struct ucc_slow_info
* us_info
, struct ucc_slow_private
** uccs_ret
)
131 struct ucc_slow_private
*uccs
;
133 struct ucc_slow __iomem
*us_regs
;
143 /* check if the UCC port number is in range. */
144 if ((us_info
->ucc_num
< 0) || (us_info
->ucc_num
> UCC_MAX_NUM
- 1)) {
145 printk(KERN_ERR
"%s: illegal UCC number\n", __FUNCTION__
);
151 * Check that 'max_rx_buf_length' is properly aligned (4), unless
152 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
153 * case when QE accepts 32 bits at a time.
155 if ((!us_info
->rfw
) &&
156 (us_info
->max_rx_buf_length
& (UCC_SLOW_MRBLR_ALIGNMENT
- 1))) {
157 printk(KERN_ERR
"max_rx_buf_length not aligned.\n");
161 uccs
= kzalloc(sizeof(struct ucc_slow_private
), GFP_KERNEL
);
163 printk(KERN_ERR
"%s: Cannot allocate private data\n",
168 /* Fill slow UCC structure */
169 uccs
->us_info
= us_info
;
170 /* Set the PHY base address */
171 uccs
->us_regs
= ioremap(us_info
->regs
, sizeof(struct ucc_slow
));
172 if (uccs
->us_regs
== NULL
) {
173 printk(KERN_ERR
"%s: Cannot map UCC registers\n", __FUNCTION__
);
177 uccs
->saved_uccm
= 0;
178 uccs
->p_rx_frame
= 0;
179 us_regs
= uccs
->us_regs
;
180 uccs
->p_ucce
= (u16
*) & (us_regs
->ucce
);
181 uccs
->p_uccm
= (u16
*) & (us_regs
->uccm
);
185 uccs
->rx_discarded
= 0;
186 #endif /* STATISTICS */
189 uccs
->us_pram_offset
=
190 qe_muram_alloc(UCC_SLOW_PRAM_SIZE
, ALIGNMENT_OF_UCC_SLOW_PRAM
);
191 if (IS_ERR_VALUE(uccs
->us_pram_offset
)) {
192 printk(KERN_ERR
"%s: cannot allocate MURAM for PRAM", __FUNCTION__
);
196 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
197 qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE
, id
, us_info
->protocol
,
198 uccs
->us_pram_offset
);
200 uccs
->us_pram
= qe_muram_addr(uccs
->us_pram_offset
);
202 /* Set UCC to slow type */
203 ret
= ucc_set_type(us_info
->ucc_num
, UCC_SPEED_TYPE_SLOW
);
205 printk(KERN_ERR
"%s: cannot set UCC type", __FUNCTION__
);
210 out_be16(&uccs
->us_pram
->mrblr
, us_info
->max_rx_buf_length
);
212 INIT_LIST_HEAD(&uccs
->confQ
);
215 uccs
->rx_base_offset
=
216 qe_muram_alloc(us_info
->rx_bd_ring_len
* sizeof(struct qe_bd
),
218 if (IS_ERR_VALUE(uccs
->rx_base_offset
)) {
219 printk(KERN_ERR
"%s: cannot allocate %u RX BDs\n", __FUNCTION__
,
220 us_info
->rx_bd_ring_len
);
221 uccs
->rx_base_offset
= 0;
226 uccs
->tx_base_offset
=
227 qe_muram_alloc(us_info
->tx_bd_ring_len
* sizeof(struct qe_bd
),
229 if (IS_ERR_VALUE(uccs
->tx_base_offset
)) {
230 printk(KERN_ERR
"%s: cannot allocate TX BDs", __FUNCTION__
);
231 uccs
->tx_base_offset
= 0;
237 bd
= uccs
->confBd
= uccs
->tx_bd
= qe_muram_addr(uccs
->tx_base_offset
);
238 for (i
= 0; i
< us_info
->tx_bd_ring_len
- 1; i
++) {
239 /* clear bd buffer */
240 out_be32(&bd
->buf
, 0);
241 /* set bd status and length */
242 out_be32((u32
*) bd
, 0);
245 /* for last BD set Wrap bit */
246 out_be32(&bd
->buf
, 0);
247 out_be32((u32
*) bd
, cpu_to_be32(T_W
));
250 bd
= uccs
->rx_bd
= qe_muram_addr(uccs
->rx_base_offset
);
251 for (i
= 0; i
< us_info
->rx_bd_ring_len
- 1; i
++) {
252 /* set bd status and length */
253 out_be32((u32
*)bd
, 0);
254 /* clear bd buffer */
255 out_be32(&bd
->buf
, 0);
258 /* for last BD set Wrap bit */
259 out_be32((u32
*)bd
, cpu_to_be32(R_W
));
260 out_be32(&bd
->buf
, 0);
262 /* Set GUMR (For more details see the hardware spec.). */
264 gumr
= us_info
->tcrc
;
266 gumr
|= UCC_SLOW_GUMR_H_CDP
;
268 gumr
|= UCC_SLOW_GUMR_H_CTSP
;
270 gumr
|= UCC_SLOW_GUMR_H_CDS
;
272 gumr
|= UCC_SLOW_GUMR_H_CTSS
;
274 gumr
|= UCC_SLOW_GUMR_H_TFL
;
276 gumr
|= UCC_SLOW_GUMR_H_RFW
;
278 gumr
|= UCC_SLOW_GUMR_H_TXSY
;
280 gumr
|= UCC_SLOW_GUMR_H_RTSM
;
281 out_be32(&us_regs
->gumr_h
, gumr
);
284 gumr
= us_info
->tdcr
| us_info
->rdcr
| us_info
->tenc
| us_info
->renc
|
285 us_info
->diag
| us_info
->mode
;
287 gumr
|= UCC_SLOW_GUMR_L_TCI
;
289 gumr
|= UCC_SLOW_GUMR_L_RINV
;
291 gumr
|= UCC_SLOW_GUMR_L_TINV
;
293 gumr
|= UCC_SLOW_GUMR_L_TEND
;
294 out_be32(&us_regs
->gumr_l
, gumr
);
296 /* Function code registers */
298 /* if the data is in cachable memory, the 'global' */
299 /* in the function code should be set. */
300 uccs
->us_pram
->tbmr
= UCC_BMR_BO_BE
;
301 uccs
->us_pram
->rbmr
= UCC_BMR_BO_BE
;
303 /* rbase, tbase are offsets from MURAM base */
304 out_be16(&uccs
->us_pram
->rbase
, uccs
->rx_base_offset
);
305 out_be16(&uccs
->us_pram
->tbase
, uccs
->tx_base_offset
);
309 ucc_set_qe_mux_grant(us_info
->ucc_num
, us_info
->grant_support
);
310 /* Breakpoint Support */
311 ucc_set_qe_mux_bkpt(us_info
->ucc_num
, us_info
->brkpt_support
);
312 /* Set Tsa or NMSI mode. */
313 ucc_set_qe_mux_tsa(us_info
->ucc_num
, us_info
->tsa
);
314 /* If NMSI (not Tsa), set Tx and Rx clock. */
316 /* Rx clock routing */
317 if (ucc_set_qe_mux_rxtx(us_info
->ucc_num
, us_info
->rx_clock
,
319 printk(KERN_ERR
"%s: illegal value for RX clock\n",
324 /* Tx clock routing */
325 if (ucc_set_qe_mux_rxtx(us_info
->ucc_num
, us_info
->tx_clock
,
327 printk(KERN_ERR
"%s: illegal value for TX clock\n",
334 /* Set interrupt mask register at UCC level. */
335 out_be16(&us_regs
->uccm
, us_info
->uccm_mask
);
337 /* First, clear anything pending at UCC level,
338 * otherwise, old garbage may come through
339 * as soon as the dam is opened. */
341 /* Writing '1' clears */
342 out_be16(&us_regs
->ucce
, 0xffff);
344 /* Issue QE Init command */
345 if (us_info
->init_tx
&& us_info
->init_rx
)
346 command
= QE_INIT_TX_RX
;
347 else if (us_info
->init_tx
)
348 command
= QE_INIT_TX
;
350 command
= QE_INIT_RX
; /* We know at least one is TRUE */
352 qe_issue_cmd(command
, id
, us_info
->protocol
, 0);
357 EXPORT_SYMBOL(ucc_slow_init
);
359 void ucc_slow_free(struct ucc_slow_private
* uccs
)
364 if (uccs
->rx_base_offset
)
365 qe_muram_free(uccs
->rx_base_offset
);
367 if (uccs
->tx_base_offset
)
368 qe_muram_free(uccs
->tx_base_offset
);
371 qe_muram_free(uccs
->us_pram_offset
);
372 uccs
->us_pram
= NULL
;
377 EXPORT_SYMBOL(ucc_slow_free
);