rcar_du_encoder.c 2.4 KB

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