/drivers/char/agp/uninorth-agp.c

https://bitbucket.org/evzijst/gittest · C · 647 lines · 491 code · 97 blank · 59 comment · 76 complexity · 54b5fe835cc4f7da7010ddbcb05a8df1 MD5 · raw file

  1. /*
  2. * UniNorth AGPGART routines.
  3. */
  4. #include <linux/module.h>
  5. #include <linux/pci.h>
  6. #include <linux/init.h>
  7. #include <linux/pagemap.h>
  8. #include <linux/agp_backend.h>
  9. #include <linux/delay.h>
  10. #include <asm/uninorth.h>
  11. #include <asm/pci-bridge.h>
  12. #include <asm/prom.h>
  13. #include "agp.h"
  14. /*
  15. * NOTES for uninorth3 (G5 AGP) supports :
  16. *
  17. * There maybe also possibility to have bigger cache line size for
  18. * agp (see pmac_pci.c and look for cache line). Need to be investigated
  19. * by someone.
  20. *
  21. * PAGE size are hardcoded but this may change, see asm/page.h.
  22. *
  23. * Jerome Glisse <j.glisse@gmail.com>
  24. */
  25. static int uninorth_rev;
  26. static int is_u3;
  27. static int uninorth_fetch_size(void)
  28. {
  29. int i;
  30. u32 temp;
  31. struct aper_size_info_32 *values;
  32. pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
  33. temp &= ~(0xfffff000);
  34. values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
  35. for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
  36. if (temp == values[i].size_value) {
  37. agp_bridge->previous_size =
  38. agp_bridge->current_size = (void *) (values + i);
  39. agp_bridge->aperture_size_idx = i;
  40. return values[i].size;
  41. }
  42. }
  43. agp_bridge->previous_size =
  44. agp_bridge->current_size = (void *) (values + 1);
  45. agp_bridge->aperture_size_idx = 1;
  46. return values[1].size;
  47. return 0;
  48. }
  49. static void uninorth_tlbflush(struct agp_memory *mem)
  50. {
  51. u32 ctrl = UNI_N_CFG_GART_ENABLE;
  52. if (is_u3)
  53. ctrl |= U3_N_CFG_GART_PERFRD;
  54. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  55. ctrl | UNI_N_CFG_GART_INVAL);
  56. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, ctrl);
  57. if (uninorth_rev <= 0x30) {
  58. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  59. ctrl | UNI_N_CFG_GART_2xRESET);
  60. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  61. ctrl);
  62. }
  63. }
  64. static void uninorth_cleanup(void)
  65. {
  66. u32 tmp;
  67. pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, &tmp);
  68. if (!(tmp & UNI_N_CFG_GART_ENABLE))
  69. return;
  70. tmp |= UNI_N_CFG_GART_INVAL;
  71. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, tmp);
  72. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, 0);
  73. if (uninorth_rev <= 0x30) {
  74. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  75. UNI_N_CFG_GART_2xRESET);
  76. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  77. 0);
  78. }
  79. }
  80. static int uninorth_configure(void)
  81. {
  82. struct aper_size_info_32 *current_size;
  83. current_size = A_SIZE_32(agp_bridge->current_size);
  84. printk(KERN_INFO PFX "configuring for size idx: %d\n",
  85. current_size->size_value);
  86. /* aperture size and gatt addr */
  87. pci_write_config_dword(agp_bridge->dev,
  88. UNI_N_CFG_GART_BASE,
  89. (agp_bridge->gatt_bus_addr & 0xfffff000)
  90. | current_size->size_value);
  91. /* HACK ALERT
  92. * UniNorth seem to be buggy enough not to handle properly when
  93. * the AGP aperture isn't mapped at bus physical address 0
  94. */
  95. agp_bridge->gart_bus_addr = 0;
  96. #ifdef CONFIG_PPC64
  97. /* Assume U3 or later on PPC64 systems */
  98. /* high 4 bits of GART physical address go in UNI_N_CFG_AGP_BASE */
  99. pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_AGP_BASE,
  100. (agp_bridge->gatt_bus_addr >> 32) & 0xf);
  101. #else
  102. pci_write_config_dword(agp_bridge->dev,
  103. UNI_N_CFG_AGP_BASE, agp_bridge->gart_bus_addr);
  104. #endif
  105. if (is_u3) {
  106. pci_write_config_dword(agp_bridge->dev,
  107. UNI_N_CFG_GART_DUMMY_PAGE,
  108. agp_bridge->scratch_page_real >> 12);
  109. }
  110. return 0;
  111. }
  112. static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start,
  113. int type)
  114. {
  115. int i, j, num_entries;
  116. void *temp;
  117. temp = agp_bridge->current_size;
  118. num_entries = A_SIZE_32(temp)->num_entries;
  119. if (type != 0 || mem->type != 0)
  120. /* We know nothing of memory types */
  121. return -EINVAL;
  122. if ((pg_start + mem->page_count) > num_entries)
  123. return -EINVAL;
  124. j = pg_start;
  125. while (j < (pg_start + mem->page_count)) {
  126. if (agp_bridge->gatt_table[j])
  127. return -EBUSY;
  128. j++;
  129. }
  130. for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
  131. agp_bridge->gatt_table[j] =
  132. cpu_to_le32((mem->memory[i] & 0xFFFFF000UL) | 0x1UL);
  133. flush_dcache_range((unsigned long)__va(mem->memory[i]),
  134. (unsigned long)__va(mem->memory[i])+0x1000);
  135. }
  136. (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
  137. mb();
  138. flush_dcache_range((unsigned long)&agp_bridge->gatt_table[pg_start],
  139. (unsigned long)&agp_bridge->gatt_table[pg_start + mem->page_count]);
  140. uninorth_tlbflush(mem);
  141. return 0;
  142. }
  143. static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
  144. {
  145. int i, num_entries;
  146. void *temp;
  147. u32 *gp;
  148. temp = agp_bridge->current_size;
  149. num_entries = A_SIZE_32(temp)->num_entries;
  150. if (type != 0 || mem->type != 0)
  151. /* We know nothing of memory types */
  152. return -EINVAL;
  153. if ((pg_start + mem->page_count) > num_entries)
  154. return -EINVAL;
  155. gp = (u32 *) &agp_bridge->gatt_table[pg_start];
  156. for (i = 0; i < mem->page_count; ++i) {
  157. if (gp[i]) {
  158. printk("u3_insert_memory: entry 0x%x occupied (%x)\n",
  159. i, gp[i]);
  160. return -EBUSY;
  161. }
  162. }
  163. for (i = 0; i < mem->page_count; i++) {
  164. gp[i] = (mem->memory[i] >> PAGE_SHIFT) | 0x80000000UL;
  165. flush_dcache_range((unsigned long)__va(mem->memory[i]),
  166. (unsigned long)__va(mem->memory[i])+0x1000);
  167. }
  168. mb();
  169. flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]);
  170. uninorth_tlbflush(mem);
  171. return 0;
  172. }
  173. int u3_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
  174. {
  175. size_t i;
  176. u32 *gp;
  177. if (type != 0 || mem->type != 0)
  178. /* We know nothing of memory types */
  179. return -EINVAL;
  180. gp = (u32 *) &agp_bridge->gatt_table[pg_start];
  181. for (i = 0; i < mem->page_count; ++i)
  182. gp[i] = 0;
  183. mb();
  184. flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]);
  185. uninorth_tlbflush(mem);
  186. return 0;
  187. }
  188. static void uninorth_agp_enable(struct agp_bridge_data *bridge, u32 mode)
  189. {
  190. u32 command, scratch, status;
  191. int timeout;
  192. pci_read_config_dword(bridge->dev,
  193. bridge->capndx + PCI_AGP_STATUS,
  194. &status);
  195. command = agp_collect_device_status(bridge, mode, status);
  196. command |= PCI_AGP_COMMAND_AGP;
  197. if (uninorth_rev == 0x21) {
  198. /*
  199. * Darwin disable AGP 4x on this revision, thus we
  200. * may assume it's broken. This is an AGP2 controller.
  201. */
  202. command &= ~AGPSTAT2_4X;
  203. }
  204. if ((uninorth_rev >= 0x30) && (uninorth_rev <= 0x33)) {
  205. /*
  206. * We need to to set REQ_DEPTH to 7 for U3 versions 1.0, 2.1,
  207. * 2.2 and 2.3, Darwin do so.
  208. */
  209. if ((command >> AGPSTAT_RQ_DEPTH_SHIFT) > 7)
  210. command = (command & ~AGPSTAT_RQ_DEPTH)
  211. | (7 << AGPSTAT_RQ_DEPTH_SHIFT);
  212. }
  213. uninorth_tlbflush(NULL);
  214. timeout = 0;
  215. do {
  216. pci_write_config_dword(bridge->dev,
  217. bridge->capndx + PCI_AGP_COMMAND,
  218. command);
  219. pci_read_config_dword(bridge->dev,
  220. bridge->capndx + PCI_AGP_COMMAND,
  221. &scratch);
  222. } while ((scratch & PCI_AGP_COMMAND_AGP) == 0 && ++timeout < 1000);
  223. if ((scratch & PCI_AGP_COMMAND_AGP) == 0)
  224. printk(KERN_ERR PFX "failed to write UniNorth AGP command reg\n");
  225. if (uninorth_rev >= 0x30) {
  226. /* This is an AGP V3 */
  227. agp_device_command(command, (status & AGPSTAT_MODE_3_0));
  228. } else {
  229. /* AGP V2 */
  230. agp_device_command(command, 0);
  231. }
  232. uninorth_tlbflush(NULL);
  233. }
  234. #ifdef CONFIG_PM
  235. static int agp_uninorth_suspend(struct pci_dev *pdev, pm_message_t state)
  236. {
  237. u32 cmd;
  238. u8 agp;
  239. struct pci_dev *device = NULL;
  240. if (state != PMSG_SUSPEND)
  241. return 0;
  242. /* turn off AGP on the video chip, if it was enabled */
  243. for_each_pci_dev(device) {
  244. /* Don't touch the bridge yet, device first */
  245. if (device == pdev)
  246. continue;
  247. /* Only deal with devices on the same bus here, no Mac has a P2P
  248. * bridge on the AGP port, and mucking around the entire PCI
  249. * tree is source of problems on some machines because of a bug
  250. * in some versions of pci_find_capability() when hitting a dead
  251. * device
  252. */
  253. if (device->bus != pdev->bus)
  254. continue;
  255. agp = pci_find_capability(device, PCI_CAP_ID_AGP);
  256. if (!agp)
  257. continue;
  258. pci_read_config_dword(device, agp + PCI_AGP_COMMAND, &cmd);
  259. if (!(cmd & PCI_AGP_COMMAND_AGP))
  260. continue;
  261. printk("uninorth-agp: disabling AGP on device %s\n",
  262. pci_name(device));
  263. cmd &= ~PCI_AGP_COMMAND_AGP;
  264. pci_write_config_dword(device, agp + PCI_AGP_COMMAND, cmd);
  265. }
  266. /* turn off AGP on the bridge */
  267. agp = pci_find_capability(pdev, PCI_CAP_ID_AGP);
  268. pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd);
  269. if (cmd & PCI_AGP_COMMAND_AGP) {
  270. printk("uninorth-agp: disabling AGP on bridge %s\n",
  271. pci_name(pdev));
  272. cmd &= ~PCI_AGP_COMMAND_AGP;
  273. pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, cmd);
  274. }
  275. /* turn off the GART */
  276. uninorth_cleanup();
  277. return 0;
  278. }
  279. static int agp_uninorth_resume(struct pci_dev *pdev)
  280. {
  281. return 0;
  282. }
  283. #endif
  284. static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
  285. {
  286. char *table;
  287. char *table_end;
  288. int size;
  289. int page_order;
  290. int num_entries;
  291. int i;
  292. void *temp;
  293. struct page *page;
  294. /* We can't handle 2 level gatt's */
  295. if (bridge->driver->size_type == LVL2_APER_SIZE)
  296. return -EINVAL;
  297. table = NULL;
  298. i = bridge->aperture_size_idx;
  299. temp = bridge->current_size;
  300. size = page_order = num_entries = 0;
  301. do {
  302. size = A_SIZE_32(temp)->size;
  303. page_order = A_SIZE_32(temp)->page_order;
  304. num_entries = A_SIZE_32(temp)->num_entries;
  305. table = (char *) __get_free_pages(GFP_KERNEL, page_order);
  306. if (table == NULL) {
  307. i++;
  308. bridge->current_size = A_IDX32(bridge);
  309. } else {
  310. bridge->aperture_size_idx = i;
  311. }
  312. } while (!table && (i < bridge->driver->num_aperture_sizes));
  313. if (table == NULL)
  314. return -ENOMEM;
  315. table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
  316. for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
  317. SetPageReserved(page);
  318. bridge->gatt_table_real = (u32 *) table;
  319. bridge->gatt_table = (u32 *)table;
  320. bridge->gatt_bus_addr = virt_to_phys(table);
  321. for (i = 0; i < num_entries; i++)
  322. bridge->gatt_table[i] = 0;
  323. flush_dcache_range((unsigned long)table, (unsigned long)table_end);
  324. return 0;
  325. }
  326. static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
  327. {
  328. int page_order;
  329. char *table, *table_end;
  330. void *temp;
  331. struct page *page;
  332. temp = bridge->current_size;
  333. page_order = A_SIZE_32(temp)->page_order;
  334. /* Do not worry about freeing memory, because if this is
  335. * called, then all agp memory is deallocated and removed
  336. * from the table.
  337. */
  338. table = (char *) bridge->gatt_table_real;
  339. table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
  340. for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
  341. ClearPageReserved(page);
  342. free_pages((unsigned long) bridge->gatt_table_real, page_order);
  343. return 0;
  344. }
  345. void null_cache_flush(void)
  346. {
  347. mb();
  348. }
  349. /* Setup function */
  350. static struct aper_size_info_32 uninorth_sizes[7] =
  351. {
  352. #if 0 /* Not sure uninorth supports that high aperture sizes */
  353. {256, 65536, 6, 64},
  354. {128, 32768, 5, 32},
  355. {64, 16384, 4, 16},
  356. #endif
  357. {32, 8192, 3, 8},
  358. {16, 4096, 2, 4},
  359. {8, 2048, 1, 2},
  360. {4, 1024, 0, 1}
  361. };
  362. /*
  363. * Not sure that u3 supports that high aperture sizes but it
  364. * would strange if it did not :)
  365. */
  366. static struct aper_size_info_32 u3_sizes[8] =
  367. {
  368. {512, 131072, 7, 128},
  369. {256, 65536, 6, 64},
  370. {128, 32768, 5, 32},
  371. {64, 16384, 4, 16},
  372. {32, 8192, 3, 8},
  373. {16, 4096, 2, 4},
  374. {8, 2048, 1, 2},
  375. {4, 1024, 0, 1}
  376. };
  377. struct agp_bridge_driver uninorth_agp_driver = {
  378. .owner = THIS_MODULE,
  379. .aperture_sizes = (void *)uninorth_sizes,
  380. .size_type = U32_APER_SIZE,
  381. .num_aperture_sizes = 4,
  382. .configure = uninorth_configure,
  383. .fetch_size = uninorth_fetch_size,
  384. .cleanup = uninorth_cleanup,
  385. .tlb_flush = uninorth_tlbflush,
  386. .mask_memory = agp_generic_mask_memory,
  387. .masks = NULL,
  388. .cache_flush = null_cache_flush,
  389. .agp_enable = uninorth_agp_enable,
  390. .create_gatt_table = uninorth_create_gatt_table,
  391. .free_gatt_table = uninorth_free_gatt_table,
  392. .insert_memory = uninorth_insert_memory,
  393. .remove_memory = agp_generic_remove_memory,
  394. .alloc_by_type = agp_generic_alloc_by_type,
  395. .free_by_type = agp_generic_free_by_type,
  396. .agp_alloc_page = agp_generic_alloc_page,
  397. .agp_destroy_page = agp_generic_destroy_page,
  398. .cant_use_aperture = 1,
  399. };
  400. struct agp_bridge_driver u3_agp_driver = {
  401. .owner = THIS_MODULE,
  402. .aperture_sizes = (void *)u3_sizes,
  403. .size_type = U32_APER_SIZE,
  404. .num_aperture_sizes = 8,
  405. .configure = uninorth_configure,
  406. .fetch_size = uninorth_fetch_size,
  407. .cleanup = uninorth_cleanup,
  408. .tlb_flush = uninorth_tlbflush,
  409. .mask_memory = agp_generic_mask_memory,
  410. .masks = NULL,
  411. .cache_flush = null_cache_flush,
  412. .agp_enable = uninorth_agp_enable,
  413. .create_gatt_table = uninorth_create_gatt_table,
  414. .free_gatt_table = uninorth_free_gatt_table,
  415. .insert_memory = u3_insert_memory,
  416. .remove_memory = u3_remove_memory,
  417. .alloc_by_type = agp_generic_alloc_by_type,
  418. .free_by_type = agp_generic_free_by_type,
  419. .agp_alloc_page = agp_generic_alloc_page,
  420. .agp_destroy_page = agp_generic_destroy_page,
  421. .cant_use_aperture = 1,
  422. .needs_scratch_page = 1,
  423. };
  424. static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
  425. {
  426. .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
  427. .chipset_name = "UniNorth",
  428. },
  429. {
  430. .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP_P,
  431. .chipset_name = "UniNorth/Pangea",
  432. },
  433. {
  434. .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP15,
  435. .chipset_name = "UniNorth 1.5",
  436. },
  437. {
  438. .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP2,
  439. .chipset_name = "UniNorth 2",
  440. },
  441. {
  442. .device_id = PCI_DEVICE_ID_APPLE_U3_AGP,
  443. .chipset_name = "U3",
  444. },
  445. {
  446. .device_id = PCI_DEVICE_ID_APPLE_U3L_AGP,
  447. .chipset_name = "U3L",
  448. },
  449. {
  450. .device_id = PCI_DEVICE_ID_APPLE_U3H_AGP,
  451. .chipset_name = "U3H",
  452. },
  453. };
  454. static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
  455. const struct pci_device_id *ent)
  456. {
  457. struct agp_device_ids *devs = uninorth_agp_device_ids;
  458. struct agp_bridge_data *bridge;
  459. struct device_node *uninorth_node;
  460. u8 cap_ptr;
  461. int j;
  462. cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
  463. if (cap_ptr == 0)
  464. return -ENODEV;
  465. /* probe for known chipsets */
  466. for (j = 0; devs[j].chipset_name != NULL; ++j) {
  467. if (pdev->device == devs[j].device_id) {
  468. printk(KERN_INFO PFX "Detected Apple %s chipset\n",
  469. devs[j].chipset_name);
  470. goto found;
  471. }
  472. }
  473. printk(KERN_ERR PFX "Unsupported Apple chipset (device id: %04x).\n",
  474. pdev->device);
  475. return -ENODEV;
  476. found:
  477. /* Set revision to 0 if we could not read it. */
  478. uninorth_rev = 0;
  479. is_u3 = 0;
  480. /* Locate core99 Uni-N */
  481. uninorth_node = of_find_node_by_name(NULL, "uni-n");
  482. /* Locate G5 u3 */
  483. if (uninorth_node == NULL) {
  484. is_u3 = 1;
  485. uninorth_node = of_find_node_by_name(NULL, "u3");
  486. }
  487. if (uninorth_node) {
  488. int *revprop = (int *)
  489. get_property(uninorth_node, "device-rev", NULL);
  490. if (revprop != NULL)
  491. uninorth_rev = *revprop & 0x3f;
  492. of_node_put(uninorth_node);
  493. }
  494. bridge = agp_alloc_bridge();
  495. if (!bridge)
  496. return -ENOMEM;
  497. if (is_u3)
  498. bridge->driver = &u3_agp_driver;
  499. else
  500. bridge->driver = &uninorth_agp_driver;
  501. bridge->dev = pdev;
  502. bridge->capndx = cap_ptr;
  503. bridge->flags = AGP_ERRATA_FASTWRITES;
  504. /* Fill in the mode register */
  505. pci_read_config_dword(pdev, cap_ptr+PCI_AGP_STATUS, &bridge->mode);
  506. pci_set_drvdata(pdev, bridge);
  507. return agp_add_bridge(bridge);
  508. }
  509. static void __devexit agp_uninorth_remove(struct pci_dev *pdev)
  510. {
  511. struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
  512. agp_remove_bridge(bridge);
  513. agp_put_bridge(bridge);
  514. }
  515. static struct pci_device_id agp_uninorth_pci_table[] = {
  516. {
  517. .class = (PCI_CLASS_BRIDGE_HOST << 8),
  518. .class_mask = ~0,
  519. .vendor = PCI_VENDOR_ID_APPLE,
  520. .device = PCI_ANY_ID,
  521. .subvendor = PCI_ANY_ID,
  522. .subdevice = PCI_ANY_ID,
  523. },
  524. { }
  525. };
  526. MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table);
  527. static struct pci_driver agp_uninorth_pci_driver = {
  528. .name = "agpgart-uninorth",
  529. .id_table = agp_uninorth_pci_table,
  530. .probe = agp_uninorth_probe,
  531. .remove = agp_uninorth_remove,
  532. #ifdef CONFIG_PM
  533. .suspend = agp_uninorth_suspend,
  534. .resume = agp_uninorth_resume,
  535. #endif
  536. };
  537. static int __init agp_uninorth_init(void)
  538. {
  539. if (agp_off)
  540. return -EINVAL;
  541. return pci_register_driver(&agp_uninorth_pci_driver);
  542. }
  543. static void __exit agp_uninorth_cleanup(void)
  544. {
  545. pci_unregister_driver(&agp_uninorth_pci_driver);
  546. }
  547. module_init(agp_uninorth_init);
  548. module_exit(agp_uninorth_cleanup);
  549. MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
  550. MODULE_LICENSE("GPL");