Loading drivers/video/omap2/dss/apply.c +191 −30 Original line number Original line Diff line number Diff line Loading @@ -105,6 +105,9 @@ static struct { struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; bool fifo_merge_dirty; bool fifo_merge; bool irq_enabled; bool irq_enabled; } dss_data; } dss_data; Loading Loading @@ -585,11 +588,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) } } } } static void dss_write_regs_common(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); int i; if (!dss_data.fifo_merge_dirty) return; for (i = 0; i < num_mgrs; ++i) { struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; mgr = omap_dss_get_overlay_manager(i); mp = get_mgr_priv(mgr); if (mp->enabled) { if (dss_data.fifo_merge_dirty) { dispc_enable_fifomerge(dss_data.fifo_merge); dss_data.fifo_merge_dirty = false; } if (mp->updating) mp->shadow_info_dirty = true; } } } static void dss_write_regs(void) static void dss_write_regs(void) { { const int num_mgrs = omap_dss_get_num_overlay_managers(); const int num_mgrs = omap_dss_get_num_overlay_managers(); int i; int i; dss_write_regs_common(); for (i = 0; i < num_mgrs; ++i) { for (i = 0; i < num_mgrs; ++i) { struct omap_overlay_manager *mgr; struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; struct mgr_priv_data *mp; Loading Loading @@ -659,6 +691,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) dss_mgr_write_regs(mgr); dss_mgr_write_regs(mgr); dss_write_regs_common(); mp->updating = true; mp->updating = true; if (!dss_data.irq_enabled && need_isr()) if (!dss_data.irq_enabled && need_isr()) Loading Loading @@ -859,11 +893,20 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, op->extra_info_dirty = true; op->extra_info_dirty = true; } } static void dss_ovl_setup_fifo(struct omap_overlay *ovl) static void dss_apply_fifo_merge(bool use_fifo_merge) { if (dss_data.fifo_merge == use_fifo_merge) return; dss_data.fifo_merge = use_fifo_merge; dss_data.fifo_merge_dirty = true; } static void dss_ovl_setup_fifo(struct omap_overlay *ovl, bool use_fifo_merge) { { struct ovl_priv_data *op = get_ovl_priv(ovl); struct ovl_priv_data *op = get_ovl_priv(ovl); struct omap_dss_device *dssdev; struct omap_dss_device *dssdev; u32 size, burst_size; u32 fifo_low, fifo_high; u32 fifo_low, fifo_high; if (!op->enabled && !op->enabling) if (!op->enabled && !op->enabling) Loading @@ -871,33 +914,14 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) dssdev = ovl->manager->device; dssdev = ovl->manager->device; size = dispc_ovl_get_fifo_size(ovl->id); dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, use_fifo_merge); burst_size = dispc_ovl_get_burst_size(ovl->id); switch (dssdev->type) { case OMAP_DISPLAY_TYPE_DPI: case OMAP_DISPLAY_TYPE_DBI: case OMAP_DISPLAY_TYPE_SDI: case OMAP_DISPLAY_TYPE_VENC: case OMAP_DISPLAY_TYPE_HDMI: default_get_overlay_fifo_thresholds(ovl->id, size, burst_size, &fifo_low, &fifo_high); break; #ifdef CONFIG_OMAP2_DSS_DSI case OMAP_DISPLAY_TYPE_DSI: dsi_get_overlay_fifo_thresholds(ovl->id, size, burst_size, &fifo_low, &fifo_high); break; #endif default: BUG(); } dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); } } static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, bool use_fifo_merge) { { struct omap_overlay *ovl; struct omap_overlay *ovl; struct mgr_priv_data *mp; struct mgr_priv_data *mp; Loading @@ -908,10 +932,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) return; return; list_for_each_entry(ovl, &mgr->overlays, list) list_for_each_entry(ovl, &mgr->overlays, list) dss_ovl_setup_fifo(ovl); dss_ovl_setup_fifo(ovl, use_fifo_merge); } } static void dss_setup_fifos(void) static void dss_setup_fifos(bool use_fifo_merge) { { const int num_mgrs = omap_dss_get_num_overlay_managers(); const int num_mgrs = omap_dss_get_num_overlay_managers(); struct omap_overlay_manager *mgr; struct omap_overlay_manager *mgr; Loading @@ -919,15 +943,91 @@ static void dss_setup_fifos(void) for (i = 0; i < num_mgrs; ++i) { for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); mgr = omap_dss_get_overlay_manager(i); dss_mgr_setup_fifos(mgr); dss_mgr_setup_fifos(mgr, use_fifo_merge); } } } } static int get_num_used_managers(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; int i; int enabled_mgrs; enabled_mgrs = 0; for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); mp = get_mgr_priv(mgr); if (!mp->enabled) continue; enabled_mgrs++; } return enabled_mgrs; } static int get_num_used_overlays(void) { const int num_ovls = omap_dss_get_num_overlays(); struct omap_overlay *ovl; struct ovl_priv_data *op; struct mgr_priv_data *mp; int i; int enabled_ovls; enabled_ovls = 0; for (i = 0; i < num_ovls; ++i) { ovl = omap_dss_get_overlay(i); op = get_ovl_priv(ovl); if (!op->enabled && !op->enabling) continue; mp = get_mgr_priv(ovl->manager); if (!mp->enabled) continue; enabled_ovls++; } return enabled_ovls; } static bool get_use_fifo_merge(void) { int enabled_mgrs = get_num_used_managers(); int enabled_ovls = get_num_used_overlays(); if (!dss_has_feature(FEAT_FIFO_MERGE)) return false; /* * In theory the only requirement for fifomerge is enabled_ovls <= 1. * However, if we have two managers enabled and set/unset the fifomerge, * we need to set the GO bits in particular sequence for the managers, * and wait in between. * * This is rather difficult as new apply calls can happen at any time, * so we simplify the problem by requiring also that enabled_mgrs <= 1. * In practice this shouldn't matter, because when only one overlay is * enabled, most likely only one output is enabled. */ return enabled_mgrs <= 1 && enabled_ovls <= 1; } int dss_mgr_enable(struct omap_overlay_manager *mgr) int dss_mgr_enable(struct omap_overlay_manager *mgr) { { struct mgr_priv_data *mp = get_mgr_priv(mgr); struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; unsigned long flags; int r; int r; bool fifo_merge; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -945,11 +1045,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) goto err; goto err; } } dss_setup_fifos(); /* step 1: setup fifos/fifomerge before enabling the manager */ fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_write_regs(); dss_set_go_bits(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); /* wait until fifo config is in */ wait_pending_extra_info_updates(); /* step 2: enable the manager */ spin_lock_irqsave(&data_lock, flags); if (!mgr_manual_update(mgr)) if (!mgr_manual_update(mgr)) mp->updating = true; mp->updating = true; Loading @@ -974,6 +1086,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) { { struct mgr_priv_data *mp = get_mgr_priv(mgr); struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; unsigned long flags; bool fifo_merge; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -988,8 +1101,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) mp->updating = false; mp->updating = false; mp->enabled = false; mp->enabled = false; fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); spin_unlock_irqrestore(&data_lock, flags); wait_pending_extra_info_updates(); out: out: mutex_unlock(&apply_lock); mutex_unlock(&apply_lock); } } Loading Loading @@ -1241,6 +1362,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) { { struct ovl_priv_data *op = get_ovl_priv(ovl); struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; unsigned long flags; bool fifo_merge; int r; int r; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -1266,7 +1388,22 @@ int dss_ovl_enable(struct omap_overlay *ovl) goto err2; goto err2; } } dss_setup_fifos(); /* step 1: configure fifos/fifomerge for currently enabled ovls */ fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); /* wait for fifo configs to go in */ wait_pending_extra_info_updates(); /* step 2: enable the overlay */ spin_lock_irqsave(&data_lock, flags); op->enabling = false; op->enabling = false; dss_apply_ovl_enable(ovl, true); dss_apply_ovl_enable(ovl, true); Loading @@ -1276,6 +1413,9 @@ int dss_ovl_enable(struct omap_overlay *ovl) spin_unlock_irqrestore(&data_lock, flags); spin_unlock_irqrestore(&data_lock, flags); /* wait for overlay to be enabled */ wait_pending_extra_info_updates(); mutex_unlock(&apply_lock); mutex_unlock(&apply_lock); return 0; return 0; Loading @@ -1291,6 +1431,7 @@ int dss_ovl_disable(struct omap_overlay *ovl) { { struct ovl_priv_data *op = get_ovl_priv(ovl); struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; unsigned long flags; bool fifo_merge; int r; int r; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -1305,14 +1446,34 @@ int dss_ovl_disable(struct omap_overlay *ovl) goto err; goto err; } } /* step 1: disable the overlay */ spin_lock_irqsave(&data_lock, flags); spin_lock_irqsave(&data_lock, flags); dss_apply_ovl_enable(ovl, false); dss_apply_ovl_enable(ovl, false); dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); /* wait for the overlay to be disabled */ wait_pending_extra_info_updates(); /* step 2: configure fifos/fifomerge */ spin_lock_irqsave(&data_lock, flags); fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_write_regs(); dss_set_go_bits(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); spin_unlock_irqrestore(&data_lock, flags); /* wait for fifo config to go in */ wait_pending_extra_info_updates(); mutex_unlock(&apply_lock); mutex_unlock(&apply_lock); return 0; return 0; Loading drivers/video/omap2/dss/dispc.c +49 −6 Original line number Original line Diff line number Diff line Loading @@ -909,7 +909,7 @@ static void dispc_configure_burst_sizes(void) dispc_ovl_set_burst_size(i, burst_size); dispc_ovl_set_burst_size(i, burst_size); } } u32 dispc_ovl_get_burst_size(enum omap_plane plane) static u32 dispc_ovl_get_burst_size(enum omap_plane plane) { { unsigned unit = dss_feat_get_burst_size_unit(); unsigned unit = dss_feat_get_burst_size_unit(); /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ Loading Loading @@ -1018,7 +1018,7 @@ static void dispc_read_plane_fifo_sizes(void) } } } } u32 dispc_ovl_get_fifo_size(enum omap_plane plane) static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) { { return dispc.fifo_size[plane]; return dispc.fifo_size[plane]; } } Loading @@ -1039,13 +1039,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n", plane, plane, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), lo_start, lo_end), lo_start, lo_end) * unit, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), hi_start, hi_end), hi_start, hi_end) * unit, low, high); low * unit, high * unit); dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), FLD_VAL(high, hi_start, hi_end) | FLD_VAL(high, hi_start, hi_end) | Loading @@ -1054,10 +1054,53 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) void dispc_enable_fifomerge(bool enable) void dispc_enable_fifomerge(bool enable) { { if (!dss_has_feature(FEAT_FIFO_MERGE)) { WARN_ON(enable); return; } DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } } void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high, bool use_fifomerge) { /* * All sizes are in bytes. Both the buffer and burst are made of * buffer_units, and the fifo thresholds must be buffer_unit aligned. */ unsigned buf_unit = dss_feat_get_buffer_size_unit(); unsigned ovl_fifo_size, total_fifo_size, burst_size; int i; burst_size = dispc_ovl_get_burst_size(plane); ovl_fifo_size = dispc_ovl_get_fifo_size(plane); if (use_fifomerge) { total_fifo_size = 0; for (i = 0; i < omap_dss_get_num_overlays(); ++i) total_fifo_size += dispc_ovl_get_fifo_size(i); } else { total_fifo_size = ovl_fifo_size; } /* * We use the same low threshold for both fifomerge and non-fifomerge * cases, but for fifomerge we calculate the high threshold using the * combined fifo size */ if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { *fifo_low = ovl_fifo_size - burst_size * 2; *fifo_high = total_fifo_size - burst_size; } else { *fifo_low = ovl_fifo_size - burst_size; *fifo_high = total_fifo_size - buf_unit; } } static void dispc_ovl_set_fir(enum omap_plane plane, static void dispc_ovl_set_fir(enum omap_plane plane, int hinc, int vinc, int hinc, int vinc, enum omap_color_component color_comp) enum omap_color_component color_comp) Loading drivers/video/omap2/dss/display.c +0 −10 Original line number Original line Diff line number Diff line Loading @@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev, } } EXPORT_SYMBOL(omapdss_default_get_resolution); EXPORT_SYMBOL(omapdss_default_get_resolution); void default_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high) { unsigned buf_unit = dss_feat_get_buffer_size_unit(); *fifo_high = fifo_size - buf_unit; *fifo_low = fifo_size - burst_size; } int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) { { switch (dssdev->type) { switch (dssdev->type) { Loading drivers/video/omap2/dss/dsi.c +0 −8 Original line number Original line Diff line number Diff line Loading @@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) } } EXPORT_SYMBOL(omapdss_dsi_enable_te); EXPORT_SYMBOL(omapdss_dsi_enable_te); void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high) { *fifo_high = fifo_size - burst_size; *fifo_low = fifo_size - burst_size * 2; } int dsi_init_display(struct omap_dss_device *dssdev) int dsi_init_display(struct omap_dss_device *dssdev) { { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); Loading drivers/video/omap2/dss/dss.h +2 −8 Original line number Original line Diff line number Diff line Loading @@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev, struct omap_dss_device *dssdev); struct omap_dss_device *dssdev); bool dss_use_replication(struct omap_dss_device *dssdev, bool dss_use_replication(struct omap_dss_device *dssdev, enum omap_color_mode mode); enum omap_color_mode mode); void default_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high); /* manager */ /* manager */ int dss_init_overlay_managers(struct platform_device *pdev); int dss_init_overlay_managers(struct platform_device *pdev); Loading Loading @@ -313,9 +310,6 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, bool enable_hsdiv); bool enable_hsdiv); void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high); void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); struct platform_device *dsi_get_dsidev_from_id(int module); struct platform_device *dsi_get_dsidev_from_id(int module); Loading Loading @@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); u32 dispc_ovl_get_fifo_size(enum omap_plane plane); void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, u32 dispc_ovl_get_burst_size(enum omap_plane plane); u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, bool ilace, bool replication); bool ilace, bool replication); int dispc_ovl_enable(enum omap_plane plane, bool enable); int dispc_ovl_enable(enum omap_plane plane, bool enable); Loading Loading
drivers/video/omap2/dss/apply.c +191 −30 Original line number Original line Diff line number Diff line Loading @@ -105,6 +105,9 @@ static struct { struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; bool fifo_merge_dirty; bool fifo_merge; bool irq_enabled; bool irq_enabled; } dss_data; } dss_data; Loading Loading @@ -585,11 +588,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) } } } } static void dss_write_regs_common(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); int i; if (!dss_data.fifo_merge_dirty) return; for (i = 0; i < num_mgrs; ++i) { struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; mgr = omap_dss_get_overlay_manager(i); mp = get_mgr_priv(mgr); if (mp->enabled) { if (dss_data.fifo_merge_dirty) { dispc_enable_fifomerge(dss_data.fifo_merge); dss_data.fifo_merge_dirty = false; } if (mp->updating) mp->shadow_info_dirty = true; } } } static void dss_write_regs(void) static void dss_write_regs(void) { { const int num_mgrs = omap_dss_get_num_overlay_managers(); const int num_mgrs = omap_dss_get_num_overlay_managers(); int i; int i; dss_write_regs_common(); for (i = 0; i < num_mgrs; ++i) { for (i = 0; i < num_mgrs; ++i) { struct omap_overlay_manager *mgr; struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; struct mgr_priv_data *mp; Loading Loading @@ -659,6 +691,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) dss_mgr_write_regs(mgr); dss_mgr_write_regs(mgr); dss_write_regs_common(); mp->updating = true; mp->updating = true; if (!dss_data.irq_enabled && need_isr()) if (!dss_data.irq_enabled && need_isr()) Loading Loading @@ -859,11 +893,20 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, op->extra_info_dirty = true; op->extra_info_dirty = true; } } static void dss_ovl_setup_fifo(struct omap_overlay *ovl) static void dss_apply_fifo_merge(bool use_fifo_merge) { if (dss_data.fifo_merge == use_fifo_merge) return; dss_data.fifo_merge = use_fifo_merge; dss_data.fifo_merge_dirty = true; } static void dss_ovl_setup_fifo(struct omap_overlay *ovl, bool use_fifo_merge) { { struct ovl_priv_data *op = get_ovl_priv(ovl); struct ovl_priv_data *op = get_ovl_priv(ovl); struct omap_dss_device *dssdev; struct omap_dss_device *dssdev; u32 size, burst_size; u32 fifo_low, fifo_high; u32 fifo_low, fifo_high; if (!op->enabled && !op->enabling) if (!op->enabled && !op->enabling) Loading @@ -871,33 +914,14 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) dssdev = ovl->manager->device; dssdev = ovl->manager->device; size = dispc_ovl_get_fifo_size(ovl->id); dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, use_fifo_merge); burst_size = dispc_ovl_get_burst_size(ovl->id); switch (dssdev->type) { case OMAP_DISPLAY_TYPE_DPI: case OMAP_DISPLAY_TYPE_DBI: case OMAP_DISPLAY_TYPE_SDI: case OMAP_DISPLAY_TYPE_VENC: case OMAP_DISPLAY_TYPE_HDMI: default_get_overlay_fifo_thresholds(ovl->id, size, burst_size, &fifo_low, &fifo_high); break; #ifdef CONFIG_OMAP2_DSS_DSI case OMAP_DISPLAY_TYPE_DSI: dsi_get_overlay_fifo_thresholds(ovl->id, size, burst_size, &fifo_low, &fifo_high); break; #endif default: BUG(); } dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); } } static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, bool use_fifo_merge) { { struct omap_overlay *ovl; struct omap_overlay *ovl; struct mgr_priv_data *mp; struct mgr_priv_data *mp; Loading @@ -908,10 +932,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) return; return; list_for_each_entry(ovl, &mgr->overlays, list) list_for_each_entry(ovl, &mgr->overlays, list) dss_ovl_setup_fifo(ovl); dss_ovl_setup_fifo(ovl, use_fifo_merge); } } static void dss_setup_fifos(void) static void dss_setup_fifos(bool use_fifo_merge) { { const int num_mgrs = omap_dss_get_num_overlay_managers(); const int num_mgrs = omap_dss_get_num_overlay_managers(); struct omap_overlay_manager *mgr; struct omap_overlay_manager *mgr; Loading @@ -919,15 +943,91 @@ static void dss_setup_fifos(void) for (i = 0; i < num_mgrs; ++i) { for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); mgr = omap_dss_get_overlay_manager(i); dss_mgr_setup_fifos(mgr); dss_mgr_setup_fifos(mgr, use_fifo_merge); } } } } static int get_num_used_managers(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; int i; int enabled_mgrs; enabled_mgrs = 0; for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); mp = get_mgr_priv(mgr); if (!mp->enabled) continue; enabled_mgrs++; } return enabled_mgrs; } static int get_num_used_overlays(void) { const int num_ovls = omap_dss_get_num_overlays(); struct omap_overlay *ovl; struct ovl_priv_data *op; struct mgr_priv_data *mp; int i; int enabled_ovls; enabled_ovls = 0; for (i = 0; i < num_ovls; ++i) { ovl = omap_dss_get_overlay(i); op = get_ovl_priv(ovl); if (!op->enabled && !op->enabling) continue; mp = get_mgr_priv(ovl->manager); if (!mp->enabled) continue; enabled_ovls++; } return enabled_ovls; } static bool get_use_fifo_merge(void) { int enabled_mgrs = get_num_used_managers(); int enabled_ovls = get_num_used_overlays(); if (!dss_has_feature(FEAT_FIFO_MERGE)) return false; /* * In theory the only requirement for fifomerge is enabled_ovls <= 1. * However, if we have two managers enabled and set/unset the fifomerge, * we need to set the GO bits in particular sequence for the managers, * and wait in between. * * This is rather difficult as new apply calls can happen at any time, * so we simplify the problem by requiring also that enabled_mgrs <= 1. * In practice this shouldn't matter, because when only one overlay is * enabled, most likely only one output is enabled. */ return enabled_mgrs <= 1 && enabled_ovls <= 1; } int dss_mgr_enable(struct omap_overlay_manager *mgr) int dss_mgr_enable(struct omap_overlay_manager *mgr) { { struct mgr_priv_data *mp = get_mgr_priv(mgr); struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; unsigned long flags; int r; int r; bool fifo_merge; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -945,11 +1045,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) goto err; goto err; } } dss_setup_fifos(); /* step 1: setup fifos/fifomerge before enabling the manager */ fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_write_regs(); dss_set_go_bits(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); /* wait until fifo config is in */ wait_pending_extra_info_updates(); /* step 2: enable the manager */ spin_lock_irqsave(&data_lock, flags); if (!mgr_manual_update(mgr)) if (!mgr_manual_update(mgr)) mp->updating = true; mp->updating = true; Loading @@ -974,6 +1086,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) { { struct mgr_priv_data *mp = get_mgr_priv(mgr); struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; unsigned long flags; bool fifo_merge; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -988,8 +1101,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) mp->updating = false; mp->updating = false; mp->enabled = false; mp->enabled = false; fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); spin_unlock_irqrestore(&data_lock, flags); wait_pending_extra_info_updates(); out: out: mutex_unlock(&apply_lock); mutex_unlock(&apply_lock); } } Loading Loading @@ -1241,6 +1362,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) { { struct ovl_priv_data *op = get_ovl_priv(ovl); struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; unsigned long flags; bool fifo_merge; int r; int r; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -1266,7 +1388,22 @@ int dss_ovl_enable(struct omap_overlay *ovl) goto err2; goto err2; } } dss_setup_fifos(); /* step 1: configure fifos/fifomerge for currently enabled ovls */ fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); /* wait for fifo configs to go in */ wait_pending_extra_info_updates(); /* step 2: enable the overlay */ spin_lock_irqsave(&data_lock, flags); op->enabling = false; op->enabling = false; dss_apply_ovl_enable(ovl, true); dss_apply_ovl_enable(ovl, true); Loading @@ -1276,6 +1413,9 @@ int dss_ovl_enable(struct omap_overlay *ovl) spin_unlock_irqrestore(&data_lock, flags); spin_unlock_irqrestore(&data_lock, flags); /* wait for overlay to be enabled */ wait_pending_extra_info_updates(); mutex_unlock(&apply_lock); mutex_unlock(&apply_lock); return 0; return 0; Loading @@ -1291,6 +1431,7 @@ int dss_ovl_disable(struct omap_overlay *ovl) { { struct ovl_priv_data *op = get_ovl_priv(ovl); struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; unsigned long flags; bool fifo_merge; int r; int r; mutex_lock(&apply_lock); mutex_lock(&apply_lock); Loading @@ -1305,14 +1446,34 @@ int dss_ovl_disable(struct omap_overlay *ovl) goto err; goto err; } } /* step 1: disable the overlay */ spin_lock_irqsave(&data_lock, flags); spin_lock_irqsave(&data_lock, flags); dss_apply_ovl_enable(ovl, false); dss_apply_ovl_enable(ovl, false); dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); /* wait for the overlay to be disabled */ wait_pending_extra_info_updates(); /* step 2: configure fifos/fifomerge */ spin_lock_irqsave(&data_lock, flags); fifo_merge = get_use_fifo_merge(); dss_setup_fifos(fifo_merge); dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_write_regs(); dss_set_go_bits(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); spin_unlock_irqrestore(&data_lock, flags); /* wait for fifo config to go in */ wait_pending_extra_info_updates(); mutex_unlock(&apply_lock); mutex_unlock(&apply_lock); return 0; return 0; Loading
drivers/video/omap2/dss/dispc.c +49 −6 Original line number Original line Diff line number Diff line Loading @@ -909,7 +909,7 @@ static void dispc_configure_burst_sizes(void) dispc_ovl_set_burst_size(i, burst_size); dispc_ovl_set_burst_size(i, burst_size); } } u32 dispc_ovl_get_burst_size(enum omap_plane plane) static u32 dispc_ovl_get_burst_size(enum omap_plane plane) { { unsigned unit = dss_feat_get_burst_size_unit(); unsigned unit = dss_feat_get_burst_size_unit(); /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ Loading Loading @@ -1018,7 +1018,7 @@ static void dispc_read_plane_fifo_sizes(void) } } } } u32 dispc_ovl_get_fifo_size(enum omap_plane plane) static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) { { return dispc.fifo_size[plane]; return dispc.fifo_size[plane]; } } Loading @@ -1039,13 +1039,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n", plane, plane, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), lo_start, lo_end), lo_start, lo_end) * unit, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), hi_start, hi_end), hi_start, hi_end) * unit, low, high); low * unit, high * unit); dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), FLD_VAL(high, hi_start, hi_end) | FLD_VAL(high, hi_start, hi_end) | Loading @@ -1054,10 +1054,53 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) void dispc_enable_fifomerge(bool enable) void dispc_enable_fifomerge(bool enable) { { if (!dss_has_feature(FEAT_FIFO_MERGE)) { WARN_ON(enable); return; } DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } } void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high, bool use_fifomerge) { /* * All sizes are in bytes. Both the buffer and burst are made of * buffer_units, and the fifo thresholds must be buffer_unit aligned. */ unsigned buf_unit = dss_feat_get_buffer_size_unit(); unsigned ovl_fifo_size, total_fifo_size, burst_size; int i; burst_size = dispc_ovl_get_burst_size(plane); ovl_fifo_size = dispc_ovl_get_fifo_size(plane); if (use_fifomerge) { total_fifo_size = 0; for (i = 0; i < omap_dss_get_num_overlays(); ++i) total_fifo_size += dispc_ovl_get_fifo_size(i); } else { total_fifo_size = ovl_fifo_size; } /* * We use the same low threshold for both fifomerge and non-fifomerge * cases, but for fifomerge we calculate the high threshold using the * combined fifo size */ if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { *fifo_low = ovl_fifo_size - burst_size * 2; *fifo_high = total_fifo_size - burst_size; } else { *fifo_low = ovl_fifo_size - burst_size; *fifo_high = total_fifo_size - buf_unit; } } static void dispc_ovl_set_fir(enum omap_plane plane, static void dispc_ovl_set_fir(enum omap_plane plane, int hinc, int vinc, int hinc, int vinc, enum omap_color_component color_comp) enum omap_color_component color_comp) Loading
drivers/video/omap2/dss/display.c +0 −10 Original line number Original line Diff line number Diff line Loading @@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev, } } EXPORT_SYMBOL(omapdss_default_get_resolution); EXPORT_SYMBOL(omapdss_default_get_resolution); void default_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high) { unsigned buf_unit = dss_feat_get_buffer_size_unit(); *fifo_high = fifo_size - buf_unit; *fifo_low = fifo_size - burst_size; } int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) { { switch (dssdev->type) { switch (dssdev->type) { Loading
drivers/video/omap2/dss/dsi.c +0 −8 Original line number Original line Diff line number Diff line Loading @@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) } } EXPORT_SYMBOL(omapdss_dsi_enable_te); EXPORT_SYMBOL(omapdss_dsi_enable_te); void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high) { *fifo_high = fifo_size - burst_size; *fifo_low = fifo_size - burst_size * 2; } int dsi_init_display(struct omap_dss_device *dssdev) int dsi_init_display(struct omap_dss_device *dssdev) { { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); Loading
drivers/video/omap2/dss/dss.h +2 −8 Original line number Original line Diff line number Diff line Loading @@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev, struct omap_dss_device *dssdev); struct omap_dss_device *dssdev); bool dss_use_replication(struct omap_dss_device *dssdev, bool dss_use_replication(struct omap_dss_device *dssdev, enum omap_color_mode mode); enum omap_color_mode mode); void default_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high); /* manager */ /* manager */ int dss_init_overlay_managers(struct platform_device *pdev); int dss_init_overlay_managers(struct platform_device *pdev); Loading Loading @@ -313,9 +310,6 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, bool enable_hsdiv); bool enable_hsdiv); void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, u32 burst_size, u32 *fifo_low, u32 *fifo_high); void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); struct platform_device *dsi_get_dsidev_from_id(int module); struct platform_device *dsi_get_dsidev_from_id(int module); Loading Loading @@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); u32 dispc_ovl_get_fifo_size(enum omap_plane plane); void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, u32 dispc_ovl_get_burst_size(enum omap_plane plane); u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, bool ilace, bool replication); bool ilace, bool replication); int dispc_ovl_enable(enum omap_plane plane, bool enable); int dispc_ovl_enable(enum omap_plane plane, bool enable); Loading