parallel-display.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * i.MX drm driver - parallel display implementation
  4. *
  5. * Copyright (C) 2012 Sascha Hauer, Pengutronix
  6. */
  7. #include <linux/component.h>
  8. #include <linux/media-bus-format.h>
  9. #include <linux/module.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/videodev2.h>
  12. #include <video/of_display_timing.h>
  13. #include <drm/drm_atomic_helper.h>
  14. #include <drm/drm_bridge.h>
  15. #include <drm/drm_edid.h>
  16. #include <drm/drm_fb_helper.h>
  17. #include <drm/drm_managed.h>
  18. #include <drm/drm_of.h>
  19. #include <drm/drm_panel.h>
  20. #include <drm/drm_probe_helper.h>
  21. #include <drm/drm_simple_kms_helper.h>
  22. #include "imx-drm.h"
  23. struct imx_parallel_display_encoder {
  24. struct drm_connector connector;
  25. struct drm_encoder encoder;
  26. struct drm_bridge bridge;
  27. struct imx_parallel_display *pd;
  28. };
  29. struct imx_parallel_display {
  30. struct device *dev;
  31. void *edid;
  32. u32 bus_format;
  33. u32 bus_flags;
  34. struct drm_display_mode mode;
  35. struct drm_panel *panel;
  36. struct drm_bridge *next_bridge;
  37. };
  38. static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c)
  39. {
  40. return container_of(c, struct imx_parallel_display_encoder, connector)->pd;
  41. }
  42. static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge *b)
  43. {
  44. return container_of(b, struct imx_parallel_display_encoder, bridge)->pd;
  45. }
  46. static int imx_pd_connector_get_modes(struct drm_connector *connector)
  47. {
  48. struct imx_parallel_display *imxpd = con_to_imxpd(connector);
  49. struct device_node *np = imxpd->dev->of_node;
  50. int num_modes;
  51. num_modes = drm_panel_get_modes(imxpd->panel, connector);
  52. if (num_modes > 0)
  53. return num_modes;
  54. if (imxpd->edid) {
  55. drm_connector_update_edid_property(connector, imxpd->edid);
  56. num_modes = drm_add_edid_modes(connector, imxpd->edid);
  57. }
  58. if (np) {
  59. struct drm_display_mode *mode = drm_mode_create(connector->dev);
  60. int ret;
  61. if (!mode)
  62. return -EINVAL;
  63. ret = of_get_drm_display_mode(np, &imxpd->mode,
  64. &imxpd->bus_flags,
  65. OF_USE_NATIVE_MODE);
  66. if (ret) {
  67. drm_mode_destroy(connector->dev, mode);
  68. return ret;
  69. }
  70. drm_mode_copy(mode, &imxpd->mode);
  71. mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
  72. drm_mode_probed_add(connector, mode);
  73. num_modes++;
  74. }
  75. return num_modes;
  76. }
  77. static void imx_pd_bridge_enable(struct drm_bridge *bridge)
  78. {
  79. struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
  80. drm_panel_prepare(imxpd->panel);
  81. drm_panel_enable(imxpd->panel);
  82. }
  83. static void imx_pd_bridge_disable(struct drm_bridge *bridge)
  84. {
  85. struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
  86. drm_panel_disable(imxpd->panel);
  87. drm_panel_unprepare(imxpd->panel);
  88. }
  89. static const u32 imx_pd_bus_fmts[] = {
  90. MEDIA_BUS_FMT_RGB888_1X24,
  91. MEDIA_BUS_FMT_BGR888_1X24,
  92. MEDIA_BUS_FMT_GBR888_1X24,
  93. MEDIA_BUS_FMT_RGB666_1X18,
  94. MEDIA_BUS_FMT_RGB666_1X24_CPADHI,
  95. MEDIA_BUS_FMT_RGB565_1X16,
  96. };
  97. static u32 *
  98. imx_pd_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
  99. struct drm_bridge_state *bridge_state,
  100. struct drm_crtc_state *crtc_state,
  101. struct drm_connector_state *conn_state,
  102. unsigned int *num_output_fmts)
  103. {
  104. struct drm_display_info *di = &conn_state->connector->display_info;
  105. struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
  106. u32 *output_fmts;
  107. if (!imxpd->bus_format && !di->num_bus_formats) {
  108. *num_output_fmts = ARRAY_SIZE(imx_pd_bus_fmts);
  109. return kmemdup(imx_pd_bus_fmts, sizeof(imx_pd_bus_fmts),
  110. GFP_KERNEL);
  111. }
  112. *num_output_fmts = 1;
  113. output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
  114. if (!output_fmts)
  115. return NULL;
  116. if (!imxpd->bus_format && di->num_bus_formats)
  117. output_fmts[0] = di->bus_formats[0];
  118. else
  119. output_fmts[0] = imxpd->bus_format;
  120. return output_fmts;
  121. }
  122. static bool imx_pd_format_supported(u32 output_fmt)
  123. {
  124. unsigned int i;
  125. for (i = 0; i < ARRAY_SIZE(imx_pd_bus_fmts); i++) {
  126. if (imx_pd_bus_fmts[i] == output_fmt)
  127. return true;
  128. }
  129. return false;
  130. }
  131. static u32 *
  132. imx_pd_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
  133. struct drm_bridge_state *bridge_state,
  134. struct drm_crtc_state *crtc_state,
  135. struct drm_connector_state *conn_state,
  136. u32 output_fmt,
  137. unsigned int *num_input_fmts)
  138. {
  139. struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
  140. u32 *input_fmts;
  141. /*
  142. * If the next bridge does not support bus format negotiation, let's
  143. * use the static bus format definition (imxpd->bus_format) if it's
  144. * specified, RGB888 when it's not.
  145. */
  146. if (output_fmt == MEDIA_BUS_FMT_FIXED)
  147. output_fmt = imxpd->bus_format ? : MEDIA_BUS_FMT_RGB888_1X24;
  148. /* Now make sure the requested output format is supported. */
  149. if ((imxpd->bus_format && imxpd->bus_format != output_fmt) ||
  150. !imx_pd_format_supported(output_fmt)) {
  151. *num_input_fmts = 0;
  152. return NULL;
  153. }
  154. *num_input_fmts = 1;
  155. input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
  156. if (!input_fmts)
  157. return NULL;
  158. input_fmts[0] = output_fmt;
  159. return input_fmts;
  160. }
  161. static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge,
  162. struct drm_bridge_state *bridge_state,
  163. struct drm_crtc_state *crtc_state,
  164. struct drm_connector_state *conn_state)
  165. {
  166. struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
  167. struct drm_display_info *di = &conn_state->connector->display_info;
  168. struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
  169. struct drm_bridge_state *next_bridge_state = NULL;
  170. struct drm_bridge *next_bridge;
  171. u32 bus_flags, bus_fmt;
  172. next_bridge = drm_bridge_get_next_bridge(bridge);
  173. if (next_bridge)
  174. next_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
  175. next_bridge);
  176. if (next_bridge_state)
  177. bus_flags = next_bridge_state->input_bus_cfg.flags;
  178. else if (di->num_bus_formats)
  179. bus_flags = di->bus_flags;
  180. else
  181. bus_flags = imxpd->bus_flags;
  182. bus_fmt = bridge_state->input_bus_cfg.format;
  183. if (!imx_pd_format_supported(bus_fmt))
  184. return -EINVAL;
  185. bridge_state->output_bus_cfg.flags = bus_flags;
  186. bridge_state->input_bus_cfg.flags = bus_flags;
  187. imx_crtc_state->bus_flags = bus_flags;
  188. imx_crtc_state->bus_format = bridge_state->input_bus_cfg.format;
  189. imx_crtc_state->di_hsync_pin = 2;
  190. imx_crtc_state->di_vsync_pin = 3;
  191. return 0;
  192. }
  193. static const struct drm_connector_funcs imx_pd_connector_funcs = {
  194. .fill_modes = drm_helper_probe_single_connector_modes,
  195. .destroy = imx_drm_connector_destroy,
  196. .reset = drm_atomic_helper_connector_reset,
  197. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  198. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  199. };
  200. static const struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
  201. .get_modes = imx_pd_connector_get_modes,
  202. };
  203. static const struct drm_bridge_funcs imx_pd_bridge_funcs = {
  204. .enable = imx_pd_bridge_enable,
  205. .disable = imx_pd_bridge_disable,
  206. .atomic_reset = drm_atomic_helper_bridge_reset,
  207. .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
  208. .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
  209. .atomic_check = imx_pd_bridge_atomic_check,
  210. .atomic_get_input_bus_fmts = imx_pd_bridge_atomic_get_input_bus_fmts,
  211. .atomic_get_output_bus_fmts = imx_pd_bridge_atomic_get_output_bus_fmts,
  212. };
  213. static int imx_pd_bind(struct device *dev, struct device *master, void *data)
  214. {
  215. struct drm_device *drm = data;
  216. struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
  217. struct imx_parallel_display_encoder *imxpd_encoder;
  218. struct drm_connector *connector;
  219. struct drm_encoder *encoder;
  220. struct drm_bridge *bridge;
  221. int ret;
  222. imxpd_encoder = drmm_simple_encoder_alloc(drm, struct imx_parallel_display_encoder,
  223. encoder, DRM_MODE_ENCODER_NONE);
  224. if (IS_ERR(imxpd_encoder))
  225. return PTR_ERR(imxpd_encoder);
  226. imxpd_encoder->pd = imxpd;
  227. connector = &imxpd_encoder->connector;
  228. encoder = &imxpd_encoder->encoder;
  229. bridge = &imxpd_encoder->bridge;
  230. ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
  231. if (ret)
  232. return ret;
  233. /* set the connector's dpms to OFF so that
  234. * drm_helper_connector_dpms() won't return
  235. * immediately since the current state is ON
  236. * at this point.
  237. */
  238. connector->dpms = DRM_MODE_DPMS_OFF;
  239. bridge->funcs = &imx_pd_bridge_funcs;
  240. drm_bridge_attach(encoder, bridge, NULL, 0);
  241. if (imxpd->next_bridge) {
  242. ret = drm_bridge_attach(encoder, imxpd->next_bridge, bridge, 0);
  243. if (ret < 0)
  244. return ret;
  245. } else {
  246. drm_connector_helper_add(connector,
  247. &imx_pd_connector_helper_funcs);
  248. drm_connector_init(drm, connector, &imx_pd_connector_funcs,
  249. DRM_MODE_CONNECTOR_DPI);
  250. drm_connector_attach_encoder(connector, encoder);
  251. }
  252. return 0;
  253. }
  254. static const struct component_ops imx_pd_ops = {
  255. .bind = imx_pd_bind,
  256. };
  257. static int imx_pd_probe(struct platform_device *pdev)
  258. {
  259. struct device *dev = &pdev->dev;
  260. struct device_node *np = dev->of_node;
  261. const u8 *edidp;
  262. struct imx_parallel_display *imxpd;
  263. int edid_len;
  264. int ret;
  265. u32 bus_format = 0;
  266. const char *fmt;
  267. imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
  268. if (!imxpd)
  269. return -ENOMEM;
  270. /* port@1 is the output port */
  271. ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel,
  272. &imxpd->next_bridge);
  273. if (ret && ret != -ENODEV)
  274. return ret;
  275. edidp = of_get_property(np, "edid", &edid_len);
  276. if (edidp)
  277. imxpd->edid = devm_kmemdup(dev, edidp, edid_len, GFP_KERNEL);
  278. ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
  279. if (!ret) {
  280. if (!strcmp(fmt, "rgb24"))
  281. bus_format = MEDIA_BUS_FMT_RGB888_1X24;
  282. else if (!strcmp(fmt, "rgb565"))
  283. bus_format = MEDIA_BUS_FMT_RGB565_1X16;
  284. else if (!strcmp(fmt, "bgr666"))
  285. bus_format = MEDIA_BUS_FMT_RGB666_1X18;
  286. else if (!strcmp(fmt, "lvds666"))
  287. bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
  288. }
  289. imxpd->bus_format = bus_format;
  290. imxpd->dev = dev;
  291. platform_set_drvdata(pdev, imxpd);
  292. return component_add(dev, &imx_pd_ops);
  293. }
  294. static int imx_pd_remove(struct platform_device *pdev)
  295. {
  296. component_del(&pdev->dev, &imx_pd_ops);
  297. return 0;
  298. }
  299. static const struct of_device_id imx_pd_dt_ids[] = {
  300. { .compatible = "fsl,imx-parallel-display", },
  301. { /* sentinel */ }
  302. };
  303. MODULE_DEVICE_TABLE(of, imx_pd_dt_ids);
  304. static struct platform_driver imx_pd_driver = {
  305. .probe = imx_pd_probe,
  306. .remove = imx_pd_remove,
  307. .driver = {
  308. .of_match_table = imx_pd_dt_ids,
  309. .name = "imx-parallel-display",
  310. },
  311. };
  312. module_platform_driver(imx_pd_driver);
  313. MODULE_DESCRIPTION("i.MX parallel display driver");
  314. MODULE_AUTHOR("Sascha Hauer, Pengutronix");
  315. MODULE_LICENSE("GPL");
  316. MODULE_ALIAS("platform:imx-parallel-display");