void __init stxh205_configure_ethernet(struct stxh205_ethernet_config *config) { static int configured; struct stxh205_ethernet_config default_config; struct plat_stmmacenet_data *plat_data; struct stm_pad_config *pad_config; int interface; struct clk *clk; BUG_ON(configured++); if (!config) config = &default_config; plat_data = &stxh205_ethernet_platform_data; switch (config->mode) { case stxh205_ethernet_mode_mii: pad_config = &stxh205_ethernet_mii_pad_config; if (config->ext_clk) stm_pad_set_pio_ignored(pad_config, "PHYCLK"); else stm_pad_set_pio_out(pad_config, "PHYCLK", 1); if (config->no_txer) stm_pad_set_pio_ignored(pad_config, "TXER"); interface = PHY_INTERFACE_MODE_MII; break; case stxh205_ethernet_mode_rmii: pad_config = &stxh205_ethernet_rmii_pad_config; if (config->ext_clk) { stm_pad_set_pio_in(pad_config, "PHYCLK", 2); /* ETH_SEL_INTERNAL_NOTEXT_PHYCLK */ pad_config->sysconfs[4].value = 0; } else { stm_pad_set_pio_out(pad_config, "PHYCLK", 1); /* ETH_SEL_INTERNAL_NOTEXT_PHYCLK */ pad_config->sysconfs[4].value = 1; } interface = PHY_INTERFACE_MODE_RMII; break; case stxh205_ethernet_mode_reverse_mii: pad_config = &stxh205_ethernet_reverse_mii_pad_config; if (config->ext_clk) stm_pad_set_pio_ignored(pad_config, "PHYCLK"); else stm_pad_set_pio_out(pad_config, "PHYCLK", 1); if (config->no_txer) stm_pad_set_pio_ignored(pad_config, "TXER"); interface = PHY_INTERFACE_MODE_MII; break; default: BUG(); return; } plat_data->custom_cfg = (void *) pad_config; plat_data->interface = interface; plat_data->bus_id = config->phy_bus; plat_data->phy_addr = config->phy_addr; plat_data->mdio_bus_data = config->mdio_bus_data; clk = clk_get(NULL, "stmmac_clk"); if (!IS_ERR(clk)) clk_enable(clk); clk = clk_get(NULL, "stmmac_phy_clk"); if (!IS_ERR(clk)) clk_enable(clk); platform_device_register(&stxh205_ethernet_device); }
/* ONLY MII mode on GMAC1 is tested */ void __init stih415_configure_ethernet(int port, struct stih415_ethernet_config *config) { static int configured[ARRAY_SIZE(stih415_ethernet_devices)]; struct stih415_ethernet_config default_config; struct plat_stmmacenet_data *plat_data; struct stm_pad_config *pad_config; BUG_ON(port < 0 || port >= ARRAY_SIZE(stih415_ethernet_devices)); BUG_ON(configured[port]++); if (!config) config = &default_config; plat_data = &stih415_ethernet_platform_data[port]; switch (config->interface) { case PHY_INTERFACE_MODE_MII: pad_config = &stih415_ethernet_mii_pad_configs[port]; if (config->ext_clk) stm_pad_set_pio_ignored(pad_config, "PHYCLK"); else stm_pad_set_pio_out(pad_config, "PHYCLK", 1 + port); break; case PHY_INTERFACE_MODE_GMII: pad_config = &stih415_ethernet_gmii_pad_configs[port]; stm_pad_set_pio_out(pad_config, "PHYCLK", 4); if (port == 0) plat_data->fix_mac_speed = stih415_ethernet_gmii0_speed; else plat_data->fix_mac_speed = stih415_ethernet_gmii1_speed; plat_data->bsp_priv = config->txclk_select; break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID: /* This mode is similar to GMII (GTX) except the data * buses are reduced down to 4 bits and the 2 error * signals are removed. The data rate is maintained by * using both edges of the clock. This also explains * the different retiming configuration for this mode. */ pad_config = &stih415_ethernet_rgmii_pad_configs[port]; stm_pad_set_pio_out(pad_config, "PHYCLK", 4); if (port == 0) plat_data->fix_mac_speed = stih415_ethernet_rgmii0_gtx_speed; else plat_data->fix_mac_speed = stih415_ethernet_rgmii1_gtx_speed; /* Configure so that stmmac gets clock */ plat_data->bsp_priv = config->txclk_select; break; case PHY_INTERFACE_MODE_RMII: { struct sysconf_field *sc; pad_config = &stih415_ethernet_rmii_pad_configs[port]; /* SEL_INTERNAL_NO_EXT_PHYCLK */ if (!port) sc = sysconf_claim(2, 82, 7, 7, "rmii"); else sc = sysconf_claim(0, 29, 7, 7, "rmii"); if (config->ext_clk) { stm_pad_set_pio_in(pad_config, "PHYCLK", 3 - port); /* SEL_INTERNAL_NO_EXT_PHYCLK */ sysconf_write(sc, 0); } else { unsigned long phy_clk_rate; struct clk *phy_clk = clk_get(NULL, gmac_clk_n[port]); BUG_ON(!phy_clk); stm_pad_set_pio_out(pad_config, "PHYCLK", 2 - port); phy_clk_rate = 50000000; clk_set_rate(phy_clk, phy_clk_rate); /* SEL_INTERNAL_NO_EXT_PHYCLK */ sysconf_write(sc, 1); } } break; case PHY_INTERFACE_MODE_REV_MII: pad_config = &stih415_ethernet_reverse_mii_pad_configs[port]; if (config->ext_clk) stm_pad_set_pio_ignored(pad_config, "PHYCLK"); else stm_pad_set_pio_out(pad_config, "PHYCLK", 1 + port); break; default: BUG(); return; } plat_data->custom_cfg = (void *) pad_config; plat_data->interface = config->interface; plat_data->bus_id = config->phy_bus; plat_data->phy_bus_name = config->phy_bus_name; plat_data->phy_addr = config->phy_addr; plat_data->mdio_bus_data = config->mdio_bus_data; if (!config->mdio_bus_data) { stm_pad_set_pio_ignored(pad_config, "MDC"); stm_pad_set_pio_ignored(pad_config, "MDIO"); } platform_device_register(&stih415_ethernet_devices[port]); }
void __init stx7108_configure_ethernet(int port, struct stx7108_ethernet_config *config) { static int configured[ARRAY_SIZE(stx7108_ethernet_devices)]; struct stx7108_ethernet_config default_config; struct plat_stmmacenet_data *plat_data; struct stm_pad_config *pad_config; int interface; BUG_ON(port < 0 || port >= ARRAY_SIZE(stx7108_ethernet_devices)); BUG_ON(configured[port]++); if (!config) config = &default_config; plat_data = &stx7108_ethernet_platform_data[port]; switch (config->mode) { case stx7108_ethernet_mode_mii: pad_config = &stx7108_ethernet_mii_pad_configs[port]; if (config->ext_clk) stm_pad_set_pio_ignored(pad_config, "PHYCLK"); else stm_pad_set_pio_out(pad_config, "PHYCLK", 1 + port); interface = PHY_INTERFACE_MODE_MII; break; case stx7108_ethernet_mode_gmii: pad_config = &stx7108_ethernet_gmii_pad_configs[port]; stm_pad_set_pio_ignored(pad_config, "PHYCLK"); interface = PHY_INTERFACE_MODE_GMII; break; case stx7108_ethernet_mode_gmii_gtx: pad_config = &stx7108_ethernet_gmii_pad_configs[port]; stm_pad_set_pio_out(pad_config, "PHYCLK", 1 + port); plat_data->fix_mac_speed = stx7108_ethernet_gtx_speed; plat_data->bsp_priv = config->txclk_select; interface = PHY_INTERFACE_MODE_GMII; break; case stx7108_ethernet_mode_rgmii_gtx: /* This mode is similar to GMII (GTX) except the data * buses are reduced down to 4 bits and the 2 error * signals are removed. The data rate is maintained by * using both edges of the clock. This also explains * the different retiming configuration for this mode. */ pad_config = &stx7108_ethernet_rgmii_pad_configs[port]; stm_pad_set_pio_out(pad_config, "PHYCLK", 1 + port); plat_data->fix_mac_speed = stx7108_ethernet_gtx_speed; plat_data->bsp_priv = config->txclk_select; interface = PHY_INTERFACE_MODE_RGMII; break; case stx7108_ethernet_mode_rmii: /* GMAC1 only tested */ pad_config = &stx7108_ethernet_rmii_pad_configs[port]; if (config->ext_clk) stm_pad_set_pio_in(pad_config, "PHYCLK", 2 + port); else { unsigned long phy_clk_rate; struct clk *phy_clk = clk_get(NULL, "CLKA_ETH_PHY_1"); BUG_ON(!phy_clk); stm_pad_set_pio_out(pad_config, "PHYCLK", 1 + port); phy_clk_rate = 50000000; clk_set_rate(phy_clk, phy_clk_rate); } plat_data->fix_mac_speed = stx7108_ethernet_rmii_speed; /* MIIx_MAC_SPEED_SEL */ if (port == 0) plat_data->bsp_priv = sysconf_claim(SYS_CFG_BANK2, 27, 1, 1, "stmmac"); else plat_data->bsp_priv = sysconf_claim(SYS_CFG_BANK4, 23, 1, 1, "stmmac"); interface = PHY_INTERFACE_MODE_RMII; break; case stx7108_ethernet_mode_reverse_mii: pad_config = &stx7108_ethernet_reverse_mii_pad_configs[port]; if (config->ext_clk) stm_pad_set_pio_ignored(pad_config, "PHYCLK"); else stm_pad_set_pio_out(pad_config, "PHYCLK", 1 + port); interface = PHY_INTERFACE_MODE_MII; break; default: BUG(); return; } stx7108_ethernet_platform_data[port].bus_setup = stx7108_ethernet_bus_setup; plat_data->custom_cfg = (void *) pad_config; plat_data->interface = interface; plat_data->bus_id = config->phy_bus; plat_data->phy_addr = config->phy_addr; plat_data->mdio_bus_data = config->mdio_bus_data; stx7108_pio_dump_pad_config(stx7108_ethernet_devices[port].name, port, pad_config); platform_device_register(&stx7108_ethernet_devices[port]); }