svn commit: r255823 - in projects/pmac_pmu/sys/powerpc: cpufreq powermac
Justin Hibbits
jhibbits at FreeBSD.org
Mon Sep 23 18:53:49 UTC 2013
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 */
More information about the svn-src-projects
mailing list