Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Mar 2017 19:27:35 +0000 (UTC)
From:      "Landon J. Fuller" <landonf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r315651 - in head/sys/dev/bhnd/cores: chipc pmu
Message-ID:  <201703201927.v2KJRZxP081062@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <landon@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



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