ipuv3-crtc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * i.MX IPUv3 Graphics driver
  4. *
  5. * Copyright (C) 2011 Sascha Hauer, Pengutronix
  6. */
  7. #include <linux/clk.h>
  8. #include <linux/component.h>
  9. #include <linux/device.h>
  10. #include <linux/dma-mapping.h>
  11. #include <linux/errno.h>
  12. #include <linux/export.h>
  13. #include <linux/module.h>
  14. #include <linux/platform_device.h>
  15. #include <video/imx-ipu-v3.h>
  16. #include <drm/drm_atomic.h>
  17. #include <drm/drm_atomic_helper.h>
  18. #include <drm/drm_gem_dma_helper.h>
  19. #include <drm/drm_managed.h>
  20. #include <drm/drm_probe_helper.h>
  21. #include <drm/drm_vblank.h>
  22. #include "imx-drm.h"
  23. #include "ipuv3-plane.h"
  24. #define DRIVER_DESC "i.MX IPUv3 Graphics"
  25. struct ipu_crtc {
  26. struct device *dev;
  27. struct drm_crtc base;
  28. /* plane[0] is the full plane, plane[1] is the partial plane */
  29. struct ipu_plane *plane[2];
  30. struct ipu_dc *dc;
  31. struct ipu_di *di;
  32. int irq;
  33. struct drm_pending_vblank_event *event;
  34. };
  35. static inline struct ipu_crtc *to_ipu_crtc(struct drm_crtc *crtc)
  36. {
  37. return container_of(crtc, struct ipu_crtc, base);
  38. }
  39. static void ipu_crtc_atomic_enable(struct drm_crtc *crtc,
  40. struct drm_atomic_state *state)
  41. {
  42. struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
  43. struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
  44. ipu_prg_enable(ipu);
  45. ipu_dc_enable(ipu);
  46. ipu_dc_enable_channel(ipu_crtc->dc);
  47. ipu_di_enable(ipu_crtc->di);
  48. }
  49. static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc,
  50. struct drm_crtc_state *old_crtc_state)
  51. {
  52. bool disable_partial = false;
  53. bool disable_full = false;
  54. struct drm_plane *plane;
  55. drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
  56. if (plane == &ipu_crtc->plane[0]->base)
  57. disable_full = true;
  58. if (ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base)
  59. disable_partial = true;
  60. }
  61. if (disable_partial)
  62. ipu_plane_disable(ipu_crtc->plane[1], true);
  63. if (disable_full)
  64. ipu_plane_disable(ipu_crtc->plane[0], true);
  65. }
  66. static void ipu_crtc_atomic_disable(struct drm_crtc *crtc,
  67. struct drm_atomic_state *state)
  68. {
  69. struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
  70. crtc);
  71. struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
  72. struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
  73. ipu_dc_disable_channel(ipu_crtc->dc);
  74. ipu_di_disable(ipu_crtc->di);
  75. /*
  76. * Planes must be disabled before DC clock is removed, as otherwise the
  77. * attached IDMACs will be left in undefined state, possibly hanging
  78. * the IPU or even system.
  79. */
  80. ipu_crtc_disable_planes(ipu_crtc, old_crtc_state);
  81. ipu_dc_disable(ipu);
  82. ipu_prg_disable(ipu);
  83. drm_crtc_vblank_off(crtc);
  84. spin_lock_irq(&crtc->dev->event_lock);
  85. if (crtc->state->event && !crtc->state->active) {
  86. drm_crtc_send_vblank_event(crtc, crtc->state->event);
  87. crtc->state->event = NULL;
  88. }
  89. spin_unlock_irq(&crtc->dev->event_lock);
  90. }
  91. static void imx_drm_crtc_reset(struct drm_crtc *crtc)
  92. {
  93. struct imx_crtc_state *state;
  94. if (crtc->state)
  95. __drm_atomic_helper_crtc_destroy_state(crtc->state);
  96. kfree(to_imx_crtc_state(crtc->state));
  97. crtc->state = NULL;
  98. state = kzalloc_obj(*state);
  99. if (state)
  100. __drm_atomic_helper_crtc_reset(crtc, &state->base);
  101. }
  102. static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc)
  103. {
  104. struct imx_crtc_state *state;
  105. state = kzalloc_obj(*state);
  106. if (!state)
  107. return NULL;
  108. __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
  109. WARN_ON(state->base.crtc != crtc);
  110. state->base.crtc = crtc;
  111. return &state->base;
  112. }
  113. static void imx_drm_crtc_destroy_state(struct drm_crtc *crtc,
  114. struct drm_crtc_state *state)
  115. {
  116. __drm_atomic_helper_crtc_destroy_state(state);
  117. kfree(to_imx_crtc_state(state));
  118. }
  119. static int ipu_enable_vblank(struct drm_crtc *crtc)
  120. {
  121. struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
  122. enable_irq(ipu_crtc->irq);
  123. return 0;
  124. }
  125. static void ipu_disable_vblank(struct drm_crtc *crtc)
  126. {
  127. struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
  128. disable_irq_nosync(ipu_crtc->irq);
  129. }
  130. static const struct drm_crtc_funcs ipu_crtc_funcs = {
  131. .set_config = drm_atomic_helper_set_config,
  132. .page_flip = drm_atomic_helper_page_flip,
  133. .reset = imx_drm_crtc_reset,
  134. .atomic_duplicate_state = imx_drm_crtc_duplicate_state,
  135. .atomic_destroy_state = imx_drm_crtc_destroy_state,
  136. .enable_vblank = ipu_enable_vblank,
  137. .disable_vblank = ipu_disable_vblank,
  138. };
  139. static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
  140. {
  141. struct ipu_crtc *ipu_crtc = dev_id;
  142. struct drm_crtc *crtc = &ipu_crtc->base;
  143. unsigned long flags;
  144. int i;
  145. drm_crtc_handle_vblank(crtc);
  146. if (ipu_crtc->event) {
  147. for (i = 0; i < ARRAY_SIZE(ipu_crtc->plane); i++) {
  148. struct ipu_plane *plane = ipu_crtc->plane[i];
  149. if (!plane)
  150. continue;
  151. if (ipu_plane_atomic_update_pending(&plane->base))
  152. break;
  153. }
  154. if (i == ARRAY_SIZE(ipu_crtc->plane)) {
  155. spin_lock_irqsave(&crtc->dev->event_lock, flags);
  156. drm_crtc_send_vblank_event(crtc, ipu_crtc->event);
  157. ipu_crtc->event = NULL;
  158. drm_crtc_vblank_put(crtc);
  159. spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
  160. }
  161. }
  162. return IRQ_HANDLED;
  163. }
  164. static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc,
  165. const struct drm_display_mode *mode,
  166. struct drm_display_mode *adjusted_mode)
  167. {
  168. struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
  169. struct videomode vm;
  170. int ret;
  171. drm_display_mode_to_videomode(adjusted_mode, &vm);
  172. ret = ipu_di_adjust_videomode(ipu_crtc->di, &vm);
  173. if (ret)
  174. return false;
  175. if ((vm.vsync_len == 0) || (vm.hsync_len == 0))
  176. return false;
  177. drm_display_mode_from_videomode(&vm, adjusted_mode);
  178. return true;
  179. }
  180. static int ipu_crtc_atomic_check(struct drm_crtc *crtc,
  181. struct drm_atomic_state *state)
  182. {
  183. struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
  184. crtc);
  185. u32 primary_plane_mask = drm_plane_mask(crtc->primary);
  186. if (crtc_state->active && (primary_plane_mask & crtc_state->plane_mask) == 0)
  187. return -EINVAL;
  188. return 0;
  189. }
  190. static void ipu_crtc_atomic_begin(struct drm_crtc *crtc,
  191. struct drm_atomic_state *state)
  192. {
  193. drm_crtc_vblank_on(crtc);
  194. }
  195. static void ipu_crtc_atomic_flush(struct drm_crtc *crtc,
  196. struct drm_atomic_state *state)
  197. {
  198. spin_lock_irq(&crtc->dev->event_lock);
  199. if (crtc->state->event) {
  200. struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
  201. WARN_ON(drm_crtc_vblank_get(crtc));
  202. ipu_crtc->event = crtc->state->event;
  203. crtc->state->event = NULL;
  204. }
  205. spin_unlock_irq(&crtc->dev->event_lock);
  206. }
  207. static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
  208. {
  209. struct drm_device *dev = crtc->dev;
  210. struct drm_encoder *encoder;
  211. struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
  212. struct drm_display_mode *mode = &crtc->state->adjusted_mode;
  213. struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state);
  214. struct ipu_di_signal_cfg sig_cfg = {};
  215. unsigned long encoder_types = 0;
  216. dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
  217. mode->hdisplay);
  218. dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
  219. mode->vdisplay);
  220. list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  221. if (encoder->crtc == crtc)
  222. encoder_types |= BIT(encoder->encoder_type);
  223. }
  224. dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n",
  225. __func__, encoder_types);
  226. /*
  227. * If we have DAC or LDB, then we need the IPU DI clock to be
  228. * the same as the LDB DI clock. For TVDAC, derive the IPU DI
  229. * clock from 27 MHz TVE_DI clock, but allow to divide it.
  230. */
  231. if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) |
  232. BIT(DRM_MODE_ENCODER_LVDS)))
  233. sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT;
  234. else if (encoder_types & BIT(DRM_MODE_ENCODER_TVDAC))
  235. sig_cfg.clkflags = IPU_DI_CLKMODE_EXT;
  236. else
  237. sig_cfg.clkflags = 0;
  238. sig_cfg.enable_pol = !(imx_crtc_state->bus_flags & DRM_BUS_FLAG_DE_LOW);
  239. /* Default to driving pixel data on negative clock edges */
  240. sig_cfg.clk_pol = !!(imx_crtc_state->bus_flags &
  241. DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE);
  242. sig_cfg.bus_format = imx_crtc_state->bus_format;
  243. sig_cfg.v_to_h_sync = 0;
  244. sig_cfg.hsync_pin = imx_crtc_state->di_hsync_pin;
  245. sig_cfg.vsync_pin = imx_crtc_state->di_vsync_pin;
  246. drm_display_mode_to_videomode(mode, &sig_cfg.mode);
  247. if (!IS_ALIGNED(sig_cfg.mode.hactive, 8)) {
  248. unsigned int new_hactive = ALIGN(sig_cfg.mode.hactive, 8);
  249. dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n",
  250. sig_cfg.mode.hactive, new_hactive);
  251. sig_cfg.mode.hfront_porch -= new_hactive - sig_cfg.mode.hactive;
  252. sig_cfg.mode.hactive = new_hactive;
  253. }
  254. ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
  255. mode->flags & DRM_MODE_FLAG_INTERLACE,
  256. imx_crtc_state->bus_format, sig_cfg.mode.hactive);
  257. ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
  258. }
  259. static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
  260. .mode_fixup = ipu_crtc_mode_fixup,
  261. .mode_set_nofb = ipu_crtc_mode_set_nofb,
  262. .atomic_check = ipu_crtc_atomic_check,
  263. .atomic_begin = ipu_crtc_atomic_begin,
  264. .atomic_flush = ipu_crtc_atomic_flush,
  265. .atomic_disable = ipu_crtc_atomic_disable,
  266. .atomic_enable = ipu_crtc_atomic_enable,
  267. };
  268. static void ipu_put_resources(struct drm_device *dev, void *ptr)
  269. {
  270. struct ipu_crtc *ipu_crtc = ptr;
  271. if (!IS_ERR_OR_NULL(ipu_crtc->dc))
  272. ipu_dc_put(ipu_crtc->dc);
  273. if (!IS_ERR_OR_NULL(ipu_crtc->di))
  274. ipu_di_put(ipu_crtc->di);
  275. }
  276. static int ipu_get_resources(struct drm_device *dev, struct ipu_crtc *ipu_crtc,
  277. struct ipu_client_platformdata *pdata)
  278. {
  279. struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
  280. int ret;
  281. ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
  282. if (IS_ERR(ipu_crtc->dc))
  283. return PTR_ERR(ipu_crtc->dc);
  284. ret = drmm_add_action_or_reset(dev, ipu_put_resources, ipu_crtc);
  285. if (ret)
  286. return ret;
  287. ipu_crtc->di = ipu_di_get(ipu, pdata->di);
  288. if (IS_ERR(ipu_crtc->di))
  289. return PTR_ERR(ipu_crtc->di);
  290. return 0;
  291. }
  292. static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
  293. {
  294. struct ipu_client_platformdata *pdata = dev->platform_data;
  295. struct ipu_soc *ipu = dev_get_drvdata(dev->parent);
  296. struct drm_device *drm = data;
  297. struct ipu_plane *primary_plane;
  298. struct ipu_crtc *ipu_crtc;
  299. struct drm_crtc *crtc;
  300. int dp = -EINVAL;
  301. int ret;
  302. if (pdata->dp >= 0)
  303. dp = IPU_DP_FLOW_SYNC_BG;
  304. primary_plane = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0,
  305. DRM_PLANE_TYPE_PRIMARY);
  306. if (IS_ERR(primary_plane))
  307. return PTR_ERR(primary_plane);
  308. ipu_crtc = drmm_crtc_alloc_with_planes(drm, struct ipu_crtc, base,
  309. &primary_plane->base, NULL,
  310. &ipu_crtc_funcs, NULL);
  311. if (IS_ERR(ipu_crtc))
  312. return PTR_ERR(ipu_crtc);
  313. ipu_crtc->dev = dev;
  314. ipu_crtc->plane[0] = primary_plane;
  315. crtc = &ipu_crtc->base;
  316. crtc->port = pdata->of_node;
  317. drm_crtc_helper_add(crtc, &ipu_helper_funcs);
  318. ret = ipu_get_resources(drm, ipu_crtc, pdata);
  319. if (ret) {
  320. dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
  321. ret);
  322. return ret;
  323. }
  324. /* If this crtc is using the DP, add an overlay plane */
  325. if (pdata->dp >= 0 && pdata->dma[1] > 0) {
  326. ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1],
  327. IPU_DP_FLOW_SYNC_FG,
  328. drm_crtc_mask(&ipu_crtc->base),
  329. DRM_PLANE_TYPE_OVERLAY);
  330. if (IS_ERR(ipu_crtc->plane[1]))
  331. ipu_crtc->plane[1] = NULL;
  332. }
  333. ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
  334. ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler,
  335. IRQF_NO_AUTOEN, "imx_drm", ipu_crtc);
  336. if (ret < 0) {
  337. dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
  338. return ret;
  339. }
  340. return 0;
  341. }
  342. static const struct component_ops ipu_crtc_ops = {
  343. .bind = ipu_drm_bind,
  344. };
  345. static int ipu_drm_probe(struct platform_device *pdev)
  346. {
  347. struct device *dev = &pdev->dev;
  348. int ret;
  349. if (!dev->platform_data)
  350. return -EINVAL;
  351. ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
  352. if (ret)
  353. return ret;
  354. return component_add(dev, &ipu_crtc_ops);
  355. }
  356. static void ipu_drm_remove(struct platform_device *pdev)
  357. {
  358. component_del(&pdev->dev, &ipu_crtc_ops);
  359. }
  360. struct platform_driver ipu_drm_driver = {
  361. .driver = {
  362. .name = "imx-ipuv3-crtc",
  363. },
  364. .probe = ipu_drm_probe,
  365. .remove = ipu_drm_remove,
  366. };