sun4i_crtc.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Copyright (C) 2015 Free Electrons
  3. * Copyright (C) 2015 NextThing Co
  4. *
  5. * Maxime Ripard <maxime.ripard@free-electrons.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. */
  12. #include <drm/drmP.h>
  13. #include <drm/drm_atomic_helper.h>
  14. #include <drm/drm_crtc.h>
  15. #include <drm/drm_crtc_helper.h>
  16. #include <drm/drm_modes.h>
  17. #include <linux/clk-provider.h>
  18. #include <linux/ioport.h>
  19. #include <linux/of_address.h>
  20. #include <linux/of_irq.h>
  21. #include <linux/regmap.h>
  22. #include <video/videomode.h>
  23. #include "sun4i_backend.h"
  24. #include "sun4i_crtc.h"
  25. #include "sun4i_drv.h"
  26. #include "sun4i_tcon.h"
  27. static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
  28. struct drm_crtc_state *old_state)
  29. {
  30. struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
  31. struct drm_device *dev = crtc->dev;
  32. unsigned long flags;
  33. if (crtc->state->event) {
  34. WARN_ON(drm_crtc_vblank_get(crtc) != 0);
  35. spin_lock_irqsave(&dev->event_lock, flags);
  36. scrtc->event = crtc->state->event;
  37. spin_unlock_irqrestore(&dev->event_lock, flags);
  38. crtc->state->event = NULL;
  39. }
  40. }
  41. static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
  42. struct drm_crtc_state *old_state)
  43. {
  44. struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
  45. struct sun4i_drv *drv = scrtc->drv;
  46. DRM_DEBUG_DRIVER("Committing plane changes\n");
  47. sun4i_backend_commit(drv->backend);
  48. }
  49. static void sun4i_crtc_disable(struct drm_crtc *crtc)
  50. {
  51. struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
  52. struct sun4i_drv *drv = scrtc->drv;
  53. DRM_DEBUG_DRIVER("Disabling the CRTC\n");
  54. sun4i_tcon_disable(drv->tcon);
  55. }
  56. static void sun4i_crtc_enable(struct drm_crtc *crtc)
  57. {
  58. struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
  59. struct sun4i_drv *drv = scrtc->drv;
  60. DRM_DEBUG_DRIVER("Enabling the CRTC\n");
  61. sun4i_tcon_enable(drv->tcon);
  62. }
  63. static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = {
  64. .atomic_begin = sun4i_crtc_atomic_begin,
  65. .atomic_flush = sun4i_crtc_atomic_flush,
  66. .disable = sun4i_crtc_disable,
  67. .enable = sun4i_crtc_enable,
  68. };
  69. static const struct drm_crtc_funcs sun4i_crtc_funcs = {
  70. .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
  71. .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
  72. .destroy = drm_crtc_cleanup,
  73. .page_flip = drm_atomic_helper_page_flip,
  74. .reset = drm_atomic_helper_crtc_reset,
  75. .set_config = drm_atomic_helper_set_config,
  76. };
  77. struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm)
  78. {
  79. struct sun4i_drv *drv = drm->dev_private;
  80. struct sun4i_crtc *scrtc;
  81. int ret;
  82. scrtc = devm_kzalloc(drm->dev, sizeof(*scrtc), GFP_KERNEL);
  83. if (!scrtc)
  84. return NULL;
  85. scrtc->drv = drv;
  86. ret = drm_crtc_init_with_planes(drm, &scrtc->crtc,
  87. drv->primary,
  88. NULL,
  89. &sun4i_crtc_funcs,
  90. NULL);
  91. if (ret) {
  92. dev_err(drm->dev, "Couldn't init DRM CRTC\n");
  93. return NULL;
  94. }
  95. drm_crtc_helper_add(&scrtc->crtc, &sun4i_crtc_helper_funcs);
  96. return scrtc;
  97. }