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 { 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 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) 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 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, } 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 a81b6d6deb57..3266be23fc0d 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; - dispc_mgr_set_lcd_type_tft(dssdev->manager->id); + dpi.mgr_config.stallmode = false; + dpi.mgr_config.fifohandcheck = false; - dispc_mgr_set_tft_data_lines(dssdev->manager->id, - dssdev->phy.dpi.data_lines); + dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines; + + dpi.mgr_config.lcden_sig_polarity = 0; + + 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 e0d43b275e3e..b07e8864f82f 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_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) { - int r; + 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; - dispc_mgr_set_tft_data_lines(dssdev->manager->id, - dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)); + 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; + + 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 6c5ecf02759e..f67afe76f217 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 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, 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 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, 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 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, } 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 0fcd4d7e202e..5d31699fbd3c 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; + + struct dss_lcd_mgr_config mgr_config; } sdi; -static void sdi_basic_init(struct omap_dss_device *dssdev) - +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; - dispc_mgr_set_lcd_type_tft(dssdev->manager->id); + sdi.mgr_config.stallmode = false; + sdi.mgr_config.fifohandcheck = false; - dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24); - dispc_lcd_enable_signal_polarity(1); + sdi.mgr_config.video_port_width = 24; + sdi.mgr_config.lcden_sig_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();