via-core.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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. * Figure out how big our framebuffer memory is. Kind of ugly,
  33. * but evidently we can't trust the information found in the
  34. * fbdev configuration area.
  35. */
  36. static u16 via_function3[] = {
  37. CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
  38. CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
  39. P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3,
  40. };
  41. /* Get the BIOS-configured framebuffer size from PCI configuration space
  42. * of function 3 in the respective chipset */
  43. static int viafb_get_fb_size_from_pci(int chip_type)
  44. {
  45. int i;
  46. u8 offset = 0;
  47. u32 FBSize;
  48. u32 VideoMemSize;
  49. /* search for the "FUNCTION3" device in this chipset */
  50. for (i = 0; i < ARRAY_SIZE(via_function3); i++) {
  51. struct pci_dev *pdev;
  52. pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i],
  53. NULL);
  54. if (!pdev)
  55. continue;
  56. DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device);
  57. switch (pdev->device) {
  58. case CLE266_FUNCTION3:
  59. case KM400_FUNCTION3:
  60. offset = 0xE0;
  61. break;
  62. case CN400_FUNCTION3:
  63. case CN700_FUNCTION3:
  64. case CX700_FUNCTION3:
  65. case KM800_FUNCTION3:
  66. case KM890_FUNCTION3:
  67. case P4M890_FUNCTION3:
  68. case P4M900_FUNCTION3:
  69. case VX800_FUNCTION3:
  70. case VX855_FUNCTION3:
  71. /*case CN750_FUNCTION3: */
  72. offset = 0xA0;
  73. break;
  74. }
  75. if (!offset)
  76. break;
  77. pci_read_config_dword(pdev, offset, &FBSize);
  78. pci_dev_put(pdev);
  79. }
  80. if (!offset) {
  81. printk(KERN_ERR "cannot determine framebuffer size\n");
  82. return -EIO;
  83. }
  84. FBSize = FBSize & 0x00007000;
  85. DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
  86. if (chip_type < UNICHROME_CX700) {
  87. switch (FBSize) {
  88. case 0x00004000:
  89. VideoMemSize = (16 << 20); /*16M */
  90. break;
  91. case 0x00005000:
  92. VideoMemSize = (32 << 20); /*32M */
  93. break;
  94. case 0x00006000:
  95. VideoMemSize = (64 << 20); /*64M */
  96. break;
  97. default:
  98. VideoMemSize = (32 << 20); /*32M */
  99. break;
  100. }
  101. } else {
  102. switch (FBSize) {
  103. case 0x00001000:
  104. VideoMemSize = (8 << 20); /*8M */
  105. break;
  106. case 0x00002000:
  107. VideoMemSize = (16 << 20); /*16M */
  108. break;
  109. case 0x00003000:
  110. VideoMemSize = (32 << 20); /*32M */
  111. break;
  112. case 0x00004000:
  113. VideoMemSize = (64 << 20); /*64M */
  114. break;
  115. case 0x00005000:
  116. VideoMemSize = (128 << 20); /*128M */
  117. break;
  118. case 0x00006000:
  119. VideoMemSize = (256 << 20); /*256M */
  120. break;
  121. case 0x00007000: /* Only on VX855/875 */
  122. VideoMemSize = (512 << 20); /*512M */
  123. break;
  124. default:
  125. VideoMemSize = (32 << 20); /*32M */
  126. break;
  127. }
  128. }
  129. return VideoMemSize;
  130. }
  131. /*
  132. * Figure out and map our MMIO regions.
  133. */
  134. static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)
  135. {
  136. /*
  137. * Hook up to the device registers.
  138. */
  139. vdev->engine_start = pci_resource_start(vdev->pdev, 1);
  140. vdev->engine_len = pci_resource_len(vdev->pdev, 1);
  141. /* If this fails, others will notice later */
  142. vdev->engine_mmio = ioremap_nocache(vdev->engine_start,
  143. vdev->engine_len);
  144. /*
  145. * Likewise with I/O memory.
  146. */
  147. vdev->fbmem_start = pci_resource_start(vdev->pdev, 0);
  148. vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type);
  149. if (vdev->fbmem_len < 0)
  150. return vdev->fbmem_len;
  151. vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len);
  152. if (vdev->fbmem == NULL)
  153. return -ENOMEM;
  154. return 0;
  155. }
  156. static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev)
  157. {
  158. iounmap(vdev->fbmem);
  159. iounmap(vdev->engine_mmio);
  160. }
  161. /*
  162. * Create our subsidiary devices.
  163. */
  164. static struct viafb_subdev_info {
  165. char *name;
  166. struct platform_device *platdev;
  167. } viafb_subdevs[] = {
  168. {
  169. .name = "viafb-gpio",
  170. },
  171. {
  172. .name = "viafb-i2c",
  173. }
  174. };
  175. #define N_SUBDEVS ARRAY_SIZE(viafb_subdevs)
  176. static int __devinit via_create_subdev(struct viafb_dev *vdev,
  177. struct viafb_subdev_info *info)
  178. {
  179. int ret;
  180. info->platdev = platform_device_alloc(info->name, -1);
  181. if (!info->platdev) {
  182. dev_err(&vdev->pdev->dev, "Unable to allocate pdev %s\n",
  183. info->name);
  184. return -ENOMEM;
  185. }
  186. info->platdev->dev.parent = &vdev->pdev->dev;
  187. info->platdev->dev.platform_data = vdev;
  188. ret = platform_device_add(info->platdev);
  189. if (ret) {
  190. dev_err(&vdev->pdev->dev, "Unable to add pdev %s\n",
  191. info->name);
  192. platform_device_put(info->platdev);
  193. info->platdev = NULL;
  194. }
  195. return ret;
  196. }
  197. static int __devinit via_setup_subdevs(struct viafb_dev *vdev)
  198. {
  199. int i;
  200. /*
  201. * Ignore return values. Even if some of the devices
  202. * fail to be created, we'll still be able to use some
  203. * of the rest.
  204. */
  205. for (i = 0; i < N_SUBDEVS; i++)
  206. via_create_subdev(vdev, viafb_subdevs + i);
  207. return 0;
  208. }
  209. static void __devexit via_teardown_subdevs(void)
  210. {
  211. int i;
  212. for (i = 0; i < N_SUBDEVS; i++)
  213. if (viafb_subdevs[i].platdev) {
  214. viafb_subdevs[i].platdev->dev.platform_data = NULL;
  215. platform_device_unregister(viafb_subdevs[i].platdev);
  216. }
  217. }
  218. static int __devinit via_pci_probe(struct pci_dev *pdev,
  219. const struct pci_device_id *ent)
  220. {
  221. int ret;
  222. ret = pci_enable_device(pdev);
  223. if (ret)
  224. return ret;
  225. /*
  226. * Global device initialization.
  227. */
  228. memset(&global_dev, 0, sizeof(global_dev));
  229. global_dev.pdev = pdev;
  230. global_dev.chip_type = ent->driver_data;
  231. global_dev.port_cfg = adap_configs;
  232. spin_lock_init(&global_dev.reg_lock);
  233. ret = via_pci_setup_mmio(&global_dev);
  234. if (ret)
  235. goto out_disable;
  236. /*
  237. * Create our subdevices. Continue even if some things fail.
  238. */
  239. via_setup_subdevs(&global_dev);
  240. /*
  241. * Set up the framebuffer.
  242. */
  243. ret = via_fb_pci_probe(&global_dev);
  244. if (ret)
  245. goto out_subdevs;
  246. return 0;
  247. out_subdevs:
  248. via_teardown_subdevs();
  249. via_pci_teardown_mmio(&global_dev);
  250. out_disable:
  251. pci_disable_device(pdev);
  252. return ret;
  253. }
  254. static void __devexit via_pci_remove(struct pci_dev *pdev)
  255. {
  256. via_teardown_subdevs();
  257. via_fb_pci_remove(pdev);
  258. via_pci_teardown_mmio(&global_dev);
  259. pci_disable_device(pdev);
  260. }
  261. static struct pci_device_id via_pci_table[] __devinitdata = {
  262. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
  263. .driver_data = UNICHROME_CLE266 },
  264. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
  265. .driver_data = UNICHROME_PM800 },
  266. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
  267. .driver_data = UNICHROME_K400 },
  268. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
  269. .driver_data = UNICHROME_K800 },
  270. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
  271. .driver_data = UNICHROME_CN700 },
  272. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
  273. .driver_data = UNICHROME_K8M890 },
  274. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
  275. .driver_data = UNICHROME_CX700 },
  276. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
  277. .driver_data = UNICHROME_P4M900 },
  278. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
  279. .driver_data = UNICHROME_CN750 },
  280. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
  281. .driver_data = UNICHROME_VX800 },
  282. { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
  283. .driver_data = UNICHROME_VX855 },
  284. { }
  285. };
  286. MODULE_DEVICE_TABLE(pci, via_pci_table);
  287. static struct pci_driver via_driver = {
  288. .name = "viafb",
  289. .id_table = via_pci_table,
  290. .probe = via_pci_probe,
  291. .remove = __devexit_p(via_pci_remove),
  292. };
  293. static int __init via_core_init(void)
  294. {
  295. int ret;
  296. ret = viafb_init();
  297. if (ret)
  298. return ret;
  299. viafb_i2c_init();
  300. viafb_gpio_init();
  301. return pci_register_driver(&via_driver);
  302. }
  303. static void __exit via_core_exit(void)
  304. {
  305. pci_unregister_driver(&via_driver);
  306. viafb_gpio_exit();
  307. viafb_i2c_exit();
  308. viafb_exit();
  309. }
  310. module_init(via_core_init);
  311. module_exit(via_core_exit);