svn commit: r256575 - head/sys/mips/atheros
Adrian Chadd
adrian at FreeBSD.org
Wed Oct 16 03:11:18 UTC 2013
Author: adrian
Date: Wed Oct 16 03:11:18 2013
New Revision: 256575
URL: http://svnweb.freebsd.org/changeset/base/256575
Log:
Add in the platform specific quirks to get the AR934x SoC ethernet
up and running.
* The MAC FIFO configurations needed updating;
* Reset the MDIO block at the same time the MAC block is reset;
* The default divisor needs changing as the DB120 runs at a higher
base MDIO bus clock compared to other chips.
The long-term fix is to allow the system to have a target MDIO bus
clock rate and then calculate the most suitable divider to meet
that. This will likely need implementing before stable external
PHY or switch support can be committed.
Tested:
* AR9344 (mips74k)
* AR9331 (mips24k)
Modified:
head/sys/mips/atheros/if_arge.c
Modified: head/sys/mips/atheros/if_arge.c
==============================================================================
--- head/sys/mips/atheros/if_arge.c Wed Oct 16 02:55:31 2013 (r256574)
+++ head/sys/mips/atheros/if_arge.c Wed Oct 16 03:11:18 2013 (r256575)
@@ -90,6 +90,7 @@ MODULE_VERSION(arge, 1);
#include "miibus_if.h"
#include <mips/atheros/ar71xxreg.h>
+#include <mips/atheros/ar934xreg.h> /* XXX tsk! */
#include <mips/atheros/if_argevar.h>
#include <mips/atheros/ar71xx_setup.h>
#include <mips/atheros/ar71xx_cpudef.h>
@@ -298,17 +299,38 @@ static void
arge_reset_mac(struct arge_softc *sc)
{
uint32_t reg;
+ uint32_t reset_reg;
/* Step 1. Soft-reset MAC */
ARGE_SET_BITS(sc, AR71XX_MAC_CFG1, MAC_CFG1_SOFT_RESET);
DELAY(20);
/* Step 2. Punt the MAC core from the central reset register */
- ar71xx_device_stop(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC :
- RST_RESET_GE1_MAC);
+ /*
+ * XXX TODO: migrate this (and other) chip specific stuff into
+ * a chipdef method.
+ */
+ if (sc->arge_mac_unit == 0) {
+ reset_reg = RST_RESET_GE0_MAC;
+ } else {
+ reset_reg = RST_RESET_GE1_MAC;
+ }
+
+ /*
+ * AR934x (and later) also needs the MDIO block reset.
+ */
+ if (ar71xx_soc == AR71XX_SOC_AR9341 ||
+ ar71xx_soc == AR71XX_SOC_AR9342 ||
+ ar71xx_soc == AR71XX_SOC_AR9344) {
+ if (sc->arge_mac_unit == 0) {
+ reset_reg |= AR934X_RESET_GE0_MDIO;
+ } else {
+ reset_reg |= AR934X_RESET_GE1_MDIO;
+ }
+ }
+ ar71xx_device_stop(reset_reg);
DELAY(100);
- ar71xx_device_start(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC :
- RST_RESET_GE1_MAC);
+ ar71xx_device_start(reset_reg);
/* Step 3. Reconfigure MAC block */
ARGE_WRITE(sc, AR71XX_MAC_CFG1,
@@ -322,14 +344,46 @@ arge_reset_mac(struct arge_softc *sc)
ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536);
}
+/*
+ * Fetch the MDIO bus clock rate.
+ *
+ * For now, the default is DIV_28 for everything
+ * bar AR934x, which will be DIV_42.
+ *
+ * It will definitely need updating to take into account
+ * the MDIO bus core clock rate and the target clock
+ * rate for the chip.
+ */
+static uint32_t
+arge_fetch_mdiobus_clock_rate(struct arge_softc *sc)
+{
+
+ switch (ar71xx_soc) {
+ case AR71XX_SOC_AR9341:
+ case AR71XX_SOC_AR9342:
+ case AR71XX_SOC_AR9344:
+ return (MAC_MII_CFG_CLOCK_DIV_42);
+ default:
+ return (MAC_MII_CFG_CLOCK_DIV_28);
+ }
+}
+
static void
arge_reset_miibus(struct arge_softc *sc)
{
+ uint32_t mdio_div;
- /* Reset MII bus */
- ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET);
+ mdio_div = arge_fetch_mdiobus_clock_rate(sc);
+
+ /*
+ * XXX AR934x and later; should we be also resetting the
+ * MDIO block(s) using the reset register block?
+ */
+
+ /* Reset MII bus; program in the default divisor */
+ ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET | mdio_div);
DELAY(100);
- ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28);
+ ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, mdio_div);
DELAY(100);
}
@@ -588,9 +642,13 @@ arge_attach(device_t dev)
case AR71XX_SOC_AR7242:
case AR71XX_SOC_AR9330:
case AR71XX_SOC_AR9331:
+ case AR71XX_SOC_AR9341:
+ case AR71XX_SOC_AR9342:
+ case AR71XX_SOC_AR9344:
ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0010ffff);
ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x015500aa);
break;
+ /* AR71xx, AR913x */
default:
ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0fff0000);
ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x00001fff);
@@ -917,12 +975,16 @@ arge_set_pll(struct arge_softc *sc, int
case AR71XX_SOC_AR7242:
case AR71XX_SOC_AR9330:
case AR71XX_SOC_AR9331:
+ case AR71XX_SOC_AR9341:
+ case AR71XX_SOC_AR9342:
+ case AR71XX_SOC_AR9344:
fifo_tx = 0x01f00140;
break;
case AR71XX_SOC_AR9130:
case AR71XX_SOC_AR9132:
fifo_tx = 0x00780fff;
break;
+ /* AR71xx */
default:
fifo_tx = 0x008001ff;
}
More information about the svn-src-all
mailing list