[PATCH] powerpc/qe: Setup clock source for TDM

Xie Xiaobo X.Xie at freescale.com
Tue Mar 18 20:09:05 EST 2014


Add tdm clock configuration in both qe clock system and
ucc fast controler.

Signed-off-by: Xie Xiaobo <X.Xie at freescale.com>
Signed-off-by: Haiying Wang <Haiying.Wang at freescale.com>
---
 arch/powerpc/include/asm/immap_qe.h   |   5 +-
 arch/powerpc/include/asm/qe.h         |  13 +-
 arch/powerpc/include/asm/ucc.h        |   6 +-
 arch/powerpc/include/asm/ucc_fast.h   |  10 +-
 arch/powerpc/sysdev/qe_lib/qe.c       |   9 +-
 arch/powerpc/sysdev/qe_lib/ucc.c      | 773 +++++++++++++++++++++++++++++++++-
 arch/powerpc/sysdev/qe_lib/ucc_fast.c |  40 +-
 7 files changed, 845 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/immap_qe.h b/arch/powerpc/include/asm/immap_qe.h
index bedbff8..c76ef30 100644
--- a/arch/powerpc/include/asm/immap_qe.h
+++ b/arch/powerpc/include/asm/immap_qe.h
@@ -159,10 +159,7 @@ struct spi {
 
 /* SI */
 struct si1 {
-	__be16	siamr1;		/* SI1 TDMA mode register */
-	__be16	sibmr1;		/* SI1 TDMB mode register */
-	__be16	sicmr1;		/* SI1 TDMC mode register */
-	__be16	sidmr1;		/* SI1 TDMD mode register */
+	__be16	sixmr1[4];	/* SI1 TDMx (x = A B C D) mode register */
 	u8	siglmr1_h;	/* SI1 global mode register high */
 	u8	res0[0x1];
 	u8	sicmdr1_h;	/* SI1 command register high */
diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
index 32b9bfa..1c80fdc 100644
--- a/arch/powerpc/include/asm/qe.h
+++ b/arch/powerpc/include/asm/qe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2006, 2014 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Authors: 	Shlomi Gridish <gridish at freescale.com>
  * 		Li Yang <leoli at freescale.com>
@@ -75,6 +75,8 @@ enum qe_clock {
 	QE_CLK22,		/* Clock 22 */
 	QE_CLK23,		/* Clock 23 */
 	QE_CLK24,		/* Clock 24 */
+	QE_RSYNC_PIN,		/* RSYNC from pin */
+	QE_TSYNC_PIN,		/* TSYNC from pin */
 	QE_CLK_DUMMY
 };
 
@@ -636,6 +638,15 @@ struct ucc_slow_pram {
 #define UCC_BISYNC_UCCE_TXB	0x0002
 #define UCC_BISYNC_UCCE_RXB	0x0001
 
+/* Transparent UCC Event Register (UCCE) */
+#define UCC_TRANS_UCCE_GRA	0x0080
+#define UCC_TRANS_UCCE_TXE	0x0010
+#define UCC_TRANS_UCCE_RXF	0x0008
+#define UCC_TRANS_UCCE_BSY	0x0004
+#define UCC_TRANS_UCCE_TXB	0x0002
+#define UCC_TRANS_UCCE_RXB	0x0001
+
+
 /* Gigabit Ethernet Fast UCC Event Register (UCCE) */
 #define UCC_GETH_UCCE_MPD       0x80000000
 #define UCC_GETH_UCCE_SCAR      0x40000000
diff --git a/arch/powerpc/include/asm/ucc.h b/arch/powerpc/include/asm/ucc.h
index 6927ac2..0a942c9 100644
--- a/arch/powerpc/include/asm/ucc.h
+++ b/arch/powerpc/include/asm/ucc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2006, 2014 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Authors: 	Shlomi Gridish <gridish at freescale.com>
  * 		Li Yang <leoli at freescale.com>
@@ -41,6 +41,10 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num);
 
 int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
 	enum comm_dir mode);
+int ucc_set_tdm_rxtx_clk(unsigned int tdm_num, enum qe_clock clock,
+	enum comm_dir mode);
+int ucc_set_tdm_rxtx_sync(unsigned int tdm_num, enum qe_clock clock,
+	enum comm_dir mode);
 
 int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask);
 
diff --git a/arch/powerpc/include/asm/ucc_fast.h b/arch/powerpc/include/asm/ucc_fast.h
index 72ea9ba..98e19d8 100644
--- a/arch/powerpc/include/asm/ucc_fast.h
+++ b/arch/powerpc/include/asm/ucc_fast.h
@@ -1,7 +1,7 @@
 /*
  * Internal header file for UCC FAST unit routines.
  *
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2006, 2014 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Authors: 	Shlomi Gridish <gridish at freescale.com>
  * 		Li Yang <leoli at freescale.com>
@@ -27,12 +27,15 @@
 #define R_I	0x10000000	/* interrupt on reception */
 #define R_L	0x08000000	/* last */
 #define R_F	0x04000000	/* first */
+#define R_CM	0x02000000	/* CM */
 
 /* transmit BD's status */
 #define T_R	0x80000000	/* ready bit */
 #define T_W	0x20000000	/* wrap bit */
 #define T_I	0x10000000	/* interrupt on completion */
 #define T_L	0x08000000	/* last */
+#define T_TC	0x04000000	/* crc */
+#define T_CM	0x02000000	/* CM */
 
 /* Rx Data buffer must be 4 bytes aligned in most cases */
 #define UCC_FAST_RX_ALIGN			4
@@ -118,9 +121,12 @@ enum ucc_fast_transparent_tcrc {
 /* Fast UCC initialization structure */
 struct ucc_fast_info {
 	int ucc_num;
+	int tdm_num;
 	enum qe_clock rx_clock;
 	enum qe_clock tx_clock;
-	u32 regs;
+	enum qe_clock rx_sync;
+	enum qe_clock tx_sync;
+	resource_size_t regs;
 	int irq;
 	u32 uccm_mask;
 	int bd_mem_part;
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 238a07b..9a9f733 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2006-2010, 2014 Freescale Semiconductor, Inc.
+ * All rights reserved.
  *
  * Authors: 	Shlomi Gridish <gridish at freescale.com>
  * 		Li Yang <leoli at freescale.com>
@@ -240,6 +241,12 @@ enum qe_clock qe_clock_source(const char *source)
 	if (strcasecmp(source, "none") == 0)
 		return QE_CLK_NONE;
 
+	if (strcasecmp(source, "tsync_pin") == 0)
+		return QE_TSYNC_PIN;
+
+	if (strcasecmp(source, "rsync_pin") == 0)
+		return QE_RSYNC_PIN;
+
 	if (strncasecmp(source, "brg", 3) == 0) {
 		i = simple_strtoul(source + 3, NULL, 10);
 		if ((i >= 1) && (i <= 16))
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
index 621575b..5c27e04 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -3,7 +3,7 @@
  *
  * QE UCC API Set - UCC specific routines implementations.
  *
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2006, 2014 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Authors: 	Shlomi Gridish <gridish at freescale.com>
  * 		Li Yang <leoli at freescale.com>
@@ -210,3 +210,774 @@ int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
 
 	return 0;
 }
+
+/* tdm_num: TDM A-H port num is 0-7 */
+int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
+		enum comm_dir mode)
+{
+	u32 clock_bits, shift;
+	struct qe_mux *qe_mux_reg;
+	 __be32 __iomem *cmxs1cr;
+
+	clock_bits = 0;
+	qe_mux_reg = &qe_immr->qmx;
+
+	if ((tdm_num > 7 || tdm_num < 0))
+		return -EINVAL;
+
+	/* The communications direction must be RX or TX */
+	if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
+		return -EINVAL;
+
+	switch (mode) {
+	case COMM_DIR_RX:
+		switch (tdm_num) {
+		case 0:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK3:
+					clock_bits = 6;
+					break;
+			case QE_CLK8:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 28;
+			break;
+		case 1:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK5:
+					clock_bits = 6;
+					break;
+			case QE_CLK10:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 24;
+			break;
+		case 2:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK7:
+					clock_bits = 6;
+					break;
+			case QE_CLK12:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 20;
+			break;
+		case 3:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK9:
+					clock_bits = 6;
+					break;
+			case QE_CLK14:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 16;
+			break;
+		case 4:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK11:
+					clock_bits = 6;
+					break;
+			case QE_CLK16:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 28;
+			break;
+		case 5:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK13:
+					clock_bits = 6;
+					break;
+			case QE_CLK18:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 24;
+			break;
+		case 6:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK15:
+					clock_bits = 6;
+					break;
+			case QE_CLK20:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 20;
+			break;
+		case 7:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK17:
+					clock_bits = 6;
+					break;
+			case QE_CLK22:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 16;
+			break;
+		default:
+				break;
+		}
+		break;
+	case COMM_DIR_TX:
+		switch (tdm_num) {
+		case 0:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK4:
+					clock_bits = 6;
+					break;
+			case QE_CLK9:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 12;
+			break;
+		case 1:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK6:
+					clock_bits = 6;
+					break;
+			case QE_CLK11:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 8;
+			break;
+		case 2:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK8:
+					clock_bits = 6;
+					break;
+			case QE_CLK13:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 4;
+			break;
+		case 3:
+			switch (clock) {
+			case QE_BRG3:
+					clock_bits = 1;
+					break;
+			case QE_BRG4:
+					clock_bits = 2;
+					break;
+			case QE_CLK1:
+					clock_bits = 4;
+					break;
+			case QE_CLK2:
+					clock_bits = 5;
+					break;
+			case QE_CLK10:
+					clock_bits = 6;
+					break;
+			case QE_CLK15:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 0;
+			break;
+		case 4:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK12:
+					clock_bits = 6;
+					break;
+			case QE_CLK17:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 12;
+			break;
+		case 5:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK14:
+					clock_bits = 6;
+					break;
+			case QE_CLK19:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 8;
+			break;
+		case 6:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK16:
+					clock_bits = 6;
+					break;
+			case QE_CLK21:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 4;
+			break;
+		case 7:
+			switch (clock) {
+			case QE_BRG12:
+					clock_bits = 1;
+					break;
+			case QE_BRG13:
+					clock_bits = 2;
+					break;
+			case QE_CLK23:
+					clock_bits = 4;
+					break;
+			case QE_CLK24:
+					clock_bits = 5;
+					break;
+			case QE_CLK18:
+					clock_bits = 6;
+					break;
+			case QE_CLK3:
+					clock_bits = 7;
+					break;
+			default:
+					break;
+			}
+			shift = 0;
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (!clock_bits)
+		return -ENOENT;
+
+	cmxs1cr = (tdm_num < 4) ? (&qe_mux_reg->cmxsi1cr_l) :
+				  (&qe_mux_reg->cmxsi1cr_h);
+
+	clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
+		   clock_bits << shift);
+
+	return 0;
+}
+
+
+int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
+		enum comm_dir mode)
+{
+	u32 shift, clock_bits;
+	struct qe_mux *qe_mux_reg;
+	int source;
+
+	source = 0;
+	shift = 0;
+	qe_mux_reg = &qe_immr->qmx;
+
+	if ((tdm_num > 7 || tdm_num < 0))
+		return -EINVAL;
+
+	/* The communications direction must be RX or TX */
+	if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
+		return -EINVAL;
+
+	switch (mode) {
+	case COMM_DIR_RX:
+		switch (tdm_num) {
+		case 0:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG10:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 30;
+			break;
+		case 1:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG10:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 28;
+			break;
+		case 2:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG11:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 26;
+			break;
+		case 3:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG11:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 24;
+			break;
+		case 4:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG14:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 22;
+			break;
+		case 5:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG14:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 20;
+			break;
+		case 6:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG15:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 18;
+			break;
+		case 7:
+			switch (clock) {
+			case QE_RSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG15:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 16;
+			break;
+		default:
+			source = -1;
+			break;
+		}
+		break;
+	case COMM_DIR_TX:
+		switch (tdm_num) {
+		case 0:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG10:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 14;
+			break;
+		case 1:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG10:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 12;
+			break;
+		case 2:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG11:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 10;
+			break;
+		case 3:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG9:
+					source = 1;
+					break;
+			case QE_BRG11:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 8;
+			break;
+		case 4:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG14:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 6;
+			break;
+		case 5:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG14:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 4;
+			break;
+		case 6:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG15:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 2;
+			break;
+		case 7:
+			switch (clock) {
+			case QE_TSYNC_PIN:
+					source = 0;
+					break;
+			case QE_BRG13:
+					source = 1;
+					break;
+			case QE_BRG15:
+					source = 2;
+					break;
+			default:
+					source = -1;
+					break;
+			}
+			shift = 0;
+			break;
+
+		default:
+			source = -1;
+			break;
+		}
+		break;
+	default:
+		source = -1;
+		break;
+	}
+
+	if (source == -1)
+		return -ENOENT;
+
+	clock_bits = (u32) source;
+
+	clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
+			QE_CMXUCR_TX_CLK_SRC_MASK << shift,
+			clock_bits << shift);
+
+	return 0;
+}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index 65aaf15..16b88d6 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2006, 2014 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Authors: 	Shlomi Gridish <gridish at freescale.com>
  * 		Li Yang <leoli at freescale.com>
@@ -327,6 +327,44 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
 			ucc_fast_free(uccf);
 			return -EINVAL;
 		}
+#ifdef CONFIG_FSL_UCC_TDM
+	} else {
+		/* tdm Rx clock routing */
+		if ((uf_info->rx_clock != QE_CLK_NONE) &&
+			ucc_set_tdm_rxtx_clk(uf_info->tdm_num,
+				uf_info->rx_clock, COMM_DIR_RX)) {
+			pr_err("%s: illegal value for RX clock", __func__);
+			ucc_fast_free(uccf);
+			return -EINVAL;
+		}
+
+		/* tdm Tx clock routing */
+		if ((uf_info->tx_clock != QE_CLK_NONE) &&
+			ucc_set_tdm_rxtx_clk(uf_info->tdm_num,
+				uf_info->tx_clock, COMM_DIR_TX)) {
+			pr_err("%s:illegal value for TX clock", __func__);
+			ucc_fast_free(uccf);
+			return -EINVAL;
+		}
+
+		/* tdm Rx sync clock routing */
+		if ((uf_info->rx_sync != QE_CLK_NONE) &&
+			ucc_set_tdm_rxtx_sync(uf_info->tdm_num,
+				uf_info->rx_sync, COMM_DIR_RX)) {
+			pr_err("%s:illegal value for TX clock", __func__);
+			ucc_fast_free(uccf);
+			return -EINVAL;
+		}
+
+		/* tdm Tx sync clock routing */
+		if ((uf_info->tx_sync != QE_CLK_NONE) &&
+			ucc_set_tdm_rxtx_sync(uf_info->tdm_num,
+				uf_info->tx_sync, COMM_DIR_TX)) {
+			pr_err("%s:illegal value for TX clock", __func__);
+			ucc_fast_free(uccf);
+			return -EINVAL;
+		}
+#endif
 	}
 
 	/* Set interrupt mask register at UCC level. */
-- 
1.8.4




More information about the Linuxppc-dev mailing list