Skip to contentSkip to conversation

CPU PPC440x5 on Virtex5 FX

PATCH New Ricardo Ribalda Delgado 4 participants 19 messages Jul 11, 2008 – Jul 14, 2008 Networking

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

This patchs gives support for the embbedded ppc440 on the Virtex5 FPGAs

---
 cpu/ppc4xx/4xx_enet.c       |    3 +-
 cpu/ppc4xx/4xx_uart.c       |    3 +
 cpu/ppc4xx/cpu.c            |    4 +
 cpu/ppc4xx/gpio.c           |    5 +
 cpu/ppc4xx/interrupts.c     |  238 ++++++++++++++++++++++++++++++++++++-------
 cpu/ppc4xx/miiphy.c         |    5 +
 cpu/ppc4xx/speed.c          |    6 +-
 include/asm-ppc/processor.h |    3 +-
 net/eth.c                   |    3 +-
 9 files changed, 228 insertions(+), 42 deletions(-)
cpu/ppc4xx/4xx_enet.c +2 -1
index 4e863dc..cf26237 100644
@@ -97,7 +97,8 @@
  * network support enabled.
  * Remark: CONFIG_405 describes Xilinx PPC405 FPGA without EMAC controller!
  */
-#if defined(CONFIG_CMD_NET) && !defined(CONFIG_405) && !defined(CONFIG_IOP480)
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_405) && !defined(CONFIG_IOP480) \
+	&& !defined(CONFIG_440_VIRTEX5)
 
 #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
 #error "CONFIG_MII has to be defined!"
cpu/ppc4xx/4xx_uart.c +3 -0
index a7587d4..37d3dbc 100644
@@ -48,6 +48,7 @@
 #include <watchdog.h>
 #include <asm/ppc4xx-intvec.h>
 
+#if !defined(CONFIG_440_VIRTEX5)
 #ifdef CONFIG_SERIAL_MULTI
 #include <serial.h>
 #endif
@@ -873,3 +874,5 @@ int serial_tstc(void)
 #endif /* CONFIG_SERIAL_MULTI */
 
 #endif	/* CONFIG_405GP || CONFIG_405CR */
+
+#endif
cpu/ppc4xx/cpu.c +4 -0
index 39f439d..f510cdd 100644
@@ -508,6 +508,10 @@ int checkcpu (void)
 		puts("GT Rev. A");
 		strcpy(addstr, "Security/Kasumi support");
 		break;
+	
+	case PVR_VIRTEX5:
+		printf(" VIRTEX5");
+		break;
 
 	default:
 		printf (" UNKNOWN (PVR=%08x)", pvr);
cpu/ppc4xx/gpio.c +5 -0
index df99f53..59159ee 100644
@@ -26,6 +26,9 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+
 #if defined(CFG_4xx_GPIO_TABLE)
 gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_4xx_GPIO_TABLE;
 #endif
@@ -253,3 +256,5 @@ void gpio_set_chip_configuration(void)
 	}
 }
 #endif /* CFG_4xx_GPIO_TABLE */
+
+#endif
cpu/ppc4xx/interrupts.c +201 -37

389 lines not on this page · raw message

cpu/ppc4xx/miiphy.c +5 -0
index c882720..172fbcd 100644
@@ -43,6 +43,9 @@
 #include <405_mal.h>
 #include <miiphy.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+
 #if !defined(CONFIG_PHY_CLK_FREQ)
 #define CONFIG_PHY_CLK_FREQ	0
 #endif
@@ -331,3 +334,5 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg,
 {
 	return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
 }
+
+#endif
cpu/ppc4xx/speed.c +5 -1
index 34bd721..d1681e4 100644
@@ -415,7 +415,8 @@ ulong get_PCI_freq (void)
 	return sys_info.freqPCI;
 }
 
-#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
+#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)\
+	&&!defined(CONFIG_440_VIRTEX5)
 void get_sys_info (sys_info_t * sysInfo)
 {
 	unsigned long strp0;
@@ -448,6 +449,8 @@ void get_sys_info (sys_info_t * sysInfo)
 	sysInfo->freqUART = sysInfo->freqPLB;
 }
 #else
+
+#if !defined(CONFIG_440_VIRTEX5)
 void get_sys_info (sys_info_t * sysInfo)
 {
 	unsigned long strp0;
@@ -534,6 +537,7 @@ void get_sys_info (sys_info_t * sysInfo)
 }
 
 #endif
+#endif
 
 #if defined(CONFIG_YUCCA)
 unsigned long determine_sysper(void)
include/asm-ppc/processor.h +1 -2
index 10fd478..88f193a 100644
@@ -827,13 +827,12 @@
 #define PVR_7400	0x000C0000
 #define PVR_7410	0x800C0000
 #define PVR_7450	0x80000000
-
 #define PVR_85xx	0x80200000
 #define PVR_85xx_REV1	(PVR_85xx | 0x0010)
 #define PVR_85xx_REV2	(PVR_85xx | 0x0020)
-
 #define PVR_86xx	0x80040000
 #define PVR_86xx_REV1	(PVR_86xx | 0x0010)
+#define PVR_VIRTEX5     0x7ff21912
 
 /*
  * For the 8xx processors, all of them report the same PVR family for
net/eth.c +2 -1
index 7fc9aee..54b59b8 100644
@@ -621,7 +621,8 @@ int eth_initialize(bd_t *bis)
 	at91rm9200_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) \
-	&& !defined(CONFIG_AP1000) && !defined(CONFIG_405)
+	&& !defined(CONFIG_AP1000) && !defined(CONFIG_405) \
+	&& !defined(CONFIG_440_VIRTEX5)
 	emac4xx_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_MCF52x2)
Signature · 1 line
1.5.6.2
#1 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Some days ago a sent to mailing list patch (currently is in) where I rename CONFIG_XILINX_ML300 -> CONFIG_XILINX_405.

I would like to see if you can use the same style for 440 -> CONFIG_XILINX_440. I have no detail information about ppc440 but IMHO only virtex5 fx (or whatever) support it -> make no sense to me use virtex5 in name.

SR: Do you agree with me?

There is big part of code relate with interrupt controller which is the same with microblaze. This should be handled in the same way. Any suggestion? (Do generic driver?)

M

BTW: some comments in code.

author

This patchs gives support for the embbedded ppc440 on the Virtex5 FPGAs

---
 cpu/ppc4xx/4xx_enet.c       |    3 +-
 cpu/ppc4xx/4xx_uart.c       |    3 +
 cpu/ppc4xx/cpu.c            |    4 +
 cpu/ppc4xx/gpio.c           |    5 +
 cpu/ppc4xx/interrupts.c     |  238 ++++++++++++++++++++++++++++++++++++-------
 cpu/ppc4xx/miiphy.c         |    5 +
 cpu/ppc4xx/speed.c          |    6 +-
 include/asm-ppc/processor.h |    3 +-
 net/eth.c                   |    3 +-
 9 files changed, 228 insertions(+), 42 deletions(-)
cpu/ppc4xx/4xx_enet.c +2 -1
index 4e863dc..cf26237 100644
@@ -97,7 +97,8 @@
  * network support enabled.
  * Remark: CONFIG_405 describes Xilinx PPC405 FPGA without EMAC controller!
  */
-#if defined(CONFIG_CMD_NET) && !defined(CONFIG_405) && !defined(CONFIG_IOP480)
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_405) && !defined(CONFIG_IOP480)
\
+	&& !defined(CONFIG_440_VIRTEX5)
 
 #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
 #error "CONFIG_MII has to be defined!"
cpu/ppc4xx/4xx_uart.c +3 -0
index a7587d4..37d3dbc 100644
@@ -48,6 +48,7 @@
 #include <watchdog.h>
 #include <asm/ppc4xx-intvec.h>
 
+#if !defined(CONFIG_440_VIRTEX5)
 #ifdef CONFIG_SERIAL_MULTI
 #include <serial.h>
 #endif
@@ -873,3 +874,5 @@ int serial_tstc(void)
 #endif /* CONFIG_SERIAL_MULTI */
 
 #endif	/* CONFIG_405GP || CONFIG_405CR */
+
+#endif
cpu/ppc4xx/cpu.c +4 -0
index 39f439d..f510cdd 100644
@@ -508,6 +508,10 @@ int checkcpu (void)
 		puts("GT Rev. A");
 		strcpy(addstr, "Security/Kasumi support");
 		break;
+	
+	case PVR_VIRTEX5:
+		printf(" VIRTEX5");
+		break;
 
 

why you use printf here? puts is enough.

default:
printf (" UNKNOWN (PVR=%08x)", pvr);

cpu/ppc4xx/gpio.c +5 -0
index df99f53..59159ee 100644
@@ -26,6 +26,9 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+
 #if defined(CFG_4xx_GPIO_TABLE)
 gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_4xx_GPIO_TABLE;
 #endif
@@ -253,3 +256,5 @@ void gpio_set_chip_configuration(void)
 	}
 }
 #endif /* CFG_4xx_GPIO_TABLE */
+
+#endif
cpu/ppc4xx/interrupts.c +20 -7
index 8620e2b..4648f52 100644
@@ -8,6 +8,10 @@
  * (C) Copyright 2003 (440GX port)
  * Travis B. Sawyer, Sandburst Corporation, tsawyer at sandburst.com
  *
+ * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX)
+ * Ricardo Ribalda, Universidad Autonoma de Madrid, ricardo.ribalda at uam.es
+ * Work supported by Qtechnology (htpp://qtec.com)
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -41,6 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /*
  * Define the number of UIC's
  */
+#if !defined(CONFIG_440_VIRTEX5)
 #if defined(CONFIG_440SPE) || \
     defined(CONFIG_460EX) || defined(CONFIG_460GT)
 #define UIC_MAX		4
@@ -54,17 +59,23 @@ DECLARE_GLOBAL_DATA_PTR;
 #else
 #define UIC_MAX		1
 #endif
-
+#else
+void xilinx_pic_enable(void);
+#endif
 /*
  * CPM interrupt vector functions.
  */
-struct	irq_action {
+struct irq_action {
 	interrupt_handler_t *handler;
 	void *arg;
 	int count;
 };
 
+#if !defined(CONFIG_440_VIRTEX5)
 static struct irq_action irq_vecs[UIC_MAX * 32];
+#else
+static struct irq_action irq_vecs[XPAR_INTC_MAX_NUM_INTR_INPUTS];
+#endif
 
 u32 get_dcr(u16);
 void set_dcr(u16, u32);
@@ -81,27 +92,25 @@ static __inline__ void set_evpr(unsigned long val)
 	asm volatile("mtspr 0x03f,%0" : : "r" (val));
 }
 
-#else /* !defined(CONFIG_440) */
+#else				/* !defined(CONFIG_440) */
 
 static __inline__ void set_pit(unsigned long val)
 {
 	asm volatile("mtpit %0" : : "r" (val));
 }
 
-
 static __inline__ void set_tcr(unsigned long val)
 {
 	asm volatile("mttcr %0" : : "r" (val));
 }
 
-
 static __inline__ void set_evpr(unsigned long val)
 {
 	asm volatile("mtevpr %0" : : "r" (val));
 }
-#endif /* defined(CONFIG_440 */
+#endif				/* defined(CONFIG_440 */
 
-int interrupt_init_cpu (unsigned *decrementer_count)
+int interrupt_init_cpu(unsigned *decrementer_count)
 {
 	int vec;
 	unsigned long val;
@@ -112,7 +121,11 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	/*
 	 * Mark all irqs as free
 	 */
+#if !defined (CONFIG_440_VIRTEX5)
 	for (vec = 0; vec < (UIC_MAX * 32); vec++) {
+#else
+	for (vec = 0; vec < XPAR_INTC_MAX_NUM_INTR_INPUTS; vec++) {
+#endif
 

:-( no use this loooooooooooooong value which comes from generated xparameters.h. SR:Am I understand correctly that 405 or 440 use 32 bits (64...) wide interrupt controllers?

irq_vecs[vec].handler = NULL; irq_vecs[vec].arg = NULL;
irq_vecs[vec].count = 0;
@@ -123,19 +136,19 @@ int interrupt_init_cpu (unsigned *decrementer_count)
* Init PIT
*/
#if defined(CONFIG_440)
- val = mfspr( tcr );
- val &= (~0x04400000); /* clear DIS & ARE */
- mtspr( tcr, val );
- mtspr( dec, 0 ); /* Prevent exception after TSR clear*/
- mtspr( decar, 0 ); /* clear reload */
- mtspr( tsr, 0x08000000 ); /* clear DEC status */
- val = gd->bd->bi_intfreq/1000; /* 1 msec */
- mtspr( decar, val ); /* Set auto-reload value */
- mtspr( dec, val ); /* Set inital val */
+ val = mfspr(tcr);
+ val &= (~0x04400000); /* clear DIS & ARE */
+ mtspr(tcr, val);
+ mtspr(dec, 0); /* Prevent exception after TSR clear */
+ mtspr(decar, 0); /* clear reload */
+ mtspr(tsr, 0x08000000); /* clear DEC status */
+ val = gd->bd->bi_intfreq / 1000; /* 1 msec */
+ mtspr(decar, val); /* Set auto-reload value */
+ mtspr(dec, val); /* Set inital val */
#else
set_pit(gd->bd->bi_intfreq / 1000);
#endif
-#endif /* CONFIG_4xx */
+#endif /* CONFIG_4xx */

IMHO coding style issue

#ifdef CONFIG_ADCIOP
/*
@@ -156,6 +169,8 @@ int interrupt_init_cpu (unsigned *decrementer_count)
*/
set_evpr(0x00000000);

+#if !defined (CONFIG_440_VIRTEX5)
+
#if !defined(CONFIG_440GX)
#if (UIC_MAX > 1)
/* Install the UIC1 handlers */
@@ -170,7 +185,7 @@ int interrupt_init_cpu (unsigned *decrementer_count)
irq_install_handler(VECNUM_UIC3NC, uic_cascade_interrupt, 0); irq_install_handler(VECNUM_UIC3C, uic_cascade_interrupt, 0);
#endif
-#else /* !defined(CONFIG_440GX) */
+#else /* !defined(CONFIG_440GX) */

coding style

/* Take the GX out of compatibility mode
* Travis Sawyer, 9 Mar 2004
* NOTE: 440gx user manual inconsistency here
@@ -179,18 +194,27 @@ int interrupt_init_cpu (unsigned *decrementer_count)
*/
mfsdr(sdr_mfr, val);
val &= ~0x10000000;
- mtsdr(sdr_mfr,val);
+ mtsdr(sdr_mfr, val);

/* Enable UIC interrupts via UIC Base Enable Register */ mtdcr(uicb0sr, UICB0_ALL);
mtdcr(uicb0er, 0x54000000);
/* None are critical */
mtdcr(uicb0cr, 0);
-#endif /* !defined(CONFIG_440GX) */
+#endif /* !defined(CONFIG_440GX) */

coding style

+
+#else
+ /*
+ * Enable xilinx pic
+ */
+ xilinx_pic_enable();

so big comment

+#endif

return (0);
}

+#if !defined(CONFIG_440_VIRTEX5)
/* Handler for UIC interrupt */
static void uic_interrupt(u32 uic_base, int vec_base)
{
@@ -214,7 +238,7 @@ static void uic_interrupt(u32 uic_base, int vec_base)

if (irq_vecs[vec].handler != NULL) {
/* call isr */
- (*irq_vecs[vec].handler)(irq_vecs[vec].arg);
+ (*irq_vecs[vec].handler) (irq_vecs[vec].arg);
} else {
set_dcr(uic_base + UIC_ER,
get_dcr(uic_base + UIC_ER) &
@@ -227,7 +251,8 @@ static void uic_interrupt(u32 uic_base, int vec_base)
* After servicing the interrupt, we have to remove the
* status indicator
*/
- set_dcr(uic_base + UIC_SR, (0x80000000 >> (vec & 0x1f)));
+ set_dcr(uic_base + UIC_SR,
+ (0x80000000 >> (vec & 0x1f)));
}

/*
@@ -254,10 +279,10 @@ static void uic_cascade_interrupt(void *para)
#define UIC_BMSR uic0msr
#define UIC_BSR uic0sr
#endif
-#else /* CONFIG_440 */
+#else /* CONFIG_440 */

CS

#define UIC_BMSR uicmsr
#define UIC_BSR uicsr
-#endif /* CONFIG_440 */
+#endif /* CONFIG_440 */

CS

/*
* Handle external interrupts
@@ -294,9 +319,9 @@ void external_interrupt(struct pt_regs *regs)
if ((UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr))
uic_interrupt(UIC0_DCR_BASE, 0);
#endif
-#else /* CONFIG_440 */
+#else /* CONFIG_440 */
uic_interrupt(UIC0_DCR_BASE, 0);
-#endif /* CONFIG_440 */
+#endif /* CONFIG_440 */

mtdcr(UIC_BSR, uic_msr);

@@ -313,7 +338,8 @@ void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
/*
* Print warning when replacing with a different irq vector */
- if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler != 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);
}
@@ -339,7 +365,7 @@ void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
debug("Install interrupt for vector %d ==> %p\n", vec, handler);
}

-void irq_free_handler (int vec)
+void irq_free_handler(int vec)
{
int i;

@@ -365,28 +391,166 @@ void irq_free_handler (int vec)
irq_vecs[vec].handler = NULL; irq_vecs[vec].arg = NULL;
}
+#else
+
+#define intc XPAR_INTC_0_BASEADDR
+#define ISR (0*4) /* Interrupt Status Register */
+#define IPR (1*4) /* Interrupt Pending Register */
+#define IER (2*4) /* Interrupt Enable Register */
+#define IAR (3*4) /* Interrupt Acknowledge Register */
+#define SIE (4*4) /* Set Interrupt Enable bits */
+#define CIE (5*4) /* Clear Interrupt Enable bits */
+#define IVR (6*4) /* Interrupt Vector Register */
+#define MER (7*4) /* Master Enable Register */

these look weird to me - have defines value in the middle of source code -> maybe header.

this looks like duplication with MB where I use interrupt controller.

+#define intc_out_be32(addr, mask) out32((addr), (mask))
+#define intc_in_be32(addr) in32((addr))
+
+void xilinx_pic_enable(void)
+{
+
+ printf("Xilinx PIC at 0x%8x\n", intc);
+
+ /*
+ * Disable all external interrupts until they are
+ * explicitly requested.
+ */
+ intc_out_be32(intc + IER, 0);
+
+ /* Acknowledge any pending interrupts just in case. */
+ intc_out_be32(intc + IAR, ~(u32) 0);
+
+ /* Turn on the Master Enable. */
+ intc_out_be32(intc + MER, 0x3UL);
+
+ return;
+
+}
+
+int xilinx_pic_irq_get(void)
+{
+ u32 irq;
+ irq = intc_in_be32(intc + IVR);
+
+ /* If no interrupt is pending then all bits of the IVR are set to 1. As
+ * the IVR is as many bits wide as numbers of inputs are available.
+ * Therefore, if all bits of the IVR are set to one, its content will
+ * be bigger than XPAR_INTC_MAX_NUM_INTR_INPUTS.
+ */
+ if (irq >= XPAR_INTC_MAX_NUM_INTR_INPUTS)
+ irq = -1; /* report no pending interrupt. */
+
+ debug("get_irq: %d\n", irq);
+ return (irq);
+}
+
+static void xilinx_pic_irq_enable(unsigned int irq)
+{
+ unsigned long mask = (0x00000001 << (irq & 31));
+ debug("enable: %d\n", irq);
+ intc_out_be32(intc + SIE, mask);
+}
+
+static void xilinx_pic_irq_disable(unsigned int irq)
+{
+ unsigned long mask = (0x00000001 << (irq & 31));
+ debug("disable: %d\n", irq);
+ intc_out_be32(intc + CIE, mask);
+}
+
+static void xilinx_pic_irq_ack(unsigned int irq)
+{
+ unsigned long mask = (0x00000001 << (irq & 31));
+ debug("ack: %d\n", irq);
+ intc_out_be32(intc + IAR, mask);
+}
+
+static void xilinx_pic_interrupt(void)
+{
+ int irq;
+
+ irq = xilinx_pic_irq_get();
+ if (irq < 0)
+ return;
+
+ irq_vecs[irq].count++;
+
+ if (irq_vecs[irq].handler != NULL) {
+ /* call isr */
+ (*irq_vecs[irq].handler) (irq_vecs[irq].arg);
+
+ } else {
+ xilinx_pic_irq_disable(irq);
+ printf("Masking bogus interrupt %d\n", irq);
+ }
+
+ xilinx_pic_irq_ack(irq);
+ return;
+}
+
+void external_interrupt(struct pt_regs *regs)
+{
+ xilinx_pic_interrupt();
+}
+
+/*
+ * Install and free a interrupt handler.
+ */
+void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg) +{
+ /*
+ * Print warning when replacing with a different irq vector
+ */
+ 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);
+ }
+ irq_vecs[vec].handler = handler;
+ irq_vecs[vec].arg = arg;
+
+ xilinx_pic_irq_enable(vec);
+
+ debug("Install interrupt for vector %d ==> %p\n", vec, handler);
+}
+
+void irq_free_handler(int vec)
+{
+ debug("Free interrupt for vector %d ==> %p\n",
+ vec, irq_vecs[vec].handler);
+
+ xilinx_pic_irq_disable(vec);
+
+ irq_vecs[vec].handler = NULL;
+ irq_vecs[vec].arg = NULL;
+}
+
+#endif

-void timer_interrupt_cpu (struct pt_regs *regs)
+void timer_interrupt_cpu(struct pt_regs *regs)
{
/* nothing to do here */
return;
}

#if defined(CONFIG_CMD_IRQ)
-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 ("Interrupt-Information:\n");
- printf ("Nr Routine Arg Count\n");
+ printf("Interrupt-Information:\n");
+ printf("Nr Routine Arg Count\n");

+#if !defined (CONFIG_440_VIRTEX5)
for (vec = 0; vec < (UIC_MAX * 32); vec++) {
+#else
+ for (vec = 0; vec < XPAR_INTC_MAX_NUM_INTR_INPUTS; vec++) {
+#endif
if (irq_vecs[vec].handler != NULL) {
- printf ("%02d %08lx %08lx %d\n",
- vec,
- (ulong)irq_vecs[vec].handler,
- (ulong)irq_vecs[vec].arg,
- irq_vecs[vec].count);
+ printf("%02d %08lx %08lx %d\n",

+			       vec,
+			       (ulong) irq_vecs[vec].handler,
+			       (ulong) irq_vecs[vec].arg, irq_vecs[vec].count);

}
}

cpu/ppc4xx/miiphy.c +3 -0
index c882720..172fbcd 100644
@@ -43,6 +43,9 @@
 #include <405_mal.h>
 #include <miiphy.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+
 #if !defined(CONFIG_PHY_CLK_FREQ)
 #define CONFIG_PHY_CLK_FREQ	0
 #endif
@@ -331,3 +334,5 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,

unsigned char reg,
{
return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
}
+
+#endif

cpu/ppc4xx/speed.c +0 -1
index 34bd721..d1681e4 100644
@@ -415,7 +415,8 @@ ulong get_PCI_freq (void)
 	return sys_info.freqPCI;
 }
 
-#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) &&

!defined(CONFIG_440SPE)
+#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)\
+ &&!defined(CONFIG_440_VIRTEX5)
void get_sys_info (sys_info_t * sysInfo)
{
unsigned long strp0;
@@ -448,6 +449,8 @@ void get_sys_info (sys_info_t * sysInfo)
sysInfo->freqUART = sysInfo->freqPLB;
}
#else
+
+#if !defined(CONFIG_440_VIRTEX5)
void get_sys_info (sys_info_t * sysInfo)
{
unsigned long strp0;
@@ -534,6 +537,7 @@ void get_sys_info (sys_info_t * sysInfo)
}

#endif
+#endif

#if defined(CONFIG_YUCCA)
unsigned long determine_sysper(void)

include/asm-ppc/processor.h +1 -2
index 10fd478..88f193a 100644
@@ -827,13 +827,12 @@
 #define PVR_7400	0x000C0000
 #define PVR_7410	0x800C0000
 #define PVR_7450	0x80000000
-
 #define PVR_85xx	0x80200000
 #define PVR_85xx_REV1	(PVR_85xx | 0x0010)
 #define PVR_85xx_REV2	(PVR_85xx | 0x0020)
-
 #define PVR_86xx	0x80040000
 #define PVR_86xx_REV1	(PVR_86xx | 0x0010)
+#define PVR_VIRTEX5     0x7ff21912
 
 /*
  * For the 8xx processors, all of them report the same PVR family for
net/eth.c +2 -1
index 7fc9aee..54b59b8 100644
@@ -621,7 +621,8 @@ int eth_initialize(bd_t *bis)
 	at91rm9200_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) \
-	&& !defined(CONFIG_AP1000) && !defined(CONFIG_405)
+	&& !defined(CONFIG_AP1000) && !defined(CONFIG_405) \
+	&& !defined(CONFIG_440_VIRTEX5)
 	emac4xx_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_MCF52x2)
Signature · 13 lines
1.5.6.2


-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
U-Boot-Users mailing list

U-Boot-Users at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/u-boot-users
#2 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Quoted 9 lines · Michal Simek

Some days ago a sent to mailing list patch (currently is in) where I rename CONFIG_XILINX_ML300 -> CONFIG_XILINX_405.

I would like to see if you can use the same style for 440 -> CONFIG_XILINX_440. I have no detail information about ppc440 but IMHO only virtex5 fx (or whatever) support it -> make no sense to me use virtex5 in name.

SR: Do you agree with me?

Yes, renaming this to CONFIG_XILINX_440 is a good idea.

Quoted 3 lines

There is big part of code relate with interrupt controller which is the same with microblaze. This should be handled in the same way. Any suggestion? (Do generic driver?)

Yes, I already mentioned in my review, that this code should go into a separate file. If the microblaze implementation is the same or very similar then please use the same code here and move to to a common directory. Perhaps:

drivers/interrupt/xilinx.c ?

Comments?

Quoted 3 lines

M

BTW: some comments in code.

Michal, your comments are very hard to spot since you don't quote the original code by "> ".

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
=====================================================================

#3 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Hello Stefan

Quoted 1 line

Yes, renaming this to CONFIG_XILINX_440 is a good idea.

I will rename it and resend

Quoted 8 lines

Yes, I already mentioned in my review, that this code should go into a separate file. If the microblaze implementation is the same or very similar then please use the same code here and move to to a common directory. Perhaps:

drivers/interrupt/xilinx.c ?

Comments?

Completely with you. I can create a generic driver if you would like.

Best Regards

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/
#4 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

In reply to Stefan Roese

Hi Stefan,

Quoted 11 lines
Quoted 9 lines

Some days ago a sent to mailing list patch (currently is in) where I rename CONFIG_XILINX_ML300 -> CONFIG_XILINX_405.

I would like to see if you can use the same style for 440 -> CONFIG_XILINX_440. I have no detail information about ppc440 but IMHO only virtex5 fx (or whatever) support it -> make no sense to me use virtex5 in name.

SR: Do you agree with me?

Yes, renaming this to CONFIG_XILINX_440 is a good idea.

nice to hear.

Quoted 4 lines
Quoted 3 lines

There is big part of code relate with interrupt controller which is the same with microblaze. This should be handled in the same way. Any suggestion? (Do generic driver?)

Quoted 8 lines

Yes, I already mentioned in my review, that this code should go into a separate file. If the microblaze implementation is the same or very similar then please use the same code here and move to to a common directory. Perhaps:

drivers/interrupt/xilinx.c ?

Comments?

1. use macros names which are in microblaze xparameters.h. These values are generate by u-boot BSP. Add ppc440 to it solves your problem with generic boards.
2. I don't know if is good idea to create drivers for interrupt controllers. If yes xilinx_intc.c, will be better.
I will wait for WD comments.

Quoted 5 lines
Quoted 2 lines

BTW: some comments in code.

Michal, your comments are very hard to spot since you don't quote the original code by "> ".

I used web based email which is ...

Michal

Quoted 9 lines

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
=====================================================================

#5 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

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

2. I don't know if is good idea to create drivers for interrupt controllers.

I have to admit that such an idea surprises me a bit.

Quoted 2 lines

If yes xilinx_intc.c, will be better.
I will wait for WD comments.

In my opinion an interrupt controller is fundamentally different from an device that is handled by a device driver. It therefore has no place in the drivers/ directory.

Best regards,

Wolfgang Denk

Signature · 4 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
Horses just naturally have mohawk haircuts.
#6 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

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

2. I don't know if is good idea to create drivers for interrupt controllers.

Quoted 8 lines

I have to admit that such an idea surprises me a bit.

Quoted 2 lines

If yes xilinx_intc.c, will be better.
I will wait for WD comments.

In my opinion an interrupt controller is fundamentally different from an device that is handled by a device driver. It therefore has no place in the drivers/ directory.

Yes, I was hesitating here too. Only other idea that comes to my mind is:

cpu/xilinx/interrupt.c

Better?

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
=====================================================================

#7 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Quoted 11 lines
Quoted 10 lines
Quoted 2 lines · In message <[email protected]> you wrote:

2. I don't know if is good idea to create drivers for interrupt controllers.

I have to admit that such an idea surprises me a bit.

Quoted 2 lines

If yes xilinx_intc.c, will be better.
I will wait for WD comments.

In my opinion an interrupt controller is fundamentally different from an device that is handled by a device driver. It therefore has no place in the drivers/ directory.

Quoted 6 lines

Yes, I was hesitating here too. Only other idea that comes to my mind is:

cpu/xilinx/interrupt.c

Better?

xilinx is not type of cpu. :-( I'll think about smarter way.

Best regards,
Michal

Quoted 15 lines

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
=====================================================================

No virus found in this incoming message.
Checked by AVG - http://www.avg.com
Version: 8.0.138 / Virus Database: 270.4.7/1545 - Release Date: 10.7.2008 06:43

#8 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

In reply to Michal Simek

Hi Michal

I am trying to solve the xilinx irq.... I have some questions:

1) Where can I find the official u-boot bsp for edk?
http://git.monstr.eu/ is dead
2) Do we really need a new bsp for this? Can't we just use the
Linux_2_6. I just need a couple of definitions...

Best Regards

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/
#9 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Hi Ricardo,

Quoted 6 lines

Hi Michal

I am trying to solve the xilinx irq.... I have some questions:

1) Where can I find the official u-boot bsp for edk?
http://git.monstr.eu/ is dead

yes. git.monstr.eu was temporary down because I was changing my servers. currently is server up.

Quoted 2 lines

2) Do we really need a new bsp for this? Can't we just use the
Linux_2_6. I just need a couple of definitions...

No. we don't need new BSP for this. The BSP exists more than year.
http://git.monstr.eu/cgi-bin/gitweb.cgi?p=u-boot-bsp.git;a=summary
and description is at:
http://www.monstr.eu/wiki/doku.php?id=uboot:uboot

Could you send me your mhs and mss file? I'll add it to u-boot bsp and I send you bsp and output.

Thanks,
Michal

Quoted 10 lines

Best Regards

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/
#10 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

In reply to Michal Simek

Hello Stefan

If everyone agrees I can change the naming, no big problem there.

Quoted 4 lines

I would like to see if you can use the same style for 440 -> CONFIG_XILINX_440. I have no detail information about ppc440 but IMHO only virtex5 fx (or whatever) support it -> make no sense to me use virtex5 in name.

Quoted 8 lines

SR: Do you agree with me?

There is big part of code relate with interrupt controller which is the same with microblaze. This should be handled in the same way. Any suggestion? (Do generic driver?)

I will suggest the creation of a new directory /drivers/interrupt/

And locate there the pic drivers

Quoted 3 lines

:-( no use this loooooooooooooong value which comes from generated xparameters.h. SR:Am I understand correctly that 405 or 440 use 32 bits (64...) wide interrupt controllers?

I prefer using the xparameters.h values. IMO this helps the creation of the u-boot for a board

Best regards and thanks for the comments

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/
#11 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

In reply to Ricardo Ribalda Delgado

Ricardo,

Quoted 2 lines · Ricardo Ribalda Delgado

This patchs gives support for the embbedded ppc440 on the Virtex5 FPGAs

Thanks.

Some general comments:

Please rebase your 4xx related patches on the "next" branch of my u-boot-ppc4xx repository. I just pushed some bigger rework/cleanup patchsets that are destined for the next merge window.

And please add "ppc4xx: " to the beginning of the patch subject and add me to CC on 4xx related patches.

More comments below...

Quoted 33 lines
---
 cpu/ppc4xx/4xx_enet.c       |    3 +-
 cpu/ppc4xx/4xx_uart.c       |    3 +
 cpu/ppc4xx/cpu.c            |    4 +
 cpu/ppc4xx/gpio.c           |    5 +
 cpu/ppc4xx/interrupts.c     |  238
++++++++++++++++++++++++++++++++++++------- cpu/ppc4xx/miiphy.c         |  
 5 +
 cpu/ppc4xx/speed.c          |    6 +-
 include/asm-ppc/processor.h |    3 +-
 net/eth.c                   |    3 +-
 9 files changed, 228 insertions(+), 42 deletions(-)
cpu/ppc4xx/4xx_enet.c +0 -0
index 4e863dc..cf26237 100644
@@ -97,7 +97,8 @@
  * network support enabled.
  * Remark: CONFIG_405 describes Xilinx PPC405 FPGA without EMAC

controller! */
-#if defined(CONFIG_CMD_NET) && !defined(CONFIG_405) && !defined(CONFIG_IOP480) +#if defined(CONFIG_CMD_NET) &&
!defined(CONFIG_405) && !defined(CONFIG_IOP480) \ + &&
!defined(CONFIG_440_VIRTEX5)

#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) #error "CONFIG_MII has to be defined!"

cpu/ppc4xx/4xx_uart.c +0 -0
index a7587d4..37d3dbc 100644

cpu/ppc4xx/4xx_uart.c line 51

Quoted 4 lines
cpu/ppc4xx/4xx_uart.c +1 -0
@@ -48,6 +48,7 @@
 #include <watchdog.h>
 #include <asm/ppc4xx-intvec.h>
 
+#if !defined(CONFIG_440_VIRTEX5)

You add this "#if !defined(CONFIG_440_VIRTEX5)" to many of the cpu/ppc4xx files with this patch. I don't like this. We should let the Makefile handle this. Perhaps something like this:

ifndef $(CONFIG_440_VIRTEX5)
COBJS += 4xx_enet.o
...
endif

Quoted 29 lines
cpu/ppc4xx/4xx_uart.c +2 -0
 #ifdef CONFIG_SERIAL_MULTI
 #include <serial.h>
 #endif
@@ -873,3 +874,5 @@ int serial_tstc(void)
 #endif /* CONFIG_SERIAL_MULTI */
 
 #endif	/* CONFIG_405GP || CONFIG_405CR */
+
+#endif
cpu/ppc4xx/cpu.c +4 -0
index 39f439d..f510cdd 100644
@@ -508,6 +508,10 @@ int checkcpu (void)
 		puts("GT Rev. A");
 		strcpy(addstr, "Security/Kasumi support");
 		break;
+
+	case PVR_VIRTEX5:
+		printf(" VIRTEX5");
+		break;
 
 	default:
 		printf (" UNKNOWN (PVR=%08x)", pvr);
cpu/ppc4xx/gpio.c +0 -0
index df99f53..59159ee 100644

cpu/ppc4xx/gpio.c line 31

Quoted 6 lines
cpu/ppc4xx/gpio.c +3 -0
@@ -26,6 +26,9 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+

Again, move this to the Makefile instead.

Quoted 35 lines
cpu/ppc4xx/gpio.c +0 -0
 #if defined(CFG_4xx_GPIO_TABLE)
 gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] =

CFG_4xx_GPIO_TABLE; #endif

cpu/ppc4xx/gpio.c +2 -0
@@ -253,3 +256,5 @@ void gpio_set_chip_configuration(void)
 	}
 }
 #endif /* CFG_4xx_GPIO_TABLE */
+
+#endif
cpu/ppc4xx/interrupts.c +5 -0
index 8620e2b..4648f52 100644
@@ -8,6 +8,10 @@
  * (C) Copyright 2003 (440GX port)
  * Travis B. Sawyer, Sandburst Corporation, tsawyer at sandburst.com
  *
+ * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX)
+ * Ricardo Ribalda, Universidad Autonoma de Madrid, ricardo.ribalda at uam.es
+ * Work supported by Qtechnology (htpp://qtec.com)
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -41,6 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /*
  * Define the number of UIC's
  */
+#if !defined(CONFIG_440_VIRTEX5)
 #if defined(CONFIG_440SPE) || \
     defined(CONFIG_460EX) || defined(CONFIG_460GT)
 #define UIC_MAX		4
@@ -54,17 +59,23 @@ DECLARE_GLOBAL_DATA_PTR;
 #else
 #define UIC_MAX		1

cpu/ppc4xx/interrupts.c DECLARE_GLOBAL_DATA_PTR; · line 68

Quoted 10 lines
cpu/ppc4xx/interrupts.c +4 -2
 #endif
-
+#else
+void xilinx_pic_enable(void);
+#endif
 /*
  * CPM interrupt vector functions.
  */
-struct	irq_action {
+struct irq_action {

You seem to have run Lindent on this file too, correct? Please don't do this when you also add and/or fix something. This makes it hard to see the "real" changes. Only run Lindent on newly created files.

Quoted 202 lines
cpu/ppc4xx/interrupts.c +42 -24
 	interrupt_handler_t *handler;
 	void *arg;
 	int count;
 };
 
+#if !defined(CONFIG_440_VIRTEX5)
 static struct irq_action irq_vecs[UIC_MAX * 32];
+#else
+static struct irq_action irq_vecs[XPAR_INTC_MAX_NUM_INTR_INPUTS];
+#endif
 
 u32 get_dcr(u16);
 void set_dcr(u16, u32);
@@ -81,27 +92,25 @@ static __inline__ void set_evpr(unsigned long val)
 	asm volatile("mtspr 0x03f,%0" : : "r" (val));
 }
 
-#else /* !defined(CONFIG_440) */
+#else				/* !defined(CONFIG_440) */
 
 static __inline__ void set_pit(unsigned long val)
 {
 	asm volatile("mtpit %0" : : "r" (val));
 }
 
-
 static __inline__ void set_tcr(unsigned long val)
 {
 	asm volatile("mttcr %0" : : "r" (val));
 }
 
-
 static __inline__ void set_evpr(unsigned long val)
 {
 	asm volatile("mtevpr %0" : : "r" (val));
 }
-#endif /* defined(CONFIG_440 */
+#endif				/* defined(CONFIG_440 */
 
-int interrupt_init_cpu (unsigned *decrementer_count)
+int interrupt_init_cpu(unsigned *decrementer_count)
 {
 	int vec;
 	unsigned long val;
@@ -112,7 +121,11 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	/*
 	 * Mark all irqs as free
 	 */
+#if !defined (CONFIG_440_VIRTEX5)
 	for (vec = 0; vec < (UIC_MAX * 32); vec++) {
+#else
+	for (vec = 0; vec < XPAR_INTC_MAX_NUM_INTR_INPUTS; vec++) {
+#endif
 		irq_vecs[vec].handler = NULL;
 		irq_vecs[vec].arg = NULL;
 		irq_vecs[vec].count = 0;
@@ -123,19 +136,19 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	 * Init PIT
 	 */
 #if defined(CONFIG_440)
-	val = mfspr( tcr );
-	val &= (~0x04400000);		/* clear DIS & ARE */
-	mtspr( tcr, val );
-	mtspr( dec, 0 );		/* Prevent exception after TSR clear*/
-	mtspr( decar, 0 );		/* clear reload */
-	mtspr( tsr, 0x08000000 );	/* clear DEC status */
-	val = gd->bd->bi_intfreq/1000;	/* 1 msec */
-	mtspr( decar, val );		/* Set auto-reload value */
-	mtspr( dec, val );		/* Set inital val */
+	val = mfspr(tcr);
+	val &= (~0x04400000);	/* clear DIS & ARE */
+	mtspr(tcr, val);
+	mtspr(dec, 0);		/* Prevent exception after TSR clear */
+	mtspr(decar, 0);	/* clear reload */
+	mtspr(tsr, 0x08000000);	/* clear DEC status */
+	val = gd->bd->bi_intfreq / 1000;	/* 1 msec */
+	mtspr(decar, val);	/* Set auto-reload value */
+	mtspr(dec, val);	/* Set inital val */
 #else
 	set_pit(gd->bd->bi_intfreq / 1000);
 #endif
-#endif  /* CONFIG_4xx */
+#endif				/* CONFIG_4xx */
 
 #ifdef CONFIG_ADCIOP
 	/*
@@ -156,6 +169,8 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	 */
 	set_evpr(0x00000000);
 
+#if !defined (CONFIG_440_VIRTEX5)
+
 #if !defined(CONFIG_440GX)
 #if (UIC_MAX > 1)
 	/* Install the UIC1 handlers */
@@ -170,7 +185,7 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	irq_install_handler(VECNUM_UIC3NC, uic_cascade_interrupt, 0);
 	irq_install_handler(VECNUM_UIC3C, uic_cascade_interrupt, 0);
 #endif
-#else /* !defined(CONFIG_440GX) */
+#else				/* !defined(CONFIG_440GX) */
 	/* Take the GX out of compatibility mode
 	 * Travis Sawyer, 9 Mar 2004
 	 * NOTE: 440gx user manual inconsistency here
@@ -179,18 +194,27 @@ int interrupt_init_cpu (unsigned *decrementer_count)
 	 */
 	mfsdr(sdr_mfr, val);
 	val &= ~0x10000000;
-	mtsdr(sdr_mfr,val);
+	mtsdr(sdr_mfr, val);
 
 	/* Enable UIC interrupts via UIC Base Enable Register */
 	mtdcr(uicb0sr, UICB0_ALL);
 	mtdcr(uicb0er, 0x54000000);
 	/* None are critical */
 	mtdcr(uicb0cr, 0);
-#endif /* !defined(CONFIG_440GX) */
+#endif				/* !defined(CONFIG_440GX) */
+
+#else
+	/*
+	 * Enable xilinx pic
+	 */
+	xilinx_pic_enable();
+
+#endif
 
 	return (0);
 }
 
+#if !defined(CONFIG_440_VIRTEX5)
 /* Handler for UIC interrupt */
 static void uic_interrupt(u32 uic_base, int vec_base)
 {
@@ -214,7 +238,7 @@ static void uic_interrupt(u32 uic_base, int vec_base)
 
 			if (irq_vecs[vec].handler != NULL) {
 				/* call isr */
-				(*irq_vecs[vec].handler)(irq_vecs[vec].arg);
+				(*irq_vecs[vec].handler) (irq_vecs[vec].arg);
 			} else {
 				set_dcr(uic_base + UIC_ER,
 					get_dcr(uic_base + UIC_ER) &
@@ -227,7 +251,8 @@ static void uic_interrupt(u32 uic_base, int vec_base)
 			 * After servicing the interrupt, we have to remove the
 			 * status indicator
 			 */
-			set_dcr(uic_base + UIC_SR, (0x80000000 >> (vec & 0x1f)));
+			set_dcr(uic_base + UIC_SR,
+				(0x80000000 >> (vec & 0x1f)));
 		}
 
 		/*
@@ -254,10 +279,10 @@ static void uic_cascade_interrupt(void *para)
 #define UIC_BMSR	uic0msr
 #define UIC_BSR		uic0sr
 #endif
-#else /* CONFIG_440 */
+#else				/* CONFIG_440 */
 #define UIC_BMSR	uicmsr
 #define UIC_BSR		uicsr
-#endif /* CONFIG_440 */
+#endif				/* CONFIG_440 */
 
 /*
  * Handle external interrupts
@@ -294,9 +319,9 @@ void external_interrupt(struct pt_regs *regs)
 	if ((UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr))
 		uic_interrupt(UIC0_DCR_BASE, 0);
 #endif
-#else /* CONFIG_440 */
+#else				/* CONFIG_440 */
 	uic_interrupt(UIC0_DCR_BASE, 0);
-#endif /* CONFIG_440 */
+#endif				/* CONFIG_440 */
 
 	mtdcr(UIC_BSR, uic_msr);
 
@@ -313,7 +338,8 @@ void irq_install_handler(int vec, interrupt_handler_t *

handler, void *arg) /*

cpu/ppc4xx/interrupts.c +0 -1
 	 * Print warning when replacing with a different irq vector
 	 */
-	if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler !=

handler)) { + if ((irq_vecs[vec].handler != NULL)

cpu/ppc4xx/interrupts.c +3 -1
+	    && (irq_vecs[vec].handler != handler)) {
 		printf("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
 		       vec, (uint) handler, (uint) irq_vecs[vec].handler);
 	}
@@ -339,7 +365,7 @@ void irq_install_handler(int vec, interrupt_handler_t *
 handler, void *arg) debug("Install interrupt for vector %d ==> %p\n", vec,
 handler); }
 
-void irq_free_handler (int vec)
+void irq_free_handler(int vec)
 {
 	int i;
 
@@ -365,28 +391,166 @@ void irq_free_handler (int vec)
 	irq_vecs[vec].handler = NULL;
 	irq_vecs[vec].arg = NULL;
 }
+#else

cpu/ppc4xx/interrupts.c void irq_free_handler (int vec) · line 404

Quoted 10 lines
cpu/ppc4xx/interrupts.c +10 -0
+
+#define intc    XPAR_INTC_0_BASEADDR
+#define ISR (0*4)		/* Interrupt Status Register */
+#define IPR (1*4)		/* Interrupt Pending Register */
+#define IER (2*4)		/* Interrupt Enable Register */
+#define IAR (3*4)		/* Interrupt Acknowledge Register */
+#define SIE (4*4)		/* Set Interrupt Enable bits */
+#define CIE (5*4)		/* Clear Interrupt Enable bits */
+#define IVR (6*4)		/* Interrupt Vector Register */
+#define MER (7*4)		/* Master Enable Register */

This seems to be a completely different interrupt handler than used on IBM/AMCC PPC4xx. Please don't add this code to this file but to a new file. Does this Xilinx interrupt controller have a name? I'll probably rename the current interrupt.c to uic.c soon.

cpu/ppc4xx/interrupts.c void irq_free_handler (int vec) · line 407

Quoted 2 lines
cpu/ppc4xx/interrupts.c +2 -0
+#define intc_out_be32(addr, mask)     out32((addr), (mask))
+#define intc_in_be32(addr)            in32((addr))

Please don't define new accessor macros here. Use the existing ones, this makes the code better readable.

And use out_be32()/in_be32() instead of out32()/in32().

Quoted 162 lines
cpu/ppc4xx/interrupts.c +131 -9
+void xilinx_pic_enable(void)
+{
+
+	printf("Xilinx PIC at 0x%8x\n", intc);
+
+	/*
+	 * Disable all external interrupts until they are
+	 * explicitly requested.
+	 */
+	intc_out_be32(intc + IER, 0);
+
+	/* Acknowledge any pending interrupts just in case. */
+	intc_out_be32(intc + IAR, ~(u32) 0);
+
+	/* Turn on the Master Enable. */
+	intc_out_be32(intc + MER, 0x3UL);
+
+	return;
+
+}
+
+int xilinx_pic_irq_get(void)
+{
+	u32 irq;
+	irq = intc_in_be32(intc + IVR);
+
+	/* If no interrupt is pending then all bits of the IVR are set to 1. As
+	 * the IVR is as many bits wide as numbers of inputs are available.
+	 * Therefore, if all bits of the IVR are set to one, its content will
+	 * be bigger than XPAR_INTC_MAX_NUM_INTR_INPUTS.
+	 */
+	if (irq >= XPAR_INTC_MAX_NUM_INTR_INPUTS)
+		irq = -1;	/* report no pending interrupt. */
+
+	debug("get_irq: %d\n", irq);
+	return (irq);
+}
+
+static void xilinx_pic_irq_enable(unsigned int irq)
+{
+	unsigned long mask = (0x00000001 << (irq & 31));
+	debug("enable: %d\n", irq);
+	intc_out_be32(intc + SIE, mask);
+}
+
+static void xilinx_pic_irq_disable(unsigned int irq)
+{
+	unsigned long mask = (0x00000001 << (irq & 31));
+	debug("disable: %d\n", irq);
+	intc_out_be32(intc + CIE, mask);
+}
+
+static void xilinx_pic_irq_ack(unsigned int irq)
+{
+	unsigned long mask = (0x00000001 << (irq & 31));
+	debug("ack: %d\n", irq);
+	intc_out_be32(intc + IAR, mask);
+}
+
+static void xilinx_pic_interrupt(void)
+{
+	int irq;
+
+	irq = xilinx_pic_irq_get();
+	if (irq < 0)
+		return;
+
+	irq_vecs[irq].count++;
+
+	if (irq_vecs[irq].handler != NULL) {
+		/* call isr */
+		(*irq_vecs[irq].handler) (irq_vecs[irq].arg);
+
+	} else {
+		xilinx_pic_irq_disable(irq);
+		printf("Masking bogus interrupt %d\n", irq);
+	}
+
+	xilinx_pic_irq_ack(irq);
+	return;
+}
+
+void external_interrupt(struct pt_regs *regs)
+{
+	xilinx_pic_interrupt();
+}
+
+/*
+ * Install and free a interrupt handler.
+ */
+void irq_install_handler(int vec, interrupt_handler_t * handler, void
 *arg) +{
+	/*
+	 * Print warning when replacing with a different irq vector
+	 */
+	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);
+	}
+	irq_vecs[vec].handler = handler;
+	irq_vecs[vec].arg = arg;
+
+	xilinx_pic_irq_enable(vec);
+
+	debug("Install interrupt for vector %d ==> %p\n", vec, handler);
+}
+
+void irq_free_handler(int vec)
+{
+	debug("Free interrupt for vector %d ==> %p\n",
+	      vec, irq_vecs[vec].handler);
+
+	xilinx_pic_irq_disable(vec);
+
+	irq_vecs[vec].handler = NULL;
+	irq_vecs[vec].arg = NULL;
+}
+
+#endif
 
-void timer_interrupt_cpu (struct pt_regs *regs)
+void timer_interrupt_cpu(struct pt_regs *regs)
 {
 	/* nothing to do here */
 	return;
 }
 
 #if defined(CONFIG_CMD_IRQ)
-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 ("Interrupt-Information:\n");
-	printf ("Nr  Routine   Arg       Count\n");
+	printf("Interrupt-Information:\n");
+	printf("Nr  Routine   Arg       Count\n");
 
+#if !defined (CONFIG_440_VIRTEX5)
 	for (vec = 0; vec < (UIC_MAX * 32); vec++) {
+#else
+	for (vec = 0; vec < XPAR_INTC_MAX_NUM_INTR_INPUTS; vec++) {
+#endif
 		if (irq_vecs[vec].handler != NULL) {
-			printf ("%02d  %08lx  %08lx  %d\n",
-				vec,
-				(ulong)irq_vecs[vec].handler,
-				(ulong)irq_vecs[vec].arg,
-				irq_vecs[vec].count);
+			printf("%02d  %08lx  %08lx  %d\n",
+			       vec,
+			       (ulong) irq_vecs[vec].handler,
+			       (ulong) irq_vecs[vec].arg, irq_vecs[vec].count);
 		}
 	}
cpu/ppc4xx/miiphy.c +0 -0
index c882720..172fbcd 100644

cpu/ppc4xx/miiphy.c line 48

Quoted 6 lines
cpu/ppc4xx/miiphy.c +3 -0
@@ -43,6 +43,9 @@
 #include <405_mal.h>
 #include <miiphy.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+

-> Makefile.

Quoted 46 lines
cpu/ppc4xx/miiphy.c +2 -0
 #if !defined(CONFIG_PHY_CLK_FREQ)
 #define CONFIG_PHY_CLK_FREQ	0
 #endif
@@ -331,3 +334,5 @@ int emac4xx_miiphy_write (char *devname, unsigned char
 addr, unsigned char reg, {
 	return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
 }
+
+#endif
cpu/ppc4xx/speed.c +0 -1
index 34bd721..d1681e4 100644
@@ -415,7 +415,8 @@ ulong get_PCI_freq (void)
 	return sys_info.freqPCI;
 }
 
-#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) &&

!defined(CONFIG_440SPE) +#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)\

cpu/ppc4xx/speed.c +4 -0
+	&&!defined(CONFIG_440_VIRTEX5)
 void get_sys_info (sys_info_t * sysInfo)
 {
 	unsigned long strp0;
@@ -448,6 +449,8 @@ void get_sys_info (sys_info_t * sysInfo)
 	sysInfo->freqUART = sysInfo->freqPLB;
 }
 #else
+
+#if !defined(CONFIG_440_VIRTEX5)
 void get_sys_info (sys_info_t * sysInfo)
 {
 	unsigned long strp0;
@@ -534,6 +537,7 @@ void get_sys_info (sys_info_t * sysInfo)
 }
 
 #endif
+#endif
 
 #if defined(CONFIG_YUCCA)
 unsigned long determine_sysper(void)
include/asm-ppc/processor.h +0 -0
index 10fd478..88f193a 100644

include/asm-ppc/processor.h line 834

Quoted 8 lines
include/asm-ppc/processor.h +0 -2
@@ -827,13 +827,12 @@
 #define PVR_7400	0x000C0000
 #define PVR_7410	0x800C0000
 #define PVR_7450	0x80000000
-
 #define PVR_85xx	0x80200000
 #define PVR_85xx_REV1	(PVR_85xx | 0x0010)
 #define PVR_85xx_REV2	(PVR_85xx | 0x0020)
-

Please don't remove those empty lines here.

Quoted 11 lines
include/asm-ppc/processor.h +1 -0
 #define PVR_86xx	0x80040000
 #define PVR_86xx_REV1	(PVR_86xx | 0x0010)
+#define PVR_VIRTEX5     0x7ff21912
 
 /*
  * For the 8xx processors, all of them report the same PVR family for
net/eth.c +0 -0
index 7fc9aee..54b59b8 100644

net/eth.c int eth_initialize(bd_t *bis) · line 628

Quoted 9 lines
net/eth.c +2 -1
@@ -621,7 +621,8 @@ int eth_initialize(bd_t *bis)
 	at91rm9200_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) \
-	&& !defined(CONFIG_AP1000) && !defined(CONFIG_405)
+	&& !defined(CONFIG_AP1000) && !defined(CONFIG_405) \
+	&& !defined(CONFIG_440_VIRTEX5)
 	emac4xx_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_MCF52x2)

Please send this eth.c patch as a separate patch. It need to go through the networking custodian.

Please fix and resubmit. Thanks.

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
=====================================================================

#12 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Hello Stefan

I will regenerate the patches and send then again. I will be out 'till Monay.

Best Regards and thanks for your comments

Quoted 643 lines · Stefan Roese

Ricardo,

Quoted 2 lines · Ricardo Ribalda Delgado

This patchs gives support for the embbedded ppc440 on the Virtex5 FPGAs

Thanks.

Some general comments:

Please rebase your 4xx related patches on the "next" branch of my u-boot-ppc4xx repository. I just pushed some bigger rework/cleanup patchsets that are destined for the next merge window.

And please add "ppc4xx: " to the beginning of the patch subject and add me to CC on 4xx related patches.

More comments below...

Quoted 33 lines
---
 cpu/ppc4xx/4xx_enet.c       |    3 +-
 cpu/ppc4xx/4xx_uart.c       |    3 +
 cpu/ppc4xx/cpu.c            |    4 +
 cpu/ppc4xx/gpio.c           |    5 +
 cpu/ppc4xx/interrupts.c     |  238
++++++++++++++++++++++++++++++++++++------- cpu/ppc4xx/miiphy.c         |
 5 +
 cpu/ppc4xx/speed.c          |    6 +-
 include/asm-ppc/processor.h |    3 +-
 net/eth.c                   |    3 +-
 9 files changed, 228 insertions(+), 42 deletions(-)
cpu/ppc4xx/4xx_enet.c +0 -0
index 4e863dc..cf26237 100644
@@ -97,7 +97,8 @@
  * network support enabled.
  * Remark: CONFIG_405 describes Xilinx PPC405 FPGA without EMAC

controller! */
-#if defined(CONFIG_CMD_NET) && !defined(CONFIG_405) && !defined(CONFIG_IOP480) +#if defined(CONFIG_CMD_NET) &&
!defined(CONFIG_405) && !defined(CONFIG_IOP480) \ + &&
!defined(CONFIG_440_VIRTEX5)

#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) #error "CONFIG_MII has to be defined!"

cpu/ppc4xx/4xx_uart.c +0 -0
index a7587d4..37d3dbc 100644

cpu/ppc4xx/4xx_uart.c line 51

Quoted 4 lines
cpu/ppc4xx/4xx_uart.c +1 -0
@@ -48,6 +48,7 @@
 #include <watchdog.h>
 #include <asm/ppc4xx-intvec.h>
 
+#if !defined(CONFIG_440_VIRTEX5)

You add this "#if !defined(CONFIG_440_VIRTEX5)" to many of the cpu/ppc4xx files with this patch. I don't like this. We should let the Makefile handle this. Perhaps something like this:

ifndef $(CONFIG_440_VIRTEX5)
COBJS += 4xx_enet.o
..
endif

Quoted 29 lines
cpu/ppc4xx/4xx_uart.c +2 -0
 #ifdef CONFIG_SERIAL_MULTI
 #include <serial.h>
 #endif
@@ -873,3 +874,5 @@ int serial_tstc(void)
 #endif /* CONFIG_SERIAL_MULTI */
 
 #endif       /* CONFIG_405GP || CONFIG_405CR */
+
+#endif
cpu/ppc4xx/cpu.c +4 -0
index 39f439d..f510cdd 100644
@@ -508,6 +508,10 @@ int checkcpu (void)
              puts("GT Rev. A");
              strcpy(addstr, "Security/Kasumi support");
              break;
+
+     case PVR_VIRTEX5:
+             printf(" VIRTEX5");
+             break;
 
      default:
              printf (" UNKNOWN (PVR=%08x)", pvr);
cpu/ppc4xx/gpio.c +0 -0
index df99f53..59159ee 100644

cpu/ppc4xx/gpio.c line 31

Quoted 6 lines
cpu/ppc4xx/gpio.c +3 -0
@@ -26,6 +26,9 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+

Again, move this to the Makefile instead.

Quoted 35 lines
cpu/ppc4xx/gpio.c +0 -0
 #if defined(CFG_4xx_GPIO_TABLE)
 gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] =

CFG_4xx_GPIO_TABLE; #endif

cpu/ppc4xx/gpio.c +2 -0
@@ -253,3 +256,5 @@ void gpio_set_chip_configuration(void)
      }
 }
 #endif /* CFG_4xx_GPIO_TABLE */
+
+#endif
cpu/ppc4xx/interrupts.c +5 -0
index 8620e2b..4648f52 100644
@@ -8,6 +8,10 @@
  * (C) Copyright 2003 (440GX port)
  * Travis B. Sawyer, Sandburst Corporation, tsawyer at sandburst.com
  *
+ * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX)
+ * Ricardo Ribalda, Universidad Autonoma de Madrid, ricardo.ribalda at uam.es
+ * Work supported by Qtechnology (htpp://qtec.com)
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -41,6 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /*
  * Define the number of UIC's
  */
+#if !defined(CONFIG_440_VIRTEX5)
 #if defined(CONFIG_440SPE) || \
     defined(CONFIG_460EX) || defined(CONFIG_460GT)
 #define UIC_MAX              4
@@ -54,17 +59,23 @@ DECLARE_GLOBAL_DATA_PTR;
 #else
 #define UIC_MAX              1

cpu/ppc4xx/interrupts.c DECLARE_GLOBAL_DATA_PTR; · line 68

Quoted 10 lines
cpu/ppc4xx/interrupts.c +4 -2
 #endif
-
+#else
+void xilinx_pic_enable(void);
+#endif
 /*
  * CPM interrupt vector functions.
  */
-struct       irq_action {
+struct irq_action {

You seem to have run Lindent on this file too, correct? Please don't do this when you also add and/or fix something. This makes it hard to see the "real" changes. Only run Lindent on newly created files.

Quoted 202 lines
cpu/ppc4xx/interrupts.c +42 -24
      interrupt_handler_t *handler;
      void *arg;
      int count;
 };
 
+#if !defined(CONFIG_440_VIRTEX5)
 static struct irq_action irq_vecs[UIC_MAX * 32];
+#else
+static struct irq_action irq_vecs[XPAR_INTC_MAX_NUM_INTR_INPUTS];
+#endif
 
 u32 get_dcr(u16);
 void set_dcr(u16, u32);
@@ -81,27 +92,25 @@ static __inline__ void set_evpr(unsigned long val)
      asm volatile("mtspr 0x03f,%0" : : "r" (val));
 }
 
-#else /* !defined(CONFIG_440) */
+#else                                /* !defined(CONFIG_440) */
 
 static __inline__ void set_pit(unsigned long val)
 {
      asm volatile("mtpit %0" : : "r" (val));
 }
 
-
 static __inline__ void set_tcr(unsigned long val)
 {
      asm volatile("mttcr %0" : : "r" (val));
 }
 
-
 static __inline__ void set_evpr(unsigned long val)
 {
      asm volatile("mtevpr %0" : : "r" (val));
 }
-#endif /* defined(CONFIG_440 */
+#endif                               /* defined(CONFIG_440 */
 
-int interrupt_init_cpu (unsigned *decrementer_count)
+int interrupt_init_cpu(unsigned *decrementer_count)
 {
      int vec;
      unsigned long val;
@@ -112,7 +121,11 @@ int interrupt_init_cpu (unsigned *decrementer_count)
      /*
       * Mark all irqs as free
       */
+#if !defined (CONFIG_440_VIRTEX5)
      for (vec = 0; vec < (UIC_MAX * 32); vec++) {
+#else
+     for (vec = 0; vec < XPAR_INTC_MAX_NUM_INTR_INPUTS; vec++) {
+#endif
              irq_vecs[vec].handler = NULL;
              irq_vecs[vec].arg = NULL;
              irq_vecs[vec].count = 0;
@@ -123,19 +136,19 @@ int interrupt_init_cpu (unsigned *decrementer_count)
       * Init PIT
       */
 #if defined(CONFIG_440)
-     val = mfspr( tcr );
-     val &= (~0x04400000);           /* clear DIS & ARE */
-     mtspr( tcr, val );
-     mtspr( dec, 0 );                /* Prevent exception after TSR clear*/
-     mtspr( decar, 0 );              /* clear reload */
-     mtspr( tsr, 0x08000000 );       /* clear DEC status */
-     val = gd->bd->bi_intfreq/1000;  /* 1 msec */
-     mtspr( decar, val );            /* Set auto-reload value */
-     mtspr( dec, val );              /* Set inital val */
+     val = mfspr(tcr);
+     val &= (~0x04400000);   /* clear DIS & ARE */
+     mtspr(tcr, val);
+     mtspr(dec, 0);          /* Prevent exception after TSR clear */
+     mtspr(decar, 0);        /* clear reload */
+     mtspr(tsr, 0x08000000); /* clear DEC status */
+     val = gd->bd->bi_intfreq / 1000;        /* 1 msec */
+     mtspr(decar, val);      /* Set auto-reload value */
+     mtspr(dec, val);        /* Set inital val */
 #else
      set_pit(gd->bd->bi_intfreq / 1000);
 #endif
-#endif  /* CONFIG_4xx */
+#endif                               /* CONFIG_4xx */
 
 #ifdef CONFIG_ADCIOP
      /*
@@ -156,6 +169,8 @@ int interrupt_init_cpu (unsigned *decrementer_count)
       */
      set_evpr(0x00000000);
 
+#if !defined (CONFIG_440_VIRTEX5)
+
 #if !defined(CONFIG_440GX)
 #if (UIC_MAX > 1)
      /* Install the UIC1 handlers */
@@ -170,7 +185,7 @@ int interrupt_init_cpu (unsigned *decrementer_count)
      irq_install_handler(VECNUM_UIC3NC, uic_cascade_interrupt, 0);
      irq_install_handler(VECNUM_UIC3C, uic_cascade_interrupt, 0);
 #endif
-#else /* !defined(CONFIG_440GX) */
+#else                                /* !defined(CONFIG_440GX) */
      /* Take the GX out of compatibility mode
       * Travis Sawyer, 9 Mar 2004
       * NOTE: 440gx user manual inconsistency here
@@ -179,18 +194,27 @@ int interrupt_init_cpu (unsigned *decrementer_count)
       */
      mfsdr(sdr_mfr, val);
      val &= ~0x10000000;
-     mtsdr(sdr_mfr,val);
+     mtsdr(sdr_mfr, val);
 
      /* Enable UIC interrupts via UIC Base Enable Register */
      mtdcr(uicb0sr, UICB0_ALL);
      mtdcr(uicb0er, 0x54000000);
      /* None are critical */
      mtdcr(uicb0cr, 0);
-#endif /* !defined(CONFIG_440GX) */
+#endif                               /* !defined(CONFIG_440GX) */
+
+#else
+     /*
+      * Enable xilinx pic
+      */
+     xilinx_pic_enable();
+
+#endif
 
      return (0);
 }
 
+#if !defined(CONFIG_440_VIRTEX5)
 /* Handler for UIC interrupt */
 static void uic_interrupt(u32 uic_base, int vec_base)
 {
@@ -214,7 +238,7 @@ static void uic_interrupt(u32 uic_base, int vec_base)
 
                      if (irq_vecs[vec].handler != NULL) {
                              /* call isr */
-                             (*irq_vecs[vec].handler)(irq_vecs[vec].arg);
+                             (*irq_vecs[vec].handler) (irq_vecs[vec].arg);
                      } else {
                              set_dcr(uic_base + UIC_ER,
                                      get_dcr(uic_base + UIC_ER) &
@@ -227,7 +251,8 @@ static void uic_interrupt(u32 uic_base, int vec_base)
                       * After servicing the interrupt, we have to remove the
                       * status indicator
                       */
-                     set_dcr(uic_base + UIC_SR, (0x80000000 >> (vec & 0x1f)));
+                     set_dcr(uic_base + UIC_SR,
+                             (0x80000000 >> (vec & 0x1f)));
              }
 
              /*
@@ -254,10 +279,10 @@ static void uic_cascade_interrupt(void *para)
 #define UIC_BMSR     uic0msr
 #define UIC_BSR              uic0sr
 #endif
-#else /* CONFIG_440 */
+#else                                /* CONFIG_440 */
 #define UIC_BMSR     uicmsr
 #define UIC_BSR              uicsr
-#endif /* CONFIG_440 */
+#endif                               /* CONFIG_440 */
 
 /*
  * Handle external interrupts
@@ -294,9 +319,9 @@ void external_interrupt(struct pt_regs *regs)
      if ((UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr))
              uic_interrupt(UIC0_DCR_BASE, 0);
 #endif
-#else /* CONFIG_440 */
+#else                                /* CONFIG_440 */
      uic_interrupt(UIC0_DCR_BASE, 0);
-#endif /* CONFIG_440 */
+#endif                               /* CONFIG_440 */
 
      mtdcr(UIC_BSR, uic_msr);
 
@@ -313,7 +338,8 @@ void irq_install_handler(int vec, interrupt_handler_t *

handler, void *arg) /*
* Print warning when replacing with a different irq vector */
- if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler !=
handler)) { + if ((irq_vecs[vec].handler != NULL)

cpu/ppc4xx/interrupts.c +3 -1
+         && (irq_vecs[vec].handler != handler)) {
              printf("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
                     vec, (uint) handler, (uint) irq_vecs[vec].handler);
      }
@@ -339,7 +365,7 @@ void irq_install_handler(int vec, interrupt_handler_t *
 handler, void *arg) debug("Install interrupt for vector %d ==> %p\n", vec,
 handler); }
 
-void irq_free_handler (int vec)
+void irq_free_handler(int vec)
 {
      int i;
 
@@ -365,28 +391,166 @@ void irq_free_handler (int vec)
      irq_vecs[vec].handler = NULL;
      irq_vecs[vec].arg = NULL;
 }
+#else

cpu/ppc4xx/interrupts.c void irq_free_handler (int vec) · line 404

Quoted 10 lines
cpu/ppc4xx/interrupts.c +10 -0
+
+#define intc    XPAR_INTC_0_BASEADDR
+#define ISR (0*4)            /* Interrupt Status Register */
+#define IPR (1*4)            /* Interrupt Pending Register */
+#define IER (2*4)            /* Interrupt Enable Register */
+#define IAR (3*4)            /* Interrupt Acknowledge Register */
+#define SIE (4*4)            /* Set Interrupt Enable bits */
+#define CIE (5*4)            /* Clear Interrupt Enable bits */
+#define IVR (6*4)            /* Interrupt Vector Register */
+#define MER (7*4)            /* Master Enable Register */

This seems to be a completely different interrupt handler than used on IBM/AMCC PPC4xx. Please don't add this code to this file but to a new file. Does this Xilinx interrupt controller have a name? I'll probably rename the current interrupt.c to uic.c soon.

cpu/ppc4xx/interrupts.c void irq_free_handler (int vec) · line 407

Quoted 2 lines
cpu/ppc4xx/interrupts.c +2 -0
+#define intc_out_be32(addr, mask)     out32((addr), (mask))
+#define intc_in_be32(addr)            in32((addr))

Please don't define new accessor macros here. Use the existing ones, this makes the code better readable.

And use out_be32()/in_be32() instead of out32()/in32().

Quoted 162 lines
cpu/ppc4xx/interrupts.c +131 -9
+void xilinx_pic_enable(void)
+{
+
+     printf("Xilinx PIC at 0x%8x\n", intc);
+
+     /*
+      * Disable all external interrupts until they are
+      * explicitly requested.
+      */
+     intc_out_be32(intc + IER, 0);
+
+     /* Acknowledge any pending interrupts just in case. */
+     intc_out_be32(intc + IAR, ~(u32) 0);
+
+     /* Turn on the Master Enable. */
+     intc_out_be32(intc + MER, 0x3UL);
+
+     return;
+
+}
+
+int xilinx_pic_irq_get(void)
+{
+     u32 irq;
+     irq = intc_in_be32(intc + IVR);
+
+     /* If no interrupt is pending then all bits of the IVR are set to 1. As
+      * the IVR is as many bits wide as numbers of inputs are available.
+      * Therefore, if all bits of the IVR are set to one, its content will
+      * be bigger than XPAR_INTC_MAX_NUM_INTR_INPUTS.
+      */
+     if (irq >= XPAR_INTC_MAX_NUM_INTR_INPUTS)
+             irq = -1;       /* report no pending interrupt. */
+
+     debug("get_irq: %d\n", irq);
+     return (irq);
+}
+
+static void xilinx_pic_irq_enable(unsigned int irq)
+{
+     unsigned long mask = (0x00000001 << (irq & 31));
+     debug("enable: %d\n", irq);
+     intc_out_be32(intc + SIE, mask);
+}
+
+static void xilinx_pic_irq_disable(unsigned int irq)
+{
+     unsigned long mask = (0x00000001 << (irq & 31));
+     debug("disable: %d\n", irq);
+     intc_out_be32(intc + CIE, mask);
+}
+
+static void xilinx_pic_irq_ack(unsigned int irq)
+{
+     unsigned long mask = (0x00000001 << (irq & 31));
+     debug("ack: %d\n", irq);
+     intc_out_be32(intc + IAR, mask);
+}
+
+static void xilinx_pic_interrupt(void)
+{
+     int irq;
+
+     irq = xilinx_pic_irq_get();
+     if (irq < 0)
+             return;
+
+     irq_vecs[irq].count++;
+
+     if (irq_vecs[irq].handler != NULL) {
+             /* call isr */
+             (*irq_vecs[irq].handler) (irq_vecs[irq].arg);
+
+     } else {
+             xilinx_pic_irq_disable(irq);
+             printf("Masking bogus interrupt %d\n", irq);
+     }
+
+     xilinx_pic_irq_ack(irq);
+     return;
+}
+
+void external_interrupt(struct pt_regs *regs)
+{
+     xilinx_pic_interrupt();
+}
+
+/*
+ * Install and free a interrupt handler.
+ */
+void irq_install_handler(int vec, interrupt_handler_t * handler, void
 *arg) +{
+     /*
+      * Print warning when replacing with a different irq vector
+      */
+     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);
+     }
+     irq_vecs[vec].handler = handler;
+     irq_vecs[vec].arg = arg;
+
+     xilinx_pic_irq_enable(vec);
+
+     debug("Install interrupt for vector %d ==> %p\n", vec, handler);
+}
+
+void irq_free_handler(int vec)
+{
+     debug("Free interrupt for vector %d ==> %p\n",
+           vec, irq_vecs[vec].handler);
+
+     xilinx_pic_irq_disable(vec);
+
+     irq_vecs[vec].handler = NULL;
+     irq_vecs[vec].arg = NULL;
+}
+
+#endif
 
-void timer_interrupt_cpu (struct pt_regs *regs)
+void timer_interrupt_cpu(struct pt_regs *regs)
 {
      /* nothing to do here */
      return;
 }
 
 #if defined(CONFIG_CMD_IRQ)
-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 ("Interrupt-Information:\n");
-     printf ("Nr  Routine   Arg       Count\n");
+     printf("Interrupt-Information:\n");
+     printf("Nr  Routine   Arg       Count\n");
 
+#if !defined (CONFIG_440_VIRTEX5)
      for (vec = 0; vec < (UIC_MAX * 32); vec++) {
+#else
+     for (vec = 0; vec < XPAR_INTC_MAX_NUM_INTR_INPUTS; vec++) {
+#endif
              if (irq_vecs[vec].handler != NULL) {
-                     printf ("%02d  %08lx  %08lx  %d\n",
-                             vec,
-                             (ulong)irq_vecs[vec].handler,
-                             (ulong)irq_vecs[vec].arg,
-                             irq_vecs[vec].count);
+                     printf("%02d  %08lx  %08lx  %d\n",
+                            vec,
+                            (ulong) irq_vecs[vec].handler,
+                            (ulong) irq_vecs[vec].arg, irq_vecs[vec].count);
              }
      }
cpu/ppc4xx/miiphy.c +0 -0
index c882720..172fbcd 100644

cpu/ppc4xx/miiphy.c line 48

Quoted 6 lines
cpu/ppc4xx/miiphy.c +3 -0
@@ -43,6 +43,9 @@
 #include <405_mal.h>
 #include <miiphy.h>
 
+
+#if !defined(CONFIG_440_VIRTEX5)
+

-> Makefile.

Quoted 46 lines
cpu/ppc4xx/miiphy.c +2 -0
 #if !defined(CONFIG_PHY_CLK_FREQ)
 #define CONFIG_PHY_CLK_FREQ  0
 #endif
@@ -331,3 +334,5 @@ int emac4xx_miiphy_write (char *devname, unsigned char
 addr, unsigned char reg, {
      return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
 }
+
+#endif
cpu/ppc4xx/speed.c +0 -1
index 34bd721..d1681e4 100644
@@ -415,7 +415,8 @@ ulong get_PCI_freq (void)
      return sys_info.freqPCI;
 }
 
-#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) &&

!defined(CONFIG_440SPE) +#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)\

cpu/ppc4xx/speed.c +4 -0
+     &&!defined(CONFIG_440_VIRTEX5)
 void get_sys_info (sys_info_t * sysInfo)
 {
      unsigned long strp0;
@@ -448,6 +449,8 @@ void get_sys_info (sys_info_t * sysInfo)
      sysInfo->freqUART = sysInfo->freqPLB;
 }
 #else
+
+#if !defined(CONFIG_440_VIRTEX5)
 void get_sys_info (sys_info_t * sysInfo)
 {
      unsigned long strp0;
@@ -534,6 +537,7 @@ void get_sys_info (sys_info_t * sysInfo)
 }
 
 #endif
+#endif
 
 #if defined(CONFIG_YUCCA)
 unsigned long determine_sysper(void)
include/asm-ppc/processor.h +0 -0
index 10fd478..88f193a 100644

include/asm-ppc/processor.h line 834

Quoted 8 lines
include/asm-ppc/processor.h +0 -2
@@ -827,13 +827,12 @@
 #define PVR_7400     0x000C0000
 #define PVR_7410     0x800C0000
 #define PVR_7450     0x80000000
-
 #define PVR_85xx     0x80200000
 #define PVR_85xx_REV1        (PVR_85xx | 0x0010)
 #define PVR_85xx_REV2        (PVR_85xx | 0x0020)
-

Please don't remove those empty lines here.

Quoted 11 lines
include/asm-ppc/processor.h +1 -0
 #define PVR_86xx     0x80040000
 #define PVR_86xx_REV1        (PVR_86xx | 0x0010)
+#define PVR_VIRTEX5     0x7ff21912
 
 /*
  * For the 8xx processors, all of them report the same PVR family for
net/eth.c +0 -0
index 7fc9aee..54b59b8 100644

net/eth.c int eth_initialize(bd_t *bis) · line 628

Quoted 9 lines
net/eth.c +2 -1
@@ -621,7 +621,8 @@ int eth_initialize(bd_t *bis)
      at91rm9200_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) \
-     && !defined(CONFIG_AP1000) && !defined(CONFIG_405)
+     && !defined(CONFIG_AP1000) && !defined(CONFIG_405) \
+     && !defined(CONFIG_440_VIRTEX5)
      emac4xx_miiphy_initialize(bis);
 #endif
 #if defined(CONFIG_MCF52x2)

Please send this eth.c patch as a separate patch. It need to go through the networking custodian.

Please fix and resubmit. Thanks.

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
=====================================================================

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/
#13 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

In reply to Stefan Roese

Hello Stefan

I'm back from short hollydays, so expect some patches in this week
:). Some general questions:

master or next:
Shall I apply the patches to master or to next? Both have modifications from 2 days ago.

interrupts:
I have been thinking about the irq handler and I am going to create this files:

-interrupt.c (actual file) -> common part
-uic.c (new file) -> uic part (extracted from interrupt.c) -xilinx_iic.c (new file) -> Xilinx Irq handler

The Makefile will select among uic.c or xilinx_iic.c

ml507:
As you know I have been sending patches for the ml507 board. I will wait until this patch in accepted until I resend the ml507 patch. Is this ok?

Thanks

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/
#14 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Hi Racardo,

Quoted 6 lines · Ricardo Ribalda Delgado

I'm back from short hollydays, so expect some patches in this week
:). Some general questions:

master or next:
Shall I apply the patches to master or to next? Both have modifications from 2 days ago.

"next" please. "master" is only for bug fixes now, since the merge window is closed.

Quoted 7 lines

interrupts:
I have been thinking about the irq handler and I am going to create this files:

-interrupt.c (actual file) -> common part
-uic.c (new file) -> uic part (extracted from interrupt.c) -xilinx_iic.c (new file) -> Xilinx Irq handler

xilinx_iic.c ??? This really sounds like I2C. Please choose a different name.

Quoted 1 line

The Makefile will select among uic.c or xilinx_iic.c

Yes, this is possible. But IIRC then the microblaze CPU suport has the same or at least a similar interrupt handler. Isn't there a way to use some interrupt code on both CPU architectures?

Quoted 4 lines

ml507:
As you know I have been sending patches for the ml507 board. I will wait until this patch in accepted until I resend the ml507 patch. Is this ok?

To clarify: You will wait to send the ml507 board support patches until the CPU & interrupt stuff is accepted?

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
=====================================================================

#15 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Hello again

Quoted 2 lines

"next" please. "master" is only for bug fixes now, since the merge window is closed.

ACK

Quoted 1 line

xilinx_iic.c ??? This really sounds like I2C. Please choose a different name.

What about xilinx_irq?

Quoted 6 lines
Quoted 2 lines

The Makefile will select among uic.c or xilinx_iic.c

Yes, this is possible. But IIRC then the microblaze CPU suport has the same or at least a similar interrupt handler. Isn't there a way to use some interrupt code on both CPU architectures?

You are right, but I cannot see how to share code between architechtures... If WD don't have a good idea we should have here the xilinx iic code repeated.

Quoted 8 lines
Quoted 5 lines

ml507:
As you know I have been sending patches for the ml507 board. I will wait until this patch in accepted until I resend the ml507 patch. Is this ok?

To clarify: You will wait to send the ml507 board support patches until the CPU & interrupt stuff is accepted?

Yes, because the ml507 code depends directly on the CPU and the IRQ stuff.

Best Regards

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/
#16 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Quoted 4 lines · In message <[email protected]> you…

You are right, but I cannot see how to share code between architechtures... If WD don't have a good idea we should have here the xilinx iic code repeated.

No. Duplicating code is never a good idea.

Best regards,

Wolfgang Denk

Signature · 5 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
The trouble with our times is that the future is not what it used  to
be.                                                     - Paul Valery
#17 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Quoted 5 lines
Quoted 3 lines

You are right, but I cannot see how to share code between architechtures... If WD don't have a good idea we should have here the xilinx iic code repeated.

No. Duplicating code is never a good idea.

I agree.

Michal

Quoted 3 lines

Best regards,

Wolfgang Denk

#18 lore raw

PATCH 1/1 CPU PPC440x5 on Virtex5 FX

Hello All:

I am preparing a patch for ppc.c that divides interrupts.c in
interrupts.c and ioc.c. My idea was to add a new file called xilinx_irq.c and place there the xilinx interrupt handling.

I would like that microblaze and xilinx_irq.c use the same code:
but I see this quite complicated. I can create a file with the xilinx irq logic (init, enable, disable and ack) but I cannot see where shall I place it if there is no drivers/interrupt/ directory

One more question: interrupts/microblace access the pic registers like:
address=&PIC;
pic=value;
If I create a new file, I suppose that I have to move it to
out_be32() and in_be32(). Am I right?

Best regards

Signature · 2 lines
Ricardo Ribalda
http://www.eps.uam.es/~rribalda/