aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/omap2/dss/apply.c85
-rw-r--r--drivers/video/omap2/dss/dispc.c26
-rw-r--r--drivers/video/omap2/dss/display.c34
-rw-r--r--drivers/video/omap2/dss/dpi.c31
-rw-r--r--drivers/video/omap2/dss/dsi.c91
-rw-r--r--drivers/video/omap2/dss/dss.h31
-rw-r--r--drivers/video/omap2/dss/manager.c35
-rw-r--r--drivers/video/omap2/dss/overlay.c13
-rw-r--r--drivers/video/omap2/dss/rfbi.c39
-rw-r--r--drivers/video/omap2/dss/sdi.c32
10 files changed, 271 insertions, 146 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 3ce7a3ec6224..0fefc68372b9 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -104,6 +104,7 @@ struct mgr_priv_data {
104 bool shadow_extra_info_dirty; 104 bool shadow_extra_info_dirty;
105 105
106 struct omap_video_timings timings; 106 struct omap_video_timings timings;
107 struct dss_lcd_mgr_config lcd_config;
107}; 108};
108 109
109static struct { 110static struct {
@@ -137,6 +138,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
137void dss_apply_init(void) 138void dss_apply_init(void)
138{ 139{
139 const int num_ovls = dss_feat_get_num_ovls(); 140 const int num_ovls = dss_feat_get_num_ovls();
141 struct mgr_priv_data *mp;
140 int i; 142 int i;
141 143
142 spin_lock_init(&data_lock); 144 spin_lock_init(&data_lock);
@@ -168,16 +170,35 @@ void dss_apply_init(void)
168 170
169 op->user_info = op->info; 171 op->user_info = op->info;
170 } 172 }
173
174 /*
175 * Initialize some of the lcd_config fields for TV manager, this lets
176 * us prevent checking if the manager is LCD or TV at some places
177 */
178 mp = &dss_data.mgr_priv_data_array[OMAP_DSS_CHANNEL_DIGIT];
179
180 mp->lcd_config.video_port_width = 24;
181 mp->lcd_config.clock_info.lck_div = 1;
182 mp->lcd_config.clock_info.pck_div = 1;
171} 183}
172 184
185/*
186 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
187 * manager is always auto update, stallmode field for TV manager is false by
188 * default
189 */
173static bool ovl_manual_update(struct omap_overlay *ovl) 190static bool ovl_manual_update(struct omap_overlay *ovl)
174{ 191{
175 return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 192 struct mgr_priv_data *mp = get_mgr_priv(ovl->manager);
193
194 return mp->lcd_config.stallmode;
176} 195}
177 196
178static bool mgr_manual_update(struct omap_overlay_manager *mgr) 197static bool mgr_manual_update(struct omap_overlay_manager *mgr)
179{ 198{
180 return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 199 struct mgr_priv_data *mp = get_mgr_priv(mgr);
200
201 return mp->lcd_config.stallmode;
181} 202}
182 203
183static int dss_check_settings_low(struct omap_overlay_manager *mgr, 204static int dss_check_settings_low(struct omap_overlay_manager *mgr,
@@ -214,7 +235,7 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr,
214 ois[ovl->id] = oi; 235 ois[ovl->id] = oi;
215 } 236 }
216 237
217 return dss_mgr_check(mgr, mi, &mp->timings, ois); 238 return dss_mgr_check(mgr, mi, &mp->timings, &mp->lcd_config, ois);
218} 239}
219 240
220/* 241/*
@@ -550,7 +571,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
550 571
551 mp = get_mgr_priv(ovl->manager); 572 mp = get_mgr_priv(ovl->manager);
552 573
553 replication = dss_use_replication(ovl->manager->device, oi->color_mode); 574 replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
554 575
555 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings); 576 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
556 if (r) { 577 if (r) {
@@ -633,6 +654,24 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
633 654
634 dispc_mgr_set_timings(mgr->id, &mp->timings); 655 dispc_mgr_set_timings(mgr->id, &mp->timings);
635 656
657 /* lcd_config parameters */
658 if (dss_mgr_is_lcd(mgr->id)) {
659 dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode);
660
661 dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
662 dispc_mgr_enable_fifohandcheck(mgr->id,
663 mp->lcd_config.fifohandcheck);
664
665 dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
666
667 dispc_mgr_set_tft_data_lines(mgr->id,
668 mp->lcd_config.video_port_width);
669
670 dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
671
672 dispc_mgr_set_lcd_type_tft(mgr->id);
673 }
674
636 mp->extra_info_dirty = false; 675 mp->extra_info_dirty = false;
637 if (mp->updating) 676 if (mp->updating)
638 mp->shadow_extra_info_dirty = true; 677 mp->shadow_extra_info_dirty = true;
@@ -1292,6 +1331,44 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
1292 mutex_unlock(&apply_lock); 1331 mutex_unlock(&apply_lock);
1293} 1332}
1294 1333
1334static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
1335 const struct dss_lcd_mgr_config *config)
1336{
1337 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1338
1339 mp->lcd_config = *config;
1340 mp->extra_info_dirty = true;
1341}
1342
1343void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
1344 const struct dss_lcd_mgr_config *config)
1345{
1346 unsigned long flags;
1347 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1348
1349 mutex_lock(&apply_lock);
1350
1351 if (mp->enabled) {
1352 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1353 mgr->name);
1354 goto out;
1355 }
1356
1357 spin_lock_irqsave(&data_lock, flags);
1358
1359 dss_apply_mgr_lcd_config(mgr, config);
1360
1361 dss_write_regs();
1362 dss_set_go_bits();
1363
1364 spin_unlock_irqrestore(&data_lock, flags);
1365
1366 wait_pending_extra_info_updates();
1367
1368out:
1369 mutex_unlock(&apply_lock);
1370}
1371
1295int dss_ovl_set_info(struct omap_overlay *ovl, 1372int dss_ovl_set_info(struct omap_overlay *ovl,
1296 struct omap_overlay_info *info) 1373 struct omap_overlay_info *info)
1297{ 1374{
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d1a7a0c90289..5b289c5f695b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -498,16 +498,6 @@ void dispc_runtime_put(void)
498 WARN_ON(r < 0 && r != -ENOSYS); 498 WARN_ON(r < 0 && r != -ENOSYS);
499} 499}
500 500
501static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
502{
503 if (channel == OMAP_DSS_CHANNEL_LCD ||
504 channel == OMAP_DSS_CHANNEL_LCD2 ||
505 channel == OMAP_DSS_CHANNEL_LCD3)
506 return true;
507 else
508 return false;
509}
510
511u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 501u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
512{ 502{
513 return mgr_desc[channel].vsync_irq; 503 return mgr_desc[channel].vsync_irq;
@@ -1010,7 +1000,7 @@ static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
1010{ 1000{
1011 u32 coef_r, coef_g, coef_b; 1001 u32 coef_r, coef_g, coef_b;
1012 1002
1013 if (!dispc_mgr_is_lcd(channel)) 1003 if (!dss_mgr_is_lcd(channel))
1014 return; 1004 return;
1015 1005
1016 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | 1006 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) |
@@ -1869,7 +1859,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
1869 1859
1870 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; 1860 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
1871 pclk = dispc_mgr_pclk_rate(channel); 1861 pclk = dispc_mgr_pclk_rate(channel);
1872 if (dispc_mgr_is_lcd(channel)) 1862 if (dss_mgr_is_lcd(channel))
1873 lclk = dispc_mgr_lclk_rate(channel); 1863 lclk = dispc_mgr_lclk_rate(channel);
1874 else 1864 else
1875 lclk = dispc_fclk_rate(); 1865 lclk = dispc_fclk_rate();
@@ -2452,7 +2442,7 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
2452 2442
2453void dispc_mgr_enable(enum omap_channel channel, bool enable) 2443void dispc_mgr_enable(enum omap_channel channel, bool enable)
2454{ 2444{
2455 if (dispc_mgr_is_lcd(channel)) 2445 if (dss_mgr_is_lcd(channel))
2456 dispc_mgr_enable_lcd_out(channel, enable); 2446 dispc_mgr_enable_lcd_out(channel, enable);
2457 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 2447 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2458 dispc_mgr_enable_digit_out(enable); 2448 dispc_mgr_enable_digit_out(enable);
@@ -2642,7 +2632,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
2642 2632
2643 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); 2633 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
2644 2634
2645 if (dispc_mgr_is_lcd(channel)) 2635 if (dss_mgr_is_lcd(channel))
2646 timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, 2636 timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw,
2647 timings->hfp, timings->hbp, 2637 timings->hfp, timings->hbp,
2648 timings->vsw, timings->vfp, 2638 timings->vsw, timings->vfp,
@@ -2734,7 +2724,7 @@ void dispc_mgr_set_timings(enum omap_channel channel,
2734 return; 2724 return;
2735 } 2725 }
2736 2726
2737 if (dispc_mgr_is_lcd(channel)) { 2727 if (dss_mgr_is_lcd(channel)) {
2738 _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw, 2728 _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw,
2739 t.vfp, t.vbp, t.vsync_level, t.hsync_level, 2729 t.vfp, t.vbp, t.vsync_level, t.hsync_level,
2740 t.data_pclk_edge, t.de_level, t.sync_pclk_edge); 2730 t.data_pclk_edge, t.de_level, t.sync_pclk_edge);
@@ -2840,7 +2830,7 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
2840{ 2830{
2841 unsigned long r; 2831 unsigned long r;
2842 2832
2843 if (dispc_mgr_is_lcd(channel)) { 2833 if (dss_mgr_is_lcd(channel)) {
2844 int pcd; 2834 int pcd;
2845 u32 l; 2835 u32 l;
2846 2836
@@ -3224,15 +3214,13 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3224 return 0; 3214 return 0;
3225} 3215}
3226 3216
3227int dispc_mgr_set_clock_div(enum omap_channel channel, 3217void dispc_mgr_set_clock_div(enum omap_channel channel,
3228 struct dispc_clock_info *cinfo) 3218 struct dispc_clock_info *cinfo)
3229{ 3219{
3230 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 3220 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
3231 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 3221 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
3232 3222
3233 dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div); 3223 dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
3234
3235 return 0;
3236} 3224}
3237 3225
3238int dispc_mgr_get_clock_div(enum omap_channel channel, 3226int dispc_mgr_get_clock_div(enum omap_channel channel,
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 1a0c15f83d0d..5bd957e85505 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -316,40 +316,6 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
316} 316}
317EXPORT_SYMBOL(omapdss_default_get_timings); 317EXPORT_SYMBOL(omapdss_default_get_timings);
318 318
319/* Checks if replication logic should be used. Only use for active matrix,
320 * when overlay is in RGB12U or RGB16 mode, and LCD interface is
321 * 18bpp or 24bpp */
322bool dss_use_replication(struct omap_dss_device *dssdev,
323 enum omap_color_mode mode)
324{
325 int bpp;
326
327 if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
328 return false;
329
330 switch (dssdev->type) {
331 case OMAP_DISPLAY_TYPE_DPI:
332 bpp = dssdev->phy.dpi.data_lines;
333 break;
334 case OMAP_DISPLAY_TYPE_HDMI:
335 case OMAP_DISPLAY_TYPE_VENC:
336 case OMAP_DISPLAY_TYPE_SDI:
337 bpp = 24;
338 break;
339 case OMAP_DISPLAY_TYPE_DBI:
340 bpp = dssdev->ctrl.pixel_size;
341 break;
342 case OMAP_DISPLAY_TYPE_DSI:
343 bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
344 break;
345 default:
346 BUG();
347 return false;
348 }
349
350 return bpp > 16;
351}
352
353void dss_init_device(struct platform_device *pdev, 319void dss_init_device(struct platform_device *pdev,
354 struct omap_dss_device *dssdev) 320 struct omap_dss_device *dssdev)
355{ 321{
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index a81b6d6deb57..3266be23fc0d 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -38,6 +38,8 @@
38static struct { 38static struct {
39 struct regulator *vdds_dsi_reg; 39 struct regulator *vdds_dsi_reg;
40 struct platform_device *dsidev; 40 struct platform_device *dsidev;
41
42 struct dss_lcd_mgr_config mgr_config;
41} dpi; 43} dpi;
42 44
43static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) 45static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -83,11 +85,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
83 85
84 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 86 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
85 87
86 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 88 dpi.mgr_config.clock_info = dispc_cinfo;
87 if (r) {
88 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
89 return r;
90 }
91 89
92 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 90 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
93 *lck_div = dispc_cinfo.lck_div; 91 *lck_div = dispc_cinfo.lck_div;
@@ -112,9 +110,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
112 if (r) 110 if (r)
113 return r; 111 return r;
114 112
115 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 113 dpi.mgr_config.clock_info = dispc_cinfo;
116 if (r)
117 return r;
118 114
119 *fck = dss_cinfo.fck; 115 *fck = dss_cinfo.fck;
120 *lck_div = dispc_cinfo.lck_div; 116 *lck_div = dispc_cinfo.lck_div;
@@ -155,15 +151,18 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
155 return 0; 151 return 0;
156} 152}
157 153
158static void dpi_basic_init(struct omap_dss_device *dssdev) 154static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
159{ 155{
160 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); 156 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
161 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 157
158 dpi.mgr_config.stallmode = false;
159 dpi.mgr_config.fifohandcheck = false;
160
161 dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
162 162
163 dispc_mgr_set_lcd_type_tft(dssdev->manager->id); 163 dpi.mgr_config.lcden_sig_polarity = 0;
164 164
165 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 165 dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
166 dssdev->phy.dpi.data_lines);
167} 166}
168 167
169int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 168int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
@@ -196,8 +195,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
196 if (r) 195 if (r)
197 goto err_get_dispc; 196 goto err_get_dispc;
198 197
199 dpi_basic_init(dssdev);
200
201 if (dpi_use_dsi_pll(dssdev)) { 198 if (dpi_use_dsi_pll(dssdev)) {
202 r = dsi_runtime_get(dpi.dsidev); 199 r = dsi_runtime_get(dpi.dsidev);
203 if (r) 200 if (r)
@@ -212,6 +209,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
212 if (r) 209 if (r)
213 goto err_set_mode; 210 goto err_set_mode;
214 211
212 dpi_config_lcd_manager(dssdev);
213
215 mdelay(2); 214 mdelay(2);
216 215
217 r = dss_mgr_enable(dssdev->manager); 216 r = dss_mgr_enable(dssdev->manager);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index e0d43b275e3e..b07e8864f82f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -331,6 +331,8 @@ struct dsi_data {
331 unsigned num_lanes_used; 331 unsigned num_lanes_used;
332 332
333 unsigned scp_clk_refcount; 333 unsigned scp_clk_refcount;
334
335 struct dss_lcd_mgr_config mgr_config;
334}; 336};
335 337
336struct dsi_packet_sent_handler_data { 338struct dsi_packet_sent_handler_data {
@@ -4337,14 +4339,40 @@ EXPORT_SYMBOL(omap_dsi_update);
4337 4339
4338/* Display funcs */ 4340/* Display funcs */
4339 4341
4340static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4342static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4341{ 4343{
4344 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4345 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4346 struct dispc_clock_info dispc_cinfo;
4342 int r; 4347 int r;
4348 unsigned long long fck;
4349
4350 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
4351
4352 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
4353 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
4354
4355 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
4356 if (r) {
4357 DSSERR("Failed to calc dispc clocks\n");
4358 return r;
4359 }
4360
4361 dsi->mgr_config.clock_info = dispc_cinfo;
4362
4363 return 0;
4364}
4365
4366static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4367{
4368 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4369 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4343 struct omap_video_timings timings; 4370 struct omap_video_timings timings;
4371 int r;
4372 u32 irq = 0;
4344 4373
4345 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { 4374 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4346 u16 dw, dh; 4375 u16 dw, dh;
4347 u32 irq;
4348 4376
4349 dssdev->driver->get_resolution(dssdev, &dw, &dh); 4377 dssdev->driver->get_resolution(dssdev, &dw, &dh);
4350 4378
@@ -4363,16 +4391,16 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4363 (void *) dssdev, irq); 4391 (void *) dssdev, irq);
4364 if (r) { 4392 if (r) {
4365 DSSERR("can't get FRAMEDONE irq\n"); 4393 DSSERR("can't get FRAMEDONE irq\n");
4366 return r; 4394 goto err;
4367 } 4395 }
4368 4396
4369 dispc_mgr_enable_stallmode(dssdev->manager->id, true); 4397 dsi->mgr_config.stallmode = true;
4370 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); 4398 dsi->mgr_config.fifohandcheck = true;
4371 } else { 4399 } else {
4372 timings = dssdev->panel.timings; 4400 timings = dssdev->panel.timings;
4373 4401
4374 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 4402 dsi->mgr_config.stallmode = false;
4375 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0); 4403 dsi->mgr_config.fifohandcheck = false;
4376 } 4404 }
4377 4405
4378 /* 4406 /*
@@ -4388,12 +4416,24 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4388 4416
4389 dss_mgr_set_timings(dssdev->manager, &timings); 4417 dss_mgr_set_timings(dssdev->manager, &timings);
4390 4418
4391 dispc_mgr_set_lcd_type_tft(dssdev->manager->id); 4419 r = dsi_configure_dispc_clocks(dssdev);
4420 if (r)
4421 goto err1;
4422
4423 dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
4424 dsi->mgr_config.video_port_width =
4425 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
4426 dsi->mgr_config.lcden_sig_polarity = 0;
4392 4427
4393 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 4428 dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
4394 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt));
4395 4429
4396 return 0; 4430 return 0;
4431err1:
4432 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE)
4433 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4434 (void *) dssdev, irq);
4435err:
4436 return r;
4397} 4437}
4398 4438
4399static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4439static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
@@ -4433,33 +4473,6 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
4433 return 0; 4473 return 0;
4434} 4474}
4435 4475
4436static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4437{
4438 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4439 struct dispc_clock_info dispc_cinfo;
4440 int r;
4441 unsigned long long fck;
4442
4443 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
4444
4445 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
4446 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
4447
4448 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
4449 if (r) {
4450 DSSERR("Failed to calc dispc clocks\n");
4451 return r;
4452 }
4453
4454 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
4455 if (r) {
4456 DSSERR("Failed to set dispc clocks\n");
4457 return r;
4458 }
4459
4460 return 0;
4461}
4462
4463static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4476static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4464{ 4477{
4465 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4478 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4481,10 +4494,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4481 4494
4482 DSSDBG("PLL OK\n"); 4495 DSSDBG("PLL OK\n");
4483 4496
4484 r = dsi_configure_dispc_clocks(dssdev);
4485 if (r)
4486 goto err2;
4487
4488 r = dsi_cio_init(dssdev); 4497 r = dsi_cio_init(dssdev);
4489 if (r) 4498 if (r)
4490 goto err2; 4499 goto err2;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6c5ecf02759e..f67afe76f217 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -158,6 +158,19 @@ struct reg_field {
158 u8 low; 158 u8 low;
159}; 159};
160 160
161struct dss_lcd_mgr_config {
162 enum dss_io_pad_mode io_pad_mode;
163
164 bool stallmode;
165 bool fifohandcheck;
166
167 struct dispc_clock_info clock_info;
168
169 int video_port_width;
170
171 int lcden_sig_polarity;
172};
173
161struct seq_file; 174struct seq_file;
162struct platform_device; 175struct platform_device;
163 176
@@ -194,6 +207,8 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
194int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 207int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
195void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 208void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
196 struct omap_video_timings *timings); 209 struct omap_video_timings *timings);
210void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
211 const struct dss_lcd_mgr_config *config);
197const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); 212const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
198 213
199bool dss_ovl_is_enabled(struct omap_overlay *ovl); 214bool dss_ovl_is_enabled(struct omap_overlay *ovl);
@@ -216,8 +231,6 @@ void dss_init_device(struct platform_device *pdev,
216 struct omap_dss_device *dssdev); 231 struct omap_dss_device *dssdev);
217void dss_uninit_device(struct platform_device *pdev, 232void dss_uninit_device(struct platform_device *pdev,
218 struct omap_dss_device *dssdev); 233 struct omap_dss_device *dssdev);
219bool dss_use_replication(struct omap_dss_device *dssdev,
220 enum omap_color_mode mode);
221 234
222/* manager */ 235/* manager */
223int dss_init_overlay_managers(struct platform_device *pdev); 236int dss_init_overlay_managers(struct platform_device *pdev);
@@ -229,8 +242,18 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
229int dss_mgr_check(struct omap_overlay_manager *mgr, 242int dss_mgr_check(struct omap_overlay_manager *mgr,
230 struct omap_overlay_manager_info *info, 243 struct omap_overlay_manager_info *info,
231 const struct omap_video_timings *mgr_timings, 244 const struct omap_video_timings *mgr_timings,
245 const struct dss_lcd_mgr_config *config,
232 struct omap_overlay_info **overlay_infos); 246 struct omap_overlay_info **overlay_infos);
233 247
248static inline bool dss_mgr_is_lcd(enum omap_channel id)
249{
250 if (id == OMAP_DSS_CHANNEL_LCD || id == OMAP_DSS_CHANNEL_LCD2 ||
251 id == OMAP_DSS_CHANNEL_LCD3)
252 return true;
253 else
254 return false;
255}
256
234/* overlay */ 257/* overlay */
235void dss_init_overlays(struct platform_device *pdev); 258void dss_init_overlays(struct platform_device *pdev);
236void dss_uninit_overlays(struct platform_device *pdev); 259void dss_uninit_overlays(struct platform_device *pdev);
@@ -240,6 +263,8 @@ int dss_ovl_simple_check(struct omap_overlay *ovl,
240 const struct omap_overlay_info *info); 263 const struct omap_overlay_info *info);
241int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, 264int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
242 const struct omap_video_timings *mgr_timings); 265 const struct omap_video_timings *mgr_timings);
266bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
267 enum omap_color_mode mode);
243 268
244/* DSS */ 269/* DSS */
245int dss_init_platform_driver(void) __init; 270int dss_init_platform_driver(void) __init;
@@ -425,7 +450,7 @@ void dispc_mgr_set_timings(enum omap_channel channel,
425unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 450unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
426unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 451unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
427unsigned long dispc_core_clk_rate(void); 452unsigned long dispc_core_clk_rate(void);
428int dispc_mgr_set_clock_div(enum omap_channel channel, 453void dispc_mgr_set_clock_div(enum omap_channel channel,
429 struct dispc_clock_info *cinfo); 454 struct dispc_clock_info *cinfo);
430int dispc_mgr_get_clock_div(enum omap_channel channel, 455int dispc_mgr_get_clock_div(enum omap_channel channel,
431 struct dispc_clock_info *cinfo); 456 struct dispc_clock_info *cinfo);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index a51eb060c142..53710fadc82d 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -665,9 +665,40 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
665 return 0; 665 return 0;
666} 666}
667 667
668static int dss_mgr_check_lcd_config(struct omap_overlay_manager *mgr,
669 const struct dss_lcd_mgr_config *config)
670{
671 struct dispc_clock_info cinfo = config->clock_info;
672 int dl = config->video_port_width;
673 bool stallmode = config->stallmode;
674 bool fifohandcheck = config->fifohandcheck;
675
676 if (cinfo.lck_div < 1 || cinfo.lck_div > 255)
677 return -EINVAL;
678
679 if (cinfo.pck_div < 1 || cinfo.pck_div > 255)
680 return -EINVAL;
681
682 if (dl != 12 && dl != 16 && dl != 18 && dl != 24)
683 return -EINVAL;
684
685 /* fifohandcheck should be used only with stallmode */
686 if (stallmode == false && fifohandcheck == true)
687 return -EINVAL;
688
689 /*
690 * io pad mode can be only checked by using dssdev connected to the
691 * manager. Ignore checking these for now, add checks when manager
692 * is capable of holding information related to the connected interface
693 */
694
695 return 0;
696}
697
668int dss_mgr_check(struct omap_overlay_manager *mgr, 698int dss_mgr_check(struct omap_overlay_manager *mgr,
669 struct omap_overlay_manager_info *info, 699 struct omap_overlay_manager_info *info,
670 const struct omap_video_timings *mgr_timings, 700 const struct omap_video_timings *mgr_timings,
701 const struct dss_lcd_mgr_config *lcd_config,
671 struct omap_overlay_info **overlay_infos) 702 struct omap_overlay_info **overlay_infos)
672{ 703{
673 struct omap_overlay *ovl; 704 struct omap_overlay *ovl;
@@ -683,6 +714,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
683 if (r) 714 if (r)
684 return r; 715 return r;
685 716
717 r = dss_mgr_check_lcd_config(mgr, lcd_config);
718 if (r)
719 return r;
720
686 list_for_each_entry(ovl, &mgr->overlays, list) { 721 list_for_each_entry(ovl, &mgr->overlays, list) {
687 struct omap_overlay_info *oi; 722 struct omap_overlay_info *oi;
688 int r; 723 int r;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index ec69325a118a..952c6fad9a81 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -687,3 +687,16 @@ int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
687 687
688 return 0; 688 return 0;
689} 689}
690
691/*
692 * Checks if replication logic should be used. Only use when overlay is in
693 * RGB12U or RGB16 mode, and video port width interface is 18bpp or 24bpp
694 */
695bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
696 enum omap_color_mode mode)
697{
698 if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
699 return false;
700
701 return config.video_port_width > 16;
702}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 539d709c6c0e..7c087424b634 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -300,10 +300,11 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
300} 300}
301EXPORT_SYMBOL(omap_rfbi_write_pixels); 301EXPORT_SYMBOL(omap_rfbi_write_pixels);
302 302
303static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, 303static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
304 u16 height, void (*callback)(void *data), void *data) 304 u16 height, void (*callback)(void *data), void *data)
305{ 305{
306 u32 l; 306 u32 l;
307 int r;
307 struct omap_video_timings timings = { 308 struct omap_video_timings timings = {
308 .hsw = 1, 309 .hsw = 1,
309 .hfp = 1, 310 .hfp = 1,
@@ -322,7 +323,9 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
322 323
323 dss_mgr_set_timings(dssdev->manager, &timings); 324 dss_mgr_set_timings(dssdev->manager, &timings);
324 325
325 dispc_mgr_enable(dssdev->manager->id, true); 326 r = dss_mgr_enable(dssdev->manager);
327 if (r)
328 return r;
326 329
327 rfbi.framedone_callback = callback; 330 rfbi.framedone_callback = callback;
328 rfbi.framedone_callback_data = data; 331 rfbi.framedone_callback_data = data;
@@ -335,6 +338,8 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
335 l = FLD_MOD(l, 1, 4, 4); /* ITE */ 338 l = FLD_MOD(l, 1, 4, 4); /* ITE */
336 339
337 rfbi_write_reg(RFBI_CONTROL, l); 340 rfbi_write_reg(RFBI_CONTROL, l);
341
342 return 0;
338} 343}
339 344
340static void framedone_callback(void *data, u32 mask) 345static void framedone_callback(void *data, u32 mask)
@@ -814,8 +819,11 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
814 u16 x, u16 y, u16 w, u16 h, 819 u16 x, u16 y, u16 w, u16 h,
815 void (*callback)(void *), void *data) 820 void (*callback)(void *), void *data)
816{ 821{
817 rfbi_transfer_area(dssdev, w, h, callback, data); 822 int r;
818 return 0; 823
824 r = rfbi_transfer_area(dssdev, w, h, callback, data);
825
826 return r;
819} 827}
820EXPORT_SYMBOL(omap_rfbi_update); 828EXPORT_SYMBOL(omap_rfbi_update);
821 829
@@ -859,6 +867,22 @@ static void rfbi_dump_regs(struct seq_file *s)
859#undef DUMPREG 867#undef DUMPREG
860} 868}
861 869
870static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
871{
872 struct dss_lcd_mgr_config mgr_config;
873
874 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
875
876 mgr_config.stallmode = true;
877 /* Do we need fifohandcheck for RFBI? */
878 mgr_config.fifohandcheck = false;
879
880 mgr_config.video_port_width = dssdev->ctrl.pixel_size;
881 mgr_config.lcden_sig_polarity = 0;
882
883 dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
884}
885
862int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 886int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
863{ 887{
864 int r; 888 int r;
@@ -885,12 +909,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
885 goto err1; 909 goto err1;
886 } 910 }
887 911
888 dispc_mgr_set_lcd_type_tft(dssdev->manager->id); 912 rfbi_config_lcd_manager(dssdev);
889
890 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI);
891 dispc_mgr_enable_stallmode(dssdev->manager->id, true);
892
893 dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
894 913
895 rfbi_configure(dssdev->phy.rfbi.channel, 914 rfbi_configure(dssdev->phy.rfbi.channel,
896 dssdev->ctrl.pixel_size, 915 dssdev->ctrl.pixel_size,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0fcd4d7e202e..5d31699fbd3c 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -32,18 +32,21 @@
32static struct { 32static struct {
33 bool update_enabled; 33 bool update_enabled;
34 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
35} sdi;
36 35
37static void sdi_basic_init(struct omap_dss_device *dssdev) 36 struct dss_lcd_mgr_config mgr_config;
37} sdi;
38 38
39static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
39{ 40{
40 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); 41 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
41 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 42
43 sdi.mgr_config.stallmode = false;
44 sdi.mgr_config.fifohandcheck = false;
42 45
43 dispc_mgr_set_lcd_type_tft(dssdev->manager->id); 46 sdi.mgr_config.video_port_width = 24;
47 sdi.mgr_config.lcden_sig_polarity = 1;
44 48
45 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24); 49 dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
46 dispc_lcd_enable_signal_polarity(1);
47} 50}
48 51
49int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) 52int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
@@ -51,8 +54,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
51 struct omap_video_timings *t = &dssdev->panel.timings; 54 struct omap_video_timings *t = &dssdev->panel.timings;
52 struct dss_clock_info dss_cinfo; 55 struct dss_clock_info dss_cinfo;
53 struct dispc_clock_info dispc_cinfo; 56 struct dispc_clock_info dispc_cinfo;
54 u16 lck_div, pck_div;
55 unsigned long fck;
56 unsigned long pck; 57 unsigned long pck;
57 int r; 58 int r;
58 59
@@ -75,8 +76,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
75 if (r) 76 if (r)
76 goto err_get_dispc; 77 goto err_get_dispc;
77 78
78 sdi_basic_init(dssdev);
79
80 /* 15.5.9.1.2 */ 79 /* 15.5.9.1.2 */
81 dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 80 dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
82 dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 81 dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
@@ -85,11 +84,9 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
85 if (r) 84 if (r)
86 goto err_calc_clock_div; 85 goto err_calc_clock_div;
87 86
88 fck = dss_cinfo.fck; 87 sdi.mgr_config.clock_info = dispc_cinfo;
89 lck_div = dispc_cinfo.lck_div;
90 pck_div = dispc_cinfo.pck_div;
91 88
92 pck = fck / lck_div / pck_div / 1000; 89 pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
93 90
94 if (pck != t->pixel_clock) { 91 if (pck != t->pixel_clock) {
95 DSSWARN("Could not find exact pixel clock. Requested %d kHz, " 92 DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
@@ -106,9 +103,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
106 if (r) 103 if (r)
107 goto err_set_dss_clock_div; 104 goto err_set_dss_clock_div;
108 105
109 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 106 sdi_config_lcd_manager(dssdev);
110 if (r)
111 goto err_set_dispc_clock_div;
112 107
113 dss_sdi_init(dssdev->phy.sdi.datapairs); 108 dss_sdi_init(dssdev->phy.sdi.datapairs);
114 r = dss_sdi_enable(); 109 r = dss_sdi_enable();
@@ -125,7 +120,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
125err_mgr_enable: 120err_mgr_enable:
126 dss_sdi_disable(); 121 dss_sdi_disable();
127err_sdi_enable: 122err_sdi_enable:
128err_set_dispc_clock_div:
129err_set_dss_clock_div: 123err_set_dss_clock_div:
130err_calc_clock_div: 124err_calc_clock_div:
131 dispc_runtime_put(); 125 dispc_runtime_put();