rcar_du_encoder.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * rcar_du_encoder.c -- R-Car Display Unit Encoder
  4. *
  5. * Copyright (C) 2013-2014 Renesas Electronics Corporation
  6. *
  7. * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  8. */
  9. #include <linux/export.h>
  10. #include <drm/drmP.h>
  11. #include <drm/drm_crtc.h>
  12. #include <drm/drm_crtc_helper.h>
  13. #include <drm/drm_panel.h>
  14. #include "rcar_du_drv.h"
  15. #include "rcar_du_encoder.h"
  16. #include "rcar_du_kms.h"
  17. /* -----------------------------------------------------------------------------
  18. * Encoder
  19. */
  20. static void rcar_du_encoder_mode_set(struct drm_encoder *encoder,
  21. struct drm_crtc_state *crtc_state,
  22. struct drm_connector_state *conn_state)
  23. {
  24. struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
  25. rcar_du_crtc_route_output(crtc_state->crtc, renc->output);
  26. }
  27. static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
  28. .atomic_mode_set = rcar_du_encoder_mode_set,
  29. };
  30. static const struct drm_encoder_funcs encoder_funcs = {
  31. .destroy = drm_encoder_cleanup,
  32. };
  33. int rcar_du_encoder_init(struct rcar_du_device *rcdu,
  34. enum rcar_du_output output,
  35. struct device_node *enc_node,
  36. struct device_node *con_node)
  37. {
  38. struct rcar_du_encoder *renc;
  39. struct drm_encoder *encoder;
  40. struct drm_bridge *bridge = NULL;
  41. int ret;
  42. renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL);
  43. if (renc == NULL)
  44. return -ENOMEM;
  45. renc->output = output;
  46. encoder = rcar_encoder_to_drm_encoder(renc);
  47. dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
  48. enc_node, output);
  49. /* Locate the DRM bridge from the encoder DT node. */
  50. bridge = of_drm_find_bridge(enc_node);
  51. if (!bridge) {
  52. ret = -EPROBE_DEFER;
  53. goto done;
  54. }
  55. ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
  56. DRM_MODE_ENCODER_NONE, NULL);
  57. if (ret < 0)
  58. goto done;
  59. drm_encoder_helper_add(encoder, &encoder_helper_funcs);
  60. /*
  61. * Attach the bridge to the encoder. The bridge will create the
  62. * connector.
  63. */
  64. ret = drm_bridge_attach(encoder, bridge, NULL);
  65. if (ret) {
  66. drm_encoder_cleanup(encoder);
  67. return ret;
  68. }
  69. done:
  70. if (ret < 0) {
  71. if (encoder->name)
  72. encoder->funcs->destroy(encoder);
  73. devm_kfree(rcdu->dev, renc);
  74. }
  75. return ret;
  76. }