summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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 3ce7a3ec622..0fefc68372b 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -104,6 +104,7 @@ struct mgr_priv_data {
bool shadow_extra_info_dirty;
struct omap_video_timings timings;
+ struct dss_lcd_mgr_config lcd_config;
};
static struct {
@@ -137,6 +138,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
void dss_apply_init(void)
{
const int num_ovls = dss_feat_get_num_ovls();
+ struct mgr_priv_data *mp;
int i;
spin_lock_init(&data_lock);
@@ -168,16 +170,35 @@ void dss_apply_init(void)
op->user_info = op->info;
}
+
+ /*
+ * Initialize some of the lcd_config fields for TV manager, this lets
+ * us prevent checking if the manager is LCD or TV at some places
+ */
+ mp = &dss_data.mgr_priv_data_array[OMAP_DSS_CHANNEL_DIGIT];
+
+ mp->lcd_config.video_port_width = 24;
+ mp->lcd_config.clock_info.lck_div = 1;
+ mp->lcd_config.clock_info.pck_div = 1;
}
+/*
+ * A LCD manager's stallmode decides whether it is in manual or auto update. TV
+ * manager is always auto update, stallmode field for TV manager is false by
+ * default
+ */
static bool ovl_manual_update(struct omap_overlay *ovl)
{
- return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+ struct mgr_priv_data *mp = get_mgr_priv(ovl->manager);
+
+ return mp->lcd_config.stallmode;
}
static bool mgr_manual_update(struct omap_overlay_manager *mgr)
{
- return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+ return mp->lcd_config.stallmode;
}
static 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,
ois[ovl->id] = oi;
}
- return dss_mgr_check(mgr, mi, &mp->timings, ois);
+ return dss_mgr_check(mgr, mi, &mp->timings, &mp->lcd_config, ois);
}
/*
@@ -550,7 +571,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
mp = get_mgr_priv(ovl->manager);
- replication = dss_use_replication(ovl->manager->device, oi->color_mode);
+ replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
if (r) {
@@ -633,6 +654,24 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
dispc_mgr_set_timings(mgr->id, &mp->timings);
+ /* lcd_config parameters */
+ if (dss_mgr_is_lcd(mgr->id)) {
+ dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode);
+
+ dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
+ dispc_mgr_enable_fifohandcheck(mgr->id,
+ mp->lcd_config.fifohandcheck);
+
+ dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
+
+ dispc_mgr_set_tft_data_lines(mgr->id,
+ mp->lcd_config.video_port_width);
+
+ dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
+
+ dispc_mgr_set_lcd_type_tft(mgr->id);
+ }
+
mp->extra_info_dirty = false;
if (mp->updating)
mp->shadow_extra_info_dirty = true;
@@ -1292,6 +1331,44 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
mutex_unlock(&apply_lock);
}
+static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
+ const struct dss_lcd_mgr_config *config)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+ mp->lcd_config = *config;
+ mp->extra_info_dirty = true;
+}
+
+void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+ const struct dss_lcd_mgr_config *config)
+{
+ unsigned long flags;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+ mutex_lock(&apply_lock);
+
+ if (mp->enabled) {
+ DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
+ mgr->name);
+ goto out;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ dss_apply_mgr_lcd_config(mgr, config);
+
+ dss_write_regs();
+ dss_set_go_bits();
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ wait_pending_extra_info_updates();
+
+out:
+ mutex_unlock(&apply_lock);
+}
+
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d1a7a0c9028..5b289c5f695 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -498,16 +498,6 @@ void dispc_runtime_put(void)
WARN_ON(r < 0 && r != -ENOSYS);
}
-static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
-{
- if (channel == OMAP_DSS_CHANNEL_LCD ||
- channel == OMAP_DSS_CHANNEL_LCD2 ||
- channel == OMAP_DSS_CHANNEL_LCD3)
- return true;
- else
- return false;
-}
-
u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
{
return mgr_desc[channel].vsync_irq;
@@ -1010,7 +1000,7 @@ static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
{
u32 coef_r, coef_g, coef_b;
- if (!dispc_mgr_is_lcd(channel))
+ if (!dss_mgr_is_lcd(channel))
return;
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,
nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
pclk = dispc_mgr_pclk_rate(channel);
- if (dispc_mgr_is_lcd(channel))
+ if (dss_mgr_is_lcd(channel))
lclk = dispc_mgr_lclk_rate(channel);
else
lclk = dispc_fclk_rate();
@@ -2452,7 +2442,7 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
void dispc_mgr_enable(enum omap_channel channel, bool enable)
{
- if (dispc_mgr_is_lcd(channel))
+ if (dss_mgr_is_lcd(channel))
dispc_mgr_enable_lcd_out(channel, enable);
else if (channel == OMAP_DSS_CHANNEL_DIGIT)
dispc_mgr_enable_digit_out(enable);
@@ -2642,7 +2632,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
- if (dispc_mgr_is_lcd(channel))
+ if (dss_mgr_is_lcd(channel))
timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw,
timings->hfp, timings->hbp,
timings->vsw, timings->vfp,
@@ -2734,7 +2724,7 @@ void dispc_mgr_set_timings(enum omap_channel channel,
return;
}
- if (dispc_mgr_is_lcd(channel)) {
+ if (dss_mgr_is_lcd(channel)) {
_dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw,
t.vfp, t.vbp, t.vsync_level, t.hsync_level,
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)
{
unsigned long r;
- if (dispc_mgr_is_lcd(channel)) {
+ if (dss_mgr_is_lcd(channel)) {
int pcd;
u32 l;
@@ -3224,15 +3214,13 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
return 0;
}
-int dispc_mgr_set_clock_div(enum omap_channel channel,
+void dispc_mgr_set_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo)
{
DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
-
- return 0;
}
int 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 1a0c15f83d0..5bd957e8550 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,
}
EXPORT_SYMBOL(omapdss_default_get_timings);
-/* Checks if replication logic should be used. Only use for active matrix,
- * when overlay is in RGB12U or RGB16 mode, and LCD interface is
- * 18bpp or 24bpp */
-bool dss_use_replication(struct omap_dss_device *dssdev,
- enum omap_color_mode mode)
-{
- int bpp;
-
- if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
- return false;
-
- switch (dssdev->type) {
- case OMAP_DISPLAY_TYPE_DPI:
- bpp = dssdev->phy.dpi.data_lines;
- break;
- case OMAP_DISPLAY_TYPE_HDMI:
- case OMAP_DISPLAY_TYPE_VENC:
- case OMAP_DISPLAY_TYPE_SDI:
- bpp = 24;
- break;
- case OMAP_DISPLAY_TYPE_DBI:
- bpp = dssdev->ctrl.pixel_size;
- break;
- case OMAP_DISPLAY_TYPE_DSI:
- bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
- break;
- default:
- BUG();
- return false;
- }
-
- return bpp > 16;
-}
-
void dss_init_device(struct platform_device *pdev,
struct omap_dss_device *dssdev)
{
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index a81b6d6deb5..3266be23fc0 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -38,6 +38,8 @@
static struct {
struct regulator *vdds_dsi_reg;
struct platform_device *dsidev;
+
+ struct dss_lcd_mgr_config mgr_config;
} dpi;
static 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,
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
- r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
- if (r) {
- dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
- return r;
- }
+ dpi.mgr_config.clock_info = dispc_cinfo;
*fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
*lck_div = dispc_cinfo.lck_div;
@@ -112,9 +110,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
if (r)
return r;
- r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
- if (r)
- return r;
+ dpi.mgr_config.clock_info = dispc_cinfo;
*fck = dss_cinfo.fck;
*lck_div = dispc_cinfo.lck_div;
@@ -155,15 +151,18 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
return 0;
}
-static void dpi_basic_init(struct omap_dss_device *dssdev)
+static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
{
- dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
- dispc_mgr_enable_stallmode(dssdev->manager->id, false);
+ dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
+
+ dpi.mgr_config.stallmode = false;
+ dpi.mgr_config.fifohandcheck = false;
+
+ dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
- dispc_mgr_set_lcd_type_tft(dssdev->manager->id);
+ dpi.mgr_config.lcden_sig_polarity = 0;
- dispc_mgr_set_tft_data_lines(dssdev->manager->id,
- dssdev->phy.dpi.data_lines);
+ dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
}
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
@@ -196,8 +195,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_get_dispc;
- dpi_basic_init(dssdev);
-
if (dpi_use_dsi_pll(dssdev)) {
r = dsi_runtime_get(dpi.dsidev);
if (r)
@@ -212,6 +209,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_set_mode;
+ dpi_config_lcd_manager(dssdev);
+
mdelay(2);
r = dss_mgr_enable(dssdev->manager);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index e0d43b275e3..b07e8864f82 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -331,6 +331,8 @@ struct dsi_data {
unsigned num_lanes_used;
unsigned scp_clk_refcount;
+
+ struct dss_lcd_mgr_config mgr_config;
};
struct dsi_packet_sent_handler_data {
@@ -4337,14 +4339,40 @@ EXPORT_SYMBOL(omap_dsi_update);
/* Display funcs */
-static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
+static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct dispc_clock_info dispc_cinfo;
int r;
+ unsigned long long fck;
+
+ fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+
+ dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
+ dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
+
+ r = dispc_calc_clock_rates(fck, &dispc_cinfo);
+ if (r) {
+ DSSERR("Failed to calc dispc clocks\n");
+ return r;
+ }
+
+ dsi->mgr_config.clock_info = dispc_cinfo;
+
+ return 0;
+}
+
+static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_video_timings timings;
+ int r;
+ u32 irq = 0;
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
u16 dw, dh;
- u32 irq;
dssdev->driver->get_resolution(dssdev, &dw, &dh);
@@ -4363,16 +4391,16 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
(void *) dssdev, irq);
if (r) {
DSSERR("can't get FRAMEDONE irq\n");
- return r;
+ goto err;
}
- dispc_mgr_enable_stallmode(dssdev->manager->id, true);
- dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
+ dsi->mgr_config.stallmode = true;
+ dsi->mgr_config.fifohandcheck = true;
} else {
timings = dssdev->panel.timings;
- dispc_mgr_enable_stallmode(dssdev->manager->id, false);
- dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0);
+ dsi->mgr_config.stallmode = false;
+ dsi->mgr_config.fifohandcheck = false;
}
/*
@@ -4388,12 +4416,24 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dss_mgr_set_timings(dssdev->manager, &timings);
- dispc_mgr_set_lcd_type_tft(dssdev->manager->id);
+ r = dsi_configure_dispc_clocks(dssdev);
+ if (r)
+ goto err1;
+
+ dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
+ dsi->mgr_config.video_port_width =
+ dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+ dsi->mgr_config.lcden_sig_polarity = 0;
- dispc_mgr_set_tft_data_lines(dssdev->manager->id,
- dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt));
+ dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
return 0;
+err1:
+ if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE)
+ omap_dispc_unregister_isr(dsi_framedone_irq_callback,
+ (void *) dssdev, irq);
+err:
+ return r;
}
static 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)
return 0;
}
-static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
-{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- struct dispc_clock_info dispc_cinfo;
- int r;
- unsigned long long fck;
-
- fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
-
- dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
- dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
-
- r = dispc_calc_clock_rates(fck, &dispc_cinfo);
- if (r) {
- DSSERR("Failed to calc dispc clocks\n");
- return r;
- }
-
- r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
- if (r) {
- DSSERR("Failed to set dispc clocks\n");
- return r;
- }
-
- return 0;
-}
-
static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
{
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)
DSSDBG("PLL OK\n");
- r = dsi_configure_dispc_clocks(dssdev);
- if (r)
- goto err2;
-
r = dsi_cio_init(dssdev);
if (r)
goto err2;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6c5ecf02759..f67afe76f21 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -158,6 +158,19 @@ struct reg_field {
u8 low;
};
+struct dss_lcd_mgr_config {
+ enum dss_io_pad_mode io_pad_mode;
+
+ bool stallmode;
+ bool fifohandcheck;
+
+ struct dispc_clock_info clock_info;
+
+ int video_port_width;
+
+ int lcden_sig_polarity;
+};
+
struct seq_file;
struct platform_device;
@@ -194,6 +207,8 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
struct omap_video_timings *timings);
+void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+ const struct dss_lcd_mgr_config *config);
const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
bool dss_ovl_is_enabled(struct omap_overlay *ovl);
@@ -216,8 +231,6 @@ void dss_init_device(struct platform_device *pdev,
struct omap_dss_device *dssdev);
void dss_uninit_device(struct platform_device *pdev,
struct omap_dss_device *dssdev);
-bool dss_use_replication(struct omap_dss_device *dssdev,
- enum omap_color_mode mode);
/* manager */
int dss_init_overlay_managers(struct platform_device *pdev);
@@ -229,8 +242,18 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
int dss_mgr_check(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info,
const struct omap_video_timings *mgr_timings,
+ const struct dss_lcd_mgr_config *config,
struct omap_overlay_info **overlay_infos);
+static inline bool dss_mgr_is_lcd(enum omap_channel id)
+{
+ if (id == OMAP_DSS_CHANNEL_LCD || id == OMAP_DSS_CHANNEL_LCD2 ||
+ id == OMAP_DSS_CHANNEL_LCD3)
+ return true;
+ else
+ return false;
+}
+
/* overlay */
void dss_init_overlays(struct platform_device *pdev);
void dss_uninit_overlays(struct platform_device *pdev);
@@ -240,6 +263,8 @@ int dss_ovl_simple_check(struct omap_overlay *ovl,
const struct omap_overlay_info *info);
int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
const struct omap_video_timings *mgr_timings);
+bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
+ enum omap_color_mode mode);
/* DSS */
int dss_init_platform_driver(void) __init;
@@ -425,7 +450,7 @@ void dispc_mgr_set_timings(enum omap_channel channel,
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
unsigned long dispc_core_clk_rate(void);
-int dispc_mgr_set_clock_div(enum omap_channel channel,
+void dispc_mgr_set_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index a51eb060c14..53710fadc82 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,
return 0;
}
+static int dss_mgr_check_lcd_config(struct omap_overlay_manager *mgr,
+ const struct dss_lcd_mgr_config *config)
+{
+ struct dispc_clock_info cinfo = config->clock_info;
+ int dl = config->video_port_width;
+ bool stallmode = config->stallmode;
+ bool fifohandcheck = config->fifohandcheck;
+
+ if (cinfo.lck_div < 1 || cinfo.lck_div > 255)
+ return -EINVAL;
+
+ if (cinfo.pck_div < 1 || cinfo.pck_div > 255)
+ return -EINVAL;
+
+ if (dl != 12 && dl != 16 && dl != 18 && dl != 24)
+ return -EINVAL;
+
+ /* fifohandcheck should be used only with stallmode */
+ if (stallmode == false && fifohandcheck == true)
+ return -EINVAL;
+
+ /*
+ * io pad mode can be only checked by using dssdev connected to the
+ * manager. Ignore checking these for now, add checks when manager
+ * is capable of holding information related to the connected interface
+ */
+
+ return 0;
+}
+
int dss_mgr_check(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info,
const struct omap_video_timings *mgr_timings,
+ const struct dss_lcd_mgr_config *lcd_config,
struct omap_overlay_info **overlay_infos)
{
struct omap_overlay *ovl;
@@ -683,6 +714,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
if (r)
return r;
+ r = dss_mgr_check_lcd_config(mgr, lcd_config);
+ if (r)
+ return r;
+
list_for_each_entry(ovl, &mgr->overlays, list) {
struct omap_overlay_info *oi;
int r;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index ec69325a118..952c6fad9a8 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,
return 0;
}
+
+/*
+ * Checks if replication logic should be used. Only use when overlay is in
+ * RGB12U or RGB16 mode, and video port width interface is 18bpp or 24bpp
+ */
+bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
+ enum omap_color_mode mode)
+{
+ if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
+ return false;
+
+ return config.video_port_width > 16;
+}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 539d709c6c0..7c087424b63 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,
}
EXPORT_SYMBOL(omap_rfbi_write_pixels);
-static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
+static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
u16 height, void (*callback)(void *data), void *data)
{
u32 l;
+ int r;
struct omap_video_timings timings = {
.hsw = 1,
.hfp = 1,
@@ -322,7 +323,9 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
dss_mgr_set_timings(dssdev->manager, &timings);
- dispc_mgr_enable(dssdev->manager->id, true);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ return r;
rfbi.framedone_callback = callback;
rfbi.framedone_callback_data = data;
@@ -335,6 +338,8 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
l = FLD_MOD(l, 1, 4, 4); /* ITE */
rfbi_write_reg(RFBI_CONTROL, l);
+
+ return 0;
}
static void framedone_callback(void *data, u32 mask)
@@ -814,8 +819,11 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h,
void (*callback)(void *), void *data)
{
- rfbi_transfer_area(dssdev, w, h, callback, data);
- return 0;
+ int r;
+
+ r = rfbi_transfer_area(dssdev, w, h, callback, data);
+
+ return r;
}
EXPORT_SYMBOL(omap_rfbi_update);
@@ -859,6 +867,22 @@ static void rfbi_dump_regs(struct seq_file *s)
#undef DUMPREG
}
+static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
+{
+ struct dss_lcd_mgr_config mgr_config;
+
+ mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
+
+ mgr_config.stallmode = true;
+ /* Do we need fifohandcheck for RFBI? */
+ mgr_config.fifohandcheck = false;
+
+ mgr_config.video_port_width = dssdev->ctrl.pixel_size;
+ mgr_config.lcden_sig_polarity = 0;
+
+ dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
+}
+
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
{
int r;
@@ -885,12 +909,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
goto err1;
}
- dispc_mgr_set_lcd_type_tft(dssdev->manager->id);
-
- dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI);
- dispc_mgr_enable_stallmode(dssdev->manager->id, true);
-
- dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
+ rfbi_config_lcd_manager(dssdev);
rfbi_configure(dssdev->phy.rfbi.channel,
dssdev->ctrl.pixel_size,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0fcd4d7e202..5d31699fbd3 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -32,18 +32,21 @@
static struct {
bool update_enabled;
struct regulator *vdds_sdi_reg;
-} sdi;
-static void sdi_basic_init(struct omap_dss_device *dssdev)
+ struct dss_lcd_mgr_config mgr_config;
+} sdi;
+static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
{
- dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
- dispc_mgr_enable_stallmode(dssdev->manager->id, false);
+ sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
+
+ sdi.mgr_config.stallmode = false;
+ sdi.mgr_config.fifohandcheck = false;
- dispc_mgr_set_lcd_type_tft(dssdev->manager->id);
+ sdi.mgr_config.video_port_width = 24;
+ sdi.mgr_config.lcden_sig_polarity = 1;
- dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24);
- dispc_lcd_enable_signal_polarity(1);
+ dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
}
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
@@ -51,8 +54,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
struct omap_video_timings *t = &dssdev->panel.timings;
struct dss_clock_info dss_cinfo;
struct dispc_clock_info dispc_cinfo;
- u16 lck_div, pck_div;
- unsigned long fck;
unsigned long pck;
int r;
@@ -75,8 +76,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_get_dispc;
- sdi_basic_init(dssdev);
-
/* 15.5.9.1.2 */
dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
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)
if (r)
goto err_calc_clock_div;
- fck = dss_cinfo.fck;
- lck_div = dispc_cinfo.lck_div;
- pck_div = dispc_cinfo.pck_div;
+ sdi.mgr_config.clock_info = dispc_cinfo;
- pck = fck / lck_div / pck_div / 1000;
+ pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
if (pck != t->pixel_clock) {
DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
@@ -106,9 +103,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_set_dss_clock_div;
- r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
- if (r)
- goto err_set_dispc_clock_div;
+ sdi_config_lcd_manager(dssdev);
dss_sdi_init(dssdev->phy.sdi.datapairs);
r = dss_sdi_enable();
@@ -125,7 +120,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
err_mgr_enable:
dss_sdi_disable();
err_sdi_enable:
-err_set_dispc_clock_div:
err_set_dss_clock_div:
err_calc_clock_div:
dispc_runtime_put();