Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Jan 2016 19:34:05 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r294678 - stable/10/sys/arm/freescale/imx
Message-ID:  <201601241934.u0OJY6pK081659@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sun Jan 24 19:34:05 2016
New Revision: 294678
URL: https://svnweb.freebsd.org/changeset/base/294678

Log:
  MFC r291149, r291367:
  
    Update the imx5/imx6 cpu_reset() implementation based on a new understanding
    of the SRS (software reset) bit in the watchdog control register.  Despite
    what the manual seems to imply, this bit DOES trigger an immediate reset, as
    opposed to simply flagging the type of reset as software-triggered.
  
    Rename sysctl node hw.imx6 to hw.imx.  Move its definition to imx_machdep.c
    so that code shared between imx5 and imx6 can work with OIDs under that node.
  
    Add last_reset_status (integer) and last_reset_reason (string) OIDs that
    provide info about the last chip reset (power-on, software reset, watchdog
    timeout).

Modified:
  stable/10/sys/arm/freescale/imx/imx6_anatop.c
  stable/10/sys/arm/freescale/imx/imx6_machdep.c
  stable/10/sys/arm/freescale/imx/imx_machdep.c
  stable/10/sys/arm/freescale/imx/imx_machdep.h
  stable/10/sys/arm/freescale/imx/imx_wdogreg.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/arm/freescale/imx/imx6_anatop.c
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx6_anatop.c	Sun Jan 24 19:21:53 2016	(r294677)
+++ stable/10/sys/arm/freescale/imx/imx6_anatop.c	Sun Jan 24 19:34:05 2016	(r294678)
@@ -73,11 +73,10 @@ __FBSDID("$FreeBSD$");
 #include <arm/freescale/fsl_ocotpreg.h>
 #include <arm/freescale/fsl_ocotpvar.h>
 #include <arm/freescale/imx/imx_ccmvar.h>
+#include <arm/freescale/imx/imx_machdep.h>
 #include <arm/freescale/imx/imx6_anatopreg.h>
 #include <arm/freescale/imx/imx6_anatopvar.h>
 
-static SYSCTL_NODE(_hw, OID_AUTO, imx6, CTLFLAG_RW, NULL, "i.MX6 container");
-
 static struct resource_spec imx6_anatop_spec[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
@@ -396,23 +395,23 @@ cpufreq_initialize(struct imx6_anatop_so
 	uint32_t cfg3speed;
 	struct oppt * op;
 
-	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
 	    OID_AUTO, "cpu_mhz", CTLFLAG_RD, &sc->cpu_curmhz, 0, 
 	    "CPU frequency");
 
-	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6), 
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx), 
 	    OID_AUTO, "cpu_minmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
 	    cpufreq_sysctl_minmhz, "IU", "Minimum CPU frequency");
 
-	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
 	    OID_AUTO, "cpu_maxmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
 	    cpufreq_sysctl_maxmhz, "IU", "Maximum CPU frequency");
 
-	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
 	    OID_AUTO, "cpu_maxmhz_hw", CTLFLAG_RD, &sc->cpu_maxmhz_hw, 0, 
 	    "Maximum CPU frequency allowed by hardware");
 
-	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
 	    OID_AUTO, "cpu_overclock_enable", CTLFLAG_RWTUN, 
 	    &sc->cpu_overclock_enable, 0, 
 	    "Allow setting CPU frequency higher than cpu_maxmhz_hw");
@@ -630,10 +629,10 @@ initialize_tempmon(struct imx6_anatop_so
 	callout_reset_sbt(&sc->temp_throttle_callout, sc->temp_throttle_delay, 
 	    0, tempmon_throttle_check, sc, 0);
 
-	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6), 
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx), 
 	    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
 	    temp_sysctl_handler, "IK", "Current die temperature");
-	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6), 
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx), 
 	    OID_AUTO, "throttle_temperature", CTLTYPE_INT | CTLFLAG_RW, sc,
 	    0, temp_throttle_sysctl_handler, "IK", 
 	    "Throttle CPU when exceeding this temperature");

Modified: stable/10/sys/arm/freescale/imx/imx6_machdep.c
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx6_machdep.c	Sun Jan 24 19:21:53 2016	(r294677)
+++ stable/10/sys/arm/freescale/imx/imx6_machdep.c	Sun Jan 24 19:34:05 2016	(r294678)
@@ -99,7 +99,6 @@ initarm_lastaddr(void)
 void
 initarm_early_init(void)
 {
-
 	/* Inform the MPCore timer driver that its clock is variable. */
 	arm_tmr_change_frequency(ARM_TMR_FREQUENCY_VARIES);
 }
@@ -113,6 +112,9 @@ initarm_gpio_init(void)
 void
 initarm_late_init(void)
 {
+	const uint32_t IMX6_WDOG_SR_PHYS = 0x020bc004;
+
+	imx_wdog_init_last_reset(IMX6_WDOG_SR_PHYS);
 
 	/* Cache the gpio1 node handle for imx6_decode_fdt() workaround code. */
 	gpio1_node = OF_node_from_xref(

Modified: stable/10/sys/arm/freescale/imx/imx_machdep.c
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx_machdep.c	Sun Jan 24 19:21:53 2016	(r294677)
+++ stable/10/sys/arm/freescale/imx/imx_machdep.c	Sun Jan 24 19:34:05 2016	(r294678)
@@ -45,6 +45,15 @@ __FBSDID("$FreeBSD$");
 #include <arm/freescale/imx/imx_machdep.h>
 #include <arm/freescale/imx/imx_wdogreg.h>
 
+SYSCTL_NODE(_hw, OID_AUTO, imx, CTLFLAG_RW, NULL, "i.MX container");
+
+static int last_reset_status;
+SYSCTL_UINT(_hw_imx, OID_AUTO, last_reset_status, CTLFLAG_RD, 
+    &last_reset_status, 0, "Last reset status register");
+
+SYSCTL_STRING(_hw_imx, OID_AUTO, last_reset_reason, CTLFLAG_RD, 
+    "unknown", 0, "Last reset reason");
+
 struct arm32_dma_range *
 bus_dma_get_range(void)
 {
@@ -72,21 +81,36 @@ imx_wdog_cpu_reset(vm_offset_t wdcr_phys
 	volatile uint16_t * pcr;
 
 	/*
-	 * The deceptively simple write of WDOG_CR_WDE enables the watchdog,
-	 * sets the timeout to its minimum value (half a second), and also
-	 * clears the SRS bit which results in the SFTW (software-requested
-	 * reset) bit being set in the watchdog status register after the reset.
-	 * This is how software can distinguish a reset from a wdog timeout.
+	 * Trigger an immediate reset by clearing the SRS bit in the watchdog
+	 * control register.  The reset happens on the next cycle of the wdog
+	 * 32KHz clock, so hang out in a spin loop until the reset takes effect.
 	 */
 	if ((pcr = arm_devmap_ptov(wdcr_physaddr, sizeof(*pcr))) == NULL) {
 		printf("cpu_reset() can't find its control register... locking up now.");
 	} else {
-		*pcr = WDOG_CR_WDE;
+		*pcr &= ~WDOG_CR_SRS;
 	}
 	for (;;)
 		continue;
 }
 
+void
+imx_wdog_init_last_reset(vm_offset_t wdsr_phys)
+{
+	volatile uint16_t * psr;
+
+	if ((psr = arm_devmap_ptov(wdsr_phys, sizeof(*psr))) == NULL)
+		return;
+	last_reset_status = *psr;
+	if (last_reset_status & WDOG_RSR_SFTW) {
+		sysctl___hw_imx_last_reset_reason.oid_arg1 = "SoftwareReset";
+	} else if (last_reset_status & WDOG_RSR_TOUT) {
+		sysctl___hw_imx_last_reset_reason.oid_arg1 = "WatchdogTimeout";
+	} else if (last_reset_status & WDOG_RSR_POR) {
+		sysctl___hw_imx_last_reset_reason.oid_arg1 = "PowerOnReset";
+	}
+}
+
 u_int
 imx_soc_family(void)
 {

Modified: stable/10/sys/arm/freescale/imx/imx_machdep.h
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx_machdep.h	Sun Jan 24 19:21:53 2016	(r294677)
+++ stable/10/sys/arm/freescale/imx/imx_machdep.h	Sun Jan 24 19:34:05 2016	(r294678)
@@ -30,10 +30,14 @@
 #define	IMX_MACHDEP_H
 
 #include <sys/types.h>
+#include <sys/sysctl.h>
+
+SYSCTL_DECL(_hw_imx);
 
 /* Common functions, implemented in imx_machdep.c. */
 
 void imx_wdog_cpu_reset(vm_offset_t _wdcr_phys)  __attribute__((__noreturn__));
+void imx_wdog_init_last_reset(vm_offset_t _wdsr_phys);
 
 /* From here down, routines are implemented in imxNN_machdep.c. */
 

Modified: stable/10/sys/arm/freescale/imx/imx_wdogreg.h
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx_wdogreg.h	Sun Jan 24 19:21:53 2016	(r294677)
+++ stable/10/sys/arm/freescale/imx/imx_wdogreg.h	Sun Jan 24 19:34:05 2016	(r294678)
@@ -47,6 +47,7 @@
 #define		WDOG_SR_STEP2		0xaaaa
 
 #define	WDOG_RSR_REG	0x04	/* Reset Status Register */
+#define		WDOG_RSR_POR		(1 << 4) /* Due to Power-On Reset */
 #define		WDOG_RSR_TOUT		(1 << 1) /* Due WDog timeout reset */
 #define		WDOG_RSR_SFTW		(1 << 0) /* Due Soft reset */
 



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