Author: adrian
Date: Mon Nov 16 04:28:00 2015
New Revision: 290910
URL: https://svnweb.freebsd.org/changeset/base/290910

Log:
  Add initial support for the QCA953x ("Honeybee") from Qualcomm Atheros.
  
  The QCA953x SoC is an integrated 2x2 2GHz 11n + MIPS24k core, with
  a 5 port FE switch, gige WAN port, and all the same stuff you'd find on
  its predecessor - the AR9331.
  
  However, buried deep in here somewhere is also a PCIe EP/RC for various
  applications and some other weird bits I don't yet know about.
  
  This is enough to get the reference board up and booting.  I haven't yet
  had it pass lots of packets - I need to finalise the ethernet switch
  bits and the GMAC configuration (ie, how the ethernet ports and switch
  are wired up) and I'll bring that in when I commit the base configuration
  files to use the thing.
  
  The wifi stuff will come much later.  I have to port that support from
  Linux ath9k and extend our vendor HAL to support it.
  
  The reference board (AP143) comes with 32MB RAM and 4MB flash, so in order
  to use it I need to get USB working fully so I can run root from there.
  
  Thankyou to Qualcomm Atheros for access to the reference design board.
  
  Details:
  
  * Add register definitions from openwrt;
  * It looks like a QCA955x but shrunk down to a QCA933x footprint, so
    use the QCA955x bits and fix up the clock detection code to do the
    QCA953x bits (they're very subtly different);
  * Teach GPIO about it;
  * Teach EHCI about it;
  * Teach if_arge about it;
  * Teach the CPU detection code about it.
  
  Tested:
  
  * AP143, QCA9533v2 SoC
  
  Obtained from:        Linux, Linux OpenWRT

Added:
  head/sys/mips/atheros/qca953x_chip.c   (contents, props changed)
  head/sys/mips/atheros/qca953x_chip.h   (contents, props changed)
  head/sys/mips/atheros/qca953xreg.h   (contents, props changed)
Modified:
  head/sys/mips/atheros/ar71xx_ehci.c
  head/sys/mips/atheros/ar71xx_gpio.c
  head/sys/mips/atheros/ar71xx_setup.c
  head/sys/mips/atheros/ar71xx_setup.h
  head/sys/mips/atheros/files.ar71xx
  head/sys/mips/atheros/if_arge.c

Modified: head/sys/mips/atheros/ar71xx_ehci.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_ehci.c Mon Nov 16 04:15:39 2015        
(r290909)
+++ head/sys/mips/atheros/ar71xx_ehci.c Mon Nov 16 04:28:00 2015        
(r290910)
@@ -173,6 +173,8 @@ ar71xx_ehci_attach(device_t self)
                case AR71XX_SOC_AR9341:
                case AR71XX_SOC_AR9342:
                case AR71XX_SOC_AR9344:
+               case AR71XX_SOC_QCA9533:
+               case AR71XX_SOC_QCA9533_V2:
                case AR71XX_SOC_QCA9556:
                case AR71XX_SOC_QCA9558:
                        sc->sc_flags |= EHCI_SCFLG_TT | EHCI_SCFLG_NORESTERM;

Modified: head/sys/mips/atheros/ar71xx_gpio.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_gpio.c Mon Nov 16 04:15:39 2015        
(r290909)
+++ head/sys/mips/atheros/ar71xx_gpio.c Mon Nov 16 04:28:00 2015        
(r290910)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/gpio/gpiobusvar.h>
 #include <mips/atheros/ar933xreg.h>
 #include <mips/atheros/ar934xreg.h>
+#include <mips/atheros/qca953xreg.h>
 #include <mips/atheros/qca955xreg.h>
 
 #include "gpio_if.h"
@@ -102,9 +103,15 @@ static int ar71xx_gpio_pin_toggle(device
 static void
 ar71xx_gpio_function_enable(struct ar71xx_gpio_softc *sc, uint32_t mask)
 {
+
+       /*
+        * XXX TODO: refactor this out into a per-chipset method.
+        */
        if (ar71xx_soc == AR71XX_SOC_AR9341 ||
            ar71xx_soc == AR71XX_SOC_AR9342 ||
            ar71xx_soc == AR71XX_SOC_AR9344 ||
+           ar71xx_soc == AR71XX_SOC_QCA9533 ||
+           ar71xx_soc == AR71XX_SOC_QCA9533_V2 ||
            ar71xx_soc == AR71XX_SOC_QCA9556 ||
            ar71xx_soc == AR71XX_SOC_QCA9558)
                GPIO_SET_BITS(sc, AR934X_GPIO_REG_FUNC, mask);
@@ -115,9 +122,15 @@ ar71xx_gpio_function_enable(struct ar71x
 static void
 ar71xx_gpio_function_disable(struct ar71xx_gpio_softc *sc, uint32_t mask)
 {
+
+       /*
+        * XXX TODO: refactor this out into a per-chipset method.
+        */
        if (ar71xx_soc == AR71XX_SOC_AR9341 ||
            ar71xx_soc == AR71XX_SOC_AR9342 ||
            ar71xx_soc == AR71XX_SOC_AR9344 ||
+           ar71xx_soc == AR71XX_SOC_QCA9533 ||
+           ar71xx_soc == AR71XX_SOC_QCA9533_V2 ||
            ar71xx_soc == AR71XX_SOC_QCA9556 ||
            ar71xx_soc == AR71XX_SOC_QCA9558)
                GPIO_CLEAR_BITS(sc, AR934X_GPIO_REG_FUNC, mask);
@@ -182,6 +195,10 @@ ar71xx_gpio_pin_max(device_t dev, int *m
                case AR71XX_SOC_AR9344:
                        *maxpin = AR934X_GPIO_COUNT - 1;
                        break;
+               case AR71XX_SOC_QCA9533:
+               case AR71XX_SOC_QCA9533_V2:
+                       *maxpin = QCA953X_GPIO_COUNT - 1;
+                       break;
                case AR71XX_SOC_QCA9556:
                case AR71XX_SOC_QCA9558:
                        *maxpin = QCA955X_GPIO_COUNT - 1;

Modified: head/sys/mips/atheros/ar71xx_setup.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_setup.c        Mon Nov 16 04:15:39 2015        
(r290909)
+++ head/sys/mips/atheros/ar71xx_setup.c        Mon Nov 16 04:28:00 2015        
(r290910)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #include <mips/atheros/ar933xreg.h>
 #include <mips/atheros/ar934xreg.h>
 #include <mips/atheros/qca955xreg.h>
+#include <mips/atheros/qca953xreg.h>
 
 #include <mips/atheros/ar71xx_setup.h>
 
@@ -65,6 +66,7 @@ __FBSDID("$FreeBSD$");
 #include <mips/atheros/ar91xx_chip.h>
 #include <mips/atheros/ar933x_chip.h>
 #include <mips/atheros/ar934x_chip.h>
+#include <mips/atheros/qca953x_chip.h>
 #include <mips/atheros/qca955x_chip.h>
 
 #define        AR71XX_SYS_TYPE_LEN             128
@@ -186,6 +188,22 @@ ar71xx_detect_sys_type(void)
                ar71xx_cpu_ops = &ar934x_chip_def;
                break;
 
+       case REV_ID_MAJOR_QCA9533:
+               minor = 0;
+               rev = (id & QCA953X_REV_ID_REVISION_MASK);
+               chip = "9533";
+               ar71xx_soc = AR71XX_SOC_QCA9533;
+               ar71xx_cpu_ops = &qca953x_chip_def;
+               break;
+
+       case REV_ID_MAJOR_QCA9533_V2:
+               minor = 0;
+               rev = (id & QCA953X_REV_ID_REVISION_MASK);
+               chip = "9533v2";
+               ar71xx_soc = AR71XX_SOC_QCA9533_V2;
+               ar71xx_cpu_ops = &qca953x_chip_def;
+               break;
+
        case REV_ID_MAJOR_QCA9556:
                minor = 0;
                rev = (id & QCA955X_REV_ID_REVISION_MASK);

Modified: head/sys/mips/atheros/ar71xx_setup.h
==============================================================================
--- head/sys/mips/atheros/ar71xx_setup.h        Mon Nov 16 04:15:39 2015        
(r290909)
+++ head/sys/mips/atheros/ar71xx_setup.h        Mon Nov 16 04:28:00 2015        
(r290910)
@@ -46,6 +46,8 @@ enum ar71xx_soc_type {
        AR71XX_SOC_AR9344,
        AR71XX_SOC_QCA9556,
        AR71XX_SOC_QCA9558,
+       AR71XX_SOC_QCA9533,
+       AR71XX_SOC_QCA9533_V2,
 };
 extern enum ar71xx_soc_type ar71xx_soc;
 

Modified: head/sys/mips/atheros/files.ar71xx
==============================================================================
--- head/sys/mips/atheros/files.ar71xx  Mon Nov 16 04:15:39 2015        
(r290909)
+++ head/sys/mips/atheros/files.ar71xx  Mon Nov 16 04:28:00 2015        
(r290910)
@@ -27,6 +27,7 @@ mips/atheros/ar724x_chip.c    standard
 mips/atheros/ar91xx_chip.c     standard
 mips/atheros/ar933x_chip.c     standard
 mips/atheros/ar934x_chip.c     standard
+mips/atheros/qca953x_chip.c    standard
 mips/atheros/qca955x_chip.c    standard
 mips/atheros/ar71xx_fixup.c    optional ar71xx_ath_eeprom
 mips/atheros/qca955x_apb.c     optional qca955x_apb

Modified: head/sys/mips/atheros/if_arge.c
==============================================================================
--- head/sys/mips/atheros/if_arge.c     Mon Nov 16 04:15:39 2015        
(r290909)
+++ head/sys/mips/atheros/if_arge.c     Mon Nov 16 04:28:00 2015        
(r290910)
@@ -94,6 +94,7 @@ MODULE_VERSION(arge, 1);
 
 #include <mips/atheros/ar71xxreg.h>
 #include <mips/atheros/ar934xreg.h>    /* XXX tsk! */
+#include <mips/atheros/qca953xreg.h>   /* XXX tsk! */
 #include <mips/atheros/qca955xreg.h>   /* XXX tsk! */
 #include <mips/atheros/if_argevar.h>
 #include <mips/atheros/ar71xx_setup.h>
@@ -399,6 +400,16 @@ arge_reset_mac(struct arge_softc *sc)
                        reset_reg |= QCA955X_RESET_GE1_MDIO;
                }
        }
+
+       if (ar71xx_soc == AR71XX_SOC_QCA9533 ||
+          ar71xx_soc == AR71XX_SOC_QCA9533_V2) {
+               if (sc->arge_mac_unit == 0) {
+                       reset_reg |= QCA953X_RESET_GE0_MDIO;
+               } else {
+                       reset_reg |= QCA953X_RESET_GE1_MDIO;
+               }
+       }
+
        ar71xx_device_stop(reset_reg);
        DELAY(100);
        ar71xx_device_start(reset_reg);
@@ -470,6 +481,8 @@ arge_mdio_get_divider(struct arge_softc 
        case AR71XX_SOC_AR9341:
        case AR71XX_SOC_AR9342:
        case AR71XX_SOC_AR9344:
+       case AR71XX_SOC_QCA9533:
+       case AR71XX_SOC_QCA9533_V2:
        case AR71XX_SOC_QCA9556:
        case AR71XX_SOC_QCA9558:
                table = ar933x_mdio_div_table;
@@ -561,6 +574,8 @@ arge_fetch_mdiobus_clock_rate(struct arg
        case AR71XX_SOC_AR9341:
        case AR71XX_SOC_AR9342:
        case AR71XX_SOC_AR9344:
+       case AR71XX_SOC_QCA9533:
+       case AR71XX_SOC_QCA9533_V2:
        case AR71XX_SOC_QCA9556:
        case AR71XX_SOC_QCA9558:
                return (MAC_MII_CFG_CLOCK_DIV_58);
@@ -681,6 +696,8 @@ arge_attach(device_t dev)
        case AR71XX_SOC_AR9341:
        case AR71XX_SOC_AR9342:
        case AR71XX_SOC_AR9344:
+       case AR71XX_SOC_QCA9533:
+       case AR71XX_SOC_QCA9533_V2:
        case AR71XX_SOC_QCA9556:
        case AR71XX_SOC_QCA9558:
                /* Arbitrary alignment */
@@ -904,6 +921,8 @@ arge_attach(device_t dev)
                case AR71XX_SOC_AR9341:
                case AR71XX_SOC_AR9342:
                case AR71XX_SOC_AR9344:
+               case AR71XX_SOC_QCA9533:
+               case AR71XX_SOC_QCA9533_V2:
                case AR71XX_SOC_QCA9556:
                case AR71XX_SOC_QCA9558:
                        ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0010ffff);
@@ -1278,6 +1297,8 @@ arge_set_pll(struct arge_softc *sc, int 
                case AR71XX_SOC_AR9341:
                case AR71XX_SOC_AR9342:
                case AR71XX_SOC_AR9344:
+               case AR71XX_SOC_QCA9533:
+               case AR71XX_SOC_QCA9533_V2:
                case AR71XX_SOC_QCA9556:
                case AR71XX_SOC_QCA9558:
                        fifo_tx = 0x01f00140;

Added: head/sys/mips/atheros/qca953x_chip.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/atheros/qca953x_chip.c        Mon Nov 16 04:28:00 2015        
(r290910)
@@ -0,0 +1,393 @@
+/*-
+ * Copyright (c) 2015 Adrian Chadd <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#include <net/ethernet.h>
+
+#include <machine/clock.h>
+#include <machine/cpu.h>
+#include <machine/cpuregs.h>
+#include <machine/hwfunc.h>
+#include <machine/md_var.h>
+#include <machine/trap.h>
+#include <machine/vmparam.h>
+
+#include <mips/atheros/ar71xxreg.h>
+#include <mips/atheros/qca953xreg.h>
+
+#include <mips/atheros/ar71xx_cpudef.h>
+#include <mips/atheros/ar71xx_setup.h>
+
+#include <mips/atheros/ar71xx_chip.h>
+
+#include <mips/atheros/qca953x_chip.h>
+
+static void
+qca953x_chip_detect_mem_size(void)
+{
+}
+
+static void
+qca953x_chip_detect_sys_frequency(void)
+{
+       unsigned long ref_rate;
+       unsigned long cpu_rate;
+       unsigned long ddr_rate;
+       unsigned long ahb_rate;
+       uint32_t pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
+       uint32_t cpu_pll, ddr_pll;
+       uint32_t bootstrap;
+
+       bootstrap = ATH_READ_REG(QCA953X_RESET_REG_BOOTSTRAP);
+       if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40)
+               ref_rate = 40 * 1000 * 1000;
+       else
+               ref_rate = 25 * 1000 * 1000;
+
+       pll = ATH_READ_REG(QCA953X_PLL_CPU_CONFIG_REG);
+       out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+                 QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
+       ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+                 QCA953X_PLL_CPU_CONFIG_REFDIV_MASK;
+       nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) &
+              QCA953X_PLL_CPU_CONFIG_NINT_MASK;
+       frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
+              QCA953X_PLL_CPU_CONFIG_NFRAC_MASK;
+
+       cpu_pll = nint * ref_rate / ref_div;
+       cpu_pll += frac * (ref_rate >> 6) / ref_div;
+       cpu_pll /= (1 << out_div);
+
+       pll = ATH_READ_REG(QCA953X_PLL_DDR_CONFIG_REG);
+       out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+                 QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
+       ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+                 QCA953X_PLL_DDR_CONFIG_REFDIV_MASK;
+       nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) &
+              QCA953X_PLL_DDR_CONFIG_NINT_MASK;
+       frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
+              QCA953X_PLL_DDR_CONFIG_NFRAC_MASK;
+
+       ddr_pll = nint * ref_rate / ref_div;
+       ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
+       ddr_pll /= (1 << out_div);
+
+       clk_ctrl = ATH_READ_REG(QCA953X_PLL_CLK_CTRL_REG);
+
+       postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
+                 QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+
+       if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
+               cpu_rate = ref_rate;
+       else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
+               cpu_rate = cpu_pll / (postdiv + 1);
+       else
+               cpu_rate = ddr_pll / (postdiv + 1);
+
+       postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
+                 QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+
+       if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
+               ddr_rate = ref_rate;
+       else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
+               ddr_rate = ddr_pll / (postdiv + 1);
+       else
+               ddr_rate = cpu_pll / (postdiv + 1);
+
+       postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
+                 QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+
+       if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
+               ahb_rate = ref_rate;
+       else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
+               ahb_rate = ddr_pll / (postdiv + 1);
+       else
+               ahb_rate = cpu_pll / (postdiv + 1);
+
+       u_ar71xx_ddr_freq = ddr_rate;
+       u_ar71xx_cpu_freq = cpu_rate;
+       u_ar71xx_ahb_freq = ahb_rate;
+
+       u_ar71xx_wdt_freq = ref_rate;
+       u_ar71xx_uart_freq = ref_rate;
+       u_ar71xx_mdio_freq = ref_rate;
+       u_ar71xx_refclk = ref_rate;
+}
+
+static void
+qca953x_chip_device_stop(uint32_t mask)
+{
+       uint32_t reg;
+
+       reg = ATH_READ_REG(QCA953X_RESET_REG_RESET_MODULE);
+       ATH_WRITE_REG(QCA953X_RESET_REG_RESET_MODULE, reg | mask);
+}
+
+static void
+qca953x_chip_device_start(uint32_t mask)
+{
+       uint32_t reg;
+
+       reg = ATH_READ_REG(QCA953X_RESET_REG_RESET_MODULE);
+       ATH_WRITE_REG(QCA953X_RESET_REG_RESET_MODULE, reg & ~mask);
+}
+
+static int
+qca953x_chip_device_stopped(uint32_t mask)
+{
+       uint32_t reg;
+
+       reg = ATH_READ_REG(QCA953X_RESET_REG_RESET_MODULE);
+       return ((reg & mask) == mask);
+}
+
+static void
+qca953x_chip_set_mii_speed(uint32_t unit, uint32_t speed)
+{
+
+       /* XXX TODO */
+       return;
+}
+
+static void
+qca953x_chip_set_pll_ge(int unit, int speed, uint32_t pll)
+{
+       switch (unit) {
+       case 0:
+               ATH_WRITE_REG(QCA953X_PLL_ETH_XMII_CONTROL_REG, pll);
+               break;
+       case 1:
+               ATH_WRITE_REG(QCA953X_PLL_ETH_SGMII_CONTROL_REG, pll);
+               break;
+       default:
+               printf("%s: invalid PLL set for arge unit: %d\n",
+                   __func__, unit);
+               return;
+       }
+}
+
+static void
+qca953x_chip_ddr_flush(ar71xx_flush_ddr_id_t id)
+{
+
+       switch (id) {
+       case AR71XX_CPU_DDR_FLUSH_GE0:
+               ar71xx_ddr_flush(QCA953X_DDR_REG_FLUSH_GE0);
+               break;
+       case AR71XX_CPU_DDR_FLUSH_GE1:
+               ar71xx_ddr_flush(QCA953X_DDR_REG_FLUSH_GE1);
+               break;
+       case AR71XX_CPU_DDR_FLUSH_USB:
+               ar71xx_ddr_flush(QCA953X_DDR_REG_FLUSH_USB);
+               break;
+       case AR71XX_CPU_DDR_FLUSH_PCIE:
+               ar71xx_ddr_flush(QCA953X_DDR_REG_FLUSH_PCIE);
+               break;
+       case AR71XX_CPU_DDR_FLUSH_WMAC:
+               ar71xx_ddr_flush(QCA953X_DDR_REG_FLUSH_WMAC);
+               break;
+       default:
+               printf("%s: invalid flush (%d)\n", __func__, id);
+       }
+}
+
+static uint32_t
+qca953x_chip_get_eth_pll(unsigned int mac, int speed)
+{
+       uint32_t pll;
+
+       switch (speed) {
+       case 10:
+               pll = QCA953X_PLL_VAL_10;
+               break;
+       case 100:
+               pll = QCA953X_PLL_VAL_100;
+               break;
+       case 1000:
+               pll = QCA953X_PLL_VAL_1000;
+               break;
+       default:
+               printf("%s%d: invalid speed %d\n", __func__, mac, speed);
+               pll = 0;
+       }
+       return (pll);
+}
+
+static void
+qca953x_chip_reset_ethernet_switch(void)
+{
+}
+
+static void
+qca953x_configure_gmac(uint32_t gmac_cfg)
+{
+       uint32_t reg;
+
+       reg = ATH_READ_REG(QCA953X_GMAC_REG_ETH_CFG);
+       printf("%s: ETH_CFG=0x%08x\n", __func__, reg);
+       reg &= ~(QCA953X_ETH_CFG_SW_ONLY_MODE |
+           QCA953X_ETH_CFG_SW_PHY_SWAP |
+           QCA953X_ETH_CFG_SW_APB_ACCESS |
+           QCA953X_ETH_CFG_SW_ACC_MSB_FIRST);
+
+       reg |= gmac_cfg;
+       ATH_WRITE_REG(QCA953X_GMAC_REG_ETH_CFG, reg);
+}
+
+static void
+qca953x_chip_init_usb_peripheral(void)
+{
+       uint32_t bootstrap;
+
+       bootstrap = ATH_READ_REG(QCA953X_RESET_REG_BOOTSTRAP);
+
+       ar71xx_device_stop(QCA953X_RESET_USBSUS_OVERRIDE);
+       DELAY(1000);
+
+       ar71xx_device_start(QCA953X_RESET_USB_PHY);
+       DELAY(1000);
+
+       ar71xx_device_start(QCA953X_RESET_USB_PHY_ANALOG);
+       DELAY(1000);
+
+       ar71xx_device_start(QCA953X_RESET_USB_HOST);
+       DELAY(1000);
+}
+
+static void
+qca953x_chip_set_mii_if(uint32_t unit, uint32_t mii_mode)
+{
+
+       /*
+        * XXX !
+        *
+        * Nothing to see here; although gmac0 can have its
+        * MII configuration changed, the register values
+        * are slightly different.
+        */
+}
+
+/*
+ * XXX TODO: fetch default MII divider configuration
+ */
+
+static void
+qca953x_chip_reset_wmac(void)
+{
+
+       /* XXX TODO */
+}
+
+static void
+qca953x_chip_init_gmac(void)
+{
+       long gmac_cfg;
+
+       if (resource_long_value("qca953x_gmac", 0, "gmac_cfg",
+           &gmac_cfg) == 0) {
+               printf("%s: gmac_cfg=0x%08lx\n",
+                   __func__,
+                   (long) gmac_cfg);
+               qca953x_configure_gmac((uint32_t) gmac_cfg);
+       }
+}
+
+/*
+ * Reset the NAND Flash Controller.
+ *
+ * + active=1 means "make it active".
+ * + active=0 means "make it inactive".
+ */
+static void
+qca953x_chip_reset_nfc(int active)
+{
+}
+
+/*
+ * Configure the GPIO output mux setup.
+ *
+ * The QCA953x has an output mux which allowed
+ * certain functions to be configured on any pin.
+ * Specifically, the switch PHY link LEDs and
+ * WMAC external RX LNA switches are not limited to
+ * a specific GPIO pin.
+ */
+static void
+qca953x_chip_gpio_output_configure(int gpio, uint8_t func)
+{
+       uint32_t reg, s;
+       uint32_t t;
+
+       if (gpio > QCA953X_GPIO_COUNT)
+               return;
+
+       reg = QCA953X_GPIO_REG_OUT_FUNC0 + 4 * (gpio / 4);
+       s = 8 * (gpio % 4);
+
+       /* read-modify-write */
+       t = ATH_READ_REG(AR71XX_GPIO_BASE + reg);
+       t &= ~(0xff << s);
+       t |= func << s;
+       ATH_WRITE_REG(AR71XX_GPIO_BASE + reg, t);
+
+       /* flush write */
+       ATH_READ_REG(AR71XX_GPIO_BASE + reg);
+}
+
+struct ar71xx_cpu_def qca953x_chip_def = {
+       &qca953x_chip_detect_mem_size,
+       &qca953x_chip_detect_sys_frequency,
+       &qca953x_chip_device_stop,
+       &qca953x_chip_device_start,
+       &qca953x_chip_device_stopped,
+       &qca953x_chip_set_pll_ge,
+       &qca953x_chip_set_mii_speed,
+       &qca953x_chip_set_mii_if,
+       &qca953x_chip_get_eth_pll,
+       &qca953x_chip_ddr_flush,
+       &qca953x_chip_init_usb_peripheral,
+       &qca953x_chip_reset_ethernet_switch,
+       &qca953x_chip_reset_wmac,
+       &qca953x_chip_init_gmac,
+       &qca953x_chip_reset_nfc,
+       &qca953x_chip_gpio_output_configure,
+};

Added: head/sys/mips/atheros/qca953x_chip.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/atheros/qca953x_chip.h        Mon Nov 16 04:28:00 2015        
(r290910)
@@ -0,0 +1,34 @@
+/*-
+ * Copyright (c) 2015 Adrian Chadd <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $FreeBSD$ */
+
+#ifndef        __QCA953X_CHIP_H__
+#define        __QCA953X_CHIP_H__
+
+extern struct ar71xx_cpu_def qca953x_chip_def;
+
+#endif

Added: head/sys/mips/atheros/qca953xreg.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/atheros/qca953xreg.h  Mon Nov 16 04:28:00 2015        
(r290910)
@@ -0,0 +1,195 @@
+/*-
+ * Copyright (c) 2015 Adrian Chadd <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef        __QCA953XREG_H__
+#define        __QCA953XREG_H__
+
+#define        BIT(x)                          (1 << (x))
+
+/* Revision ID information */
+#define        REV_ID_MAJOR_QCA9533            0x0140
+#define        REV_ID_MAJOR_QCA9533_V2         0x0160
+#define        QCA953X_REV_ID_REVISION_MASK    0xf
+
+/* Big enough to cover APB and SPI, and most peripherals */
+/*
+ * it needs to cover SPI because right now the if_ath_ahb
+ * code uses rman to map in the SPI address into memory
+ * to read data instead of us squirreling it away at early
+ * boot-time and using the firmware interface.
+ *
+ * if_ath_ahb.c should use the same firmware interface
+ * that if_ath_pci.c uses.
+ */
+#define        QCA953X_GMAC_BASE      (AR71XX_APB_BASE + 0x00070000)
+#define        QCA953X_GMAC_SIZE      0x14
+#define        QCA953X_WMAC_BASE      (AR71XX_APB_BASE + 0x00100000)
+#define        QCA953X_WMAC_SIZE      0x20000
+#define        QCA953X_EHCI_BASE      0x1b000000
+#define        QCA953X_EHCI_SIZE      0x200
+#define        QCA953X_SRIF_BASE      (AR71XX_APB_BASE + 0x00116000)
+#define        QCA953X_SRIF_SIZE      0x1000
+
+#define        QCA953X_PCI_CFG_BASE0  0x14000000
+#define        QCA953X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000)
+#define        QCA953X_PCI_CRP_BASE0  (AR71XX_APB_BASE + 0x000c0000)
+#define        QCA953X_PCI_MEM_BASE0  0x10000000
+#define        QCA953X_PCI_MEM_SIZE   0x02000000
+
+/* PLL Block */
+#define        QCA953X_PLL_CPU_CONFIG_REG              (AR71XX_PLL_CPU_BASE + 
0x00)
+#define        QCA953X_PLL_DDR_CONFIG_REG              (AR71XX_PLL_CPU_BASE + 
0x04)
+#define        QCA953X_PLL_CLK_CTRL_REG                (AR71XX_PLL_CPU_BASE + 
0x08)
+
+#define        QCA953X_PLL_ETH_XMII_CONTROL_REG        (AR71XX_PLL_CPU_BASE + 
0x2c)
+#define        QCA953X_PLL_ETH_SGMII_CONTROL_REG       (AR71XX_PLL_CPU_BASE + 
0x48)
+
+#define        QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT      0
+#define        QCA953X_PLL_CPU_CONFIG_NFRAC_MASK       0x3f
+#define        QCA953X_PLL_CPU_CONFIG_NINT_SHIFT       6
+#define        QCA953X_PLL_CPU_CONFIG_NINT_MASK        0x3f
+#define        QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT     12
+#define        QCA953X_PLL_CPU_CONFIG_REFDIV_MASK      0x1f
+#define        QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT     19
+#define        QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK      0x3
+
+#define        QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT      0
+#define        QCA953X_PLL_DDR_CONFIG_NFRAC_MASK       0x3ff
+#define        QCA953X_PLL_DDR_CONFIG_NINT_SHIFT       10
+#define        QCA953X_PLL_DDR_CONFIG_NINT_MASK        0x3f
+#define        QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT     16
+#define        QCA953X_PLL_DDR_CONFIG_REFDIV_MASK      0x1f
+#define        QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT     23
+#define        QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK      0x7
+
+#define        QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS     BIT(2)
+#define        QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS     BIT(3)
+#define        QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS     BIT(4)
+#define        QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
+#define        QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK  0x1f
+#define        QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
+#define        QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK  0x1f
+#define        QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
+#define        QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK  0x1f
+#define        QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
+#define        QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
+#define        QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
+#define        QCA953X_PLL_VAL_1000                    0x16000000
+#define        QCA953X_PLL_VAL_100                     0x00000101
+#define        QCA953X_PLL_VAL_10                      0x00001616
+
+/* Reset block */
+
+#define        QCA953X_RESET_REG_RESET_MODULE          (AR71XX_RST_BLOCK_BASE 
+ 0x1c)
+#define        QCA953X_RESET_USB_EXT_PWR               BIT(29)
+#define        QCA953X_RESET_EXTERNAL                  BIT(28)
+#define        QCA953X_RESET_RTC                       BIT(27)
+#define        QCA953X_RESET_FULL_CHIP                 BIT(24)
+#define        QCA953X_RESET_GE1_MDIO                  BIT(23)
+#define        QCA953X_RESET_GE0_MDIO                  BIT(22)
+#define        QCA953X_RESET_CPU_NMI                   BIT(21)
+#define        QCA953X_RESET_CPU_COLD                  BIT(20)
+#define        QCA953X_RESET_DDR                       BIT(16)
+#define        QCA953X_RESET_USB_PHY_PLL_PWD_EXT       BIT(15)
+#define        QCA953X_RESET_GE1_MAC                   BIT(13)
+#define        QCA953X_RESET_ETH_SWITCH_ANALOG         BIT(12)
+#define        QCA953X_RESET_USB_PHY_ANALOG            BIT(11)
+#define        QCA953X_RESET_GE0_MAC                   BIT(9)
+#define        QCA953X_RESET_ETH_SWITCH                BIT(8)
+#define        QCA953X_RESET_PCIE_PHY                  BIT(7)
+#define        QCA953X_RESET_PCIE                      BIT(6)
+#define        QCA953X_RESET_USB_HOST                  BIT(5)
+#define        QCA953X_RESET_USB_PHY                   BIT(4)
+#define        QCA953X_RESET_USBSUS_OVERRIDE           BIT(3)
+
+#define        QCA953X_RESET_REG_BOOTSTRAP             (AR71XX_RST_BLOCK_BASE 
+ 0xb0)
+#define        QCA953X_BOOTSTRAP_SW_OPTION2            BIT(12)
+#define        QCA953X_BOOTSTRAP_SW_OPTION1            BIT(11)
+#define        QCA953X_BOOTSTRAP_EJTAG_MODE            BIT(5)
+#define        QCA953X_BOOTSTRAP_REF_CLK_40            BIT(4)
+#define        QCA953X_BOOTSTRAP_SDRAM_DISABLED        BIT(1)
+#define        QCA953X_BOOTSTRAP_DDR1                  BIT(0)
+
+#define        QCA953X_RESET_REG_EXT_INT_STATUS        (AR71XX_RST_BLOCK_BASE 
+ 0xac)
+
+#define        QCA953X_DDR_REG_FLUSH_GE0               (AR71XX_APB_BASE + 0x9c)
+#define        QCA953X_DDR_REG_FLUSH_GE1               (AR71XX_APB_BASE + 0xa0)
+#define        QCA953X_DDR_REG_FLUSH_USB               (AR71XX_APB_BASE + 0xa4)
+#define        QCA953X_DDR_REG_FLUSH_PCIE              (AR71XX_APB_BASE + 0xa8)
+#define        QCA953X_DDR_REG_FLUSH_WMAC              (AR71XX_APB_BASE + 0xac)
+
+/* GPIO block */
+#define        QCA953X_GPIO_REG_OUT_FUNC0      0x2c
+#define        QCA953X_GPIO_REG_OUT_FUNC1      0x30
+#define        QCA953X_GPIO_REG_OUT_FUNC2      0x34
+#define        QCA953X_GPIO_REG_OUT_FUNC3      0x38
+#define        QCA953X_GPIO_REG_OUT_FUNC4      0x3c
+#define        QCA953X_GPIO_REG_IN_ENABLE0     0x44
+#define        QCA953X_GPIO_REG_FUNC           0x6c
+
+#define        QCA953X_GPIO_OUT_MUX_SPI_CS1    10
+#define        QCA953X_GPIO_OUT_MUX_SPI_CS2    11
+#define        QCA953X_GPIO_OUT_MUX_SPI_CS0    9
+#define        QCA953X_GPIO_OUT_MUX_SPI_CLK    8
+#define        QCA953X_GPIO_OUT_MUX_SPI_MOSI   12
+#define        QCA953X_GPIO_OUT_MUX_LED_LINK1  41
+#define        QCA953X_GPIO_OUT_MUX_LED_LINK2  42
+#define        QCA953X_GPIO_OUT_MUX_LED_LINK3  43
+#define        QCA953X_GPIO_OUT_MUX_LED_LINK4  44
+#define        QCA953X_GPIO_OUT_MUX_LED_LINK5  45
+
+#define        QCA953X_GPIO_COUNT              18
+
+/* GMAC block */
+#define        QCA953X_GMAC_REG_ETH_CFG        (QCA953X_GMAC_BASE + 0x00)
+
+#define        QCA953X_ETH_CFG_SW_ONLY_MODE            BIT(6)
+#define        QCA953X_ETH_CFG_SW_PHY_SWAP             BIT(7)
+#define        QCA953X_ETH_CFG_SW_APB_ACCESS           BIT(9)
+#define        QCA953X_ETH_CFG_SW_ACC_MSB_FIRST        BIT(13)
+
+/* SRIF block */
+#define        QCA953X_SRIF_CPU_DPLL1_REG              0x1c0
+#define        QCA953X_SRIF_CPU_DPLL2_REG              0x1c4
+#define        QCA953X_SRIF_CPU_DPLL3_REG              0x1c8
+
+#define        QCA953X_SRIF_DDR_DPLL1_REG              0x240
+#define        QCA953X_SRIF_DDR_DPLL2_REG              0x244
+#define        QCA953X_SRIF_DDR_DPLL3_REG              0x248
+
+#define        QCA953X_SRIF_DPLL1_REFDIV_SHIFT         27
+#define        QCA953X_SRIF_DPLL1_REFDIV_MASK          0x1f
+#define        QCA953X_SRIF_DPLL1_NINT_SHIFT           18
+#define        QCA953X_SRIF_DPLL1_NINT_MASK            0x1ff
+#define        QCA953X_SRIF_DPLL1_NFRAC_MASK           0x0003ffff
+
+#define        QCA953X_SRIF_DPLL2_LOCAL_PLL            BIT(30)
+#define        QCA953X_SRIF_DPLL2_OUTDIV_SHIFT         13
+#define        QCA953X_SRIF_DPLL2_OUTDIV_MASK          0x7
+
+#endif /* __QCA953XREG_H__ */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to