Skip to contentSkip to conversation

rtc: Add M41T62 support

PATCH Superseded Stefan Roese 2 participants 11 messages Mar 11, 2008

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/9 rtc: Add M41T62 support

This patch add support for the STM M41T62 RTC. It is used and tested on the AMCC Canyonlands 406EX platform.

---
 drivers/rtc/Makefile |    1 +
 drivers/rtc/m41t62.c |  135 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+), 0 deletions(-)
 create mode 100644 drivers/rtc/m41t62.c
drivers/rtc/Makefile +1 -0
index 2af2bf4..17c0f86 100644
@@ -41,6 +41,7 @@ COBJS-y += ds174x.o
 COBJS-y += ds3231.o
 COBJS-y += m41t11.o
 COBJS-y += m41t60.o
+COBJS-y += m41t62.o
 COBJS-y += max6900.o
 COBJS-y += m48t35ax.o
 COBJS-y += mc146818.o
drivers/rtc/m41t62.c new file +135 -0

135 lines not on this page · raw message

Signature · 1 line
1.5.4.4
#1 lore raw

PATCH 2/9 ppc4xx: miiphy.c reworked

While adding the 460EX/GT support I reworked the 4xx miiphy code. It badly neede some cleanup.

---
 cpu/ppc4xx/miiphy.c |  196 +++++++++++++++++++++------------------------------
 1 files changed, 80 insertions(+), 116 deletions(-)
cpu/ppc4xx/miiphy.c +80 -116
index 3978773..c882720 100644
@@ -29,6 +29,11 @@
   |
   +-----------------------------------------------------------------------------*/
 
+/* define DEBUG for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
 #include <common.h>
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -38,7 +43,10 @@
 #include <405_mal.h>
 #include <miiphy.h>
 
-#undef ET_DEBUG
+#if !defined(CONFIG_PHY_CLK_FREQ)
+#define CONFIG_PHY_CLK_FREQ	0
+#endif
+
 /***********************************************************/
 /* Dump out to the screen PHY regs			   */
 /***********************************************************/
@@ -164,9 +172,21 @@ int phy_setup_aneg (char *devname, unsigned char addr)
 /***********************************************************/
 /* read a phy reg and return the value with a rc	   */
 /***********************************************************/
+/* AMCC_TODO:
+ * Find out of the choice for the emac for MDIO is from the bridges,
+ * i.e. ZMII or RGMII as approporiate.  If the bridges are not used
+ * to determine the emac for MDIO, then is the SDR0_ETH_CFG[MDIO_SEL]
+ * used?  If so, then this routine below does not apply to the 460EX/GT.
+ *
+ * sr: Currently on 460EX only EMAC0 works with MDIO, so we always
+ * return EMAC0 offset here
+ */
 unsigned int miiphy_getemac_offset (void)
 {
-#if (defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)) && defined(CONFIG_NET_MULTI)
+#if (defined(CONFIG_440) && \
+    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_460EX) && !defined(CONFIG_460GT)) && \
+    defined(CONFIG_NET_MULTI)
 	unsigned long zmii;
 	unsigned long eoffset;
 
@@ -217,153 +237,97 @@ unsigned int miiphy_getemac_offset (void)
 #endif
 }
 
-int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
-			 unsigned short *value)
+static int emac_miiphy_wait(u32 emac_reg)
 {
-	unsigned long sta_reg;	/* STA scratch area */
-	unsigned long i;
-	unsigned long emac_reg;
+	u32 sta_reg;
+	int i;
 
-	emac_reg = miiphy_getemac_offset ();
-	/* see if it is ready for 1000 nsec */
+	/* wait for completion */
 	i = 0;
-
-	/* see if it is ready for  sec */
-	while ((in_be32((void *)EMAC_STACR + emac_reg) & EMAC_STACR_OC) ==
-	       EMAC_STACR_OC_MASK) {
-		udelay (7);
-		if (i > 5) {
-#ifdef ET_DEBUG
-			sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
-			printf ("read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
-			printf ("read err 1\n");
-#endif
+	do {
+		sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
+		if (i++ > 5) {
+			debug("%s [%d]: Timeout! EMAC_STACR=0x%0x\n", __func__,
+			      __LINE__, sta_reg);
 			return -1;
 		}
-		i++;
-	}
+		udelay(10);
+	} while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK);
+
+	return 0;
+}
+
+static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value)
+{
+	u32 emac_reg;
+	u32 sta_reg;
+
+	emac_reg = miiphy_getemac_offset();
+
+	/* wait for completion */
+	if (emac_miiphy_wait(emac_reg) != 0)
+		return -1;
+
 	sta_reg = reg;		/* reg address */
+
 	/* set clock (50Mhz) and read flags */
 #if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
     defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
     defined(CONFIG_405EX)
 #if defined(CONFIG_IBM_EMAC4_V4)	/* EMAC4 V4 changed bit setting */
-	sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
+	sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | cmd;
 #else
-	sta_reg |= EMAC_STACR_READ;
+	sta_reg |= cmd;
 #endif
 #else
-	sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
+	sta_reg = (sta_reg | cmd) & ~EMAC_STACR_CLK_100MHZ;
 #endif
 
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
-    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
-    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \
-    !defined(CONFIG_405EX)
+	/* Some boards (mainly 405EP based) define the PHY clock freqency fixed */
 	sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
-#endif
-	sta_reg = sta_reg | (addr << 5);	/* Phy address */
+	sta_reg = sta_reg | ((u32)addr << 5);	/* Phy address */
 	sta_reg = sta_reg | EMAC_STACR_OC_MASK;	/* new IBM emac v4 */
+	if (cmd == EMAC_STACR_WRITE)
+		memcpy(&sta_reg, &value, 2);	/* put in data */
+
 	out_be32((void *)EMAC_STACR + emac_reg, sta_reg);
-#ifdef ET_DEBUG
-	printf ("a2: write: EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
-#endif
+	debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
 
-	sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
-#ifdef ET_DEBUG
-	printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
-#endif
-	i = 0;
-	while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
-		udelay (7);
-		if (i > 5)
-			return -1;
+	/* wait for completion */
+	if (emac_miiphy_wait(emac_reg) != 0)
+		return -1;
 
-		i++;
-		sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
-#ifdef ET_DEBUG
-		printf ("a22: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
-#endif
-	}
+	debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
 	if ((sta_reg & EMAC_STACR_PHYE) != 0)
 		return -1;
 
-	*value = *(short *)(&sta_reg);
 	return 0;
+}
 
-}				/* phy_read */
-
-/***********************************************************/
-/* write a phy reg and return the value with a rc	    */
-/***********************************************************/
-
-int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg,
-			  unsigned short value)
+int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
+			 unsigned short *value)
 {
-	unsigned long sta_reg;	/* STA scratch area */
-	unsigned long i;
+	unsigned long sta_reg;
 	unsigned long emac_reg;
 
 	emac_reg = miiphy_getemac_offset ();
-	/* see if it is ready for 1000 nsec */
-	i = 0;
-
-	while ((in_be32((void *)EMAC_STACR + emac_reg) & EMAC_STACR_OC) ==
-	       EMAC_STACR_OC_MASK) {
-		if (i > 5)
-			return -1;
-
-		udelay (7);
-		i++;
-	}
-	sta_reg = 0;
-	sta_reg = reg;		/* reg address */
-	/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
-    defined(CONFIG_405EX)
-#if defined(CONFIG_IBM_EMAC4_V4)	/* EMAC4 V4 changed bit setting */
-	sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
-#else
-	sta_reg |= EMAC_STACR_WRITE;
-#endif
-#else
-	sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
-#endif
-
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
-    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
-    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \
-    !defined(CONFIG_405EX)
-	sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;	/* Set clock frequency (PLB freq. dependend) */
-#endif
-	sta_reg = sta_reg | ((unsigned long)addr << 5);	/* Phy address */
-	sta_reg = sta_reg | EMAC_STACR_OC_MASK;	/* new IBM emac v4 */
-	memcpy (&sta_reg, &value, 2);	/* put in data */
 
-	out_be32((void *)EMAC_STACR + emac_reg, sta_reg);
+	if (emac_miiphy_command(addr, reg, EMAC_STACR_READ, 0) != 0)
+		return -1;
 
-	/* wait for completion */
-	i = 0;
 	sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
-#ifdef ET_DEBUG
-	printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
-#endif
-	while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
-		udelay (7);
-		if (i > 5)
-			return -1;
-
-		i++;
-		sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
-#ifdef ET_DEBUG
-		printf ("a32: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
-#endif
-	}
-
-	if ((sta_reg & EMAC_STACR_PHYE) != 0)
-		return -1;
+	*value = *(u16 *)(&sta_reg);
 
 	return 0;
+}
 
-} /* phy_write */
+/***********************************************************/
+/* write a phy reg and return the value with a rc	    */
+/***********************************************************/
+
+int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg,
+			  unsigned short value)
+{
+	return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
+}
Signature · 1 line
1.5.4.4
#2 lore raw

PATCH 3/9 ppc4xx: program_tlb now uses 64bit physical addess

In reply to Stefan Roese

This patch changes the physical addess parameter from 32bit to 64bit. This is needed for 36bit 4xx platforms to access areas located beyond the 4GB border, like SoC peripherals (EBC etc.).

---
 board/netstal/hcu5/sdram.c |    2 --
 cpu/ppc4xx/tlb.c           |   27 ++++++++++++++-------------
 include/asm-ppc/mmu.h      |   18 +++++++++---------
 post/cpu/ppc4xx/cache.c    |    2 --
 4 files changed, 23 insertions(+), 26 deletions(-)
board/netstal/hcu5/sdram.c +0 -2
index d3c2233..0b16b50 100644
@@ -70,8 +70,6 @@ void dflush(void);
 #define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
 	/* disable caching on DDR2 */
 
-void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
-
 void board_add_ram_info(int use_default)
 {
 	PPC4xx_SYS_INFO board_cfg;
cpu/ppc4xx/tlb.c +14 -13
index ed493f1..2bfcba1 100644
@@ -31,9 +31,9 @@
 #include <asm/mmu.h>
 
 typedef struct region {
-	unsigned long base;
-	unsigned long size;
-	unsigned long tlb_word2_i_value;
+	u64 base;
+	u32 size;
+	u32 tlb_word2_i_value;
 } region_t;
 
 void remove_tlb(u32 vaddr, u32 size)
@@ -182,10 +182,10 @@ void change_tlb(u32 vaddr, u32 size, u32 tlb_word2_i_value)
 	asm("isync");
 }
 
-static int add_tlb_entry(unsigned long phys_addr,
-			 unsigned long virt_addr,
-			 unsigned long tlb_word0_size_value,
-			 unsigned long tlb_word2_i_value)
+static int add_tlb_entry(u64 phys_addr,
+			 u32 virt_addr,
+			 u32 tlb_word0_size_value,
+			 u32 tlb_word2_i_value)
 {
 	int i;
 	unsigned long tlb_word0_value;
@@ -204,7 +204,8 @@ static int add_tlb_entry(unsigned long phys_addr,
 	/* Second, create the TLB entry */
 	tlb_word0_value = TLB_WORD0_EPN_ENCODE(virt_addr) | TLB_WORD0_V_ENABLE |
 		TLB_WORD0_TS_0 | tlb_word0_size_value;
-	tlb_word1_value = TLB_WORD1_RPN_ENCODE(phys_addr) | TLB_WORD1_ERPN_ENCODE(0);
+	tlb_word1_value = TLB_WORD1_RPN_ENCODE((u32)phys_addr) |
+		TLB_WORD1_ERPN_ENCODE(phys_addr >> 32);
 	tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
 		TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
 		TLB_WORD2_W_DISABLE | tlb_word2_i_value |
@@ -228,10 +229,10 @@ static int add_tlb_entry(unsigned long phys_addr,
 	return 0;
 }
 
-static void program_tlb_addr(unsigned long phys_addr,
-			     unsigned long virt_addr,
-			     unsigned long mem_size,
-			     unsigned long tlb_word2_i_value)
+static void program_tlb_addr(u64 phys_addr,
+			     u32 virt_addr,
+			     u32 mem_size,
+			     u32 tlb_word2_i_value)
 {
 	int rc;
 	int tlb_i;
@@ -331,7 +332,7 @@ static void program_tlb_addr(unsigned long phys_addr,
  * Common usage for boards with SDRAM DIMM modules to dynamically
  * configure the TLB's for the SDRAM
  */
-void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value)
+void program_tlb(u64 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value)
 {
 	region_t region_array;
 
include/asm-ppc/mmu.h +9 -9
index 5af22af..49d6860 100644
@@ -549,14 +549,14 @@ extern int num_tlb_entries;
 /*----------------------------------------------------------------------------+
 | TLB specific defines.
 +----------------------------------------------------------------------------*/
-#define TLB_256MB_ALIGN_MASK 0xF0000000
-#define TLB_16MB_ALIGN_MASK  0xFF000000
-#define TLB_1MB_ALIGN_MASK   0xFFF00000
-#define TLB_256KB_ALIGN_MASK 0xFFFC0000
-#define TLB_64KB_ALIGN_MASK  0xFFFF0000
-#define TLB_16KB_ALIGN_MASK  0xFFFFC000
-#define TLB_4KB_ALIGN_MASK   0xFFFFF000
-#define TLB_1KB_ALIGN_MASK   0xFFFFFC00
+#define TLB_256MB_ALIGN_MASK 0xFF0000000ULL
+#define TLB_16MB_ALIGN_MASK  0xFFF000000ULL
+#define TLB_1MB_ALIGN_MASK   0xFFFF00000ULL
+#define TLB_256KB_ALIGN_MASK 0xFFFFC0000ULL
+#define TLB_64KB_ALIGN_MASK  0xFFFFF0000ULL
+#define TLB_16KB_ALIGN_MASK  0xFFFFFC000ULL
+#define TLB_4KB_ALIGN_MASK   0xFFFFFF000ULL
+#define TLB_1KB_ALIGN_MASK   0xFFFFFFC00ULL
 #define TLB_256MB_SIZE       0x10000000
 #define TLB_16MB_SIZE        0x01000000
 #define TLB_1MB_SIZE         0x00100000
@@ -697,7 +697,7 @@ unsigned long mftlb1(unsigned long index);
 unsigned long mftlb2(unsigned long index);
 unsigned long mftlb3(unsigned long index);
 
-void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
+void program_tlb(u64 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
 void remove_tlb(u32 vaddr, u32 size);
 void change_tlb(u32 vaddr, u32 size, u32 tlb_word2_i_value);
 #endif /* __ASSEMBLY__ */
post/cpu/ppc4xx/cache.c +0 -2
index c86a150..466ca92 100644
@@ -42,8 +42,6 @@
 
 #define CACHE_POST_SIZE	1024
 
-void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
-
 int cache_post_test1 (int tlb, void *p, int size);
 int cache_post_test2 (int tlb, void *p, int size);
 int cache_post_test3 (int tlb, void *p, int size);
Signature · 1 line
1.5.4.4
#3 lore raw

PATCH 4/9 ppc4xx: interrupt.c reworked

In reply to Stefan Roese

This patch is a rework of the 4xx interrupt handling done while adding the 460EX/GT support. Interrupts are needed on 4xx for the EMAC driver.

---
 cpu/ppc4xx/interrupts.c |  589 +++++++++++-----------------------------------
 1 files changed, 141 insertions(+), 448 deletions(-)
cpu/ppc4xx/interrupts.c +141 -448
index 2f3dc32..698bcb5 100644
@@ -38,7 +38,22 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/****************************************************************************/
+/*
+ * Define the number of UIC's
+ */
+#if defined(CONFIG_440SPE) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#define UIC_MAX		4
+#elif defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_405EX)
+#define UIC_MAX		3
+#elif defined(CONFIG_440GP) || defined(CONFIG_440SP) || \
+    defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#define UIC_MAX		2
+#else
+#define UIC_MAX		1
+#endif
 
 /*
  * CPM interrupt vector functions.
@@ -49,28 +64,15 @@ struct	irq_action {
 	int count;
 };
 
-static struct irq_action irq_vecs[32];
-void uic0_interrupt( void * parms); /* UIC0 handler */
+static struct irq_action irq_vecs[UIC_MAX * 32];
 
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-static struct irq_action irq_vecs1[32]; /* For UIC1 */
+u32 get_dcr(u16);
+void set_dcr(u16, u32);
 
-void uic1_interrupt( void * parms); /* UIC1 handler */
-
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-static struct irq_action irq_vecs2[32]; /* For UIC2 */
-void uic2_interrupt( void * parms); /* UIC2 handler */
-#endif /* CONFIG_440GX CONFIG_440SPE */
-
-#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-static struct irq_action irq_vecs3[32]; /* For UIC3 */
-void uic3_interrupt( void * parms); /* UIC3 handler */
-#endif /* CONFIG_440SPE */
-
-#endif /* CONFIG_440 */
+#if (UIC_MAX > 1) && !defined(CONFIG_440GX)
+static void uic_cascade_interrupt(void *para);
+#endif
 
-/****************************************************************************/
 #if defined(CONFIG_440)
 
 /* SPRN changed in 440 */
@@ -99,8 +101,6 @@ static __inline__ void set_evpr(unsigned long val)
 }
 #endif /* defined(CONFIG_440 */
 
-/****************************************************************************/
-
 int interrupt_init_cpu (unsigned *decrementer_count)
 {
 	int vec;
@@ -112,26 +112,10 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	/*
 	 * Mark all irqs as free
 	 */
-	for (vec=0; vec<32; vec++) {
+	for (vec = 0; vec < (UIC_MAX * 32); vec++) {
 		irq_vecs[vec].handler = NULL;
 		irq_vecs[vec].arg = NULL;
 		irq_vecs[vec].count = 0;
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-		irq_vecs1[vec].handler = NULL;
-		irq_vecs1[vec].arg = NULL;
-		irq_vecs1[vec].count = 0;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-		irq_vecs2[vec].handler = NULL;
-		irq_vecs2[vec].arg = NULL;
-		irq_vecs2[vec].count = 0;
-#endif /* CONFIG_440GX */
-#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-		irq_vecs3[vec].handler = NULL;
-		irq_vecs3[vec].arg = NULL;
-		irq_vecs3[vec].count = 0;
-#endif /* CONFIG_440SPE */
-#endif
 	}
 
 #ifdef CONFIG_4xx
@@ -172,15 +156,21 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	 */
 	set_evpr(0x00000000);
 
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
 #if !defined(CONFIG_440GX)
+#if (UIC_MAX > 1)
 	/* Install the UIC1 handlers */
-	irq_install_handler(VECNUM_UIC1NC, uic1_interrupt, 0);
-	irq_install_handler(VECNUM_UIC1C, uic1_interrupt, 0);
+	irq_install_handler(VECNUM_UIC1NC, uic_cascade_interrupt, 0);
+	irq_install_handler(VECNUM_UIC1C, uic_cascade_interrupt, 0);
 #endif
+#if (UIC_MAX > 2)
+	irq_install_handler(VECNUM_UIC2NC, uic_cascade_interrupt, 0);
+	irq_install_handler(VECNUM_UIC2C, uic_cascade_interrupt, 0);
 #endif
-
-#if defined(CONFIG_440GX)
+#if (UIC_MAX > 3)
+	irq_install_handler(VECNUM_UIC3NC, uic_cascade_interrupt, 0);
+	irq_install_handler(VECNUM_UIC3C, uic_cascade_interrupt, 0);
+#endif
+#else /* !defined(CONFIG_440GX) */
 	/* Take the GX out of compatibility mode
 	 * Travis Sawyer, 9 Mar 2004
 	 * NOTE: 440gx user manual inconsistency here
@@ -196,110 +186,24 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	mtdcr(uicb0er, 0x54000000);
 	/* None are critical */
 	mtdcr(uicb0cr, 0);
-#endif
+#endif /* !defined(CONFIG_440GX) */
 
 	return (0);
 }
 
-/****************************************************************************/
-
-/*
- * Handle external interrupts
- */
-#if defined(CONFIG_440GX)
-void external_interrupt(struct pt_regs *regs)
+/* Handler for UIC interrupt */
+static void uic_interrupt(u32 uic_base, int vec_base)
 {
-	ulong uic_msr;
-
-	/*
-	 * Read masked interrupt status register to determine interrupt source
-	 */
-	/* 440 GX uses base uic register */
-	uic_msr = mfdcr(uicb0msr);
-
-	if ( (UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr) )
-		uic0_interrupt(0);
-
-	if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
-		uic1_interrupt(0);
-
-	if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
-		uic2_interrupt(0);
-
-	mtdcr(uicb0sr, uic_msr);
-
-	return;
-
-} /* external_interrupt CONFIG_440GX */
-
-#elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-void external_interrupt(struct pt_regs *regs)
-{
-	ulong uic_msr;
-
-	/*
-	 * Read masked interrupt status register to determine interrupt source
-	 */
-	/* 440 SPe uses base uic register */
-	uic_msr = mfdcr(uic0msr);
-
-	if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
-		uic1_interrupt(0);
-
-	if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
-		uic2_interrupt(0);
-
-	if (uic_msr & ~(UICB0_ALL))
-		uic0_interrupt(0);
-
-	mtdcr(uic0sr, uic_msr);
-
-	return;
-
-} /* external_interrupt CONFIG_440EPX & CONFIG_440GRX */
-
-#elif defined(CONFIG_440SPE)
-void external_interrupt(struct pt_regs *regs)
-{
-	ulong uic_msr;
-
-	/*
-	 * Read masked interrupt status register to determine interrupt source
-	 */
-	/* 440 SPe uses base uic register */
-	uic_msr = mfdcr(uic0msr);
-
-	if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
-		uic1_interrupt(0);
-
-	if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
-		uic2_interrupt(0);
-
-	if ( (UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr) )
-		uic3_interrupt(0);
-
-	if (uic_msr & ~(UICB0_ALL))
-		uic0_interrupt(0);
-
-	mtdcr(uic0sr, uic_msr);
-
-	return;
-} /* external_interrupt CONFIG_440SPE */
-
-#else
-
-void external_interrupt(struct pt_regs *regs)
-{
-	ulong uic_msr;
-	ulong msr_shift;
+	u32 uic_msr;
+	u32 msr_shift;
 	int vec;
 
 	/*
 	 * Read masked interrupt status register to determine interrupt source
 	 */
-	uic_msr = mfdcr(uicmsr);
+	uic_msr = get_dcr(uic_base + UIC_MSR);
 	msr_shift = uic_msr;
-	vec = 0;
+	vec = vec_base;
 
 	while (msr_shift != 0) {
 		if (msr_shift & 0x80000000) {
@@ -312,14 +216,17 @@ void external_interrupt(struct pt_regs *regs)
 				/* call isr */
 				(*irq_vecs[vec].handler)(irq_vecs[vec].arg);
 			} else {
-				mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec));
-				printf ("Masking bogus interrupt vector 0x%x\n", vec);
+				set_dcr(uic_base + UIC_ER,
+					get_dcr(uic_base + UIC_ER) &
+					~(0x80000000 >> vec));
+				printf("Masking bogus interrupt vector %d"
+				       " (UIC_BASE=0x%x)\n", vec, uic_base);
 			}
 
 			/*
 			 * After servicing the interrupt, we have to remove the status indicator.
 			 */
-			mtdcr(uicsr, (0x80000000 >> vec));
+			set_dcr(uic_base + UIC_SR, (0x80000000 >> vec));
 		}
 
 		/*
@@ -329,324 +236,150 @@ void external_interrupt(struct pt_regs *regs)
 		vec++;
 	}
 }
-#endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-/* Handler for UIC0 interrupt */
-void uic0_interrupt( void * parms)
+#if (UIC_MAX > 1) && !defined(CONFIG_440GX)
+static void uic_cascade_interrupt(void *para)
 {
-	ulong uic_msr;
-	ulong msr_shift;
-	int vec;
-
-	/*
-	 * Read masked interrupt status register to determine interrupt source
-	 */
-	uic_msr = mfdcr(uicmsr);
-	msr_shift = uic_msr;
-	vec = 0;
-
-	while (msr_shift != 0) {
-		if (msr_shift & 0x80000000) {
-			/*
-			 * Increment irq counter (for debug purpose only)
-			 */
-			irq_vecs[vec].count++;
-
-			if (irq_vecs[vec].handler != NULL) {
-				/* call isr */
-				(*irq_vecs[vec].handler)(irq_vecs[vec].arg);
-			} else {
-				mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec));
-				printf ("Masking bogus interrupt vector (uic0) 0x%x\n", vec);
-			}
-
-			/*
-			 * After servicing the interrupt, we have to remove the status indicator.
-			 */
-			mtdcr(uicsr, (0x80000000 >> vec));
-		}
-
-		/*
-		 * Shift msr to next position and increment vector
-		 */
-		msr_shift <<= 1;
-		vec++;
-	}
+	external_interrupt(para);
 }
+#endif
 
-#endif /* CONFIG_440GX */
-
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-/* Handler for UIC1 interrupt */
-void uic1_interrupt( void * parms)
-{
-	ulong uic1_msr;
-	ulong msr_shift;
-	int vec;
-
-	/*
-	 * Read masked interrupt status register to determine interrupt source
-	 */
-	uic1_msr = mfdcr(uic1msr);
-	msr_shift = uic1_msr;
-	vec = 0;
-
-	while (msr_shift != 0) {
-		if (msr_shift & 0x80000000) {
-			/*
-			 * Increment irq counter (for debug purpose only)
-			 */
-			irq_vecs1[vec].count++;
-
-			if (irq_vecs1[vec].handler != NULL) {
-				/* call isr */
-				(*irq_vecs1[vec].handler)(irq_vecs1[vec].arg);
-			} else {
-				mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> vec));
-				printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec);
-			}
-
-			/*
-			 * After servicing the interrupt, we have to remove the status indicator.
-			 */
-			mtdcr(uic1sr, (0x80000000 >> vec));
-		}
-
-		/*
-		 * Shift msr to next position and increment vector
-		 */
-		msr_shift <<= 1;
-		vec++;
-	}
-}
-#endif /* defined(CONFIG_440) */
+#if defined(CONFIG_440)
+#if defined(CONFIG_440GX)
+/* 440GX uses base uic register */
+#define UIC_BMSR	uicb0msr
+#define UIC_BSR		uicb0sr
+#else
+#define UIC_BMSR	uic0msr
+#define UIC_BSR		uic0sr
+#endif
+#else /* CONFIG_440 */
+#define UIC_BMSR	uicmsr
+#define UIC_BSR		uicsr
+#endif /* CONFIG_440 */
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-/* Handler for UIC2 interrupt */
-void uic2_interrupt( void * parms)
+/*
+ * Handle external interrupts
+ */
+void external_interrupt(struct pt_regs *regs)
 {
-	ulong uic2_msr;
-	ulong msr_shift;
-	int vec;
+	u32 uic_msr;
 
 	/*
 	 * Read masked interrupt status register to determine interrupt source
 	 */
-	uic2_msr = mfdcr(uic2msr);
-	msr_shift = uic2_msr;
-	vec = 0;
+	uic_msr = mfdcr(UIC_BMSR);
 
-	while (msr_shift != 0) {
-		if (msr_shift & 0x80000000) {
-			/*
-			 * Increment irq counter (for debug purpose only)
-			 */
-			irq_vecs2[vec].count++;
-
-			if (irq_vecs2[vec].handler != NULL) {
-				/* call isr */
-				(*irq_vecs2[vec].handler)(irq_vecs2[vec].arg);
-			} else {
-				mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> vec));
-				printf ("Masking bogus interrupt vector (uic2) 0x%x\n", vec);
-			}
-
-			/*
-			 * After servicing the interrupt, we have to remove the status indicator.
-			 */
-			mtdcr(uic2sr, (0x80000000 >> vec));
-		}
-
-		/*
-		 * Shift msr to next position and increment vector
-		 */
-		msr_shift <<= 1;
-		vec++;
-	}
-}
-#endif /* defined(CONFIG_440GX) */
-
-#if defined(CONFIG_440SPE)
-/* Handler for UIC3 interrupt */
-void uic3_interrupt( void * parms)
-{
-	ulong uic3_msr;
-	ulong msr_shift;
-	int vec;
+#if (UIC_MAX > 1)
+	if ((UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr))
+		uic_interrupt(UIC1_DCR_BASE, 32);
+#endif
 
-	/*
-	 * Read masked interrupt status register to determine interrupt source
-	 */
-	uic3_msr = mfdcr(uic3msr);
-	msr_shift = uic3_msr;
-	vec = 0;
+#if (UIC_MAX > 2)
+	if ((UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr))
+		uic_interrupt(UIC2_DCR_BASE, 64);
+#endif
 
-	while (msr_shift != 0) {
-		if (msr_shift & 0x80000000) {
-			/*
-			 * Increment irq counter (for debug purpose only)
-			 */
-			irq_vecs3[vec].count++;
+#if (UIC_MAX > 3)
+	if ((UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr))
+		uic_interrupt(UIC3_DCR_BASE, 96);
+#endif
 
-			if (irq_vecs3[vec].handler != NULL) {
-				/* call isr */
-				(*irq_vecs3[vec].handler)(irq_vecs3[vec].arg);
-			} else {
-				mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> vec));
-				printf ("Masking bogus interrupt vector (uic3) 0x%x\n", vec);
-			}
+#if defined(CONFIG_440)
+#if !defined(CONFIG_440GX)
+	if (uic_msr & ~(UICB0_ALL))
+		uic_interrupt(UIC0_DCR_BASE, 0);
+#else
+	if ((UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr))
+		uic_interrupt(UIC0_DCR_BASE, 0);
+#endif
+#else /* CONFIG_440 */
+	uic_interrupt(UIC0_DCR_BASE, 0);
+#endif /* CONFIG_440 */
 
-			/*
-			 * After servicing the interrupt, we have to remove the status indicator.
-			 */
-			mtdcr(uic3sr, (0x80000000 >> vec));
-		}
+	mtdcr(UIC_BSR, uic_msr);
 
-		/*
-		 * Shift msr to next position and increment vector
-		 */
-		msr_shift <<= 1;
-		vec++;
-	}
+	return;
 }
-#endif /* defined(CONFIG_440SPE) */
-
-/****************************************************************************/
 
 /*
  * Install and free a interrupt handler.
  */
-
-void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
+void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
 {
-	struct irq_action *irqa = irq_vecs;
-	int i = vec;
-
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-	if ((vec > 31) && (vec < 64)) {
-		i = vec - 32;
-		irqa = irq_vecs1;
-	} else if (vec > 63) {
-		i = vec - 64;
-		irqa = irq_vecs2;
-	}
-#else  /* CONFIG_440GX */
-	if (vec > 31) {
-		i = vec - 32;
-		irqa = irq_vecs1;
-	}
-#endif /* CONFIG_440GX */
-#endif /* CONFIG_440 */
+	int i;
 
 	/*
-	 * print warning when replacing with a different irq vector
+	 * Print warning when replacing with a different irq vector
 	 */
-	if ((irqa[i].handler != NULL) && (irqa[i].handler != handler)) {
-		printf ("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
-			vec, (uint) handler, (uint) irqa[i].handler);
+	if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler != handler)) {
+		printf("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
+		       vec, (uint) handler, (uint) irq_vecs[vec].handler);
 	}
-	irqa[i].handler = handler;
-	irqa[i].arg = arg;
-
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-	if ((vec > 31) && (vec < 64))
-		mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
-	else if (vec > 63)
-		mtdcr (uic2er, mfdcr (uic2er) | (0x80000000 >> i));
-	else
-#endif /* CONFIG_440GX */
-	if (vec > 31)
-		mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
-	else
+	irq_vecs[vec].handler = handler;
+	irq_vecs[vec].arg = arg;
+
+	i = vec & 0x1f;
+	if ((vec >= 0) && (vec < 32))
+		mtdcr(uicer, mfdcr(uicer) | (0x80000000 >> i));
+#if (UIC_MAX > 1)
+	else if ((vec >= 32) && (vec < 64))
+		mtdcr(uic1er, mfdcr(uic1er) | (0x80000000 >> i));
+#endif
+#if (UIC_MAX > 2)
+	else if ((vec >= 64) && (vec < 96))
+		mtdcr(uic2er, mfdcr(uic2er) | (0x80000000 >> i));
 #endif
-		mtdcr (uicer, mfdcr (uicer) | (0x80000000 >> i));
-#if 0
-	printf ("Install interrupt for vector %d ==> %p\n", vec, handler);
+#if (UIC_MAX > 3)
+	else if (vec >= 96)
+		mtdcr(uic3er, mfdcr(uic3er) | (0x80000000 >> i));
 #endif
+
+	debug("Install interrupt for vector %d ==> %p\n", vec, handler);
 }
 
 void irq_free_handler (int vec)
 {
-	struct irq_action *irqa = irq_vecs;
-	int i = vec;
-
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-	if ((vec > 31) && (vec < 64)) {
-		irqa = irq_vecs1;
-		i = vec - 32;
-	} else if (vec > 63) {
-		irqa = irq_vecs2;
-		i = vec - 64;
-	}
-#endif /* CONFIG_440GX */
-	if (vec > 31) {
-		irqa = irq_vecs1;
-		i = vec - 32;
-	}
-#endif
+	int i;
 
-#if 0
-	printf ("Free interrupt for vector %d ==> %p\n",
-		vec, irq_vecs[vec].handler);
-#endif
+	debug("Free interrupt for vector %d ==> %p\n",
+	      vec, irq_vecs[vec].handler);
 
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-	if ((vec > 31) && (vec < 64))
-		mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
-	else if (vec > 63)
-		mtdcr (uic2er, mfdcr (uic2er) & ~(0x80000000 >> i));
-	else
-#endif /* CONFIG_440GX */
-	if (vec > 31)
-		mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
-	else
+	i = vec & 0x1f;
+	if ((vec >= 0) && (vec < 32))
+		mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> i));
+#if (UIC_MAX > 1)
+	else if ((vec >= 32) && (vec < 64))
+		mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> i));
+#endif
+#if (UIC_MAX > 2)
+	else if ((vec >= 64) && (vec < 96))
+		mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> i));
+#endif
+#if (UIC_MAX > 3)
+	else if (vec >= 96)
+		mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> i));
 #endif
-		mtdcr (uicer, mfdcr (uicer) & ~(0x80000000 >> i));
 
-	irqa[i].handler = NULL;
-	irqa[i].arg = NULL;
+	irq_vecs[vec].handler = NULL;
+	irq_vecs[vec].arg = NULL;
 }
 
-/****************************************************************************/
-
 void timer_interrupt_cpu (struct pt_regs *regs)
 {
 	/* nothing to do here */
 	return;
 }
 
-/****************************************************************************/
-
 #if defined(CONFIG_CMD_IRQ)
-
-/*******************************************************************************
- *
- * irqinfo - print information about PCI devices
- *
- */
-int
-do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	int vec;
 
-	printf ("\nInterrupt-Information:\n");
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-	printf ("\nUIC 0\n");
-#endif
+	printf ("Interrupt-Information:\n");
 	printf ("Nr  Routine   Arg       Count\n");
 
-	for (vec=0; vec<32; vec++) {
+	for (vec = 0; vec < (UIC_MAX * 32); vec++) {
 		if (irq_vecs[vec].handler != NULL) {
 			printf ("%02d  %08lx  %08lx  %d\n",
 				vec,
@@ -656,46 +389,6 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		}
 	}
 
-#if defined(CONFIG_440) || defined(CONFIG_405EX)
-	printf ("\nUIC 1\n");
-	printf ("Nr  Routine   Arg       Count\n");
-
-	for (vec=0; vec<32; vec++) {
-		if (irq_vecs1[vec].handler != NULL)
-			printf ("%02d  %08lx  %08lx  %d\n",
-				vec+31, (ulong)irq_vecs1[vec].handler,
-				(ulong)irq_vecs1[vec].arg, irq_vecs1[vec].count);
-	}
-	printf("\n");
-#endif
-
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-	printf ("\nUIC 2\n");
-	printf ("Nr  Routine   Arg       Count\n");
-
-	for (vec=0; vec<32; vec++) {
-		if (irq_vecs2[vec].handler != NULL)
-			printf ("%02d  %08lx  %08lx  %d\n",
-				vec+63, (ulong)irq_vecs2[vec].handler,
-				(ulong)irq_vecs2[vec].arg, irq_vecs2[vec].count);
-	}
-	printf("\n");
-#endif
-
-#if defined(CONFIG_440SPE)
-	printf ("\nUIC 3\n");
-	printf ("Nr  Routine   Arg       Count\n");
-
-	for (vec=0; vec<32; vec++) {
-		if (irq_vecs3[vec].handler != NULL)
-			printf ("%02d  %08lx  %08lx  %d\n",
-					vec+63, (ulong)irq_vecs3[vec].handler,
-					(ulong)irq_vecs3[vec].arg, irq_vecs3[vec].count);
-	}
-	printf("\n");
-#endif
-
 	return 0;
 }
 #endif
Signature · 1 line
1.5.4.4
#4 lore raw

PATCH 6/9 ppc4xx: Add AMCC Canyonlands support (460EX)

In reply to Stefan Roese

This patch adds support for the AMCC Canyonlands 460EX evaluation board.

---
 MAINTAINERS                          |    1 +
 MAKEALL                              |    1 +
 Makefile                             |    3 +
 board/amcc/canyonlands/Makefile      |   51 ++++
 board/amcc/canyonlands/bootstrap.c   |  169 ++++++++++++
 board/amcc/canyonlands/canyonlands.c |  385 ++++++++++++++++++++++++++++
 board/amcc/canyonlands/config.mk     |   49 ++++
 board/amcc/canyonlands/init.S        |  114 ++++++++
 board/amcc/canyonlands/u-boot.lds    |  146 +++++++++++
 include/asm-ppc/gpio.h               |    5 +-
 include/configs/canyonlands.h        |  470 ++++++++++++++++++++++++++++++++++
 11 files changed, 1392 insertions(+), 2 deletions(-)
 create mode 100644 board/amcc/canyonlands/Makefile
 create mode 100644 board/amcc/canyonlands/bootstrap.c
 create mode 100644 board/amcc/canyonlands/canyonlands.c
 create mode 100644 board/amcc/canyonlands/config.mk
 create mode 100644 board/amcc/canyonlands/init.S
 create mode 100644 board/amcc/canyonlands/u-boot.lds
 create mode 100644 include/configs/canyonlands.h
MAINTAINERS +1 -0
index dc13580..f248fff 100644
@@ -319,6 +319,7 @@ Stefan Roese <[email protected]>
 	alpr			PPC440GX
 	bamboo			PPC440EP
 	bunbinga		PPC405EP
+	canyonlands		PPC460EX
 	ebony			PPC440GP
 	haleakala		PPC405EXr
 	katmai			PPC440SPe
MAKEALL +1 -0
index 0e1c0cb..f3b1968 100755
@@ -165,6 +165,7 @@ LIST_4xx="		\
 	bamboo_nand	\
 	bubinga		\
 	CANBT		\
+	canyonlands	\
 	CMS700		\
 	CPCI2DP		\
 	CPCI405		\
Makefile +3 -0
index 90198f6..b46e43a 100644
@@ -1170,6 +1170,9 @@ bubinga_config:	unconfig
 CANBT_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx canbt esd
 
+canyonlands_config:	unconfig
+	@$(MKCONFIG) $(@:_config=) ppc ppc4xx canyonlands amcc
+
 CATcenter_config	\
 CATcenter_25_config	\
 CATcenter_33_config:	unconfig
board/amcc/canyonlands/Makefile new file +51 -0

51 lines not on this page · raw message

board/amcc/canyonlands/bootstrap.c new file +169 -0

169 lines not on this page · raw message

board/amcc/canyonlands/canyonlands.c new file +385 -0

385 lines not on this page · raw message

board/amcc/canyonlands/config.mk new file +49 -0

49 lines not on this page · raw message

board/amcc/canyonlands/init.S new file +114 -0

114 lines not on this page · raw message

board/amcc/canyonlands/u-boot.lds new file +146 -0

146 lines not on this page · raw message

include/asm-ppc/gpio.h +3 -2
index c3a4a88..fc05dc0 100644
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007
+ * (C) Copyright 2007-2008
  * Stefan Roese, DENX Software Engineering, sr at denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -27,7 +27,8 @@
 /* 4xx PPC's have 2 GPIO controllers */
 #if defined(CONFIG_405EZ) ||					\
 	defined(CONFIG_440EP) || defined(CONFIG_440GR) ||	\
-	defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+	defined(CONFIG_440EPX) || defined(CONFIG_440GRX) ||	\
+	defined(CONFIG_460EX) || defined(CONFIG_460GT)
 #define GPIO_GROUP_MAX	2
 #else
 #define GPIO_GROUP_MAX	1
include/configs/canyonlands.h new file +470 -0

470 lines not on this page · raw message

Signature · 1 line
1.5.4.4
#5 lore raw

PATCH 5/9 ppc4xx: Add basic support for AMCC 460EX/460GT

This patch adds basic support for the AMCC 460EX/460GT PPC's.

Enable high bandwidth access on 460EX/GT. This should/could probably be done on other PPC's too, like 440SPe. This is currently not used, but with this setup it is possible to use it later on in e.g. the Linux EMAC driver for performance gain.

---
 cpu/ppc4xx/44x_spd_ddr2.c       |   41 +++-
 cpu/ppc4xx/4xx_enet.c           |  369 ++++++++++++++++++++-----
 cpu/ppc4xx/4xx_pci.c            |    9 +-
 cpu/ppc4xx/4xx_pcie.c           |  203 +++++++++++++-
 cpu/ppc4xx/4xx_uart.c           |   24 +-
 cpu/ppc4xx/cpu.c                |   45 +++-
 cpu/ppc4xx/cpu_init.c           |    1 +
 cpu/ppc4xx/ndfc.c               |    3 +-
 cpu/ppc4xx/speed.c              |  125 ++++++++-
 cpu/ppc4xx/start.S              |   11 +-
 include/405_mal.h               |    1 +
 include/4xx_i2c.h               |    3 +-
 include/asm-ppc/4xx_pcie.h      |   79 +++++-
 include/asm-ppc/ppc4xx-intvec.h |   71 +++++
 include/asm-ppc/processor.h     |    4 +
 include/asm-ppc/u-boot.h        |    6 +-
 include/common.h                |    4 +-
 include/ppc405.h                |   23 ++-
 include/ppc440.h                |  590 +++++++++++++++++++++++++++++++++------
 include/ppc4xx_enet.h           |   18 +-
 20 files changed, 1426 insertions(+), 204 deletions(-)

Unfortunately this patch is too big for the list (101k). So please find a gzipped version attached.

Best regards,
Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-ppc4xx-Add-basic-support-for-AMCC-460EX-460GT.patch.gz
Type: application/x-gzip
Size: 22055 bytes
Desc: not available
Url : http://lists.denx.de/pipermail/u-boot/attachments/20080311/01a3aa2d/attachment.bin

#6 lore raw

PATCH 5/9 ppc4xx: Add basic support for AMCC 460EX/460GT

Quoted 3 lines · In message <[email protected]> you wrote:

Unfortunately this patch is too big for the list (101k). So please find a gzipped version attached.

Grrrghh.... Please stick to the rules!

Binary attachments are not allowed!

Best regards,

Wolfgang Denk

Signature · 7 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
You could end up being oddly sad and full of a strange, diffuse  com-
passion  which would lead you to believe that it might be a good idea
to wipe out the whole human race and start again with amoebas.
                                 - Terry Pratchett, _Guards! Guards!_
#7 lore raw

PATCH 5/9 ppc4xx: Add basic support for AMCC 460EX/460GT

Quoted 7 lines · Wolfgang Denk
Quoted 2 lines · In message <[email protected]> you wrote:

Unfortunately this patch is too big for the list (101k). So please find a gzipped version attached.

Grrrghh.... Please stick to the rules!

Binary attachments are not allowed!

I'm sure that I have expressed before that I don't like these limits on this mailing list. You might have noticed that the linuxppc-dev mailing list nowadays has a limit of 400k. From my experience this 40k rule makes all our lives harder. Yours, since you have to manually moderate this list, and mine because I now have to rework the patch series.

And yes, I know that the patch you rejected is > 100k, which is the "hard limit".

But fine, I'll rework the patch series and resend soon.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================

#8 lore raw

PATCH 7/9 ppc4xx: Add Canyonlands NAND booting support

In reply to Stefan Roese

460EX doesn't support a fixed bootstrap option to boot from 512 byte page NAND devices. The only bootstrap option for NAND booting is option F for 2k page devices. So to boot from a 512 bype page device, the I2C bootstrap EEPROM needs to be programmed accordingly.

This patch adds basic NAND booting support for the AMCC Canyonlands aval board and also adds support to the "bootstrap" command, to enable NAND booting I2C setting.

Tested with 512 byte page NAND device (32MByte) on Canyonlands.

---
 MAKEALL                                      |    1 +
 Makefile                                     |    8 ++
 board/amcc/canyonlands/Makefile              |    2 +-
 board/amcc/canyonlands/bootstrap.c           |   23 +++--
 board/amcc/canyonlands/canyonlands.c         |   27 +++++-
 board/amcc/canyonlands/init.S                |    7 +-
 board/amcc/canyonlands/u-boot-nand.lds       |  137 ++++++++++++++++++++++++++
 cpu/ppc4xx/start.S                           |    8 ++-
 include/configs/canyonlands.h                |   89 +++++++++++++++--
 nand_spl/board/amcc/canyonlands/Makefile     |  100 +++++++++++++++++++
 nand_spl/board/amcc/canyonlands/config.mk    |   49 +++++++++
 nand_spl/board/amcc/canyonlands/ddr2_fixed.c |   96 ++++++++++++++++++
 nand_spl/board/amcc/canyonlands/u-boot.lds   |   65 ++++++++++++
 13 files changed, 586 insertions(+), 26 deletions(-)
 create mode 100644 board/amcc/canyonlands/u-boot-nand.lds
 create mode 100644 nand_spl/board/amcc/canyonlands/Makefile
 create mode 100644 nand_spl/board/amcc/canyonlands/config.mk
 create mode 100644 nand_spl/board/amcc/canyonlands/ddr2_fixed.c
 create mode 100644 nand_spl/board/amcc/canyonlands/u-boot.lds
MAKEALL +1 -0
index f3b1968..15b011d 100755
@@ -166,6 +166,7 @@ LIST_4xx="		\
 	bubinga		\
 	CANBT		\
 	canyonlands	\
+	canyonlands_nand \
 	CMS700		\
 	CPCI2DP		\
 	CPCI405		\
Makefile +8 -0
index b46e43a..730448a 100644
@@ -1173,6 +1173,14 @@ CANBT_config:	unconfig
 canyonlands_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx canyonlands amcc
 
+canyonlands_nand_config:	unconfig
+	@mkdir -p $(obj)include $(obj)board/amcc/canyonlands
+	@mkdir -p $(obj)nand_spl/board/amcc/canyonlands
+	@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
+	@$(MKCONFIG) -n $@ -a canyonlands ppc ppc4xx canyonlands amcc
+	@echo "TEXT_BASE = 0x01000000" > $(obj)board/amcc/canyonlands/config.tmp
+	@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
+
 CATcenter_config	\
 CATcenter_25_config	\
 CATcenter_33_config:	unconfig
board/amcc/canyonlands/Makefile +1 -1
index a3385c7..3238c15 100644
@@ -33,7 +33,7 @@ OBJS	:= $(addprefix $(obj),$(COBJS))
 SOBJS	:= $(addprefix $(obj),$(SOBJS))
 
 $(LIB):	$(OBJS) $(SOBJS)
-	$(AR) $(ARFLAGS) $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
 
 clean:
 	rm -f $(SOBJS) $(OBJS)
board/amcc/canyonlands/bootstrap.c +12 -11
index 3f5822e..37fa1c9 100644
@@ -28,7 +28,7 @@
 #include <asm/io.h>
 
 /*
- * NOR and NAND boot options change bytes 6, 7, 8, 9, 11. The
+ * NOR and NAND boot options change bytes 5, 6, 8, 9, 11. The
  * values are independent of the rest of the clock settings.
  */
 
@@ -45,14 +45,14 @@ static char *config_labels[] = {
 
 static u8 boot_configs[][17] = {
 	{
-		(NOR_COMPATIBLE),
+		(NAND_COMPATIBLE | NOR_COMPATIBLE),
 		0x86, 0x80, 0xce, 0x1f, 0x79, 0x80, 0x00, 0xa0, 0x40, 0x08,
-		0x23, 0x50, 0x0d, 0x95, 0x00, 0x00
+		0x23, 0x50, 0x0d, 0x05, 0x00, 0x00
 	},
 	{
-		(NOR_COMPATIBLE),
+		(NAND_COMPATIBLE | NOR_COMPATIBLE),
 		0x86, 0x80, 0xba, 0x14, 0x99, 0x80, 0x00, 0xa0, 0x40, 0x08,
-		0x23, 0x50, 0x0d, 0x95, 0x00, 0x00
+		0x23, 0x50, 0x0d, 0x05, 0x00, 0x00
 	},
 	{
 		0,
@@ -61,10 +61,10 @@ static u8 boot_configs[][17] = {
 };
 
 /*
- * Bytes 6,8,9,11 change for NAND boot
+ * Bytes 5,6,8,9,11 change for NAND boot
  */
 static u8 nand_boot[] = {
-	0xd0,  0xa0, 0x68, 0x58
+	0x90, 0x01,  0xa0, 0x68, 0x58
 };
 
 static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@@ -146,10 +146,11 @@ static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	buf = &boot_configs[x][1];
 
 	if (b_nand) {
-		buf[6] = nand_boot[0];
-		buf[8] = nand_boot[1];
-		buf[9] = nand_boot[2];
-		buf[11] = nand_boot[3];
+		buf[5] = nand_boot[0];
+		buf[6] = nand_boot[1];
+		buf[8] = nand_boot[2];
+		buf[9] = nand_boot[3];
+		buf[11] = nand_boot[4];
 	}
 
 	if (i2c_write(I2C_EEPROM_ADDR, 0, 1, buf, 16) != 0)
board/amcc/canyonlands/canyonlands.c +23 -4
index 8292d2d..3551429 100644
@@ -134,6 +134,18 @@ u32 ddr_clktr(u32 default_val) {
 	return (SDRAM_CLKTR_CLKP_90_DEG_ADV);
 }
 
+#if defined(CONFIG_NAND_U_BOOT)
+/*
+ * NAND booting U-Boot version uses a fixed initialization, since the whole
+ * I2C SPD DIMM autodetection/calibration doesn't fit into the 4k of boot
+ * code.
+ */
+long int initdram(int board_type)
+{
+	return CFG_MBYTES_SDRAM << 20;
+}
+#endif
+
 #if defined(CFG_DRAM_TEST)
 int testdram(void)
 {
@@ -308,14 +320,14 @@ int board_early_init_r (void)
 	 * EBC address which accepts bigger regions:
 	 *
 	 * 0xfc00.0000 -> 4.cc00.0000
-	 *
-	 * For this we have to remap the CS0 and re-relocate the envrironment,
-	 * since the original FLASH location which was needed upon startup is
-	 * now not correct anymore.
 	 */
 
 	/* Remap the NOR FLASH to 0xcc00.0000 ... 0xcfff.ffff */
+#if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
+	mtebc(pb3cr, CFG_FLASH_BASE_PHYS_L | 0xda000);
+#else
 	mtebc(pb0cr, CFG_FLASH_BASE_PHYS_L | 0xda000);
+#endif
 
 	/* Remove TLB entry of boot EBC mapping */
 	remove_tlb(CFG_BOOT_BASE_ADDR, 16 << 20);
@@ -329,6 +341,13 @@ int board_early_init_r (void)
 	 * 0xfc00.0000 is possible
 	 */
 
+	/*
+	 * Clear potential errors resulting from auto-calibration.
+	 * If not done, then we could get an interrupt later on when
+	 * exceptions are enabled.
+	 */
+	set_mcsr(get_mcsr());
+
 	return 0;
 }
 
board/amcc/canyonlands/init.S +6 -1
index 5d48847..b7cac23 100644
@@ -46,7 +46,12 @@ tlbtab:
 	 * use the speed up boot process. It is patched after relocation to
 	 * enable SA_I
 	 */
+#ifndef CONFIG_NAND_SPL
 	tlbentry(CFG_BOOT_BASE_ADDR, SZ_16M, CFG_BOOT_BASE_ADDR, 4, AC_R|AC_W|AC_X|SA_G) /* TLB 0 */
+#else
+	tlbentry(CFG_NAND_BOOT_SPL_SRC, SZ_4K, CFG_NAND_BOOT_SPL_SRC, 4, AC_R|AC_W|AC_X|SA_G)
+	tlbentry(CFG_SDRAM_BASE, SZ_256M, CFG_SDRAM_BASE, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+#endif
 
 	/*
 	 * TLB entries for SDRAM are not needed on this platform.
@@ -78,7 +83,7 @@ tlbtab:
 	tlbentry(CFG_BCSR_BASE, SZ_1K, CFG_BCSR_BASE, 4, AC_R|AC_W|SA_G|SA_I)
 
 	/* TLB-entry for OCM */
-	tlbentry(CFG_OCM_BASE, SZ_4K, 0x00040000, 4, AC_R|AC_W|AC_X)
+	tlbentry(CFG_OCM_BASE, SZ_16K, 0x00040000, 4, AC_R|AC_W|AC_X|SA_I)
 
 	/* TLB-entry for Local Configuration registers => peripherals */
 	tlbentry(CFG_LOCAL_CONF_REGS, SZ_16M, CFG_LOCAL_CONF_REGS, 4, AC_R|AC_W|AC_X|SA_G|SA_I)
board/amcc/canyonlands/u-boot-nand.lds new file +137 -0

137 lines not on this page · raw message

cpu/ppc4xx/start.S +7 -1
index cdfc943..8d2777d 100644
@@ -403,7 +403,8 @@ rsttlb:	tlbwe	r0,r1,0x0000	/* Invalidate all entries (V=0)*/
 2:
 
 #if defined(CONFIG_NAND_SPL)
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT)
 	/*
 	 * Enable internal SRAM (only on 440EPx/GRx, 440EP/GR have no OCM)
 	 */
@@ -415,6 +416,11 @@ rsttlb:	tlbwe	r0,r1,0x0000	/* Invalidate all entries (V=0)*/
 	mfdcr	r1,isram0_pmeg
 	and	r1,r1,r2		/* Disable pwr mgmt */
 	mtdcr	isram0_pmeg,r1
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+	lis	r1,0x4000		/* BAS = 8000_0000 */
+	ori	r1,r1,0x4580		/* 16k */
+	mtdcr	isram0_sb0cr,r1
+#endif
 #endif
 #if defined(CONFIG_440EP)
 	/*
include/configs/canyonlands.h +81 -8

120 lines not on this page · raw message

nand_spl/board/amcc/canyonlands/Makefile new file +100 -0

100 lines not on this page · raw message

nand_spl/board/amcc/canyonlands/config.mk new file +49 -0

49 lines not on this page · raw message

nand_spl/board/amcc/canyonlands/ddr2_fixed.c new file +96 -0

96 lines not on this page · raw message

nand_spl/board/amcc/canyonlands/u-boot.lds new file +65 -0

65 lines not on this page · raw message

Signature · 1 line
1.5.4.4
#9 lore raw

PATCH 8/9 usb: Add CFG_OHCI_USE_NPS to common USB-OHCI driver

In reply to Stefan Roese

This patch adds CFG_OHCI_USE_NPS to the common USB-OHCI driver. This way a board just needs to define this new option to enable the "force NoPowerSwitching mode" instead of adding new CPU/architecture defines to the USB source itself.

This new option will be used first with the new AMCC 460EX Canyonlands board port, which will be posted in a few days.

This patch also fixes a small compilation problem when DEBUG is enabled.

---
 drivers/usb/usb_ohci.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/usb/usb_ohci.c +3 -2
index fb4726f..829bbca 100644
@@ -68,7 +68,8 @@
     defined(CONFIG_S3C2410) || \
     defined(CONFIG_440EP) || \
     defined(CONFIG_PCI_OHCI) || \
-    defined(CONFIG_MPC5200)
+    defined(CONFIG_MPC5200) || \
+    defined(CFG_OHCI_USE_NPS)
 # define OHCI_USE_NPS		/* force NoPowerSwitching mode */
 #endif
 
@@ -415,7 +416,7 @@ static void ohci_dump (ohci_t *controller, int verbose)
 		ep_print_int_eds (controller, "hcca");
 	dbg ("hcca frame #%04x", controller->hcca->frame_no);
 	ohci_dump_roothub (controller, 1);
-
+}
 #endif /* DEBUG */
 
 /*-------------------------------------------------------------------------*
Signature · 1 line
1.5.4.4
#10 lore raw

PATCH 9/9 ppc4xx: Add USB OHCI support to AMCC Canyonlands 460EX eval board

In reply to Stefan Roese

This patch adds USB OHCI support to the Canyonlands board port. It also enables EXT2 support.

---
 board/amcc/canyonlands/canyonlands.c |   14 +++++++
 board/amcc/canyonlands/init.S        |    3 +
 include/configs/canyonlands.h        |   68 +++++++++++++++++++++++-----------
 include/ppc440.h                     |    3 +
 4 files changed, 66 insertions(+), 22 deletions(-)
board/amcc/canyonlands/canyonlands.c +14 -0
index 3551429..36779f5 100644
@@ -26,6 +26,7 @@
 #include <asm/io.h>
 #include <asm/mmu.h>
 #include <asm/4xx_pcie.h>
+#include <asm/gpio.h>
 
 extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
 
@@ -100,6 +101,19 @@ int board_early_init_f(void)
 
 	mtsdr(SDR0_SRST1, 0);	/* Pull AHB out of reset default=1 */
 
+	/* Setup PLB4-AHB bridge based on the system address map */
+	mtdcr(AHB_TOP, 0x8000004B);
+	mtdcr(AHB_BOT, 0x8000004B);
+
+	/*
+	 * Configure USB-STP pins as alternate and not GPIO
+	 * It seems to be neccessary to configure the STP pins as GPIO
+	 * input at powerup (perhaps while USB reset is asserted). So
+	 * we configure those pins to their "real" function now.
+	 */
+	gpio_config(16, GPIO_OUT, GPIO_ALT1, GPIO_OUT_1);
+	gpio_config(19, GPIO_OUT, GPIO_ALT1, GPIO_OUT_1);
+
 	return 0;
 }
 
board/amcc/canyonlands/init.S +3 -0
index b7cac23..bd4cab5 100644
@@ -88,6 +88,9 @@ tlbtab:
 	/* TLB-entry for Local Configuration registers => peripherals */
 	tlbentry(CFG_LOCAL_CONF_REGS, SZ_16M, CFG_LOCAL_CONF_REGS, 4, AC_R|AC_W|AC_X|SA_G|SA_I)
 
+	/* AHB: Internal USB Peripherals (USB, SATA) */
+	tlbentry(CFG_AHB_BASE, SZ_1M, 0xbff00000, 4, AC_R|AC_W|AC_X|SA_G|SA_I)
+
 	tlbtab_end
 
 #if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
include/configs/canyonlands.h +46 -22

98 lines not on this page · raw message

include/ppc440.h +3 -0
index cf29fe7..80dd332 100644
@@ -3355,6 +3355,9 @@
 #define SDR0_DDR0_DDRM_DECODE(n)	((((unsigned long)(n))>>29)&0x03)
 #define SDR0_DDR0_TUNE_ENCODE(n)	((((unsigned long)(n))&0x2FF)<<0)
 #define SDR0_DDR0_TUNE_DECODE(n)	((((unsigned long)(n))>>0)&0x2FF)
+
+#define AHB_TOP			0xA4
+#define AHB_BOT			0xA5
 #endif /* CONFIG_460EX || CONFIG_460GT */
 
 #define SDR0_SDCS_SDD			(0x80000000 >> 31)
Signature · 1 line
1.5.4.4