dc-kms.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2024 NXP
  4. */
  5. #include <linux/of.h>
  6. #include <linux/of_graph.h>
  7. #include <drm/drm_atomic_helper.h>
  8. #include <drm/drm_bridge.h>
  9. #include <drm/drm_bridge_connector.h>
  10. #include <drm/drm_connector.h>
  11. #include <drm/drm_crtc.h>
  12. #include <drm/drm_device.h>
  13. #include <drm/drm_encoder.h>
  14. #include <drm/drm_gem_framebuffer_helper.h>
  15. #include <drm/drm_mode_config.h>
  16. #include <drm/drm_print.h>
  17. #include <drm/drm_probe_helper.h>
  18. #include <drm/drm_simple_kms_helper.h>
  19. #include <drm/drm_vblank.h>
  20. #include "dc-de.h"
  21. #include "dc-drv.h"
  22. #include "dc-kms.h"
  23. static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
  24. .fb_create = drm_gem_fb_create,
  25. .atomic_check = drm_atomic_helper_check,
  26. .atomic_commit = drm_atomic_helper_commit,
  27. };
  28. static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
  29. int crtc_index)
  30. {
  31. struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
  32. struct drm_device *drm = &dc_drm->base;
  33. struct drm_crtc *crtc = &dc_crtc->base;
  34. struct drm_connector *connector;
  35. struct device *dev = drm->dev;
  36. struct drm_encoder *encoder;
  37. struct drm_bridge *bridge;
  38. int ret;
  39. bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
  40. 0, 0);
  41. if (IS_ERR(bridge)) {
  42. ret = PTR_ERR(bridge);
  43. if (ret == -ENODEV)
  44. return 0;
  45. return dev_err_probe(dev, ret,
  46. "failed to find bridge for CRTC%u\n",
  47. crtc->index);
  48. }
  49. encoder = &dc_drm->encoder[crtc_index];
  50. ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
  51. if (ret) {
  52. dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
  53. crtc->index, ret);
  54. return ret;
  55. }
  56. encoder->possible_crtcs = drm_crtc_mask(crtc);
  57. ret = drm_bridge_attach(encoder, bridge, NULL,
  58. DRM_BRIDGE_ATTACH_NO_CONNECTOR);
  59. if (ret) {
  60. dev_err(dev,
  61. "failed to attach bridge to encoder for CRTC%u: %d\n",
  62. crtc->index, ret);
  63. return ret;
  64. }
  65. connector = drm_bridge_connector_init(drm, encoder);
  66. if (IS_ERR(connector)) {
  67. ret = PTR_ERR(connector);
  68. dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
  69. crtc->index, ret);
  70. return ret;
  71. }
  72. ret = drm_connector_attach_encoder(connector, encoder);
  73. if (ret)
  74. dev_err(dev,
  75. "failed to attach encoder to connector for CRTC%u: %d\n",
  76. crtc->index, ret);
  77. return ret;
  78. }
  79. int dc_kms_init(struct dc_drm_device *dc_drm)
  80. {
  81. struct drm_device *drm = &dc_drm->base;
  82. int ret, i;
  83. ret = drmm_mode_config_init(drm);
  84. if (ret)
  85. return ret;
  86. drm->mode_config.min_width = 60;
  87. drm->mode_config.min_height = 60;
  88. drm->mode_config.max_width = 8192;
  89. drm->mode_config.max_height = 8192;
  90. drm->mode_config.funcs = &dc_drm_mode_config_funcs;
  91. drm->vblank_disable_immediate = true;
  92. drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
  93. for (i = 0; i < DC_DISPLAYS; i++) {
  94. ret = dc_crtc_init(dc_drm, i);
  95. if (ret)
  96. return ret;
  97. ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
  98. if (ret)
  99. return ret;
  100. }
  101. for (i = 0; i < DC_DISPLAYS; i++) {
  102. ret = dc_crtc_post_init(dc_drm, i);
  103. if (ret)
  104. return ret;
  105. }
  106. ret = drm_vblank_init(drm, DC_DISPLAYS);
  107. if (ret) {
  108. dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
  109. return ret;
  110. }
  111. drm_mode_config_reset(drm);
  112. drm_kms_helper_poll_init(drm);
  113. return 0;
  114. }
  115. void dc_kms_uninit(struct dc_drm_device *dc_drm)
  116. {
  117. drm_kms_helper_poll_fini(&dc_drm->base);
  118. }