pmac_feature.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /*
  2. * arch/ppc/platforms/pmac_feature.c
  3. *
  4. * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
  5. * Ben. Herrenschmidt (benh@kernel.crashing.org)
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version
  10. * 2 of the License, or (at your option) any later version.
  11. *
  12. * TODO:
  13. *
  14. * - Replace mdelay with some schedule loop if possible
  15. * - Shorten some obfuscated delays on some routines (like modem
  16. * power)
  17. * - Refcount some clocks (see darwin)
  18. * - Split split split...
  19. *
  20. */
  21. #include <linux/config.h>
  22. #include <linux/types.h>
  23. #include <linux/init.h>
  24. #include <linux/delay.h>
  25. #include <linux/kernel.h>
  26. #include <linux/sched.h>
  27. #include <linux/spinlock.h>
  28. #include <linux/adb.h>
  29. #include <linux/pmu.h>
  30. #include <linux/ioport.h>
  31. #include <linux/pci.h>
  32. #include <asm/sections.h>
  33. #include <asm/errno.h>
  34. #include <asm/keylargo.h>
  35. #include <asm/uninorth.h>
  36. #include <asm/io.h>
  37. #include <asm/prom.h>
  38. #include <asm/machdep.h>
  39. #include <asm/pmac_feature.h>
  40. #include <asm/dbdma.h>
  41. #include <asm/pci-bridge.h>
  42. #include <asm/pmac_low_i2c.h>
  43. #undef DEBUG_FEATURE
  44. #ifdef DEBUG_FEATURE
  45. #define DBG(fmt...) printk(KERN_DEBUG fmt)
  46. #else
  47. #define DBG(fmt...)
  48. #endif
  49. /*
  50. * We use a single global lock to protect accesses. Each driver has
  51. * to take care of its own locking
  52. */
  53. static DEFINE_SPINLOCK(feature_lock __pmacdata);
  54. #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
  55. #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
  56. /*
  57. * Instance of some macio stuffs
  58. */
  59. struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata;
  60. struct macio_chip* __pmac macio_find(struct device_node* child, int type)
  61. {
  62. while(child) {
  63. int i;
  64. for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
  65. if (child == macio_chips[i].of_node &&
  66. (!type || macio_chips[i].type == type))
  67. return &macio_chips[i];
  68. child = child->parent;
  69. }
  70. return NULL;
  71. }
  72. EXPORT_SYMBOL_GPL(macio_find);
  73. static const char* macio_names[] __pmacdata =
  74. {
  75. "Unknown",
  76. "Grand Central",
  77. "OHare",
  78. "OHareII",
  79. "Heathrow",
  80. "Gatwick",
  81. "Paddington",
  82. "Keylargo",
  83. "Pangea",
  84. "Intrepid",
  85. "K2"
  86. };
  87. /*
  88. * Uninorth reg. access. Note that Uni-N regs are big endian
  89. */
  90. #define UN_REG(r) (uninorth_base + ((r) >> 2))
  91. #define UN_IN(r) (in_be32(UN_REG(r)))
  92. #define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
  93. #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
  94. #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
  95. static struct device_node* uninorth_node __pmacdata;
  96. static u32* uninorth_base __pmacdata;
  97. static u32 uninorth_rev __pmacdata;
  98. static void *u3_ht;
  99. extern struct device_node *k2_skiplist[2];
  100. /*
  101. * For each motherboard family, we have a table of functions pointers
  102. * that handle the various features.
  103. */
  104. typedef long (*feature_call)(struct device_node* node, long param, long value);
  105. struct feature_table_entry {
  106. unsigned int selector;
  107. feature_call function;
  108. };
  109. struct pmac_mb_def
  110. {
  111. const char* model_string;
  112. const char* model_name;
  113. int model_id;
  114. struct feature_table_entry* features;
  115. unsigned long board_flags;
  116. };
  117. static struct pmac_mb_def pmac_mb __pmacdata;
  118. /*
  119. * Here are the chip specific feature functions
  120. */
  121. static long __pmac g5_read_gpio(struct device_node* node, long param, long value)
  122. {
  123. struct macio_chip* macio = &macio_chips[0];
  124. return MACIO_IN8(param);
  125. }
  126. static long __pmac g5_write_gpio(struct device_node* node, long param, long value)
  127. {
  128. struct macio_chip* macio = &macio_chips[0];
  129. MACIO_OUT8(param, (u8)(value & 0xff));
  130. return 0;
  131. }
  132. static long __pmac g5_gmac_enable(struct device_node* node, long param, long value)
  133. {
  134. struct macio_chip* macio = &macio_chips[0];
  135. unsigned long flags;
  136. if (node == NULL)
  137. return -ENODEV;
  138. LOCK(flags);
  139. if (value) {
  140. MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
  141. mb();
  142. k2_skiplist[0] = NULL;
  143. } else {
  144. k2_skiplist[0] = node;
  145. mb();
  146. MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
  147. }
  148. UNLOCK(flags);
  149. mdelay(1);
  150. return 0;
  151. }
  152. static long __pmac g5_fw_enable(struct device_node* node, long param, long value)
  153. {
  154. struct macio_chip* macio = &macio_chips[0];
  155. unsigned long flags;
  156. if (node == NULL)
  157. return -ENODEV;
  158. LOCK(flags);
  159. if (value) {
  160. MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
  161. mb();
  162. k2_skiplist[1] = NULL;
  163. } else {
  164. k2_skiplist[1] = node;
  165. mb();
  166. MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
  167. }
  168. UNLOCK(flags);
  169. mdelay(1);
  170. return 0;
  171. }
  172. static long __pmac g5_mpic_enable(struct device_node* node, long param, long value)
  173. {
  174. unsigned long flags;
  175. if (node->parent == NULL || strcmp(node->parent->name, "u3"))
  176. return 0;
  177. LOCK(flags);
  178. UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
  179. UNLOCK(flags);
  180. return 0;
  181. }
  182. static long __pmac g5_eth_phy_reset(struct device_node* node, long param, long value)
  183. {
  184. struct macio_chip* macio = &macio_chips[0];
  185. struct device_node *phy;
  186. int need_reset;
  187. /*
  188. * We must not reset the combo PHYs, only the BCM5221 found in
  189. * the iMac G5.
  190. */
  191. phy = of_get_next_child(node, NULL);
  192. if (!phy)
  193. return -ENODEV;
  194. need_reset = device_is_compatible(phy, "B5221");
  195. of_node_put(phy);
  196. if (!need_reset)
  197. return 0;
  198. /* PHY reset is GPIO 29, not in device-tree unfortunately */
  199. MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
  200. KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
  201. /* Thankfully, this is now always called at a time when we can
  202. * schedule by sungem.
  203. */
  204. msleep(10);
  205. MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
  206. return 0;
  207. }
  208. static long __pmac g5_i2s_enable(struct device_node *node, long param, long value)
  209. {
  210. /* Very crude implementation for now */
  211. struct macio_chip* macio = &macio_chips[0];
  212. unsigned long flags;
  213. if (value == 0)
  214. return 0; /* don't disable yet */
  215. LOCK(flags);
  216. MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
  217. KL3_I2S0_CLK18_ENABLE);
  218. udelay(10);
  219. MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
  220. K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
  221. udelay(10);
  222. MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
  223. UNLOCK(flags);
  224. udelay(10);
  225. return 0;
  226. }
  227. #ifdef CONFIG_SMP
  228. static long __pmac g5_reset_cpu(struct device_node* node, long param, long value)
  229. {
  230. unsigned int reset_io = 0;
  231. unsigned long flags;
  232. struct macio_chip* macio;
  233. struct device_node* np;
  234. macio = &macio_chips[0];
  235. if (macio->type != macio_keylargo2)
  236. return -ENODEV;
  237. np = find_path_device("/cpus");
  238. if (np == NULL)
  239. return -ENODEV;
  240. for (np = np->child; np != NULL; np = np->sibling) {
  241. u32* num = (u32 *)get_property(np, "reg", NULL);
  242. u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
  243. if (num == NULL || rst == NULL)
  244. continue;
  245. if (param == *num) {
  246. reset_io = *rst;
  247. break;
  248. }
  249. }
  250. if (np == NULL || reset_io == 0)
  251. return -ENODEV;
  252. LOCK(flags);
  253. MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
  254. (void)MACIO_IN8(reset_io);
  255. udelay(1);
  256. MACIO_OUT8(reset_io, 0);
  257. (void)MACIO_IN8(reset_io);
  258. UNLOCK(flags);
  259. return 0;
  260. }
  261. #endif /* CONFIG_SMP */
  262. /*
  263. * This can be called from pmac_smp so isn't static
  264. *
  265. * This takes the second CPU off the bus on dual CPU machines
  266. * running UP
  267. */
  268. void __pmac g5_phy_disable_cpu1(void)
  269. {
  270. UN_OUT(U3_API_PHY_CONFIG_1, 0);
  271. }
  272. static long __pmac generic_get_mb_info(struct device_node* node, long param, long value)
  273. {
  274. switch(param) {
  275. case PMAC_MB_INFO_MODEL:
  276. return pmac_mb.model_id;
  277. case PMAC_MB_INFO_FLAGS:
  278. return pmac_mb.board_flags;
  279. case PMAC_MB_INFO_NAME:
  280. /* hack hack hack... but should work */
  281. *((const char **)value) = pmac_mb.model_name;
  282. return 0;
  283. }
  284. return -EINVAL;
  285. }
  286. /*
  287. * Table definitions
  288. */
  289. /* Used on any machine
  290. */
  291. static struct feature_table_entry any_features[] __pmacdata = {
  292. { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
  293. { 0, NULL }
  294. };
  295. /* G5 features
  296. */
  297. static struct feature_table_entry g5_features[] __pmacdata = {
  298. { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
  299. { PMAC_FTR_1394_ENABLE, g5_fw_enable },
  300. { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
  301. { PMAC_FTR_READ_GPIO, g5_read_gpio },
  302. { PMAC_FTR_WRITE_GPIO, g5_write_gpio },
  303. { PMAC_FTR_GMAC_PHY_RESET, g5_eth_phy_reset },
  304. { PMAC_FTR_SOUND_CHIP_ENABLE, g5_i2s_enable },
  305. #ifdef CONFIG_SMP
  306. { PMAC_FTR_RESET_CPU, g5_reset_cpu },
  307. #endif /* CONFIG_SMP */
  308. { 0, NULL }
  309. };
  310. static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
  311. { "PowerMac7,2", "PowerMac G5",
  312. PMAC_TYPE_POWERMAC_G5, g5_features,
  313. 0,
  314. },
  315. { "PowerMac7,3", "PowerMac G5",
  316. PMAC_TYPE_POWERMAC_G5, g5_features,
  317. 0,
  318. },
  319. { "PowerMac8,1", "iMac G5",
  320. PMAC_TYPE_IMAC_G5, g5_features,
  321. 0,
  322. },
  323. { "PowerMac9,1", "PowerMac G5",
  324. PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
  325. 0,
  326. },
  327. { "RackMac3,1", "XServe G5",
  328. PMAC_TYPE_XSERVE_G5, g5_features,
  329. 0,
  330. },
  331. };
  332. /*
  333. * The toplevel feature_call callback
  334. */
  335. long __pmac pmac_do_feature_call(unsigned int selector, ...)
  336. {
  337. struct device_node* node;
  338. long param, value;
  339. int i;
  340. feature_call func = NULL;
  341. va_list args;
  342. if (pmac_mb.features)
  343. for (i=0; pmac_mb.features[i].function; i++)
  344. if (pmac_mb.features[i].selector == selector) {
  345. func = pmac_mb.features[i].function;
  346. break;
  347. }
  348. if (!func)
  349. for (i=0; any_features[i].function; i++)
  350. if (any_features[i].selector == selector) {
  351. func = any_features[i].function;
  352. break;
  353. }
  354. if (!func)
  355. return -ENODEV;
  356. va_start(args, selector);
  357. node = (struct device_node*)va_arg(args, void*);
  358. param = va_arg(args, long);
  359. value = va_arg(args, long);
  360. va_end(args);
  361. return func(node, param, value);
  362. }
  363. static int __init probe_motherboard(void)
  364. {
  365. int i;
  366. struct macio_chip* macio = &macio_chips[0];
  367. const char* model = NULL;
  368. struct device_node *dt;
  369. /* Lookup known motherboard type in device-tree. First try an
  370. * exact match on the "model" property, then try a "compatible"
  371. * match is none is found.
  372. */
  373. dt = find_devices("device-tree");
  374. if (dt != NULL)
  375. model = (const char *) get_property(dt, "model", NULL);
  376. for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
  377. if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
  378. pmac_mb = pmac_mb_defs[i];
  379. goto found;
  380. }
  381. }
  382. for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
  383. if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
  384. pmac_mb = pmac_mb_defs[i];
  385. goto found;
  386. }
  387. }
  388. /* Fallback to selection depending on mac-io chip type */
  389. switch(macio->type) {
  390. case macio_keylargo2:
  391. pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
  392. pmac_mb.model_name = "Unknown K2-based";
  393. pmac_mb.features = g5_features;
  394. default:
  395. return -ENODEV;
  396. }
  397. found:
  398. /* Check for "mobile" machine */
  399. if (model && (strncmp(model, "PowerBook", 9) == 0
  400. || strncmp(model, "iBook", 5) == 0))
  401. pmac_mb.board_flags |= PMAC_MB_MOBILE;
  402. printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
  403. return 0;
  404. }
  405. /* Initialize the Core99 UniNorth host bridge and memory controller
  406. */
  407. static void __init probe_uninorth(void)
  408. {
  409. uninorth_node = of_find_node_by_name(NULL, "u3");
  410. if (uninorth_node && uninorth_node->n_addrs > 0) {
  411. /* Small hack until I figure out if parsing in prom.c is correct. I should
  412. * get rid of those pre-parsed junk anyway
  413. */
  414. unsigned long address = uninorth_node->addrs[0].address;
  415. uninorth_base = ioremap(address, 0x40000);
  416. uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
  417. u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
  418. } else
  419. uninorth_node = NULL;
  420. if (!uninorth_node)
  421. return;
  422. printk(KERN_INFO "Found U3 memory controller & host bridge, revision: %d\n",
  423. uninorth_rev);
  424. printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
  425. }
  426. static void __init probe_one_macio(const char* name, const char* compat, int type)
  427. {
  428. struct device_node* node;
  429. int i;
  430. volatile u32* base;
  431. u32* revp;
  432. node = find_devices(name);
  433. if (!node || !node->n_addrs)
  434. return;
  435. if (compat)
  436. do {
  437. if (device_is_compatible(node, compat))
  438. break;
  439. node = node->next;
  440. } while (node);
  441. if (!node)
  442. return;
  443. for(i=0; i<MAX_MACIO_CHIPS; i++) {
  444. if (!macio_chips[i].of_node)
  445. break;
  446. if (macio_chips[i].of_node == node)
  447. return;
  448. }
  449. if (i >= MAX_MACIO_CHIPS) {
  450. printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
  451. printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
  452. return;
  453. }
  454. base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size);
  455. if (!base) {
  456. printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
  457. return;
  458. }
  459. if (type == macio_keylargo) {
  460. u32* did = (u32 *)get_property(node, "device-id", NULL);
  461. if (*did == 0x00000025)
  462. type = macio_pangea;
  463. if (*did == 0x0000003e)
  464. type = macio_intrepid;
  465. }
  466. macio_chips[i].of_node = node;
  467. macio_chips[i].type = type;
  468. macio_chips[i].base = base;
  469. macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
  470. macio_chips[i].name = macio_names[type];
  471. revp = (u32 *)get_property(node, "revision-id", NULL);
  472. if (revp)
  473. macio_chips[i].rev = *revp;
  474. printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
  475. macio_names[type], macio_chips[i].rev, macio_chips[i].base);
  476. }
  477. static int __init
  478. probe_macios(void)
  479. {
  480. probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
  481. macio_chips[0].lbus.index = 0;
  482. macio_chips[1].lbus.index = 1;
  483. return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
  484. }
  485. static void __init
  486. set_initial_features(void)
  487. {
  488. struct device_node *np;
  489. if (macio_chips[0].type == macio_keylargo2) {
  490. #ifndef CONFIG_SMP
  491. /* On SMP machines running UP, we have the second CPU eating
  492. * bus cycles. We need to take it off the bus. This is done
  493. * from pmac_smp for SMP kernels running on one CPU
  494. */
  495. np = of_find_node_by_type(NULL, "cpu");
  496. if (np != NULL)
  497. np = of_find_node_by_type(np, "cpu");
  498. if (np != NULL) {
  499. g5_phy_disable_cpu1();
  500. of_node_put(np);
  501. }
  502. #endif /* CONFIG_SMP */
  503. /* Enable GMAC for now for PCI probing. It will be disabled
  504. * later on after PCI probe
  505. */
  506. np = of_find_node_by_name(NULL, "ethernet");
  507. while(np) {
  508. if (device_is_compatible(np, "K2-GMAC"))
  509. g5_gmac_enable(np, 0, 1);
  510. np = of_find_node_by_name(np, "ethernet");
  511. }
  512. /* Enable FW before PCI probe. Will be disabled later on
  513. * Note: We should have a batter way to check that we are
  514. * dealing with uninorth internal cell and not a PCI cell
  515. * on the external PCI. The code below works though.
  516. */
  517. np = of_find_node_by_name(NULL, "firewire");
  518. while(np) {
  519. if (device_is_compatible(np, "pci106b,5811")) {
  520. macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
  521. g5_fw_enable(np, 0, 1);
  522. }
  523. np = of_find_node_by_name(np, "firewire");
  524. }
  525. }
  526. }
  527. void __init
  528. pmac_feature_init(void)
  529. {
  530. /* Detect the UniNorth memory controller */
  531. probe_uninorth();
  532. /* Probe mac-io controllers */
  533. if (probe_macios()) {
  534. printk(KERN_WARNING "No mac-io chip found\n");
  535. return;
  536. }
  537. /* Setup low-level i2c stuffs */
  538. pmac_init_low_i2c();
  539. /* Probe machine type */
  540. if (probe_motherboard())
  541. printk(KERN_WARNING "Unknown PowerMac !\n");
  542. /* Set some initial features (turn off some chips that will
  543. * be later turned on)
  544. */
  545. set_initial_features();
  546. }
  547. int __init pmac_feature_late_init(void)
  548. {
  549. #if 0
  550. struct device_node* np;
  551. /* Request some resources late */
  552. if (uninorth_node)
  553. request_OF_resource(uninorth_node, 0, NULL);
  554. np = find_devices("hammerhead");
  555. if (np)
  556. request_OF_resource(np, 0, NULL);
  557. np = find_devices("interrupt-controller");
  558. if (np)
  559. request_OF_resource(np, 0, NULL);
  560. #endif
  561. return 0;
  562. }
  563. device_initcall(pmac_feature_late_init);
  564. #if 0
  565. static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
  566. {
  567. int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
  568. int bits[8] = { 8,16,0,32,2,4,0,0 };
  569. int freq = (frq >> 8) & 0xf;
  570. if (freqs[freq] == 0)
  571. printk("%s: Unknown HT link frequency %x\n", name, freq);
  572. else
  573. printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
  574. name, freqs[freq],
  575. bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
  576. }
  577. #endif
  578. void __init pmac_check_ht_link(void)
  579. {
  580. #if 0 /* Disabled for now */
  581. u32 ufreq, freq, ucfg, cfg;
  582. struct device_node *pcix_node;
  583. u8 px_bus, px_devfn;
  584. struct pci_controller *px_hose;
  585. (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
  586. ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
  587. ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
  588. dump_HT_speeds("U3 HyperTransport", cfg, freq);
  589. pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
  590. if (pcix_node == NULL) {
  591. printk("No PCI-X bridge found\n");
  592. return;
  593. }
  594. px_hose = pcix_node->phb;
  595. px_bus = pcix_node->busno;
  596. px_devfn = pcix_node->devfn;
  597. early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
  598. early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
  599. dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
  600. early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
  601. early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
  602. dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
  603. #endif
  604. }
  605. /*
  606. * Early video resume hook
  607. */
  608. static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
  609. static void *pmac_early_vresume_data __pmacdata;
  610. void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
  611. {
  612. if (_machine != _MACH_Pmac)
  613. return;
  614. preempt_disable();
  615. pmac_early_vresume_proc = proc;
  616. pmac_early_vresume_data = data;
  617. preempt_enable();
  618. }
  619. EXPORT_SYMBOL(pmac_set_early_video_resume);
  620. /*
  621. * AGP related suspend/resume code
  622. */
  623. static struct pci_dev *pmac_agp_bridge __pmacdata;
  624. static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
  625. static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
  626. void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
  627. int (*suspend)(struct pci_dev *bridge),
  628. int (*resume)(struct pci_dev *bridge))
  629. {
  630. if (suspend || resume) {
  631. pmac_agp_bridge = bridge;
  632. pmac_agp_suspend = suspend;
  633. pmac_agp_resume = resume;
  634. return;
  635. }
  636. if (bridge != pmac_agp_bridge)
  637. return;
  638. pmac_agp_suspend = pmac_agp_resume = NULL;
  639. return;
  640. }
  641. EXPORT_SYMBOL(pmac_register_agp_pm);
  642. void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
  643. {
  644. if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
  645. return;
  646. if (pmac_agp_bridge->bus != dev->bus)
  647. return;
  648. pmac_agp_suspend(pmac_agp_bridge);
  649. }
  650. EXPORT_SYMBOL(pmac_suspend_agp_for_card);
  651. void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
  652. {
  653. if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
  654. return;
  655. if (pmac_agp_bridge->bus != dev->bus)
  656. return;
  657. pmac_agp_resume(pmac_agp_bridge);
  658. }
  659. EXPORT_SYMBOL(pmac_resume_agp_for_card);