On 31/01/16(Sun) 23:47, Olivier Cherrier wrote:
> Hi,
>
> It may not be the proper solution to control the fans on macppc smu (G5)
> but the following patch allows me to work with my iMac G5 without
> losing my hearing capacity ...
>
>
>
> $ sysctl hw.sensors
> hw.sensors.smu0.temp0=44.72 degC (CPU T-Diode)
> hw.sensors.smu0.fan0=1530 RPM (System Fan)
> hw.sensors.smu0.fan1=1530 RPM (CPU fan)
> hw.sensors.smu0.fan2=1530 RPM (Hard Drive)
> hw.sensors.smu0.volt0=11.87 VDC (CPU Voltage)
> hw.sensors.smu0.current0=0.63 A (CPU Current)
> hw.sensors.lmtemp0.temp0=51.00 degC
> $
>
> The fan range are:
> smu0 at mainbus0
> system: min-value: 1000
> system: max-value: 4000
> system: unmanage-value: 4000
> cpu: min-value: 1500
> cpu: max-value: 4400
> cpu: unmanage-value: 4400
> hd: min-value: 1800
> hd: max-value: 6000
> hd: unmanage-value: 6000
Could you test the diff below and tell me if it also helps? It is
adapted from a submission from Dominic Marks:
https://marc.info/?l=openbsd-ppc&m=142836014007157&w=2
Index: dev/smu.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/smu.c,v
retrieving revision 1.27
diff -u -p -r1.27 smu.c
--- dev/smu.c 4 Jun 2015 18:01:44 -0000 1.27
+++ dev/smu.c 18 Mar 2016 11:58:23 -0000
@@ -54,6 +54,13 @@ struct smu_sensor {
struct ksensor sensor;
};
+/* SMU CPU T-Diode sensor. */
+#define SMU_CPU_TEMP 0
+
+/* CPU temperature boundaries in muK. */
+#define CPU_TEMP_MAX (80 * 1000000 + 273150000)
+#define CPU_TEMP_MIN (30 * 1000000 + 273150000)
+
struct smu_softc {
struct device sc_dev;
@@ -145,8 +152,9 @@ int smu_time_write(time_t);
int smu_get_datablock(struct smu_softc *sc, u_int8_t, u_int8_t *, size_t);
int smu_fan_set_rpm(struct smu_softc *, struct smu_fan *, u_int16_t);
int smu_fan_refresh(struct smu_softc *, struct smu_fan *);
+int smu_fan_adjust(struct smu_softc *, struct smu_fan *, u_int64_t);
int smu_sensor_refresh(struct smu_softc *, struct smu_sensor *);
-void smu_refresh_sensors(void *);
+void smu_refresh(void *);
int smu_i2c_acquire_bus(void *, int);
void smu_i2c_release_bus(void *, int);
@@ -365,7 +373,7 @@ smu_attach(struct device *parent, struct
sc->sc_slots_pow_scale = (data[4] << 8) + data[5];
sc->sc_slots_pow_offset = (data[6] << 8) + data[7];
- sensor_task_register(sc, smu_refresh_sensors, 5);
+ sensor_task_register(sc, smu_refresh, 5);
#endif /* !SMALL_KERNEL */
printf("\n");
@@ -643,9 +651,10 @@ smu_sensor_refresh(struct smu_softc *sc,
}
void
-smu_refresh_sensors(void *arg)
+smu_refresh(void *arg)
{
struct smu_softc *sc = arg;
+ struct ksensor *ks;
int i;
rw_enter_write(&sc->sc_lock);
@@ -653,6 +662,10 @@ smu_refresh_sensors(void *arg)
smu_sensor_refresh(sc, &sc->sc_sensors[i]);
for (i = 0; i < sc->sc_num_fans; i++)
smu_fan_refresh(sc, &sc->sc_fans[i]);
+ if (sensor_find(0, SENSOR_TEMP, SMU_CPU_TEMP, &ks) == 0) {
+ for (i = 0; i < sc->sc_num_fans; i++)
+ smu_fan_adjust(sc, &sc->sc_fans[i], ks->value);
+ }
rw_exit_write(&sc->sc_lock);
}
@@ -754,4 +767,22 @@ smu_slew_voltage(u_int freq_scale)
smu_do_cmd(sc, 250);
rw_exit_write(&sc->sc_lock);
+}
+
+int
+smu_fan_adjust(struct smu_softc *sc, struct smu_fan *fan, u_int64_t ctemp)
+{
+ u_int16_t rpm;;
+
+ if (ctemp < CPU_TEMP_MIN) {
+ rpm = fan->min_rpm;
+ } else if (ctemp < CPU_TEMP_MAX) {
+ rpm = fan->min_rpm + (ctemp - CPU_TEMP_MIN) *
+ (fan->max_rpm - fan->min_rpm) /
+ (CPU_TEMP_MAX - CPU_TEMP_MIN);
+ } else {
+ rpm = fan->max_rpm;
+ }
+
+ return smu_fan_set_rpm(sc, fan, rpm);
}