hibmc_drm_drv.c 9.4 KB

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