| Li Yang | 9865853 | 2006-10-03 23:10:46 -0500 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. | 
 | 3 |  * | 
 | 4 |  * Authors: 	Shlomi Gridish <gridish@freescale.com> | 
 | 5 |  * 		Li Yang <leoli@freescale.com> | 
 | 6 |  * | 
 | 7 |  * Description: | 
 | 8 |  * Internal header file for UCC SLOW unit routines. | 
 | 9 |  * | 
 | 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. | 
 | 14 |  */ | 
 | 15 | #ifndef __UCC_SLOW_H__ | 
 | 16 | #define __UCC_SLOW_H__ | 
 | 17 |  | 
 | 18 | #include <linux/kernel.h> | 
 | 19 |  | 
 | 20 | #include <asm/immap_qe.h> | 
 | 21 | #include <asm/qe.h> | 
 | 22 |  | 
 | 23 | #include "ucc.h" | 
 | 24 |  | 
 | 25 | /* transmit BD's status */ | 
 | 26 | #define T_R	0x80000000	/* ready bit */ | 
 | 27 | #define T_PAD	0x40000000	/* add pads to short frames */ | 
 | 28 | #define T_W	0x20000000	/* wrap bit */ | 
 | 29 | #define T_I	0x10000000	/* interrupt on completion */ | 
 | 30 | #define T_L	0x08000000	/* last */ | 
 | 31 |  | 
 | 32 | #define T_A	0x04000000	/* Address - the data transmitted as address | 
 | 33 | 				   chars */ | 
 | 34 | #define T_TC	0x04000000	/* transmit CRC */ | 
 | 35 | #define T_CM	0x02000000	/* continuous mode */ | 
 | 36 | #define T_DEF	0x02000000	/* collision on previous attempt to transmit */ | 
 | 37 | #define T_P	0x01000000	/* Preamble - send Preamble sequence before | 
 | 38 | 				   data */ | 
 | 39 | #define T_HB	0x01000000	/* heartbeat */ | 
 | 40 | #define T_NS	0x00800000	/* No Stop */ | 
 | 41 | #define T_LC	0x00800000	/* late collision */ | 
 | 42 | #define T_RL	0x00400000	/* retransmission limit */ | 
 | 43 | #define T_UN	0x00020000	/* underrun */ | 
 | 44 | #define T_CT	0x00010000	/* CTS lost */ | 
 | 45 | #define T_CSL	0x00010000	/* carrier sense lost */ | 
 | 46 | #define T_RC	0x003c0000	/* retry count */ | 
 | 47 |  | 
 | 48 | /* Receive BD's status */ | 
 | 49 | #define R_E	0x80000000	/* buffer empty */ | 
 | 50 | #define R_W	0x20000000	/* wrap bit */ | 
 | 51 | #define R_I	0x10000000	/* interrupt on reception */ | 
 | 52 | #define R_L	0x08000000	/* last */ | 
 | 53 | #define R_C	0x08000000	/* the last byte in this buffer is a cntl | 
 | 54 | 				   char */ | 
 | 55 | #define R_F	0x04000000	/* first */ | 
 | 56 | #define R_A	0x04000000	/* the first byte in this buffer is address | 
 | 57 | 				   byte */ | 
 | 58 | #define R_CM	0x02000000	/* continuous mode */ | 
 | 59 | #define R_ID	0x01000000	/* buffer close on reception of idles */ | 
 | 60 | #define R_M	0x01000000	/* Frame received because of promiscuous | 
 | 61 | 				   mode */ | 
 | 62 | #define R_AM	0x00800000	/* Address match */ | 
 | 63 | #define R_DE	0x00800000	/* Address match */ | 
 | 64 | #define R_LG	0x00200000	/* Break received */ | 
 | 65 | #define R_BR	0x00200000	/* Frame length violation */ | 
 | 66 | #define R_NO	0x00100000	/* Rx Non Octet Aligned Packet */ | 
 | 67 | #define R_FR	0x00100000	/* Framing Error (no stop bit) character | 
 | 68 | 				   received */ | 
 | 69 | #define R_PR	0x00080000	/* Parity Error character received */ | 
 | 70 | #define R_AB	0x00080000	/* Frame Aborted */ | 
 | 71 | #define R_SH	0x00080000	/* frame is too short */ | 
 | 72 | #define R_CR	0x00040000	/* CRC Error */ | 
 | 73 | #define R_OV	0x00020000	/* Overrun */ | 
 | 74 | #define R_CD	0x00010000	/* CD lost */ | 
 | 75 | #define R_CL	0x00010000	/* this frame is closed because of a | 
 | 76 | 				   collision */ | 
 | 77 |  | 
 | 78 | /* Rx Data buffer must be 4 bytes aligned in most cases.*/ | 
 | 79 | #define UCC_SLOW_RX_ALIGN		4 | 
 | 80 | #define UCC_SLOW_MRBLR_ALIGNMENT	4 | 
 | 81 | #define UCC_SLOW_PRAM_SIZE		0x100 | 
 | 82 | #define ALIGNMENT_OF_UCC_SLOW_PRAM	64 | 
 | 83 |  | 
 | 84 | /* UCC Slow Channel Protocol Mode */ | 
 | 85 | enum ucc_slow_channel_protocol_mode { | 
 | 86 | 	UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002, | 
 | 87 | 	UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004, | 
 | 88 | 	UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008, | 
 | 89 | }; | 
 | 90 |  | 
 | 91 | /* UCC Slow Transparent Transmit CRC (TCRC) */ | 
 | 92 | enum ucc_slow_transparent_tcrc { | 
 | 93 | 	/* 16-bit CCITT CRC (HDLC).  (X16 + X12 + X5 + 1) */ | 
 | 94 | 	UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000, | 
 | 95 | 	/* CRC16 (BISYNC).  (X16 + X15 + X2 + 1) */ | 
 | 96 | 	UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000, | 
 | 97 | 	/* 32-bit CCITT CRC (Ethernet and HDLC) */ | 
 | 98 | 	UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000, | 
 | 99 | }; | 
 | 100 |  | 
 | 101 | /* UCC Slow oversampling rate for transmitter (TDCR) */ | 
 | 102 | enum ucc_slow_tx_oversampling_rate { | 
 | 103 | 	/* 1x clock mode */ | 
 | 104 | 	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000, | 
 | 105 | 	/* 8x clock mode */ | 
 | 106 | 	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000, | 
 | 107 | 	/* 16x clock mode */ | 
 | 108 | 	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000, | 
 | 109 | 	/* 32x clock mode */ | 
 | 110 | 	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000, | 
 | 111 | }; | 
 | 112 |  | 
 | 113 | /* UCC Slow Oversampling rate for receiver (RDCR) | 
 | 114 | */ | 
 | 115 | enum ucc_slow_rx_oversampling_rate { | 
 | 116 | 	/* 1x clock mode */ | 
 | 117 | 	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000, | 
 | 118 | 	/* 8x clock mode */ | 
 | 119 | 	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000, | 
 | 120 | 	/* 16x clock mode */ | 
 | 121 | 	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000, | 
 | 122 | 	/* 32x clock mode */ | 
 | 123 | 	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000, | 
 | 124 | }; | 
 | 125 |  | 
 | 126 | /* UCC Slow Transmitter encoding method (TENC) | 
 | 127 | */ | 
 | 128 | enum ucc_slow_tx_encoding_method { | 
 | 129 | 	UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000, | 
 | 130 | 	UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100 | 
 | 131 | }; | 
 | 132 |  | 
 | 133 | /* UCC Slow Receiver decoding method (RENC) | 
 | 134 | */ | 
 | 135 | enum ucc_slow_rx_decoding_method { | 
 | 136 | 	UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000, | 
 | 137 | 	UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800 | 
 | 138 | }; | 
 | 139 |  | 
 | 140 | /* UCC Slow Diagnostic mode (DIAG) | 
 | 141 | */ | 
 | 142 | enum ucc_slow_diag_mode { | 
 | 143 | 	UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000, | 
 | 144 | 	UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040, | 
 | 145 | 	UCC_SLOW_DIAG_MODE_ECHO = 0x00000080, | 
 | 146 | 	UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0 | 
 | 147 | }; | 
 | 148 |  | 
 | 149 | struct ucc_slow_info { | 
 | 150 | 	int ucc_num; | 
| Timur Tabi | 6b0b594 | 2007-10-03 11:34:59 -0500 | [diff] [blame] | 151 | 	int protocol;			/* QE_CR_PROTOCOL_xxx */ | 
| Li Yang | 9865853 | 2006-10-03 23:10:46 -0500 | [diff] [blame] | 152 | 	enum qe_clock rx_clock; | 
 | 153 | 	enum qe_clock tx_clock; | 
| Timur Tabi | 6b0b594 | 2007-10-03 11:34:59 -0500 | [diff] [blame] | 154 | 	phys_addr_t regs; | 
| Li Yang | 9865853 | 2006-10-03 23:10:46 -0500 | [diff] [blame] | 155 | 	int irq; | 
 | 156 | 	u16 uccm_mask; | 
 | 157 | 	int data_mem_part; | 
 | 158 | 	int init_tx; | 
 | 159 | 	int init_rx; | 
 | 160 | 	u32 tx_bd_ring_len; | 
 | 161 | 	u32 rx_bd_ring_len; | 
 | 162 | 	int rx_interrupts; | 
 | 163 | 	int brkpt_support; | 
 | 164 | 	int grant_support; | 
 | 165 | 	int tsa; | 
 | 166 | 	int cdp; | 
 | 167 | 	int cds; | 
 | 168 | 	int ctsp; | 
 | 169 | 	int ctss; | 
 | 170 | 	int rinv; | 
 | 171 | 	int tinv; | 
 | 172 | 	int rtsm; | 
 | 173 | 	int rfw; | 
 | 174 | 	int tci; | 
 | 175 | 	int tend; | 
 | 176 | 	int tfl; | 
 | 177 | 	int txsy; | 
 | 178 | 	u16 max_rx_buf_length; | 
 | 179 | 	enum ucc_slow_transparent_tcrc tcrc; | 
 | 180 | 	enum ucc_slow_channel_protocol_mode mode; | 
 | 181 | 	enum ucc_slow_diag_mode diag; | 
 | 182 | 	enum ucc_slow_tx_oversampling_rate tdcr; | 
 | 183 | 	enum ucc_slow_rx_oversampling_rate rdcr; | 
 | 184 | 	enum ucc_slow_tx_encoding_method tenc; | 
 | 185 | 	enum ucc_slow_rx_decoding_method renc; | 
 | 186 | }; | 
 | 187 |  | 
 | 188 | struct ucc_slow_private { | 
 | 189 | 	struct ucc_slow_info *us_info; | 
| Timur Tabi | 6b0b594 | 2007-10-03 11:34:59 -0500 | [diff] [blame] | 190 | 	struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */ | 
| Li Yang | 9865853 | 2006-10-03 23:10:46 -0500 | [diff] [blame] | 191 | 	struct ucc_slow_pram *us_pram;	/* a pointer to the parameter RAM */ | 
 | 192 | 	u32 us_pram_offset; | 
 | 193 | 	int enabled_tx;		/* Whether channel is enabled for Tx (ENT) */ | 
 | 194 | 	int enabled_rx;		/* Whether channel is enabled for Rx (ENR) */ | 
 | 195 | 	int stopped_tx;		/* Whether channel has been stopped for Tx | 
 | 196 | 				   (STOP_TX, etc.) */ | 
 | 197 | 	int stopped_rx;		/* Whether channel has been stopped for Rx */ | 
 | 198 | 	struct list_head confQ;	/* frames passed to chip waiting for tx */ | 
 | 199 | 	u32 first_tx_bd_mask;	/* mask is used in Tx routine to save status | 
 | 200 | 				   and length for first BD in a frame */ | 
 | 201 | 	u32 tx_base_offset;	/* first BD in Tx BD table offset (In MURAM) */ | 
 | 202 | 	u32 rx_base_offset;	/* first BD in Rx BD table offset (In MURAM) */ | 
| Timur Tabi | 5af68af | 2007-02-16 22:31:21 -0600 | [diff] [blame] | 203 | 	struct qe_bd *confBd;	/* next BD for confirm after Tx */ | 
 | 204 | 	struct qe_bd *tx_bd;	/* next BD for new Tx request */ | 
 | 205 | 	struct qe_bd *rx_bd;	/* next BD to collect after Rx */ | 
| Li Yang | 9865853 | 2006-10-03 23:10:46 -0500 | [diff] [blame] | 206 | 	void *p_rx_frame;	/* accumulating receive frame */ | 
 | 207 | 	u16 *p_ucce;		/* a pointer to the event register in memory. | 
 | 208 | 				 */ | 
 | 209 | 	u16 *p_uccm;		/* a pointer to the mask register in memory */ | 
 | 210 | 	u16 saved_uccm;		/* a saved mask for the RX Interrupt bits */ | 
 | 211 | #ifdef STATISTICS | 
 | 212 | 	u32 tx_frames;		/* Transmitted frames counters */ | 
 | 213 | 	u32 rx_frames;		/* Received frames counters (only frames | 
 | 214 | 				   passed to application) */ | 
 | 215 | 	u32 rx_discarded;	/* Discarded frames counters (frames that | 
 | 216 | 				   were discarded by the driver due to | 
 | 217 | 				   errors) */ | 
 | 218 | #endif				/* STATISTICS */ | 
 | 219 | }; | 
 | 220 |  | 
 | 221 | /* ucc_slow_init | 
 | 222 |  * Initializes Slow UCC according to provided parameters. | 
 | 223 |  * | 
 | 224 |  * us_info  - (In) pointer to the slow UCC info structure. | 
 | 225 |  * uccs_ret - (Out) pointer to the slow UCC structure. | 
 | 226 |  */ | 
 | 227 | int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret); | 
 | 228 |  | 
 | 229 | /* ucc_slow_free | 
 | 230 |  * Frees all resources for slow UCC. | 
 | 231 |  * | 
 | 232 |  * uccs - (In) pointer to the slow UCC structure. | 
 | 233 |  */ | 
 | 234 | void ucc_slow_free(struct ucc_slow_private * uccs); | 
 | 235 |  | 
 | 236 | /* ucc_slow_enable | 
 | 237 |  * Enables a fast UCC port. | 
 | 238 |  * This routine enables Tx and/or Rx through the General UCC Mode Register. | 
 | 239 |  * | 
 | 240 |  * uccs - (In) pointer to the slow UCC structure. | 
 | 241 |  * mode - (In) TX, RX, or both. | 
 | 242 |  */ | 
 | 243 | void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode); | 
 | 244 |  | 
 | 245 | /* ucc_slow_disable | 
 | 246 |  * Disables a fast UCC port. | 
 | 247 |  * This routine disables Tx and/or Rx through the General UCC Mode Register. | 
 | 248 |  * | 
 | 249 |  * uccs - (In) pointer to the slow UCC structure. | 
 | 250 |  * mode - (In) TX, RX, or both. | 
 | 251 |  */ | 
 | 252 | void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode); | 
 | 253 |  | 
 | 254 | /* ucc_slow_poll_transmitter_now | 
 | 255 |  * Immediately forces a poll of the transmitter for data to be sent. | 
 | 256 |  * Typically, the hardware performs a periodic poll for data that the | 
 | 257 |  * transmit routine has set up to be transmitted. In cases where | 
 | 258 |  * this polling cycle is not soon enough, this optional routine can | 
 | 259 |  * be invoked to force a poll right away, instead. Proper use for | 
 | 260 |  * each transmission for which this functionality is desired is to | 
 | 261 |  * call the transmit routine and then this routine right after. | 
 | 262 |  * | 
 | 263 |  * uccs - (In) pointer to the slow UCC structure. | 
 | 264 |  */ | 
 | 265 | void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs); | 
 | 266 |  | 
 | 267 | /* ucc_slow_graceful_stop_tx | 
 | 268 |  * Smoothly stops transmission on a specified slow UCC. | 
 | 269 |  * | 
 | 270 |  * uccs - (In) pointer to the slow UCC structure. | 
 | 271 |  */ | 
 | 272 | void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs); | 
 | 273 |  | 
 | 274 | /* ucc_slow_stop_tx | 
 | 275 |  * Stops transmission on a specified slow UCC. | 
 | 276 |  * | 
 | 277 |  * uccs - (In) pointer to the slow UCC structure. | 
 | 278 |  */ | 
 | 279 | void ucc_slow_stop_tx(struct ucc_slow_private * uccs); | 
 | 280 |  | 
| Timur Tabi | 6b0b594 | 2007-10-03 11:34:59 -0500 | [diff] [blame] | 281 | /* ucc_slow_restart_tx | 
| Li Yang | 9865853 | 2006-10-03 23:10:46 -0500 | [diff] [blame] | 282 |  * Restarts transmitting on a specified slow UCC. | 
 | 283 |  * | 
 | 284 |  * uccs - (In) pointer to the slow UCC structure. | 
 | 285 |  */ | 
| Timur Tabi | 6b0b594 | 2007-10-03 11:34:59 -0500 | [diff] [blame] | 286 | void ucc_slow_restart_tx(struct ucc_slow_private *uccs); | 
| Li Yang | 9865853 | 2006-10-03 23:10:46 -0500 | [diff] [blame] | 287 |  | 
 | 288 | u32 ucc_slow_get_qe_cr_subblock(int uccs_num); | 
 | 289 |  | 
 | 290 | #endif				/* __UCC_SLOW_H__ */ |