hibmc_drm_drv.c 10 KB

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