diff options
Diffstat (limited to 'drivers/video/omap2/dss/apply.c')
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 236 |
1 files changed, 25 insertions, 211 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 52a5940a377..6354bb84285 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -111,9 +111,6 @@ static struct { struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; - bool fifo_merge_dirty; - bool fifo_merge; - bool irq_enabled; } dss_data; @@ -677,40 +674,11 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) mp->shadow_extra_info_dirty = true; } -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) { const int num_mgrs = omap_dss_get_num_overlay_managers(); int i; - dss_write_regs_common(); - for (i = 0; i < num_mgrs; ++i) { struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; @@ -799,8 +767,6 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) dss_mgr_write_regs(mgr); dss_mgr_write_regs_extra(mgr); - dss_write_regs_common(); - mp->updating = true; if (!dss_data.irq_enabled && need_isr()) @@ -984,20 +950,11 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, op->extra_info_dirty = true; } -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) +static void dss_ovl_setup_fifo(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); u32 fifo_low, fifo_high; + bool use_fifo_merge = false; if (!op->enabled && !op->enabling) return; @@ -1008,8 +965,7 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); } -static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, - bool use_fifo_merge) +static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) { struct omap_overlay *ovl; struct mgr_priv_data *mp; @@ -1020,10 +976,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, return; list_for_each_entry(ovl, &mgr->overlays, list) - dss_ovl_setup_fifo(ovl, use_fifo_merge); + dss_ovl_setup_fifo(ovl); } -static void dss_setup_fifos(bool use_fifo_merge) +static void dss_setup_fifos(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); struct omap_overlay_manager *mgr; @@ -1031,91 +987,15 @@ static void dss_setup_fifos(bool use_fifo_merge) for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); - dss_mgr_setup_fifos(mgr, use_fifo_merge); + dss_mgr_setup_fifos(mgr); } } -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) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; int r; - bool fifo_merge; mutex_lock(&apply_lock); @@ -1133,23 +1013,11 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) goto err; } - /* 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_setup_fifos(); dss_write_regs(); 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)) mp->updating = true; @@ -1174,7 +1042,6 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; - bool fifo_merge; mutex_lock(&apply_lock); @@ -1189,16 +1056,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) mp->updating = 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); - wait_pending_extra_info_updates(); out: mutex_unlock(&apply_lock); } @@ -1314,21 +1173,19 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings) { unsigned long flags; - - mutex_lock(&apply_lock); + struct mgr_priv_data *mp = get_mgr_priv(mgr); spin_lock_irqsave(&data_lock, flags); - dss_apply_mgr_timings(mgr, timings); - - dss_write_regs(); - dss_set_go_bits(); + if (mp->updating) { + DSSERR("cannot set timings for %s: manager needs to be disabled\n", + mgr->name); + goto out; + } + dss_apply_mgr_timings(mgr, timings); +out: spin_unlock_irqrestore(&data_lock, flags); - - wait_pending_extra_info_updates(); - - mutex_unlock(&apply_lock); } static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, @@ -1346,7 +1203,7 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, unsigned long flags; struct mgr_priv_data *mp = get_mgr_priv(mgr); - mutex_lock(&apply_lock); + spin_lock_irqsave(&data_lock, flags); if (mp->enabled) { DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n", @@ -1354,19 +1211,9 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, 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); + spin_unlock_irqrestore(&data_lock, flags); } int dss_ovl_set_info(struct omap_overlay *ovl, @@ -1483,6 +1330,13 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl) goto err; } + spin_unlock_irqrestore(&data_lock, flags); + + /* wait for pending extra_info updates to ensure the ovl is disabled */ + wait_pending_extra_info_updates(); + + spin_lock_irqsave(&data_lock, flags); + op->channel = -1; ovl->manager = NULL; @@ -1517,7 +1371,6 @@ int dss_ovl_enable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; - bool fifo_merge; int r; mutex_lock(&apply_lock); @@ -1543,22 +1396,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) goto err2; } - /* 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); + dss_setup_fifos(); op->enabling = false; dss_apply_ovl_enable(ovl, true); @@ -1568,9 +1406,6 @@ int dss_ovl_enable(struct omap_overlay *ovl) spin_unlock_irqrestore(&data_lock, flags); - /* wait for overlay to be enabled */ - wait_pending_extra_info_updates(); - mutex_unlock(&apply_lock); return 0; @@ -1586,7 +1421,6 @@ int dss_ovl_disable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; - bool fifo_merge; int r; mutex_lock(&apply_lock); @@ -1601,34 +1435,14 @@ int dss_ovl_disable(struct omap_overlay *ovl) goto err; } - /* step 1: disable the overlay */ spin_lock_irqsave(&data_lock, flags); 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_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); - /* wait for fifo config to go in */ - wait_pending_extra_info_updates(); - mutex_unlock(&apply_lock); return 0; |