diff options
-rw-r--r-- | arch/arm/include/asm/mvf_edma_regs.h | 65 | ||||
-rw-r--r-- | arch/arm/include/asm/mvf_switch.h | 90 | ||||
-rw-r--r-- | arch/arm/mach-mvf/board-twr_vf600.c | 52 | ||||
-rw-r--r-- | arch/arm/mach-mvf/clock.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mvf/irq.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-mvf/l2switch.c | 119 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/mvf.h | 4 | ||||
-rw-r--r-- | drivers/char/ftimer.c | 3 | ||||
-rw-r--r-- | drivers/char/lptimer.c | 16 | ||||
-rw-r--r-- | drivers/char/mvf_timer_master.c | 1 | ||||
-rw-r--r-- | drivers/char/pitimer.c | 35 | ||||
-rw-r--r-- | drivers/dma/mvf_edma.c | 141 | ||||
-rw-r--r-- | drivers/net/mvf_switch.c | 319 | ||||
-rw-r--r-- | drivers/net/mvf_switch.h | 57 |
14 files changed, 428 insertions, 480 deletions
diff --git a/arch/arm/include/asm/mvf_edma_regs.h b/arch/arm/include/asm/mvf_edma_regs.h index d5d2f253df07..b87d47ee9bd7 100644 --- a/arch/arm/include/asm/mvf_edma_regs.h +++ b/arch/arm/include/asm/mvf_edma_regs.h @@ -86,46 +86,43 @@ /* Register read/write macros */ /* offset 0x0000_0000 - 0x0000_00ff main dma control area */ -#define MVF_EDMA_CR(base) MVF_REG32((long)(base) + 0x00000000) -#define MVF_EDMA_ES(base) MVF_REG32((long)(base) + 0x00000004) -//#define MVF_EDMA_ERQH(base) MVF_REG32((long)(base) + 0x00000008) -#define MVF_EDMA_ERQ(base) MVF_REG32((long)(base) + 0x0000000C) -//#define MVF_EDMA_EEIH(base) MVF_REG32((long)(base) + 0x00000010) -#define MVF_EDMA_EEI(base) MVF_REG32((long)(base) + 0x00000014) -#define MVF_EDMA_SERQ(base) MVF_REG08((long)(base) + 0x00000008) -#define MVF_EDMA_CERQ(base) MVF_REG08((long)(base) + 0x00000019) -#define MVF_EDMA_SEEI(base) MVF_REG08((long)(base) + 0x0000001A) -#define MVF_EDMA_CEEI(base) MVF_REG08((long)(base) + 0x0000001B) -#define MVF_EDMA_CINT(base) MVF_REG08((long)(base) + 0x0000001C) -#define MVF_EDMA_CERR(base) MVF_REG08((long)(base) + 0x0000001D) -#define MVF_EDMA_SSRT(base) MVF_REG08((long)(base) + 0x0000001E) -#define MVF_EDMA_CDNE(base) MVF_REG08((long)(base) + 0x0000001F) -//#define MVF_EDMA_INTH(base) MVF_REG32((long)(base) + 0x00000020) -#define MVF_EDMA_INT(base) MVF_REG32((long)(base) + 0x00000024) -//#define MVF_EDMA_ERRH(base) MVF_REG32((long)(base) + 0x00000028) -#define MVF_EDMA_ERR(base) MVF_REG32((long)(base) + 0x0000002C) -//#define MVF_EDMA_RSH(base) MVF_REG32((long)(base) + 0x00000030) -#define MVF_EDMA_RS(base) MVF_REG32((long)(base) + 0x00000034) +#define MVF_EDMA_CR(base) MVF_REG32((long)((long)(base) + 0x00000000)) +#define MVF_EDMA_ES(base) MVF_REG32((long)((long)(base) + 0x00000004)) +#define MVF_EDMA_ERQ(base) MVF_REG32((long)((long)(base) + 0x0000000C)) +#define MVF_EDMA_EEI(base) MVF_REG32((long)((long)(base) + 0x00000014)) + +#define MVF_EDMA_CEEI(base) MVF_REG08((long)((long)(base) + 0x00000018)) +#define MVF_EDMA_SEEI(base) MVF_REG08((long)((long)(base) + 0x00000019)) +#define MVF_EDMA_CERQ(base) MVF_REG08((long)((long)(base) + 0x0000001a)) +#define MVF_EDMA_SERQ(base) MVF_REG08((long)((long)(base) + 0x0000001b)) +#define MVF_EDMA_CDNE(base) MVF_REG08((long)((long)(base) + 0x0000001c)) +#define MVF_EDMA_SSRT(base) MVF_REG08((long)((long)(base) + 0x0000001d)) +#define MVF_EDMA_CERR(base) MVF_REG08((long)((long)(base) + 0x0000001e)) +#define MVF_EDMA_CINT(base) MVF_REG08((long)((long)(base) + 0x0000001f)) + +#define MVF_EDMA_INT(base) MVF_REG32((long)((long)(base) + 0x00000024)) +#define MVF_EDMA_ERR(base) MVF_REG32((long)((long)(base) + 0x0000002C)) +#define MVF_EDMA_RS(base) MVF_REG32((long)((long)(base) + 0x00000034)) /* Parameterized register read/write macros for multiple registers */ /* offset 0x0000_0100 - 0x0000_011f dma channel priority area */ -#define MVF_EDMA_DCHPRI(base,x) MVF_REG08((long)(base) + 0x00000100 +((x)*0x001)) +#define MVF_EDMA_DCHPRI(base,x) MVF_REG08((long)((long)(base) + 0x00000100 +((x)*0x001))) /* offset 0x0000_1000 - 0x0000_13ff tcd area */ -#define MVF_EDMA_TCD_SADDR(base,x) MVF_REG32((long)(base) + 0x00001000 +((x)*0x020)) -#define MVF_EDMA_TCD_ATTR(base,x) MVF_REG16((long)(base) + 0x00001004 +((x)*0x020)) -#define MVF_EDMA_TCD_SOFF(base,x) MVF_REG16((long)(base) + 0x00001006 +((x)*0x020)) -#define MVF_EDMA_TCD_NBYTES(base,x) MVF_REG32((long)(base) + 0x00001008 +((x)*0x020)) -#define MVF_EDMA_TCD_SLAST(base,x) MVF_REG32((long)(base) + 0x0000100C +((x)*0x020)) -#define MVF_EDMA_TCD_DADDR(base,x) MVF_REG32((long)(base) + 0x00001010 +((x)*0x020)) -#define MVF_EDMA_TCD_CITER_ELINK(base,x) MVF_REG16((long)(base) + 0x00001014 +((x)*0x020)) -#define MVF_EDMA_TCD_CITER(base, x) MVF_REG16((long)(base) + 0x00001014 +((x)*0x020)) -#define MVF_EDMA_TCD_DOFF(base,x) MVF_REG16((long)(base) + 0x00001016 +((x)*0x020)) -#define MVF_EDMA_TCD_DLAST_SGA(base, x) MVF_REG32((long)(base) + 0x00001018 +((x)*0x020)) -#define MVF_EDMA_TCD_BITER_ELINK(base,x) MVF_REG16((long)(base) + 0x0000101C +((x)*0x020)) -#define MVF_EDMA_TCD_BITER(base, x) MVF_REG16((long)(base) + 0x0000101C +((x)*0x020)) -#define MVF_EDMA_TCD_CSR(base,x) MVF_REG16((long)(base) + 0x0000101e +((x)*0x020)) +#define MVF_EDMA_TCD_SADDR(base,x) MVF_REG32((long)((long)(base) + 0x00001000 +((x)*0x020))) +#define MVF_EDMA_TCD_SOFF(base,x) MVF_REG16((long)((long)(base) + 0x00001004 +((x)*0x020))) +#define MVF_EDMA_TCD_ATTR(base,x) MVF_REG16((long)((long)(base) + 0x00001006 +((x)*0x020))) +#define MVF_EDMA_TCD_NBYTES(base,x) MVF_REG32((long)((long)(base) + 0x00001008 +((x)*0x020))) +#define MVF_EDMA_TCD_SLAST(base,x) MVF_REG32((long)((long)(base) + 0x0000100C +((x)*0x020))) +#define MVF_EDMA_TCD_DADDR(base,x) MVF_REG32((long)((long)(base) + 0x00001010 +((x)*0x020))) +#define MVF_EDMA_TCD_DOFF(base,x) MVF_REG16((long)((long)(base) + 0x00001014 +((x)*0x020))) +#define MVF_EDMA_TCD_CITER_ELINK(base,x) MVF_REG16((long)((long)(base) + 0x00001016 +((x)*0x020))) +#define MVF_EDMA_TCD_CITER(base, x) MVF_REG16((long)((long)(base) + 0x00001016 +((x)*0x020))) +#define MVF_EDMA_TCD_DLAST_SGA(base, x) MVF_REG32((long)((long)(base) + 0x00001018 +((x)*0x020))) +#define MVF_EDMA_TCD_CSR(base,x) MVF_REG16((long)((long)(base) + 0x0000101c +((x)*0x020))) +#define MVF_EDMA_TCD_BITER_ELINK(base,x) MVF_REG16((long)((long)(base) + 0x0000101e +((x)*0x020))) +#define MVF_EDMA_TCD_BITER(base, x) MVF_REG16((long)((long)(base) + 0x0000101e +((x)*0x020))) /* Bit definitions and macros for CR */ #define MVF_EDMA_CR_EDBG (0x00000002) diff --git a/arch/arm/include/asm/mvf_switch.h b/arch/arm/include/asm/mvf_switch.h index a9ddbfcd1635..d8d41c3c2f9f 100644 --- a/arch/arm/include/asm/mvf_switch.h +++ b/arch/arm/include/asm/mvf_switch.h @@ -49,7 +49,8 @@ #define SWITCH_EPORT_NUMBER 2 -#define MVF_MII_SWITCH_SPEED 0x09 +// 2.5MHz + HOLD time +#define MVF_MII_SWITCH_SPEED ((0x09<<1)|((uint)0x100)) // register offset for fec @@ -107,99 +108,87 @@ typedef struct l2switch { unsigned long ESW_SCRATCH; unsigned long ESW_PER; unsigned long reserved0[1]; + // 0x10 unsigned long ESW_VLANV; unsigned long ESW_DBCR; unsigned long ESW_DMCR; unsigned long ESW_BKLR; + // 0x20 unsigned long ESW_BMPC; unsigned long ESW_MODE; unsigned long ESW_VIMSEL; unsigned long ESW_VOMSEL; + // 0x30 unsigned long ESW_VIMEN; unsigned long ESW_VID; - /*from 0x38 0x3C*/ unsigned long esw_reserved0[2]; - unsigned long ESW_MCR;/*0x40*/ + + // 0x40 + unsigned long ESW_MCR; unsigned long ESW_EGMAP; unsigned long ESW_INGMAP; unsigned long ESW_INGSAL; + + // 0x50 unsigned long ESW_INGSAH; unsigned long ESW_INGDAL; unsigned long ESW_INGDAH; unsigned long ESW_ENGSAL; + + // 0x60 unsigned long ESW_ENGSAH; unsigned long ESW_ENGDAL; unsigned long ESW_ENGDAH; - unsigned long ESW_MCVAL;/*0x6C*/ + unsigned long ESW_MCVAL; /*from 0x70--0x7C*/ unsigned long esw_reserved1[4]; - unsigned long ESW_MMSR;/*0x80*/ + + // 0x80 + unsigned long ESW_MMSR; unsigned long ESW_LMT; unsigned long ESW_LFC; unsigned long ESW_PCSR; + + // 0x90 unsigned long ESW_IOSR; - unsigned long ESW_QWT;/*0x94*/ - unsigned long esw_reserved2[1];/*0x98*/ - unsigned long ESW_P0BCT;/*0x9C*/ + unsigned long ESW_QWT; + unsigned long esw_reserved2[1]; + unsigned long ESW_P0BCT; + + // 0xa0 /*from 0xA0-0xB8*/ unsigned long esw_reserved3[7]; - unsigned long ESW_P0FFEN;/*0xBC*/ - /*MCF_ESW_PSNP(x) 0xFC0DC0C0+((x-1)*0x004))) 0xC0-0xDC*/ - /*#define MCF_ESW_PSNP(x) \ - (*(volatile unsigned long*)(0xFC0DC0C0+((x-1)*0x004)))*/ + unsigned long ESW_P0FFEN; + + // 0xc0-0xdf unsigned long ESW_PSNP[8]; - /*MCF_ESW_IPSNP(x) 0xFC0DC0E0+((x-1)*0x004) 0xE0-0xFC*/ - /*#define MCF_ESW_IPSNP(x) \ - (*(volatile unsigned long*)(0xFC0DC0E0+((x-1)*0x004)))*/ + + // 0xe0-0xff unsigned long ESW_IPSNP[8]; - /*port0-port2 VLAN Priority resolution map 0xFC0D_C100-C108*/ - /*#define MCF_ESW_PVRES(x) \ - (*(volatile unsigned long*)(0xFC0DC100+((x)*0x004)))*/ + + // 0x100-0x13f unsigned long ESW_PVRES[3]; - /*from 0x10C-0x13C*/ unsigned long esw_reserved4[13]; - unsigned long ESW_IPRES;/*0x140*/ - /*from 0x144-0x17C*/ + + // 0x140 + unsigned long ESW_IPRES; unsigned long esw_reserved5[15]; - /*port0-port2 Priority Configuration 0xFC0D_C180-C188*/ - /*#define MCF_ESW_PRES(x) \ - (*(volatile unsigned long*)(0xFC0DC180+((x)*0x004)))*/ unsigned long ESW_PRES[3]; - /*from 0x18C-0x1FC*/ unsigned long esw_reserved6[29]; - /*port0-port2 VLAN ID 0xFC0D_C200-C208*/ - /*#define MCF_ESW_PID(x) \ - (*(volatile unsigned long*)(0xFC0DC200+((x)*0x004)))*/ unsigned long ESW_PID[3]; - /*from 0x20C-0x27C*/ unsigned long esw_reserved7[29]; - /*port0-port2 VLAN domain resolution entry 0xFC0D_C280-C2FC*/ - /*#define MCF_ESW_VRES(x) \ - (*(volatile unsigned long*)(0xFC0DC280+((x)*0x004)))*/ unsigned long ESW_VRES[32]; - unsigned long ESW_DISCN;/*0x300*/ + unsigned long ESW_DISCN; unsigned long ESW_DISCB; unsigned long ESW_NDISCN; - unsigned long ESW_NDISCB;/*0xFC0DC30C*/ - /*per port statistics 0xFC0DC310_C33C*/ - /*#define MCF_ESW_POQC(x) \ - (*(volatile unsigned long*)(0xFC0DC310+((x)*0x010))) - #define MCF_ESW_PMVID(x) \ - (*(volatile unsigned long*)(0xFC0DC314+((x)*0x010))) - #define MCF_ESW_PMVTAG(x) \ - (*(volatile unsigned long*)(0xFC0DC318+((x)*0x010))) - #define MCF_ESW_PBL(x) \ - (*(volatile unsigned long*)(0xFC0DC31C+((x)*0x010))) - */ + unsigned long ESW_NDISCB; esw_port_statistics_status port_statistics_status[3]; - /*from 0x340-0x400*/ unsigned long esw_reserved8[48]; - /*0xFC0DC400---0xFC0DC418*/ /*unsigned long MCF_ESW_ISR;*/ unsigned long switch_ievent; /* Interrupt event reg */ /*unsigned long MCF_ESW_IMR;*/ @@ -214,10 +203,8 @@ typedef struct l2switch { unsigned long fec_r_des_active; /* Receive descriptor reg */ /*unsigned long MCF_ESW_TDAR;*/ unsigned long fec_x_des_active; /* Transmit descriptor reg */ - /*from 0x420-0x4FC*/ unsigned long esw_reserved9[57]; - /*0xFC0DC500---0xFC0DC508*/ unsigned long ESW_LREC0; unsigned long ESW_LREC1; unsigned long ESW_LSR; @@ -234,12 +221,13 @@ typedef struct l2switchaddrtable { #define MCF_FEC_RCR_PROM (0x00000008) -#define MCF_FEC_RCR_RMII_MODE (0x00000100) +#define MCF_FEC_RCR_RMII_MODE (0x00000104) #define MCF_FEC_RCR_MAX_FL(x) (((x)&0x00003FFF)<<16) #define MCF_FEC_RCR_CRC_FWD (0x00004000) #define MCF_FEC_TCR_FDEN (0x00000004) #define MCF_FEC_ECR_ETHER_EN (0x00000002) #define MCF_FEC_ECR_ENA_1588 (0x00000010) +#define MCF_FEC_ECR_SWAP (0x00000100) typedef struct _eswIOCTL_PORT_CONF { int port; @@ -607,10 +595,14 @@ struct switch_enet_private { /* Timer for Aging */ struct timer_list timer_aging; int learning_irqhandle_enable; + + dma_addr_t bd_dma; + }; struct switch_platform_private { struct platform_device *pdev; + struct clk *fec0,*fec1,*l2sw; unsigned long quirks; int num_slots; /* Slots on controller */ diff --git a/arch/arm/mach-mvf/board-twr_vf600.c b/arch/arm/mach-mvf/board-twr_vf600.c index bd5d7ea67ec7..6c7ac64b3470 100644 --- a/arch/arm/mach-mvf/board-twr_vf600.c +++ b/arch/arm/mach-mvf/board-twr_vf600.c @@ -215,10 +215,10 @@ static struct fec_platform_data fec_data __initdata = { .phy = PHY_INTERFACE_MODE_RMII, }; -static struct resource edma_resources[] = { +static struct resource edma_resources0[] = { [0] = { .start = MVF_DMA0_BASE_ADDR, - .end = MVF_DMA0_BASE_ADDR + 0x2000, + .end = MVF_DMA0_BASE_ADDR + 0x2000-1, .flags = IORESOURCE_MEM, }, [1] = { @@ -230,34 +230,41 @@ static struct resource edma_resources[] = { .start = MXC_INT_DMA0_ERROR, .end = MXC_INT_DMA0_ERROR, .flags = IORESOURCE_IRQ, - } -#if 0 - [3] = { + }, +}; + +static struct platform_device edma_device0 = { + .name = "mvf-edma", + .id = 0, + .num_resources = 3, + .resource = edma_resources0, +}; + +static struct resource edma_resources1[] = { + [0] = { .start = MVF_DMA1_BASE_ADDR, .end = MVF_DMA1_BASE_ADDR + 0x2000, .flags = IORESOURCE_MEM, }, - [4] = { + [1] = { .start = MXC_INT_DMA1, .end = MXC_INT_DMA1, .flags = IORESOURCE_IRQ, - } - [5] = { + }, + [2] = { .start = MXC_INT_DMA1_ERROR, .end = MXC_INT_DMA1_ERROR, .flags = IORESOURCE_IRQ, - } -#endif + }, }; -static struct platform_device edma_device = { +static struct platform_device edma_device1 = { .name = "mvf-edma", - .id = 0, + .id = 1, .num_resources = 3, - .resource = edma_resources, + .resource = edma_resources1, }; - // // Timer resources // @@ -265,7 +272,7 @@ static struct platform_device edma_device = { static struct resource pit_resources[] = { [0] = { .start = MVF_PIT_BASE_ADDR, - .end = MVF_PIT_BASE_ADDR + 0x1000, + .end = MVF_PIT_BASE_ADDR + 0x1000-1, .flags = IORESOURCE_MEM, }, [1] = { @@ -281,12 +288,12 @@ static struct platform_device pit_device = { .num_resources = 2, .resource = pit_resources, }; - +#if 1 // ftm 0 static struct resource ftm0_resources[] = { [0] = { .start = MVF_FTM0_BASE_ADDR, - .end = MVF_FTM0_BASE_ADDR + 0x1000, + .end = MVF_FTM0_BASE_ADDR + 0x1000-1, .flags = IORESOURCE_MEM, }, [1] = { @@ -302,12 +309,13 @@ static struct platform_device ftm0_device = { .num_resources = 2, .resource = ftm0_resources, }; - +#endif +#if 1 // ftm 1 static struct resource ftm1_resources[] = { [0] = { .start = MVF_FTM1_BASE_ADDR, - .end = MVF_FTM1_BASE_ADDR + 0x1000, + .end = MVF_FTM1_BASE_ADDR + 0x1000-1, .flags = IORESOURCE_MEM, }, [1] = { @@ -323,12 +331,13 @@ static struct platform_device ftm1_device = { .num_resources = 2, .resource = ftm1_resources, }; +#endif // pit static struct resource lpt_resources[] = { [0] = { .start = MVF_LPTMR_BASE_ADDR, - .end = MVF_LPTMR_BASE_ADDR + 0x1000, + .end = MVF_LPTMR_BASE_ADDR + 0x1000-1, .flags = IORESOURCE_MEM, }, [1] = { @@ -417,7 +426,8 @@ static void __init twr_vf600_init(void) printk("TWR_VF600: Adding lcdif\n"); mvf_add_lcdif(&lcdif_data); - platform_device_register(&edma_device); + platform_device_register(&edma_device0); + platform_device_register(&edma_device1); platform_device_register(&pit_device); platform_device_register(&ftm0_device); platform_device_register(&ftm1_device); diff --git a/arch/arm/mach-mvf/clock.c b/arch/arm/mach-mvf/clock.c index aa680c7e854c..cd7e95fc749a 100644 --- a/arch/arm/mach-mvf/clock.c +++ b/arch/arm/mach-mvf/clock.c @@ -4209,7 +4209,7 @@ int __init mvf_clocks_init(unsigned long sirc, unsigned long firc, 3 << MXC_CCM_CCGRx_CG9_OFFSET | 3 << MXC_CCM_CCGRx_CG12_OFFSET | 3 << MXC_CCM_CCGRx_CG13_OFFSET | - 3 << MXC_CCM_CCGRx_CG15_OFFSET, + 0 << MXC_CCM_CCGRx_CG15_OFFSET, //disable OpenVG clock MXC_CCM_CCGR8); __raw_writel(3 << MXC_CCM_CCGRx_CG0_OFFSET | 3 << MXC_CCM_CCGRx_CG1_OFFSET | diff --git a/arch/arm/mach-mvf/irq.c b/arch/arm/mach-mvf/irq.c index ac0a07240512..c67aceeaf74d 100644 --- a/arch/arm/mach-mvf/irq.c +++ b/arch/arm/mach-mvf/irq.c @@ -56,12 +56,16 @@ void mvf_init_irq(void) struct irq_desc *desc; unsigned int i; void __iomem *mscm_base = MVF_IO_ADDRESS(MVF_MSCM_BASE_ADDR); + void __iomem *ddrmc_base = MVF_IO_ADDRESS(MVF_DDRMC_BASE_ADDR); /* Interrupt Ruter Shared Peripheral */ for ( i = 0;i < 112;i++) { __raw_writew(0x01,mscm_base + 0x880 + (i<<1)); } + /* mask DDR Interrupt */ + __raw_writel(0x1FFFFFFF, ddrmc_base + 0x148); + /* start offset if global timer irq id, which is 27. * ID table: * Global timer, PPI -> ID27 diff --git a/arch/arm/mach-mvf/l2switch.c b/arch/arm/mach-mvf/l2switch.c index 06599fb8cd04..f07f49f4e5be 100644 --- a/arch/arm/mach-mvf/l2switch.c +++ b/arch/arm/mach-mvf/l2switch.c @@ -36,6 +36,8 @@ #include <asm/traps.h> #include <asm/mvf_switch.h> +#include <mach/hardware.h> +#include <asm/mach/arch.h> #if (defined(CONFIG_SOC_IMX28) || defined(CONFIG_ARCH_MX6)) || defined(CONFIG_ARCH_MVF) \ && defined(CONFIG_FEC_1588) @@ -44,15 +46,14 @@ // base address -#define FEC_ETH0 0x400D0000 -#define FEC_ETH1 0x400D1000 -#define L2SWITCH_1 0x400E8000 - -#pragma message "need fix!!!!! L2SWITCH_ATBL" -#define L2SWITCH_ATBL 0x400F0000 +//#define FEC_ETH0 0x400D0000 +//#define FEC_ETH1 0x400D1000 +//#define L2SWITCH_1 0x400E8000 +#define L2SWITCH_ATBL 0x400EC000 static unsigned char switch_mac_default[] = { - 0x00, 0x04, 0x9F, 0x00, 0xB3, 0x49, +// 0x00, 0x04, 0x9F, 0x00, 0xB3, 0x49, + 0xae, 0xc6, 0x09, 0x97, 0x21, 0x01, }; static unsigned char switch_mac_addr[6]; @@ -67,60 +68,21 @@ static void switch_request_intrs(struct net_device *dev, char *name; unsigned short irq; } *idp, id[] = { - /*{ "esw_isr(EBERR)", 38 },*/ - { "esw_isr(RxBuffer)", 39 }, - { "esw_isr(RxFrame)", 40 }, - { "esw_isr(TxBuffer)", 41 }, - { "esw_isr(TxFrame)", 42 }, - { "esw_isr(QM)", 43 }, - { "esw_isr(P0OutputDiscard)", 44 }, - { "esw_isr(P1OutputDiscard)", 45 }, - { "esw_isr(P2OutputDiscard)", 46 }, - { "esw_isr(LearningRecord)", 47 }, + { "esw_isr", MXC_INT_ENET_SWITCH}, { NULL }, }; fep = netdev_priv(dev); /*intrruption L2 ethernet SWITCH */ - b = 64 + 64 + 64; /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq, - switch_net_irq_handler, IRQF_DISABLED, - idp->name, irq_privatedata) != 0) + if (request_irq(idp->irq, + switch_net_irq_handler, 0,idp->name, irq_privatedata) != 0) printk(KERN_ERR "FEC: Could not alloc %s IRQ(%d)!\n", - idp->name, b+idp->irq); + idp->name, idp->irq); + printk(KERN_INFO "L2 Switch: %s IRQ(%d) installed.!\n", idp->name, idp->irq); } - - /* Configure RMII */ -// #if 0 -// // set in u-boot -// MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC & -// MCF_GPIO_PAR_FEC_FEC_MASK) | -// MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL; -// -// MCF_GPIO_PAR_FEC = -// (MCF_GPIO_PAR_FEC & -// MCF_GPIO_PAR_FEC_FEC_MASK) | -// MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL; -// -// MCF_GPIO_SRCR_FEC = 0x0F; -// -// MCF_GPIO_PAR_SIMP0H = -// (MCF_GPIO_PAR_SIMP0H & -// MCF_GPIO_PAR_SIMP0H_DAT_MASK) | -// MCF_GPIO_PAR_SIMP0H_DAT_GPIO; -// -// MCF_GPIO_PDDR_G = -// (MCF_GPIO_PDDR_G & -// MCF_GPIO_PDDR_G4_MASK) | -// MCF_GPIO_PDDR_G4_OUTPUT; -// -// MCF_GPIO_PODR_G = -// (MCF_GPIO_PODR_G & -// MCF_GPIO_PODR_G4_MASK); -// #endif } static void switch_set_mii(struct net_device *dev) @@ -128,32 +90,6 @@ static void switch_set_mii(struct net_device *dev) struct switch_enet_private *fep = netdev_priv(dev); volatile switch_t *fecp; -// #if 0 -// fecp = fep->hwp; -// -// MCF_FEC_RCR0 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | -// MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD); -// MCF_FEC_RCR1 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | -// MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD); -// /* TCR */ -// MCF_FEC_TCR0 = MCF_FEC_TCR_FDEN; -// MCF_FEC_TCR1 = MCF_FEC_TCR_FDEN; -// /* ECR */ -// #ifdef ENHANCE_BUFFER -// MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588; -// MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588; -// #else /*legac buffer*/ -// MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN; -// MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN; -// #endif -// /* -// * Set MII speed to 2.5 MHz -// */ -// MCF_FEC_MSCR0 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; -// MCF_FEC_MSCR1 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; -// #endif -// - writel((MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD), fep->fec[0] + FEC_R_CNTRL); writel((MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD), fep->fec[1] + FEC_R_CNTRL); @@ -161,11 +97,11 @@ static void switch_set_mii(struct net_device *dev) writel(MCF_FEC_TCR_FDEN, fep->fec[1] + FEC_X_CNTRL); #ifdef CONFIG_ENHANCED_BD - writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588, fep->fec[0] + FEC_ECNTRL); - writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588, fep->fec[1] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588 |MCF_FEC_ECR_SWAP, fep->fec[0] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588 |MCF_FEC_ECR_SWAP, fep->fec[1] + FEC_ECNTRL); #else - writel(MCF_FEC_ECR_ETHER_EN , fep->fec[0] + FEC_ECNTRL); - writel(MCF_FEC_ECR_ETHER_EN , fep->fec[1] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN |MCF_FEC_ECR_SWAP, fep->fec[0] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN |MCF_FEC_ECR_SWAP, fep->fec[1] + FEC_ECNTRL); #endif writel( MVF_MII_SWITCH_SPEED, fep->fec[0] + FEC_MII_SPEED); writel( MVF_MII_SWITCH_SPEED, fep->fec[1] + FEC_MII_SPEED); @@ -241,13 +177,13 @@ static void switch_platform_flush_cache(void) * Define the fixed address of the FEC hardware. */ static unsigned int switch_platform_hw[] = { - L2SWITCH_1, + MVF_ETH_L2_SW_BASE_ADDR, L2SWITCH_ATBL, }; static unsigned int fec_platform_hw[] = { - FEC_ETH0, - FEC_ETH1, + MVF_ENET0_IEEE1588_BASE_ADDR, + MVF_ENET1_IEEE1588_BASE_ADDR, }; static struct mvf_switch_platform_data mvf_switch_data = { @@ -268,18 +204,18 @@ static struct mvf_switch_platform_data mvf_switch_data = { // non-used-structure static struct resource l2switch_resources[] = { [0] = { - .start = 0xFC0DC000, - .end = 0xFC0DC508, + .start = MVF_ETH_L2_SW_BASE_ADDR, + .end = MVF_ETH_L2_SW_BASE_ADDR+0x1000 - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = (64 + 64 + 64 + 38), - .end = (64 + 64 + 64 + 48), + .start = MXC_INT_ENET_SWITCH, + .end = MXC_INT_ENET_SWITCH, .flags = IORESOURCE_IRQ, }, [2] = { - .start = 0xFC0E0000, - .end = 0xFC0E3FFC, + .start = AIPS1_OFF_BASE_ADDR + 0x4F000, + .end = AIPS1_OFF_BASE_ADDR + 0x4F000 + 0x1000 - 1, .flags = IORESOURCE_MEM, }, }; @@ -314,12 +250,13 @@ static int __init param_switch_addr_setup(char *str) { char *end; int i; - +#if 0 for (i = 0; i < 6; i++) { switch_mac_addr[i] = str ? simple_strtoul(str, &end, 16) : 0; if (str) str = (*end ) ? end + 1 : end; } +#endif return 0; } __setup("switchaddr=", param_switch_addr_setup); diff --git a/arch/arm/plat-mxc/include/mach/mvf.h b/arch/arm/plat-mxc/include/mach/mvf.h index ee8ebf8a69ad..8c5aaad02d70 100644 --- a/arch/arm/plat-mxc/include/mach/mvf.h +++ b/arch/arm/plat-mxc/include/mach/mvf.h @@ -393,8 +393,8 @@ #define MXC_INT_GPIOB 140 #define MXC_INT_GPIOC 141 #define MXC_INT_GPIOD 142 -#define MXC_INT_GPIOE 153 -#define MXC_INT_END 153 +#define MXC_INT_GPIOE 143 +#define MXC_INT_END 143 #define MVF_INT_UART0 MXC_INT_UART0 #define MVF_INT_UART1 MXC_INT_UART1 diff --git a/drivers/char/ftimer.c b/drivers/char/ftimer.c index 88a31997ef8f..9fe19fa70475 100644 --- a/drivers/char/ftimer.c +++ b/drivers/char/ftimer.c @@ -311,7 +311,7 @@ int ftm_probe(struct platform_device *pdev) struct resource *ftm_membase, *ftm_irq; struct mvf_ftm_dev *timedevptr; - ftm_membase = platform_get_resource(pdev, IORESOURCE_MEM, 1); + ftm_membase = platform_get_resource(pdev, IORESOURCE_MEM, 0); ftm_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!ftm_irq || !ftm_membase){ @@ -353,6 +353,7 @@ int ftm_probe(struct platform_device *pdev) platform_set_drvdata(pdev, timedevptr); timer_master_register_platform(pdev); + printk (KERN_INFO "Flex Timer Module Driver (id = %d) Installed.\n", pdev->id); return 0; } diff --git a/drivers/char/lptimer.c b/drivers/char/lptimer.c index 3203580beda1..d955cbd4c7fb 100644 --- a/drivers/char/lptimer.c +++ b/drivers/char/lptimer.c @@ -112,7 +112,7 @@ int lpt_enable_timer( int timer_handle) // must not be altered. val = readl(membase + LPTMR_CSR_OFFSET); val |= ( LPTMR_CSR_TEN|LPTMR_CSR_TIE); - writel( val, membase + LPTMR_CSR_TEN); + writel( val, membase + LPTMR_CSR_OFFSET); return 0; } @@ -142,7 +142,7 @@ int lpt_disable_timer( int timer_handle) // including the CNR and TCF. val = readl(membase + LPTMR_CSR_OFFSET); val &= ~LPTMR_CSR_TEN; - writel( val, membase + LPTMR_CSR_TEN); + writel( val, membase + LPTMR_CSR_OFFSET); return 0; } @@ -175,6 +175,9 @@ int lpt_read_counter( int timer_handle, unsigned long *counter) pdev = timer_master_get_pdev(timer_handle); timedevptr = platform_get_drvdata(pdev); + // Synchronize temporary reg + writel( 0, timedevptr->membase + LPTMR_CNR_OFFSET); + // 16bit timer *counter = readl( timedevptr->membase + LPTMR_CNR_OFFSET) & 0x0000ffff; @@ -251,6 +254,11 @@ int lpt_param_set( int timer_handle, struct mvf_lpt_request *req, void (*event_h // compare writel( req->compare_value, membase + LPTMR_CMR_OFFSET); +#if 0 +printk("register LPTMR_CSR_OFFSET %x\n", readl( timedevptr->membase + LPTMR_CSR_OFFSET)); +printk("register LPTMR_PSR_OFFSET %x\n", readl( timedevptr->membase + LPTMR_PSR_OFFSET)); +printk("register LPTMR_CMR_OFFSET %x\n", readl( timedevptr->membase + LPTMR_CMR_OFFSET)); +#endif timedevptr->event_handler = event_handler; timedevptr->configured++; @@ -272,7 +280,7 @@ int lpt_probe(struct platform_device *pdev) struct resource *lptmr_membase, *lptmr_irq; struct mvf_lpt_dev *timedevptr; - lptmr_membase = platform_get_resource(pdev, IORESOURCE_MEM, 1); + lptmr_membase = platform_get_resource(pdev, IORESOURCE_MEM, 0); lptmr_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!lptmr_irq || !lptmr_membase){ @@ -310,6 +318,8 @@ int lpt_probe(struct platform_device *pdev) timer_master_register_platform(pdev); + printk (KERN_INFO "Low Power Timer Driver Installed.\n"); + return 0; } diff --git a/drivers/char/mvf_timer_master.c b/drivers/char/mvf_timer_master.c index 56d134d499be..4bf245feed54 100644 --- a/drivers/char/mvf_timer_master.c +++ b/drivers/char/mvf_timer_master.c @@ -88,6 +88,7 @@ static int timer_master_alloc_timer( int index) if ( master_control.is_opened[ i] == TIMER_AVAILABLE){ master_control.is_opened[ i] = TIMER_BUSY; ret = i; + break; } } }else diff --git a/drivers/char/pitimer.c b/drivers/char/pitimer.c index b83da781e76c..2b81732d4aa5 100644 --- a/drivers/char/pitimer.c +++ b/drivers/char/pitimer.c @@ -115,7 +115,13 @@ int pit_enable_timer( int timer_handle) membase = timedevptr->membase; - writel( PIT_TFLG_TIF, timedevptr->membase + PIT_TFLG_OFFSET( i)); +// writel( PIT_TFLG_TIF, timedevptr->membase + PIT_TFLG_OFFSET( i)); + + // enable timer Int + val = PIT_TCTR_TIE; + writel( val, membase + PIT_TCTRL_OFFSET( i)); + + // enable timer val = PIT_TCTR_TEN | PIT_TCTR_TIE; writel( val, membase + PIT_TCTRL_OFFSET( i)); @@ -195,7 +201,6 @@ int pit_param_set( int timer_handle, unsigned long load_val, void (*event_handle struct platform_device *pdev; struct mvf_pit_dev *timedevptr; - if ( !timer_master_is_opened( timer_handle)){ return -EAGAIN; } @@ -227,12 +232,12 @@ int pit_probe(struct platform_device *pdev) { int size; int result; - int i; + int i, init_start; unsigned long val; struct resource *pit_membase, *pit_irq; struct mvf_pit_dev *timedevptr; - pit_membase = platform_get_resource(pdev, IORESOURCE_MEM, 1); + pit_membase = platform_get_resource(pdev, IORESOURCE_MEM, 0); pit_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!pit_irq || !pit_membase){ @@ -278,10 +283,26 @@ int pit_probe(struct platform_device *pdev) // timer clock start writel( 0, timedevptr->membase + PIT_MCR_OFFSET); }else{ - // assume PIT 0 is kernel system tick +#ifdef CONFIG_MVF_USE_PIT pit_alloc_timer( PIT0); - printk(KERN_WARNING"Maybe PIT0 is system tick\n"); + printk(KERN_WARNING"PIT0 is system tick.\n"); +#endif + } + + // init timer +#ifdef CONFIG_MVF_USE_PIT + // init from pit1 + init_start = 1; +#else + // init from pit0 + init_start = 0; +#endif + + for ( i = init_start; i < TIMER_MASTER_MAX_TIMER; i ++){ + writel( 0, timedevptr->membase + PIT_TCTRL_OFFSET( i)); + } + printk (KERN_INFO "Periodic Timer Driver Installed.\n"); return 0; } @@ -293,7 +314,7 @@ static int __devexit pit_remove(struct platform_device *pdev) timedevptr = platform_get_drvdata(pdev); // disable all - pit_disable_timer( 0); +// pit_disable_timer( 0); clk_disable( timedevptr->clk); kfree( timedevptr); diff --git a/drivers/dma/mvf_edma.c b/drivers/dma/mvf_edma.c index e04e45af74c1..cf934174b558 100644 --- a/drivers/dma/mvf_edma.c +++ b/drivers/dma/mvf_edma.c @@ -29,6 +29,8 @@ #include <asm/mvf_edma.h> #include <asm/mvf_edma_regs.h> +//#define SCATTER_TEST + #define MVF_MODE_MEMCPY 0x01 #define MVF_MODE_CYCLIC 0x02 #define MVF_MODE_SC 0x03 @@ -68,6 +70,20 @@ struct mvf_dma_engine { int err_irq[MVF_MAX_DMA_ENGINE]; }; +void mvf_dma_regdump( void __iomem *base, int channel) +{ + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_SADDR(base, channel), (unsigned int)MVF_EDMA_TCD_SADDR(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_DADDR(base, channel), (unsigned int)MVF_EDMA_TCD_DADDR(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_ATTR(base, channel), (unsigned int)MVF_EDMA_TCD_ATTR(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_SOFF(base, channel), (unsigned int)MVF_EDMA_TCD_SOFF(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_NBYTES(base, channel), (unsigned int)MVF_EDMA_TCD_NBYTES(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_SLAST(base, channel), (unsigned int)MVF_EDMA_TCD_SLAST(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_CITER(base, channel), (unsigned int)MVF_EDMA_TCD_CITER(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_BITER(base, channel), (unsigned int)MVF_EDMA_TCD_BITER(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_DOFF(base, channel), (unsigned int)MVF_EDMA_TCD_DOFF(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_DLAST_SGA(base, channel),(unsigned int)MVF_EDMA_TCD_DLAST_SGA(base, channel)); + printk("REG ADDR=%x REG%x\n", (unsigned int)&MVF_EDMA_TCD_CSR(base, channel), (unsigned int)MVF_EDMA_TCD_CSR(base, channel)); +} static void mvf_dma_reset_chan(struct mvf_dma_chan *mvf_chan) { @@ -169,18 +185,18 @@ static int mvf_dma_sg_next(struct mvf_dma_chan *mvf_chan, struct scatterlist *sg if ( mvf_chan->word_size == DMA_SLAVE_BUSWIDTH_1_BYTE){ srcflag = MVF_EDMA_TCD_ATTR_SSIZE_8BIT; dstflag = MVF_EDMA_TCD_ATTR_DSIZE_8BIT; - srcdelta = 0; + srcdelta = 1; dstdelta = 1; }else if ( mvf_chan->word_size == DMA_SLAVE_BUSWIDTH_2_BYTES){ srcflag = MVF_EDMA_TCD_ATTR_SSIZE_16BIT; dstflag = MVF_EDMA_TCD_ATTR_DSIZE_16BIT; - srcdelta = 0; + srcdelta = 2; dstdelta = 2; }else{ srcflag = MVF_EDMA_TCD_ATTR_SSIZE_32BIT; dstflag = MVF_EDMA_TCD_ATTR_DSIZE_32BIT; - srcdelta = 0; + srcdelta = 4; dstdelta = 4; } @@ -217,6 +233,12 @@ static int mvf_dma_sg_next(struct mvf_dma_chan *mvf_chan, struct scatterlist *sg MVF_EDMA_TCD_BITER(base, channel) = MVF_EDMA_TCD_BITER_BITER(1); MVF_EDMA_TCD_DLAST_SGA(base, channel) = MVF_EDMA_TCD_DLAST_SGA_DLAST_SGA(0); +// mvf_dma_regdump(base, channel); + + MVF_EDMA_TCD_CSR(base,channel) |= MVF_EDMA_TCD_CSR_INT_MAJOR; + MVF_EDMA_TCD_CSR(base,channel) &= ~MVF_EDMA_TCD_CSR_D_REQ; + MVF_EDMA_SEEI(base) = MVF_EDMA_SEEI_SEEI(channel); + return now; } @@ -253,14 +275,19 @@ static int mvf_dma_handle(struct mvf_dma_chan *mvf_chan) if (mvf_chan->sg_list) { current_sg = mvf_chan->sg_list; mvf_chan->sg_list = sg_next(mvf_chan->sg_list); - // prepare next transfer if (mvf_chan->sg_list) { +#ifdef SCATTER_TEST + if ( mvf_chan->sg_list->length != 0){ +#endif // re-fill tx parameter mvf_dma_sg_next(mvf_chan, mvf_chan->sg_list); // start tx mvf_dma_enable_chan(mvf_chan); ret = 1; +#ifdef SCATTER_TEST + } +#endif } } } @@ -290,10 +317,10 @@ static irqreturn_t mvf_dma_int_handler(int irq, void *dev_id) printk("error irq\n"); return IRQ_HANDLED; } + //printk("DMA irq occured = CR:%x ES:%x SRC:%x \n", MVF_EDMA_CR(base), MVF_EDMA_ES(base),MVF_EDMA_INT(base)); // read int source and clear soon int_src = MVF_EDMA_INT(base); - MVF_EDMA_CINT(base) = MVF_EDMA_CINT_CAIR; // deliver int source and re-enable (if scatter gather is configured) for (i = 0; i < MVF_EACH_DMA_CHANNEL; i++) { @@ -310,6 +337,7 @@ static irqreturn_t mvf_dma_int_handler(int irq, void *dev_id) tasklet_schedule(&mvf_chan->tasklet); } } + MVF_EDMA_CINT(base) = i; } } @@ -331,10 +359,11 @@ static irqreturn_t mvf_dma_err_handler(int irq, void *dev_id) engine = i; } } + printk(KERN_INFO"DMA error irq occured = CR:%x ES:%x\n", (unsigned int)MVF_EDMA_CR(base), (unsigned int)MVF_EDMA_ES(base)); // fail safe if (!base){ - printk("error irq\n"); + printk(KERN_INFO"error irq\n"); return IRQ_HANDLED; } @@ -343,6 +372,7 @@ static irqreturn_t mvf_dma_err_handler(int irq, void *dev_id) if ( err & (1 << i)){ mvf_chan = mvf_find_chan(mvf_dma, engine, i); if (mvf_chan){ + mvf_chan->last_completed = mvf_chan->desc.cookie; mvf_chan->status = DMA_ERROR; tasklet_schedule(&mvf_chan->tasklet); } @@ -357,14 +387,13 @@ static irqreturn_t mvf_dma_err_handler(int irq, void *dev_id) static int mvf_dma_alloc_chan_resources(struct dma_chan *chan) { struct mvf_dma_chan *mvf_chan = to_mvf_dma_chan(chan); -// struct mvf_dma_engine *mvf_dma = mvf_chan->mvf_dma; mvf_dma_reset_chan(mvf_chan); dma_async_tx_descriptor_init(&mvf_chan->desc, chan); mvf_chan->desc.tx_submit = mvf_dma_tx_submit; - /* the descriptor is ready */ + // the descriptor is ready async_tx_ack(&mvf_chan->desc); return 0; @@ -373,11 +402,8 @@ static int mvf_dma_alloc_chan_resources(struct dma_chan *chan) static void mvf_dma_free_chan_resources(struct dma_chan *chan) { struct mvf_dma_chan *mvf_chan = to_mvf_dma_chan(chan); -// struct mvf_dma_engine *mvf_dma = mvf_chan->mvf_dma; mvf_dma_disable_chan(mvf_chan); - -// free_irq(mvf_chan->chan_irq, mvf_dma); } @@ -387,12 +413,9 @@ mvf_edma_set_tcd_params(struct mvf_dma_chan *mvf_chan, u32 source, u32 dest, u32 citer, u32 biter, u32 doff, u32 dlast_sga, int major_int, int disable_req) { -// struct mvf_dma_chan *mvf_chan = to_mvf_dma_chan(chan); -// struct mvf_dma_engine *mvf_dma = mvf_chan->mvf_dma; - int channel = mvf_chan->chan.chan_id % MVF_EACH_DMA_CHANNEL; void __iomem *base = mvf_chan->chan_mem_base; - + MVF_EDMA_TCD_SADDR(base, channel) = source; MVF_EDMA_TCD_DADDR(base, channel) = dest; MVF_EDMA_TCD_ATTR(base, channel) = attr; @@ -404,6 +427,21 @@ mvf_edma_set_tcd_params(struct mvf_dma_chan *mvf_chan, u32 source, u32 dest, MVF_EDMA_TCD_DOFF(base, channel) = MVF_EDMA_TCD_DOFF_DOFF(doff); MVF_EDMA_TCD_DLAST_SGA(base, channel) = MVF_EDMA_TCD_DLAST_SGA_DLAST_SGA(dlast_sga); +#if 0 + printk("Channel:%d Top reg:%x\n TX descriptor src : %x / dest : %x / attr : %x\n",channel, &MVF_EDMA_TCD_SADDR(base, channel), source,dest,attr); + MVF_EDMA_TCD_SADDR(base, channel) = source&0xfffffff0; + MVF_EDMA_TCD_DADDR(base, channel) = dest&0xffffff00; + MVF_EDMA_TCD_ATTR(base, channel) = (0 | MVF_EDMA_TCD_ATTR_SSIZE_32BIT | MVF_EDMA_TCD_ATTR_DSIZE_32BIT); + MVF_EDMA_TCD_SOFF(base, channel) = 0x4; + MVF_EDMA_TCD_NBYTES(base, channel) = 16; + MVF_EDMA_TCD_SLAST(base, channel) = 0; + MVF_EDMA_TCD_CITER(base, channel) = 1; + MVF_EDMA_TCD_BITER(base, channel) = 1; + MVF_EDMA_TCD_DOFF(base, channel) = 4; + MVF_EDMA_TCD_DLAST_SGA(base, channel) = 0; + MVF_EDMA_TCD_CSR(base, channel) = 0x0000; +#endif + /* interrupt at the end of major loop */ if (major_int) MVF_EDMA_TCD_CSR(base,channel) |= MVF_EDMA_TCD_CSR_INT_MAJOR; @@ -487,12 +525,8 @@ static struct dma_async_tx_descriptor *mvf_prep_slave_sg( } mvf_chan->sg_list = sgl; -#if 1 ret = mvf_dma_setup_sg(mvf_chan, sg_len, dma_length, dmamode); -#else - ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len, - dma_length, imxdmac->per_address, dmamode); -#endif + if (ret) return NULL; @@ -514,20 +548,12 @@ static struct dma_async_tx_descriptor *mvf_dma_prep_dma_cyclic( mvf_chan->status = DMA_IN_PROGRESS; mvf_chan->flags = MVF_MODE_CYCLIC; -#if 0 - ret = imx_dma_setup_progression_handler(imxdmac->imxdma_channel, - imxdma_progression); - if (ret) { - dev_err(imxdma->dev, "Failed to setup the DMA handler\n"); - return NULL; - } -#endif - if (mvf_chan->sg_list) kfree(mvf_chan->sg_list); mvf_chan->sg_list = kcalloc(periods + 1, sizeof(struct scatterlist), GFP_KERNEL); + if (!mvf_chan->sg_list) return NULL; @@ -542,10 +568,12 @@ static struct dma_async_tx_descriptor *mvf_dma_prep_dma_cyclic( } /* close the loop */ +#ifndef SCATTER_TEST mvf_chan->sg_list[periods].offset = 0; mvf_chan->sg_list[periods].length = 0; mvf_chan->sg_list[periods].page_link = ((unsigned long)mvf_chan->sg_list | 0x01) & ~0x02; +#endif if (direction == DMA_DEV_TO_MEM) dmamode = DMA_MODE_READ; @@ -573,33 +601,14 @@ static struct dma_async_tx_descriptor *mvf_dma_prep_memcpy mvf_chan->flags = MVF_MODE_MEMCPY; mvf_chan->status = DMA_IN_PROGRESS; - // chan_id -#if 1 mvf_edma_set_tcd_params( mvf_chan, src, dst, - (0 | MVF_EDMA_TCD_ATTR_SSIZE_32BIT | MVF_EDMA_TCD_ATTR_DSIZE_32BIT), - 0x04, - len, 0x0, 1, 1, - 0x04, 0x0, 0x1,0x0); - -#else - // channel control - if ( channel == 10){ - mvf_edma_set_tcd_params( - channel, - src, - dst, - (0 | MVF_EDMA_TCD_ATTR_SSIZE_32BIT | MVF_EDMA_TCD_ATTR_DSIZE_32BIT), - 0x04, + (0 | MVF_EDMA_TCD_ATTR_SSIZE_8BIT | MVF_EDMA_TCD_ATTR_DSIZE_8BIT), + 0x01, len, 0x0, 1, 1, - 0x04, 0x0, 0x1,0x0); - }else{ - } -#endif - - + 0x01, 0x0, 0x1,0x0); mvf_chan->desc_count = 0; return &mvf_chan->desc; @@ -689,22 +698,6 @@ static int __init mvf_dma_init(struct mvf_dma_engine *mvf_dma) } return 0; - - -#if 0 - int ret; - - ret = clk_prepare_enable(mvf_dma->clk); - if (ret) - return ret; - - ret = mxs_reset_block(mvf_dma->base); - if (ret) - goto err_out; - -err_out: - return ret; -#endif } static int __init mvf_dma_probe(struct platform_device *pdev) @@ -727,7 +720,7 @@ static int __init mvf_dma_probe(struct platform_device *pdev) } mvf_dma->base[i] = ioremap(iores->start, resource_size(iores)); - if (!mvf_dma->base) { + if (!mvf_dma->base[i]) { ret = -ENOMEM; goto err_ioremap; } @@ -744,14 +737,6 @@ static int __init mvf_dma_probe(struct platform_device *pdev) mvf_dma->err_irq[i]=errirq_res->start; } -#if 0 - mvf_dma->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(mvf_dma->clk)) { - ret = PTR_ERR(mvf_dma->clk); - goto err_clk; - } -#endif - dma_cap_set(DMA_MEMCPY, mvf_dma->dma_device.cap_mask); dma_cap_set(DMA_SLAVE, mvf_dma->dma_device.cap_mask); dma_cap_set(DMA_CYCLIC, mvf_dma->dma_device.cap_mask); @@ -761,7 +746,6 @@ static int __init mvf_dma_probe(struct platform_device *pdev) /* Initialize channel parameters */ for (i = 0; i < MVF_EDMA_CHANNELS; i++) { struct mvf_dma_chan *mvf_chan = &mvf_dma->mvf_chans[i]; - index = i / MVF_EACH_DMA_CHANNEL; mvf_chan->mvf_dma = mvf_dma; @@ -771,7 +755,6 @@ static int __init mvf_dma_probe(struct platform_device *pdev) tasklet_init(&mvf_chan->tasklet, mvf_dma_tasklet, (unsigned long) mvf_chan); - /* Add the channel to mvf_chan list */ list_add_tail(&mvf_chan->chan.device_node, &mvf_dma->dma_device.channels); @@ -802,7 +785,7 @@ static int __init mvf_dma_probe(struct platform_device *pdev) goto err_init; } - dev_info(mvf_dma->dma_device.dev, "initialized\n"); + printk(KERN_INFO "eDMA driver Installed.\n"); return 0; diff --git a/drivers/net/mvf_switch.c b/drivers/net/mvf_switch.c index b2a943756aa5..3c5ece8f78f7 100644 --- a/drivers/net/mvf_switch.c +++ b/drivers/net/mvf_switch.c @@ -39,6 +39,7 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/signal.h> +#include <linux/clk.h> #include <asm/irq.h> #include <asm/pgtable.h> @@ -49,6 +50,8 @@ #include <asm/mvf_switch.h> #include "mvf_switch.h" +#define LOOKUP_ELEMENTS 2048 + #define SWITCH_MAX_PORTS 1 #define CONFIG_FEC_SHARED_PHY #define FEC_PHY @@ -58,6 +61,8 @@ #define CONFIG_ENHANCED_BD #endif +#define TOMOICHI_DMA_MOVE + /* Interrupt events/masks. */ #define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */ @@ -71,6 +76,16 @@ #define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */ #define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */ +#define FEC_MMFR_ST (1 << 30) +#define FEC_MMFR_OP_READ (2 << 28) +#define FEC_MMFR_OP_WRITE (1 << 28) +#define FEC_MMFR_PA(v) ((v & 0x1f) << 23) +#define FEC_MMFR_RA(v) ((v & 0x1f) << 18) +#define FEC_MMFR_TA (2 << 16) +#define FEC_MMFR_DATA(v) (v & 0xffff) +#define FEC_MII_TIMEOUT 30 /* ms */ + + static int switch_enet_open(struct net_device *dev); static int switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t switch_enet_interrupt(int irq, void *dev_id); @@ -87,8 +102,7 @@ static void switch_set_mac_address(struct net_device *dev); /* Make MII read/write commands for the FEC. */ #define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) -#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \ - (VAL & 0xffff)) +#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) /* Transmitter timeout. */ @@ -102,6 +116,30 @@ struct port_status ports_link_status; /* the user space pid, used to send the link change to user space */ long user_pid = 1; +// for debug +void dump_regs(void __iomem *fec) +{ + printk("FEC_ECNTRL REG = %x\n", readl(fec + FEC_ECNTRL)); + printk("FEC_MII_SPEED REG = %x\n", readl(fec + FEC_MII_SPEED)); + printk("FEC_R_CNTRL REG = %x\n", readl(fec + FEC_R_CNTRL)); + printk("FEC_X_CNTRL REG = %x\n", readl(fec + FEC_X_CNTRL)); +} + +static void adjust_phy_speed( struct switch_enet_private *fep, int phy_index) +{ + u32 val; + + val = readl(fep->fec[phy_index] + FEC_R_CNTRL); + if (fep->phydev[phy_index] && fep->phydev[phy_index]->speed == SPEED_100){ + printk("Phy %d is 100M\n", phy_index); + val &= ~(1 << 9); + }else{ + printk("Phy %d is 10M\n", phy_index); + val |= (1 << 9); + } + writel(val, fep->fec[phy_index] + FEC_R_CNTRL); +} + /* ----------------------------------------------------------------*/ /* * Calculate Galois Field Arithmetic CRC for Polynom x^8+x^2+x+1. @@ -156,7 +194,6 @@ void read_atable(struct switch_enet_private *fep, int index, unsigned long *read_lo, unsigned long *read_hi) { -// unsigned long atable_base = 0xFC0E0000; unsigned long atable_base = (long)fep->hwentry; *read_lo = *((volatile unsigned long *)(atable_base + (index<<3))); @@ -167,7 +204,6 @@ void write_atable(struct switch_enet_private *fep, int index, unsigned long write_lo, unsigned long write_hi) { -// unsigned long atable_base = 0xFC0E0000; unsigned long atable_base = (long)fep->hwentry; *((volatile unsigned long *)(atable_base + (index<<3))) = write_lo; @@ -241,7 +277,7 @@ eswPortInfo *esw_portinfofifo_read( void esw_clear_atable(struct switch_enet_private *fep) { int index; - for (index = 0; index < 2048; index++) + for (index = 0; index < LOOKUP_ELEMENTS; index++) write_atable(fep, index, 0, 0); } @@ -249,7 +285,7 @@ void esw_dump_atable(struct switch_enet_private *fep) { int index; unsigned long read_lo, read_hi; - for (index = 0; index < 2048; index++) { + for (index = 0; index < LOOKUP_ELEMENTS; index++) { read_atable(fep, index, &read_lo, &read_hi); } @@ -1077,11 +1113,11 @@ void esw_mac_lookup_table_range(struct switch_enet_private *fep) int index; unsigned long read_lo, read_hi; /* Pointer to switch address look up memory*/ - for (index = 0; index < 2048; index++) + for (index = 0; index < LOOKUP_ELEMENTS; index++) write_atable(fep, index, index, (~index)); /* Pointer to switch address look up memory*/ - for (index = 0; index < 2048; index++) { + for (index = 0; index < LOOKUP_ELEMENTS; index++) { read_atable(fep, index, &read_lo, &read_hi); if (read_lo != index) { printk(KERN_ERR "%s:Mismatch at low %d\n", @@ -2321,6 +2357,7 @@ int esw_get_mac_address_lookup_table(struct switch_enet_private *fep, static void l2switch_aging_timer(unsigned long data) { struct switch_enet_private *fep; +printk("aging occured\n"); fep = (struct switch_enet_private *)data; @@ -3203,6 +3240,9 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) cbd_t *bdp; unsigned short status; unsigned long flags; +#ifdef TOMOICHI_DMA_MOVE + void *bufaddr; +#endif fep = netdev_priv(dev); fecp = (switch_t *)fep->hwp; @@ -3219,7 +3259,11 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Set buffer length and buffer pointer. */ +#ifdef TOMOICHI_DMA_MOVE + bufaddr = skb->data; +#else bdp->cbd_bufaddr = __pa(skb->data); +#endif bdp->cbd_datlen = skb->len; /* @@ -3233,7 +3277,11 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) memcpy(fep->tx_bounce[index1], (void *)skb->data, bdp->cbd_datlen); +#ifdef TOMOICHI_DMA_MOVE + bufaddr = fep->tx_bounce[index1]; +#else bdp->cbd_bufaddr = __pa(fep->tx_bounce[index1]); +#endif } /* Save skb pointer. */ @@ -3246,8 +3294,13 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) * data. */ // flush_dcache_range((unsigned long)skb->data, +#ifdef TOMOICHI_DMA_MOVE + bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr, + SWITCH_ENET_TX_FRSIZE, DMA_TO_DEVICE); +#else flush_kernel_vmap_range(skb->data, (unsigned long)skb->data + skb->len); +#endif /* Send it on its way. Tell FEC it's ready, interrupt when done, * it's the last BD of the frame, and to put the CRC on the end. @@ -3304,12 +3357,14 @@ switch_enet_interrupt(int irq, void *dev_id) irqreturn_t ret = IRQ_NONE; fecp = (switch_t *)dev->base_addr; - /* Get the interrupt events that caused us to be here. */ do { int_events = fecp->switch_ievent; fecp->switch_ievent = int_events; + +// if (int_events)printk("Interrupt %s:%d occured ev:%x, reg address %x\n", __func__, __LINE__,int_events, &fecp->switch_ievent); + /* Handle receive event in its own function. */ /* Transmit OK, or non-fatal error. Update the buffer @@ -3361,7 +3416,12 @@ switch_enet_tx(struct net_device *dev) while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { if (bdp == fep->cur_tx && fep->tx_full == 0) break; - +#ifdef TOMOICHI_DMA_MOVE + if (bdp->cbd_bufaddr) + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, + SWITCH_ENET_TX_FRSIZE, DMA_TO_DEVICE); + bdp->cbd_bufaddr = 0; +#endif skb = fep->tx_skbuff[fep->skb_dirty]; /* Check for errors. */ if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | @@ -3483,6 +3543,7 @@ switch_enet_rx(struct net_device *dev) dev->stats.rx_bytes += pkt_len; data = (__u8 *)__va(bdp->cbd_bufaddr); + /* This does 16 byte alignment, exactly what we need. * The packet length includes FCS, but we don't want to * include that when passing upstream as it messes up @@ -3498,6 +3559,7 @@ switch_enet_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); } + rx_processing_done: /* Clear the status flags for this buffer */ @@ -3524,70 +3586,45 @@ rx_processing_done: spin_unlock_irq(&fep->hw_lock); } -static int fec_mdio_transfer(struct mii_bus *bus, int phy_id, - int reg, int regval) +static int mvf_fec_mdio_read(struct mii_bus *bus, + int phy_id, int reg) { - struct net_device *dev = bus->priv; - unsigned long flags; + unsigned long time_left; struct switch_enet_private *fep; - int tries = 100; - int retval = 0; - fep = netdev_priv(dev); - spin_lock_irqsave(&fep->mii_lock, flags); - - regval |= phy_id << 23; -#if 0 - MCF_FEC_MMFR0 = regval; -#else - writel(regval, fep->fec[0] + FEC_MII_DATA); -#endif - - /* wait for it to finish, this takes about 23 us on lite5200b */ -#if 0 - while (!(MCF_FEC_EIR0 & FEC_ENET_MII) && --tries) -#else - while (!(readl(fep->fec[0]+FEC_IEVENT) & FEC_ENET_MII) && --tries) -#endif - udelay(5); - - if (!tries) { - printk(KERN_ERR "%s timeout\n", __func__); - return -ETIMEDOUT; - } - -#if 0 - MCF_FEC_EIR0 = FEC_ENET_MII; -#else - writel(FEC_ENET_MII, fep->fec[0]+FEC_IEVENT); -#endif - -#if 0 - retval = MCF_FEC_MMFR0; -#else - retval = readl(fep->fec[0] + FEC_MII_DATA); -#endif + struct net_device *dev = bus->priv; - spin_unlock_irqrestore(&fep->mii_lock, flags); + fep = netdev_priv(dev); - return retval; -} + /* start a read op */ + writel(FEC_MMFR_ST | FEC_MMFR_OP_READ | + FEC_MMFR_PA(phy_id) | FEC_MMFR_RA(reg) | + FEC_MMFR_TA, fep->fec[0] + FEC_MII_DATA); + mdelay(FEC_MII_TIMEOUT); -static int mvf_fec_mdio_read(struct mii_bus *bus, - int phy_id, int reg) -{ - int ret; - ret = fec_mdio_transfer(bus, phy_id, reg, - mk_mii_read(reg)); - return ret; + /* return value */ + return FEC_MMFR_DATA(readl(fep->fec[0] + FEC_MII_DATA)); } static int mvf_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data) { - return fec_mdio_transfer(bus, phy_id, reg, - mk_mii_write(reg, data)); + unsigned long time_left; + struct switch_enet_private *fep; + struct net_device *dev = bus->priv; + + fep = netdev_priv(dev); + + /* start a write op */ + writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE | + FEC_MMFR_PA(phy_id) | FEC_MMFR_RA(reg) | + FEC_MMFR_TA | FEC_MMFR_DATA(data), + fep->fec[0] + FEC_MII_DATA); + + mdelay(FEC_MII_TIMEOUT); + + return 0; } static void switch_adjust_link1(struct net_device *dev) @@ -3605,6 +3642,7 @@ static void switch_adjust_link1(struct net_device *dev) if (phydev1->speed != priv->phy1_speed) { new_state = 1; priv->phy1_speed = phydev1->speed; + adjust_phy_speed(priv,0); } if (priv->phy1_old_link == PHY_DOWN) { @@ -3626,6 +3664,10 @@ static void switch_adjust_link1(struct net_device *dev) /*Send the new status to user space*/ if (user_pid != 1) sys_tkill(user_pid, SIGUSR1); + +#if 1 + phy_print_status(phydev1); +#endif } } @@ -3644,6 +3686,7 @@ static void switch_adjust_link2(struct net_device *dev) if (phydev2->speed != priv->phy2_speed) { new_state = 1; priv->phy2_speed = phydev2->speed; + adjust_phy_speed(priv,1); } if (priv->phy2_old_link == PHY_DOWN) { @@ -3665,13 +3708,17 @@ static void switch_adjust_link2(struct net_device *dev) /*Send the new status to user space*/ if (user_pid != 1) sys_tkill(user_pid, SIGUSR1); + +#if 1 + phy_print_status(phydev2); +#endif } } static int mvf_switch_init_phy(struct net_device *dev) { struct switch_enet_private *priv = netdev_priv(dev); - struct phy_device *phydev[SWITCH_EPORT_NUMBER] = {NULL, NULL}; + struct phy_device *phydev[PHY_MAX_ADDR] = {NULL, NULL}; int i, startnode = 0; /* search for connect PHY device */ @@ -3722,34 +3769,24 @@ static int mvf_switch_init_phy(struct net_device *dev) priv->phy2_speed = 0; priv->phy2_duplex = -1; -#ifndef CONFIG_ARCH_MVF - phydev[0] = phy_connect(dev, phydev[0]->dev.bus_id, -#else phydev[0] = phy_connect(dev, dev_name(&phydev[0]->dev), -#endif &switch_adjust_link1, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(phydev[0])) { printk(KERN_ERR " %s phy_connect failed\n", __func__); return PTR_ERR(phydev[0]); } - -#ifndef CONFIG_ARCH_MVF - phydev[1] = phy_connect(dev, phydev[1]->dev.bus_id, -#else - phydev[0] = phy_connect(dev, dev_name(&phydev[0]->dev), -#endif + phydev[1] = phy_connect(dev, dev_name(&phydev[1]->dev), &switch_adjust_link2, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(phydev[1])) { printk(KERN_ERR " %s phy_connect failed\n", __func__); return PTR_ERR(phydev[1]); } - + printk("Phy devs %s, %s\n", dev_name(&phydev[0]->dev),dev_name(&phydev[1]->dev)); for (i = 0; i < SWITCH_EPORT_NUMBER; i++) { printk(KERN_INFO "attached phy %i to driver %s\n", phydev[i]->addr, phydev[i]->drv->name); priv->phydev[i] = phydev[i]; } - return 0; } /* -----------------------------------------------------------------------*/ @@ -3760,6 +3797,7 @@ switch_enet_open(struct net_device *dev) volatile switch_t *fecp; int i; + fecp = (volatile switch_t *)fep->hwp; /* I should reset the ring buffers here, but I don't yet know * a simple way to do that. @@ -3783,7 +3821,6 @@ switch_enet_open(struct net_device *dev) /* no phy, go full duplex, it's most likely a hub chip */ switch_restart(dev, 1); - /* if the fec is the fist open, we need to do nothing*/ /* if the fec is not the fist open, we need to restart the FEC*/ if (fep->sequence_done == 0) @@ -3800,6 +3837,8 @@ switch_enet_open(struct net_device *dev) netif_start_queue(dev); fep->opened = 1; + + return 0; } @@ -3809,6 +3848,7 @@ switch_enet_close(struct net_device *dev) struct switch_enet_private *fep = netdev_priv(dev); int i; + /* Don't know what to do yet.*/ fep->opened = 0; netif_stop_queue(dev); @@ -3820,6 +3860,8 @@ switch_enet_close(struct net_device *dev) phy_write(fep->phydev[i], MII_BMCR, BMCR_PDOWN); } #endif + + return 0; } @@ -3897,78 +3939,57 @@ switch_set_mac_address(struct net_device *dev) static void switch_hw_init( struct switch_enet_private *fep) { -#if 0 - /* GPIO config - RMII mode for both MACs */ - MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC & - MCF_GPIO_PAR_FEC_FEC_MASK) | - MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL; -#endif - + int i; -#if 0 - /* Initialize MAC 0/1 */ - /* RCR */ - MCF_FEC_RCR0 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | - MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD); - MCF_FEC_RCR1 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | - MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD); - /* TCR */ - MCF_FEC_TCR0 = MCF_FEC_TCR_FDEN; - MCF_FEC_TCR1 = MCF_FEC_TCR_FDEN; -#else +// /* Initialize MAC 0/1 */ +// /* RCR */ +// MCF_FEC_RCR0 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | +// MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD); +// MCF_FEC_RCR1 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | +// MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD); +// /* TCR */ +// MCF_FEC_TCR0 = MCF_FEC_TCR_FDEN; +// MCF_FEC_TCR1 = MCF_FEC_TCR_FDEN; writel((MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD), fep->fec[0] + FEC_R_CNTRL); writel((MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD), fep->fec[1] + FEC_R_CNTRL); writel(MCF_FEC_TCR_FDEN, fep->fec[0] + FEC_X_CNTRL); writel(MCF_FEC_TCR_FDEN, fep->fec[1] + FEC_X_CNTRL); -#endif - - -#if 0 /* ECR */ -#ifdef CONFIG_ENHANCED_BD - MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588; - MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588; -#else - MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN; - MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN; -#endif - -#else - +// #ifdef CONFIG_ENHANCED_BD +// MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588; +// MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588; +//#else +// MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN; +// MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN; +//#endif #ifdef CONFIG_ENHANCED_BD - writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588, fep->fec[0] + FEC_ECNTRL); - writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588, fep->fec[1] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588 |MCF_FEC_ECR_SWAP, fep->fec[0] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588 |MCF_FEC_ECR_SWAP, fep->fec[1] + FEC_ECNTRL); #else - writel(MCF_FEC_ECR_ETHER_EN , fep->fec[0] + FEC_ECNTRL); - writel(MCF_FEC_ECR_ETHER_EN , fep->fec[1] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN |MCF_FEC_ECR_SWAP, fep->fec[0] + FEC_ECNTRL); + writel(MCF_FEC_ECR_ETHER_EN |MCF_FEC_ECR_SWAP, fep->fec[1] + FEC_ECNTRL); #endif -#endif -#if 0 - MCF_FEC_MSCR0 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; - MCF_FEC_MSCR1 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; +// MCF_FEC_MSCR0 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; +// MCF_FEC_MSCR1 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; - MCF_FEC_EIMR0 = FEC_ENET_TXF | FEC_ENET_RXF; - MCF_FEC_EIMR1 = FEC_ENET_TXF | FEC_ENET_RXF; +// MCF_FEC_EIMR0 = FEC_ENET_TXF | FEC_ENET_RXF; +// MCF_FEC_EIMR1 = FEC_ENET_TXF | FEC_ENET_RXF; /*MCF_PPMHR0*/ - MCF_PPMCR0 = 0; -#else +// MCF_PPMCR0 = 0; writel( MVF_MII_SWITCH_SPEED, fep->fec[0] + FEC_MII_SPEED); writel( MVF_MII_SWITCH_SPEED, fep->fec[1] + FEC_MII_SPEED); writel( FEC_ENET_TXF | FEC_ENET_RXF, fep->fec[0] + FEC_IMASK); writel( FEC_ENET_TXF | FEC_ENET_RXF, fep->fec[1] + FEC_IMASK); -// MCF_PPMCR0 = 0; -// writel( , fep->fec[0] + ); - #pragma message "need fix!!!!!" -#endif - - + for (i = 0; i < SWITCH_EPORT_NUMBER; i++) { + adjust_phy_speed(fep, i); + } } #ifdef CONFIG_ARCH_MVF @@ -4006,7 +4027,11 @@ int __init switch_enet_init(struct net_device *dev, /* Allocate memory for buffer descriptors. */ +//#ifdef TOMOICHI_DMA_MOVE +// mem_addr = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, GFP_KERNEL); +//#else mem_addr = __get_free_page(GFP_DMA); +//#endif if (mem_addr == 0) { printk(KERN_ERR "Switch: allocate descriptor memory failed?\n"); return -ENOMEM; @@ -4026,7 +4051,7 @@ int __init switch_enet_init(struct net_device *dev, fep->index = slot; fep->hwp = fecp; #ifdef CONFIG_ARCH_MVF - fep->hwentry = (eswAddrTable_t *)ioremap(plat->switch_hw[1], SZ_4K); + fep->hwentry = (eswAddrTable_t *)ioremap(plat->switch_hw[1], SZ_16K); #else fep->hwentry = (eswAddrTable_t *)plat->switch_hw[1]; #endif @@ -4108,6 +4133,7 @@ int __init switch_enet_init(struct net_device *dev, for (j = 0; j < SWITCH_ENET_RX_FRPPG; j++) { bdp->cbd_sc = BD_ENET_RX_EMPTY; bdp->cbd_bufaddr = __pa(mem_addr); + #ifdef CONFIG_ENHANCED_BD bdp->bdu = 0x00000000; bdp->ebd_status = RX_BD_INT; @@ -4185,6 +4211,7 @@ int __init switch_enet_init(struct net_device *dev, fecp->switch_imask = MCF_ESW_IMR_RXB | MCF_ESW_IMR_TXB | MCF_ESW_IMR_RXF | MCF_ESW_IMR_TXF; esw_clear_atable(fep); + /* Queue up command to detect the PHY and initialize the * remainder of the interface. */ @@ -4214,14 +4241,10 @@ switch_restart(struct net_device *dev, int duplex) fep = netdev_priv(dev); fecp = fep->hwp; plat = fep->pdev->dev.platform_data; + /* Whack a reset. We should wait for this.*/ -#if 0 - MCF_FEC_ECR0 = 1; - MCF_FEC_ECR1 = 1; -#else writel(1, fep->fec[0] + FEC_ECNTRL); writel(1, fep->fec[1] + FEC_ECNTRL); -#endif udelay(10); @@ -4343,6 +4366,11 @@ switch_stop(struct net_device *dev) udelay(10); } +static int mvf_fec_mdio_reset(struct mii_bus *bus) +{ + return 0; +} + static int fec_mdio_register(struct net_device *dev, int slot) { @@ -4366,8 +4394,9 @@ static int fec_mdio_register(struct net_device *dev, "support more than 2 mii bus\n"); } - fep->mdio_bus->read = &mvf_fec_mdio_read; - fep->mdio_bus->write = &mvf_fec_mdio_write; + fep->mdio_bus->read = mvf_fec_mdio_read; + fep->mdio_bus->write = mvf_fec_mdio_write; + fep->mdio_bus->reset = mvf_fec_mdio_reset; fep->mdio_bus->priv = dev; err = mdiobus_register(fep->mdio_bus); if (err) { @@ -4387,7 +4416,6 @@ static int __init eth_switch_probe(struct platform_device *pdev) struct net_device *dev; int i, err; struct switch_enet_private *fep; - struct switch_platform_private *chip; struct task_struct *task; @@ -4401,6 +4429,23 @@ static int __init eth_switch_probe(struct platform_device *pdev) (unsigned int)chip); return err; } + chip->fec0 = clk_get(&pdev->dev, "fec_clk"); + chip->fec1 = clk_get(&pdev->dev, "fec1_clk"); + chip->l2sw = clk_get(&pdev->dev, "eth_l2_sw_clk"); + + if ( IS_ERR( chip->fec0 )) { + dev_err(&pdev->dev, "Could not get FEC0 clock \n"); + return PTR_ERR( chip->fec0); + } + if ( IS_ERR( chip->fec1 )) { + dev_err(&pdev->dev, "Could not get FEC1 clock \n"); + return PTR_ERR( chip->fec1); + } + if ( IS_ERR( chip->l2sw )) { + dev_err(&pdev->dev, "Could not get L2 Switch clock \n"); + return PTR_ERR( chip->l2sw); + } + chip->pdev = pdev; chip->num_slots = SWITCH_MAX_PORTS; @@ -4449,6 +4494,7 @@ static int __init eth_switch_probe(struct platform_device *pdev) return -ENOMEM; } #endif + /* setup timer for Learning Aging function */ init_timer(&fep->timer_aging); fep->timer_aging.function = l2switch_aging_timer; @@ -4499,6 +4545,9 @@ static int eth_switch_remove(struct platform_device *pdev) del_timer_sync(&fep->timer_aging); } + clk_disable( chip->fec0); + clk_disable( chip->fec1); + clk_disable( chip->l2sw); platform_set_drvdata(pdev, NULL); kfree(chip); diff --git a/drivers/net/mvf_switch.h b/drivers/net/mvf_switch.h index 7e40414836d5..5fbf1a4e1665 100644 --- a/drivers/net/mvf_switch.h +++ b/drivers/net/mvf_switch.h @@ -62,63 +62,6 @@ #error "L2SWITCH: descriptor ring size constants too large" #endif -/*unsigned long MCF_ESW_LOOKUP_MEM;*/ -#if 0 -#define MCF_ESW_REVISION (*(volatile unsigned long *)(0xFC0DC000)) -#define MCF_ESW_PER (*(volatile unsigned long *)(0xFC0DC008)) -#define MCF_ESW_VLANV (*(volatile unsigned long *)(0xFC0DC010)) -#define MCF_ESW_DBCR (*(volatile unsigned long *)(0xFC0DC014)) -#define MCF_ESW_DMCR (*(volatile unsigned long *)(0xFC0DC018)) -#define MCF_ESW_BKLR (*(volatile unsigned long *)(0xFC0DC01C)) -#define MCF_ESW_BMPC (*(volatile unsigned long *)(0xFC0DC020)) -#define MCF_ESW_MODE (*(volatile unsigned long *)(0xFC0DC024)) - -#define MCF_ESW_ISR (*(volatile unsigned long *)(0xFC0DC400)) -#define MCF_ESW_IMR (*(volatile unsigned long *)(0xFC0DC404)) -#define MCF_ESW_TDAR (*(volatile unsigned long *)(0xFC0DC418)) -#define MCF_ESW_LOOKUP_MEM (*(volatile unsigned long *)(0xFC0E0000)) - -#define MCF_PPMCR0 (*(volatile unsigned short *)(0xFC04002D)) -#define MCF_PPMHR0 (*(volatile unsigned long *)(0xFC040030)) -#endif - -#if 0 -// for compile -#define MCF_FEC_EIR0 (*(volatile unsigned long *)(0xFC0D4004)) -#define MCF_FEC_EIR1 (*(volatile unsigned long *)(0xFC0D8004)) -#define MCF_FEC_EIMR0 (*(volatile unsigned long *)(0xFC0D4008)) -#define MCF_FEC_EIMR1 (*(volatile unsigned long *)(0xFC0D8008)) -#define MCF_FEC_MMFR0 (*(volatile unsigned long *)(0xFC0D4040)) -#define MCF_FEC_MMFR1 (*(volatile unsigned long *)(0xFC0D8040)) -#define MCF_FEC_MSCR0 (*(volatile unsigned long *)(0xFC0D4044)) -#define MCF_FEC_MSCR1 (*(volatile unsigned long *)(0xFC0D8044)) -#define MCF_FEC_RCR0 (*(volatile unsigned long *)(0xFC0D4084)) -#define MCF_FEC_RCR1 (*(volatile unsigned long *)(0xFC0D8084)) -#define MCF_FEC_TCR0 (*(volatile unsigned long *)(0xFC0D40C4)) -#define MCF_FEC_TCR1 (*(volatile unsigned long *)(0xFC0D80C4)) -#define MCF_FEC_ECR0 (*(volatile unsigned long *)(0xFC0D4024)) -#define MCF_FEC_ECR1 (*(volatile unsigned long *)(0xFC0D8024)) -#else -// from fec.h -// #define FEC_R_CNTRL 0x084 /* Receive control reg */ -// #define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */ -// #define FEC_IEVENT 0x004 /* Interrupt event reg */ -// #define FEC_IMASK 0x008 -// #define FEC_MII_DATA 0x040 /* MII manage frame reg */ -// #define FEC_MII_SPEED 0x044 /* MII speed control reg */ -// #define FEC_ECNTRL 0x024 /* Ethernet control reg */ - -#endif - -#define MCF_FEC_RCR_PROM (0x00000008) -#define MCF_FEC_RCR_RMII_MODE (0x00000100) -#define MCF_FEC_RCR_MAX_FL(x) (((x)&0x00003FFF)<<16) -#define MCF_FEC_RCR_CRC_FWD (0x00004000) -#define MCF_FEC_TCR_FDEN (0x00000004) -#define MCF_FEC_ECR_ETHER_EN (0x00000002) -#define MCF_FEC_ECR_ENA_1588 (0x00000010) - - /*=============================================================*/ #define LEARNING_AGING_TIMER (10 * HZ) |