diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 3ce7a3ec6224..30915bdcb237 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,6 +170,16 @@ 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; } static bool ovl_manual_update(struct omap_overlay *ovl) @@ -633,6 +645,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 +1322,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/dpi.c b/drivers/video/omap2/dss/dpi.c index 6664775c3e45..3266be23fc0d 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -162,21 +162,7 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) dpi.mgr_config.lcden_sig_polarity = 0; - dispc_mgr_set_io_pad_mode(dpi.mgr_config.io_pad_mode); - dispc_mgr_enable_stallmode(dssdev->manager->id, - dpi.mgr_config.stallmode); - dispc_mgr_enable_fifohandcheck(dssdev->manager->id, - dpi.mgr_config.fifohandcheck); - - dispc_mgr_set_tft_data_lines(dssdev->manager->id, - dpi.mgr_config.video_port_width); - - dispc_mgr_set_clock_div(dssdev->manager->id, - &dpi.mgr_config.clock_info); - - dispc_lcd_enable_signal_polarity(dpi.mgr_config.lcden_sig_polarity); - - dispc_mgr_set_lcd_type_tft(dssdev->manager->id); + dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config); } int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index f51df30d8c15..b07e8864f82f 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4425,22 +4425,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); dsi->mgr_config.lcden_sig_polarity = 0; - dispc_mgr_set_io_pad_mode(dsi->mgr_config.io_pad_mode); - - dispc_mgr_enable_stallmode(dssdev->manager->id, - dsi->mgr_config.stallmode); - dispc_mgr_enable_fifohandcheck(dssdev->manager->id, - dsi->mgr_config.fifohandcheck); - - dispc_mgr_set_clock_div(dssdev->manager->id, - &dsi->mgr_config.clock_info); - - dispc_mgr_set_tft_data_lines(dssdev->manager->id, - dsi->mgr_config.video_port_width); - - dispc_lcd_enable_signal_polarity(dsi->mgr_config.lcden_sig_polarity); - - dispc_mgr_set_lcd_type_tft(dssdev->manager->id); + dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config); return 0; err1: diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 061c95e20d49..80ed88f53c19 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -207,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); @@ -244,6 +246,15 @@ int dss_mgr_check(struct omap_overlay_manager *mgr, const struct omap_video_timings *mgr_timings, 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); diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 0dc8dac1c07c..cc22426144cb 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -872,18 +872,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) mgr_config.video_port_width = dssdev->ctrl.pixel_size; mgr_config.lcden_sig_polarity = 0; - dispc_mgr_set_io_pad_mode(mgr_config.io_pad_mode); - - dispc_mgr_enable_stallmode(dssdev->manager->id, mgr_config.stallmode); - dispc_mgr_enable_fifohandcheck(dssdev->manager->id, - mgr_config.fifohandcheck); - - dispc_mgr_set_tft_data_lines(dssdev->manager->id, - mgr_config.video_port_width); - - dispc_lcd_enable_signal_polarity(mgr_config.lcden_sig_polarity); - - dispc_mgr_set_lcd_type_tft(dssdev->manager->id); + dss_mgr_set_lcd_config(dssdev->manager, &mgr_config); } int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index f102eae6e2af..5d31699fbd3c 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -46,20 +46,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) sdi.mgr_config.video_port_width = 24; sdi.mgr_config.lcden_sig_polarity = 1; - dispc_mgr_set_io_pad_mode(sdi.mgr_config.io_pad_mode); - dispc_mgr_enable_stallmode(dssdev->manager->id, - sdi.mgr_config.stallmode); - dispc_mgr_enable_fifohandcheck(dssdev->manager->id, - sdi.mgr_config.fifohandcheck); - - dispc_mgr_set_clock_div(dssdev->manager->id, - &sdi.mgr_config.clock_info); - - dispc_mgr_set_tft_data_lines(dssdev->manager->id, - sdi.mgr_config.video_port_width); - dispc_lcd_enable_signal_polarity(sdi.mgr_config.lcden_sig_polarity); - - dispc_mgr_set_lcd_type_tft(dssdev->manager->id); + dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config); } int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)