Index: git/board/atmel/at91sam9x5ek/at91sam9x5ek.c =================================================================== --- git.orig/board/atmel/at91sam9x5ek/at91sam9x5ek.c 2013-02-11 10:22:37.000000000 -0600 +++ git/board/atmel/at91sam9x5ek/at91sam9x5ek.c 2013-02-11 13:52:43.930054966 -0600 @@ -60,8 +60,6 @@ /* Enable CS3 */ csa = readl(&matrix->ebicsa); csa |= AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA; - /* NAND flash on D16 */ - csa |= AT91_MATRIX_NFD0_ON_D16; /* Configure IO drive */ csa &= ~AT91_MATRIX_EBI_EBI_IOSR_NORMAL; @@ -115,8 +113,9 @@ #ifdef CONFIG_MACB if (has_emac0()) + /* MTOCGD3: use phy addr 5 for ethernet switch */ rc = macb_eth_initialize(0, - (void *)ATMEL_BASE_EMAC0, 0x00); + (void *)ATMEL_BASE_EMAC0, 0x05); if (has_emac1()) rc = macb_eth_initialize(1, (void *)ATMEL_BASE_EMAC1, 0x00); Index: git/include/configs/at91sam9x5ek.h =================================================================== --- git.orig/include/configs/at91sam9x5ek.h 2013-02-11 10:22:38.000000000 -0600 +++ git/include/configs/at91sam9x5ek.h 2013-02-11 13:56:13.890363608 -0600 @@ -54,6 +54,7 @@ #define CONFIG_USART_ID ATMEL_ID_SYS /* LCD */ +/* MTOCGD3 has no LCD #define CONFIG_LCD #define LCD_BPP LCD_COLOR16 #define LCD_OUTPUT_BPP 24 @@ -65,6 +66,7 @@ #define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 #define CONFIG_SYS_CONSOLE_IS_IN_ENV +*/ #define CONFIG_BOOTDELAY 3 @@ -120,12 +122,14 @@ /* our CLE is AD22 */ #define CONFIG_SYS_NAND_MASK_CLE (1 << 22) #define CONFIG_SYS_NAND_ENABLE_PIN AT91_PIN_PD4 -#define CONFIG_SYS_NAND_READY_PIN AT91_PIN_PD5 +/* MTOCGD3: nand ready is on PC31 */ +#define CONFIG_SYS_NAND_READY_PIN AT91_PIN_PC31 /* PMECC & PMERRLOC */ #define CONFIG_ATMEL_NAND_HWECC 1 #define CONFIG_ATMEL_NAND_HW_PMECC 1 -#define CONFIG_PMECC_CAP 2 +/* MTOCGD3: 4-bit PMECC */ +#define CONFIG_PMECC_CAP 4 #define CONFIG_PMECC_SECTOR_SIZE 512 #define CONFIG_PMECC_INDEX_TABLE_OFFSET 0x8000 @@ -140,9 +144,14 @@ /* Ethernet */ #define CONFIG_MACB -#define CONFIG_RMII +/* MTOCGD3 is MII */ +#undef CONFIG_RMII #define CONFIG_NET_RETRY_COUNT 20 -#define CONFIG_MACB_SEARCH_PHY +/* MTOCGD3: MAC is connected to fixed-speed PHY on ethernet switch */ +#undef CONFIG_MACB_SEARCH_PHY +#define CONFIG_FIXED_PHY 1 +/* enable MII command */ +#define CONFIG_CMD_MII 1 #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ @@ -155,9 +164,8 @@ #define CONFIG_ENV_OFFSET 0xc0000 #define CONFIG_ENV_OFFSET_REDUND 0x100000 #define CONFIG_ENV_SIZE 0x20000 /* 1 sector = 128 kB */ -#define CONFIG_BOOTCOMMAND "nand read " \ - "0x22000000 0x200000 0x300000; " \ - "bootm 0x22000000" +/* MTOCGD3: read from env variables for boot */ +#define CONFIG_BOOTCOMMAND "nboot.jffs2 ${loadaddr} 0 ${kernel_addr}; bootm ${loadaddr}" #else #ifdef CONFIG_SYS_USE_SPIFLASH /* bootstrap + u-boot + env + linux in spi flash */ @@ -172,11 +180,8 @@ #endif #endif -#define CONFIG_BOOTARGS "mem=128M console=ttyS0,115200 " \ - "mtdparts=atmel_nand:" \ - "8M(bootstrap/uboot/kernel)ro,-(rootfs) " \ - "root=/dev/mtdblock1 rw " \ - "rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs" +/* MTOCGD3: rootfs is jffs2 */ +#define CONFIG_BOOTARGS "mem=128M console=ttyS0,115200 root=/dev/mtdblock8 ro rootfstype=jffs2" #define CONFIG_BAUDRATE 115200 @@ -199,4 +204,22 @@ #error CONFIG_USE_IRQ not supported #endif +// MTOCGD3 defaults +#define CONFIG_ENV_OVERWRITE 1 /* Allow Overwrite of serial# & ethaddr */ +#define CONFIG_ETHADDR 00:08:00:87:00:02 +#define CONFIG_IPADDR 192.168.2.1 +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_SERVERIP 192.168.2.2 +#define CONFIG_HOSTNAME AT91SAM9G25 +#define CONFIG_LOADADDR 0x22000000 + +// MTOCGD3 - enable watchdog +#define CONFIG_AT91SAM9_WATCHDOG 1 +#define CONFIG_HW_WATCHDOG 1 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr=0x200000\0" \ + "" + + #endif Index: git/drivers/net/macb.c =================================================================== --- git.orig/drivers/net/macb.c 2013-02-11 13:52:43.930054966 -0600 +++ git/drivers/net/macb.c 2013-02-11 13:52:43.930054966 -0600 @@ -86,6 +86,18 @@ #define TXBUF_WRAP 0x40000000 #define TXBUF_USED 0x80000000 +#define BIT0 (1<<0) +#define BIT1 (1<<1) +#define BIT2 (1<<2) +#define BIT3 (1<<3) +#define BIT4 (1<<4) +#define BIT5 (1<<5) +#define BIT6 (1<<6) +#define BIT7 (1<<7) +#define BIT8 (1<<8) +#define BIT9 (1<<9) +#define BIT10 (1<<10) + struct macb_device { void *regs; @@ -105,6 +117,7 @@ const struct device *dev; struct eth_device netdev; unsigned short phy_addr; + unsigned short ext_phy_addr; }; #define to_macb(_nd) container_of(_nd, struct macb_device, netdev) @@ -113,6 +126,13 @@ unsigned long netctl; unsigned long netstat; unsigned long frame; + unsigned short phya; + + // use extended phy addr if set, else use fixed phy addr + if (macb->ext_phy_addr != 0) + phya = macb->ext_phy_addr; + else + phya = macb->phy_addr; netctl = macb_readl(macb, NCR); netctl |= MACB_BIT(MPE); @@ -120,7 +140,7 @@ frame = (MACB_BF(SOF, 1) | MACB_BF(RW, 1) - | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(PHYA, phya) | MACB_BF(REGA, reg) | MACB_BF(CODE, 2) | MACB_BF(DATA, value)); @@ -140,6 +160,14 @@ unsigned long netctl; unsigned long netstat; unsigned long frame; + unsigned short phya; + + // use extended phy addr if set, else use fixed phy addr + if (macb->ext_phy_addr != 0) + phya = macb->ext_phy_addr; + else + phya = macb->phy_addr; + netctl = macb_readl(macb, NCR); netctl |= MACB_BIT(MPE); @@ -147,7 +175,7 @@ frame = (MACB_BF(SOF, 1) | MACB_BF(RW, 2) - | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(PHYA, phya) | MACB_BF(REGA, reg) | MACB_BF(CODE, 2)); macb_writel(macb, MAN, frame); @@ -167,15 +195,59 @@ #if defined(CONFIG_CMD_MII) +// Micrel switch support -- converts SMI register address to split reg and phy address fields +void convert_smi_reg(u8 smi_reg, u8 *reg, u8 *phy_adr) +{ + u8 new_phy_adr = 0; + + // lower 5 bits go in reg + if (reg) + *reg = smi_reg & 0x1f; + + // upper 3 bits go in phy_adr bits 4,3,0 + if (smi_reg & BIT5) + new_phy_adr |= BIT0; + if (smi_reg & BIT6) + new_phy_adr |= BIT3; + if (smi_reg & BIT7) + new_phy_adr |= BIT4; + + // bits 1 and 2 are always 1 + new_phy_adr |= BIT1; + new_phy_adr |= BIT2; + + if (phy_adr) + *phy_adr = new_phy_adr; +} + int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value) { struct eth_device *dev = eth_get_dev_by_name(devname); struct macb_device *macb = to_macb(dev); + u8 smi_reg = reg; + u8 phy_arg = phy_adr; + u8 reg_arg = reg; + + if (phy_adr == 0 || phy_adr > 6) + return -1; + + // ---micrel switch support--- + // use phy_adr 0x06 to designate that reg is an SMI command and we should + // construct phy_adr and reg values for accessing the control registers + if (phy_adr == 0x06) { + convert_smi_reg(smi_reg, ®_arg, &phy_arg); + //debug("reading SMI reg %x, phy_adr %x, reg %x\n", + // smi_reg, phy_arg, reg_arg); + debug("reading SMI reg %x\n", smi_reg); + } - if ( macb->phy_addr != phy_adr ) - return -1; + // allow reading any phy addr value (ethernet switch) + macb->ext_phy_addr = phy_arg; + + *value = macb_mdio_read(macb, reg_arg); - *value = macb_mdio_read(macb, reg); + // reset to use fixed phy for later calls + macb->ext_phy_addr = 0; return 0; } @@ -184,11 +256,30 @@ { struct eth_device *dev = eth_get_dev_by_name(devname); struct macb_device *macb = to_macb(dev); + u8 smi_reg = reg; + u8 phy_arg = phy_adr; + u8 reg_arg = reg; + + if (phy_adr == 0 || phy_adr > 6) + return -1; + + // ---micrel switch support--- + // use phy_adr 0x06 to designate that reg is an SMI command and we should + // construct phy_adr and reg values for accessing the control registers + if (phy_adr == 0x06) { + convert_smi_reg(smi_reg, ®_arg, &phy_arg); + //debug("writing value %x to SMI reg %x, phy_adr %x, reg %x\n", + // value, smi_reg, phy_arg, reg_arg); + debug("writing value %x to SMI reg %x\n", value, smi_reg); + } - if ( macb->phy_addr != phy_adr ) - return -1; + // allow using any phy addr value (ethernet switch) + macb->ext_phy_addr = phy_arg; - macb_mdio_write(macb, reg, value); + macb_mdio_write(macb, reg_arg, value); + + // reset to use fixed phy for later calls + macb->ext_phy_addr = 0; return 0; } @@ -396,6 +487,14 @@ return 0; } +#ifdef CONFIG_FIXED_PHY + ncfgr = macb_readl(macb, NCFGR); + // MTOCGD3: force link to 100, full duplex + ncfgr |= MACB_BIT(SPD); + ncfgr |= MACB_BIT(FD); + macb_writel(macb, NCFGR, ncfgr); + return 1; +#else status = macb_mdio_read(macb, MII_BMSR); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ @@ -428,6 +527,7 @@ macb_writel(macb, NCFGR, ncfgr); return 1; } +#endif /* CONFIG_FIXED_PHY */ } static int macb_init(struct eth_device *netdev, bd_t *bd) @@ -554,6 +654,7 @@ macb->regs = regs; macb->phy_addr = phy_addr; + macb->ext_phy_addr = 0; sprintf(netdev->name, "macb%d", id); netdev->init = macb_init; @@ -583,6 +684,10 @@ #if defined(CONFIG_CMD_MII) miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write); #endif + + // MTOCGD3: enable micrel switch + macb_miiphy_write("macb0", 6, 1, 0x41); + return 0; }