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