Merge branch 'master' of git://git.denx.de/u-boot-net

This commit is contained in:
Tom Rini 2015-08-12 15:46:36 -04:00
commit fcd78fa604
13 changed files with 210 additions and 55 deletions

View File

@ -45,7 +45,12 @@ void lpc32xx_mac_init(void)
{
/* Enable MAC interface */
writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER
| CLK_MAC_MII, &clk->macclk_ctrl);
#if defined(CONFIG_RMII)
| CLK_MAC_RMII,
#else
| CLK_MAC_MII,
#endif
&clk->macclk_ctrl);
}
void lpc32xx_mlc_nand_init(void)

View File

@ -598,7 +598,8 @@ static void davinci_eth_close(struct eth_device *dev)
debug_emac("+ emac_close\n");
davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */
davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
if (readl(&adap_emac->RXCONTROL) & 1)
davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
/* Reset EMAC module and disable interrupts in wrapper */
writel(1, &adap_emac->SOFTRESET);

View File

@ -126,6 +126,7 @@ static int e1000_detect_gig_phy(struct e1000_hw *hw);
static void e1000_set_media_type(struct e1000_hw *hw);
static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
#ifndef CONFIG_E1000_NO_NVM
@ -729,7 +730,10 @@ void e1000_release_eeprom(struct e1000_hw *hw)
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
}
e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
}
/******************************************************************************
* Reads a 16 bit word from the EEPROM.
*
@ -992,10 +996,6 @@ e1000_get_software_semaphore(struct e1000_hw *hw)
DEBUGFUNC();
swsm = E1000_READ_REG(hw, SWSM);
swsm &= ~E1000_SWSM_SMBI;
E1000_WRITE_REG(hw, SWSM, swsm);
if (hw->mac_type != e1000_80003es2lan)
return E1000_SUCCESS;
@ -1102,6 +1102,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
return E1000_SUCCESS;
}
/* Take ownership of the PHY */
static int32_t
e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
{
@ -1115,10 +1116,7 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
if (e1000_get_hw_eeprom_semaphore(hw))
return -E1000_ERR_SWFW_SYNC;
if (hw->mac_type == e1000_igb)
swfw_sync = E1000_READ_REG(hw, I210_SW_FW_SYNC);
else
swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
if (!(swfw_sync & (fwmask | swmask)))
break;
@ -1141,6 +1139,21 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
return E1000_SUCCESS;
}
static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask)
{
uint32_t swfw_sync = 0;
DEBUGFUNC();
while (e1000_get_hw_eeprom_semaphore(hw))
; /* Empty */
swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
swfw_sync &= ~mask;
E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
e1000_put_hw_eeprom_semaphore(hw);
}
static bool e1000_is_second_port(struct e1000_hw *hw)
{
switch (hw->mac_type) {
@ -4004,7 +4017,7 @@ e1000_wait_autoneg(struct e1000_hw *hw)
DEBUGFUNC();
DEBUGOUT("Waiting for Auto-Neg to complete.\n");
/* We will wait for autoneg to complete or 4.5 seconds to expire. */
/* We will wait for autoneg to complete or timeout to expire. */
for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
/* Read the MII Status Register and wait for Auto-Neg
* Complete bit to be set.
@ -4438,6 +4451,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
if (hw->mac_type >= e1000_82571)
mdelay(10);
} else {
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
* bit to put the PHY into reset. Then, take it out of reset.
@ -4462,6 +4476,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
}
e1000_swfw_sync_release(hw, swfw);
/* Wait for FW to finish PHY configuration. */
ret_val = e1000_get_phy_cfg_done(hw);
if (ret_val != E1000_SUCCESS)

View File

@ -2460,7 +2460,7 @@ struct e1000_hw {
#define MII_CR_SPEED_100 0x2000
#define MII_CR_SPEED_10 0x0000
#define E1000_PHY_ADDRESS 0x01
#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
#define PHY_AUTO_NEG_TIME 80 /* 8.0 Seconds */
#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
#define PHY_REVISION_MASK 0xFFFFFFF0
#define DEVICE_SPEED_MASK 0x00000300 /* Device Ctrl Reg Speed Mask */
@ -2496,7 +2496,6 @@ struct e1000_hw {
#define ICH_GFPREG_BASE_MASK 0x1FFF
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
#define E1000_I210_SW_FW_SYNC 0x5B50 /* Software-Firmware Synchronization - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
/* SPI EEPROM Status Register */

View File

@ -520,6 +520,7 @@ static int fm_eth_recv(struct eth_device *dev)
u16 status, len;
u8 *data;
u16 offset_out;
int ret = 1;
fm_eth = (struct fm_eth *)dev->priv;
pram = fm_eth->rx_pram;
@ -533,7 +534,7 @@ static int fm_eth_recv(struct eth_device *dev)
net_process_received_packet(data, len);
} else {
printf("%s: Rx error\n", dev->name);
return 0;
ret = 0;
}
/* clear the RxBDs */
@ -559,7 +560,7 @@ static int fm_eth_recv(struct eth_device *dev)
}
fm_eth->cur_rxbd = (void *)rxbd;
return 1;
return ret;
}
static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)

View File

@ -151,7 +151,7 @@ struct lpc32xx_eth_registers {
#define SUPP_SPEED 0x00000100
/* MCFG register bitfields/masks and offsets (see Table 292) */
#define MCFG_CLOCK_SELECT_MASK 0x0000001C
#define MCFG_RESET_MII_MGMT 0x00008000
/* divide clock by 28 (see Table 293) */
#define MCFG_CLOCK_SELECT_DIV28 0x0000001C
@ -168,9 +168,10 @@ struct lpc32xx_eth_registers {
#define COMMAND_RXENABLE 0x00000001
#define COMMAND_TXENABLE 0x00000002
#define COMMAND_PASSRUNTFRAME 0x00000040
#define COMMAND_RMII 0x00000200
#define COMMAND_FULL_DUPLEX 0x00000400
/* Helper: general reset */
#define COMMAND_RESETS 0x0000001C
#define COMMAND_RESETS 0x00000038
/* STATUS register bitfields/masks and offsets (see Table 283) */
#define STATUS_RXSTATUS 0x00000001
@ -201,6 +202,7 @@ struct lpc32xx_eth_device {
struct eth_device dev;
struct lpc32xx_eth_registers *regs;
struct lpc32xx_eth_buffers *bufs;
bool phy_rmii;
};
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device))
@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static struct lpc32xx_eth_device lpc32xx_eth = {
.regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE,
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS,
#if defined(CONFIG_RMII)
.phy_rmii = true,
#endif
};
#define TX_TIMEOUT 10000
@ -459,8 +464,22 @@ static int lpc32xx_eth_init(struct eth_device *dev)
struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs;
int index;
/* Release SOFT reset to let MII talk to PHY */
clrbits_le32(&regs->mac1, MAC1_SOFT_RESET);
/* Initial MAC initialization */
writel(MAC1_PASS_ALL_RX_FRAMES, &regs->mac1);
writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, &regs->mac2);
writel(PKTSIZE_ALIGN, &regs->maxf);
/* Retries: 15 (0xF). Collision window: 57 (0x37). */
writel(0x370F, &regs->clrt);
/* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */
writel(0x0012, &regs->ipgr);
/* pass runt (smaller than 64 bytes) frames */
if (lpc32xx_eth_device->phy_rmii)
writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, &regs->command);
else
writel(COMMAND_PASSRUNTFRAME, &regs->command);
/* Configure Full/Half Duplex mode */
if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) {
@ -477,20 +496,6 @@ static int lpc32xx_eth_init(struct eth_device *dev)
else
writel(0, &regs->supp);
/* Initial MAC initialization */
writel(MAC1_PASS_ALL_RX_FRAMES, &regs->mac1);
writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, &regs->mac2);
writel(PKTSIZE_ALIGN, &regs->maxf);
/* Retries: 15 (0xF). Collision window: 57 (0x37). */
writel(0x370F, &regs->clrt);
/* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */
writel(0x0012, &regs->ipgr);
/* pass runt (smaller than 64 bytes) frames */
writel(COMMAND_PASSRUNTFRAME, &regs->command);
/* Save station address */
writel((unsigned long) (dev->enetaddr[0] |
(dev->enetaddr[1] << 8)), &regs->sa2);
@ -562,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev)
#if defined(CONFIG_PHYLIB)
int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid)
{
struct lpc32xx_eth_device *lpc32xx_eth_device =
container_of(dev, struct lpc32xx_eth_device, dev);
struct mii_dev *bus;
struct phy_device *phydev;
int ret;
@ -582,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid)
return -ENOMEM;
}
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII);
if (lpc32xx_eth_device->phy_rmii)
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII);
else
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII);
if (!phydev) {
printf("phy_connect failed\n");
return -ENODEV;
@ -604,7 +615,7 @@ int lpc32xx_eth_initialize(bd_t *bis)
* Set RMII management clock rate. With HCLK at 104 MHz and
* a divider of 28, this will be 3.72 MHz.
*/
writel(MCFG_RESET_MII_MGMT, &regs->mcfg);
writel(MCFG_CLOCK_SELECT_DIV28, &regs->mcfg);
/* Reset all MAC logic */
@ -630,7 +641,7 @@ int lpc32xx_eth_initialize(bd_t *bis)
eth_register(dev);
#if defined(CONFIG_PHYLIB)
lpc32xx_eth_phylib_init(dev, 0);
lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR);
#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, mii_reg_read, mii_reg_write);
#endif

View File

@ -54,6 +54,7 @@ struct macb_dma_desc {
#define DMA_DESC_BYTES(n) (n * sizeof(struct macb_dma_desc))
#define MACB_TX_DMA_DESC_SIZE (DMA_DESC_BYTES(MACB_TX_RING_SIZE))
#define MACB_RX_DMA_DESC_SIZE (DMA_DESC_BYTES(MACB_RX_RING_SIZE))
#define MACB_TX_DUMMY_DMA_DESC_SIZE (DMA_DESC_BYTES(1))
#define RXADDR_USED 0x00000001
#define RXADDR_WRAP 0x00000002
@ -93,6 +94,9 @@ struct macb_device {
unsigned long rx_ring_dma;
unsigned long tx_ring_dma;
struct macb_dma_desc *dummy_desc;
unsigned long dummy_desc_dma;
const struct device *dev;
struct eth_device netdev;
unsigned short phy_addr;
@ -525,6 +529,30 @@ static int macb_phy_init(struct macb_device *macb)
return 1;
}
static int gmac_init_multi_queues(struct macb_device *macb)
{
int i, num_queues = 1;
u32 queue_mask;
/* bit 0 is never set but queue 0 always exists */
queue_mask = gem_readl(macb, DCFG6) & 0xff;
queue_mask |= 0x1;
for (i = 1; i < MACB_MAX_QUEUES; i++)
if (queue_mask & (1 << i))
num_queues++;
macb->dummy_desc->ctrl = TXBUF_USED;
macb->dummy_desc->addr = 0;
flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma +
MACB_TX_DUMMY_DMA_DESC_SIZE);
for (i = 1; i < num_queues; i++)
gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1);
return 0;
}
static int macb_init(struct eth_device *netdev, bd_t *bd)
{
struct macb_device *macb = to_macb(netdev);
@ -565,6 +593,9 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
macb_writel(macb, TBQP, macb->tx_ring_dma);
if (macb_is_gem(macb)) {
/* Check the multi queue and initialize the queue for tx */
gmac_init_multi_queues(macb);
/*
* When the GMAC IP with GE feature, this bit is used to
* select interface between RGMII and GMII.
@ -712,6 +743,8 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
&macb->rx_ring_dma);
macb->tx_ring = dma_alloc_coherent(MACB_TX_DMA_DESC_SIZE,
&macb->tx_ring_dma);
macb->dummy_desc = dma_alloc_coherent(MACB_TX_DUMMY_DMA_DESC_SIZE,
&macb->dummy_desc_dma);
/* TODO: we need check the rx/tx_ring_dma is dcache line aligned */

View File

@ -60,6 +60,13 @@
/* GEM specific register offsets */
#define GEM_DCFG1 0x0280
#define GEM_DCFG6 0x0294
#define MACB_MAX_QUEUES 8
/* GEM specific multi queues register offset */
/* hw_q can be 0~7 */
#define GEM_TBQP(hw_q) (0x0440 + ((hw_q) << 2))
/* Bitfields in NCR */
#define MACB_LB_OFFSET 0
@ -309,5 +316,7 @@
readl((port)->regs + GEM_##reg)
#define gem_writel(port, reg, value) \
writel((value), (port)->regs + GEM_##reg)
#define gem_writel_queue_TBQP(port, value, queue_num) \
writel((value), (port)->regs + GEM_TBQP(queue_num))
#endif /* __DRIVERS_MACB_H__ */

View File

@ -137,6 +137,24 @@ static int bcm5482_config(struct phy_device *phydev)
return 0;
}
static int bcm_cygnus_startup(struct phy_device *phydev)
{
/* Read the Status (2x to make sure link is right) */
genphy_update_link(phydev);
genphy_parse_link(phydev);
return 0;
}
static int bcm_cygnus_config(struct phy_device *phydev)
{
genphy_config_aneg(phydev);
phy_reset(phydev);
return 0;
}
/*
* Find out if PHY is in copper or serdes mode by looking at Expansion Reg
* 0x42 - "Operating Mode Status Register"
@ -264,11 +282,22 @@ static struct phy_driver BCM5482S_driver = {
.shutdown = &genphy_shutdown,
};
static struct phy_driver BCM_CYGNUS_driver = {
.name = "Broadcom CYGNUS GPHY",
.uid = 0xae025200,
.mask = 0xfffff0,
.features = PHY_GBIT_FEATURES,
.config = &bcm_cygnus_config,
.startup = &bcm_cygnus_startup,
.shutdown = &genphy_shutdown,
};
int phy_broadcom_init(void)
{
phy_register(&BCM5482S_driver);
phy_register(&BCM5464S_driver);
phy_register(&BCM5461S_driver);
phy_register(&BCM_CYGNUS_driver);
return 0;
}

View File

@ -303,30 +303,58 @@ static int m88e1518_config(struct phy_device *phydev)
* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
* /88E1514 Rev A0, Errata Section 3.1
*/
/* EEE initialization */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000);
/* SGMII-to-Copper mode initialization */
if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); /* page 0xff */
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); /* reg page 0 */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); /* reg page 18 */
/* Write HWCFG_MODE = SGMII to Copper */
/* Select page 18 */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 18);
/* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
m88e1518_phy_writebits(phydev, 20, 0, 3, 1);
/* Phy reset */
/* PHY reset is necessary after changing MODE[2:0] */
m88e1518_phy_writebits(phydev, 20, 15, 1, 1);
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); /* reg page 18 */
/* Reset page selection */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
udelay(100);
}
return m88e1111s_config(phydev);
}
/* Marvell 88E1510 */
static int m88e1510_config(struct phy_device *phydev)
{
/* Select page 3 */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
/* Enable INTn output on LED[2] */
m88e1518_phy_writebits(phydev, 18, 7, 1, 1);
/* Configure LEDs */
m88e1518_phy_writebits(phydev, 16, 0, 4, 3); /* LED[0]:0011 (ACT) */
m88e1518_phy_writebits(phydev, 16, 4, 4, 6); /* LED[1]:0110 (LINK) */
/* Reset page selection */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
return m88e1518_config(phydev);
}
/* Marvell 88E1118 */
static int m88e1118_config(struct phy_device *phydev)
{
@ -539,6 +567,16 @@ static struct phy_driver M88E1149S_driver = {
.shutdown = &genphy_shutdown,
};
static struct phy_driver M88E1510_driver = {
.name = "Marvell 88E1510",
.uid = 0x1410dd0,
.mask = 0xffffff0,
.features = PHY_GBIT_FEATURES,
.config = &m88e1510_config,
.startup = &m88e1011s_startup,
.shutdown = &genphy_shutdown,
};
static struct phy_driver M88E1518_driver = {
.name = "Marvell 88E1518",
.uid = 0x1410dd1,
@ -569,6 +607,7 @@ int phy_marvell_init(void)
phy_register(&M88E1118R_driver);
phy_register(&M88E1111S_driver);
phy_register(&M88E1011S_driver);
phy_register(&M88E1510_driver);
phy_register(&M88E1518_driver);
return 0;

View File

@ -554,7 +554,7 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev,
}
static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
int phy_id,
u32 phy_id,
phy_interface_t interface)
{
struct phy_device *dev;
@ -763,11 +763,13 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
phy_interface_t interface)
{
/* Reset the bus */
if (bus->reset)
if (bus->reset) {
bus->reset(bus);
/* Wait 15ms to make sure the PHY has come out of hard reset */
udelay(15000);
/* Wait 15ms to make sure the PHY has come out of hard reset */
udelay(15000);
}
return get_phy_device_by_mask(bus, phy_mask, interface);
}

View File

@ -41,6 +41,7 @@
#define MIIM_RTL8211F_PAGE_SELECT 0x1f
#define MIIM_RTL8211F_TX_DELAY 0x100
#define MIIM_RTL8211F_LCR 0x10
/* RealTek RTL8211x */
static int rtl8211x_config(struct phy_device *phydev)
@ -79,6 +80,13 @@ static int rtl8211f_config(struct phy_device *phydev)
MIIM_RTL8211F_PAGE_SELECT, 0x0);
}
/* Set green LED for Link, yellow LED for Active */
phy_write(phydev, MDIO_DEVAD_NONE,
MIIM_RTL8211F_PAGE_SELECT, 0xd04);
phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f);
phy_write(phydev, MDIO_DEVAD_NONE,
MIIM_RTL8211F_PAGE_SELECT, 0x0);
genphy_config_aneg(phydev);
return 0;

View File

@ -249,6 +249,8 @@ static void show_block_marker(void)
if (tftp_tsize) {
ulong pos = tftp_cur_block * tftp_block_size +
tftp_block_wrap_offset;
if (pos > tftp_tsize)
pos = tftp_tsize;
while (tftp_tsize_num_hash < pos * 50 / tftp_tsize) {
putc('#');