cgtqmx6eval: Add Ethernet support
cgtqmx6eval can be populated with a AR8035 or KSZ9031 depending on the board revision. Add Ethernet support. Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
This commit is contained in:
parent
066f876bf6
commit
f02229021d
@ -27,6 +27,10 @@
|
||||
#include <power/pfuze100_pmic.h>
|
||||
#include <linux/fb.h>
|
||||
#include <ipu_pixfmt.h>
|
||||
#include <malloc.h>
|
||||
#include <miiphy.h>
|
||||
#include <netdev.h>
|
||||
#include <micrel.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -43,6 +47,11 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define MX6Q_QMX6_PFUZE_MUX IMX_GPIO_NR(6, 9)
|
||||
|
||||
|
||||
#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
|
||||
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
|
||||
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
|
||||
@ -98,6 +107,51 @@ static iomux_v3_cfg_t const usb_otg_pads[] = {
|
||||
MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
};
|
||||
|
||||
static iomux_v3_cfg_t enet_pads_ksz9031[] = {
|
||||
MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
};
|
||||
|
||||
static iomux_v3_cfg_t enet_pads_final_ksz9031[] = {
|
||||
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
};
|
||||
|
||||
static iomux_v3_cfg_t enet_pads_ar8035[] = {
|
||||
MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
||||
};
|
||||
|
||||
#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
|
||||
struct i2c_pads_info i2c_pad_info1 = {
|
||||
.scl = {
|
||||
@ -169,6 +223,159 @@ int power_init_board(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
struct phy_device *phydev;
|
||||
struct mii_dev *bus;
|
||||
unsigned short id1, id2;
|
||||
int ret;
|
||||
|
||||
iomux_v3_cfg_t enet_reset = MX6_PAD_EIM_D23__GPIO3_IO23 |
|
||||
MUX_PAD_CTRL(NO_PAD_CTRL);
|
||||
|
||||
/* check whether KSZ9031 or AR8035 has to be configured */
|
||||
imx_iomux_v3_setup_multiple_pads(enet_pads_ar8035,
|
||||
ARRAY_SIZE(enet_pads_ar8035));
|
||||
imx_iomux_v3_setup_pad(enet_reset);
|
||||
|
||||
/* phy reset */
|
||||
gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
|
||||
udelay(2000);
|
||||
gpio_set_value(IMX_GPIO_NR(3, 23), 1);
|
||||
udelay(500);
|
||||
|
||||
bus = fec_get_miibus(IMX_FEC_BASE, -1);
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
|
||||
if (!phydev) {
|
||||
printf("Error: phy device not found.\n");
|
||||
ret = -ENODEV;
|
||||
goto free_bus;
|
||||
}
|
||||
|
||||
/* get the PHY id */
|
||||
id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
|
||||
id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
|
||||
|
||||
if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
|
||||
/* re-configure for Micrel KSZ9031 */
|
||||
printf("configure Micrel KSZ9031 Ethernet Phy at address %d\n",
|
||||
phydev->addr);
|
||||
|
||||
/* phy reset: gpio3-23 */
|
||||
gpio_set_value(IMX_GPIO_NR(3, 23), 0);
|
||||
gpio_set_value(IMX_GPIO_NR(6, 30), (phydev->addr >> 2));
|
||||
gpio_set_value(IMX_GPIO_NR(6, 25), 1);
|
||||
gpio_set_value(IMX_GPIO_NR(6, 27), 1);
|
||||
gpio_set_value(IMX_GPIO_NR(6, 28), 1);
|
||||
gpio_set_value(IMX_GPIO_NR(6, 29), 1);
|
||||
imx_iomux_v3_setup_multiple_pads(enet_pads_ksz9031,
|
||||
ARRAY_SIZE(enet_pads_ksz9031));
|
||||
gpio_set_value(IMX_GPIO_NR(6, 24), 1);
|
||||
udelay(500);
|
||||
gpio_set_value(IMX_GPIO_NR(3, 23), 1);
|
||||
imx_iomux_v3_setup_multiple_pads(enet_pads_final_ksz9031,
|
||||
ARRAY_SIZE(enet_pads_final_ksz9031));
|
||||
} else if ((id1 == 0x004d) && (id2 == 0xd072)) {
|
||||
/* configure Atheros AR8035 - actually nothing to do */
|
||||
printf("configure Atheros AR8035 Ethernet Phy at address %d\n",
|
||||
phydev->addr);
|
||||
} else {
|
||||
printf("Unknown Ethernet-Phy: 0x%04x 0x%04x\n", id1, id2);
|
||||
ret = -EINVAL;
|
||||
goto free_phydev;
|
||||
}
|
||||
|
||||
ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
|
||||
if (ret)
|
||||
goto free_phydev;
|
||||
|
||||
return 0;
|
||||
|
||||
free_phydev:
|
||||
free(phydev);
|
||||
free_bus:
|
||||
free(bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mx6_rgmii_rework(struct phy_device *phydev)
|
||||
{
|
||||
unsigned short id1, id2;
|
||||
unsigned short val;
|
||||
|
||||
/* check whether KSZ9031 or AR8035 has to be configured */
|
||||
id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
|
||||
id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
|
||||
|
||||
if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
|
||||
/* finalize phy configuration for Micrel KSZ9031 */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 4);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x0000);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 5);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_REG);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 6);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0xFFFF);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 8);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3FFF);
|
||||
|
||||
/* fix KSZ9031 link up issue */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x0);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x4);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x6);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_REG);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x1A80);
|
||||
}
|
||||
|
||||
if ((id1 == 0x004d) && (id2 == 0xd072)) {
|
||||
/* enable AR8035 ouput a 125MHz clk from CLK_25M */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x7);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_DATA_POST_INC_RW | 0x16);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC | 0x7);
|
||||
val = phy_read(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA);
|
||||
val &= 0xfe63;
|
||||
val |= 0x18;
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, val);
|
||||
|
||||
/* introduce tx clock delay */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
|
||||
val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
|
||||
val |= 0x0100;
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
|
||||
|
||||
/* disable hibernation */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0xb);
|
||||
val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3c40);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_phy_config(struct phy_device *phydev)
|
||||
{
|
||||
mx6_rgmii_rework(phydev);
|
||||
|
||||
if (phydev->drv->config)
|
||||
phydev->drv->config(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_iomux_uart(void)
|
||||
{
|
||||
|
@ -97,6 +97,19 @@
|
||||
#define CONFIG_LBA48
|
||||
#define CONFIG_LIBATA
|
||||
|
||||
/* Ethernet */
|
||||
#define CONFIG_CMD_PING
|
||||
#define CONFIG_CMD_DHCP
|
||||
#define CONFIG_CMD_MII
|
||||
#define CONFIG_FEC_MXC
|
||||
#define CONFIG_MII
|
||||
#define IMX_FEC_BASE ENET_BASE_ADDR
|
||||
#define CONFIG_FEC_XCV_TYPE RGMII
|
||||
#define CONFIG_ETHPRIME "FEC"
|
||||
#define CONFIG_FEC_MXC_PHYADDR 6
|
||||
#define CONFIG_PHYLIB
|
||||
#define CONFIG_PHY_ATHEROS
|
||||
|
||||
/* Command definition */
|
||||
|
||||
#define CONFIG_MXC_UART_BASE UART2_BASE
|
||||
|
@ -20,6 +20,10 @@
|
||||
#define MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW 0x6
|
||||
#define MII_KSZ9031_EXT_RGMII_CLOCK_SKEW 0x8
|
||||
|
||||
/* Registers */
|
||||
#define MMD_ACCESS_CONTROL 0xd
|
||||
#define MMD_ACCESS_REG_DATA 0xe
|
||||
|
||||
struct phy_device;
|
||||
int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val);
|
||||
int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum);
|
||||
|
Loading…
Reference in New Issue
Block a user