Commit 0ee5d6e6 authored by Alexander Potashev's avatar Alexander Potashev

RT73025. ea-lpc1788: Ethernet driver

* The driver structure is almost the same as in the STM32 Ethernet driver.
* The PHY autodetection code was copied from the STM32 Ethernet driver
    (see `lpc178x_phy_init()`)
* The speed/duplex detection logic grabbed from the Linux kernel
    (see linux/drivers/net/phy/phy_device.c)
* The DMA used for Ethernet cannot work with the SoC-internal "System
    RAM", thus we use the external memory (SDRAM) for DMA descriptors
    and buffers.
parent e24bb062
......@@ -24,6 +24,7 @@
*/
#include <common.h>
#include <netdev.h>
#include <asm/arch/lpc178x_gpio.h>
......@@ -251,6 +252,9 @@ DECLARE_GLOBAL_DATA_PTR;
* the code in `gpio_init()`.
*/
static const struct lpc178x_gpio_pin_config ea_lpc1788_gpio[] = {
/*
* GPIO configuration for UART
*/
#if CONFIG_LPC178X_UART_PORT == 0
/* P0.2 (D) = UART0 TXD */
{{0, 2}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
......@@ -266,6 +270,9 @@ static const struct lpc178x_gpio_pin_config ea_lpc1788_gpio[] = {
#endif
#ifdef CONFIG_NR_DRAM_BANKS
/*
* GPIO configuration for SDRAM
*/
#define LPC178X_GPIO_EMC_REGVAL \
(LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0))
......@@ -294,7 +301,33 @@ static const struct lpc178x_gpio_pin_config ea_lpc1788_gpio[] = {
{{2, 29}, LPC178X_GPIO_EMC_REGVAL},
{{2, 30}, LPC178X_GPIO_EMC_REGVAL},
{{2, 31}, LPC178X_GPIO_EMC_REGVAL},
#endif
#endif /* CONFIG_NR_DRAM_BANKS */
#ifdef CONFIG_LPC178X_ETH
/*
* GPIO configuration for Ethernet
*/
/* P1.0 (D) = RMII ENET_TXD0 */
{{1, 0}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0)},
/* P1.1 (D) = RMII ENET_TXD1 */
{{1, 1}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0)},
/* P1.4 (D) = RMII ENET_TX_EN */
{{1, 4}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0)},
/* P1.8 (D) = RMII CRS */
{{1, 8}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0)},
/* P1.9 (D) = RMII RXD0 */
{{1, 9}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0)},
/* P1.10 (D) = RMII RXD1 */
{{1, 10}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0)},
/* P1.14 (D) = RMII RXER */
{{1, 14}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
/* P1.15 (D) = RMII CLK */
{{1, 15}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
/* P1.16 (D) = RMII MCD */
{{1, 16}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
/* P1.17 (D) = RMII MDIO */
{{1, 17}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
#endif /* CONFIG_LPC178X_ETH */
};
/*
......@@ -472,3 +505,13 @@ int dram_init(void)
return 0;
}
#ifdef CONFIG_LPC178X_ETH
/*
* Register ethernet driver
*/
int board_eth_init(bd_t *bis)
{
return lpc178x_eth_driver_init(bis);
}
#endif
......@@ -224,6 +224,93 @@ static u32 clock_val[CLOCK_END];
#define LPC178X_PLL_FEED_KEY1 0xAA
#define LPC178X_PLL_FEED_KEY2 0x55
/*
* Verify that the Ethernet clock divider value results in a
* PHY REF_CLK that does not exceed 2.5 MHz.
*/
#ifdef CONFIG_LPC178X_ETH
#if !defined(CONFIG_LPC178X_ETH_DIV_SEL)
#error CONFIG_LPC178X_ETH_DIV_SEL is not set
#elif CONFIG_LPC178X_ETH_DIV_SEL == 0 /* HCLK/4 */
#if LPC178X_EMC_RATE > 10 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
/* CONFIG_LPC178X_ETH_DIV_SEL=1 leads to the same HCLK/4 */
#elif CONFIG_LPC178X_ETH_DIV_SEL == 2 /* HCLK/6 */
#if LPC178X_EMC_RATE > 15 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 10 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 3 /* HCLK/8 */
#if LPC178X_EMC_RATE > 20 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 15 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 4 /* HCLK/10 */
#if LPC178X_EMC_RATE > 25 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 20 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 5 /* HCLK/14 */
#if LPC178X_EMC_RATE > 35 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 25 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 6 /* HCLK/20 */
#if LPC178X_EMC_RATE > 50 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 35 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 7 /* HCLK/28 */
#if LPC178X_EMC_RATE > 70 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 50 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 8 /* HCLK/36 */
#if LPC178X_EMC_RATE > 80 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 70 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 9 /* HCLK/40 */
#if LPC178X_EMC_RATE > 90 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 80 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 10 /* HCLK/44 */
#if LPC178X_EMC_RATE > 100 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 90 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#elif CONFIG_LPC178X_ETH_DIV_SEL == 11 /* HCLK/48 */
#if LPC178X_EMC_RATE > 120 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too small
#endif
#if LPC178X_EMC_RATE <= 100 * 1000 * 1000
#error CONFIG_LPC178X_ETH_DIV_SEL is too large
#endif
#else
#error Unknown value of CONFIG_LPC178X_ETH_DIV_SEL
#endif /* CONFIG_LPC178X_ETH_DIV_SEL */
#endif /* CONFIG_LPC178X_ETH */
/*
* Apply changes made in PLLCON and PLLCFG
*
......
......@@ -77,6 +77,7 @@ COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
COBJS-$(CONFIG_CORE10100) += core10100.o
COBJS-$(CONFIG_STM32_ETH) += stm32_eth.o
COBJS-$(CONFIG_LPC178X_ETH) += lpc178x_eth.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
......
This diff is collapsed.
......@@ -58,6 +58,7 @@
#define LPC178X_SCC_PCONP_PCGPIO_MSK (1 << 15)
#define LPC178X_SCC_PCONP_PCUART2_MSK (1 << 24)
#define LPC178X_SCC_PCONP_PCUART3_MSK (1 << 25)
#define LPC178X_SCC_PCONP_PCENET_MSK (1 << 30)
/*
* PLL register map
......
......@@ -165,6 +165,10 @@
#define CONFIG_SYS_RAM_BASE (0xA0000000 + \
(CONFIG_SYS_RAM_CS * 0x10000000))
#define CONFIG_SYS_RAM_SIZE (32 * 1024 * 1024)
/*
* Buffers for Ethernet DMA (cannot be in the internal System RAM)
*/
#define CONFIG_MEM_ETH_DMA_BUF_BASE 0xA1F00000 /* 31st megabyte */
/*
* Use the CPU_CLOCK/2 for EMC
*/
......@@ -217,7 +221,21 @@
/*
* Ethernet configuration
*/
/* TBD */
#define CONFIG_NET_MULTI
#define CONFIG_LPC178X_ETH
#define CONFIG_LPC178X_ENET_USE_PHY_RMII
#define CONFIG_LPC178X_ETH_DIV_SEL 7 /* HCLK/28 */
/*
* Ethernet RX buffers are malloced from the internal SRAM (more precisely,
* from CONFIG_SYS_MALLOC_LEN part of it). Each RX buffer has size of 1536B.
* So, keep this in mind when changing the value of the following config,
* which determines the number of ethernet RX buffers (number of frames which
* may be received without processing until overflow happens).
*/
#define CONFIG_SYS_RX_ETH_BUFFER 4
#define CONFIG_SYS_TX_ETH_BUFFER 4
/*
* Console I/O buffer size
......@@ -265,7 +283,7 @@
#undef CONFIG_CMD_IMLS
#undef CONFIG_CMD_LOADS
#undef CONFIG_CMD_MISC
#undef CONFIG_CMD_NET
#define CONFIG_CMD_NET /* Obligatory for the Ethernet driver to build */
#undef CONFIG_CMD_NFS
#undef CONFIG_CMD_SOURCE
#undef CONFIG_CMD_XIMG
......
......@@ -87,6 +87,7 @@ int sh_eth_initialize(bd_t *bis);
int dm9000_initialize(bd_t *bis);
int core_eth_init(bd_t *bis);
int stm32_eth_init(bd_t *bis);
int lpc178x_eth_driver_init(bd_t *bis);
/* Boards with PCI network controllers can call this from their board_eth_init()
* function to initialize whatever's on board.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment