output.c 7.8 KB

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