Author: landonf
Date: Mon Mar 20 19:27:35 2017
New Revision: 315651
URL: https://svnweb.freebsd.org/changeset/base/315651

Log:
  Integrate BCM4706 PMU (rev6) support, derived from the ISC-licensed Broadcom
  sbchipc.h and hndpmu.c sources included in the RT-N16 and later firmware
  source drops.
  
  Approved by:  adrian (mentor, implicit)

Modified:
  head/sys/dev/bhnd/cores/chipc/chipcreg.h
  head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c
  head/sys/dev/bhnd/cores/pmu/bhnd_pmureg.h

Modified: head/sys/dev/bhnd/cores/chipc/chipcreg.h
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipcreg.h    Mon Mar 20 19:25:42 2017        
(r315650)
+++ head/sys/dev/bhnd/cores/chipc/chipcreg.h    Mon Mar 20 19:27:35 2017        
(r315651)
@@ -1,11 +1,11 @@
 /*-
  * Copyright (c) 2015-2016 Landon Fuller <lan...@landonf.org>
- * Copyright (c) 2010 Broadcom Corporation
+ * Copyright (c) 2010-2015 Broadcom Corporation
  * All rights reserved.
  *
- * This file is derived from the sbchipc.h header distributed with
- * Broadcom's initial brcm80211 Linux driver release, as
- * contributed to the Linux staging repository.
+ * This file is derived from the sbchipc.h header contributed by Broadcom 
+ * to to the Linux staging repository, as well as later revisions of sbchipc.h
+ * distributed with the Asus RT-N16 firmware source code release.
  * 
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -928,6 +928,29 @@ enum {
 #define        CHIPC_CST43228_SDIO_OTP_PRESENT         0x10
 #define        CHIPC_CST43228_SDIO_RESET               0x20
 
+/* 4706 chipstatus reg bits */
+#define        CHIPC_CST4706_LOWCOST_PKG               (1<<0)  /* 0: 
full-featured package 1: low-cost package */
+#define        CHIPC_CST4706_SFLASH_PRESENT            (1<<1)  /* 0: parallel, 
1: serial flash is present */
+#define        CHIPC_CST4706_SFLASH_TYPE               (1<<2)  /* 0: 8b-p/ST-s 
flash, 1: 16b-p/Atmal-s flash */
+#define        CHIPC_CST4706_MIPS_BENDIAN              (1<<3)  /* 0: little,  
1: big endian */
+#define        CHIPC_CST4706_PCIE1_DISABLE             (1<<5)  /* PCIE1 enable 
strap pin */
+
+/* 4706 flashstrconfig reg bits */
+#define        CHIPC_FLSTRCF4706_MASK                  0x000000ff
+#define        CHIPC_FLSTRCF4706_SF1                   0x00000001      /* 2nd 
serial flash present */
+#define        CHIPC_FLSTRCF4706_PF1                   0x00000002      /* 2nd 
parallel flash present */
+#define        CHIPC_FLSTRCF4706_SF1_TYPE              0x00000004      /* 2nd 
serial flash type : 0 : ST, 1 : Atmel */
+#define        CHIPC_FLSTRCF4706_NF1                   0x00000008      /* 2nd 
NAND flash present */
+#define        CHIPC_FLSTRCF4706_1ST_MADDR_SEG_MASK    0x000000f0      /* 
Valid value mask */
+#define        CHIPC_FLSTRCF4706_1ST_MADDR_SEG_SHIFT   4
+#define          CHIPC_FLSTRCF4706_1ST_MADDR_SEG_4MB   0x1             /* 4MB 
*/
+#define          CHIPC_FLSTRCF4706_1ST_MADDR_SEG_8MB   0x2             /* 8MB 
*/
+#define          CHIPC_FLSTRCF4706_1ST_MADDR_SEG_16MB  0x3             /* 16MB 
*/
+#define          CHIPC_FLSTRCF4706_1ST_MADDR_SEG_32MB  0x4             /* 32MB 
*/
+#define          CHIPC_FLSTRCF4706_1ST_MADDR_SEG_64MB  0x5             /* 64MB 
*/
+#define          CHIPC_FLSTRCF4706_1ST_MADDR_SEG_128MB 0x6             /* 
128MB */
+#define          CHIPC_FLSTRCF4706_1ST_MADDR_SEG_256MB 0x7             /* 
256MB */
+
 /*
 * Register eci_inputlo bitfield values.
 * - BT packet type information bits [7:0]

Modified: head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c
==============================================================================
--- head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c Mon Mar 20 19:25:42 2017        
(r315650)
+++ head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c Mon Mar 20 19:27:35 2017        
(r315651)
@@ -69,6 +69,9 @@ static uint32_t       bhnd_pmu1_alpclk0(struct
 
 static uint32_t        bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, 
u_int m);
 
+static uint32_t        bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int 
pll0,
+                   u_int m);
+
 /* PMU resources */
 static bool    bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc);
 static bool    bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc);
@@ -2329,6 +2332,47 @@ bhnd_pmu5_clock(struct bhnd_pmu_query *s
        return ((fc / div) * 1000000);
 }
 
+static uint32_t
+bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m)
+{
+       uint32_t chipst, clock;
+       uint32_t ndiv, p1div, p2div, tmp;
+
+       /* Get N, P1 and P2 dividers to determine CPU clock */
+       BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
+           pll0 + BHND_PMU6_4706_PROCPLL_OFF);
+       BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
+
+       tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
+       ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_NDIV_INT);
+       p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P1DIV);
+       p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P2DIV);
+
+       /* Fixed 25MHz reference clock */
+       clock = 25 * 1000 * 1000;
+
+       /* The low-cost bonding uses an input divider of 4; otherwise, 2 */
+       chipst = sc->io->rd_chipst(sc->io_ctx);
+       if (chipst & CHIPC_CST4706_LOWCOST_PKG)
+               clock /= 4;
+       else
+               clock /= 2;
+
+       clock *= ndiv * p2div / p1div;
+
+       switch (m) {
+       case BHND_PMU6_MAINPLL_CPU:
+               return (clock);
+       case BHND_PMU6_MAINPLL_MEM:
+               return (clock / 2);
+       case BHND_PMU6_MAINPLL_SI:
+               return (clock / 4);
+       default:
+               PMU_LOG(sc, "bad m divider: %d", m);
+               return (0);
+       }
+}
+
 /**
  * Return the backplane clock frequency, in Hz.
  * 
@@ -2425,6 +2469,10 @@ bhnd_pmu_si_clock(struct bhnd_pmu_query 
                clock = bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
                    BHND_PMU5_MAINPLL_SI);
                break;
+       case BHND_CHIPID_BCM4706:
+               clock = bhnd_pmu6_4706_clock(sc, BHND_PMU4706_MAINPLL_PLL0,
+                   BHND_PMU6_MAINPLL_SI);
+               break;
        case BHND_CHIPID_BCM53572:
                clock = 75000000;
                break;
@@ -2446,8 +2494,6 @@ bhnd_pmu_si_clock(struct bhnd_pmu_query 
 uint32_t 
 bhnd_pmu_cpu_clock(struct bhnd_pmu_query *sc)
 {
-       uint32_t clock;
-
        /* 5354 chip uses a non programmable PLL of frequency 240MHz */
        if (sc->cid.chip_id == BHND_CHIPID_BCM5354)
                return (240 * 1000 * 1000); /* 240MHz */
@@ -2466,27 +2512,27 @@ bhnd_pmu_cpu_clock(struct bhnd_pmu_query
            sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
            sc->cid.chip_id != BHND_CHIPID_BCM4330)
        {
-               u_int pll;
-
                switch (sc->cid.chip_id) {
                case BHND_CHIPID_BCM5356:
-                       pll = BHND_PMU5356_MAINPLL_PLL0;
-                       break;
+                       return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
+                           BHND_PMU5_MAINPLL_CPU));
+
                case BHND_CHIPID_BCM5357:
                case BHND_CHIPID_BCM4749:
-                       pll = BHND_PMU5357_MAINPLL_PLL0;
-                       break;
+                       return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
+                           BHND_PMU5_MAINPLL_CPU));
+
+               case BHND_CHIPID_BCM4706:
+                       return (bhnd_pmu6_4706_clock(sc,
+                           BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_CPU));
+
                default:
-                       pll = BHND_PMU4716_MAINPLL_PLL0;
-                       break;
+                       return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
+                           BHND_PMU5_MAINPLL_CPU));
                }
-
-               clock = bhnd_pmu5_clock(sc, pll, BHND_PMU5_MAINPLL_CPU);
        } else {
-               clock = bhnd_pmu_si_clock(sc);
+               return (bhnd_pmu_si_clock(sc));
        }
-
-       return (clock);
 }
 
 /**
@@ -2497,8 +2543,6 @@ bhnd_pmu_cpu_clock(struct bhnd_pmu_query
 uint32_t
 bhnd_pmu_mem_clock(struct bhnd_pmu_query *sc)
 {
-       uint32_t clock;
-
        if (BHND_PMU_REV(sc) >= 5 &&
            sc->cid.chip_id != BHND_CHIPID_BCM4329 &&
            sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
@@ -2510,27 +2554,28 @@ bhnd_pmu_mem_clock(struct bhnd_pmu_query
            sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
            sc->cid.chip_id != BHND_CHIPID_BCM4330)
        {
-               u_int pll;
-
                switch (sc->cid.chip_id) {
                case BHND_CHIPID_BCM5356:
-                       pll = BHND_PMU5356_MAINPLL_PLL0;
-                       break;
+                       return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
+                           BHND_PMU5_MAINPLL_MEM));
+
                case BHND_CHIPID_BCM5357:
                case BHND_CHIPID_BCM4749:
-                       pll = BHND_PMU5357_MAINPLL_PLL0;
-                       break;
+                       return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
+                           BHND_PMU5_MAINPLL_MEM));
+
+               case BHND_CHIPID_BCM4706:
+                       return (bhnd_pmu6_4706_clock(sc,
+                           BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_MEM));
+
                default:
-                       pll = BHND_PMU4716_MAINPLL_PLL0;
-                       break;
+                       return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
+                           BHND_PMU5_MAINPLL_MEM));
                }
 
-               clock = bhnd_pmu5_clock(sc, pll, BHND_PMU5_MAINPLL_MEM);
        } else {
-               clock = bhnd_pmu_si_clock(sc);
+               return (bhnd_pmu_si_clock(sc));
        }
-
-       return (clock);
 }
 
 /* Measure ILP clock frequency */

Modified: head/sys/dev/bhnd/cores/pmu/bhnd_pmureg.h
==============================================================================
--- head/sys/dev/bhnd/cores/pmu/bhnd_pmureg.h   Mon Mar 20 19:25:42 2017        
(r315650)
+++ head/sys/dev/bhnd/cores/pmu/bhnd_pmureg.h   Mon Mar 20 19:27:35 2017        
(r315651)
@@ -370,6 +370,24 @@
 #define        BHND_PMU5_MAINPLL_MEM           2
 #define        BHND_PMU5_MAINPLL_SI            3
 
+/* PMU rev 6 (BCM4706/Northstar) */
+#define        BHND_PMU4706_MAINPLL_PLL0               0
+#define        BHND_PMU6_4706_PROCPLL_OFF              4       /* The CPU PLL 
*/
+#define        BHND_PMU6_4706_PROC_P1DIV_MASK          0x000f0000
+#define        BHND_PMU6_4706_PROC_P1DIV_SHIFT         16
+#define        BHND_PMU6_4706_PROC_P2DIV_MASK          0x0000f000
+#define        BHND_PMU6_4706_PROC_P2DIV_SHIFT         12
+#define        BHND_PMU6_4706_PROC_NDIV_INT_MASK       0x00000ff8
+#define        BHND_PMU6_4706_PROC_NDIV_INT_SHIFT      3
+#define        BHND_PMU6_4706_PROC_NDIV_MODE_MASK      0x00000007
+#define        BHND_PMU6_4706_PROC_NDIV_MODE_SHIFT     0
+
+/* Divider allocation in 4706 */
+#define        BHND_PMU6_MAINPLL_CPU           1
+#define        BHND_PMU6_MAINPLL_MEM           2
+#define        BHND_PMU6_MAINPLL_SI            3
+
+/* PMU7 (?) */
 #define        BHND_PMU7_PLL_PLLCTL7           7
 #define        BHND_PMU7_PLL_PLLCTL8           8
 #define        BHND_PMU7_PLL_PLLCTL11          11
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to