longhaul.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. /*
  2. * (C) 2001-2004 Dave Jones. <davej@redhat.com>
  3. * (C) 2002 Padraig Brady. <padraig@antefacto.com>
  4. *
  5. * Licensed under the terms of the GNU GPL License version 2.
  6. * Based upon datasheets & sample CPUs kindly provided by VIA.
  7. *
  8. * VIA have currently 3 different versions of Longhaul.
  9. * Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
  10. * It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0.
  11. * Version 2 of longhaul is backward compatible with v1, but adds
  12. * LONGHAUL MSR for purpose of both frequency and voltage scaling.
  13. * Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C).
  14. * Version 3 of longhaul got renamed to Powersaver and redesigned
  15. * to use only the POWERSAVER MSR at 0x110a.
  16. * It is present in Ezra-T (C5M), Nehemiah (C5X) and above.
  17. * It's pretty much the same feature wise to longhaul v2, though
  18. * there is provision for scaling FSB too, but this doesn't work
  19. * too well in practice so we don't even try to use this.
  20. *
  21. * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
  22. */
  23. #include <linux/kernel.h>
  24. #include <linux/module.h>
  25. #include <linux/moduleparam.h>
  26. #include <linux/init.h>
  27. #include <linux/cpufreq.h>
  28. #include <linux/pci.h>
  29. #include <linux/slab.h>
  30. #include <linux/string.h>
  31. #include <linux/delay.h>
  32. #include <linux/timex.h>
  33. #include <linux/io.h>
  34. #include <linux/acpi.h>
  35. #include <asm/msr.h>
  36. #include <acpi/processor.h>
  37. #include "longhaul.h"
  38. #define PFX "longhaul: "
  39. #define TYPE_LONGHAUL_V1 1
  40. #define TYPE_LONGHAUL_V2 2
  41. #define TYPE_POWERSAVER 3
  42. #define CPU_SAMUEL 1
  43. #define CPU_SAMUEL2 2
  44. #define CPU_EZRA 3
  45. #define CPU_EZRA_T 4
  46. #define CPU_NEHEMIAH 5
  47. #define CPU_NEHEMIAH_C 6
  48. /* Flags */
  49. #define USE_ACPI_C3 (1 << 1)
  50. #define USE_NORTHBRIDGE (1 << 2)
  51. static int cpu_model;
  52. static unsigned int numscales = 16;
  53. static unsigned int fsb;
  54. static const struct mV_pos *vrm_mV_table;
  55. static const unsigned char *mV_vrm_table;
  56. static unsigned int highest_speed, lowest_speed; /* kHz */
  57. static unsigned int minmult, maxmult;
  58. static int can_scale_voltage;
  59. static struct acpi_processor *pr;
  60. static struct acpi_processor_cx *cx;
  61. static u32 acpi_regs_addr;
  62. static u8 longhaul_flags;
  63. static unsigned int longhaul_index;
  64. /* Module parameters */
  65. static int scale_voltage;
  66. static int disable_acpi_c3;
  67. static int revid_errata;
  68. /* Clock ratios multiplied by 10 */
  69. static int mults[32];
  70. static int eblcr[32];
  71. static int longhaul_version;
  72. static struct cpufreq_frequency_table *longhaul_table;
  73. static char speedbuffer[8];
  74. static char *print_speed(int speed)
  75. {
  76. if (speed < 1000) {
  77. snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed);
  78. return speedbuffer;
  79. }
  80. if (speed%1000 == 0)
  81. snprintf(speedbuffer, sizeof(speedbuffer),
  82. "%dGHz", speed/1000);
  83. else
  84. snprintf(speedbuffer, sizeof(speedbuffer),
  85. "%d.%dGHz", speed/1000, (speed%1000)/100);
  86. return speedbuffer;
  87. }
  88. static unsigned int calc_speed(int mult)
  89. {
  90. int khz;
  91. khz = (mult/10)*fsb;
  92. if (mult%10)
  93. khz += fsb/2;
  94. khz *= 1000;
  95. return khz;
  96. }
  97. static int longhaul_get_cpu_mult(void)
  98. {
  99. unsigned long invalue = 0, lo, hi;
  100. rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
  101. invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
  102. if (longhaul_version == TYPE_LONGHAUL_V2 ||
  103. longhaul_version == TYPE_POWERSAVER) {
  104. if (lo & (1<<27))
  105. invalue += 16;
  106. }
  107. return eblcr[invalue];
  108. }
  109. /* For processor with BCR2 MSR */
  110. static void do_longhaul1(unsigned int mults_index)
  111. {
  112. union msr_bcr2 bcr2;
  113. rdmsrl(MSR_VIA_BCR2, bcr2.val);
  114. /* Enable software clock multiplier */
  115. bcr2.bits.ESOFTBF = 1;
  116. bcr2.bits.CLOCKMUL = mults_index & 0xff;
  117. /* Sync to timer tick */
  118. safe_halt();
  119. /* Change frequency on next halt or sleep */
  120. wrmsrl(MSR_VIA_BCR2, bcr2.val);
  121. /* Invoke transition */
  122. ACPI_FLUSH_CPU_CACHE();
  123. halt();
  124. /* Disable software clock multiplier */
  125. local_irq_disable();
  126. rdmsrl(MSR_VIA_BCR2, bcr2.val);
  127. bcr2.bits.ESOFTBF = 0;
  128. wrmsrl(MSR_VIA_BCR2, bcr2.val);
  129. }
  130. /* For processor with Longhaul MSR */
  131. static void do_powersaver(int cx_address, unsigned int mults_index,
  132. unsigned int dir)
  133. {
  134. union msr_longhaul longhaul;
  135. u32 t;
  136. rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  137. /* Setup new frequency */
  138. if (!revid_errata)
  139. longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
  140. else
  141. longhaul.bits.RevisionKey = 0;
  142. longhaul.bits.SoftBusRatio = mults_index & 0xf;
  143. longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4;
  144. /* Setup new voltage */
  145. if (can_scale_voltage)
  146. longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f;
  147. /* Sync to timer tick */
  148. safe_halt();
  149. /* Raise voltage if necessary */
  150. if (can_scale_voltage && dir) {
  151. longhaul.bits.EnableSoftVID = 1;
  152. wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  153. /* Change voltage */
  154. if (!cx_address) {
  155. ACPI_FLUSH_CPU_CACHE();
  156. halt();
  157. } else {
  158. ACPI_FLUSH_CPU_CACHE();
  159. /* Invoke C3 */
  160. inb(cx_address);
  161. /* Dummy op - must do something useless after P_LVL3
  162. * read */
  163. t = inl(acpi_gbl_FADT.xpm_timer_block.address);
  164. }
  165. longhaul.bits.EnableSoftVID = 0;
  166. wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  167. }
  168. /* Change frequency on next halt or sleep */
  169. longhaul.bits.EnableSoftBusRatio = 1;
  170. wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  171. if (!cx_address) {
  172. ACPI_FLUSH_CPU_CACHE();
  173. halt();
  174. } else {
  175. ACPI_FLUSH_CPU_CACHE();
  176. /* Invoke C3 */
  177. inb(cx_address);
  178. /* Dummy op - must do something useless after P_LVL3 read */
  179. t = inl(acpi_gbl_FADT.xpm_timer_block.address);
  180. }
  181. /* Disable bus ratio bit */
  182. longhaul.bits.EnableSoftBusRatio = 0;
  183. wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  184. /* Reduce voltage if necessary */
  185. if (can_scale_voltage && !dir) {
  186. longhaul.bits.EnableSoftVID = 1;
  187. wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  188. /* Change voltage */
  189. if (!cx_address) {
  190. ACPI_FLUSH_CPU_CACHE();
  191. halt();
  192. } else {
  193. ACPI_FLUSH_CPU_CACHE();
  194. /* Invoke C3 */
  195. inb(cx_address);
  196. /* Dummy op - must do something useless after P_LVL3
  197. * read */
  198. t = inl(acpi_gbl_FADT.xpm_timer_block.address);
  199. }
  200. longhaul.bits.EnableSoftVID = 0;
  201. wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  202. }
  203. }
  204. /**
  205. * longhaul_set_cpu_frequency()
  206. * @mults_index : bitpattern of the new multiplier.
  207. *
  208. * Sets a new clock ratio.
  209. */
  210. static void longhaul_setstate(unsigned int table_index)
  211. {
  212. unsigned int mults_index;
  213. int speed, mult;
  214. struct cpufreq_freqs freqs;
  215. unsigned long flags;
  216. unsigned int pic1_mask, pic2_mask;
  217. u16 bm_status = 0;
  218. u32 bm_timeout = 1000;
  219. unsigned int dir = 0;
  220. mults_index = longhaul_table[table_index].index;
  221. /* Safety precautions */
  222. mult = mults[mults_index & 0x1f];
  223. if (mult == -1)
  224. return;
  225. speed = calc_speed(mult);
  226. if ((speed > highest_speed) || (speed < lowest_speed))
  227. return;
  228. /* Voltage transition before frequency transition? */
  229. if (can_scale_voltage && longhaul_index < table_index)
  230. dir = 1;
  231. freqs.old = calc_speed(longhaul_get_cpu_mult());
  232. freqs.new = speed;
  233. freqs.cpu = 0; /* longhaul.c is UP only driver */
  234. cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
  235. pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
  236. fsb, mult/10, mult%10, print_speed(speed/1000));
  237. retry_loop:
  238. preempt_disable();
  239. local_irq_save(flags);
  240. pic2_mask = inb(0xA1);
  241. pic1_mask = inb(0x21); /* works on C3. save mask. */
  242. outb(0xFF, 0xA1); /* Overkill */
  243. outb(0xFE, 0x21); /* TMR0 only */
  244. /* Wait while PCI bus is busy. */
  245. if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
  246. || ((pr != NULL) && pr->flags.bm_control))) {
  247. bm_status = inw(acpi_regs_addr);
  248. bm_status &= 1 << 4;
  249. while (bm_status && bm_timeout) {
  250. outw(1 << 4, acpi_regs_addr);
  251. bm_timeout--;
  252. bm_status = inw(acpi_regs_addr);
  253. bm_status &= 1 << 4;
  254. }
  255. }
  256. if (longhaul_flags & USE_NORTHBRIDGE) {
  257. /* Disable AGP and PCI arbiters */
  258. outb(3, 0x22);
  259. } else if ((pr != NULL) && pr->flags.bm_control) {
  260. /* Disable bus master arbitration */
  261. acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
  262. }
  263. switch (longhaul_version) {
  264. /*
  265. * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B])
  266. * Software controlled multipliers only.
  267. */
  268. case TYPE_LONGHAUL_V1:
  269. do_longhaul1(mults_index);
  270. break;
  271. /*
  272. * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5B] and Ezra [C5C]
  273. *
  274. * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N])
  275. * Nehemiah can do FSB scaling too, but this has never been proven
  276. * to work in practice.
  277. */
  278. case TYPE_LONGHAUL_V2:
  279. case TYPE_POWERSAVER:
  280. if (longhaul_flags & USE_ACPI_C3) {
  281. /* Don't allow wakeup */
  282. acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
  283. do_powersaver(cx->address, mults_index, dir);
  284. } else {
  285. do_powersaver(0, mults_index, dir);
  286. }
  287. break;
  288. }
  289. if (longhaul_flags & USE_NORTHBRIDGE) {
  290. /* Enable arbiters */
  291. outb(0, 0x22);
  292. } else if ((pr != NULL) && pr->flags.bm_control) {
  293. /* Enable bus master arbitration */
  294. acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
  295. }
  296. outb(pic2_mask, 0xA1); /* restore mask */
  297. outb(pic1_mask, 0x21);
  298. local_irq_restore(flags);
  299. preempt_enable();
  300. freqs.new = calc_speed(longhaul_get_cpu_mult());
  301. /* Check if requested frequency is set. */
  302. if (unlikely(freqs.new != speed)) {
  303. printk(KERN_INFO PFX "Failed to set requested frequency!\n");
  304. /* Revision ID = 1 but processor is expecting revision key
  305. * equal to 0. Jumpers at the bottom of processor will change
  306. * multiplier and FSB, but will not change bits in Longhaul
  307. * MSR nor enable voltage scaling. */
  308. if (!revid_errata) {
  309. printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" "
  310. "option.\n");
  311. revid_errata = 1;
  312. msleep(200);
  313. goto retry_loop;
  314. }
  315. /* Why ACPI C3 sometimes doesn't work is a mystery for me.
  316. * But it does happen. Processor is entering ACPI C3 state,
  317. * but it doesn't change frequency. I tried poking various
  318. * bits in northbridge registers, but without success. */
  319. if (longhaul_flags & USE_ACPI_C3) {
  320. printk(KERN_INFO PFX "Disabling ACPI C3 support.\n");
  321. longhaul_flags &= ~USE_ACPI_C3;
  322. if (revid_errata) {
  323. printk(KERN_INFO PFX "Disabling \"Ignore "
  324. "Revision ID\" option.\n");
  325. revid_errata = 0;
  326. }
  327. msleep(200);
  328. goto retry_loop;
  329. }
  330. /* This shouldn't happen. Longhaul ver. 2 was reported not
  331. * working on processors without voltage scaling, but with
  332. * RevID = 1. RevID errata will make things right. Just
  333. * to be 100% sure. */
  334. if (longhaul_version == TYPE_LONGHAUL_V2) {
  335. printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n");
  336. longhaul_version = TYPE_LONGHAUL_V1;
  337. msleep(200);
  338. goto retry_loop;
  339. }
  340. }
  341. /* Report true CPU frequency */
  342. cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
  343. if (!bm_timeout)
  344. printk(KERN_INFO PFX "Warning: Timeout while waiting for "
  345. "idle PCI bus.\n");
  346. }
  347. /*
  348. * Centaur decided to make life a little more tricky.
  349. * Only longhaul v1 is allowed to read EBLCR BSEL[0:1].
  350. * Samuel2 and above have to try and guess what the FSB is.
  351. * We do this by assuming we booted at maximum multiplier, and interpolate
  352. * between that value multiplied by possible FSBs and cpu_mhz which
  353. * was calculated at boot time. Really ugly, but no other way to do this.
  354. */
  355. #define ROUNDING 0xf
  356. static int guess_fsb(int mult)
  357. {
  358. int speed = cpu_khz / 1000;
  359. int i;
  360. int speeds[] = { 666, 1000, 1333, 2000 };
  361. int f_max, f_min;
  362. for (i = 0; i < 4; i++) {
  363. f_max = ((speeds[i] * mult) + 50) / 100;
  364. f_max += (ROUNDING / 2);
  365. f_min = f_max - ROUNDING;
  366. if ((speed <= f_max) && (speed >= f_min))
  367. return speeds[i] / 10;
  368. }
  369. return 0;
  370. }
  371. static int __cpuinit longhaul_get_ranges(void)
  372. {
  373. unsigned int i, j, k = 0;
  374. unsigned int ratio;
  375. int mult;
  376. /* Get current frequency */
  377. mult = longhaul_get_cpu_mult();
  378. if (mult == -1) {
  379. printk(KERN_INFO PFX "Invalid (reserved) multiplier!\n");
  380. return -EINVAL;
  381. }
  382. fsb = guess_fsb(mult);
  383. if (fsb == 0) {
  384. printk(KERN_INFO PFX "Invalid (reserved) FSB!\n");
  385. return -EINVAL;
  386. }
  387. /* Get max multiplier - as we always did.
  388. * Longhaul MSR is useful only when voltage scaling is enabled.
  389. * C3 is booting at max anyway. */
  390. maxmult = mult;
  391. /* Get min multiplier */
  392. switch (cpu_model) {
  393. case CPU_NEHEMIAH:
  394. minmult = 50;
  395. break;
  396. case CPU_NEHEMIAH_C:
  397. minmult = 40;
  398. break;
  399. default:
  400. minmult = 30;
  401. break;
  402. }
  403. pr_debug("MinMult:%d.%dx MaxMult:%d.%dx\n",
  404. minmult/10, minmult%10, maxmult/10, maxmult%10);
  405. highest_speed = calc_speed(maxmult);
  406. lowest_speed = calc_speed(minmult);
  407. pr_debug("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb,
  408. print_speed(lowest_speed/1000),
  409. print_speed(highest_speed/1000));
  410. if (lowest_speed == highest_speed) {
  411. printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n");
  412. return -EINVAL;
  413. }
  414. if (lowest_speed > highest_speed) {
  415. printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
  416. lowest_speed, highest_speed);
  417. return -EINVAL;
  418. }
  419. longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
  420. GFP_KERNEL);
  421. if (!longhaul_table)
  422. return -ENOMEM;
  423. for (j = 0; j < numscales; j++) {
  424. ratio = mults[j];
  425. if (ratio == -1)
  426. continue;
  427. if (ratio > maxmult || ratio < minmult)
  428. continue;
  429. longhaul_table[k].frequency = calc_speed(ratio);
  430. longhaul_table[k].index = j;
  431. k++;
  432. }
  433. if (k <= 1) {
  434. kfree(longhaul_table);
  435. return -ENODEV;
  436. }
  437. /* Sort */
  438. for (j = 0; j < k - 1; j++) {
  439. unsigned int min_f, min_i;
  440. min_f = longhaul_table[j].frequency;
  441. min_i = j;
  442. for (i = j + 1; i < k; i++) {
  443. if (longhaul_table[i].frequency < min_f) {
  444. min_f = longhaul_table[i].frequency;
  445. min_i = i;
  446. }
  447. }
  448. if (min_i != j) {
  449. swap(longhaul_table[j].frequency,
  450. longhaul_table[min_i].frequency);
  451. swap(longhaul_table[j].index,
  452. longhaul_table[min_i].index);
  453. }
  454. }
  455. longhaul_table[k].frequency = CPUFREQ_TABLE_END;
  456. /* Find index we are running on */
  457. for (j = 0; j < k; j++) {
  458. if (mults[longhaul_table[j].index & 0x1f] == mult) {
  459. longhaul_index = j;
  460. break;
  461. }
  462. }
  463. return 0;
  464. }
  465. static void __cpuinit longhaul_setup_voltagescaling(void)
  466. {
  467. union msr_longhaul longhaul;
  468. struct mV_pos minvid, maxvid, vid;
  469. unsigned int j, speed, pos, kHz_step, numvscales;
  470. int min_vid_speed;
  471. rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
  472. if (!(longhaul.bits.RevisionID & 1)) {
  473. printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
  474. return;
  475. }
  476. if (!longhaul.bits.VRMRev) {
  477. printk(KERN_INFO PFX "VRM 8.5\n");
  478. vrm_mV_table = &vrm85_mV[0];
  479. mV_vrm_table = &mV_vrm85[0];
  480. } else {
  481. printk(KERN_INFO PFX "Mobile VRM\n");
  482. if (cpu_model < CPU_NEHEMIAH)
  483. return;
  484. vrm_mV_table = &mobilevrm_mV[0];
  485. mV_vrm_table = &mV_mobilevrm[0];
  486. }
  487. minvid = vrm_mV_table[longhaul.bits.MinimumVID];
  488. maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
  489. if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
  490. printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
  491. "Voltage scaling disabled.\n",
  492. minvid.mV/1000, minvid.mV%1000,
  493. maxvid.mV/1000, maxvid.mV%1000);
  494. return;
  495. }
  496. if (minvid.mV == maxvid.mV) {
  497. printk(KERN_INFO PFX "Claims to support voltage scaling but "
  498. "min & max are both %d.%03d. "
  499. "Voltage scaling disabled\n",
  500. maxvid.mV/1000, maxvid.mV%1000);
  501. return;
  502. }
  503. /* How many voltage steps*/
  504. numvscales = maxvid.pos - minvid.pos + 1;
  505. printk(KERN_INFO PFX
  506. "Max VID=%d.%03d "
  507. "Min VID=%d.%03d, "
  508. "%d possible voltage scales\n",
  509. maxvid.mV/1000, maxvid.mV%1000,
  510. minvid.mV/1000, minvid.mV%1000,
  511. numvscales);
  512. /* Calculate max frequency at min voltage */
  513. j = longhaul.bits.MinMHzBR;
  514. if (longhaul.bits.MinMHzBR4)
  515. j += 16;
  516. min_vid_speed = eblcr[j];
  517. if (min_vid_speed == -1)
  518. return;
  519. switch (longhaul.bits.MinMHzFSB) {
  520. case 0:
  521. min_vid_speed *= 13333;
  522. break;
  523. case 1:
  524. min_vid_speed *= 10000;
  525. break;
  526. case 3:
  527. min_vid_speed *= 6666;
  528. break;
  529. default:
  530. return;
  531. break;
  532. }
  533. if (min_vid_speed >= highest_speed)
  534. return;
  535. /* Calculate kHz for one voltage step */
  536. kHz_step = (highest_speed - min_vid_speed) / numvscales;
  537. j = 0;
  538. while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
  539. speed = longhaul_table[j].frequency;
  540. if (speed > min_vid_speed)
  541. pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
  542. else
  543. pos = minvid.pos;
  544. longhaul_table[j].index |= mV_vrm_table[pos] << 8;
  545. vid = vrm_mV_table[mV_vrm_table[pos]];
  546. printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
  547. speed, j, vid.mV);
  548. j++;
  549. }
  550. can_scale_voltage = 1;
  551. printk(KERN_INFO PFX "Voltage scaling enabled.\n");
  552. }
  553. static int longhaul_verify(struct cpufreq_policy *policy)
  554. {
  555. return cpufreq_frequency_table_verify(policy, longhaul_table);
  556. }
  557. static int longhaul_target(struct cpufreq_policy *policy,
  558. unsigned int target_freq, unsigned int relation)
  559. {
  560. unsigned int table_index = 0;
  561. unsigned int i;
  562. unsigned int dir = 0;
  563. u8 vid, current_vid;
  564. if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
  565. relation, &table_index))
  566. return -EINVAL;
  567. /* Don't set same frequency again */
  568. if (longhaul_index == table_index)
  569. return 0;
  570. if (!can_scale_voltage)
  571. longhaul_setstate(table_index);
  572. else {
  573. /* On test system voltage transitions exceeding single
  574. * step up or down were turning motherboard off. Both
  575. * "ondemand" and "userspace" are unsafe. C7 is doing
  576. * this in hardware, C3 is old and we need to do this
  577. * in software. */
  578. i = longhaul_index;
  579. current_vid = (longhaul_table[longhaul_index].index >> 8);
  580. current_vid &= 0x1f;
  581. if (table_index > longhaul_index)
  582. dir = 1;
  583. while (i != table_index) {
  584. vid = (longhaul_table[i].index >> 8) & 0x1f;
  585. if (vid != current_vid) {
  586. longhaul_setstate(i);
  587. current_vid = vid;
  588. msleep(200);
  589. }
  590. if (dir)
  591. i++;
  592. else
  593. i--;
  594. }
  595. longhaul_setstate(table_index);
  596. }
  597. longhaul_index = table_index;
  598. return 0;
  599. }
  600. static unsigned int longhaul_get(unsigned int cpu)
  601. {
  602. if (cpu)
  603. return 0;
  604. return calc_speed(longhaul_get_cpu_mult());
  605. }
  606. static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
  607. u32 nesting_level,
  608. void *context, void **return_value)
  609. {
  610. struct acpi_device *d;
  611. if (acpi_bus_get_device(obj_handle, &d))
  612. return 0;
  613. *return_value = acpi_driver_data(d);
  614. return 1;
  615. }
  616. /* VIA don't support PM2 reg, but have something similar */
  617. static int enable_arbiter_disable(void)
  618. {
  619. struct pci_dev *dev;
  620. int status = 1;
  621. int reg;
  622. u8 pci_cmd;
  623. /* Find PLE133 host bridge */
  624. reg = 0x78;
  625. dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
  626. NULL);
  627. /* Find PM133/VT8605 host bridge */
  628. if (dev == NULL)
  629. dev = pci_get_device(PCI_VENDOR_ID_VIA,
  630. PCI_DEVICE_ID_VIA_8605_0, NULL);
  631. /* Find CLE266 host bridge */
  632. if (dev == NULL) {
  633. reg = 0x76;
  634. dev = pci_get_device(PCI_VENDOR_ID_VIA,
  635. PCI_DEVICE_ID_VIA_862X_0, NULL);
  636. /* Find CN400 V-Link host bridge */
  637. if (dev == NULL)
  638. dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL);
  639. }
  640. if (dev != NULL) {
  641. /* Enable access to port 0x22 */
  642. pci_read_config_byte(dev, reg, &pci_cmd);
  643. if (!(pci_cmd & 1<<7)) {
  644. pci_cmd |= 1<<7;
  645. pci_write_config_byte(dev, reg, pci_cmd);
  646. pci_read_config_byte(dev, reg, &pci_cmd);
  647. if (!(pci_cmd & 1<<7)) {
  648. printk(KERN_ERR PFX
  649. "Can't enable access to port 0x22.\n");
  650. status = 0;
  651. }
  652. }
  653. pci_dev_put(dev);
  654. return status;
  655. }
  656. return 0;
  657. }
  658. static int longhaul_setup_southbridge(void)
  659. {
  660. struct pci_dev *dev;
  661. u8 pci_cmd;
  662. /* Find VT8235 southbridge */
  663. dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
  664. if (dev == NULL)
  665. /* Find VT8237 southbridge */
  666. dev = pci_get_device(PCI_VENDOR_ID_VIA,
  667. PCI_DEVICE_ID_VIA_8237, NULL);
  668. if (dev != NULL) {
  669. /* Set transition time to max */
  670. pci_read_config_byte(dev, 0xec, &pci_cmd);
  671. pci_cmd &= ~(1 << 2);
  672. pci_write_config_byte(dev, 0xec, pci_cmd);
  673. pci_read_config_byte(dev, 0xe4, &pci_cmd);
  674. pci_cmd &= ~(1 << 7);
  675. pci_write_config_byte(dev, 0xe4, pci_cmd);
  676. pci_read_config_byte(dev, 0xe5, &pci_cmd);
  677. pci_cmd |= 1 << 7;
  678. pci_write_config_byte(dev, 0xe5, pci_cmd);
  679. /* Get address of ACPI registers block*/
  680. pci_read_config_byte(dev, 0x81, &pci_cmd);
  681. if (pci_cmd & 1 << 7) {
  682. pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
  683. acpi_regs_addr &= 0xff00;
  684. printk(KERN_INFO PFX "ACPI I/O at 0x%x\n",
  685. acpi_regs_addr);
  686. }
  687. pci_dev_put(dev);
  688. return 1;
  689. }
  690. return 0;
  691. }
  692. static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy)
  693. {
  694. struct cpuinfo_x86 *c = &cpu_data(0);
  695. char *cpuname = NULL;
  696. int ret;
  697. u32 lo, hi;
  698. /* Check what we have on this motherboard */
  699. switch (c->x86_model) {
  700. case 6:
  701. cpu_model = CPU_SAMUEL;
  702. cpuname = "C3 'Samuel' [C5A]";
  703. longhaul_version = TYPE_LONGHAUL_V1;
  704. memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
  705. memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr));
  706. break;
  707. case 7:
  708. switch (c->x86_mask) {
  709. case 0:
  710. longhaul_version = TYPE_LONGHAUL_V1;
  711. cpu_model = CPU_SAMUEL2;
  712. cpuname = "C3 'Samuel 2' [C5B]";
  713. /* Note, this is not a typo, early Samuel2's had
  714. * Samuel1 ratios. */
  715. memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
  716. memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
  717. break;
  718. case 1 ... 15:
  719. longhaul_version = TYPE_LONGHAUL_V2;
  720. if (c->x86_mask < 8) {
  721. cpu_model = CPU_SAMUEL2;
  722. cpuname = "C3 'Samuel 2' [C5B]";
  723. } else {
  724. cpu_model = CPU_EZRA;
  725. cpuname = "C3 'Ezra' [C5C]";
  726. }
  727. memcpy(mults, ezra_mults, sizeof(ezra_mults));
  728. memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr));
  729. break;
  730. }
  731. break;
  732. case 8:
  733. cpu_model = CPU_EZRA_T;
  734. cpuname = "C3 'Ezra-T' [C5M]";
  735. longhaul_version = TYPE_POWERSAVER;
  736. numscales = 32;
  737. memcpy(mults, ezrat_mults, sizeof(ezrat_mults));
  738. memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr));
  739. break;
  740. case 9:
  741. longhaul_version = TYPE_POWERSAVER;
  742. numscales = 32;
  743. memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
  744. memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
  745. switch (c->x86_mask) {
  746. case 0 ... 1:
  747. cpu_model = CPU_NEHEMIAH;
  748. cpuname = "C3 'Nehemiah A' [C5XLOE]";
  749. break;
  750. case 2 ... 4:
  751. cpu_model = CPU_NEHEMIAH;
  752. cpuname = "C3 'Nehemiah B' [C5XLOH]";
  753. break;
  754. case 5 ... 15:
  755. cpu_model = CPU_NEHEMIAH_C;
  756. cpuname = "C3 'Nehemiah C' [C5P]";
  757. break;
  758. }
  759. break;
  760. default:
  761. cpuname = "Unknown";
  762. break;
  763. }
  764. /* Check Longhaul ver. 2 */
  765. if (longhaul_version == TYPE_LONGHAUL_V2) {
  766. rdmsr(MSR_VIA_LONGHAUL, lo, hi);
  767. if (lo == 0 && hi == 0)
  768. /* Looks like MSR isn't present */
  769. longhaul_version = TYPE_LONGHAUL_V1;
  770. }
  771. printk(KERN_INFO PFX "VIA %s CPU detected. ", cpuname);
  772. switch (longhaul_version) {
  773. case TYPE_LONGHAUL_V1:
  774. case TYPE_LONGHAUL_V2:
  775. printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version);
  776. break;
  777. case TYPE_POWERSAVER:
  778. printk(KERN_CONT "Powersaver supported.\n");
  779. break;
  780. };
  781. /* Doesn't hurt */
  782. longhaul_setup_southbridge();
  783. /* Find ACPI data for processor */
  784. acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
  785. ACPI_UINT32_MAX, &longhaul_walk_callback, NULL,
  786. NULL, (void *)&pr);
  787. /* Check ACPI support for C3 state */
  788. if (pr != NULL && longhaul_version == TYPE_POWERSAVER) {
  789. cx = &pr->power.states[ACPI_STATE_C3];
  790. if (cx->address > 0 && cx->latency <= 1000)
  791. longhaul_flags |= USE_ACPI_C3;
  792. }
  793. /* Disable if it isn't working */
  794. if (disable_acpi_c3)
  795. longhaul_flags &= ~USE_ACPI_C3;
  796. /* Check if northbridge is friendly */
  797. if (enable_arbiter_disable())
  798. longhaul_flags |= USE_NORTHBRIDGE;
  799. /* Check ACPI support for bus master arbiter disable */
  800. if (!(longhaul_flags & USE_ACPI_C3
  801. || longhaul_flags & USE_NORTHBRIDGE)
  802. && ((pr == NULL) || !(pr->flags.bm_control))) {
  803. printk(KERN_ERR PFX
  804. "No ACPI support. Unsupported northbridge.\n");
  805. return -ENODEV;
  806. }
  807. if (longhaul_flags & USE_NORTHBRIDGE)
  808. printk(KERN_INFO PFX "Using northbridge support.\n");
  809. if (longhaul_flags & USE_ACPI_C3)
  810. printk(KERN_INFO PFX "Using ACPI support.\n");
  811. ret = longhaul_get_ranges();
  812. if (ret != 0)
  813. return ret;
  814. if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0))
  815. longhaul_setup_voltagescaling();
  816. policy->cpuinfo.transition_latency = 200000; /* nsec */
  817. policy->cur = calc_speed(longhaul_get_cpu_mult());
  818. ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
  819. if (ret)
  820. return ret;
  821. cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu);
  822. return 0;
  823. }
  824. static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy)
  825. {
  826. cpufreq_frequency_table_put_attr(policy->cpu);
  827. return 0;
  828. }
  829. static struct freq_attr *longhaul_attr[] = {
  830. &cpufreq_freq_attr_scaling_available_freqs,
  831. NULL,
  832. };
  833. static struct cpufreq_driver longhaul_driver = {
  834. .verify = longhaul_verify,
  835. .target = longhaul_target,
  836. .get = longhaul_get,
  837. .init = longhaul_cpu_init,
  838. .exit = __devexit_p(longhaul_cpu_exit),
  839. .name = "longhaul",
  840. .owner = THIS_MODULE,
  841. .attr = longhaul_attr,
  842. };
  843. static int __init longhaul_init(void)
  844. {
  845. struct cpuinfo_x86 *c = &cpu_data(0);
  846. if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
  847. return -ENODEV;
  848. #ifdef CONFIG_SMP
  849. if (num_online_cpus() > 1) {
  850. printk(KERN_ERR PFX "More than 1 CPU detected, "
  851. "longhaul disabled.\n");
  852. return -ENODEV;
  853. }
  854. #endif
  855. #ifdef CONFIG_X86_IO_APIC
  856. if (cpu_has_apic) {
  857. printk(KERN_ERR PFX "APIC detected. Longhaul is currently "
  858. "broken in this configuration.\n");
  859. return -ENODEV;
  860. }
  861. #endif
  862. switch (c->x86_model) {
  863. case 6 ... 9:
  864. return cpufreq_register_driver(&longhaul_driver);
  865. case 10:
  866. printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n");
  867. default:
  868. ;
  869. }
  870. return -ENODEV;
  871. }
  872. static void __exit longhaul_exit(void)
  873. {
  874. int i;
  875. for (i = 0; i < numscales; i++) {
  876. if (mults[i] == maxmult) {
  877. longhaul_setstate(i);
  878. break;
  879. }
  880. }
  881. cpufreq_unregister_driver(&longhaul_driver);
  882. kfree(longhaul_table);
  883. }
  884. /* Even if BIOS is exporting ACPI C3 state, and it is used
  885. * with success when CPU is idle, this state doesn't
  886. * trigger frequency transition in some cases. */
  887. module_param(disable_acpi_c3, int, 0644);
  888. MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
  889. /* Change CPU voltage with frequency. Very useful to save
  890. * power, but most VIA C3 processors aren't supporting it. */
  891. module_param(scale_voltage, int, 0644);
  892. MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
  893. /* Force revision key to 0 for processors which doesn't
  894. * support voltage scaling, but are introducing itself as
  895. * such. */
  896. module_param(revid_errata, int, 0644);
  897. MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
  898. MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
  899. MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
  900. MODULE_LICENSE("GPL");
  901. late_initcall(longhaul_init);
  902. module_exit(longhaul_exit);