Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 May 2012 07:43:11 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234919 - head/sys/mips/atheros
Message-ID:  <201205020743.q427hBCe071991@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed May  2 07:43:11 2012
New Revision: 234919
URL: http://svn.freebsd.org/changeset/base/234919

Log:
  Implement PLL configuration override support, similar to what openwrt
  implements.

Modified:
  head/sys/mips/atheros/if_arge.c
  head/sys/mips/atheros/if_argevar.h

Modified: head/sys/mips/atheros/if_arge.c
==============================================================================
--- head/sys/mips/atheros/if_arge.c	Wed May  2 07:41:26 2012	(r234918)
+++ head/sys/mips/atheros/if_arge.c	Wed May  2 07:43:11 2012	(r234919)
@@ -101,6 +101,7 @@ typedef enum {
 	ARGE_DBG_RX	=	0x00000008,
 	ARGE_DBG_ERR	=	0x00000010,
 	ARGE_DBG_RESET	=	0x00000020,
+	ARGE_DBG_PLL	=	0x00000040,
 } arge_debug_flags;
 
 static const char * arge_miicfg_str[] = {
@@ -331,6 +332,34 @@ arge_reset_miibus(struct arge_softc *sc)
 	DELAY(100);
 }
 
+static void
+arge_fetch_pll_config(struct arge_softc *sc)
+{
+	long int val;
+
+	if (resource_long_value(device_get_name(sc->arge_dev),
+	    device_get_unit(sc->arge_dev),
+	    "pll_10", &val) == 0) {
+		sc->arge_pllcfg.pll_10 = val;
+		device_printf(sc->arge_dev, "%s: pll_10 = 0x%x\n",
+		    __func__, (int) val);
+	}
+	if (resource_long_value(device_get_name(sc->arge_dev),
+	    device_get_unit(sc->arge_dev),
+	    "pll_100", &val) == 0) {
+		sc->arge_pllcfg.pll_100 = val;
+		device_printf(sc->arge_dev, "%s: pll_100 = 0x%x\n",
+		    __func__, (int) val);
+	}
+	if (resource_long_value(device_get_name(sc->arge_dev),
+	    device_get_unit(sc->arge_dev),
+	    "pll_1000", &val) == 0) {
+		sc->arge_pllcfg.pll_1000 = val;
+		device_printf(sc->arge_dev, "%s: pll_1000 = 0x%x\n",
+		    __func__, (int) val);
+	}
+}
+
 static int
 arge_attach(device_t dev)
 {
@@ -372,6 +401,11 @@ arge_attach(device_t dev)
 	    ("if_arge: Only MAC0 and MAC1 supported"));
 
 	/*
+	 * Fetch the PLL configuration.
+	 */
+	arge_fetch_pll_config(sc);
+
+	/*
 	 * Get the MII configuration, if applicable.
 	 */
 	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
@@ -821,7 +855,7 @@ arge_set_pll(struct arge_softc *sc, int 
 	uint32_t		fifo_tx, pll;
 	int if_speed;
 
-	ARGEDEBUG(sc, ARGE_DBG_MII, "set_pll(%04x, %s)\n", media,
+	ARGEDEBUG(sc, ARGE_DBG_PLL, "set_pll(%04x, %s)\n", media,
 	    duplex == IFM_FDX ? "full" : "half");
 	cfg = ARGE_READ(sc, AR71XX_MAC_CFG2);
 	cfg &= ~(MAC_CFG2_IFACE_MODE_1000
@@ -859,7 +893,7 @@ arge_set_pll(struct arge_softc *sc, int 
 		    "Unknown media %d\n", media);
 	}
 
-	ARGEDEBUG(sc, ARGE_DBG_MII, "%s: if_speed=%d\n", __func__, if_speed);
+	ARGEDEBUG(sc, ARGE_DBG_PLL, "%s: if_speed=%d\n", __func__, if_speed);
 
 	switch (ar71xx_soc) {
 		case AR71XX_SOC_AR7240:
@@ -881,8 +915,18 @@ arge_set_pll(struct arge_softc *sc, int 
 	    rx_filtmask);
 	ARGE_WRITE(sc, AR71XX_MAC_FIFO_TX_THRESHOLD, fifo_tx);
 
-	/* set PLL registers */
+	/* fetch PLL registers */
 	pll = ar71xx_device_get_eth_pll(sc->arge_mac_unit, if_speed);
+	ARGEDEBUG(sc, ARGE_DBG_PLL, "%s: pll=0x%x\n", __func__, pll);
+
+	/* Override if required by platform data */
+	if (if_speed == 10 && sc->arge_pllcfg.pll_10 != 0)
+		pll = sc->arge_pllcfg.pll_10;
+	else if (if_speed == 100 && sc->arge_pllcfg.pll_100 != 0)
+		pll = sc->arge_pllcfg.pll_100;
+	else if (if_speed == 1000 && sc->arge_pllcfg.pll_1000 != 0)
+		pll = sc->arge_pllcfg.pll_1000;
+	ARGEDEBUG(sc, ARGE_DBG_PLL, "%s: final pll=0x%x\n", __func__, pll);
 
 	/* XXX ensure pll != 0 */
 	ar71xx_device_set_pll_ge(sc->arge_mac_unit, if_speed, pll);

Modified: head/sys/mips/atheros/if_argevar.h
==============================================================================
--- head/sys/mips/atheros/if_argevar.h	Wed May  2 07:41:26 2012	(r234918)
+++ head/sys/mips/atheros/if_argevar.h	Wed May  2 07:43:11 2012	(r234919)
@@ -118,6 +118,15 @@ struct arge_ring_data {
 	bus_addr_t		arge_tx_ring_paddr;
 };
 
+/*
+ * Allow PLL values to be overridden.
+ */
+struct arge_pll_data {
+	uint32_t pll_10;
+	uint32_t pll_100;
+	uint32_t pll_1000;
+};
+
 struct arge_softc {
 	struct ifnet		*arge_ifp;	/* interface info */
 	device_t		arge_dev;
@@ -136,6 +145,7 @@ struct arge_softc {
 	device_t		arge_miibus;
 	device_t		arge_miiproxy;
 	ar71xx_mii_mode		arge_miicfg;
+	struct arge_pll_data	arge_pllcfg;
 	bus_dma_tag_t		arge_parent_tag;
 	bus_dma_tag_t		arge_tag;
 	struct mtx		arge_mtx;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205020743.q427hBCe071991>