* with 'Suspend Modulation OFF Count Register'
* and 'Suspend Modulation ON Count Register'.
* These registers are 8bit counters that represent the number of
- * 32us intervals which the SUSP# pin is asserted/de-asserted to the
- * processor.
+ * 32us intervals which the SUSP# pin is asserted(ON)/de-asserted(OFF)
+ * to the processor.
*
* These counters define a ratio which is the effective frequency
* of operation of the system.
*
- * On Count
+ * OFF Count
* F_eff = Fgx * ----------------------
- * On Count + Off Count
+ * OFF Count + ON Count
*
* 0 <= On Count, Off Count <= 255
*
* From these limits, we can get register values
*
- * on_duration + off_duration <= MAX_DURATION
- * off_duration = on_duration * (stock_freq - freq) / freq
+ * off_duration + on_duration <= MAX_DURATION
+ * on_duration = off_duration * (stock_freq - freq) / freq
*
- * on_duration = (freq * DURATION) / stock_freq
- * off_duration = DURATION - on_duration
+ * off_duration = (freq * DURATION) / stock_freq
+ * on_duration = DURATION - off_duration
*
*
*---------------------------------------------------------------------------
*
* ChangeLog:
+ * Dec. 12, 2003 Hiroshi Miura <miura@da-cha.org>
+ * - fix on/off register mistake
+ * - fix cpu_khz calc when it stops cpu modulation.
+ *
* Dec. 11, 2002 Hiroshi Miura <miura@da-cha.org>
* - rewrite for Cyrix MediaGX Cx5510/5520 and
* NatSemi Geode Cs5530(A).
int old_tmp_freq = stock_freq;
int tmp_freq;
- *on_duration=1;
- *off_duration=0;
+ *off_duration=1;
+ *on_duration=0;
for (i=max_duration; i>0; i--) {
- tmp_on = ((khz * i) / stock_freq) & 0xff;
- tmp_off = i - tmp_on;
- tmp_freq = (stock_freq * tmp_on) / i;
+ tmp_off = ((khz * i) / stock_freq) & 0xff;
+ tmp_on = i - tmp_off;
+ tmp_freq = (stock_freq * tmp_off) / i;
/* if this relation is closer to khz, use this. If it's equal,
* prefer it, too - lower latency */
if (abs(tmp_freq - khz) <= abs(old_tmp_freq - khz)) {
freqs.new = new_khz;
- if (new_khz == stock_freq) { /* if new khz == 100% of CPU speed, it is special case */
- local_irq_save(flags);
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, (gx_params->pci_suscfg & ~(SUSMOD)));
- pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &(gx_params->pci_suscfg));
- local_irq_restore(flags);
- dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n");
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- return;
- }
-
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
local_irq_save(flags);
- switch (gx_params->cs55x0->device) {
- case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
- pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP;
- /* FIXME: need to test other values -- Zwane,Miura */
- pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */
- pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */
- pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1);
-
- if (gx_params->pci_rev < 0x10) { /* CS5530(rev 1.2, 1.3) */
+
+ if (new_khz != stock_freq) { /* if new khz == 100% of CPU speed, it is special case */
+ switch (gx_params->cs55x0->device) {
+ case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
+ pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP;
+ /* FIXME: need to test other values -- Zwane,Miura */
+ pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */
+ pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */
+ pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1);
+
+ if (gx_params->pci_rev < 0x10) { /* CS5530(rev 1.2, 1.3) */
+ suscfg = gx_params->pci_suscfg | SUSMOD;
+ } else { /* CS5530A,B.. */
+ suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE;
+ }
+ break;
+ case PCI_DEVICE_ID_CYRIX_5520:
+ case PCI_DEVICE_ID_CYRIX_5510:
suscfg = gx_params->pci_suscfg | SUSMOD;
- } else { /* CS5530A,B.. */
- suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE;
+ default:
+ local_irq_restore(flags);
+ dprintk("fatal: try to set unknown chipset.\n");
+ return;
}
- break;
- case PCI_DEVICE_ID_CYRIX_5520:
- case PCI_DEVICE_ID_CYRIX_5510:
- suscfg = gx_params->pci_suscfg | SUSMOD;
- break;
- default:
- local_irq_restore(flags);
- dprintk("fatal: try to set unknown chipset.\n");
- return;
+ } else {
+ suscfg = gx_params->pci_suscfg & ~(SUSMOD);
+ gx_params->off_duration = 0;
+ gx_params->on_duration = 0;
+ dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n");
}
pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration);