omap_crtc.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. /*
  2. * drivers/gpu/drm/omapdrm/omap_crtc.c
  3. *
  4. * Copyright (C) 2011 Texas Instruments
  5. * Author: Rob Clark <rob@ti.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License version 2 as published by
  9. * the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along with
  17. * this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <linux/completion.h>
  20. #include <drm/drm_atomic.h>
  21. #include <drm/drm_atomic_helper.h>
  22. #include <drm/drm_crtc.h>
  23. #include <drm/drm_crtc_helper.h>
  24. #include <drm/drm_mode.h>
  25. #include <drm/drm_plane_helper.h>
  26. #include "omap_drv.h"
  27. #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
  28. enum omap_page_flip_state {
  29. OMAP_PAGE_FLIP_IDLE,
  30. OMAP_PAGE_FLIP_WAIT,
  31. OMAP_PAGE_FLIP_QUEUED,
  32. OMAP_PAGE_FLIP_CANCELLED,
  33. };
  34. struct omap_crtc {
  35. struct drm_crtc base;
  36. const char *name;
  37. int pipe;
  38. enum omap_channel channel;
  39. struct omap_overlay_manager_info info;
  40. struct drm_encoder *current_encoder;
  41. /*
  42. * Temporary: eventually this will go away, but it is needed
  43. * for now to keep the output's happy. (They only need
  44. * mgr->id.) Eventually this will be replaced w/ something
  45. * more common-panel-framework-y
  46. */
  47. struct omap_overlay_manager *mgr;
  48. struct omap_video_timings timings;
  49. bool enabled;
  50. struct omap_drm_irq vblank_irq;
  51. struct omap_drm_irq error_irq;
  52. /* list of framebuffers to unpin */
  53. struct list_head pending_unpins;
  54. /*
  55. * flip_state flag indicates the current page flap state: IDLE if no
  56. * page queue has been submitted, WAIT when waiting for GEM async
  57. * completion, QUEUED when the page flip has been queued to the hardware
  58. * or CANCELLED when the CRTC is turned off before the flip gets queued
  59. * to the hardware. The flip event, if any, is stored in flip_event, and
  60. * the framebuffer queued for page flip is stored in flip_fb. The
  61. * flip_wait wait queue is used to wait for page flip completion.
  62. *
  63. * The flip_work work queue handles page flip requests without caring
  64. * about what context the GEM async callback is called from. Possibly we
  65. * should just make omap_gem always call the cb from the worker so we
  66. * don't have to care about this.
  67. */
  68. enum omap_page_flip_state flip_state;
  69. struct drm_pending_vblank_event *flip_event;
  70. struct drm_framebuffer *flip_fb;
  71. wait_queue_head_t flip_wait;
  72. struct work_struct flip_work;
  73. struct completion completion;
  74. bool ignore_digit_sync_lost;
  75. };
  76. struct omap_framebuffer_unpin {
  77. struct list_head list;
  78. struct drm_framebuffer *fb;
  79. };
  80. /* -----------------------------------------------------------------------------
  81. * Helper Functions
  82. */
  83. uint32_t pipe2vbl(struct drm_crtc *crtc)
  84. {
  85. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  86. return dispc_mgr_get_vsync_irq(omap_crtc->channel);
  87. }
  88. const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc)
  89. {
  90. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  91. return &omap_crtc->timings;
  92. }
  93. enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
  94. {
  95. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  96. return omap_crtc->channel;
  97. }
  98. /* -----------------------------------------------------------------------------
  99. * DSS Manager Functions
  100. */
  101. /*
  102. * Manager-ops, callbacks from output when they need to configure
  103. * the upstream part of the video pipe.
  104. *
  105. * Most of these we can ignore until we add support for command-mode
  106. * panels.. for video-mode the crtc-helpers already do an adequate
  107. * job of sequencing the setup of the video pipe in the proper order
  108. */
  109. /* ovl-mgr-id -> crtc */
  110. static struct omap_crtc *omap_crtcs[8];
  111. /* we can probably ignore these until we support command-mode panels: */
  112. static int omap_crtc_dss_connect(struct omap_overlay_manager *mgr,
  113. struct omap_dss_device *dst)
  114. {
  115. if (mgr->output)
  116. return -EINVAL;
  117. if ((mgr->supported_outputs & dst->id) == 0)
  118. return -EINVAL;
  119. dst->manager = mgr;
  120. mgr->output = dst;
  121. return 0;
  122. }
  123. static void omap_crtc_dss_disconnect(struct omap_overlay_manager *mgr,
  124. struct omap_dss_device *dst)
  125. {
  126. mgr->output->manager = NULL;
  127. mgr->output = NULL;
  128. }
  129. static void omap_crtc_dss_start_update(struct omap_overlay_manager *mgr)
  130. {
  131. }
  132. /* Called only from omap_crtc_setup and suspend/resume handlers. */
  133. static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
  134. {
  135. struct drm_device *dev = crtc->dev;
  136. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  137. enum omap_channel channel = omap_crtc->channel;
  138. struct omap_irq_wait *wait;
  139. u32 framedone_irq, vsync_irq;
  140. int ret;
  141. if (dispc_mgr_is_enabled(channel) == enable)
  142. return;
  143. if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
  144. /*
  145. * Digit output produces some sync lost interrupts during the
  146. * first frame when enabling, so we need to ignore those.
  147. */
  148. omap_crtc->ignore_digit_sync_lost = true;
  149. }
  150. framedone_irq = dispc_mgr_get_framedone_irq(channel);
  151. vsync_irq = dispc_mgr_get_vsync_irq(channel);
  152. if (enable) {
  153. wait = omap_irq_wait_init(dev, vsync_irq, 1);
  154. } else {
  155. /*
  156. * When we disable the digit output, we need to wait for
  157. * FRAMEDONE to know that DISPC has finished with the output.
  158. *
  159. * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
  160. * that case we need to use vsync interrupt, and wait for both
  161. * even and odd frames.
  162. */
  163. if (framedone_irq)
  164. wait = omap_irq_wait_init(dev, framedone_irq, 1);
  165. else
  166. wait = omap_irq_wait_init(dev, vsync_irq, 2);
  167. }
  168. dispc_mgr_enable(channel, enable);
  169. ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
  170. if (ret) {
  171. dev_err(dev->dev, "%s: timeout waiting for %s\n",
  172. omap_crtc->name, enable ? "enable" : "disable");
  173. }
  174. if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
  175. omap_crtc->ignore_digit_sync_lost = false;
  176. /* make sure the irq handler sees the value above */
  177. mb();
  178. }
  179. }
  180. static int omap_crtc_dss_enable(struct omap_overlay_manager *mgr)
  181. {
  182. struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
  183. dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
  184. dispc_mgr_set_timings(omap_crtc->channel,
  185. &omap_crtc->timings);
  186. omap_crtc_set_enabled(&omap_crtc->base, true);
  187. return 0;
  188. }
  189. static void omap_crtc_dss_disable(struct omap_overlay_manager *mgr)
  190. {
  191. struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
  192. omap_crtc_set_enabled(&omap_crtc->base, false);
  193. }
  194. static void omap_crtc_dss_set_timings(struct omap_overlay_manager *mgr,
  195. const struct omap_video_timings *timings)
  196. {
  197. struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
  198. DBG("%s", omap_crtc->name);
  199. omap_crtc->timings = *timings;
  200. }
  201. static void omap_crtc_dss_set_lcd_config(struct omap_overlay_manager *mgr,
  202. const struct dss_lcd_mgr_config *config)
  203. {
  204. struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
  205. DBG("%s", omap_crtc->name);
  206. dispc_mgr_set_lcd_config(omap_crtc->channel, config);
  207. }
  208. static int omap_crtc_dss_register_framedone(
  209. struct omap_overlay_manager *mgr,
  210. void (*handler)(void *), void *data)
  211. {
  212. return 0;
  213. }
  214. static void omap_crtc_dss_unregister_framedone(
  215. struct omap_overlay_manager *mgr,
  216. void (*handler)(void *), void *data)
  217. {
  218. }
  219. static const struct dss_mgr_ops mgr_ops = {
  220. .connect = omap_crtc_dss_connect,
  221. .disconnect = omap_crtc_dss_disconnect,
  222. .start_update = omap_crtc_dss_start_update,
  223. .enable = omap_crtc_dss_enable,
  224. .disable = omap_crtc_dss_disable,
  225. .set_timings = omap_crtc_dss_set_timings,
  226. .set_lcd_config = omap_crtc_dss_set_lcd_config,
  227. .register_framedone_handler = omap_crtc_dss_register_framedone,
  228. .unregister_framedone_handler = omap_crtc_dss_unregister_framedone,
  229. };
  230. /* -----------------------------------------------------------------------------
  231. * Setup, Flush and Page Flip
  232. */
  233. void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
  234. {
  235. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  236. struct drm_device *dev = crtc->dev;
  237. unsigned long flags;
  238. spin_lock_irqsave(&dev->event_lock, flags);
  239. /* Only complete events queued for our file handle. */
  240. if (omap_crtc->flip_event &&
  241. file == omap_crtc->flip_event->base.file_priv) {
  242. drm_send_vblank_event(dev, omap_crtc->pipe,
  243. omap_crtc->flip_event);
  244. omap_crtc->flip_event = NULL;
  245. }
  246. spin_unlock_irqrestore(&dev->event_lock, flags);
  247. }
  248. /* Must be called with dev->event_lock locked. */
  249. static void omap_crtc_complete_page_flip(struct drm_crtc *crtc,
  250. enum omap_page_flip_state state)
  251. {
  252. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  253. struct drm_device *dev = crtc->dev;
  254. if (omap_crtc->flip_event) {
  255. drm_send_vblank_event(dev, omap_crtc->pipe,
  256. omap_crtc->flip_event);
  257. omap_crtc->flip_event = NULL;
  258. }
  259. omap_crtc->flip_state = state;
  260. if (state == OMAP_PAGE_FLIP_IDLE)
  261. wake_up(&omap_crtc->flip_wait);
  262. }
  263. static bool omap_crtc_page_flip_pending(struct drm_crtc *crtc)
  264. {
  265. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  266. struct drm_device *dev = crtc->dev;
  267. unsigned long flags;
  268. bool pending;
  269. spin_lock_irqsave(&dev->event_lock, flags);
  270. pending = omap_crtc->flip_state != OMAP_PAGE_FLIP_IDLE;
  271. spin_unlock_irqrestore(&dev->event_lock, flags);
  272. return pending;
  273. }
  274. static void omap_crtc_wait_page_flip(struct drm_crtc *crtc)
  275. {
  276. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  277. struct drm_device *dev = crtc->dev;
  278. bool cancelled = false;
  279. unsigned long flags;
  280. /*
  281. * If we're still waiting for the GEM async operation to complete just
  282. * cancel the page flip, as we're holding the CRTC mutex preventing the
  283. * page flip work handler from queueing the page flip.
  284. *
  285. * We can't release the reference to the frame buffer here as the async
  286. * operation doesn't keep its own reference to the buffer. We'll just
  287. * let the page flip work queue handle that.
  288. */
  289. spin_lock_irqsave(&dev->event_lock, flags);
  290. if (omap_crtc->flip_state == OMAP_PAGE_FLIP_WAIT) {
  291. omap_crtc_complete_page_flip(crtc, OMAP_PAGE_FLIP_CANCELLED);
  292. cancelled = true;
  293. }
  294. spin_unlock_irqrestore(&dev->event_lock, flags);
  295. if (cancelled)
  296. return;
  297. if (wait_event_timeout(omap_crtc->flip_wait,
  298. !omap_crtc_page_flip_pending(crtc),
  299. msecs_to_jiffies(50)))
  300. return;
  301. dev_warn(crtc->dev->dev, "page flip timeout!\n");
  302. spin_lock_irqsave(&dev->event_lock, flags);
  303. omap_crtc_complete_page_flip(crtc, OMAP_PAGE_FLIP_IDLE);
  304. spin_unlock_irqrestore(&dev->event_lock, flags);
  305. }
  306. static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
  307. {
  308. struct omap_crtc *omap_crtc =
  309. container_of(irq, struct omap_crtc, error_irq);
  310. if (omap_crtc->ignore_digit_sync_lost) {
  311. irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
  312. if (!irqstatus)
  313. return;
  314. }
  315. DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
  316. }
  317. static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
  318. {
  319. struct omap_crtc *omap_crtc =
  320. container_of(irq, struct omap_crtc, vblank_irq);
  321. struct drm_device *dev = omap_crtc->base.dev;
  322. unsigned long flags;
  323. if (dispc_mgr_go_busy(omap_crtc->channel))
  324. return;
  325. DBG("%s: apply done", omap_crtc->name);
  326. __omap_irq_unregister(dev, &omap_crtc->vblank_irq);
  327. /* wakeup userspace */
  328. spin_lock_irqsave(&dev->event_lock, flags);
  329. omap_crtc_complete_page_flip(&omap_crtc->base, OMAP_PAGE_FLIP_IDLE);
  330. spin_unlock_irqrestore(&dev->event_lock, flags);
  331. complete(&omap_crtc->completion);
  332. }
  333. int omap_crtc_flush(struct drm_crtc *crtc)
  334. {
  335. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  336. struct omap_framebuffer_unpin *fb, *next;
  337. DBG("%s: GO", omap_crtc->name);
  338. WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
  339. WARN_ON(omap_crtc->vblank_irq.registered);
  340. dispc_runtime_get();
  341. if (dispc_mgr_is_enabled(omap_crtc->channel)) {
  342. dispc_mgr_go(omap_crtc->channel);
  343. omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
  344. WARN_ON(!wait_for_completion_timeout(&omap_crtc->completion,
  345. msecs_to_jiffies(100)));
  346. reinit_completion(&omap_crtc->completion);
  347. }
  348. dispc_runtime_put();
  349. /* Unpin and unreference pending framebuffers. */
  350. list_for_each_entry_safe(fb, next, &omap_crtc->pending_unpins, list) {
  351. omap_framebuffer_unpin(fb->fb);
  352. drm_framebuffer_unreference(fb->fb);
  353. list_del(&fb->list);
  354. kfree(fb);
  355. }
  356. return 0;
  357. }
  358. int omap_crtc_queue_unpin(struct drm_crtc *crtc, struct drm_framebuffer *fb)
  359. {
  360. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  361. struct omap_framebuffer_unpin *unpin;
  362. unpin = kzalloc(sizeof(*unpin), GFP_KERNEL);
  363. if (!unpin)
  364. return -ENOMEM;
  365. unpin->fb = fb;
  366. list_add_tail(&unpin->list, &omap_crtc->pending_unpins);
  367. return 0;
  368. }
  369. static void omap_crtc_setup(struct drm_crtc *crtc)
  370. {
  371. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  372. struct omap_drm_private *priv = crtc->dev->dev_private;
  373. struct drm_encoder *encoder = NULL;
  374. unsigned int i;
  375. DBG("%s: enabled=%d", omap_crtc->name, omap_crtc->enabled);
  376. dispc_runtime_get();
  377. for (i = 0; i < priv->num_encoders; i++) {
  378. if (priv->encoders[i]->crtc == crtc) {
  379. encoder = priv->encoders[i];
  380. break;
  381. }
  382. }
  383. if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder)
  384. omap_encoder_set_enabled(omap_crtc->current_encoder, false);
  385. omap_crtc->current_encoder = encoder;
  386. if (!omap_crtc->enabled) {
  387. if (encoder)
  388. omap_encoder_set_enabled(encoder, false);
  389. } else {
  390. if (encoder) {
  391. omap_encoder_set_enabled(encoder, false);
  392. omap_encoder_update(encoder, omap_crtc->mgr,
  393. &omap_crtc->timings);
  394. omap_encoder_set_enabled(encoder, true);
  395. }
  396. }
  397. dispc_runtime_put();
  398. }
  399. /* -----------------------------------------------------------------------------
  400. * CRTC Functions
  401. */
  402. static void omap_crtc_destroy(struct drm_crtc *crtc)
  403. {
  404. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  405. DBG("%s", omap_crtc->name);
  406. WARN_ON(omap_crtc->vblank_irq.registered);
  407. omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
  408. drm_crtc_cleanup(crtc);
  409. kfree(omap_crtc);
  410. }
  411. static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,
  412. const struct drm_display_mode *mode,
  413. struct drm_display_mode *adjusted_mode)
  414. {
  415. return true;
  416. }
  417. static void omap_crtc_enable(struct drm_crtc *crtc)
  418. {
  419. struct omap_drm_private *priv = crtc->dev->dev_private;
  420. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  421. unsigned int i;
  422. DBG("%s", omap_crtc->name);
  423. if (omap_crtc->enabled)
  424. return;
  425. /* Enable all planes associated with the CRTC. */
  426. for (i = 0; i < priv->num_planes; i++) {
  427. struct drm_plane *plane = priv->planes[i];
  428. if (plane->crtc == crtc)
  429. WARN_ON(omap_plane_set_enable(plane, true));
  430. }
  431. omap_crtc->enabled = true;
  432. omap_crtc_setup(crtc);
  433. omap_crtc_flush(crtc);
  434. dispc_runtime_get();
  435. drm_crtc_vblank_on(crtc);
  436. dispc_runtime_put();
  437. }
  438. static void omap_crtc_disable(struct drm_crtc *crtc)
  439. {
  440. struct omap_drm_private *priv = crtc->dev->dev_private;
  441. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  442. unsigned int i;
  443. DBG("%s", omap_crtc->name);
  444. if (!omap_crtc->enabled)
  445. return;
  446. omap_crtc_wait_page_flip(crtc);
  447. dispc_runtime_get();
  448. drm_crtc_vblank_off(crtc);
  449. dispc_runtime_put();
  450. /* Disable all planes associated with the CRTC. */
  451. for (i = 0; i < priv->num_planes; i++) {
  452. struct drm_plane *plane = priv->planes[i];
  453. if (plane->crtc == crtc)
  454. WARN_ON(omap_plane_set_enable(plane, false));
  455. }
  456. omap_crtc->enabled = false;
  457. omap_crtc_setup(crtc);
  458. omap_crtc_flush(crtc);
  459. }
  460. static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
  461. {
  462. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  463. struct drm_display_mode *mode = &crtc->state->adjusted_mode;
  464. DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
  465. omap_crtc->name, mode->base.id, mode->name,
  466. mode->vrefresh, mode->clock,
  467. mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
  468. mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
  469. mode->type, mode->flags);
  470. copy_timings_drm_to_omap(&omap_crtc->timings, mode);
  471. }
  472. static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
  473. {
  474. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  475. bool enable = (mode == DRM_MODE_DPMS_ON);
  476. DBG("%s: %d", omap_crtc->name, mode);
  477. if (enable)
  478. omap_crtc_enable(crtc);
  479. else
  480. omap_crtc_disable(crtc);
  481. }
  482. static void omap_crtc_atomic_begin(struct drm_crtc *crtc)
  483. {
  484. dispc_runtime_get();
  485. }
  486. static void omap_crtc_atomic_flush(struct drm_crtc *crtc)
  487. {
  488. omap_crtc_flush(crtc);
  489. dispc_runtime_put();
  490. }
  491. static void page_flip_worker(struct work_struct *work)
  492. {
  493. struct omap_crtc *omap_crtc =
  494. container_of(work, struct omap_crtc, flip_work);
  495. struct drm_crtc *crtc = &omap_crtc->base;
  496. struct drm_display_mode *mode = &crtc->mode;
  497. struct drm_device *dev = crtc->dev;
  498. struct drm_framebuffer *fb;
  499. struct drm_gem_object *bo;
  500. unsigned long flags;
  501. bool queue_flip;
  502. drm_modeset_lock(&crtc->mutex, NULL);
  503. spin_lock_irqsave(&dev->event_lock, flags);
  504. /*
  505. * The page flip could have been cancelled while waiting for the GEM
  506. * async operation to complete. Don't queue the flip in that case.
  507. */
  508. if (omap_crtc->flip_state == OMAP_PAGE_FLIP_WAIT) {
  509. omap_crtc->flip_state = OMAP_PAGE_FLIP_QUEUED;
  510. queue_flip = true;
  511. } else {
  512. omap_crtc->flip_state = OMAP_PAGE_FLIP_IDLE;
  513. queue_flip = false;
  514. }
  515. fb = omap_crtc->flip_fb;
  516. omap_crtc->flip_fb = NULL;
  517. spin_unlock_irqrestore(&dev->event_lock, flags);
  518. if (queue_flip) {
  519. omap_plane_mode_set(crtc->primary, crtc, fb,
  520. 0, 0, mode->hdisplay, mode->vdisplay,
  521. crtc->x, crtc->y, mode->hdisplay,
  522. mode->vdisplay);
  523. omap_crtc_flush(crtc);
  524. }
  525. drm_modeset_unlock(&crtc->mutex);
  526. bo = omap_framebuffer_bo(fb, 0);
  527. drm_gem_object_unreference_unlocked(bo);
  528. drm_framebuffer_unreference(fb);
  529. }
  530. static void page_flip_cb(void *arg)
  531. {
  532. struct drm_crtc *crtc = arg;
  533. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  534. struct omap_drm_private *priv = crtc->dev->dev_private;
  535. /* avoid assumptions about what ctxt we are called from: */
  536. queue_work(priv->wq, &omap_crtc->flip_work);
  537. }
  538. static int omap_crtc_page_flip(struct drm_crtc *crtc,
  539. struct drm_framebuffer *fb,
  540. struct drm_pending_vblank_event *event,
  541. uint32_t page_flip_flags)
  542. {
  543. struct drm_device *dev = crtc->dev;
  544. struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  545. struct drm_plane *primary = crtc->primary;
  546. struct drm_gem_object *bo;
  547. unsigned long flags;
  548. DBG("%d -> %d (event=%p)", primary->fb ? primary->fb->base.id : -1,
  549. fb->base.id, event);
  550. spin_lock_irqsave(&dev->event_lock, flags);
  551. if (omap_crtc->flip_state != OMAP_PAGE_FLIP_IDLE) {
  552. spin_unlock_irqrestore(&dev->event_lock, flags);
  553. dev_err(dev->dev, "already a pending flip\n");
  554. return -EBUSY;
  555. }
  556. /*
  557. * Store a reference to the framebuffer queued for page flip in the CRTC
  558. * private structure. We can't rely on crtc->primary->fb in the page
  559. * flip worker, as a racing CRTC disable (due for instance to an
  560. * explicit framebuffer deletion from userspace) would set that field to
  561. * NULL before the worker gets a change to run.
  562. */
  563. drm_framebuffer_reference(fb);
  564. omap_crtc->flip_fb = fb;
  565. omap_crtc->flip_event = event;
  566. omap_crtc->flip_state = OMAP_PAGE_FLIP_WAIT;
  567. drm_atomic_set_fb_for_plane(primary->state, fb);
  568. primary->fb = fb;
  569. spin_unlock_irqrestore(&dev->event_lock, flags);
  570. /*
  571. * Hold a reference temporarily until the crtc is updated
  572. * and takes the reference to the bo. This avoids it
  573. * getting freed from under us:
  574. */
  575. bo = omap_framebuffer_bo(fb, 0);
  576. drm_gem_object_reference(bo);
  577. omap_gem_op_async(bo, OMAP_GEM_READ, page_flip_cb, crtc);
  578. return 0;
  579. }
  580. static int omap_crtc_set_property(struct drm_crtc *crtc,
  581. struct drm_property *property, uint64_t val)
  582. {
  583. if (property == crtc->dev->mode_config.rotation_property) {
  584. crtc->invert_dimensions =
  585. !!(val & ((1LL << DRM_ROTATE_90) | (1LL << DRM_ROTATE_270)));
  586. }
  587. return omap_plane_set_property(crtc->primary, property, val);
  588. }
  589. static const struct drm_crtc_funcs omap_crtc_funcs = {
  590. .reset = drm_atomic_helper_crtc_reset,
  591. .set_config = drm_atomic_helper_set_config,
  592. .destroy = omap_crtc_destroy,
  593. .page_flip = omap_crtc_page_flip,
  594. .set_property = omap_crtc_set_property,
  595. .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
  596. .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
  597. };
  598. static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
  599. .dpms = omap_crtc_dpms,
  600. .mode_fixup = omap_crtc_mode_fixup,
  601. .mode_set_nofb = omap_crtc_mode_set_nofb,
  602. .disable = omap_crtc_disable,
  603. .enable = omap_crtc_enable,
  604. .atomic_begin = omap_crtc_atomic_begin,
  605. .atomic_flush = omap_crtc_atomic_flush,
  606. };
  607. /* -----------------------------------------------------------------------------
  608. * Init and Cleanup
  609. */
  610. static const char *channel_names[] = {
  611. [OMAP_DSS_CHANNEL_LCD] = "lcd",
  612. [OMAP_DSS_CHANNEL_DIGIT] = "tv",
  613. [OMAP_DSS_CHANNEL_LCD2] = "lcd2",
  614. [OMAP_DSS_CHANNEL_LCD3] = "lcd3",
  615. };
  616. void omap_crtc_pre_init(void)
  617. {
  618. dss_install_mgr_ops(&mgr_ops);
  619. }
  620. void omap_crtc_pre_uninit(void)
  621. {
  622. dss_uninstall_mgr_ops();
  623. }
  624. /* initialize crtc */
  625. struct drm_crtc *omap_crtc_init(struct drm_device *dev,
  626. struct drm_plane *plane, enum omap_channel channel, int id)
  627. {
  628. struct drm_crtc *crtc = NULL;
  629. struct omap_crtc *omap_crtc;
  630. struct omap_overlay_manager_info *info;
  631. int ret;
  632. DBG("%s", channel_names[channel]);
  633. omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
  634. if (!omap_crtc)
  635. return NULL;
  636. crtc = &omap_crtc->base;
  637. INIT_WORK(&omap_crtc->flip_work, page_flip_worker);
  638. init_waitqueue_head(&omap_crtc->flip_wait);
  639. INIT_LIST_HEAD(&omap_crtc->pending_unpins);
  640. init_completion(&omap_crtc->completion);
  641. omap_crtc->channel = channel;
  642. omap_crtc->name = channel_names[channel];
  643. omap_crtc->pipe = id;
  644. omap_crtc->vblank_irq.irqmask = pipe2vbl(crtc);
  645. omap_crtc->vblank_irq.irq = omap_crtc_vblank_irq;
  646. omap_crtc->error_irq.irqmask =
  647. dispc_mgr_get_sync_lost_irq(channel);
  648. omap_crtc->error_irq.irq = omap_crtc_error_irq;
  649. omap_irq_register(dev, &omap_crtc->error_irq);
  650. /* temporary: */
  651. omap_crtc->mgr = omap_dss_get_overlay_manager(channel);
  652. /* TODO: fix hard-coded setup.. add properties! */
  653. info = &omap_crtc->info;
  654. info->default_color = 0x00000000;
  655. info->trans_key = 0x00000000;
  656. info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
  657. info->trans_enabled = false;
  658. ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
  659. &omap_crtc_funcs);
  660. if (ret < 0) {
  661. kfree(omap_crtc);
  662. return NULL;
  663. }
  664. drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
  665. omap_plane_install_properties(crtc->primary, &crtc->base);
  666. omap_crtcs[channel] = omap_crtc;
  667. return crtc;
  668. }