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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to