output.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Copyright (C) 2012 Avionic Design GmbH
  3. * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. */
  9. #include <drm/drm_atomic_helper.h>
  10. #include <drm/drm_panel.h>
  11. #include "drm.h"
  12. int tegra_output_connector_get_modes(struct drm_connector *connector)
  13. {
  14. struct tegra_output *output = connector_to_output(connector);
  15. struct edid *edid = NULL;
  16. int err = 0;
  17. /*
  18. * If the panel provides one or more modes, use them exclusively and
  19. * ignore any other means of obtaining a mode.
  20. */
  21. if (output->panel) {
  22. err = output->panel->funcs->get_modes(output->panel);
  23. if (err > 0)
  24. return err;
  25. }
  26. if (output->edid)
  27. edid = kmemdup(output->edid, sizeof(*edid), GFP_KERNEL);
  28. else if (output->ddc)
  29. edid = drm_get_edid(connector, output->ddc);
  30. drm_mode_connector_update_edid_property(connector, edid);
  31. if (edid) {
  32. err = drm_add_edid_modes(connector, edid);
  33. kfree(edid);
  34. }
  35. return err;
  36. }
  37. struct drm_encoder *
  38. tegra_output_connector_best_encoder(struct drm_connector *connector)
  39. {
  40. struct tegra_output *output = connector_to_output(connector);
  41. return &output->encoder;
  42. }
  43. enum drm_connector_status
  44. tegra_output_connector_detect(struct drm_connector *connector, bool force)
  45. {
  46. struct tegra_output *output = connector_to_output(connector);
  47. enum drm_connector_status status = connector_status_unknown;
  48. if (gpio_is_valid(output->hpd_gpio)) {
  49. if (output->hpd_gpio_flags & OF_GPIO_ACTIVE_LOW) {
  50. if (gpio_get_value(output->hpd_gpio) != 0)
  51. status = connector_status_disconnected;
  52. else
  53. status = connector_status_connected;
  54. } else {
  55. if (gpio_get_value(output->hpd_gpio) == 0)
  56. status = connector_status_disconnected;
  57. else
  58. status = connector_status_connected;
  59. }
  60. } else {
  61. if (!output->panel)
  62. status = connector_status_disconnected;
  63. else
  64. status = connector_status_connected;
  65. }
  66. return status;
  67. }
  68. void tegra_output_connector_destroy(struct drm_connector *connector)
  69. {
  70. drm_connector_unregister(connector);
  71. drm_connector_cleanup(connector);
  72. }
  73. void tegra_output_encoder_destroy(struct drm_encoder *encoder)
  74. {
  75. drm_encoder_cleanup(encoder);
  76. }
  77. static irqreturn_t hpd_irq(int irq, void *data)
  78. {
  79. struct tegra_output *output = data;
  80. if (output->connector.dev)
  81. drm_helper_hpd_irq_event(output->connector.dev);
  82. return IRQ_HANDLED;
  83. }
  84. int tegra_output_probe(struct tegra_output *output)
  85. {
  86. struct device_node *ddc, *panel;
  87. int err, size;
  88. if (!output->of_node)
  89. output->of_node = output->dev->of_node;
  90. panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
  91. if (panel) {
  92. output->panel = of_drm_find_panel(panel);
  93. if (!output->panel)
  94. return -EPROBE_DEFER;
  95. of_node_put(panel);
  96. }
  97. output->edid = of_get_property(output->of_node, "nvidia,edid", &size);
  98. ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
  99. if (ddc) {
  100. output->ddc = of_find_i2c_adapter_by_node(ddc);
  101. if (!output->ddc) {
  102. err = -EPROBE_DEFER;
  103. of_node_put(ddc);
  104. return err;
  105. }
  106. of_node_put(ddc);
  107. }
  108. output->hpd_gpio = of_get_named_gpio_flags(output->of_node,
  109. "nvidia,hpd-gpio", 0,
  110. &output->hpd_gpio_flags);
  111. if (gpio_is_valid(output->hpd_gpio)) {
  112. unsigned long flags;
  113. err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN,
  114. "HDMI hotplug detect");
  115. if (err < 0) {
  116. dev_err(output->dev, "gpio_request_one(): %d\n", err);
  117. return err;
  118. }
  119. err = gpio_to_irq(output->hpd_gpio);
  120. if (err < 0) {
  121. dev_err(output->dev, "gpio_to_irq(): %d\n", err);
  122. gpio_free(output->hpd_gpio);
  123. return err;
  124. }
  125. output->hpd_irq = err;
  126. flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  127. IRQF_ONESHOT;
  128. err = request_threaded_irq(output->hpd_irq, NULL, hpd_irq,
  129. flags, "hpd", output);
  130. if (err < 0) {
  131. dev_err(output->dev, "failed to request IRQ#%u: %d\n",
  132. output->hpd_irq, err);
  133. gpio_free(output->hpd_gpio);
  134. return err;
  135. }
  136. output->connector.polled = DRM_CONNECTOR_POLL_HPD;
  137. /*
  138. * Disable the interrupt until the connector has been
  139. * initialized to avoid a race in the hotplug interrupt
  140. * handler.
  141. */
  142. disable_irq(output->hpd_irq);
  143. }
  144. return 0;
  145. }
  146. void tegra_output_remove(struct tegra_output *output)
  147. {
  148. if (gpio_is_valid(output->hpd_gpio)) {
  149. free_irq(output->hpd_irq, output);
  150. gpio_free(output->hpd_gpio);
  151. }
  152. if (output->ddc)
  153. put_device(&output->ddc->dev);
  154. }
  155. int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
  156. {
  157. int err;
  158. if (output->panel) {
  159. err = drm_panel_attach(output->panel, &output->connector);
  160. if (err < 0)
  161. return err;
  162. }
  163. /*
  164. * The connector is now registered and ready to receive hotplug events
  165. * so the hotplug interrupt can be enabled.
  166. */
  167. if (gpio_is_valid(output->hpd_gpio))
  168. enable_irq(output->hpd_irq);
  169. return 0;
  170. }
  171. void tegra_output_exit(struct tegra_output *output)
  172. {
  173. /*
  174. * The connector is going away, so the interrupt must be disabled to
  175. * prevent the hotplug interrupt handler from potentially crashing.
  176. */
  177. if (gpio_is_valid(output->hpd_gpio))
  178. disable_irq(output->hpd_irq);
  179. if (output->panel)
  180. drm_panel_detach(output->panel);
  181. }