svn commit: r256490 - head/sys/mips/atheros

Adrian Chadd adrian at FreeBSD.org
Tue Oct 15 03:23:09 UTC 2013


Author: adrian
Date: Tue Oct 15 03:23:08 2013
New Revision: 256490
URL: http://svnweb.freebsd.org/changeset/base/256490

Log:
  Update the AR933x SoC support to include a few new knobs:
  
  * Initialise the MDIO clock to default to the reference clock;
  * Add some code to allow the hints mechanism to allow setup of the GMAC
    config block.
  * Document how the switch is wired up internally.
  
  Tested:
  
  * AR9331 SoC (Carambola 2)

Modified:
  head/sys/mips/atheros/ar933x_chip.c

Modified: head/sys/mips/atheros/ar933x_chip.c
==============================================================================
--- head/sys/mips/atheros/ar933x_chip.c	Tue Oct 15 02:07:29 2013	(r256489)
+++ head/sys/mips/atheros/ar933x_chip.c	Tue Oct 15 03:23:08 2013	(r256490)
@@ -115,12 +115,20 @@ ar933x_chip_detect_sys_frequency(void)
 		u_ar71xx_ahb_freq = freq / t;
 	}
 
-	/* On the AR933x, the UART frequency is the reference clock,
+	/*
+	 * On the AR933x, the UART frequency is the reference clock,
 	 * not the AHB bus clock.
 	 */
 	u_ar71xx_uart_freq = u_ar71xx_refclk;
 
 	/*
+	 * XXX TODO: check whether the mdio frequency is always the
+	 * refclock frequency, or whether it's variable like on the
+	 * AR934x.
+	 */
+	u_ar71xx_mdio_freq = u_ar71xx_refclk;
+
+	/*
 	 * XXX check what the watchdog frequency should be?
 	 */
 	u_ar71xx_wdt_freq = u_ar71xx_ahb_freq;
@@ -242,6 +250,95 @@ ar933x_chip_init_usb_peripheral(void)
 	DELAY(100);
 }
 
+static void
+ar933x_configure_gmac(uint32_t gmac_cfg)
+{
+	uint32_t reg;
+
+	reg = ATH_READ_REG(AR933X_GMAC_REG_ETH_CFG);
+
+	/*
+	 * The relevant bits here include:
+	 *
+	 * + AR933X_ETH_CFG_SW_PHY_SWAP
+	 * + AR933X_ETH_CFG_SW_PHY_ADDR_SWAP
+	 *
+	 * There are other things; look at what openwrt exposes so
+	 * it can be correctly exposed.
+	 *
+	 * TODO: what about ethernet switch support? How's that work?
+	 */
+	if (bootverbose)
+		printf("%s: GMAC config was 0x%08x\n", __func__, reg);
+        reg &= ~(AR933X_ETH_CFG_SW_PHY_SWAP | AR933X_ETH_CFG_SW_PHY_ADDR_SWAP);
+	reg |= gmac_cfg;
+	if (bootverbose)
+		printf("%s: GMAC setting is 0x%08x; register is now 0x%08x\n",
+		    __func__,
+		    gmac_cfg,
+		    reg);
+	ATH_WRITE_REG(AR933X_GMAC_REG_ETH_CFG, reg);
+}
+
+static void
+ar933x_chip_init_gmac(void)
+{
+	int val;
+	uint32_t gmac_cfg = 0;
+
+	/*
+	 * These two bits need a bit better explanation.
+	 *
+	 * The default configuration in the hardware is to map both
+	 * ports to the internal switch.
+	 *
+	 * Here, GE0 == arge0, GE1 == arge1.
+	 *
+	 * The internal switch has:
+	 * + 5 MAC ports, MAC0->MAC4.
+	 * + 5 PHY ports, PHY0->PHY4,
+	 * + MAC0 connects to GE1;
+	 * + GE0 connects to PHY4;
+	 * + The other mappings are MAC1->PHY0, MAC2->PHY1 .. MAC4->PHY3.
+	 *
+	 * The GE1 port is linked in via 1000MBit/full, supplying what is
+	 * normally the 'WAN' switch ports.
+	 *
+	 * The switch is connected the MDIO bus on GE1.  It looks like
+	 * a normal AR7240 on-board switch.
+	 *
+	 * The GE0 port is connected via MII to PHY4, and can operate in
+	 * 10/100mbit, full/half duplex.  Ie, you can speak to PHY4 on
+	 * the MDIO bus and everything will simply 'work'.
+	 *
+	 * So far so good.  This looks just like an AR7240 SoC.
+	 *
+	 * However, some configurations will just expose one or two
+	 * physical ports.  In this case, some configuration bits can
+	 * be set to tweak this.
+	 *
+	 * + CFG_SW_PHY_ADDR_SWAP swaps PHY port 0 with PHY port 4.
+	 *   Ie, GE0's PHY shows up as PHY 0.  So if there's only
+	 *   one physical port, there's no need to involve the
+	 *   switch framework - it can just show up as a default,
+	 *   normal single PHY.
+	 *
+	 * + CFG_SW_PHY_SWAP swaps the internal switch connection
+	 *   between PHY0 and PHY4.  Ie, PHY4 connects to MAc1,
+	 *   PHY0 connects to GE0.
+	 */
+	if ((resource_int_value("ar933x_gmac", 0, "override_phy", &val) == 0)
+	    && (val == 0))
+		return;
+	if ((resource_int_value("ar933x_gmac", 0, "swap_phy", &val) == 0)
+	    && (val == 1))
+		gmac_cfg |= AR933X_ETH_CFG_SW_PHY_SWAP;
+	if ((resource_int_value("ar933x_gmac", 0, "swap_phy_addr", &val) == 0)
+	    && (val == 1))
+		gmac_cfg |= AR933X_ETH_CFG_SW_PHY_ADDR_SWAP;
+	ar933x_configure_gmac(gmac_cfg);
+}
+
 struct ar71xx_cpu_def ar933x_chip_def = {
 	&ar933x_chip_detect_mem_size,
 	&ar933x_chip_detect_sys_frequency,
@@ -254,5 +351,8 @@ struct ar71xx_cpu_def ar933x_chip_def = 
 	&ar933x_chip_ddr_flush_ge,
 	&ar933x_chip_get_eth_pll,
 	&ar933x_chip_ddr_flush_ip2,
-	&ar933x_chip_init_usb_peripheral
+	&ar933x_chip_init_usb_peripheral,
+	NULL,
+	NULL,
+	&ar933x_chip_init_gmac,
 };


More information about the svn-src-all mailing list