Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci/voyager set the CPU clock back to full speed on ...



details:   https://anonhg.NetBSD.org/src/rev/72d0df1f09ac
branches:  trunk
changeset: 777560:72d0df1f09ac
user:      macallan <macallan%NetBSD.org@localhost>
date:      Thu Feb 23 07:37:16 2012 +0000

description:
set the CPU clock back to full speed on shutdown
this is necessary because PMON does not touch the clock scaling register on
reboot but still reports full CPU speed which confuses the clock code

diffstat:

 sys/dev/pci/voyager/pwmclock.c |  27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)

diffs (69 lines):

diff -r eb70e5a0db94 -r 72d0df1f09ac sys/dev/pci/voyager/pwmclock.c
--- a/sys/dev/pci/voyager/pwmclock.c    Thu Feb 23 07:30:30 2012 +0000
+++ b/sys/dev/pci/voyager/pwmclock.c    Thu Feb 23 07:37:16 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pwmclock.c,v 1.3 2012/02/14 22:27:20 macallan Exp $    */
+/*     $NetBSD: pwmclock.c,v 1.4 2012/02/23 07:37:16 macallan Exp $    */
 
 /*
  * Copyright (c) 2011 Michael Lorenz
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pwmclock.c,v 1.3 2012/02/14 22:27:20 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pwmclock.c,v 1.4 2012/02/23 07:37:16 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -63,6 +63,7 @@
        uint32_t sc_count;      /* should probably be 64 bit */
        int sc_step;
        int sc_step_wanted;
+       void *sc_shutdown_cookie;
 };
 
 static int     pwmclock_match(device_t, cfdata_t, void *);
@@ -89,6 +90,8 @@
 static int  pwmclock_cpuspeed_cur(SYSCTLFN_ARGS);
 static int  pwmclock_cpuspeed_available(SYSCTLFN_ARGS);
 
+static void pwmclock_shutdown(void *);
+
 static struct timecounter pwmclock_timecounter = {
        get_pwmclock_timecount, /* get_timecount */
        0,                      /* no poll_pps */
@@ -140,6 +143,15 @@
        pwmclock = sc;
        initclocks_ptr = pwmclock_start;
 
+       /*
+        * Establish a hook so on shutdown we can set the CPU clock back to
+        * full speed. This is necessary because PMON doesn't change the 
+        * clock scale register on a warm boot, the MIPS clock code gets
+        * confused if we're too slow and the loongson-specific bits run
+        * too late in the boot process
+        */
+       sc->sc_shutdown_cookie = shutdownhook_establish(pwmclock_shutdown, sc);
+
        /* ok, let's see how far the cycle counter gets between interrupts */
        DPRINTF("calibrating CPU timer...\n");
        for (clk = 1; clk < 8; clk++) {
@@ -204,6 +216,17 @@
                aprint_error_dev(sc->sc_dev, "couldn't create 'available' node\n");
 }
 
+static void
+pwmclock_shutdown(void *cookie)
+{
+       struct pwmclock_softc *sc = cookie;
+
+       /* just in case the interrupt handler runs again after this */
+       sc->sc_step_wanted = 7;
+       /* set the clock to full speed */
+       REGVAL(LS2F_CHIPCFG0) = (REGVAL(LS2F_CHIPCFG0) & ~LS2FCFG_FREQSCALE_MASK) | 7;
+}
+
 void
 pwmclock_set_speed(struct pwmclock_softc *sc, int speed)
 {



Home | Main Index | Thread Index | Old Index