omap_encoder.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  4. * Author: Rob Clark <rob@ti.com>
  5. */
  6. #include <linux/list.h>
  7. #include <drm/drm_bridge.h>
  8. #include <drm/drm_crtc.h>
  9. #include <drm/drm_modeset_helper_vtables.h>
  10. #include <drm/drm_edid.h>
  11. #include "omap_drv.h"
  12. /*
  13. * encoder funcs
  14. */
  15. #define to_omap_encoder(x) container_of(x, struct omap_encoder, base)
  16. /* The encoder and connector both map to same dssdev.. the encoder
  17. * handles the 'active' parts, ie. anything the modifies the state
  18. * of the hw, and the connector handles the 'read-only' parts, like
  19. * detecting connection and reading edid.
  20. */
  21. struct omap_encoder {
  22. struct drm_encoder base;
  23. struct omap_dss_device *output;
  24. };
  25. static void omap_encoder_destroy(struct drm_encoder *encoder)
  26. {
  27. struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
  28. drm_encoder_cleanup(encoder);
  29. kfree(omap_encoder);
  30. }
  31. static const struct drm_encoder_funcs omap_encoder_funcs = {
  32. .destroy = omap_encoder_destroy,
  33. };
  34. static void omap_encoder_update_videomode_flags(struct videomode *vm,
  35. u32 bus_flags)
  36. {
  37. if (!(vm->flags & (DISPLAY_FLAGS_DE_LOW |
  38. DISPLAY_FLAGS_DE_HIGH))) {
  39. if (bus_flags & DRM_BUS_FLAG_DE_LOW)
  40. vm->flags |= DISPLAY_FLAGS_DE_LOW;
  41. else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
  42. vm->flags |= DISPLAY_FLAGS_DE_HIGH;
  43. }
  44. if (!(vm->flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
  45. DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
  46. if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
  47. vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
  48. else if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
  49. vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
  50. }
  51. if (!(vm->flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
  52. DISPLAY_FLAGS_SYNC_NEGEDGE))) {
  53. if (bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE)
  54. vm->flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
  55. else if (bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE)
  56. vm->flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
  57. }
  58. }
  59. static void omap_encoder_mode_set(struct drm_encoder *encoder,
  60. struct drm_display_mode *mode,
  61. struct drm_display_mode *adjusted_mode)
  62. {
  63. struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
  64. struct omap_dss_device *output = omap_encoder->output;
  65. struct omap_dss_device *dssdev;
  66. struct drm_device *dev = encoder->dev;
  67. struct drm_connector *connector;
  68. struct drm_bridge *bridge;
  69. struct videomode vm = { 0 };
  70. u32 bus_flags;
  71. list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  72. if (connector->encoder == encoder)
  73. break;
  74. }
  75. drm_display_mode_to_videomode(adjusted_mode, &vm);
  76. /*
  77. * HACK: This fixes the vm flags.
  78. * struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags and
  79. * they get lost when converting back and forth between struct
  80. * drm_display_mode and struct videomode. The hack below goes and
  81. * fetches the missing flags.
  82. *
  83. * A better solution is to use DRM's bus-flags through the whole driver.
  84. */
  85. for (dssdev = output; dssdev; dssdev = dssdev->next)
  86. omap_encoder_update_videomode_flags(&vm, dssdev->bus_flags);
  87. for (bridge = output->bridge; bridge;
  88. bridge = drm_bridge_get_next_bridge(bridge)) {
  89. if (!bridge->timings)
  90. continue;
  91. bus_flags = bridge->timings->input_bus_flags;
  92. omap_encoder_update_videomode_flags(&vm, bus_flags);
  93. }
  94. bus_flags = connector->display_info.bus_flags;
  95. omap_encoder_update_videomode_flags(&vm, bus_flags);
  96. /* Set timings for the dss manager. */
  97. dss_mgr_set_timings(output, &vm);
  98. }
  99. static void omap_encoder_disable(struct drm_encoder *encoder)
  100. {
  101. struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
  102. struct omap_dss_device *dssdev = omap_encoder->output;
  103. struct drm_device *dev = encoder->dev;
  104. dev_dbg(dev->dev, "disable(%s)\n", dssdev->name);
  105. /*
  106. * Disable the chain of external devices, starting at the one at the
  107. * internal encoder's output. This is used for DSI outputs only, as
  108. * dssdev->next is NULL for all other outputs.
  109. */
  110. omapdss_device_disable(dssdev->next);
  111. }
  112. static void omap_encoder_enable(struct drm_encoder *encoder)
  113. {
  114. struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
  115. struct omap_dss_device *dssdev = omap_encoder->output;
  116. struct drm_device *dev = encoder->dev;
  117. dev_dbg(dev->dev, "enable(%s)\n", dssdev->name);
  118. /*
  119. * Enable the chain of external devices, starting at the one at the
  120. * internal encoder's output. This is used for DSI outputs only, as
  121. * dssdev->next is NULL for all other outputs.
  122. */
  123. omapdss_device_enable(dssdev->next);
  124. }
  125. static int omap_encoder_atomic_check(struct drm_encoder *encoder,
  126. struct drm_crtc_state *crtc_state,
  127. struct drm_connector_state *conn_state)
  128. {
  129. struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
  130. enum drm_mode_status status;
  131. status = omap_connector_mode_fixup(omap_encoder->output,
  132. &crtc_state->mode,
  133. &crtc_state->adjusted_mode);
  134. if (status != MODE_OK) {
  135. dev_err(encoder->dev->dev, "invalid timings: %d\n", status);
  136. return -EINVAL;
  137. }
  138. return 0;
  139. }
  140. static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
  141. .mode_set = omap_encoder_mode_set,
  142. .disable = omap_encoder_disable,
  143. .enable = omap_encoder_enable,
  144. .atomic_check = omap_encoder_atomic_check,
  145. };
  146. /* initialize encoder */
  147. struct drm_encoder *omap_encoder_init(struct drm_device *dev,
  148. struct omap_dss_device *output)
  149. {
  150. struct drm_encoder *encoder = NULL;
  151. struct omap_encoder *omap_encoder;
  152. omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL);
  153. if (!omap_encoder)
  154. goto fail;
  155. omap_encoder->output = output;
  156. encoder = &omap_encoder->base;
  157. drm_encoder_init(dev, encoder, &omap_encoder_funcs,
  158. DRM_MODE_ENCODER_TMDS, NULL);
  159. drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs);
  160. return encoder;
  161. fail:
  162. if (encoder)
  163. omap_encoder_destroy(encoder);
  164. return NULL;
  165. }