aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/dpi.c')
-rw-r--r--drivers/video/omap2/dss/dpi.c180
1 files changed, 106 insertions, 74 deletions
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 960e977a8bf0..ff6bd30132df 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -30,47 +30,73 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32 32
33#include <plat/display.h> 33#include <video/omapdss.h>
34#include <plat/cpu.h> 34#include <plat/cpu.h>
35 35
36#include "dss.h" 36#include "dss.h"
37 37
38static struct { 38static struct {
39 struct regulator *vdds_dsi_reg; 39 struct regulator *vdds_dsi_reg;
40 struct platform_device *dsidev;
40} dpi; 41} dpi;
41 42
42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 43static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
43static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req, 44{
44 unsigned long *fck, int *lck_div, int *pck_div) 45 int dsi_module;
46
47 dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1;
48
49 return dsi_get_dsidev_from_id(dsi_module);
50}
51
52static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
53{
54 if (dssdev->clocks.dispc.dispc_fclk_src ==
55 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
56 dssdev->clocks.dispc.dispc_fclk_src ==
57 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC ||
58 dssdev->clocks.dispc.channel.lcd_clk_src ==
59 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
60 dssdev->clocks.dispc.channel.lcd_clk_src ==
61 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC)
62 return true;
63 else
64 return false;
65}
66
67static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
68 unsigned long pck_req, unsigned long *fck, int *lck_div,
69 int *pck_div)
45{ 70{
46 struct dsi_clock_info dsi_cinfo; 71 struct dsi_clock_info dsi_cinfo;
47 struct dispc_clock_info dispc_cinfo; 72 struct dispc_clock_info dispc_cinfo;
48 int r; 73 int r;
49 74
50 r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo, 75 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req,
51 &dispc_cinfo); 76 &dsi_cinfo, &dispc_cinfo);
52 if (r) 77 if (r)
53 return r; 78 return r;
54 79
55 r = dsi_pll_set_clock_div(&dsi_cinfo); 80 r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo);
56 if (r) 81 if (r)
57 return r; 82 return r;
58 83
59 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 84 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
60 85
61 r = dispc_set_clock_div(&dispc_cinfo); 86 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
62 if (r) 87 if (r)
63 return r; 88 return r;
64 89
65 *fck = dsi_cinfo.dsi1_pll_fclk; 90 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
66 *lck_div = dispc_cinfo.lck_div; 91 *lck_div = dispc_cinfo.lck_div;
67 *pck_div = dispc_cinfo.pck_div; 92 *pck_div = dispc_cinfo.pck_div;
68 93
69 return 0; 94 return 0;
70} 95}
71#else 96
72static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req, 97static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
73 unsigned long *fck, int *lck_div, int *pck_div) 98 unsigned long pck_req, unsigned long *fck, int *lck_div,
99 int *pck_div)
74{ 100{
75 struct dss_clock_info dss_cinfo; 101 struct dss_clock_info dss_cinfo;
76 struct dispc_clock_info dispc_cinfo; 102 struct dispc_clock_info dispc_cinfo;
@@ -84,7 +110,7 @@ static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
84 if (r) 110 if (r)
85 return r; 111 return r;
86 112
87 r = dispc_set_clock_div(&dispc_cinfo); 113 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
88 if (r) 114 if (r)
89 return r; 115 return r;
90 116
@@ -94,31 +120,29 @@ static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
94 120
95 return 0; 121 return 0;
96} 122}
97#endif
98 123
99static int dpi_set_mode(struct omap_dss_device *dssdev) 124static int dpi_set_mode(struct omap_dss_device *dssdev)
100{ 125{
101 struct omap_video_timings *t = &dssdev->panel.timings; 126 struct omap_video_timings *t = &dssdev->panel.timings;
102 int lck_div, pck_div; 127 int lck_div = 0, pck_div = 0;
103 unsigned long fck; 128 unsigned long fck = 0;
104 unsigned long pck; 129 unsigned long pck;
105 bool is_tft; 130 bool is_tft;
106 int r = 0; 131 int r = 0;
107 132
108 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 133 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
109 134
110 dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, 135 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
111 dssdev->panel.acb); 136 dssdev->panel.acbi, dssdev->panel.acb);
112 137
113 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 138 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
114 139
115#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 140 if (dpi_use_dsi_pll(dssdev))
116 r = dpi_set_dsi_clk(is_tft, t->pixel_clock * 1000, 141 r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000,
117 &fck, &lck_div, &pck_div); 142 &fck, &lck_div, &pck_div);
118#else 143 else
119 r = dpi_set_dispc_clk(is_tft, t->pixel_clock * 1000, 144 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
120 &fck, &lck_div, &pck_div); 145 &fck, &lck_div, &pck_div);
121#endif
122 if (r) 146 if (r)
123 goto err0; 147 goto err0;
124 148
@@ -132,10 +156,10 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
132 t->pixel_clock = pck; 156 t->pixel_clock = pck;
133 } 157 }
134 158
135 dispc_set_lcd_timings(t); 159 dispc_set_lcd_timings(dssdev->manager->id, t);
136 160
137err0: 161err0:
138 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 162 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
139 return r; 163 return r;
140} 164}
141 165
@@ -145,10 +169,12 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
145 169
146 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 170 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
147 171
148 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); 172 dispc_set_parallel_interface_mode(dssdev->manager->id,
149 dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT : 173 OMAP_DSS_PARALLELMODE_BYPASS);
150 OMAP_DSS_LCD_DISPLAY_STN); 174 dispc_set_lcd_display_type(dssdev->manager->id, is_tft ?
151 dispc_set_tft_data_lines(dssdev->phy.dpi.data_lines); 175 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
176 dispc_set_tft_data_lines(dssdev->manager->id,
177 dssdev->phy.dpi.data_lines);
152 178
153 return 0; 179 return 0;
154} 180}
@@ -169,18 +195,19 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
169 goto err1; 195 goto err1;
170 } 196 }
171 197
172 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 198 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
173 199
174 r = dpi_basic_init(dssdev); 200 r = dpi_basic_init(dssdev);
175 if (r) 201 if (r)
176 goto err2; 202 goto err2;
177 203
178#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 204 if (dpi_use_dsi_pll(dssdev)) {
179 dss_clk_enable(DSS_CLK_FCK2); 205 dss_clk_enable(DSS_CLK_SYSCK);
180 r = dsi_pll_init(dssdev, 0, 1); 206 r = dsi_pll_init(dpi.dsidev, 0, 1);
181 if (r) 207 if (r)
182 goto err3; 208 goto err3;
183#endif 209 }
210
184 r = dpi_set_mode(dssdev); 211 r = dpi_set_mode(dssdev);
185 if (r) 212 if (r)
186 goto err4; 213 goto err4;
@@ -192,13 +219,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
192 return 0; 219 return 0;
193 220
194err4: 221err4:
195#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 222 if (dpi_use_dsi_pll(dssdev))
196 dsi_pll_uninit(); 223 dsi_pll_uninit(dpi.dsidev, true);
197err3: 224err3:
198 dss_clk_disable(DSS_CLK_FCK2); 225 if (dpi_use_dsi_pll(dssdev))
199#endif 226 dss_clk_disable(DSS_CLK_SYSCK);
200err2: 227err2:
201 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 228 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
202 if (cpu_is_omap34xx()) 229 if (cpu_is_omap34xx())
203 regulator_disable(dpi.vdds_dsi_reg); 230 regulator_disable(dpi.vdds_dsi_reg);
204err1: 231err1:
@@ -212,13 +239,13 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
212{ 239{
213 dssdev->manager->disable(dssdev->manager); 240 dssdev->manager->disable(dssdev->manager);
214 241
215#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 242 if (dpi_use_dsi_pll(dssdev)) {
216 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 243 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
217 dsi_pll_uninit(); 244 dsi_pll_uninit(dpi.dsidev, true);
218 dss_clk_disable(DSS_CLK_FCK2); 245 dss_clk_disable(DSS_CLK_SYSCK);
219#endif 246 }
220 247
221 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 248 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
222 249
223 if (cpu_is_omap34xx()) 250 if (cpu_is_omap34xx())
224 regulator_disable(dpi.vdds_dsi_reg); 251 regulator_disable(dpi.vdds_dsi_reg);
@@ -234,7 +261,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
234 dssdev->panel.timings = *timings; 261 dssdev->panel.timings = *timings;
235 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 262 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
236 dpi_set_mode(dssdev); 263 dpi_set_mode(dssdev);
237 dispc_go(OMAP_DSS_CHANNEL_LCD); 264 dispc_go(dssdev->manager->id);
238 } 265 }
239} 266}
240EXPORT_SYMBOL(dpi_set_timings); 267EXPORT_SYMBOL(dpi_set_timings);
@@ -247,6 +274,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
247 int lck_div, pck_div; 274 int lck_div, pck_div;
248 unsigned long fck; 275 unsigned long fck;
249 unsigned long pck; 276 unsigned long pck;
277 struct dispc_clock_info dispc_cinfo;
250 278
251 if (!dispc_lcd_timings_ok(timings)) 279 if (!dispc_lcd_timings_ok(timings))
252 return -EINVAL; 280 return -EINVAL;
@@ -256,25 +284,18 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
256 284
257 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 285 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
258 286
259#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 287 if (dpi_use_dsi_pll(dssdev)) {
260 {
261 struct dsi_clock_info dsi_cinfo; 288 struct dsi_clock_info dsi_cinfo;
262 struct dispc_clock_info dispc_cinfo; 289 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft,
263 r = dsi_pll_calc_clock_div_pck(is_tft,
264 timings->pixel_clock * 1000, 290 timings->pixel_clock * 1000,
265 &dsi_cinfo, &dispc_cinfo); 291 &dsi_cinfo, &dispc_cinfo);
266 292
267 if (r) 293 if (r)
268 return r; 294 return r;
269 295
270 fck = dsi_cinfo.dsi1_pll_fclk; 296 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
271 lck_div = dispc_cinfo.lck_div; 297 } else {
272 pck_div = dispc_cinfo.pck_div;
273 }
274#else
275 {
276 struct dss_clock_info dss_cinfo; 298 struct dss_clock_info dss_cinfo;
277 struct dispc_clock_info dispc_cinfo;
278 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000, 299 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000,
279 &dss_cinfo, &dispc_cinfo); 300 &dss_cinfo, &dispc_cinfo);
280 301
@@ -282,10 +303,10 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
282 return r; 303 return r;
283 304
284 fck = dss_cinfo.fck; 305 fck = dss_cinfo.fck;
285 lck_div = dispc_cinfo.lck_div;
286 pck_div = dispc_cinfo.pck_div;
287 } 306 }
288#endif 307
308 lck_div = dispc_cinfo.lck_div;
309 pck_div = dispc_cinfo.pck_div;
289 310
290 pck = fck / lck_div / pck_div / 1000; 311 pck = fck / lck_div / pck_div / 1000;
291 312
@@ -299,22 +320,33 @@ int dpi_init_display(struct omap_dss_device *dssdev)
299{ 320{
300 DSSDBG("init_display\n"); 321 DSSDBG("init_display\n");
301 322
302 return 0; 323 if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
303} 324 struct regulator *vdds_dsi;
304 325
305int dpi_init(struct platform_device *pdev) 326 vdds_dsi = dss_get_vdds_dsi();
306{ 327
307 if (cpu_is_omap34xx()) { 328 if (IS_ERR(vdds_dsi)) {
308 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
309 if (IS_ERR(dpi.vdds_dsi_reg)) {
310 DSSERR("can't get VDDS_DSI regulator\n"); 329 DSSERR("can't get VDDS_DSI regulator\n");
311 return PTR_ERR(dpi.vdds_dsi_reg); 330 return PTR_ERR(vdds_dsi);
312 } 331 }
332
333 dpi.vdds_dsi_reg = vdds_dsi;
334 }
335
336 if (dpi_use_dsi_pll(dssdev)) {
337 enum omap_dss_clk_source dispc_fclk_src =
338 dssdev->clocks.dispc.dispc_fclk_src;
339 dpi.dsidev = dpi_get_dsidev(dispc_fclk_src);
313 } 340 }
314 341
315 return 0; 342 return 0;
316} 343}
317 344
345int dpi_init(void)
346{
347 return 0;
348}
349
318void dpi_exit(void) 350void dpi_exit(void)
319{ 351{
320} 352}