exynos_drm_encoder.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* exynos_drm_encoder.c
  2. *
  3. * Copyright (c) 2011 Samsung Electronics Co., Ltd.
  4. * Authors:
  5. * Inki Dae <inki.dae@samsung.com>
  6. * Joonyoung Shim <jy0922.shim@samsung.com>
  7. * Seung-Woo Kim <sw0312.kim@samsung.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the
  11. * Free Software Foundation; either version 2 of the License, or (at your
  12. * option) any later version.
  13. */
  14. #include <drm/drmP.h>
  15. #include <drm/drm_crtc_helper.h>
  16. #include "exynos_drm_drv.h"
  17. #include "exynos_drm_encoder.h"
  18. #define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\
  19. drm_encoder)
  20. /*
  21. * exynos specific encoder structure.
  22. *
  23. * @drm_encoder: encoder object.
  24. * @display: the display structure that maps to this encoder
  25. */
  26. struct exynos_drm_encoder {
  27. struct drm_encoder drm_encoder;
  28. struct exynos_drm_display *display;
  29. };
  30. static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
  31. {
  32. struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
  33. struct exynos_drm_display *display = exynos_encoder->display;
  34. DRM_DEBUG_KMS("encoder dpms: %d\n", mode);
  35. if (display->ops->dpms)
  36. display->ops->dpms(display, mode);
  37. }
  38. static bool
  39. exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
  40. const struct drm_display_mode *mode,
  41. struct drm_display_mode *adjusted_mode)
  42. {
  43. struct drm_device *dev = encoder->dev;
  44. struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
  45. struct exynos_drm_display *display = exynos_encoder->display;
  46. struct drm_connector *connector;
  47. list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  48. if (connector->encoder != encoder)
  49. continue;
  50. if (display->ops->mode_fixup)
  51. display->ops->mode_fixup(display, connector, mode,
  52. adjusted_mode);
  53. }
  54. return true;
  55. }
  56. static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
  57. struct drm_display_mode *mode,
  58. struct drm_display_mode *adjusted_mode)
  59. {
  60. struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
  61. struct exynos_drm_display *display = exynos_encoder->display;
  62. if (display->ops->mode_set)
  63. display->ops->mode_set(display, adjusted_mode);
  64. }
  65. static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)
  66. {
  67. /* drm framework doesn't check NULL. */
  68. }
  69. static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
  70. {
  71. struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
  72. struct exynos_drm_display *display = exynos_encoder->display;
  73. if (display->ops->dpms)
  74. display->ops->dpms(display, DRM_MODE_DPMS_ON);
  75. if (display->ops->commit)
  76. display->ops->commit(display);
  77. }
  78. static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
  79. {
  80. struct drm_plane *plane;
  81. struct drm_device *dev = encoder->dev;
  82. exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
  83. /* all planes connected to this encoder should be also disabled. */
  84. drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
  85. if (plane->crtc && (plane->crtc == encoder->crtc))
  86. plane->funcs->disable_plane(plane);
  87. }
  88. }
  89. static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
  90. .dpms = exynos_drm_encoder_dpms,
  91. .mode_fixup = exynos_drm_encoder_mode_fixup,
  92. .mode_set = exynos_drm_encoder_mode_set,
  93. .prepare = exynos_drm_encoder_prepare,
  94. .commit = exynos_drm_encoder_commit,
  95. .disable = exynos_drm_encoder_disable,
  96. };
  97. static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
  98. {
  99. struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
  100. drm_encoder_cleanup(encoder);
  101. kfree(exynos_encoder);
  102. }
  103. static struct drm_encoder_funcs exynos_encoder_funcs = {
  104. .destroy = exynos_drm_encoder_destroy,
  105. };
  106. static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
  107. {
  108. struct drm_encoder *clone;
  109. struct drm_device *dev = encoder->dev;
  110. struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
  111. struct exynos_drm_display *display = exynos_encoder->display;
  112. unsigned int clone_mask = 0;
  113. int cnt = 0;
  114. list_for_each_entry(clone, &dev->mode_config.encoder_list, head) {
  115. switch (display->type) {
  116. case EXYNOS_DISPLAY_TYPE_LCD:
  117. case EXYNOS_DISPLAY_TYPE_HDMI:
  118. case EXYNOS_DISPLAY_TYPE_VIDI:
  119. clone_mask |= (1 << (cnt++));
  120. break;
  121. default:
  122. continue;
  123. }
  124. }
  125. return clone_mask;
  126. }
  127. void exynos_drm_encoder_setup(struct drm_device *dev)
  128. {
  129. struct drm_encoder *encoder;
  130. list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
  131. encoder->possible_clones = exynos_drm_encoder_clones(encoder);
  132. }
  133. struct drm_encoder *
  134. exynos_drm_encoder_create(struct drm_device *dev,
  135. struct exynos_drm_display *display,
  136. unsigned long possible_crtcs)
  137. {
  138. struct drm_encoder *encoder;
  139. struct exynos_drm_encoder *exynos_encoder;
  140. if (!possible_crtcs)
  141. return NULL;
  142. exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL);
  143. if (!exynos_encoder)
  144. return NULL;
  145. exynos_encoder->display = display;
  146. encoder = &exynos_encoder->drm_encoder;
  147. encoder->possible_crtcs = possible_crtcs;
  148. DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
  149. drm_encoder_init(dev, encoder, &exynos_encoder_funcs,
  150. DRM_MODE_ENCODER_TMDS);
  151. drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs);
  152. DRM_DEBUG_KMS("encoder has been created\n");
  153. return encoder;
  154. }
  155. struct exynos_drm_display *exynos_drm_get_display(struct drm_encoder *encoder)
  156. {
  157. return to_exynos_encoder(encoder)->display;
  158. }