/*
 * 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;
}
Beispiel #3
0
	/*
	 * 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);
	}
}