[U-Boot-Users] [PATCH 4/6 part 5] UCC slow mode support in QUICC Engine

Jiang Bo-r61859 tanya.jiang at freescale.com
Thu Aug 17 14:22:18 CEST 2006


Subject: [PATCH] UCC slow mode support in QUICC Engine

---

 drivers/sysdev/qe_lib/ucc/ucc_slow.c |  397
++++++++++++++++++++++++++++++++++
 drivers/sysdev/qe_lib/ucc/ucc_slow.h |  279 ++++++++++++++++++++++++
 2 files changed, 676 insertions(+), 0 deletions(-)
 create mode 100644 drivers/sysdev/qe_lib/ucc/ucc_slow.c
 create mode 100644 drivers/sysdev/qe_lib/ucc/ucc_slow.h

0b18169549d4e89690e4ee3ebd7ad5955e2c69e3
diff --git a/drivers/sysdev/qe_lib/ucc/ucc_slow.c
b/drivers/sysdev/qe_lib/ucc/ucc_slow.c
new file mode 100644
index 0000000..8e060f8
--- /dev/null
+++ b/drivers/sysdev/qe_lib/ucc/ucc_slow.c
@@ -0,0 +1,397 @@
+/*
+ * drivers/sysdev/qe_libucc/ucc_slow.c
+ *
+ * QE UCC Slow API Set - UCC Slow specific routines implementations.
+ *
+ * (C) Copyright 2006 Freescale Semiconductor, Inc
+ * Author: Shlomi Gridish <gridish at freescale.com>
+ *
+ * History:
+ * 20060601 tanya jiang (tanya.jiang at freescale.com)
+ *	    Code style fixed; move from cpu/mpc83xx to drivers/sysdev
+ *
+ * This program is free software; you can redistribute  it and/or
modify it
+ * under  the terms of  the GNU General  Public License as published by
the
+ * Free Software Foundation;  either version 2 of the  License, or (at
your
+ * option) any later version.
+ */
+#include "common.h"
+#include "asm/errno.h"
+#include "asm/io.h"
+#include "immap_qe.h"
+#include "qe.h"
+#include "ucc.h"
+#include "ucc_slow.h"
+
+#define uccs_printk(format, arg...)  \
+        printf("\n", ## arg)
+
+#define uccs_dbg(format, arg...)            \
+        uccs_printk(format , ## arg)
+#define uccs_err(format, arg...)            \
+        uccs_printk(format , ## arg)
+#define uccs_info(format, arg...)           \
+        uccs_printk(format , ## arg)
+#define uccs_warn(format, arg...)           \
+        uccs_printk(format , ## arg)
+
+#ifdef UCCS_VERBOSE_DEBUG
+#define uccs_vdbg uccs_dbg
+#else
+#define uccs_vdbg(ugeth, fmt, args...) do { } while (0)
+#endif	/* UCCS_VERBOSE_DEBUG */
+
+u32 ucc_slow_get_qe_cr_subblock(int uccs_num)
+{
+	switch (uccs_num) {
+	case (0):
+		return (QE_CR_SUBBLOCK_UCCSLOW1);
+	case (1):
+		return (QE_CR_SUBBLOCK_UCCSLOW2);
+	case (2):
+		return (QE_CR_SUBBLOCK_UCCSLOW3);
+	case (3):
+		return (QE_CR_SUBBLOCK_UCCSLOW4);
+	case (4):
+		return (QE_CR_SUBBLOCK_UCCSLOW5);
+	case (5):
+		return (QE_CR_SUBBLOCK_UCCSLOW6);
+	case (6):
+		return (QE_CR_SUBBLOCK_UCCSLOW7);
+	case (7):
+		return (QE_CR_SUBBLOCK_UCCSLOW8);
+	default:
+		return QE_CR_SUBBLOCK_INVALID;
+	}
+}
+
+void ucc_slow_poll_transmitter_now(ucc_slow_private_t * uccs)
+{
+	out_be16(&uccs->us_regs->utodr, UCC_SLOW_TOD);
+}
+
+void ucc_slow_graceful_stop_tx(ucc_slow_private_t * uccs)
+{
+	ucc_slow_info_t *us_info = uccs->us_info;
+	u32 id;
+
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_GRACEFUL_STOP_TX, id,
+		     (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
+}
+
+void ucc_slow_stop_tx(ucc_slow_private_t * uccs)
+{
+	ucc_slow_info_t *us_info = uccs->us_info;
+	u32 id;
+
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_STOP_TX, id, (u8) QE_CR_PROTOCOL_UNSPECIFIED,
0);
+}
+
+void ucc_slow_restart_tx(ucc_slow_private_t * uccs)
+{
+	ucc_slow_info_t *us_info = uccs->us_info;
+	u32 id;
+
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_RESTART_TX, id, (u8) QE_CR_PROTOCOL_UNSPECIFIED,
0);
+}
+
+void ucc_slow_enable(ucc_slow_private_t * uccs, comm_dir_e mode)
+{
+	ucc_slow_t *us_regs;
+	u32 gumr_l;
+
+	us_regs = uccs->us_regs;
+
+	/* Enable reception and/or transmission on this UCC. */
+	gumr_l = in_be32(&us_regs->gumr_l);
+	if (mode & COMM_DIR_TX) {
+		gumr_l |= UCC_SLOW_GUMR_L_ENT;
+		uccs->enabled_tx = 1;
+	}
+	if (mode & COMM_DIR_RX) {
+		gumr_l |= UCC_SLOW_GUMR_L_ENR;
+		uccs->enabled_rx = 1;
+	}
+	out_be32(&us_regs->gumr_l, gumr_l);
+}
+
+void ucc_slow_disable(ucc_slow_private_t * uccs, comm_dir_e mode)
+{
+	ucc_slow_t *us_regs;
+	u32 gumr_l;
+
+	us_regs = uccs->us_regs;
+
+	/* Disable reception and/or transmission on this UCC. */
+	gumr_l = in_be32(&us_regs->gumr_l);
+	if (mode & COMM_DIR_TX) {
+		gumr_l &= ~UCC_SLOW_GUMR_L_ENT;
+		uccs->enabled_tx = 0;
+	}
+	if (mode & COMM_DIR_RX) {
+		gumr_l &= ~UCC_SLOW_GUMR_L_ENR;
+		uccs->enabled_rx = 0;
+	}
+	out_be32(&us_regs->gumr_l, gumr_l);
+}
+
+int ucc_slow_init(ucc_slow_info_t * us_info, ucc_slow_private_t **
uccs_ret)
+{
+	u32 i;
+	ucc_slow_t *us_regs;
+	u32 gumr;
+	u8 function_code = 0;
+	u8 *bd;
+	ucc_slow_private_t *uccs;
+	u32 id;
+	u32 command;
+	int ret;
+
+	uccs_vdbg("%s: IN", __FUNCTION__);
+
+	if (!us_info)
+		return -EINVAL;
+
+	/* check if the UCC port number is in range. */
+	if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM -
1)) {
+		uccs_err("ucc_slow_init: Illagal UCC number!");
+		return -EINVAL;
+	}
+
+	/* Set mrblr */
+	/* Check that 'max_rx_buf_length' is properly aligned (4),
unless rfw is 1,  */
+	/* meaning that QE accepts one byte at a time, unlike normal
case when QE    */
+	/* accepts 32 bits at a time.
*/
+	if ((!us_info->rfw)
+	    && (us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT -
1))) {
+		uccs_err("max_rx_buf_length not aligned.");
+		return -EINVAL;
+	}
+
+	uccs = (ucc_slow_private_t *)
kmalloc(sizeof(ucc_slow_private_t));
+	if (!uccs) {
+		uccs_err ("ucc_slow_init: No memory for "
+			  "UCC slow data structure!");
+		return -ENOMEM;
+	}
+	memset(uccs, 0, sizeof(ucc_slow_private_t));
+
+	/* Fill slow UCC structure */
+	uccs->us_info = us_info;
+	uccs->saved_uccm = 0;
+	uccs->p_rx_frame = 0;
+	uccs->us_regs = us_info->us_regs;
+	us_regs = uccs->us_regs;
+	uccs->p_ucce = (u16 *) & (us_regs->ucce);
+	uccs->p_uccm = (u16 *) & (us_regs->uccm);
+#ifdef STATISTICS
+	uccs->rx_frames = 0;
+	uccs->tx_frames = 0;
+	uccs->rx_discarded = 0;
+#endif				/* STATISTICS */
+
+	/* Get PRAM base */
+	uccs->us_pram_offset =
+	    qe_muram_alloc(UCC_SLOW_PRAM_SIZE,
ALIGNMENT_OF_UCC_SLOW_PRAM);
+	if (IS_MURAM_ERR(uccs->us_pram_offset)) {
+		uccs_err("ucc_slow_init: Can not allocate "
+			 "MURAM memory for Slow UCC.");
+		ucc_slow_free(uccs);
+		return -ENOMEM;
+	}
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id,
QE_CR_PROTOCOL_UNSPECIFIED,
+		     (u32) uccs->us_pram_offset);
+
+	uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
+
+	/* Init Guemr register */
+	if ((ret = ucc_init_guemr((ucc_common_t *) (us_info->us_regs))))
{
+		uccs_err("ucc_slow_init: Could not init the guemr
register.");
+		ucc_slow_free(uccs);
+		return ret;
+	}
+
+	/* Set UCC to slow type */
+	if ((ret = ucc_set_type(us_info->ucc_num,
+				(ucc_common_t *) (us_info->us_regs),
+				UCC_SPEED_TYPE_SLOW))) {
+		uccs_err("ucc_slow_init: Could not init the guemr
register.");
+		ucc_slow_free(uccs);
+		return ret;
+	}
+
+	out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length);
+
+	INIT_LIST_HEAD(&uccs->confQ);
+
+	/* Allocate BDs. */
+	uccs->rx_base_offset =
+	    qe_muram_alloc(us_info->rx_bd_ring_len *
UCC_SLOW_SIZE_OF_BD,
+			   QE_ALIGNMENT_OF_BD);
+	if (IS_MURAM_ERR(uccs->rx_base_offset)) {
+		uccs_err("ucc_slow_init: No memory for Rx BD's.");
+		uccs->rx_base_offset = 0;
+		ucc_slow_free(uccs);
+		return -ENOMEM;
+	}
+
+	uccs->tx_base_offset =
+	    qe_muram_alloc(us_info->tx_bd_ring_len *
UCC_SLOW_SIZE_OF_BD,
+			   QE_ALIGNMENT_OF_BD);
+	if (IS_MURAM_ERR(uccs->tx_base_offset)) {
+		uccs_err("ucc_slow_init: No memory for Tx BD's.");
+		uccs->tx_base_offset = 0;
+		ucc_slow_free(uccs);
+		return -ENOMEM;
+	}
+
+	/* Init Tx bds */
+	bd = uccs->confBd = uccs->tx_bd =
qe_muram_addr(uccs->tx_base_offset);
+	for (i = 0; i < us_info->tx_bd_ring_len; i++) {
+		BD_BUFFER_CLEAR(bd);
+		BD_STATUS_AND_LENGTH_SET(bd, 0);
+		bd += QE_SIZEOF_BD;
+	}
+	bd -= QE_SIZEOF_BD;
+	BD_STATUS_AND_LENGTH_SET(bd, T_W);	/* for last BD set Wrap
bit */
+
+	/* Init Rx bds */
+	bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
+	for (i = 0; i < us_info->rx_bd_ring_len; i++) {
+		BD_STATUS_AND_LENGTH_SET(bd, 0);
+		BD_BUFFER_CLEAR(bd);
+		bd += QE_SIZEOF_BD;
+	}
+	bd -= QE_SIZEOF_BD;
+	BD_STATUS_AND_LENGTH_SET(bd, R_W);	/* for last BD set Wrap
bit */
+
+	/* Set GUMR (For more details see the hardware spec.). */
+	/* gumr_h */
+	gumr = 0;
+	gumr |= us_info->tcrc;
+	if (us_info->cdp)
+		gumr |= UCC_SLOW_GUMR_H_CDP;
+	if (us_info->ctsp)
+		gumr |= UCC_SLOW_GUMR_H_CTSP;
+	if (us_info->cds)
+		gumr |= UCC_SLOW_GUMR_H_CDS;
+	if (us_info->ctss)
+		gumr |= UCC_SLOW_GUMR_H_CTSS;
+	if (us_info->tfl)
+		gumr |= UCC_SLOW_GUMR_H_TFL;
+	if (us_info->rfw)
+		gumr |= UCC_SLOW_GUMR_H_RFW;
+	if (us_info->txsy)
+		gumr |= UCC_SLOW_GUMR_H_TXSY;
+	if (us_info->rtsm)
+		gumr |= UCC_SLOW_GUMR_H_RTSM;
+	out_be32(&us_regs->gumr_h, gumr);
+
+	/* gumr_l */
+	gumr = 0;
+	if (us_info->tci)
+		gumr |= UCC_SLOW_GUMR_L_TCI;
+	if (us_info->rinv)
+		gumr |= UCC_SLOW_GUMR_L_RINV;
+	if (us_info->tinv)
+		gumr |= UCC_SLOW_GUMR_L_TINV;
+	if (us_info->tend)
+		gumr |= UCC_SLOW_GUMR_L_TEND;
+	gumr |= us_info->tdcr;
+	gumr |= us_info->rdcr;
+	gumr |= us_info->tenc;
+	gumr |= us_info->renc;
+	gumr |= us_info->diag;
+	gumr |= us_info->mode;
+	out_be32(&us_regs->gumr_l, gumr);
+
+	/* Function code registers */
+	/* function_code has initial value 0 */
+
+	/* if the data is in cachable memory, the 'global' */
+	/* in the function code should be set.             */
+	function_code |= us_info->data_mem_part;
+	function_code |= QE_BMR_BYTE_ORDER_BO_MOT; /* Required for QE */
+	uccs->us_pram->tfcr = function_code;
+	uccs->us_pram->rfcr = function_code;
+
+	/* rbase, tbase are offsets from MURAM base */
+	out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset);
+	out_be16(&uccs->us_pram->tbase, uccs->us_pram_offset);
+
+	/* Mux clocking */
+	/* Grant Support */
+	ucc_set_qe_mux_grant(us_info->ucc_num, us_info->grant_support);
+	/* Breakpoint Support */
+	ucc_set_qe_mux_bkpt(us_info->ucc_num, us_info->brkpt_support);
+	/* Set Tsa or NMSI mode. */
+	ucc_set_qe_mux_tsa(us_info->ucc_num, us_info->tsa);
+	/* If NMSI (not Tsa), set Tx and Rx clock. */
+	if (!us_info->tsa) {
+		/* Rx clock routing */
+		if (ucc_set_qe_mux_rxtx
+		    (us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX))
{
+			uccs_err ("ucc_slow_init: Illegal value for "
+				  "parameter 'RxClock'.");
+			ucc_slow_free(uccs);
+			return -EINVAL;
+		}
+		/* Tx clock routing */
+		if (ucc_set_qe_mux_rxtx
+		    (us_info->ucc_num, us_info->tx_clock, COMM_DIR_TX))
{
+			uccs_err ("ucc_slow_init: Illegal value for "
+				  "parameter 'TxClock'.");
+			ucc_slow_free(uccs);
+			return -EINVAL;
+		}
+	}
+
+	/*
+	 * INTERRUPTS
+	 */
+	/* Set interrupt mask register at UCC level. */
+	out_be16(&us_regs->uccm, us_info->uccm_mask);
+
+	/* First, clear anything pending at UCC level, */
+	/* otherwise, old garbage may come through     */
+	/* as soon as the dam is opened.               */
+
+	/* Writing '1' clears */
+	out_be16(&us_regs->ucce, 0xffff);
+
+	/* Issue QE Init command */
+	if (us_info->init_tx && us_info->init_rx)
+		command = QE_INIT_TX_RX;
+	else if (us_info->init_tx)
+		command = QE_INIT_TX;
+	else
+		command = QE_INIT_RX;	/* We know at least one is TRUE
*/
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(command, id, (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+	*uccs_ret = uccs;
+	return 0;
+}
+
+void ucc_slow_free(ucc_slow_private_t * uccs)
+{
+	if (!uccs)
+		return;
+
+	if (uccs->rx_base_offset)
+		qe_muram_free(uccs->rx_base_offset);
+
+	if (uccs->tx_base_offset)
+		qe_muram_free(uccs->tx_base_offset);
+
+	if (uccs->us_pram) {
+		qe_muram_free(uccs->us_pram_offset);
+		uccs->us_pram = NULL;
+	}
+
+	kfree(uccs);
+}
diff --git a/drivers/sysdev/qe_lib/ucc/ucc_slow.h
b/drivers/sysdev/qe_lib/ucc/ucc_slow.h
new file mode 100644
index 0000000..01e15ff
--- /dev/null
+++ b/drivers/sysdev/qe_lib/ucc/ucc_slow.h
@@ -0,0 +1,279 @@
+/*
+ * drivers/sysdev/qe_lib/ucc/ucc_slow.h
+ *
+ * Internal header file for UCC SLOW unit routines.
+ *
+ * (C) Copyright 2006 Freescale Semiconductor, Inc
+ * Author: Shlomi Gridish <gridish at freescale.com>
+ *
+ * History:
+ * 20060601 tanya jiang (tanya.jiang at freescale.com)
+ *	    Code style fixed; move from cpu/mpc83xx to drivers/sysdev
+ *
+ * This program is free software; you can redistribute  it and/or
modify it
+ * under  the terms of  the GNU General  Public License as published by
the
+ * Free Software Foundation;  either version 2 of the  License, or (at
your
+ * option) any later version.
+ */
+#ifndef __UCC_SLOW_H__
+#define __UCC_SLOW_H__
+
+#include "immap_qe.h"
+#include "qe.h"
+#include "ucc.h"
+
+#define UCC_SLOW_SIZE_OF_BD QE_SIZEOF_BD
+
+/* transmit BD's status.
+*/
+#define T_R     0x80000000	/* ready bit
*/
+#define T_PAD   0x40000000	/* add pads to short frames
*/
+#define T_W     0x20000000	/* wrap bit
*/
+#define T_I     0x10000000	/* interrupt on completion
*/
+#define T_L     0x08000000	/* last
*/
+
+#define T_A     0x04000000	/* Address - the data transmitted as
address chars */
+#define T_TC    0x04000000	/* transmit CRC
*/
+#define T_CM    0x02000000	/* continuous mode
*/
+#define T_DEF   0x02000000	/* collision on previous attempt to
transmit.      */
+#define T_P     0x01000000	/* Preamble - send Preamble sequence
before data   */
+#define T_HB    0x01000000	/* heartbeat.
*/
+#define T_NS    0x00800000	/* No Stop
*/
+#define T_LC    0x00800000	/* late collision.
*/
+#define T_RL    0x00400000	/* retransmission limit.
*/
+#define T_UN    0x00020000	/* underrun
*/
+#define T_CT    0x00010000	/* CTS lost
*/
+#define T_CSL   0x00010000	/* carrier sense lost.
*/
+#define T_RC    0x003c0000	/* retry count.
*/
+
+/* Receive BD's status.
+*/
+#define R_E     0x80000000	/* buffer empty
*/
+#define R_W     0x20000000	/* wrap bit
*/
+#define R_I     0x10000000	/* interrupt on reception
*/
+#define R_L     0x08000000	/* last
*/
+#define R_C     0x08000000	/* the last byte in this buffer is a
cntl char     */
+#define R_F     0x04000000	/* first
*/
+#define R_A     0x04000000	/* the first byte in this buffer is
address byte   */
+#define R_CM    0x02000000	/* continuous mode
*/
+#define R_ID    0x01000000	/* buffer close on reception of idles
*/
+#define R_M     0x01000000	/* Frame received because of promiscuous
mode.     */
+#define R_AM    0x00800000	/* Address match
*/
+#define R_DE    0x00800000	/* Address match
*/
+#define R_LG    0x00200000	/* Break received
*/
+#define R_BR    0x00200000	/* Frame length violation
*/
+#define R_NO    0x00100000	/* Rx Non Octet Aligned Packet
*/
+#define R_FR    0x00100000	/* Framing Error (no stop bit) character
received  */
+#define R_PR    0x00080000	/* Parity Error character received
*/
+#define R_AB    0x00080000	/* Frame Aborted
*/
+#define R_SH    0x00080000	/* frame is too short.
*/
+#define R_CR    0x00040000	/* CRC Error
*/
+#define R_OV    0x00020000	/* Overrun
*/
+#define R_CD    0x00010000	/* CD lost
*/
+#define R_CL    0x00010000	/* this frame is closed because of a
collision     */
+
+/* Rx Data buffer must be 4 bytes aligned in most cases.*/
+#define UCC_SLOW_RX_ALIGN             4
+#define UCC_SLOW_MRBLR_ALIGNMENT      4
+
+#define UCC_SLOW_PRAM_SIZE            0x100
+#define ALIGNMENT_OF_UCC_SLOW_PRAM    64
+
+/* UCC Slow Channel Protocol Mode
+*/
+typedef enum ucc_slow_channel_protocol_mode {
+	UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002,	/* QMC
*/
+	UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004,	/* UART
*/
+	UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008	/*
BISYNC */
+} ucc_slow_channel_protocol_mode_e;
+
+/* UCC Slow Transparent Transmit CRC (TCRC)
+*/
+typedef enum ucc_slow_transparent_tcrc {
+	/* 16-bit CCITT CRC (HDLC). (X16 + X12 + X5 + 1) */
+	UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000,
+	/* CRC16 (BISYNC). (X16 + X15 + X2 + 1) */
+	UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000,
+	/* 32-bit CCITT CRC (Ethernet and HDLC). */
+	UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000
+} ucc_slow_transparent_tcrc_e;
+
+/* UCC Slow oversampling rate for transmitter (TDCR)
+*/
+typedef enum ucc_slow_tx_oversampling_rate {
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000, /* 1x  clock
mode */
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000, /* 8x  clock
mode */
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000, /* 16x clock
mode */
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000 /* 32x clock
mode */
+} ucc_slow_tx_oversampling_rate_e;
+
+/* UCC Slow Oversampling rate for receiver (RDCR)
+*/
+typedef enum ucc_slow_rx_oversampling_rate {
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000,
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000,
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000,
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000
+} ucc_slow_rx_oversampling_rate_e;
+
+/* UCC Slow Transmitter encoding method (TENC)
+*/
+typedef enum ucc_slow_tx_encoding_method {
+	UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000,
+	UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100
+} ucc_slow_tx_encoding_method_e;
+
+/* UCC Slow Receiver decoding method (RENC)
+*/
+typedef enum ucc_slow_rx_decoding_method {
+	UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000,
+	UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800
+} ucc_slow_rx_decoding_method_e;
+
+/* UCC Slow Diagnostic mode (DIAG)
+*/
+typedef enum ucc_slow_diag_mode {
+	UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000,
+	UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040,
+	UCC_SLOW_DIAG_MODE_ECHO = 0x00000080,
+	UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0
+} ucc_slow_diag_mode_e;
+
+typedef struct ucc_slow_info {
+	int ucc_num;
+	qe_clock_e rx_clock;
+	qe_clock_e tx_clock;
+	ucc_slow_t *us_regs;
+	int irq;
+	u16 uccm_mask;
+	int data_mem_part;
+	int init_tx;
+	int init_rx;
+	u32 tx_bd_ring_len;
+	u32 rx_bd_ring_len;
+	int rx_interrupts;
+	int brkpt_support;
+	int grant_support;
+	int tsa;
+	int cdp;
+	int cds;
+	int ctsp;
+	int ctss;
+	int rinv;
+	int tinv;
+	int rtsm;
+	int rfw;
+	int tci;
+	int tend;
+	int tfl;
+	int txsy;
+	u16 max_rx_buf_length;
+	ucc_slow_transparent_tcrc_e tcrc;
+	ucc_slow_channel_protocol_mode_e mode;
+	ucc_slow_diag_mode_e diag;
+	ucc_slow_tx_oversampling_rate_e tdcr;
+	ucc_slow_rx_oversampling_rate_e rdcr;
+	ucc_slow_tx_encoding_method_e tenc;
+	ucc_slow_rx_decoding_method_e renc;
+} ucc_slow_info_t;
+
+typedef struct ucc_slow_private {
+	ucc_slow_info_t *us_info;
+	ucc_slow_t *us_regs;	/* a pointer to memory map of UCC
regs.*/
+	ucc_slow_pram_t *us_pram;/* a pointer to the parameter RAM. */
+	uint us_pram_offset;
+	int enabled_tx;		/* Whether channel is enabled for Tx
(ENT) */
+	int enabled_rx;		/* Whether channel is enabled for Rx
(ENR) */
+	int stopped_tx;		/* Whether channel has been stopped for
Tx (STOP_TX, etc.) */
+	int stopped_rx;		/* Whether channel has been stopped for
Rx */
+	struct list_head confQ;	/* frames passed to chip waiting for tx
*/
+	u32 first_tx_bd_mask;	/* mask is used in Tx routine to save
status
+				 * and length for first BD in a frame.*/
+	uint tx_base_offset;	/* first BD in Tx BD table offset (In
MURAM) */
+	uint rx_base_offset;	/* first BD in Rx BD table offset (In
MURAM) */
+	u8 *confBd;		/* next BD for confirm after Tx */
+	u8 *tx_bd;		/* next BD for new Tx request */
+	u8 *rx_bd;		/* next BD to collect after  Rx */
+	void *p_rx_frame;	/* accumulating receive frame */
+	u16 *p_ucce;		/* a pointer to the event register in
memory.*/
+	u16 *p_uccm;		/* a pointer to the mask register in
memory. */
+	u16 saved_uccm;		/* a saved mask for the RX Interrupt
bits. */
+#ifdef STATISTICS
+	u32 tx_frames;		/* Transmitted frames counters.*/
+	u32 rx_frames;		/* Received frames counters
+				 * (only frames passed to application).
*/
+	u32 rx_discarded;	/* Discarded frames counters (frames
that were
+				 * discarded by the driver due to
errors). */
+#endif				/* STATISTICS */
+} ucc_slow_private_t;
+
+/* ucc_slow_init
+ * Initializes Slow UCC according to provided parameters.
+ *
+ * us_info  - (In) pointer to the slow UCC info structure.
+ * uccs_ret - (Out) pointer to the slow UCC structure.
+ */
+int ucc_slow_init(ucc_slow_info_t * us_info, ucc_slow_private_t **
uccs_ret);
+
+/* ucc_slow_free
+ * Frees all resources for slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_free(ucc_slow_private_t * uccs);
+
+/* ucc_slow_enable
+ * Enables a fast UCC port.
+ * This routine enables Tx and/or Rx through the General UCC Mode
Register.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_slow_enable(ucc_slow_private_t * uccs, comm_dir_e mode);
+
+/* ucc_slow_disable
+ * Disables a fast UCC port.
+ * This routine disables Tx and/or Rx through the General UCC Mode
Register.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_slow_disable(ucc_slow_private_t * uccs, comm_dir_e mode);
+
+/* ucc_slow_poll_transmitter_now
+ * Immediately forces a poll of the transmitter for data to be sent.
+ * Typically, the hardware performs a periodic poll for data that the
+ * transmit routine has set up to be transmitted. In cases where
+ * this polling cycle is not soon enough, this optional routine can
+ * be invoked to force a poll right away, instead. Proper use for
+ * each transmission for which this functionality is desired is to
+ * call the transmit routine and then this routine right after.
+ *
+ * @Param         uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_poll_transmitter_now(ucc_slow_private_t * uccs);
+
+/* ucc_slow_graceful_stop_tx
+ * Smoothly stops transmission on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_graceful_stop_tx(ucc_slow_private_t * uccs);
+
+/* ucc_slow_stop_tx
+ * Stops transmission on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_stop_tx(ucc_slow_private_t * uccs);
+
+/* ucc_slow_restart_x
+ * Restarts transmitting on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_restart_x(ucc_slow_private_t * uccs);
+
+u32 ucc_slow_get_qe_cr_subblock(int uccs_num);
+
+#endif				/* __UCC_SLOW_H__ */
-- 
1.3.GIT




More information about the U-Boot mailing list