aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/sdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/sdi.c')
-rw-r--r--drivers/video/omap2/dss/sdi.c126
1 files changed, 103 insertions, 23 deletions
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index f43bfe17b3b6..7760851f6e5d 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -25,6 +25,7 @@
25#include <linux/regulator/consumer.h> 25#include <linux/regulator/consumer.h>
26#include <linux/export.h> 26#include <linux/export.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/string.h>
28 29
29#include <video/omapdss.h> 30#include <video/omapdss.h>
30#include "dss.h" 31#include "dss.h"
@@ -34,10 +35,16 @@ static struct {
34 struct regulator *vdds_sdi_reg; 35 struct regulator *vdds_sdi_reg;
35 36
36 struct dss_lcd_mgr_config mgr_config; 37 struct dss_lcd_mgr_config mgr_config;
38 struct omap_video_timings timings;
39 int datapairs;
40
41 struct omap_dss_output output;
37} sdi; 42} sdi;
38 43
39static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) 44static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
40{ 45{
46 struct omap_overlay_manager *mgr = dssdev->output->manager;
47
41 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 48 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
42 49
43 sdi.mgr_config.stallmode = false; 50 sdi.mgr_config.stallmode = false;
@@ -46,19 +53,20 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
46 sdi.mgr_config.video_port_width = 24; 53 sdi.mgr_config.video_port_width = 24;
47 sdi.mgr_config.lcden_sig_polarity = 1; 54 sdi.mgr_config.lcden_sig_polarity = 1;
48 55
49 dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config); 56 dss_mgr_set_lcd_config(mgr, &sdi.mgr_config);
50} 57}
51 58
52int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) 59int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
53{ 60{
54 struct omap_video_timings *t = &dssdev->panel.timings; 61 struct omap_dss_output *out = dssdev->output;
62 struct omap_video_timings *t = &sdi.timings;
55 struct dss_clock_info dss_cinfo; 63 struct dss_clock_info dss_cinfo;
56 struct dispc_clock_info dispc_cinfo; 64 struct dispc_clock_info dispc_cinfo;
57 unsigned long pck; 65 unsigned long pck;
58 int r; 66 int r;
59 67
60 if (dssdev->manager == NULL) { 68 if (out == NULL || out->manager == NULL) {
61 DSSERR("failed to enable display: no manager\n"); 69 DSSERR("failed to enable display: no output/manager\n");
62 return -ENODEV; 70 return -ENODEV;
63 } 71 }
64 72
@@ -77,8 +85,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
77 goto err_get_dispc; 85 goto err_get_dispc;
78 86
79 /* 15.5.9.1.2 */ 87 /* 15.5.9.1.2 */
80 dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 88 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
81 dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 89 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
82 90
83 r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); 91 r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
84 if (r) 92 if (r)
@@ -97,7 +105,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
97 } 105 }
98 106
99 107
100 dss_mgr_set_timings(dssdev->manager, t); 108 dss_mgr_set_timings(out->manager, t);
101 109
102 r = dss_set_clock_div(&dss_cinfo); 110 r = dss_set_clock_div(&dss_cinfo);
103 if (r) 111 if (r)
@@ -116,16 +124,15 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
116 * need to care about the shadow register mechanism for pck-free. The 124 * need to care about the shadow register mechanism for pck-free. The
117 * exact reason for this is unknown. 125 * exact reason for this is unknown.
118 */ 126 */
119 dispc_mgr_set_clock_div(dssdev->manager->id, 127 dispc_mgr_set_clock_div(out->manager->id, &sdi.mgr_config.clock_info);
120 &sdi.mgr_config.clock_info);
121 128
122 dss_sdi_init(dssdev->phy.sdi.datapairs); 129 dss_sdi_init(sdi.datapairs);
123 r = dss_sdi_enable(); 130 r = dss_sdi_enable();
124 if (r) 131 if (r)
125 goto err_sdi_enable; 132 goto err_sdi_enable;
126 mdelay(2); 133 mdelay(2);
127 134
128 r = dss_mgr_enable(dssdev->manager); 135 r = dss_mgr_enable(out->manager);
129 if (r) 136 if (r)
130 goto err_mgr_enable; 137 goto err_mgr_enable;
131 138
@@ -148,7 +155,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
148 155
149void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) 156void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
150{ 157{
151 dss_mgr_disable(dssdev->manager); 158 struct omap_overlay_manager *mgr = dssdev->output->manager;
159
160 dss_mgr_disable(mgr);
152 161
153 dss_sdi_disable(); 162 dss_sdi_disable();
154 163
@@ -160,6 +169,19 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
160} 169}
161EXPORT_SYMBOL(omapdss_sdi_display_disable); 170EXPORT_SYMBOL(omapdss_sdi_display_disable);
162 171
172void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
173 struct omap_video_timings *timings)
174{
175 sdi.timings = *timings;
176}
177EXPORT_SYMBOL(omapdss_sdi_set_timings);
178
179void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
180{
181 sdi.datapairs = datapairs;
182}
183EXPORT_SYMBOL(omapdss_sdi_set_datapairs);
184
163static int __init sdi_init_display(struct omap_dss_device *dssdev) 185static int __init sdi_init_display(struct omap_dss_device *dssdev)
164{ 186{
165 DSSDBG("SDI init\n"); 187 DSSDBG("SDI init\n");
@@ -180,10 +202,14 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
180 return 0; 202 return 0;
181} 203}
182 204
183static void __init sdi_probe_pdata(struct platform_device *pdev) 205static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
184{ 206{
185 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 207 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
186 int i, r; 208 const char *def_disp_name = dss_get_default_display_name();
209 struct omap_dss_device *def_dssdev;
210 int i;
211
212 def_dssdev = NULL;
187 213
188 for (i = 0; i < pdata->num_devices; ++i) { 214 for (i = 0; i < pdata->num_devices; ++i) {
189 struct omap_dss_device *dssdev = pdata->devices[i]; 215 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -191,21 +217,73 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
191 if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) 217 if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
192 continue; 218 continue;
193 219
194 r = sdi_init_display(dssdev); 220 if (def_dssdev == NULL)
195 if (r) { 221 def_dssdev = dssdev;
196 DSSERR("device %s init failed: %d\n", dssdev->name, r); 222
197 continue; 223 if (def_disp_name != NULL &&
224 strcmp(dssdev->name, def_disp_name) == 0) {
225 def_dssdev = dssdev;
226 break;
198 } 227 }
228 }
229
230 return def_dssdev;
231}
232
233static void __init sdi_probe_pdata(struct platform_device *sdidev)
234{
235 struct omap_dss_device *plat_dssdev;
236 struct omap_dss_device *dssdev;
237 int r;
238
239 plat_dssdev = sdi_find_dssdev(sdidev);
199 240
200 r = omap_dss_register_device(dssdev, &pdev->dev, i); 241 if (!plat_dssdev)
201 if (r) 242 return;
202 DSSERR("device %s register failed: %d\n", 243
203 dssdev->name, r); 244 dssdev = dss_alloc_and_init_device(&sdidev->dev);
245 if (!dssdev)
246 return;
247
248 dss_copy_device_pdata(dssdev, plat_dssdev);
249
250 r = sdi_init_display(dssdev);
251 if (r) {
252 DSSERR("device %s init failed: %d\n", dssdev->name, r);
253 dss_put_device(dssdev);
254 return;
204 } 255 }
256
257 r = dss_add_device(dssdev);
258 if (r) {
259 DSSERR("device %s register failed: %d\n", dssdev->name, r);
260 dss_put_device(dssdev);
261 return;
262 }
263}
264
265static void __init sdi_init_output(struct platform_device *pdev)
266{
267 struct omap_dss_output *out = &sdi.output;
268
269 out->pdev = pdev;
270 out->id = OMAP_DSS_OUTPUT_SDI;
271 out->type = OMAP_DISPLAY_TYPE_SDI;
272
273 dss_register_output(out);
274}
275
276static void __exit sdi_uninit_output(struct platform_device *pdev)
277{
278 struct omap_dss_output *out = &sdi.output;
279
280 dss_unregister_output(out);
205} 281}
206 282
207static int __init omap_sdi_probe(struct platform_device *pdev) 283static int __init omap_sdi_probe(struct platform_device *pdev)
208{ 284{
285 sdi_init_output(pdev);
286
209 sdi_probe_pdata(pdev); 287 sdi_probe_pdata(pdev);
210 288
211 return 0; 289 return 0;
@@ -213,7 +291,9 @@ static int __init omap_sdi_probe(struct platform_device *pdev)
213 291
214static int __exit omap_sdi_remove(struct platform_device *pdev) 292static int __exit omap_sdi_remove(struct platform_device *pdev)
215{ 293{
216 omap_dss_unregister_child_devices(&pdev->dev); 294 dss_unregister_child_devices(&pdev->dev);
295
296 sdi_uninit_output(pdev);
217 297
218 return 0; 298 return 0;
219} 299}