output.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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 <linux/of_gpio.h>
  10. #include <drm/drm_panel.h>
  11. #include "drm.h"
  12. static int tegra_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. static int tegra_connector_mode_valid(struct drm_connector *connector,
  38. struct drm_display_mode *mode)
  39. {
  40. struct tegra_output *output = connector_to_output(connector);
  41. enum drm_mode_status status = MODE_OK;
  42. int err;
  43. err = tegra_output_check_mode(output, mode, &status);
  44. if (err < 0)
  45. return MODE_ERROR;
  46. return status;
  47. }
  48. static struct drm_encoder *
  49. tegra_connector_best_encoder(struct drm_connector *connector)
  50. {
  51. struct tegra_output *output = connector_to_output(connector);
  52. return &output->encoder;
  53. }
  54. static const struct drm_connector_helper_funcs connector_helper_funcs = {
  55. .get_modes = tegra_connector_get_modes,
  56. .mode_valid = tegra_connector_mode_valid,
  57. .best_encoder = tegra_connector_best_encoder,
  58. };
  59. static enum drm_connector_status
  60. tegra_connector_detect(struct drm_connector *connector, bool force)
  61. {
  62. struct tegra_output *output = connector_to_output(connector);
  63. enum drm_connector_status status = connector_status_unknown;
  64. if (gpio_is_valid(output->hpd_gpio)) {
  65. if (gpio_get_value(output->hpd_gpio) == 0)
  66. status = connector_status_disconnected;
  67. else
  68. status = connector_status_connected;
  69. } else {
  70. if (!output->panel)
  71. status = connector_status_disconnected;
  72. else
  73. status = connector_status_connected;
  74. if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
  75. status = connector_status_connected;
  76. }
  77. return status;
  78. }
  79. static void drm_connector_clear(struct drm_connector *connector)
  80. {
  81. memset(connector, 0, sizeof(*connector));
  82. }
  83. static void tegra_connector_destroy(struct drm_connector *connector)
  84. {
  85. drm_sysfs_connector_remove(connector);
  86. drm_connector_cleanup(connector);
  87. drm_connector_clear(connector);
  88. }
  89. static const struct drm_connector_funcs connector_funcs = {
  90. .dpms = drm_helper_connector_dpms,
  91. .detect = tegra_connector_detect,
  92. .fill_modes = drm_helper_probe_single_connector_modes,
  93. .destroy = tegra_connector_destroy,
  94. };
  95. static void drm_encoder_clear(struct drm_encoder *encoder)
  96. {
  97. memset(encoder, 0, sizeof(*encoder));
  98. }
  99. static void tegra_encoder_destroy(struct drm_encoder *encoder)
  100. {
  101. drm_encoder_cleanup(encoder);
  102. drm_encoder_clear(encoder);
  103. }
  104. static const struct drm_encoder_funcs encoder_funcs = {
  105. .destroy = tegra_encoder_destroy,
  106. };
  107. static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
  108. {
  109. struct tegra_output *output = encoder_to_output(encoder);
  110. struct drm_panel *panel = output->panel;
  111. if (mode != DRM_MODE_DPMS_ON) {
  112. drm_panel_disable(panel);
  113. tegra_output_disable(output);
  114. } else {
  115. tegra_output_enable(output);
  116. drm_panel_enable(panel);
  117. }
  118. }
  119. static bool tegra_encoder_mode_fixup(struct drm_encoder *encoder,
  120. const struct drm_display_mode *mode,
  121. struct drm_display_mode *adjusted)
  122. {
  123. return true;
  124. }
  125. static void tegra_encoder_prepare(struct drm_encoder *encoder)
  126. {
  127. }
  128. static void tegra_encoder_commit(struct drm_encoder *encoder)
  129. {
  130. }
  131. static void tegra_encoder_mode_set(struct drm_encoder *encoder,
  132. struct drm_display_mode *mode,
  133. struct drm_display_mode *adjusted)
  134. {
  135. struct tegra_output *output = encoder_to_output(encoder);
  136. int err;
  137. err = tegra_output_enable(output);
  138. if (err < 0)
  139. dev_err(encoder->dev->dev, "tegra_output_enable(): %d\n", err);
  140. }
  141. static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
  142. .dpms = tegra_encoder_dpms,
  143. .mode_fixup = tegra_encoder_mode_fixup,
  144. .prepare = tegra_encoder_prepare,
  145. .commit = tegra_encoder_commit,
  146. .mode_set = tegra_encoder_mode_set,
  147. };
  148. static irqreturn_t hpd_irq(int irq, void *data)
  149. {
  150. struct tegra_output *output = data;
  151. drm_helper_hpd_irq_event(output->connector.dev);
  152. return IRQ_HANDLED;
  153. }
  154. int tegra_output_probe(struct tegra_output *output)
  155. {
  156. struct device_node *ddc, *panel;
  157. enum of_gpio_flags flags;
  158. int err, size;
  159. if (!output->of_node)
  160. output->of_node = output->dev->of_node;
  161. panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
  162. if (panel) {
  163. output->panel = of_drm_find_panel(panel);
  164. if (!output->panel)
  165. return -EPROBE_DEFER;
  166. of_node_put(panel);
  167. }
  168. output->edid = of_get_property(output->of_node, "nvidia,edid", &size);
  169. ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
  170. if (ddc) {
  171. output->ddc = of_find_i2c_adapter_by_node(ddc);
  172. if (!output->ddc) {
  173. err = -EPROBE_DEFER;
  174. of_node_put(ddc);
  175. return err;
  176. }
  177. of_node_put(ddc);
  178. }
  179. output->hpd_gpio = of_get_named_gpio_flags(output->of_node,
  180. "nvidia,hpd-gpio", 0,
  181. &flags);
  182. if (gpio_is_valid(output->hpd_gpio)) {
  183. unsigned long flags;
  184. err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN,
  185. "HDMI hotplug detect");
  186. if (err < 0) {
  187. dev_err(output->dev, "gpio_request_one(): %d\n", err);
  188. return err;
  189. }
  190. err = gpio_to_irq(output->hpd_gpio);
  191. if (err < 0) {
  192. dev_err(output->dev, "gpio_to_irq(): %d\n", err);
  193. gpio_free(output->hpd_gpio);
  194. return err;
  195. }
  196. output->hpd_irq = err;
  197. flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  198. IRQF_ONESHOT;
  199. err = request_threaded_irq(output->hpd_irq, NULL, hpd_irq,
  200. flags, "hpd", output);
  201. if (err < 0) {
  202. dev_err(output->dev, "failed to request IRQ#%u: %d\n",
  203. output->hpd_irq, err);
  204. gpio_free(output->hpd_gpio);
  205. return err;
  206. }
  207. output->connector.polled = DRM_CONNECTOR_POLL_HPD;
  208. }
  209. return 0;
  210. }
  211. int tegra_output_remove(struct tegra_output *output)
  212. {
  213. if (gpio_is_valid(output->hpd_gpio)) {
  214. free_irq(output->hpd_irq, output);
  215. gpio_free(output->hpd_gpio);
  216. }
  217. if (output->ddc)
  218. put_device(&output->ddc->dev);
  219. return 0;
  220. }
  221. int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
  222. {
  223. int connector, encoder;
  224. switch (output->type) {
  225. case TEGRA_OUTPUT_RGB:
  226. connector = DRM_MODE_CONNECTOR_LVDS;
  227. encoder = DRM_MODE_ENCODER_LVDS;
  228. break;
  229. case TEGRA_OUTPUT_HDMI:
  230. connector = DRM_MODE_CONNECTOR_HDMIA;
  231. encoder = DRM_MODE_ENCODER_TMDS;
  232. break;
  233. case TEGRA_OUTPUT_DSI:
  234. connector = DRM_MODE_CONNECTOR_DSI;
  235. encoder = DRM_MODE_ENCODER_DSI;
  236. break;
  237. default:
  238. connector = DRM_MODE_CONNECTOR_Unknown;
  239. encoder = DRM_MODE_ENCODER_NONE;
  240. break;
  241. }
  242. drm_connector_init(drm, &output->connector, &connector_funcs,
  243. connector);
  244. drm_connector_helper_add(&output->connector, &connector_helper_funcs);
  245. output->connector.dpms = DRM_MODE_DPMS_OFF;
  246. if (output->panel)
  247. drm_panel_attach(output->panel, &output->connector);
  248. drm_encoder_init(drm, &output->encoder, &encoder_funcs, encoder);
  249. drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs);
  250. drm_mode_connector_attach_encoder(&output->connector, &output->encoder);
  251. drm_sysfs_connector_add(&output->connector);
  252. output->encoder.possible_crtcs = 0x3;
  253. return 0;
  254. }
  255. int tegra_output_exit(struct tegra_output *output)
  256. {
  257. return 0;
  258. }