/* * PIO alternative Function selector */ extern void stx7108_pioalt_select(const int port, const int pin, const int alt) { int num; unsigned long sysconf, *sysconfReg; #if 0 printf("%s(port=%d, pin=%d, alt=%d)\n", __func__, port, pin, alt); BUG_ON(pin < 0 || pin > 7); BUG_ON(alt < 0 || alt > 5); #endif switch (port) { case 0 ... 14: num = port; /* in Bank #2 */ sysconfReg = (unsigned long*)STX7108_BANK2_SYSGFG(num); break; case 15 ... 26: num = port - 15; /* in Bank #4 */ sysconfReg = (unsigned long*)STX7108_BANK4_SYSGFG(num); break; default: BUG(); return; } sysconf = readl(sysconfReg); SET_SYSCONF_BITS(sysconf, TRUE, pin*4,(pin*4)+3, alt,alt); writel(sysconf, sysconfReg); }
/* ETH MAC pad configuration */ static void stmac_eth_hw_setup(const int rmii, const int ext_clk, const int phy_bus) { unsigned long sysconf; sysconf = *STX5197_HD_CONF_MON_CONFIG_CONTROL_E; /* Ethernet interface on */ /* CFG_CTRL_E.ETHERNET_INTERFACE_ON = 1 [0] */ SET_SYSCONF_BIT(sysconf, 1, 0); /* MII plyclk out enable: 0=output, 1=input */ /* CFG_CTRL_E.MII_PHYCLK_OUT_EN = ext_clk ? 1 : 0 [6] */ SET_SYSCONF_BIT(sysconf, ext_clk, 6); /* RMII/MII pin mode */ /* CFG_CTRL_E.MII_ETHERNET_SEL = rmii ? 2 : 3 [8:7] */ SET_SYSCONF_BITS(sysconf, rmii, 7, 8, 0x2, 0x3); /* MII mode */ /* CFG_CTRL_E.MII_MODE = rmii ? 0 : 1 [2] */ SET_SYSCONF_BIT(sysconf, !rmii, 2); *STX5197_HD_CONF_MON_CONFIG_CONTROL_E = sysconf; }
/* * ETH GMAC PIO configuration */ extern void stx5206_configure_ethernet( const enum stx5206_ethernet_mode mode, const int ext_clk, const int phy_bus) { unsigned int phy_sel, enmii; unsigned long phy_clk_rate; unsigned long sysconf; switch (mode) { case stx5206_ethernet_mii: phy_sel = 0x0; enmii = 1; phy_clk_rate = 25000000; /* 25 MHz */ break; case stx5206_ethernet_rmii: phy_sel = 0x4; enmii = 1; phy_clk_rate = 50000000; /* 50 MHz */ break; case stx5206_ethernet_reverse_mii: phy_sel = 0x0; enmii = 0; phy_clk_rate = 25000000; /* 25 MHz */ break; default: BUG(); return; } /* ethernet_interface_on */ sysconf = readl(STX5206_SYSCONF_SYS_CFG07); SET_SYSCONF_BIT(sysconf, 1, ETHERNET_INTERFACE_ON); writel(sysconf, STX5206_SYSCONF_SYS_CFG07); /* phy_clk_ext: MII_PHYCLK pad function: 1 = phy clock is external, * 0 = phy clock is provided by STx5289 */ sysconf = readl(STX5206_SYSCONF_SYS_CFG07); SET_SYSCONF_BIT(sysconf, ext_clk, PHY_CLK_EXT); writel(sysconf, STX5206_SYSCONF_SYS_CFG07); /* phy_intf_sel */ sysconf = readl(STX5206_SYSCONF_SYS_CFG07); SET_SYSCONF_BITS(sysconf, 1, 24, 26, phy_sel, phy_sel); writel(sysconf, STX5206_SYSCONF_SYS_CFG07); /* enMii: 1 = MII mode, 0 = Reverse MII mode */ sysconf = readl(STX5206_SYSCONF_SYS_CFG07); SET_SYSCONF_BIT(sysconf, enmii, ENMII); writel(sysconf, STX5206_SYSCONF_SYS_CFG07); /* Set PHY clock frequency (if used) */ if (!ext_clk) { if (phy_clk_rate == 25000000) /* 25 MHz */ { /* CLKGENA.CLK_DIV_LS[13] = CLK_ETHERNET_PHY = 25 MHz */ writel(17, STX5206_CLOCKGENA_PLL0LS_DIV13_CFG); } #if 0 /* QQQ: Need to check this! */ else /* 50 MHz */ { /* CLKGENA.CLK_DIV_LS[13] = CLK_ETHERNET_PHY = 50 MHz */ writel(8, STX5206_CLOCKGENA_PLL0LS_DIV13_CFG); } #endif } }
/* ETH MAC pad configuration */ extern void stx7108_configure_ethernet( const int port, const struct stx7108_ethernet_config * const config) { unsigned long sysconf; int sc_regnum; struct stx7108_gmac_pin *pins; int pins_num; unsigned char phy_sel, enmii; int i; switch (port) { case 0: sc_regnum = 27; /* ENABLE_GMAC0 */ sysconf = *STX7108_MII_SYSGFG(53); SET_SYSCONF_BIT(sysconf, TRUE, ENABLE_GMAC); *STX7108_MII_SYSGFG(53) = sysconf; break; case 1: sc_regnum = 23; /* ENABLE_GMAC1 */ sysconf = *STX7108_MII_SYSGFG(67); SET_SYSCONF_BIT(sysconf, TRUE, ENABLE_GMAC); *STX7108_MII_SYSGFG(67) = sysconf; break; default: BUG(); return; }; switch (config->mode) { case stx7108_ethernet_mode_mii: phy_sel = 0; enmii = 1; pins = stx7108_gmac_mii_pins; pins_num = ARRAY_SIZE(stx7108_gmac_mii_pins); break; case stx7108_ethernet_mode_rmii: phy_sel = 4; enmii = 1; pins = stx7108_gmac_rmii_pins; pins_num = ARRAY_SIZE(stx7108_gmac_rmii_pins); break; case stx7108_ethernet_mode_gmii: phy_sel = 0; enmii = 1; pins = stx7108_gmac_gmii_pins; pins_num = ARRAY_SIZE(stx7108_gmac_gmii_pins); break; case stx7108_ethernet_mode_gmii_gtx: phy_sel = 0; enmii = 1; pins = stx7108_gmac_gmii_gtx_pins; pins_num = ARRAY_SIZE(stx7108_gmac_gmii_gtx_pins); break; case stx7108_ethernet_mode_reverse_mii: phy_sel = 0; enmii = 0; pins = stx7108_gmac_reverse_mii_pins; pins_num = ARRAY_SIZE(stx7108_gmac_reverse_mii_pins); break; default: BUG(); return; } /* MIIx_PHY_SEL */ sysconf = *STX7108_MII_SYSGFG(sc_regnum); SET_SYSCONF_BITS(sysconf, TRUE, 2,4, phy_sel,phy_sel); *STX7108_MII_SYSGFG(sc_regnum) = sysconf; /* ENMIIx */ sysconf = *STX7108_MII_SYSGFG(sc_regnum); SET_SYSCONF_BIT(sysconf, enmii, ENMII); *STX7108_MII_SYSGFG(sc_regnum) = sysconf; pins[0].dir = config->ext_clk ? IN : OUT; for (i = 0; i < pins_num; i++) { const struct stx7108_gmac_pin *pin = &pins[i]; int portno = pin->pio[port].port; int pinno = pin->pio[port].pin; struct stx7108_pioalt_retime_cfg retime_cfg = { -1, -1, -1, -1, -1, -1 /* -1 means "do not set */ }; stx7108_pioalt_select(portno, pinno, pin->pio[port].alt); stx7108_pioalt_pad(portno, pinno, pin->dir); switch (pin->type) { case BYPASS: retime_cfg.clknotdata = 0; retime_cfg.retime = 0; break; case CLOCK: retime_cfg.clknotdata = 1; retime_cfg.clk1notclk0 = port; break; case PHY_CLOCK: retime_cfg.clknotdata = 1; if (config->mode == stx7108_ethernet_mode_gmii_gtx) { retime_cfg.clk1notclk0 = 1; retime_cfg.double_edge = 0; } else { retime_cfg.clk1notclk0 = 0; } break; case DGTX: /* extra configuration for GMII (GTK CLK) */ if (port == 1) { retime_cfg.retime = 1; retime_cfg.clk1notclk0 = 1; retime_cfg.double_edge = 0; retime_cfg.clknotdata = 0; } else { retime_cfg.retime = 1; retime_cfg.clk1notclk0 = 0; retime_cfg.double_edge = 0; retime_cfg.clknotdata = 0; } break; case DATA: retime_cfg.clknotdata = 0; retime_cfg.retime = 1; retime_cfg.clk1notclk0 = port; break; default: BUG(); break; } stx7108_pioalt_retime(portno, pinno, &retime_cfg); } }