arcpgu_sim.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ARC PGU DRM driver.
  4. *
  5. * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com)
  6. */
  7. #include <drm/drm_atomic_helper.h>
  8. #include <drm/drm_device.h>
  9. #include <drm/drm_probe_helper.h>
  10. #include "arcpgu.h"
  11. #define XRES_DEF 640
  12. #define YRES_DEF 480
  13. #define XRES_MAX 8192
  14. #define YRES_MAX 8192
  15. struct arcpgu_drm_connector {
  16. struct drm_connector connector;
  17. };
  18. static int arcpgu_drm_connector_get_modes(struct drm_connector *connector)
  19. {
  20. int count;
  21. count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
  22. drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
  23. return count;
  24. }
  25. static void arcpgu_drm_connector_destroy(struct drm_connector *connector)
  26. {
  27. drm_connector_unregister(connector);
  28. drm_connector_cleanup(connector);
  29. }
  30. static const struct drm_connector_helper_funcs
  31. arcpgu_drm_connector_helper_funcs = {
  32. .get_modes = arcpgu_drm_connector_get_modes,
  33. };
  34. static const struct drm_connector_funcs arcpgu_drm_connector_funcs = {
  35. .reset = drm_atomic_helper_connector_reset,
  36. .fill_modes = drm_helper_probe_single_connector_modes,
  37. .destroy = arcpgu_drm_connector_destroy,
  38. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  39. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  40. };
  41. static struct drm_encoder_funcs arcpgu_drm_encoder_funcs = {
  42. .destroy = drm_encoder_cleanup,
  43. };
  44. int arcpgu_drm_sim_init(struct drm_device *drm, struct device_node *np)
  45. {
  46. struct arcpgu_drm_connector *arcpgu_connector;
  47. struct drm_encoder *encoder;
  48. struct drm_connector *connector;
  49. int ret;
  50. encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL);
  51. if (encoder == NULL)
  52. return -ENOMEM;
  53. encoder->possible_crtcs = 1;
  54. encoder->possible_clones = 0;
  55. ret = drm_encoder_init(drm, encoder, &arcpgu_drm_encoder_funcs,
  56. DRM_MODE_ENCODER_VIRTUAL, NULL);
  57. if (ret)
  58. return ret;
  59. arcpgu_connector = devm_kzalloc(drm->dev, sizeof(*arcpgu_connector),
  60. GFP_KERNEL);
  61. if (!arcpgu_connector) {
  62. ret = -ENOMEM;
  63. goto error_encoder_cleanup;
  64. }
  65. connector = &arcpgu_connector->connector;
  66. drm_connector_helper_add(connector, &arcpgu_drm_connector_helper_funcs);
  67. ret = drm_connector_init(drm, connector, &arcpgu_drm_connector_funcs,
  68. DRM_MODE_CONNECTOR_VIRTUAL);
  69. if (ret < 0) {
  70. dev_err(drm->dev, "failed to initialize drm connector\n");
  71. goto error_encoder_cleanup;
  72. }
  73. ret = drm_connector_attach_encoder(connector, encoder);
  74. if (ret < 0) {
  75. dev_err(drm->dev, "could not attach connector to encoder\n");
  76. drm_connector_unregister(connector);
  77. goto error_connector_cleanup;
  78. }
  79. return 0;
  80. error_connector_cleanup:
  81. drm_connector_cleanup(connector);
  82. error_encoder_cleanup:
  83. drm_encoder_cleanup(encoder);
  84. return ret;
  85. }