// SPDX-License-Identifier: GPL-2.0-only /* * (C) 2004-2006 Sebastian Witt <se.witt@gmx.net> * * Based upon reverse engineered information * * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
*/
MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)");
MODULE_PARM_DESC(min_fsb, "Minimum FSB to use, if not defined: current FSB - 50");
/** * nforce2_calc_fsb - calculate FSB * @pll: PLL value * * Calculates FSB from PLL value
*/ staticint nforce2_calc_fsb(int pll)
{ unsignedchar mul, div;
mul = (pll >> 8) & 0xff;
div = pll & 0xff;
if (div > 0) return NFORCE2_XTAL * mul / div;
return 0;
}
/** * nforce2_calc_pll - calculate PLL value * @fsb: FSB * * Calculate PLL value for given FSB
*/ staticint nforce2_calc_pll(unsignedint fsb)
{ unsignedchar xmul, xdiv; unsignedchar mul = 0, div = 0; int tried = 0;
/* Try to calculate multiplier and divider up to 4 times */ while (((mul == 0) || (div == 0)) && (tried <= 3)) { for (xdiv = 2; xdiv <= 0x80; xdiv++) for (xmul = 1; xmul <= 0xfe; xmul++) if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) ==
fsb + tried) {
mul = xmul;
div = xdiv;
}
tried++;
}
if ((mul == 0) || (div == 0)) return -1;
return NFORCE2_PLL(mul, div);
}
/** * nforce2_write_pll - write PLL value to chipset * @pll: PLL value * * Writes new FSB PLL value to chipset
*/ staticvoid nforce2_write_pll(int pll)
{ int temp;
/* Set the pll addr. to 0x00 */
pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0);
/* Now write the value in all 64 registers */ for (temp = 0; temp <= 0x3f; temp++)
pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll);
}
/** * nforce2_get - get the CPU frequency * @cpu: CPU number * * Returns the CPU frequency
*/ staticunsignedint nforce2_get(unsignedint cpu)
{ if (cpu) return 0; return nforce2_fsb_read(0) * fid * 100;
}
/** * nforce2_target - set a new CPUFreq policy * @policy: new policy * @target_freq: the target frequency * @relation: how that frequency relates to achieved frequency * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) * * Sets a new CPUFreq policy.
*/ staticint nforce2_target(struct cpufreq_policy *policy, unsignedint target_freq, unsignedint relation)
{ /* unsigned long flags; */ struct cpufreq_freqs freqs; unsignedint target_fsb;
if ((target_freq > policy->max) || (target_freq < policy->min)) return -EINVAL;
pr_info("Detected nForce2 chipset revision %X\n",
nforce2_dev->revision);
pr_info("FSB changing is maybe unstable and can lead to crashes and data loss\n");
return 0;
}
/** * nforce2_init - initializes the nForce2 CPUFreq driver * * Initializes the nForce2 FSB support. Returns -ENODEV on unsupported * devices, -EINVAL on problems during initialization, and zero on * success.
*/ staticint __init nforce2_init(void)
{ /* TODO: do we need to detect the processor? */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.