Skip to contentSkip to conversation

qe: miscellaneous code improvements and fixes to the QE library

PATCH Superseded Timur Tabi 1 participant 1 message Sep 19, 2007

Subsystems (2)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Timur Tabi

author
#0 lore raw

PATCH v2 1/1 qe: miscellaneous code improvements and fixes to the QE library

This patch makes numerous miscellaneous code improvements to the QE library.

1. Remove struct ucc_common and merge ucc_init_guemr() into ucc_set_type() (every caller of ucc_init_guemr() also calls ucc_set_type()). Modify all callers of ucc_set_type() accordingly.

2. Remove the unused enum ucc_pram_initial_offset.

3. Refactor qe_setbrg(), also implement work-around for errata QE_General4.

4. Several printk() calls were missing the terminating \n.

5. Add __iomem where needed.

6. In ucc_slow_init() the RBASE and TBASE registers in the PRAM were programmed with the wrong value.

7. Add the protocol type to struct us_info and updated ucc_slow_init() to use it, instead of always programming QE_CR_PROTOCOL_UNSPECIFIED.

8. Rename ucc_slow_restart_x() to ucc_slow_restart_tx()

9. Add several macros in qe.h (mostly for slow UCC support, but also to standardize some naming convention) and remove several unused macros.

10. Update ucc_geth.c to use the new macros.

11. Add ucc_slow_info.protocol to specify which QE_CR_PROTOCOL_xxx protcol to use when initializing the UCC in ucc_slow_init().

12. Rename ucc_slow_pram.rfcr to rbmr and ucc_slow_pram.tfcr to tbmr, since these are the real names of the registers.

---

Applied changes based on Scott's suggestions.

This patch applies on top of Anton Vorontsov's patch "ucc_geth: fix compilation", which has been applied to the netdev tree, but not the powerpc tree.

 arch/powerpc/sysdev/qe_lib/qe.c       |   36 +++--
 arch/powerpc/sysdev/qe_lib/qe_ic.c    |    2 -
 arch/powerpc/sysdev/qe_lib/qe_io.c    |   35 ++---
 arch/powerpc/sysdev/qe_lib/ucc.c      |   68 ++++++----
 arch/powerpc/sysdev/qe_lib/ucc_fast.c |  127 ++++++++---------
 arch/powerpc/sysdev/qe_lib/ucc_slow.c |   48 +++----
 drivers/net/ucc_geth.c                |    2 +-
 include/asm-powerpc/immap_qe.h        |   23 +--
 include/asm-powerpc/qe.h              |  243 +++++++++++++++++++++++----------
 include/asm-powerpc/ucc.h             |   24 +---
 include/asm-powerpc/ucc_slow.h        |    9 +-
 11 files changed, 345 insertions(+), 272 deletions(-)
arch/powerpc/sysdev/qe_lib/qe.c +23 -13
index 90f8740..3d57d38 100644
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(qe_issue_cmd);
  * 16 BRGs, which can be connected to the QE channels or output
  * as clocks. The BRGs are in two different block of internal
  * memory mapped space.
- * The baud rate clock is the system clock divided by something.
+ * The BRG clock is the QE clock divided by 2.
  * It was set up long ago during the initial boot phase and is
  * is given to us.
  * Baud rate clocks are zero-based in the driver code (as that maps
@@ -165,28 +165,38 @@ unsigned int get_brg_clk(void)
 	return brg_clk;
 }
 
-/* This function is used by UARTS, or anything else that uses a 16x
- * oversampled clock.
+/* Program the BRG to the given sampling rate and multiplier
+ *
+ * @brg: the BRG, 1-16
+ * @rate: the desired sampling rate
+ * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
+ * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
+ * then 'multiplier' should be 8.
+ *
+ * Also note that the value programmed into the BRGC register must be even.
  */
-void qe_setbrg(u32 brg, u32 rate)
+void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
 {
-	volatile u32 *bp;
 	u32 divisor, tempval;
-	int div16 = 0;
+	u32 div16 = 0;
 
-	bp = &qe_immr->brg.brgc[brg];
+	divisor = get_brg_clk() / (rate * multiplier);
 
-	divisor = (get_brg_clk() / rate);
 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
-		div16 = 1;
+		div16 = QE_BRGC_DIV16;
 		divisor /= 16;
 	}
 
-	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
-	if (div16)
-		tempval |= QE_BRGC_DIV16;
+	/* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
+	   that the BRG divisor must be even if you're not using divide-by-16
+	   mode. */
+	if (!div16 && (divisor & 1))
+		divisor++;
+
+	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
+		QE_BRGC_ENABLE | div16;
 
-	out_be32(bp, tempval);
+	out_be32(&qe_immr->brg.brgc[brg - 1], tempval);
 }
 
 /* Initialize SNUMs (thread serial numbers) according to
arch/powerpc/sysdev/qe_lib/qe_ic.c +0 -2
index 55e6f39..9a2d1ed 100644
@@ -405,8 +405,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags)
 		set_irq_data(qe_ic->virq_high, qe_ic);
 		set_irq_chained_handler(qe_ic->virq_high, qe_ic_cascade_high);
 	}
-
-	printk("QEIC (%d IRQ sources) at %p\n", NR_QE_IC_INTS, qe_ic->regs);
 }
 
 void qe_ic_set_highest_priority(unsigned int virq, int high)
arch/powerpc/sysdev/qe_lib/qe_io.c +14 -21
index e32b45b..a114cb0 100644
@@ -195,29 +195,22 @@ EXPORT_SYMBOL(par_io_of_config);
 #ifdef DEBUG
 static void dump_par_io(void)
 {
-	int i;
+	unsigned int i;
 
-	printk(KERN_INFO "PAR IO registars:\n");
-	printk(KERN_INFO "Base address: 0x%08x\n", (u32) par_io);
+	printk(KERN_INFO "%s: par_io=%p\n", __FUNCTION__, par_io);
 	for (i = 0; i < num_par_io_ports; i++) {
-		printk(KERN_INFO "cpodr[%d] : addr - 0x%08x, val - 0x%08x\n",
-		       i, (u32) & par_io[i].cpodr,
-		       in_be32(&par_io[i].cpodr));
-		printk(KERN_INFO "cpdata[%d]: addr - 0x%08x, val - 0x%08x\n",
-		       i, (u32) & par_io[i].cpdata,
-		       in_be32(&par_io[i].cpdata));
-		printk(KERN_INFO "cpdir1[%d]: addr - 0x%08x, val - 0x%08x\n",
-		       i, (u32) & par_io[i].cpdir1,
-		       in_be32(&par_io[i].cpdir1));
-		printk(KERN_INFO "cpdir2[%d]: addr - 0x%08x, val - 0x%08x\n",
-		       i, (u32) & par_io[i].cpdir2,
-		       in_be32(&par_io[i].cpdir2));
-		printk(KERN_INFO "cppar1[%d]: addr - 0x%08x, val - 0x%08x\n",
-		       i, (u32) & par_io[i].cppar1,
-		       in_be32(&par_io[i].cppar1));
-		printk(KERN_INFO "cppar2[%d]: addr - 0x%08x, val - 0x%08x\n",
-		       i, (u32) & par_io[i].cppar2,
-		       in_be32(&par_io[i].cppar2));
+		printk(KERN_INFO "	cpodr[%u]=%08x\n", i,
+			in_be32(&par_io[i].cpodr));
+		printk(KERN_INFO "	cpdata[%u]=%08x\n", i,
+			in_be32(&par_io[i].cpdata));
+		printk(KERN_INFO "	cpdir1[%u]=%08x\n", i,
+			in_be32(&par_io[i].cpdir1));
+		printk(KERN_INFO "	cpdir2[%u]=%08x\n", i,
+			in_be32(&par_io[i].cpdir2));
+		printk(KERN_INFO "	cppar1[%u]=%08x\n", i,
+			in_be32(&par_io[i].cppar1));
+		printk(KERN_INFO "	cppar2[%u]=%08x\n", i,
+			in_be32(&par_io[i].cppar2));
 	}
 
 }
arch/powerpc/sysdev/qe_lib/ucc.c +41 -27

99 lines not on this page · raw message

arch/powerpc/sysdev/qe_lib/ucc_fast.c +61 -66

215 lines not on this page · raw message

arch/powerpc/sysdev/qe_lib/ucc_slow.c +23 -25

124 lines not on this page · raw message

drivers/net/ucc_geth.c +1 -1
index 9a38dfe..96ebdf7 100644
@@ -2919,7 +2919,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	test = in_be16(&ugeth->p_tx_glbl_pram->temoder);
 
 	/* Function code register value to be used later */
-	function_code = QE_BMR_BYTE_ORDER_BO_MOT | UCC_FAST_FUNCTION_CODE_GBL;
+	function_code = UCC_BMR_BO_BE | UCC_BMR_GBL;
 	/* Required for QE */
 
 	/* function code register */
include/asm-powerpc/immap_qe.h +8 -15
index 1020b7f..0a0644b 100644
@@ -260,7 +260,6 @@ struct ucc_slow {
 	__be16	utpt;
 	u8	res4[0x52];
 	u8	guemr;		/* UCC general extended mode register */
-	u8	res5[0x200 - 0x091];
 } __attribute__ ((packed));
 
 /* QE UCC Fast */
@@ -293,21 +292,13 @@ struct ucc_fast {
 	__be32	urtry;		/* UCC retry counter register */
 	u8	res8[0x4C];
 	u8	guemr;		/* UCC general extended mode register */
-	u8	res9[0x100 - 0x091];
-} __attribute__ ((packed));
-
-/* QE UCC */
-struct ucc_common {
-	u8	res1[0x90];
-	u8	guemr;
-	u8	res2[0x200 - 0x091];
 } __attribute__ ((packed));
 
 struct ucc {
 	union {
 		struct	ucc_slow slow;
 		struct	ucc_fast fast;
-		struct	ucc_common common;
+		u8	res[0x200];	/* UCC blocks are 512 bytes each */
 	};
 } __attribute__ ((packed));
 
@@ -406,7 +397,7 @@ struct dbg {
 
 /* RISC Special Registers (Trap and Breakpoint) */
 struct rsp {
-	u8	fixme[0x100];
+	u32	reg[0x40];	/* 64 32-bit registers */
 } __attribute__ ((packed));
 
 struct qe_immap {
@@ -435,11 +426,13 @@ struct qe_immap {
 	u8			res13[0x600];
 	struct upc		upc2;		/* MultiPHY UTOPIA POS Ctrlr 2*/
 	struct sdma		sdma;		/* SDMA */
-	struct dbg		dbg;		/* Debug Space */
-	struct rsp		rsp[0x2];	/* RISC Special Registers
+	struct dbg		dbg;		/* 0x104080 - 0x1040FF
+						   Debug Space */
+	struct rsp		rsp[0x2];	/* 0x104100 - 0x1042FF
+						   RISC Special Registers
 						   (Trap and Breakpoint) */
-	u8			res14[0x300];
-	u8			res15[0x3A00];
+	u8			res14[0x300];	/* 0x104300 - 0x1045FF */
+	u8			res15[0x3A00];	/* 0x104600 - 0x107FFF */
 	u8			res16[0x8000];	/* 0x108000 - 0x110000 */
 	u8			muram[0xC000];	/* 0x110000 - 0x11C000
 						   Multi-user RAM */
include/asm-powerpc/qe.h +168 -75

307 lines not on this page · raw message

include/asm-powerpc/ucc.h +1 -23
index afe3076..f96ea54 100644
@@ -28,35 +28,13 @@ enum ucc_speed_type {
 	UCC_SPEED_TYPE_FAST, UCC_SPEED_TYPE_SLOW
 };
 
-/* Initial UCCs Parameter RAM address relative to: MEM_MAP_BASE (IMMR).
-*/
-enum ucc_pram_initial_offset {
-	UCC_PRAM_OFFSET_UCC1 = 0x8400,
-	UCC_PRAM_OFFSET_UCC2 = 0x8500,
-	UCC_PRAM_OFFSET_UCC3 = 0x8600,
-	UCC_PRAM_OFFSET_UCC4 = 0x9000,
-	UCC_PRAM_OFFSET_UCC5 = 0x8000,
-	UCC_PRAM_OFFSET_UCC6 = 0x8100,
-	UCC_PRAM_OFFSET_UCC7 = 0x8200,
-	UCC_PRAM_OFFSET_UCC8 = 0x8300
-};
-
 /* ucc_set_type
  * Sets UCC to slow or fast mode.
  *
  * ucc_num - (In) number of UCC (0-7).
- * regs    - (In) pointer to registers base for the UCC.
  * speed   - (In) slow or fast mode for UCC.
  */
-int ucc_set_type(int ucc_num, struct ucc_common *regs,
-		 enum ucc_speed_type speed);
-
-/* ucc_init_guemr
- * Init the Guemr register.
- *
- * regs - (In) pointer to registers base for the UCC.
- */
-int ucc_init_guemr(struct ucc_common *regs);
+int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed);
 
 int ucc_set_qe_mux_mii_mng(int ucc_num);
 
include/asm-powerpc/ucc_slow.h +5 -4
index fdaac9d..0980e6a 100644
@@ -148,9 +148,10 @@ enum ucc_slow_diag_mode {
 
 struct ucc_slow_info {
 	int ucc_num;
+	int protocol;			/* QE_CR_PROTOCOL_xxx */
 	enum qe_clock rx_clock;
 	enum qe_clock tx_clock;
-	u32 regs;
+	phys_addr_t regs;
 	int irq;
 	u16 uccm_mask;
 	int data_mem_part;
@@ -186,7 +187,7 @@ struct ucc_slow_info {
 
 struct ucc_slow_private {
 	struct ucc_slow_info *us_info;
-	struct ucc_slow *us_regs;	/* a pointer to memory map of UCC regs */
+	struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */
 	struct ucc_slow_pram *us_pram;	/* a pointer to the parameter RAM */
 	u32 us_pram_offset;
 	int enabled_tx;		/* Whether channel is enabled for Tx (ENT) */
@@ -277,12 +278,12 @@ void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs);
  */
 void ucc_slow_stop_tx(struct ucc_slow_private * uccs);
 
-/* ucc_slow_restart_x
+/* ucc_slow_restart_tx
  * Restarts transmitting on a specified slow UCC.
  *
  * uccs - (In) pointer to the slow UCC structure.
  */
-void ucc_slow_restart_x(struct ucc_slow_private * uccs);
+void ucc_slow_restart_tx(struct ucc_slow_private *uccs);
 
 u32 ucc_slow_get_qe_cr_subblock(int uccs_num);
 
Signature · 1 line
1.5.2.4