via-core.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
  3. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
  4. * Copyright 2009 Jonathan Corbet <corbet@lwn.net>
  5. */
  6. /*
  7. * Core code for the Via multifunction framebuffer device.
  8. */
  9. #include "via-core.h"
  10. #include "via_i2c.h"
  11. #include "via-gpio.h"
  12. #include "global.h"
  13. #include <linux/module.h>
  14. #include <linux/platform_device.h>
  15. /*
  16. * The default port config.
  17. */
  18. static struct via_port_cfg adap_configs[] = {
  19. [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_OFF, VIASR, 0x26 },
  20. [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 },
  21. [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 },
  22. [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_I2C, VIASR, 0x2c },
  23. [VIA_PORT_3D] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x3d },
  24. { 0, 0, 0, 0 }
  25. };
  26. /*
  27. * We currently only support one viafb device (will there ever be
  28. * more than one?), so just declare it globally here.
  29. */
  30. static struct viafb_dev global_dev;
  31. /*
  32. * Basic register access; spinlock required.
  33. */
  34. static inline void viafb_mmio_write(int reg, u32 v)
  35. {
  36. iowrite32(v, global_dev.engine_mmio + reg);
  37. }
  38. static inline int viafb_mmio_read(int reg)
  39. {
  40. return ioread32(global_dev.engine_mmio + reg);
  41. }
  42. /* ---------------------------------------------------------------------- */
  43. /*
  44. * Interrupt management. We have a single IRQ line for a lot of
  45. * different functions, so we need to share it. The design here
  46. * is that we don't want to reimplement the shared IRQ code here;
  47. * we also want to avoid having contention for a single handler thread.
  48. * So each subdev driver which needs interrupts just requests
  49. * them directly from the kernel. We just have what's needed for
  50. * overall access to the interrupt control register.
  51. */
  52. /*
  53. * Which interrupts are enabled now?
  54. */
  55. static u32 viafb_enabled_ints;
  56. static void viafb_int_init(void)
  57. {
  58. viafb_enabled_ints = 0;
  59. viafb_mmio_write(VDE_INTERRUPT, 0);
  60. }
  61. /*
  62. * Allow subdevs to ask for specific interrupts to be enabled. These
  63. * functions must be called with reg_lock held
  64. */
  65. void viafb_irq_enable(u32 mask)
  66. {
  67. viafb_enabled_ints |= mask;
  68. viafb_mmio_write(VDE_INTERRUPT, viafb_enabled_ints | VDE_I_ENABLE);
  69. }
  70. EXPORT_SYMBOL_GPL(viafb_irq_enable);
  71. void viafb_irq_disable(u32 mask)
  72. {
  73. viafb_enabled_ints &= ~mask;
  74. if (viafb_enabled_ints == 0)
  75. viafb_mmio_write(VDE_INTERRUPT, 0); /* Disable entirely */
  76. else
  77. viafb_mmio_write(VDE_INTERRUPT,
  78. viafb_enabled_ints | VDE_I_ENABLE);
  79. }
  80. EXPORT_SYMBOL_GPL(viafb_irq_disable);
  81. /*
  82. * Figure out how big our framebuffer memory is. Kind of ugly,
  83. * but evidently we can't trust the information found in the
  84. * fbdev configuration area.
  85. */
  86. static u16 via_function3[] = {
  87. CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
  88. CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
  89. P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3,
  90. };
  91. /* Get the BIOS-configured framebuffer size from PCI configuration space
  92. * of function 3 in the respective chipset */
  93. static int viafb_get_fb_size_from_pci(int chip_type)
  94. {
  95. int i;
  96. u8 offset = 0;
  97. u32 FBSize;
  98. u32 VideoMemSize;
  99. /* search for the "FUNCTION3" device in this chipset */
  100. for (i = 0; i < ARRAY_SIZE(via_function3); i++) {
  101. struct pci_dev *pdev;
  102. pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i],
  103. NULL);
  104. if (!pdev)
  105. continue;
  106. DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device);
  107. switch (pdev->device) {
  108. case CLE266_FUNCTION3:
  109. case KM400_FUNCTION3:
  110. offset = 0xE0;
  111. break;
  112. case CN400_FUNCTION3:
  113. case CN700_FUNCTION3:
  114. case CX700_FUNCTION3:
  115. case KM800_FUNCTION3:
  116. case KM890_FUNCTION3:
  117. case P4M890_FUNCTION3:
  118. case P4M900_FUNCTION3:
  119. case VX800_FUNCTION3:
  120. case VX855_FUNCTION3:
  121. /*case CN750_FUNCTION3: */
  122. offset = 0xA0;
  123. break;
  124. }
  125. if (!offset)
  126. break;
  127. pci_read_config_dword(pdev, offset, &FBSize);
  128. pci_dev_put(pdev);
  129. }
  130. if (!offset) {
  131. printk(KERN_ERR "cannot determine framebuffer size\n");
  132. return -EIO;
  133. }
  134. FBSize = FBSize & 0x00007000;
  135. DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
  136. if (chip_type < UNICHROME_CX700) {
  137. switch (FBSize) {
  138. case 0x00004000:
  139. VideoMemSize = (16 << 20); /*16M */
  140. break;
  141. case 0x00005000:
  142. VideoMemSize = (32 << 20); /*32M */
  143. break;
  144. case 0x00006000:
  145. VideoMemSize = (64 << 20); /*64M */
  146. break;
  147. default:
  148. VideoMemSize = (32 << 20); /*32M */
  149. break;
  150. }
  151. } else {
  152. switch (FBSize) {
  153. case 0x00001000:
  154. VideoMemSize = (8 << 20); /*8M */
  155. break;
  156. case 0x00002000:
  157. VideoMemSize = (16 << 20); /*16M */
  158. break;
  159. case 0x00003000:
  160. VideoMemSize = (32 << 20); /*32M */
  161. break;
  162. case 0x00004000:
  163. VideoMemSize = (64 << 20); /*64M */
  164. break;
  165. case 0x00005000:
  166. VideoMemSize = (128 << 20); /*128M */
  167. break;
  168. case 0x00006000:
  169. VideoMemSize = (256 << 20); /*256M */
  170. break;
  171. case 0x00007000: /* Only on VX855/875 */
  172. VideoMemSize = (512 << 20); /*512M */
  173. break;
  174. default:
  175. VideoMemSize = (32 << 20); /*32M */
  176. break;
  177. }
  178. }
  179. return VideoMemSize;
  180. }
  181. /*
  182. * Figure out and map our MMIO regions.
  183. */
  184. static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)
  185. {
  186. /*
  187. * Hook up to the device registers.
  188. */
  189. vdev->engine_start = pci_resource_start(vdev->pdev, 1);
  190. vdev->engine_len = pci_resource_len(vdev->pdev, 1);
  191. /* If this fails, others will notice later */
  192. vdev->engine_mmio = ioremap_nocache(vdev->engine_start,
  193. vdev->engine_len);
  194. /*
  195. * Likewise with I/O memory.
  196. */
  197. vdev->fbmem_start = pci_resource_start(vdev->pdev, 0);
  198. vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type);
  199. if (vdev->fbmem_len < 0)
  200. return vdev->fbmem_len;
  201. vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len);
  202. if (vdev->fbmem == NULL)
  203. return -ENOMEM;
  204. return 0;
  205. }
  206. static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev)
  207. {
  208. iounmap(vdev->fbmem);
  209. iounmap(vdev->engine_mmio);
  210. }
  211. /*
  212. * Create our subsidiary devices.
  213. */
  214. static struct viafb_subdev_info {
  215. char *name;
  216. struct platform_device *platdev;
  217. } viafb_subdevs[] = {
  218. {
  219. .name = "viafb-gpio",
  220. },
  221. {
  222. .name = "viafb-i2c",
  223. }
  224. };
  225. #define N_SUBDEVS ARRAY_SIZE(viafb_subdevs)
  226. static int __devinit via_create_subdev(struct viafb_dev *vdev,
  227. struct viafb_subdev_info *info)
  228. {
  229. int ret;
  230. info->platdev = platform_device_alloc(info->name, -1);
  231. if (!info->platdev) {
  232. dev_err(&vdev->pdev->dev, "Unable to allocate pdev %s\n",
  233. info->name);
  234. return -ENOMEM;
  235. }
  236. info->platdev->dev.parent = &vdev->pdev->dev;
  237. info->platdev->dev.platform_data = vdev;
  238. ret = platform_device_add(info->platdev);
  239. if (ret) {
  240. dev_err(&vdev->pdev->dev, "Unable to add pdev %s\n",
  241. info->name);
  242. platform_device_put(info->platdev);
  243. info->platdev = NULL;
  244. }
  245. return ret;
  246. }
  247. static int __devinit via_setup_subdevs(struct viafb_dev *vdev)
  248. {
  249. int i;
  250. /*
  251. * Ignore return values. Even if some of the devices
  252. * fail to be created, we'll still be able to use some
  253. * of the rest.
  254. */
  255. for (i = 0; i < N_SUBDEVS; i++)
  256. via_create_subdev(vdev, viafb_subdevs + i);
  257. return 0;
  258. }
  259. static void __devexit via_teardown_subdevs(void)
  260. {
  261. int i;
  262. for (i = 0; i < N_SUBDEVS; i++)
  263. if (viafb_subdevs[i].platdev) {
  264. viafb_subdevs[i].platdev->dev.platform_data = NULL;
  265. platform_device_unregister(viafb_subdevs[i].platdev);
  266. }
  267. }
  268. static int __devinit via_pci_probe(struct pci_dev *pdev,
  269. const struct pci_device_id *ent)
  270. {
  271. int ret;
  272. ret = pci_enable_device(pdev);
  273. if (ret)
  274. return ret;
  275. /*
  276. * Global device initialization.
  277. */
  278. memset(&global_dev, 0, sizeof(global_dev));
  279. global_dev.pdev = pdev;
  280. global_dev.chip_type = ent->driver_data;
  281. global_dev.port_cfg = adap_configs;
  282. spin_lock_init(&global_dev.reg_lock);
  283. ret = via_pci_setup_mmio(&global_dev);
  284. if (ret)
  285. goto out_disable;
  286. /*
  287. * Set up interrupts and create our subdevices. Continue even if
  288. * some things fail.
  289. */
  290. viafb_int_init();
  291. via_setup_subdevs(&global_dev);
  292. /*
  293. * Set up the framebuffer.
  294. */
  295. ret = via_fb_pci_probe(&global_dev);
  296. if (ret)
  297. goto out_subdevs;
  298. return 0;
  299. out_subdevs:
  300. via_teardown_subdevs();
  301. via_pci_teardown_mmio(&global_dev);
  302. out_disable:
  303. pci_disable_device(pdev);
  304. return ret;
  305. }
  306. static void __devexit via_pci_remove(struct pci_dev *pdev)
  307. {
  308. via_teardown_subdevs();
  309. via_fb_pci_remove(pdev);
  310. via_pci_teardown_mmio(&global_dev);
  311. pci_disable_device(pdev);
  312. }
  313. static struct pci_device_id via_pci_table[] __devinitdata = {
  314. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
  315. .driver_data = UNICHROME_CLE266 },
  316. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
  317. .driver_data = UNICHROME_PM800 },
  318. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
  319. .driver_data = UNICHROME_K400 },
  320. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
  321. .driver_data = UNICHROME_K800 },
  322. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
  323. .driver_data = UNICHROME_CN700 },
  324. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
  325. .driver_data = UNICHROME_K8M890 },
  326. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
  327. .driver_data = UNICHROME_CX700 },
  328. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
  329. .driver_data = UNICHROME_P4M900 },
  330. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
  331. .driver_data = UNICHROME_CN750 },
  332. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
  333. .driver_data = UNICHROME_VX800 },
  334. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
  335. .driver_data = UNICHROME_VX855 },
  336. { }
  337. };
  338. MODULE_DEVICE_TABLE(pci, via_pci_table);
  339. static struct pci_driver via_driver = {
  340. .name = "viafb",
  341. .id_table = via_pci_table,
  342. .probe = via_pci_probe,
  343. .remove = __devexit_p(via_pci_remove),
  344. };
  345. static int __init via_core_init(void)
  346. {
  347. int ret;
  348. ret = viafb_init();
  349. if (ret)
  350. return ret;
  351. viafb_i2c_init();
  352. viafb_gpio_init();
  353. return pci_register_driver(&via_driver);
  354. }
  355. static void __exit via_core_exit(void)
  356. {
  357. pci_unregister_driver(&via_driver);
  358. viafb_gpio_exit();
  359. viafb_i2c_exit();
  360. viafb_exit();
  361. }
  362. module_init(via_core_init);
  363. module_exit(via_core_exit);