2 * Copyright (C) 2006 Freescale Semiconductor, 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/errno.h>
17 #include <linux/slab.h>
18 #include <linux/stddef.h>
19 #include <linux/interrupt.h>
20 #include <linux/err.h>
21 #include <linux/export.h>
24 #include <soc/fsl/qe/immap_qe.h>
25 #include <soc/fsl/qe/qe.h>
27 #include <soc/fsl/qe/ucc.h>
28 #include <soc/fsl/qe/ucc_slow.h>
30 u32
ucc_slow_get_qe_cr_subblock(int uccs_num
)
33 case 0: return QE_CR_SUBBLOCK_UCCSLOW1
;
34 case 1: return QE_CR_SUBBLOCK_UCCSLOW2
;
35 case 2: return QE_CR_SUBBLOCK_UCCSLOW3
;
36 case 3: return QE_CR_SUBBLOCK_UCCSLOW4
;
37 case 4: return QE_CR_SUBBLOCK_UCCSLOW5
;
38 case 5: return QE_CR_SUBBLOCK_UCCSLOW6
;
39 case 6: return QE_CR_SUBBLOCK_UCCSLOW7
;
40 case 7: return QE_CR_SUBBLOCK_UCCSLOW8
;
41 default: return QE_CR_SUBBLOCK_INVALID
;
44 EXPORT_SYMBOL(ucc_slow_get_qe_cr_subblock
);
46 void ucc_slow_graceful_stop_tx(struct ucc_slow_private
* uccs
)
48 struct ucc_slow_info
*us_info
= uccs
->us_info
;
51 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
52 qe_issue_cmd(QE_GRACEFUL_STOP_TX
, id
,
53 QE_CR_PROTOCOL_UNSPECIFIED
, 0);
55 EXPORT_SYMBOL(ucc_slow_graceful_stop_tx
);
57 void ucc_slow_stop_tx(struct ucc_slow_private
* uccs
)
59 struct ucc_slow_info
*us_info
= uccs
->us_info
;
62 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
63 qe_issue_cmd(QE_STOP_TX
, id
, QE_CR_PROTOCOL_UNSPECIFIED
, 0);
65 EXPORT_SYMBOL(ucc_slow_stop_tx
);
67 void ucc_slow_restart_tx(struct ucc_slow_private
* uccs
)
69 struct ucc_slow_info
*us_info
= uccs
->us_info
;
72 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
73 qe_issue_cmd(QE_RESTART_TX
, id
, QE_CR_PROTOCOL_UNSPECIFIED
, 0);
75 EXPORT_SYMBOL(ucc_slow_restart_tx
);
77 void ucc_slow_enable(struct ucc_slow_private
* uccs
, enum comm_dir mode
)
79 struct ucc_slow
*us_regs
;
82 us_regs
= uccs
->us_regs
;
84 /* Enable reception and/or transmission on this UCC. */
85 gumr_l
= in_be32(&us_regs
->gumr_l
);
86 if (mode
& COMM_DIR_TX
) {
87 gumr_l
|= UCC_SLOW_GUMR_L_ENT
;
90 if (mode
& COMM_DIR_RX
) {
91 gumr_l
|= UCC_SLOW_GUMR_L_ENR
;
94 out_be32(&us_regs
->gumr_l
, gumr_l
);
96 EXPORT_SYMBOL(ucc_slow_enable
);
98 void ucc_slow_disable(struct ucc_slow_private
* uccs
, enum comm_dir mode
)
100 struct ucc_slow
*us_regs
;
103 us_regs
= uccs
->us_regs
;
105 /* Disable reception and/or transmission on this UCC. */
106 gumr_l
= in_be32(&us_regs
->gumr_l
);
107 if (mode
& COMM_DIR_TX
) {
108 gumr_l
&= ~UCC_SLOW_GUMR_L_ENT
;
109 uccs
->enabled_tx
= 0;
111 if (mode
& COMM_DIR_RX
) {
112 gumr_l
&= ~UCC_SLOW_GUMR_L_ENR
;
113 uccs
->enabled_rx
= 0;
115 out_be32(&us_regs
->gumr_l
, gumr_l
);
117 EXPORT_SYMBOL(ucc_slow_disable
);
119 /* Initialize the UCC for Slow operations
121 * The caller should initialize the following us_info
123 int ucc_slow_init(struct ucc_slow_info
* us_info
, struct ucc_slow_private
** uccs_ret
)
125 struct ucc_slow_private
*uccs
;
127 struct ucc_slow __iomem
*us_regs
;
137 /* check if the UCC port number is in range. */
138 if ((us_info
->ucc_num
< 0) || (us_info
->ucc_num
> UCC_MAX_NUM
- 1)) {
139 printk(KERN_ERR
"%s: illegal UCC number\n", __func__
);
145 * Check that 'max_rx_buf_length' is properly aligned (4), unless
146 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
147 * case when QE accepts 32 bits at a time.
149 if ((!us_info
->rfw
) &&
150 (us_info
->max_rx_buf_length
& (UCC_SLOW_MRBLR_ALIGNMENT
- 1))) {
151 printk(KERN_ERR
"max_rx_buf_length not aligned.\n");
155 uccs
= kzalloc(sizeof(struct ucc_slow_private
), GFP_KERNEL
);
157 printk(KERN_ERR
"%s: Cannot allocate private data\n",
162 /* Fill slow UCC structure */
163 uccs
->us_info
= us_info
;
164 /* Set the PHY base address */
165 uccs
->us_regs
= ioremap(us_info
->regs
, sizeof(struct ucc_slow
));
166 if (uccs
->us_regs
== NULL
) {
167 printk(KERN_ERR
"%s: Cannot map UCC registers\n", __func__
);
172 uccs
->saved_uccm
= 0;
173 uccs
->p_rx_frame
= 0;
174 us_regs
= uccs
->us_regs
;
175 uccs
->p_ucce
= (u16
*) & (us_regs
->ucce
);
176 uccs
->p_uccm
= (u16
*) & (us_regs
->uccm
);
180 uccs
->rx_discarded
= 0;
181 #endif /* STATISTICS */
184 uccs
->us_pram_offset
=
185 qe_muram_alloc(UCC_SLOW_PRAM_SIZE
, ALIGNMENT_OF_UCC_SLOW_PRAM
);
186 if (IS_ERR_VALUE(uccs
->us_pram_offset
)) {
187 printk(KERN_ERR
"%s: cannot allocate MURAM for PRAM", __func__
);
191 id
= ucc_slow_get_qe_cr_subblock(us_info
->ucc_num
);
192 qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE
, id
, us_info
->protocol
,
193 uccs
->us_pram_offset
);
195 uccs
->us_pram
= qe_muram_addr(uccs
->us_pram_offset
);
197 /* Set UCC to slow type */
198 ret
= ucc_set_type(us_info
->ucc_num
, UCC_SPEED_TYPE_SLOW
);
200 printk(KERN_ERR
"%s: cannot set UCC type", __func__
);
205 out_be16(&uccs
->us_pram
->mrblr
, us_info
->max_rx_buf_length
);
207 INIT_LIST_HEAD(&uccs
->confQ
);
210 uccs
->rx_base_offset
=
211 qe_muram_alloc(us_info
->rx_bd_ring_len
* sizeof(struct qe_bd
),
213 if (IS_ERR_VALUE(uccs
->rx_base_offset
)) {
214 printk(KERN_ERR
"%s: cannot allocate %u RX BDs\n", __func__
,
215 us_info
->rx_bd_ring_len
);
216 uccs
->rx_base_offset
= 0;
221 uccs
->tx_base_offset
=
222 qe_muram_alloc(us_info
->tx_bd_ring_len
* sizeof(struct qe_bd
),
224 if (IS_ERR_VALUE(uccs
->tx_base_offset
)) {
225 printk(KERN_ERR
"%s: cannot allocate TX BDs", __func__
);
226 uccs
->tx_base_offset
= 0;
232 bd
= uccs
->confBd
= uccs
->tx_bd
= qe_muram_addr(uccs
->tx_base_offset
);
233 for (i
= 0; i
< us_info
->tx_bd_ring_len
- 1; i
++) {
234 /* clear bd buffer */
235 out_be32(&bd
->buf
, 0);
236 /* set bd status and length */
237 out_be32((u32
*) bd
, 0);
240 /* for last BD set Wrap bit */
241 out_be32(&bd
->buf
, 0);
242 out_be32((u32
*) bd
, cpu_to_be32(T_W
));
245 bd
= uccs
->rx_bd
= qe_muram_addr(uccs
->rx_base_offset
);
246 for (i
= 0; i
< us_info
->rx_bd_ring_len
- 1; i
++) {
247 /* set bd status and length */
248 out_be32((u32
*)bd
, 0);
249 /* clear bd buffer */
250 out_be32(&bd
->buf
, 0);
253 /* for last BD set Wrap bit */
254 out_be32((u32
*)bd
, cpu_to_be32(R_W
));
255 out_be32(&bd
->buf
, 0);
257 /* Set GUMR (For more details see the hardware spec.). */
259 gumr
= us_info
->tcrc
;
261 gumr
|= UCC_SLOW_GUMR_H_CDP
;
263 gumr
|= UCC_SLOW_GUMR_H_CTSP
;
265 gumr
|= UCC_SLOW_GUMR_H_CDS
;
267 gumr
|= UCC_SLOW_GUMR_H_CTSS
;
269 gumr
|= UCC_SLOW_GUMR_H_TFL
;
271 gumr
|= UCC_SLOW_GUMR_H_RFW
;
273 gumr
|= UCC_SLOW_GUMR_H_TXSY
;
275 gumr
|= UCC_SLOW_GUMR_H_RTSM
;
276 out_be32(&us_regs
->gumr_h
, gumr
);
279 gumr
= us_info
->tdcr
| us_info
->rdcr
| us_info
->tenc
| us_info
->renc
|
280 us_info
->diag
| us_info
->mode
;
282 gumr
|= UCC_SLOW_GUMR_L_TCI
;
284 gumr
|= UCC_SLOW_GUMR_L_RINV
;
286 gumr
|= UCC_SLOW_GUMR_L_TINV
;
288 gumr
|= UCC_SLOW_GUMR_L_TEND
;
289 out_be32(&us_regs
->gumr_l
, gumr
);
291 /* Function code registers */
293 /* if the data is in cachable memory, the 'global' */
294 /* in the function code should be set. */
295 uccs
->us_pram
->tbmr
= UCC_BMR_BO_BE
;
296 uccs
->us_pram
->rbmr
= UCC_BMR_BO_BE
;
298 /* rbase, tbase are offsets from MURAM base */
299 out_be16(&uccs
->us_pram
->rbase
, uccs
->rx_base_offset
);
300 out_be16(&uccs
->us_pram
->tbase
, uccs
->tx_base_offset
);
304 ucc_set_qe_mux_grant(us_info
->ucc_num
, us_info
->grant_support
);
305 /* Breakpoint Support */
306 ucc_set_qe_mux_bkpt(us_info
->ucc_num
, us_info
->brkpt_support
);
307 /* Set Tsa or NMSI mode. */
308 ucc_set_qe_mux_tsa(us_info
->ucc_num
, us_info
->tsa
);
309 /* If NMSI (not Tsa), set Tx and Rx clock. */
311 /* Rx clock routing */
312 if (ucc_set_qe_mux_rxtx(us_info
->ucc_num
, us_info
->rx_clock
,
314 printk(KERN_ERR
"%s: illegal value for RX clock\n",
319 /* Tx clock routing */
320 if (ucc_set_qe_mux_rxtx(us_info
->ucc_num
, us_info
->tx_clock
,
322 printk(KERN_ERR
"%s: illegal value for TX clock\n",
329 /* Set interrupt mask register at UCC level. */
330 out_be16(&us_regs
->uccm
, us_info
->uccm_mask
);
332 /* First, clear anything pending at UCC level,
333 * otherwise, old garbage may come through
334 * as soon as the dam is opened. */
336 /* Writing '1' clears */
337 out_be16(&us_regs
->ucce
, 0xffff);
339 /* Issue QE Init command */
340 if (us_info
->init_tx
&& us_info
->init_rx
)
341 command
= QE_INIT_TX_RX
;
342 else if (us_info
->init_tx
)
343 command
= QE_INIT_TX
;
345 command
= QE_INIT_RX
; /* We know at least one is TRUE */
347 qe_issue_cmd(command
, id
, us_info
->protocol
, 0);
352 EXPORT_SYMBOL(ucc_slow_init
);
354 void ucc_slow_free(struct ucc_slow_private
* uccs
)
359 if (uccs
->rx_base_offset
)
360 qe_muram_free(uccs
->rx_base_offset
);
362 if (uccs
->tx_base_offset
)
363 qe_muram_free(uccs
->tx_base_offset
);
366 qe_muram_free(uccs
->us_pram_offset
);
369 iounmap(uccs
->us_regs
);
373 EXPORT_SYMBOL(ucc_slow_free
);