hibmc_drm_drv.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /* Hisilicon Hibmc SoC drm driver
  2. *
  3. * Based on the bochs drm driver.
  4. *
  5. * Copyright (c) 2016 Huawei Limited.
  6. *
  7. * Author:
  8. * Rongrong Zou <zourongrong@huawei.com>
  9. * Rongrong Zou <zourongrong@gmail.com>
  10. * Jianhua Li <lijianhua@huawei.com>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. */
  18. #include <linux/console.h>
  19. #include <linux/module.h>
  20. #include <drm/drm_atomic_helper.h>
  21. #include <drm/drm_crtc_helper.h>
  22. #include "hibmc_drm_drv.h"
  23. #include "hibmc_drm_regs.h"
  24. static const struct file_operations hibmc_fops = {
  25. .owner = THIS_MODULE,
  26. .open = drm_open,
  27. .release = drm_release,
  28. .unlocked_ioctl = drm_ioctl,
  29. .compat_ioctl = drm_compat_ioctl,
  30. .mmap = hibmc_mmap,
  31. .poll = drm_poll,
  32. .read = drm_read,
  33. .llseek = no_llseek,
  34. };
  35. irqreturn_t hibmc_drm_interrupt(int irq, void *arg)
  36. {
  37. struct drm_device *dev = (struct drm_device *)arg;
  38. struct hibmc_drm_private *priv =
  39. (struct hibmc_drm_private *)dev->dev_private;
  40. u32 status;
  41. status = readl(priv->mmio + HIBMC_RAW_INTERRUPT);
  42. if (status & HIBMC_RAW_INTERRUPT_VBLANK(1)) {
  43. writel(HIBMC_RAW_INTERRUPT_VBLANK(1),
  44. priv->mmio + HIBMC_RAW_INTERRUPT);
  45. drm_handle_vblank(dev, 0);
  46. }
  47. return IRQ_HANDLED;
  48. }
  49. static struct drm_driver hibmc_driver = {
  50. .driver_features = DRIVER_GEM | DRIVER_MODESET |
  51. DRIVER_ATOMIC | DRIVER_HAVE_IRQ,
  52. .fops = &hibmc_fops,
  53. .name = "hibmc",
  54. .date = "20160828",
  55. .desc = "hibmc drm driver",
  56. .major = 1,
  57. .minor = 0,
  58. .gem_free_object_unlocked = hibmc_gem_free_object,
  59. .dumb_create = hibmc_dumb_create,
  60. .dumb_map_offset = hibmc_dumb_mmap_offset,
  61. .dumb_destroy = drm_gem_dumb_destroy,
  62. .irq_handler = hibmc_drm_interrupt,
  63. };
  64. static int __maybe_unused hibmc_pm_suspend(struct device *dev)
  65. {
  66. struct pci_dev *pdev = to_pci_dev(dev);
  67. struct drm_device *drm_dev = pci_get_drvdata(pdev);
  68. struct hibmc_drm_private *priv = drm_dev->dev_private;
  69. drm_kms_helper_poll_disable(drm_dev);
  70. priv->suspend_state = drm_atomic_helper_suspend(drm_dev);
  71. if (IS_ERR(priv->suspend_state)) {
  72. DRM_ERROR("drm_atomic_helper_suspend failed: %ld\n",
  73. PTR_ERR(priv->suspend_state));
  74. drm_kms_helper_poll_enable(drm_dev);
  75. return PTR_ERR(priv->suspend_state);
  76. }
  77. return 0;
  78. }
  79. static int __maybe_unused hibmc_pm_resume(struct device *dev)
  80. {
  81. struct pci_dev *pdev = to_pci_dev(dev);
  82. struct drm_device *drm_dev = pci_get_drvdata(pdev);
  83. struct hibmc_drm_private *priv = drm_dev->dev_private;
  84. drm_atomic_helper_resume(drm_dev, priv->suspend_state);
  85. drm_kms_helper_poll_enable(drm_dev);
  86. return 0;
  87. }
  88. static const struct dev_pm_ops hibmc_pm_ops = {
  89. SET_SYSTEM_SLEEP_PM_OPS(hibmc_pm_suspend,
  90. hibmc_pm_resume)
  91. };
  92. static int hibmc_kms_init(struct hibmc_drm_private *priv)
  93. {
  94. int ret;
  95. drm_mode_config_init(priv->dev);
  96. priv->mode_config_initialized = true;
  97. priv->dev->mode_config.min_width = 0;
  98. priv->dev->mode_config.min_height = 0;
  99. priv->dev->mode_config.max_width = 1920;
  100. priv->dev->mode_config.max_height = 1440;
  101. priv->dev->mode_config.fb_base = priv->fb_base;
  102. priv->dev->mode_config.preferred_depth = 24;
  103. priv->dev->mode_config.prefer_shadow = 0;
  104. priv->dev->mode_config.funcs = (void *)&hibmc_mode_funcs;
  105. ret = hibmc_de_init(priv);
  106. if (ret) {
  107. DRM_ERROR("failed to init de: %d\n", ret);
  108. return ret;
  109. }
  110. ret = hibmc_vdac_init(priv);
  111. if (ret) {
  112. DRM_ERROR("failed to init vdac: %d\n", ret);
  113. return ret;
  114. }
  115. return 0;
  116. }
  117. static void hibmc_kms_fini(struct hibmc_drm_private *priv)
  118. {
  119. if (priv->mode_config_initialized) {
  120. drm_mode_config_cleanup(priv->dev);
  121. priv->mode_config_initialized = false;
  122. }
  123. }
  124. /*
  125. * It can operate in one of three modes: 0, 1 or Sleep.
  126. */
  127. void hibmc_set_power_mode(struct hibmc_drm_private *priv,
  128. unsigned int power_mode)
  129. {
  130. unsigned int control_value = 0;
  131. void __iomem *mmio = priv->mmio;
  132. unsigned int input = 1;
  133. if (power_mode > HIBMC_PW_MODE_CTL_MODE_SLEEP)
  134. return;
  135. if (power_mode == HIBMC_PW_MODE_CTL_MODE_SLEEP)
  136. input = 0;
  137. control_value = readl(mmio + HIBMC_POWER_MODE_CTRL);
  138. control_value &= ~(HIBMC_PW_MODE_CTL_MODE_MASK |
  139. HIBMC_PW_MODE_CTL_OSC_INPUT_MASK);
  140. control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_MODE, power_mode);
  141. control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_OSC_INPUT, input);
  142. writel(control_value, mmio + HIBMC_POWER_MODE_CTRL);
  143. }
  144. void hibmc_set_current_gate(struct hibmc_drm_private *priv, unsigned int gate)
  145. {
  146. unsigned int gate_reg;
  147. unsigned int mode;
  148. void __iomem *mmio = priv->mmio;
  149. /* Get current power mode. */
  150. mode = (readl(mmio + HIBMC_POWER_MODE_CTRL) &
  151. HIBMC_PW_MODE_CTL_MODE_MASK) >> HIBMC_PW_MODE_CTL_MODE_SHIFT;
  152. switch (mode) {
  153. case HIBMC_PW_MODE_CTL_MODE_MODE0:
  154. gate_reg = HIBMC_MODE0_GATE;
  155. break;
  156. case HIBMC_PW_MODE_CTL_MODE_MODE1:
  157. gate_reg = HIBMC_MODE1_GATE;
  158. break;
  159. default:
  160. gate_reg = HIBMC_MODE0_GATE;
  161. break;
  162. }
  163. writel(gate, mmio + gate_reg);
  164. }
  165. static void hibmc_hw_config(struct hibmc_drm_private *priv)
  166. {
  167. unsigned int reg;
  168. /* On hardware reset, power mode 0 is default. */
  169. hibmc_set_power_mode(priv, HIBMC_PW_MODE_CTL_MODE_MODE0);
  170. /* Enable display power gate & LOCALMEM power gate*/
  171. reg = readl(priv->mmio + HIBMC_CURRENT_GATE);
  172. reg &= ~HIBMC_CURR_GATE_DISPLAY_MASK;
  173. reg &= ~HIBMC_CURR_GATE_LOCALMEM_MASK;
  174. reg |= HIBMC_CURR_GATE_DISPLAY(1);
  175. reg |= HIBMC_CURR_GATE_LOCALMEM(1);
  176. hibmc_set_current_gate(priv, reg);
  177. /*
  178. * Reset the memory controller. If the memory controller
  179. * is not reset in chip,the system might hang when sw accesses
  180. * the memory.The memory should be resetted after
  181. * changing the MXCLK.
  182. */
  183. reg = readl(priv->mmio + HIBMC_MISC_CTRL);
  184. reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK;
  185. reg |= HIBMC_MSCCTL_LOCALMEM_RESET(0);
  186. writel(reg, priv->mmio + HIBMC_MISC_CTRL);
  187. reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK;
  188. reg |= HIBMC_MSCCTL_LOCALMEM_RESET(1);
  189. writel(reg, priv->mmio + HIBMC_MISC_CTRL);
  190. }
  191. static int hibmc_hw_map(struct hibmc_drm_private *priv)
  192. {
  193. struct drm_device *dev = priv->dev;
  194. struct pci_dev *pdev = dev->pdev;
  195. resource_size_t addr, size, ioaddr, iosize;
  196. ioaddr = pci_resource_start(pdev, 1);
  197. iosize = pci_resource_len(pdev, 1);
  198. priv->mmio = devm_ioremap_nocache(dev->dev, ioaddr, iosize);
  199. if (!priv->mmio) {
  200. DRM_ERROR("Cannot map mmio region\n");
  201. return -ENOMEM;
  202. }
  203. addr = pci_resource_start(pdev, 0);
  204. size = pci_resource_len(pdev, 0);
  205. priv->fb_map = devm_ioremap(dev->dev, addr, size);
  206. if (!priv->fb_map) {
  207. DRM_ERROR("Cannot map framebuffer\n");
  208. return -ENOMEM;
  209. }
  210. priv->fb_base = addr;
  211. priv->fb_size = size;
  212. return 0;
  213. }
  214. static int hibmc_hw_init(struct hibmc_drm_private *priv)
  215. {
  216. int ret;
  217. ret = hibmc_hw_map(priv);
  218. if (ret)
  219. return ret;
  220. hibmc_hw_config(priv);
  221. return 0;
  222. }
  223. static int hibmc_unload(struct drm_device *dev)
  224. {
  225. struct hibmc_drm_private *priv = dev->dev_private;
  226. hibmc_fbdev_fini(priv);
  227. if (dev->irq_enabled)
  228. drm_irq_uninstall(dev);
  229. if (priv->msi_enabled)
  230. pci_disable_msi(dev->pdev);
  231. drm_vblank_cleanup(dev);
  232. hibmc_kms_fini(priv);
  233. hibmc_mm_fini(priv);
  234. dev->dev_private = NULL;
  235. return 0;
  236. }
  237. static int hibmc_load(struct drm_device *dev)
  238. {
  239. struct hibmc_drm_private *priv;
  240. int ret;
  241. priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
  242. if (!priv) {
  243. DRM_ERROR("no memory to allocate for hibmc_drm_private\n");
  244. return -ENOMEM;
  245. }
  246. dev->dev_private = priv;
  247. priv->dev = dev;
  248. ret = hibmc_hw_init(priv);
  249. if (ret)
  250. goto err;
  251. ret = hibmc_mm_init(priv);
  252. if (ret)
  253. goto err;
  254. ret = hibmc_kms_init(priv);
  255. if (ret)
  256. goto err;
  257. ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
  258. if (ret) {
  259. DRM_ERROR("failed to initialize vblank: %d\n", ret);
  260. goto err;
  261. }
  262. priv->msi_enabled = 0;
  263. ret = pci_enable_msi(dev->pdev);
  264. if (ret) {
  265. DRM_WARN("enabling MSI failed: %d\n", ret);
  266. } else {
  267. priv->msi_enabled = 1;
  268. ret = drm_irq_install(dev, dev->pdev->irq);
  269. if (ret)
  270. DRM_WARN("install irq failed: %d\n", ret);
  271. }
  272. /* reset all the states of crtc/plane/encoder/connector */
  273. drm_mode_config_reset(dev);
  274. ret = hibmc_fbdev_init(priv);
  275. if (ret) {
  276. DRM_ERROR("failed to initialize fbdev: %d\n", ret);
  277. goto err;
  278. }
  279. return 0;
  280. err:
  281. hibmc_unload(dev);
  282. DRM_ERROR("failed to initialize drm driver: %d\n", ret);
  283. return ret;
  284. }
  285. static int hibmc_pci_probe(struct pci_dev *pdev,
  286. const struct pci_device_id *ent)
  287. {
  288. struct drm_device *dev;
  289. int ret;
  290. dev = drm_dev_alloc(&hibmc_driver, &pdev->dev);
  291. if (IS_ERR(dev)) {
  292. DRM_ERROR("failed to allocate drm_device\n");
  293. return PTR_ERR(dev);
  294. }
  295. dev->pdev = pdev;
  296. pci_set_drvdata(pdev, dev);
  297. ret = pci_enable_device(pdev);
  298. if (ret) {
  299. DRM_ERROR("failed to enable pci device: %d\n", ret);
  300. goto err_free;
  301. }
  302. ret = hibmc_load(dev);
  303. if (ret) {
  304. DRM_ERROR("failed to load hibmc: %d\n", ret);
  305. goto err_disable;
  306. }
  307. ret = drm_dev_register(dev, 0);
  308. if (ret) {
  309. DRM_ERROR("failed to register drv for userspace access: %d\n",
  310. ret);
  311. goto err_unload;
  312. }
  313. return 0;
  314. err_unload:
  315. hibmc_unload(dev);
  316. err_disable:
  317. pci_disable_device(pdev);
  318. err_free:
  319. drm_dev_unref(dev);
  320. return ret;
  321. }
  322. static void hibmc_pci_remove(struct pci_dev *pdev)
  323. {
  324. struct drm_device *dev = pci_get_drvdata(pdev);
  325. drm_dev_unregister(dev);
  326. hibmc_unload(dev);
  327. drm_dev_unref(dev);
  328. }
  329. static struct pci_device_id hibmc_pci_table[] = {
  330. {0x19e5, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
  331. {0,}
  332. };
  333. static struct pci_driver hibmc_pci_driver = {
  334. .name = "hibmc-drm",
  335. .id_table = hibmc_pci_table,
  336. .probe = hibmc_pci_probe,
  337. .remove = hibmc_pci_remove,
  338. .driver.pm = &hibmc_pm_ops,
  339. };
  340. static int __init hibmc_init(void)
  341. {
  342. return pci_register_driver(&hibmc_pci_driver);
  343. }
  344. static void __exit hibmc_exit(void)
  345. {
  346. return pci_unregister_driver(&hibmc_pci_driver);
  347. }
  348. module_init(hibmc_init);
  349. module_exit(hibmc_exit);
  350. MODULE_DEVICE_TABLE(pci, hibmc_pci_table);
  351. MODULE_AUTHOR("RongrongZou <zourongrong@huawei.com>");
  352. MODULE_DESCRIPTION("DRM Driver for Hisilicon Hibmc");
  353. MODULE_LICENSE("GPL v2");