0334-video-da8xx-fb-adding-dt-support.patch 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. From 884d3962ef4787c8cf0b8a7a673531c623d1dff8 Mon Sep 17 00:00:00 2001
  2. From: Darren Etheridge <detheridge@ti.com>
  3. Date: Fri, 2 Aug 2013 15:35:36 -0500
  4. Subject: [PATCH 334/752] video: da8xx-fb: adding dt support
  5. Enhancing driver to enable probe triggered by a corresponding dt entry.
  6. Add da8xx-fb.txt documentation to devicetree section.
  7. Obtain fb_videomode details for the connected lcd panel using the
  8. display timing details present in DT.
  9. Ensure that platform data is present before checking whether platform
  10. callback is present (the one used to control backlight). So far this
  11. was not an issue as driver was purely non-DT triggered, but now DT
  12. support has been added this check must be performed.
  13. v2: squashing multiple commits from Afzal Mohammed (afzal@ti.com)
  14. v3: remove superfluous cast
  15. v4: expose both ti,am3352-lcdc and ti,da830-lcdc for .compatible
  16. as driver can use enhanced features of all version of the
  17. silicon block.
  18. v5: addressed review comments from Prabhakar Lad
  19. v6: Changed the .compatible naming to match the existing drm bindings
  20. for am33xx devices
  21. v7: clarify which compatible to use in the documentation for DA850
  22. Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
  23. Signed-off-by: Darren Etheridge <detheridge@ti.com>
  24. ---
  25. .../devicetree/bindings/video/da8xx-fb.txt | 42 +++++++++++++
  26. drivers/video/fbdev/da8xx-fb.c | 66 +++++++++++++++++++-
  27. 2 files changed, 105 insertions(+), 3 deletions(-)
  28. create mode 100644 Documentation/devicetree/bindings/video/da8xx-fb.txt
  29. --- /dev/null
  30. +++ b/Documentation/devicetree/bindings/video/da8xx-fb.txt
  31. @@ -0,0 +1,42 @@
  32. +TI LCD Controller on DA830/DA850/AM335x SoC's
  33. +
  34. +Required properties:
  35. +- compatible:
  36. + DA830, DA850 - "ti,da8xx-tilcdc"
  37. + AM335x SoC's - "ti,am33xx-tilcdc"
  38. +- reg: Address range of lcdc register set
  39. +- interrupts: lcdc interrupt
  40. +- display-timings: typical videomode of lcd panel, represented as child.
  41. + Refer Documentation/devicetree/bindings/video/display-timing.txt for
  42. + display timing binding details. If multiple videomodes are mentioned
  43. + in display timings node, typical videomode has to be mentioned as the
  44. + native mode or it has to be first child (driver cares only for native
  45. + videomode).
  46. +
  47. +Recommended properties:
  48. +- ti,hwmods: Name of the hwmod associated to the LCDC
  49. +
  50. +Example for am335x SoC's:
  51. +
  52. +lcdc@4830e000 {
  53. + compatible = "ti,am33xx-tilcdc";
  54. + reg = <0x4830e000 0x1000>;
  55. + interrupts = <36>;
  56. + ti,hwmods = "lcdc";
  57. + status = "okay";
  58. + display-timings {
  59. + 800x480p62 {
  60. + clock-frequency = <30000000>;
  61. + hactive = <800>;
  62. + vactive = <480>;
  63. + hfront-porch = <39>;
  64. + hback-porch = <39>;
  65. + hsync-len = <47>;
  66. + vback-porch = <29>;
  67. + vfront-porch = <13>;
  68. + vsync-len = <2>;
  69. + hsync-active = <1>;
  70. + vsync-active = <1>;
  71. + };
  72. + };
  73. +};
  74. --- a/drivers/video/fbdev/da8xx-fb.c
  75. +++ b/drivers/video/fbdev/da8xx-fb.c
  76. @@ -36,6 +36,7 @@
  77. #include <linux/slab.h>
  78. #include <linux/delay.h>
  79. #include <linux/lcm.h>
  80. +#include <video/of_display_timing.h>
  81. #include <video/da8xx-fb.h>
  82. #include <asm/div64.h>
  83. @@ -1317,12 +1318,54 @@ static struct fb_ops da8xx_fb_ops = {
  84. .fb_blank = cfb_blank,
  85. };
  86. +static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev)
  87. +{
  88. + struct lcd_ctrl_config *cfg;
  89. +
  90. + cfg = devm_kzalloc(&dev->dev, sizeof(struct fb_videomode), GFP_KERNEL);
  91. + if (!cfg)
  92. + return NULL;
  93. +
  94. + /* default values */
  95. +
  96. + if (lcd_revision == LCD_VERSION_1)
  97. + cfg->bpp = 16;
  98. + else
  99. + cfg->bpp = 32;
  100. +
  101. + /*
  102. + * For panels so far used with this LCDC, below statement is sufficient.
  103. + * For new panels, if required, struct lcd_ctrl_cfg fields to be updated
  104. + * with additional/modified values. Those values would have to be then
  105. + * obtained from dt(requiring new dt bindings).
  106. + */
  107. +
  108. + cfg->panel_shade = COLOR_ACTIVE;
  109. +
  110. + return cfg;
  111. +}
  112. +
  113. static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
  114. {
  115. struct da8xx_lcdc_platform_data *fb_pdata = dev_get_platdata(&dev->dev);
  116. struct fb_videomode *lcdc_info;
  117. + struct device_node *np = dev->dev.of_node;
  118. int i;
  119. + if (np) {
  120. + lcdc_info = devm_kzalloc(&dev->dev,
  121. + sizeof(struct fb_videomode),
  122. + GFP_KERNEL);
  123. + if (!lcdc_info)
  124. + return NULL;
  125. +
  126. + if (of_get_fb_videomode(np, lcdc_info, OF_USE_NATIVE_MODE)) {
  127. + dev_err(&dev->dev, "timings not available in DT\n");
  128. + return NULL;
  129. + }
  130. + return lcdc_info;
  131. + }
  132. +
  133. for (i = 0, lcdc_info = known_lcd_panels;
  134. i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
  135. if (strcmp(fb_pdata->type, lcdc_info->name) == 0)
  136. @@ -1351,7 +1394,7 @@ static int fb_probe(struct platform_devi
  137. int ret;
  138. unsigned long ulcm;
  139. - if (fb_pdata == NULL) {
  140. + if (fb_pdata == NULL && !device->dev.of_node) {
  141. dev_err(&device->dev, "Can not get platform data\n");
  142. return -ENOENT;
  143. }
  144. @@ -1391,7 +1434,10 @@ static int fb_probe(struct platform_devi
  145. break;
  146. }
  147. - lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
  148. + if (device->dev.of_node)
  149. + lcd_cfg = da8xx_fb_create_cfg(device);
  150. + else
  151. + lcd_cfg = fb_pdata->controller_data;
  152. if (!lcd_cfg) {
  153. ret = -EINVAL;
  154. @@ -1410,7 +1456,7 @@ static int fb_probe(struct platform_devi
  155. par->dev = &device->dev;
  156. par->lcdc_clk = tmp_lcdc_clk;
  157. par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
  158. - if (fb_pdata->panel_power_ctrl) {
  159. + if (fb_pdata && fb_pdata->panel_power_ctrl) {
  160. par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
  161. par->panel_power_ctrl(1);
  162. }
  163. @@ -1654,12 +1700,26 @@ static int fb_resume(struct device *dev)
  164. static SIMPLE_DEV_PM_OPS(fb_pm_ops, fb_suspend, fb_resume);
  165. +#if IS_ENABLED(CONFIG_OF)
  166. +static const struct of_device_id da8xx_fb_of_match[] = {
  167. + /*
  168. + * this driver supports version 1 and version 2 of the
  169. + * Texas Instruments lcd controller (lcdc) hardware block
  170. + */
  171. + {.compatible = "ti,da8xx-tilcdc", },
  172. + {.compatible = "ti,am33xx-tilcdc", },
  173. + {},
  174. +};
  175. +MODULE_DEVICE_TABLE(of, da8xx_fb_of_match);
  176. +#endif
  177. +
  178. static struct platform_driver da8xx_fb_driver = {
  179. .probe = fb_probe,
  180. .remove = fb_remove,
  181. .driver = {
  182. .name = DRIVER_NAME,
  183. .owner = THIS_MODULE,
  184. + .of_match_table = of_match_ptr(da8xx_fb_of_match),
  185. .pm = &fb_pm_ops,
  186. },
  187. };