Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Sep 2013 18:53:49 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r255823 - in projects/pmac_pmu/sys/powerpc: cpufreq powermac
Message-ID:  <201309231853.r8NIrntY094577@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhibbits
Date: Mon Sep 23 18:53:48 2013
New Revision: 255823
URL: http://svnweb.freebsd.org/changeset/base/255823

Log:
  Improve PMU-based cpufreq.  This simplifies the logic in the pmufreq code,
  and simplifies the code in the low-level sleep code, to not depend on the
  external ap_timebase variable.

Modified:
  projects/pmac_pmu/sys/powerpc/cpufreq/pmufreq.c
  projects/pmac_pmu/sys/powerpc/powermac/pmu.c
  projects/pmac_pmu/sys/powerpc/powermac/pmuvar.h

Modified: projects/pmac_pmu/sys/powerpc/cpufreq/pmufreq.c
==============================================================================
--- projects/pmac_pmu/sys/powerpc/cpufreq/pmufreq.c	Mon Sep 23 18:50:47 2013	(r255822)
+++ projects/pmac_pmu/sys/powerpc/cpufreq/pmufreq.c	Mon Sep 23 18:53:48 2013	(r255823)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD: head/sys/powerpc/cpu
 #include <sys/bus.h>
 #include <sys/cpu.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/module.h>
 
 #include <dev/ofw/ofw_bus.h>
@@ -83,16 +84,12 @@ DRIVER_MODULE(pmufreq, cpu, pmufreq_driv
 static void
 pmufreq_identify(driver_t *driver, device_t parent)
 {
-	uint16_t vers;
-	vers = mfpvr() >> 16;
+	phandle_t node;
+	uint32_t min_freq;
 
-	/* Check for an MPC7455 CPU */
-	switch (vers) {
-		case MPC7455:
-			break;
-		default:
-			return;
-	}
+	node = ofw_bus_get_node(device_get_parent(parent));
+	if (OF_getprop(node, "min-clock-frequency", &min_freq, sizeof(min_freq)) == -1)
+		return;
 
 	/* Make sure we're not being doubly invoked. */
 	if (device_find_child(parent, "pmufreq", -1) != NULL)
@@ -166,8 +163,8 @@ pmufreq_settings(device_t dev, struct cf
 	sets[0].freq = sc->maxfreq; sets[0].dev = dev;
 	sets[1].freq = sc->minfreq; sets[1].dev = dev;
 	/* Set high latency for CPU frequency changes, it's a tedious process. */
-	sets[0].lat = 1000000;
-	sets[1].lat = 1000000;
+	sets[0].lat = INT_MAX;
+	sets[1].lat = INT_MAX;
 	*count = 2;
 
 	return (0);
@@ -186,9 +183,9 @@ pmufreq_set(device_t dev, const struct c
 	sc = device_get_softc(dev);
 
 	if (set->freq == sc->maxfreq)
-		speed_sel = 1;
-	else
 		speed_sel = 0;
+	else
+		speed_sel = 1;
 
 	error = pmu_set_speed(speed_sel);
 	if (error == 0)

Modified: projects/pmac_pmu/sys/powerpc/powermac/pmu.c
==============================================================================
--- projects/pmac_pmu/sys/powerpc/powermac/pmu.c	Mon Sep 23 18:50:47 2013	(r255822)
+++ projects/pmac_pmu/sys/powerpc/powermac/pmu.c	Mon Sep 23 18:53:48 2013	(r255823)
@@ -1126,10 +1126,10 @@ pmu_resume(device_t dev)
 static register_t sprgs[4];
 static register_t srrs[2];
 extern void *ap_pcpu;
-extern u_quad_t ap_timebase;
 
 void pmu_sleep_int(void)
 {
+	u_quad_t timebase;
 	register_t hid0;
 	register_t msr;
 	register_t saved_msr;
@@ -1141,7 +1141,7 @@ void pmu_sleep_int(void)
 
 	*(unsigned long *)0x80 = 0x100;
 	saved_msr = mfmsr();
-	ap_timebase = mftb();
+	timebase = mftb();
 	flush_disable_caches();
 	if (PCPU_GET(fputhread) != NULL)
 		save_fpu(PCPU_GET(fputhread));
@@ -1165,6 +1165,7 @@ void pmu_sleep_int(void)
 		while (1)
 			mtmsr(msr);
 	}
+	mttb(timebase);
 	PCPU_SET(curthread, curthread);
 	PCPU_SET(curpcb, curthread->td_pcb);
 	pmap_activate(curthread);
@@ -1176,6 +1177,10 @@ void pmu_sleep_int(void)
 	mtspr(SPR_SRR0, srrs[0]);
 	mtspr(SPR_SRR1, srrs[1]);
 	mtmsr(saved_msr);
+	if (PCPU_GET(fputhread) == curthread)
+		enable_fpu(curthread);
+	if (PCPU_GET(vecthread) == curthread)
+		enable_vec(curthread);
 	powerpc_sync();
 }
 
@@ -1205,7 +1210,7 @@ pmu_sleep(SYSCTL_HANDLER_ARGS)
 }
 
 int
-pmu_set_speed(int high_speed)
+pmu_set_speed(int low_speed)
 {
 	struct pmu_softc *sc;
 	uint8_t sleepcmd[] = {'W', 'O', 'O', 'F', 0};
@@ -1218,17 +1223,13 @@ pmu_set_speed(int high_speed)
 	mb();
 	mtdec(0x7fffffff);
 
-	/* The PMU speed change command actually uses '1' to denote low-speed. */
-	if (high_speed)
-		sleepcmd[4] = 0;
-	else
-		sleepcmd[4] = 1;
-
+	sleepcmd[4] = low_speed;
 	pmu_send(sc, PMU_CPU_SPEED, 5, sleepcmd, 16, resp);
 	unin_chip_sleep(NULL, 1);
 	pmu_sleep_int();
 	unin_chip_wake(NULL);
 
+	mtdec(1);	/* Force a decrementer exception */
 	spinlock_exit();
 	pmu_write_reg(sc, vIER, 0x90);
 

Modified: projects/pmac_pmu/sys/powerpc/powermac/pmuvar.h
==============================================================================
--- projects/pmac_pmu/sys/powerpc/powermac/pmuvar.h	Mon Sep 23 18:50:47 2013	(r255822)
+++ projects/pmac_pmu/sys/powerpc/powermac/pmuvar.h	Mon Sep 23 18:53:48 2013	(r255823)
@@ -173,6 +173,6 @@ struct pmu_battstate {
 	int voltage;
 };
 
-int pmu_set_speed(int high_speed);
+int pmu_set_speed(int low_speed);
 
 #endif /* PMUVAR_H */



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