* [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
dss_cache struct contains a spinlock used to protect the struct. A more
logical place for the spinlock is outside the struct that it is
protecting. So move it there.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 22 ++++++++++++----------
1 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 23c723a..17639c0 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -89,13 +89,15 @@ struct mgr_priv_data {
};
static struct {
- spinlock_t lock;
struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
bool irq_enabled;
} dss_cache;
+/* protects dss_cache */
+static spinlock_t data_lock;
+
static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
{
return &dss_cache.ovl_priv_data_array[ovl->id];
@@ -108,7 +110,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
void dss_apply_init(void)
{
- spin_lock_init(&dss_cache.lock);
+ spin_lock_init(&data_lock);
}
static bool ovl_manual_update(struct omap_overlay *ovl)
@@ -149,10 +151,10 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
unsigned long flags;
bool shadow_dirty, dirty;
- spin_lock_irqsave(&dss_cache.lock, flags);
+ spin_lock_irqsave(&data_lock, flags);
dirty = mp->dirty;
shadow_dirty = mp->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
+ spin_unlock_irqrestore(&data_lock, flags);
if (!dirty && !shadow_dirty) {
r = 0;
@@ -212,10 +214,10 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
unsigned long flags;
bool shadow_dirty, dirty;
- spin_lock_irqsave(&dss_cache.lock, flags);
+ spin_lock_irqsave(&data_lock, flags);
dirty = op->dirty;
shadow_dirty = op->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
+ spin_unlock_irqrestore(&data_lock, flags);
if (!dirty && !shadow_dirty) {
r = 0;
@@ -464,7 +466,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
for (i = 0; i < num_mgrs; i++)
mgr_busy[i] = dispc_mgr_go_busy(i);
- spin_lock(&dss_cache.lock);
+ spin_lock(&data_lock);
for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
@@ -498,7 +500,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
dss_unregister_vsync_isr();
end:
- spin_unlock(&dss_cache.lock);
+ spin_unlock(&data_lock);
}
static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
@@ -620,7 +622,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
if (r)
return r;
- spin_lock_irqsave(&dss_cache.lock, flags);
+ spin_lock_irqsave(&data_lock, flags);
/* Configure overlays */
list_for_each_entry(ovl, &mgr->overlays, list)
@@ -641,7 +643,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
dss_write_regs();
}
- spin_unlock_irqrestore(&dss_cache.lock, flags);
+ spin_unlock_irqrestore(&data_lock, flags);
dispc_runtime_put();
--
1.7.4.1
^ permalink raw reply related
* [PATCH 36/65] OMAPDSS: APPLY: rename dss_cache to dss_data
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
dss_cache struct contains private data used to manage dispc. "cache" is
not a good word for it, so rename it to dss_data.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 17639c0..46d6a5c 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -38,7 +38,7 @@
* apply()
* v
* +--------------------+
- * | dss_cache |
+ * | info |
* +--------------------+
* v
* write_regs()
@@ -93,19 +93,19 @@ static struct {
struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
bool irq_enabled;
-} dss_cache;
+} dss_data;
-/* protects dss_cache */
+/* protects dss_data */
static spinlock_t data_lock;
static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
{
- return &dss_cache.ovl_priv_data_array[ovl->id];
+ return &dss_data.ovl_priv_data_array[ovl->id];
}
static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
{
- return &dss_cache.mgr_priv_data_array[mgr->id];
+ return &dss_data.mgr_priv_data_array[mgr->id];
}
void dss_apply_init(void)
@@ -433,7 +433,7 @@ static void dss_register_vsync_isr(void)
r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
- dss_cache.irq_enabled = true;
+ dss_data.irq_enabled = true;
}
static void dss_unregister_vsync_isr(void)
@@ -449,7 +449,7 @@ static void dss_unregister_vsync_isr(void)
r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
- dss_cache.irq_enabled = false;
+ dss_data.irq_enabled = false;
}
static void dss_apply_irq_handler(void *data, u32 mask)
@@ -637,7 +637,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
r = 0;
if (mgr->enabled && !mgr_manual_update(mgr)) {
- if (!dss_cache.irq_enabled)
+ if (!dss_data.irq_enabled)
dss_register_vsync_isr();
dss_write_regs();
--
1.7.4.1
^ permalink raw reply related
* [PATCH 37/65] OMAPDSS: APPLY: move ovl funcs to apply.c
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
apply.c will handle the management of dispc in the future patches. This
patch moves overlay related functions to apply.c so that they will have
access to the private data and functions of apply.c.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 84 ++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss.h | 8 +++
drivers/video/omap2/dss/overlay.c | 96 ++----------------------------------
3 files changed, 98 insertions(+), 90 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 46d6a5c..b120f95 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -662,3 +662,87 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
mgr->enabled = false;
}
+int dss_ovl_set_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info)
+{
+ int r;
+ struct omap_overlay_info old_info;
+
+ old_info = ovl->info;
+ ovl->info = *info;
+
+ if (ovl->manager) {
+ r = dss_check_overlay(ovl, ovl->manager->device);
+ if (r) {
+ ovl->info = old_info;
+ return r;
+ }
+ }
+
+ ovl->info_dirty = true;
+
+ return 0;
+}
+
+void dss_ovl_get_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info)
+{
+ *info = ovl->info;
+}
+
+int dss_ovl_set_manager(struct omap_overlay *ovl,
+ struct omap_overlay_manager *mgr)
+{
+ if (!mgr)
+ return -EINVAL;
+
+ if (ovl->manager) {
+ DSSERR("overlay '%s' already has a manager '%s'\n",
+ ovl->name, ovl->manager->name);
+ return -EINVAL;
+ }
+
+ if (ovl->info.enabled) {
+ DSSERR("overlay has to be disabled to change the manager\n");
+ return -EINVAL;
+ }
+
+ ovl->manager = mgr;
+ list_add_tail(&ovl->list, &mgr->overlays);
+ ovl->manager_changed = true;
+
+ /* XXX: When there is an overlay on a DSI manual update display, and
+ * the overlay is first disabled, then moved to tv, and enabled, we
+ * seem to get SYNC_LOST_DIGIT error.
+ *
+ * Waiting doesn't seem to help, but updating the manual update display
+ * after disabling the overlay seems to fix this. This hints that the
+ * overlay is perhaps somehow tied to the LCD output until the output
+ * is updated.
+ *
+ * Userspace workaround for this is to update the LCD after disabling
+ * the overlay, but before moving the overlay to TV.
+ */
+
+ return 0;
+}
+
+int dss_ovl_unset_manager(struct omap_overlay *ovl)
+{
+ if (!ovl->manager) {
+ DSSERR("failed to detach overlay: manager not set\n");
+ return -EINVAL;
+ }
+
+ if (ovl->info.enabled) {
+ DSSERR("overlay has to be disabled to unset the manager\n");
+ return -EINVAL;
+ }
+
+ ovl->manager = NULL;
+ list_del(&ovl->list);
+ ovl->manager_changed = true;
+
+ return 0;
+}
+
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5a6f1db..ee155a1 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -172,6 +172,14 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr);
void dss_mgr_enable(struct omap_overlay_manager *mgr);
void dss_mgr_disable(struct omap_overlay_manager *mgr);
+int dss_ovl_set_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info);
+void dss_ovl_get_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info);
+int dss_ovl_set_manager(struct omap_overlay *ovl,
+ struct omap_overlay_manager *mgr);
+int dss_ovl_unset_manager(struct omap_overlay *ovl);
+
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 3c94065..00c01a3 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -520,90 +520,6 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
return 0;
}
-static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
- struct omap_overlay_info *info)
-{
- int r;
- struct omap_overlay_info old_info;
-
- old_info = ovl->info;
- ovl->info = *info;
-
- if (ovl->manager) {
- r = dss_check_overlay(ovl, ovl->manager->device);
- if (r) {
- ovl->info = old_info;
- return r;
- }
- }
-
- ovl->info_dirty = true;
-
- return 0;
-}
-
-static void dss_ovl_get_overlay_info(struct omap_overlay *ovl,
- struct omap_overlay_info *info)
-{
- *info = ovl->info;
-}
-
-static int omap_dss_set_manager(struct omap_overlay *ovl,
- struct omap_overlay_manager *mgr)
-{
- if (!mgr)
- return -EINVAL;
-
- if (ovl->manager) {
- DSSERR("overlay '%s' already has a manager '%s'\n",
- ovl->name, ovl->manager->name);
- return -EINVAL;
- }
-
- if (ovl->info.enabled) {
- DSSERR("overlay has to be disabled to change the manager\n");
- return -EINVAL;
- }
-
- ovl->manager = mgr;
- list_add_tail(&ovl->list, &mgr->overlays);
- ovl->manager_changed = true;
-
- /* XXX: When there is an overlay on a DSI manual update display, and
- * the overlay is first disabled, then moved to tv, and enabled, we
- * seem to get SYNC_LOST_DIGIT error.
- *
- * Waiting doesn't seem to help, but updating the manual update display
- * after disabling the overlay seems to fix this. This hints that the
- * overlay is perhaps somehow tied to the LCD output until the output
- * is updated.
- *
- * Userspace workaround for this is to update the LCD after disabling
- * the overlay, but before moving the overlay to TV.
- */
-
- return 0;
-}
-
-static int omap_dss_unset_manager(struct omap_overlay *ovl)
-{
- if (!ovl->manager) {
- DSSERR("failed to detach overlay: manager not set\n");
- return -EINVAL;
- }
-
- if (ovl->info.enabled) {
- DSSERR("overlay has to be disabled to unset the manager\n");
- return -EINVAL;
- }
-
- ovl->manager = NULL;
- list_del(&ovl->list);
- ovl->manager_changed = true;
-
- return 0;
-}
-
int omap_dss_get_num_overlays(void)
{
return num_overlays;
@@ -663,10 +579,10 @@ void dss_init_overlays(struct platform_device *pdev)
break;
}
- ovl->set_manager = &omap_dss_set_manager;
- ovl->unset_manager = &omap_dss_unset_manager;
- ovl->set_overlay_info = &dss_ovl_set_overlay_info;
- ovl->get_overlay_info = &dss_ovl_get_overlay_info;
+ ovl->set_manager = &dss_ovl_set_manager;
+ ovl->unset_manager = &dss_ovl_unset_manager;
+ ovl->set_overlay_info = &dss_ovl_set_info;
+ ovl->get_overlay_info = &dss_ovl_get_info;
ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
@@ -731,8 +647,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
ovl = omap_dss_get_overlay(i);
if (!ovl->manager || force) {
if (ovl->manager)
- omap_dss_unset_manager(ovl);
- omap_dss_set_manager(ovl, mgr);
+ ovl->unset_manager(ovl);
+ ovl->set_manager(ovl, mgr);
}
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 38/65] OMAPDSS: APPLY: move mgr funcs to apply.c
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
apply.c will handle the management of dispc in the future patches. This
patch moves overlay manager related functions to apply.c so that they
will have access to the private data and functions of apply.c.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 83 +++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss.h | 9 ++++
drivers/video/omap2/dss/manager.c | 91 ++-----------------------------------
3 files changed, 97 insertions(+), 86 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index b120f95..543a10b 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -662,6 +662,89 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
mgr->enabled = false;
}
+int dss_mgr_set_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info)
+{
+ int r;
+ struct omap_overlay_manager_info old_info;
+
+ old_info = mgr->info;
+ mgr->info = *info;
+
+ r = dss_check_manager(mgr);
+ if (r) {
+ mgr->info = old_info;
+ return r;
+ }
+
+ mgr->info_dirty = true;
+
+ return 0;
+}
+
+void dss_mgr_get_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info)
+{
+ *info = mgr->info;
+}
+
+int dss_mgr_set_device(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev)
+{
+ int r;
+ struct omap_overlay *ovl;
+
+ if (dssdev->manager) {
+ DSSERR("display '%s' already has a manager '%s'\n",
+ dssdev->name, dssdev->manager->name);
+ return -EINVAL;
+ }
+
+ if ((mgr->supported_displays & dssdev->type) = 0) {
+ DSSERR("display '%s' does not support manager '%s'\n",
+ dssdev->name, mgr->name);
+ return -EINVAL;
+ }
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ if (!ovl->info.enabled)
+ continue;
+
+ r = dss_check_overlay(ovl, dssdev);
+ if (r)
+ return r;
+ }
+
+ dssdev->manager = mgr;
+ mgr->device = dssdev;
+ mgr->device_changed = true;
+
+ return 0;
+}
+
+int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
+{
+ if (!mgr->device) {
+ DSSERR("failed to unset display, display not set.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Don't allow currently enabled displays to have the overlay manager
+ * pulled out from underneath them
+ */
+ if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED)
+ return -EINVAL;
+
+ mgr->device->manager = NULL;
+ mgr->device = NULL;
+ mgr->device_changed = true;
+
+ return 0;
+}
+
+
+
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index ee155a1..afe9713 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -169,8 +169,16 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr);
int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
void dss_start_update(struct omap_overlay_manager *mgr);
int omap_dss_mgr_apply(struct omap_overlay_manager *mgr);
+
void dss_mgr_enable(struct omap_overlay_manager *mgr);
void dss_mgr_disable(struct omap_overlay_manager *mgr);
+int dss_mgr_set_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info);
+void dss_mgr_get_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info);
+int dss_mgr_set_device(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev);
+int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info);
@@ -198,6 +206,7 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
/* manager */
int dss_init_overlay_managers(struct platform_device *pdev);
void dss_uninit_overlay_managers(struct platform_device *pdev);
+int dss_check_manager(struct omap_overlay_manager *mgr);
/* overlay */
void dss_init_overlays(struct platform_device *pdev);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 62bcc38..ab0b61b 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -467,61 +467,6 @@ static struct kobj_type manager_ktype = {
.default_attrs = manager_sysfs_attrs,
};
-static int omap_dss_set_device(struct omap_overlay_manager *mgr,
- struct omap_dss_device *dssdev)
-{
- int r;
- struct omap_overlay *ovl;
-
- if (dssdev->manager) {
- DSSERR("display '%s' already has a manager '%s'\n",
- dssdev->name, dssdev->manager->name);
- return -EINVAL;
- }
-
- if ((mgr->supported_displays & dssdev->type) = 0) {
- DSSERR("display '%s' does not support manager '%s'\n",
- dssdev->name, mgr->name);
- return -EINVAL;
- }
-
- list_for_each_entry(ovl, &mgr->overlays, list) {
- if (!ovl->info.enabled)
- continue;
-
- r = dss_check_overlay(ovl, dssdev);
- if (r)
- return r;
- }
-
- dssdev->manager = mgr;
- mgr->device = dssdev;
- mgr->device_changed = true;
-
- return 0;
-}
-
-static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
-{
- if (!mgr->device) {
- DSSERR("failed to unset display, display not set.\n");
- return -EINVAL;
- }
-
- /*
- * Don't allow currently enabled displays to have the overlay manager
- * pulled out from underneath them
- */
- if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED)
- return -EINVAL;
-
- mgr->device->manager = NULL;
- mgr->device = NULL;
- mgr->device_changed = true;
-
- return 0;
-}
-
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
@@ -540,7 +485,7 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
}
-static int dss_check_manager(struct omap_overlay_manager *mgr)
+int dss_check_manager(struct omap_overlay_manager *mgr)
{
if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
/*
@@ -557,32 +502,6 @@ static int dss_check_manager(struct omap_overlay_manager *mgr)
return 0;
}
-static int omap_dss_mgr_set_info(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info)
-{
- int r;
- struct omap_overlay_manager_info old_info;
-
- old_info = mgr->info;
- mgr->info = *info;
-
- r = dss_check_manager(mgr);
- if (r) {
- mgr->info = old_info;
- return r;
- }
-
- mgr->info_dirty = true;
-
- return 0;
-}
-
-static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info)
-{
- *info = mgr->info;
-}
-
int dss_init_overlay_managers(struct platform_device *pdev)
{
int i, r;
@@ -612,11 +531,11 @@ int dss_init_overlay_managers(struct platform_device *pdev)
break;
}
- mgr->set_device = &omap_dss_set_device;
- mgr->unset_device = &omap_dss_unset_device;
+ mgr->set_device = &dss_mgr_set_device;
+ mgr->unset_device = &dss_mgr_unset_device;
mgr->apply = &omap_dss_mgr_apply;
- mgr->set_manager_info = &omap_dss_mgr_set_info;
- mgr->get_manager_info = &omap_dss_mgr_get_info;
+ mgr->set_manager_info = &dss_mgr_set_info;
+ mgr->get_manager_info = &dss_mgr_get_info;
mgr->wait_for_go = &dss_mgr_wait_for_go;
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 39/65] OMAPDSS: remove ovl/mgr check-code temporarily
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
DSS currently tries to check that the given overlay and overlay manager
settings are acceptable, but the code does not work quite properly.
Things may change between the check and the actual use of the settings.
Furthermore, the following patches will rewrite how settings are
configured and managed, and trying to keep the (broken) settings
checking working during the rewrite would be very difficult.
This patch removes the checking code, and a working version of checking
will be added back after the settings rewrite has been done.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 53 +--------------------
drivers/video/omap2/dss/dss.h | 2 -
drivers/video/omap2/dss/manager.c | 17 -------
drivers/video/omap2/dss/overlay.c | 90 -------------------------------------
4 files changed, 3 insertions(+), 159 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 543a10b..b935264 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -503,10 +503,9 @@ end:
spin_unlock(&data_lock);
}
-static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
+static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
{
struct ovl_priv_data *op;
- struct omap_dss_device *dssdev;
op = get_ovl_priv(ovl);
@@ -520,21 +519,11 @@ static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
op->enabled = false;
op->dirty = true;
}
- return 0;
+ return;
}
if (!ovl->info_dirty)
- return 0;
-
- dssdev = ovl->manager->device;
-
- if (dss_check_overlay(ovl, dssdev)) {
- if (op->enabled) {
- op->enabled = false;
- op->dirty = true;
- }
- return -EINVAL;
- }
+ return;
ovl->info_dirty = false;
op->dirty = true;
@@ -543,8 +532,6 @@ static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
op->channel = ovl->manager->id;
op->enabled = true;
-
- return 0;
}
static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
@@ -665,18 +652,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
int dss_mgr_set_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info)
{
- int r;
- struct omap_overlay_manager_info old_info;
-
- old_info = mgr->info;
mgr->info = *info;
-
- r = dss_check_manager(mgr);
- if (r) {
- mgr->info = old_info;
- return r;
- }
-
mgr->info_dirty = true;
return 0;
@@ -692,7 +668,6 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev)
{
int r;
- struct omap_overlay *ovl;
if (dssdev->manager) {
DSSERR("display '%s' already has a manager '%s'\n",
@@ -706,15 +681,6 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
return -EINVAL;
}
- list_for_each_entry(ovl, &mgr->overlays, list) {
- if (!ovl->info.enabled)
- continue;
-
- r = dss_check_overlay(ovl, dssdev);
- if (r)
- return r;
- }
-
dssdev->manager = mgr;
mgr->device = dssdev;
mgr->device_changed = true;
@@ -748,20 +714,7 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
- int r;
- struct omap_overlay_info old_info;
-
- old_info = ovl->info;
ovl->info = *info;
-
- if (ovl->manager) {
- r = dss_check_overlay(ovl, ovl->manager->device);
- if (r) {
- ovl->info = old_info;
- return r;
- }
- }
-
ovl->info_dirty = true;
return 0;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index afe9713..0ef0e08 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -206,12 +206,10 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
/* manager */
int dss_init_overlay_managers(struct platform_device *pdev);
void dss_uninit_overlay_managers(struct platform_device *pdev);
-int dss_check_manager(struct omap_overlay_manager *mgr);
/* overlay */
void dss_init_overlays(struct platform_device *pdev);
void dss_uninit_overlays(struct platform_device *pdev);
-int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev);
void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index ab0b61b..d7fd494 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -485,23 +485,6 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
}
-int dss_check_manager(struct omap_overlay_manager *mgr)
-{
- if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
- /*
- * OMAP3 supports only graphics source transparency color key
- * and alpha blending simultaneously. See TRM 15.4.2.4.2.2
- * Alpha Mode
- */
- if (mgr->info.partial_alpha_enabled && mgr->info.trans_enabled
- && mgr->info.trans_key_type !- OMAP_DSS_COLOR_KEY_GFX_DST)
- return -EINVAL;
- }
-
- return 0;
-}
-
int dss_init_overlay_managers(struct platform_device *pdev)
{
int i, r;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 00c01a3..4dc6b92 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -430,96 +430,6 @@ static struct kobj_type overlay_ktype = {
.default_attrs = overlay_sysfs_attrs,
};
-/* Check if overlay parameters are compatible with display */
-int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
-{
- struct omap_overlay_info *info;
- u16 outw, outh;
- u16 dw, dh;
- int i;
-
- if (!dssdev)
- return 0;
-
- if (!ovl->info.enabled)
- return 0;
-
- info = &ovl->info;
-
- if (info->paddr = 0) {
- DSSDBG("check_overlay failed: paddr 0\n");
- return -EINVAL;
- }
-
- dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
- DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
- ovl->id,
- info->pos_x, info->pos_y,
- info->width, info->height,
- info->out_width, info->out_height,
- dw, dh);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) = 0) {
- outw = info->width;
- outh = info->height;
- } else {
- if (info->out_width = 0)
- outw = info->width;
- else
- outw = info->out_width;
-
- if (info->out_height = 0)
- outh = info->height;
- else
- outh = info->out_height;
- }
-
- if (dw < info->pos_x + outw) {
- DSSDBG("check_overlay failed 1: %d < %d + %d\n",
- dw, info->pos_x, outw);
- return -EINVAL;
- }
-
- if (dh < info->pos_y + outh) {
- DSSDBG("check_overlay failed 2: %d < %d + %d\n",
- dh, info->pos_y, outh);
- return -EINVAL;
- }
-
- if ((ovl->supported_modes & info->color_mode) = 0) {
- DSSERR("overlay doesn't support mode %d\n", info->color_mode);
- return -EINVAL;
- }
-
- if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) {
- if (info->zorder < 0 || info->zorder > 3) {
- DSSERR("zorder out of range: %d\n",
- info->zorder);
- return -EINVAL;
- }
- /*
- * Check that zorder doesn't match with zorder of any other
- * overlay which is enabled and is also connected to the same
- * manager
- */
- for (i = 0; i < omap_dss_get_num_overlays(); i++) {
- struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i);
-
- if (tmp_ovl->id != ovl->id &&
- tmp_ovl->manager = ovl->manager &&
- tmp_ovl->info.enabled = true &&
- tmp_ovl->info.zorder = info->zorder) {
- DSSERR("%s and %s have same zorder: %d\n",
- ovl->name, tmp_ovl->name, info->zorder);
- return -EINVAL;
- }
- }
- }
-
- return 0;
-}
-
int omap_dss_get_num_overlays(void)
{
return num_overlays;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 40/65] OMAPDSS: APPLY: add mutex
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
The functions in apply.c, called mostly via function pointers in overlay
and overlay_manager structs, will be divided into two groups. The other
group will not sleep and can be called from interrupts, and the other
group may sleep.
The idea is that the non-sleeping functions may only change certain
settings in overlays and managers, and those settings may only affect
the particular overlay/manager. For example, set the base address of the
overlay.
The blocking functions, however, will handle more complex configuration
changes. For example, when an overlay is enabled and fifo-merge feature
is used, we need to do the enable in multiple steps, waiting in between,
and the change affects multiple overlays and managers.
This patch adds the mutex which is used in the blocking functions to
have exclusive access to overlays and overlay managers.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 71 ++++++++++++++++++++++++++++++++++-----
1 files changed, 62 insertions(+), 9 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index b935264..fb6d3c2 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -97,6 +97,8 @@ static struct {
/* protects dss_data */
static spinlock_t data_lock;
+/* lock for blocking functions */
+static DEFINE_MUTEX(apply_lock);
static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
{
@@ -639,14 +641,22 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
void dss_mgr_enable(struct omap_overlay_manager *mgr)
{
+ mutex_lock(&apply_lock);
+
dispc_mgr_enable(mgr->id, true);
mgr->enabled = true;
+
+ mutex_unlock(&apply_lock);
}
void dss_mgr_disable(struct omap_overlay_manager *mgr)
{
+ mutex_lock(&apply_lock);
+
dispc_mgr_enable(mgr->id, false);
mgr->enabled = false;
+
+ mutex_unlock(&apply_lock);
}
int dss_mgr_set_info(struct omap_overlay_manager *mgr,
@@ -669,44 +679,65 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
{
int r;
+ mutex_lock(&apply_lock);
+
if (dssdev->manager) {
DSSERR("display '%s' already has a manager '%s'\n",
dssdev->name, dssdev->manager->name);
- return -EINVAL;
+ r = -EINVAL;
+ goto err;
}
if ((mgr->supported_displays & dssdev->type) = 0) {
DSSERR("display '%s' does not support manager '%s'\n",
dssdev->name, mgr->name);
- return -EINVAL;
+ r = -EINVAL;
+ goto err;
}
dssdev->manager = mgr;
mgr->device = dssdev;
mgr->device_changed = true;
+ mutex_unlock(&apply_lock);
+
return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
}
int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
{
+ int r;
+
+ mutex_lock(&apply_lock);
+
if (!mgr->device) {
DSSERR("failed to unset display, display not set.\n");
- return -EINVAL;
+ r = -EINVAL;
+ goto err;
}
/*
* Don't allow currently enabled displays to have the overlay manager
* pulled out from underneath them
*/
- if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED)
- return -EINVAL;
+ if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+ r = -EINVAL;
+ goto err;
+ }
mgr->device->manager = NULL;
mgr->device = NULL;
mgr->device_changed = true;
+ mutex_unlock(&apply_lock);
+
return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
}
@@ -729,18 +760,24 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr)
{
+ int r;
+
if (!mgr)
return -EINVAL;
+ mutex_lock(&apply_lock);
+
if (ovl->manager) {
DSSERR("overlay '%s' already has a manager '%s'\n",
ovl->name, ovl->manager->name);
- return -EINVAL;
+ r = -EINVAL;
+ goto err;
}
if (ovl->info.enabled) {
DSSERR("overlay has to be disabled to change the manager\n");
- return -EINVAL;
+ r = -EINVAL;
+ goto err;
}
ovl->manager = mgr;
@@ -760,25 +797,41 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
* the overlay, but before moving the overlay to TV.
*/
+ mutex_unlock(&apply_lock);
+
return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
}
int dss_ovl_unset_manager(struct omap_overlay *ovl)
{
+ int r;
+
+ mutex_lock(&apply_lock);
+
if (!ovl->manager) {
DSSERR("failed to detach overlay: manager not set\n");
- return -EINVAL;
+ r = -EINVAL;
+ goto err;
}
if (ovl->info.enabled) {
DSSERR("overlay has to be disabled to unset the manager\n");
- return -EINVAL;
+ r = -EINVAL;
+ goto err;
}
ovl->manager = NULL;
list_del(&ovl->list);
ovl->manager_changed = true;
+ mutex_unlock(&apply_lock);
+
return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
The functions in apply.c, called mostly via function pointers in overlay
and overlay_manager structs, will be divided into two groups. The other
group will not sleep and can be called from interrupts, and the other
group may sleep.
The idea is that the non-sleeping functions may only change certain
settings in overlays and managers, and those settings may only affect
the particular overlay/manager. For example, set the base address of the
overlay.
The blocking functions, however, will handle more complex configuration
changes. For example, when an overlay is enabled and fifo-merge feature
is used, we need to do the enable in multiple steps, waiting in between,
and the change affects multiple overlays and managers.
apply.c already contains a spinlock, which has been used to protect
(badly) the dss_data. This patch adds locks/unlocks of the spinlock to
the missing places, and the lock should now properly protect dss_data.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 29 +++++++++++++++++++++++++++++
1 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index fb6d3c2..9ad2a36 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -405,6 +405,9 @@ void dss_start_update(struct omap_overlay_manager *mgr)
struct mgr_priv_data *mp = get_mgr_priv(mgr);
struct ovl_priv_data *op;
struct omap_overlay *ovl;
+ unsigned long flags;
+
+ spin_lock_irqsave(&data_lock, flags);
mp->do_manual_update = true;
dss_write_regs();
@@ -418,6 +421,8 @@ void dss_start_update(struct omap_overlay_manager *mgr)
mp->shadow_dirty = false;
dispc_mgr_enable(mgr->id, true);
+
+ spin_unlock_irqrestore(&data_lock, flags);
}
static void dss_apply_irq_handler(void *data, u32 mask);
@@ -662,16 +667,28 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
int dss_mgr_set_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&data_lock, flags);
+
mgr->info = *info;
mgr->info_dirty = true;
+ spin_unlock_irqrestore(&data_lock, flags);
+
return 0;
}
void dss_mgr_get_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&data_lock, flags);
+
*info = mgr->info;
+
+ spin_unlock_irqrestore(&data_lock, flags);
}
int dss_mgr_set_device(struct omap_overlay_manager *mgr,
@@ -745,16 +762,28 @@ err:
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&data_lock, flags);
+
ovl->info = *info;
ovl->info_dirty = true;
+ spin_unlock_irqrestore(&data_lock, flags);
+
return 0;
}
void dss_ovl_get_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&data_lock, flags);
+
*info = ovl->info;
+
+ spin_unlock_irqrestore(&data_lock, flags);
}
int dss_ovl_set_manager(struct omap_overlay *ovl,
--
1.7.4.1
^ permalink raw reply related
* [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
The current code uses dsi_video_mode_enable/disable functions to
enable/disable DISPC output for video mode displays. For command mode
displays we have no notion in the DISPC side of whether the panel is
enabled, except when a dss_start_update() call is made.
However, to properly maintain the DISPC state in apply.c, we need to
know if a manager used for a manual update display is currently in use.
This patch achieves that by changing dsi_video_mode_enable/disable to
dsi_enable/disable_video_output, which is called by both video and
command mode displays. For video mode displays it starts the actual
pixel stream, as it did before. For command mode displays it doesn't do
anything else than mark that the manager is currently in use.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays/panel-taal.c | 6 ++
drivers/video/omap2/dss/apply.c | 6 ++-
drivers/video/omap2/dss/dsi.c | 73 +++++++++++++++-------------
include/video/omapdss.h | 4 +-
4 files changed, 51 insertions(+), 38 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index dd64bd1..00c5c61 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1182,6 +1182,10 @@ static int taal_power_on(struct omap_dss_device *dssdev)
if (r)
goto err;
+ r = dsi_enable_video_output(dssdev, td->channel);
+ if (r)
+ goto err;
+
td->enabled = 1;
if (!td->intro_printed) {
@@ -1211,6 +1215,8 @@ static void taal_power_off(struct omap_dss_device *dssdev)
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
int r;
+ dsi_disable_video_output(dssdev, td->channel);
+
r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
if (!r)
r = taal_sleep_in(td);
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 9ad2a36..66f4c56 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -648,7 +648,8 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
{
mutex_lock(&apply_lock);
- dispc_mgr_enable(mgr->id, true);
+ if (!mgr_manual_update(mgr))
+ dispc_mgr_enable(mgr->id, true);
mgr->enabled = true;
mutex_unlock(&apply_lock);
@@ -658,7 +659,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
{
mutex_lock(&apply_lock);
- dispc_mgr_enable(mgr->id, false);
+ if (!mgr_manual_update(mgr))
+ dispc_mgr_enable(mgr->id, false);
mgr->enabled = false;
mutex_unlock(&apply_lock);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 08d3de90..a35f3fb 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3939,65 +3939,70 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
}
}
-int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel)
+int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
u8 data_type;
u16 word_count;
- switch (dssdev->panel.dsi_pix_fmt) {
- case OMAP_DSS_DSI_FMT_RGB888:
- data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
- break;
- case OMAP_DSS_DSI_FMT_RGB666:
- data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
- break;
- case OMAP_DSS_DSI_FMT_RGB666_PACKED:
- data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
- break;
- case OMAP_DSS_DSI_FMT_RGB565:
- data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
- break;
- default:
- BUG();
- };
+ if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_VIDEO_MODE) {
+ switch (dssdev->panel.dsi_pix_fmt) {
+ case OMAP_DSS_DSI_FMT_RGB888:
+ data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
+ break;
+ case OMAP_DSS_DSI_FMT_RGB666:
+ data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
+ break;
+ case OMAP_DSS_DSI_FMT_RGB666_PACKED:
+ data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
+ break;
+ case OMAP_DSS_DSI_FMT_RGB565:
+ data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
+ break;
+ default:
+ BUG();
+ };
- dsi_if_enable(dsidev, false);
- dsi_vc_enable(dsidev, channel, false);
+ dsi_if_enable(dsidev, false);
+ dsi_vc_enable(dsidev, channel, false);
- /* MODE, 1 = video mode */
- REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
+ /* MODE, 1 = video mode */
+ REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
- word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+ word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
- dsi_vc_write_long_header(dsidev, channel, data_type, word_count, 0);
+ dsi_vc_write_long_header(dsidev, channel, data_type,
+ word_count, 0);
- dsi_vc_enable(dsidev, channel, true);
- dsi_if_enable(dsidev, true);
+ dsi_vc_enable(dsidev, channel, true);
+ dsi_if_enable(dsidev, true);
+ }
dss_mgr_enable(dssdev->manager);
return 0;
}
-EXPORT_SYMBOL(dsi_video_mode_enable);
+EXPORT_SYMBOL(dsi_enable_video_output);
-void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel)
+void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- dsi_if_enable(dsidev, false);
- dsi_vc_enable(dsidev, channel, false);
+ if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_VIDEO_MODE) {
+ dsi_if_enable(dsidev, false);
+ dsi_vc_enable(dsidev, channel, false);
- /* MODE, 0 = command mode */
- REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
+ /* MODE, 0 = command mode */
+ REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
- dsi_vc_enable(dsidev, channel, true);
- dsi_if_enable(dsidev, true);
+ dsi_vc_enable(dsidev, channel, true);
+ dsi_if_enable(dsidev, true);
+ }
dss_mgr_disable(dssdev->manager);
}
-EXPORT_SYMBOL(dsi_video_mode_disable);
+EXPORT_SYMBOL(dsi_disable_video_output);
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
u16 w, u16 h)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index eaeca89..25ef771 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -294,8 +294,8 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
u16 len);
int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
-int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel);
-void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel);
+int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel);
+void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel);
/* Board specific data */
struct omap_dss_board_info {
--
1.7.4.1
^ permalink raw reply related
* [PATCH 43/65] OMAPDSS: APPLY: move mgr->enabled to mgr_priv_data
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
struct omap_overlay_manager contains "enabled"-field, used to track if
the manager is enabled or not. This field should be internal to apply.c.
This patch moves the field to mgr_priv_data, and applies the necessary
locking when accessing the field.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 26 +++++++++++++++++++++++---
include/video/omapdss.h | 2 --
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 66f4c56..c38bd76 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -86,6 +86,9 @@ struct mgr_priv_data {
bool manual_update;
bool do_manual_update;
+
+ /* If true, a display is enabled using this manager */
+ bool enabled;
};
static struct {
@@ -609,6 +612,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
int r;
unsigned long flags;
struct omap_overlay *ovl;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
@@ -630,7 +634,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
omap_dss_mgr_apply_ovl_fifos(ovl);
r = 0;
- if (mgr->enabled && !mgr_manual_update(mgr)) {
+ if (mp->enabled && !mgr_manual_update(mgr)) {
if (!dss_data.irq_enabled)
dss_register_vsync_isr();
@@ -646,22 +650,38 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
void dss_mgr_enable(struct omap_overlay_manager *mgr)
{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+
mutex_lock(&apply_lock);
if (!mgr_manual_update(mgr))
dispc_mgr_enable(mgr->id, true);
- mgr->enabled = true;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ mp->enabled = true;
+
+ spin_unlock_irqrestore(&data_lock, flags);
mutex_unlock(&apply_lock);
}
void dss_mgr_disable(struct omap_overlay_manager *mgr)
{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+
mutex_lock(&apply_lock);
if (!mgr_manual_update(mgr))
dispc_mgr_enable(mgr->id, false);
- mgr->enabled = false;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ mp->enabled = false;
+
+ spin_unlock_irqrestore(&data_lock, flags);
mutex_unlock(&apply_lock);
}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 25ef771..6e3e7a7 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -430,8 +430,6 @@ struct omap_overlay_manager {
struct omap_dss_device *device;
struct omap_overlay_manager_info info;
- bool enabled;
-
bool device_changed;
/* if true, info has been changed but not applied() yet */
bool info_dirty;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 44/65] OMAPDSS: APPLY: add busy field to mgr_priv_data
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add a new field to mgr_priv data, "busy", which is used to track the
status of GO bit with the manager. As manual update displays never use
the GO bit, the field is always false for managers used for manual
update displays.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 55 +++++++++++++++++++++++++-------------
1 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index c38bd76..323cffa 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -87,6 +87,10 @@ struct mgr_priv_data {
bool manual_update;
bool do_manual_update;
+ /* If true, GO bit is up and shadow registers cannot be written.
+ * Never true for manual update displays */
+ bool busy;
+
/* If true, a display is enabled using this manager */
bool enabled;
};
@@ -319,18 +323,12 @@ static int dss_write_regs(void)
const int num_mgrs = dss_feat_get_num_mgrs();
int i;
int r;
- bool mgr_busy[MAX_DSS_MANAGERS];
- bool mgr_go[MAX_DSS_MANAGERS];
+ bool mgr_go[MAX_DSS_MANAGERS] = { false };
bool busy;
r = 0;
busy = false;
- for (i = 0; i < num_mgrs; i++) {
- mgr_busy[i] = dispc_mgr_go_busy(i);
- mgr_go[i] = false;
- }
-
/* Commit overlay settings */
for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
@@ -344,7 +342,7 @@ static int dss_write_regs(void)
if (mp->manual_update && !mp->do_manual_update)
continue;
- if (mgr_busy[op->channel]) {
+ if (mp->busy) {
busy = true;
continue;
}
@@ -369,7 +367,7 @@ static int dss_write_regs(void)
if (mp->manual_update && !mp->do_manual_update)
continue;
- if (mgr_busy[i]) {
+ if (mp->busy) {
busy = true;
continue;
}
@@ -391,8 +389,10 @@ static int dss_write_regs(void)
/* We don't need GO with manual update display. LCD iface will
* always be turned off after frame, and new settings will be
* taken in to use at next update */
- if (!mp->manual_update)
+ if (!mp->manual_update) {
+ mp->busy = true;
dispc_mgr_go(i);
+ }
}
if (busy)
@@ -471,24 +471,34 @@ static void dss_apply_irq_handler(void *data, u32 mask)
const int num_ovls = dss_feat_get_num_ovls();
const int num_mgrs = dss_feat_get_num_mgrs();
int i, r;
- bool mgr_busy[MAX_DSS_MANAGERS];
-
- for (i = 0; i < num_mgrs; i++)
- mgr_busy[i] = dispc_mgr_go_busy(i);
spin_lock(&data_lock);
+ for (i = 0; i < num_mgrs; i++) {
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ mp->busy = dispc_mgr_go_busy(i);
+ }
+
for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
op = get_ovl_priv(ovl);
- if (!mgr_busy[op->channel])
+
+ if (!op->enabled)
+ continue;
+
+ mp = get_mgr_priv(ovl->manager);
+
+ if (!mp->busy)
op->shadow_dirty = false;
}
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
mp = get_mgr_priv(mgr);
- if (!mgr_busy[i])
+
+ if (!mp->busy)
mp->shadow_dirty = false;
}
@@ -497,13 +507,20 @@ static void dss_apply_irq_handler(void *data, u32 mask)
goto end;
/* re-read busy flags */
- for (i = 0; i < num_mgrs; i++)
- mgr_busy[i] = dispc_mgr_go_busy(i);
+ for (i = 0; i < num_mgrs; i++) {
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ mp->busy = dispc_mgr_go_busy(i);
+ }
/* keep running as long as there are busy managers, so that
* we can collect overlay-applied information */
for (i = 0; i < num_mgrs; ++i) {
- if (mgr_busy[i])
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ if (mp->busy)
goto end;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 45/65] OMAPDSS: APPLY: rewrite overlay enable/disable
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Overlays are currently enabled and disabled with a boolean in the struct
omap_overlay_info. The overlay info is set with ovl->set_overlay_info(),
and made into use with mgr->apply().
This doesn't work properly, as the enable/disable status may affect also
other overlays, for example when using fifo-merge. Thus the enabling and
disabling of the overlay needs to be done outside the normal overlay
configuration.
This patch achieves that by doing the following things:
1) Add function pointers to struct omap_overlay: enable(), disable() and
is_enabled(). These are used to do the obvious. The functions may block.
2) Move the "enabled" field from struct omap_overlay to ovl_priv_data.
3) Add a new route for settings to be applied to the HW, called
"extra_info". The status of the normal info and extra_info are tracked
separately.
The point here is to allow the normal info to be changed and
applied in non-blocking matter, whereas the extra_info can only be
changed when holding the mutex. This makes it possible to, for example,
set the overlay enable flag, apply it, and wait until the HW has taken
the flag into use.
This is not possible if the enable flag would be in the normal info, as
a new value for the flag could be set at any time from the users of
omapdss.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/media/video/omap/omap_vout.c | 33 +++---
drivers/video/omap2/dss/apply.c | 163 ++++++++++++++++++++++++-----
drivers/video/omap2/dss/dss.h | 3 +
drivers/video/omap2/dss/overlay.c | 20 ++--
drivers/video/omap2/omapfb/omapfb-ioctl.c | 30 +++---
drivers/video/omap2/omapfb/omapfb-main.c | 2 +
drivers/video/omap2/omapfb/omapfb-sysfs.c | 4 +-
drivers/video/omap2/omapfb/omapfb.h | 11 +--
include/video/omapdss.h | 6 +-
9 files changed, 190 insertions(+), 82 deletions(-)
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 9c5c19f..27c19fe 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -423,7 +423,7 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout,
"%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
"rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
"out_height=%d rotation_type=%d screen_width=%d\n",
- __func__, info.enabled, info.paddr, info.width, info.height,
+ __func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height,
info.color_mode, info.rotation, info.mirror, info.pos_x,
info.pos_y, info.out_width, info.out_height, info.rotation_type,
info.screen_width);
@@ -942,12 +942,8 @@ static int omap_vout_release(struct file *file)
/* Disable all the overlay managers connected with this interface */
for (i = 0; i < ovid->num_overlays; i++) {
struct omap_overlay *ovl = ovid->overlays[i];
- if (ovl->manager && ovl->manager->device) {
- struct omap_overlay_info info;
- ovl->get_overlay_info(ovl, &info);
- info.enabled = 0;
- ovl->set_overlay_info(ovl, &info);
- }
+ if (ovl->manager && ovl->manager->device)
+ ovl->disable(ovl);
}
/* Turn off the pipeline */
ret = omapvid_apply_changes(vout);
@@ -1667,7 +1663,6 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
if (ovl->manager && ovl->manager->device) {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
- info.enabled = 1;
info.paddr = addr;
if (ovl->set_overlay_info(ovl, &info)) {
ret = -EINVAL;
@@ -1686,6 +1681,16 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
if (ret)
v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
+ for (j = 0; j < ovid->num_overlays; j++) {
+ struct omap_overlay *ovl = ovid->overlays[j];
+
+ if (ovl->manager && ovl->manager->device) {
+ ret = ovl->enable(ovl);
+ if (ret)
+ goto streamon_err1;
+ }
+ }
+
ret = 0;
streamon_err1:
@@ -1715,16 +1720,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
- if (ovl->manager && ovl->manager->device) {
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
- info.enabled = 0;
- ret = ovl->set_overlay_info(ovl, &info);
- if (ret)
- v4l2_err(&vout->vid_dev->v4l2_dev,
- "failed to update overlay info in streamoff\n");
- }
+ if (ovl->manager && ovl->manager->device)
+ ovl->disable(ovl);
}
/* Turn of the pipeline */
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 323cffa..2c60e77 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -63,14 +63,18 @@ struct ovl_priv_data {
* VSYNC/EVSYNC */
bool shadow_dirty;
- bool enabled;
-
struct omap_overlay_info info;
enum omap_channel channel;
u32 fifo_low;
u32 fifo_high;
+
+ bool extra_info_dirty;
+ bool shadow_extra_info_dirty;
+
+ bool enabled;
+
};
struct mgr_priv_data {
@@ -132,11 +136,6 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
}
-static int overlay_enabled(struct omap_overlay *ovl)
-{
- return ovl->info.enabled && ovl->manager && ovl->manager->device;
-}
-
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
@@ -270,10 +269,8 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
op = get_ovl_priv(ovl);
oi = &op->info;
- if (!op->enabled) {
- dispc_ovl_enable(ovl->id, 0);
+ if (!op->enabled)
return 0;
- }
replication = dss_use_replication(ovl->manager->device, oi->color_mode);
@@ -291,11 +288,21 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
- dispc_ovl_enable(ovl->id, 1);
-
return 0;
}
+static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+
+ DSSDBGF("%d", ovl->id);
+
+ /* note: write also when op->enabled = false, so that the ovl gets
+ * disabled */
+
+ dispc_ovl_enable(ovl->id, op->enabled);
+}
+
static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp;
@@ -356,6 +363,30 @@ static int dss_write_regs(void)
mgr_go[op->channel] = true;
}
+ for (i = 0; i < num_ovls; ++i) {
+ ovl = omap_dss_get_overlay(i);
+ op = get_ovl_priv(ovl);
+
+ if (!op->extra_info_dirty)
+ continue;
+
+ mp = get_mgr_priv(ovl->manager);
+
+ if (mp->manual_update && !mp->do_manual_update)
+ continue;
+
+ if (mp->busy) {
+ busy = true;
+ continue;
+ }
+
+ dss_ovl_write_regs_extra(ovl);
+
+ op->extra_info_dirty = false;
+ op->shadow_extra_info_dirty = true;
+ mgr_go[op->channel] = true;
+ }
+
/* Commit manager settings */
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
@@ -419,6 +450,7 @@ void dss_start_update(struct omap_overlay_manager *mgr)
list_for_each_entry(ovl, &mgr->overlays, list) {
op = get_ovl_priv(ovl);
op->shadow_dirty = false;
+ op->shadow_extra_info_dirty = false;
}
mp->shadow_dirty = false;
@@ -490,8 +522,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
mp = get_mgr_priv(ovl->manager);
- if (!mp->busy)
+ if (!mp->busy) {
op->shadow_dirty = false;
+ op->shadow_extra_info_dirty = false;
+ }
}
for (i = 0; i < num_mgrs; ++i) {
@@ -541,14 +575,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
ovl->info_dirty = true;
}
- if (!overlay_enabled(ovl)) {
- if (op->enabled) {
- op->enabled = false;
- op->dirty = true;
- }
- return;
- }
-
if (!ovl->info_dirty)
return;
@@ -557,8 +583,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
op->info = ovl->info;
op->channel = ovl->manager->id;
-
- op->enabled = true;
}
static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
@@ -593,9 +617,6 @@ static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
op = get_ovl_priv(ovl);
- if (!op->enabled)
- return;
-
dssdev = ovl->manager->device;
size = dispc_ovl_get_fifo_size(ovl->id);
@@ -828,6 +849,8 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr)
{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
int r;
if (!mgr)
@@ -842,7 +865,10 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
goto err;
}
- if (ovl->info.enabled) {
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (op->enabled) {
+ spin_unlock_irqrestore(&data_lock, flags);
DSSERR("overlay has to be disabled to change the manager\n");
r = -EINVAL;
goto err;
@@ -852,6 +878,8 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
list_add_tail(&ovl->list, &mgr->overlays);
ovl->manager_changed = true;
+ spin_unlock_irqrestore(&data_lock, flags);
+
/* XXX: When there is an overlay on a DSI manual update display, and
* the overlay is first disabled, then moved to tv, and enabled, we
* seem to get SYNC_LOST_DIGIT error.
@@ -875,6 +903,8 @@ err:
int dss_ovl_unset_manager(struct omap_overlay *ovl)
{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
int r;
mutex_lock(&apply_lock);
@@ -885,7 +915,10 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
goto err;
}
- if (ovl->info.enabled) {
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (op->enabled) {
+ spin_unlock_irqrestore(&data_lock, flags);
DSSERR("overlay has to be disabled to unset the manager\n");
r = -EINVAL;
goto err;
@@ -895,9 +928,83 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
list_del(&ovl->list);
ovl->manager_changed = true;
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+bool dss_ovl_is_enabled(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ bool e;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ e = op->enabled;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ return e;
+}
+
+int dss_ovl_enable(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (ovl->manager = NULL || ovl->manager->device = NULL) {
+ r = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ op->enabled = true;
+ op->extra_info_dirty = true;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+int dss_ovl_disable(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (ovl->manager = NULL || ovl->manager->device = NULL) {
+ r = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ op->enabled = false;
+ op->extra_info_dirty = true;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
mutex_unlock(&apply_lock);
return 0;
+
err:
mutex_unlock(&apply_lock);
return r;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 0ef0e08..b597485 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -180,6 +180,9 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+bool dss_ovl_is_enabled(struct omap_overlay *ovl);
+int dss_ovl_enable(struct omap_overlay *ovl);
+int dss_ovl_disable(struct omap_overlay *ovl);
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info);
void dss_ovl_get_info(struct omap_overlay *ovl,
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 4dc6b92..7d7cdf6 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -205,7 +205,7 @@ static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled);
+ return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
}
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
@@ -213,26 +213,19 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
{
int r;
bool enable;
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
r = strtobool(buf, &enable);
if (r)
return r;
- info.enabled = enable;
+ if (enable)
+ r = ovl->enable(ovl);
+ else
+ r = ovl->disable(ovl);
- r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;
- if (ovl->manager) {
- r = ovl->manager->apply(ovl->manager);
- if (r)
- return r;
- }
-
return size;
}
@@ -489,6 +482,9 @@ void dss_init_overlays(struct platform_device *pdev)
break;
}
+ ovl->is_enabled = &dss_ovl_is_enabled;
+ ovl->enable = &dss_ovl_enable;
+ ovl->disable = &dss_ovl_disable;
ovl->set_manager = &dss_ovl_set_manager;
ovl->unset_manager = &dss_ovl_unset_manager;
ovl->set_overlay_info = &dss_ovl_set_info;
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index df7bcce..562b5cc 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -111,28 +111,22 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
set_fb_fix(fbi);
}
- if (pi->enabled) {
- struct omap_overlay_info info;
+ if (!pi->enabled) {
+ r = ovl->disable(ovl);
+ if (r)
+ goto undo;
+ }
+ if (pi->enabled) {
r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
pi->out_width, pi->out_height);
if (r)
goto undo;
-
- ovl->get_overlay_info(ovl, &info);
-
- if (!info.enabled) {
- info.enabled = pi->enabled;
- r = ovl->set_overlay_info(ovl, &info);
- if (r)
- goto undo;
- }
} else {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
- info.enabled = pi->enabled;
info.pos_x = pi->pos_x;
info.pos_y = pi->pos_y;
info.out_width = pi->out_width;
@@ -146,6 +140,12 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
if (ovl->manager)
ovl->manager->apply(ovl->manager);
+ if (pi->enabled) {
+ r = ovl->enable(ovl);
+ if (r)
+ goto undo;
+ }
+
/* Release the locks in a specific order to keep lockdep happy */
if (old_rg->id > new_rg->id) {
omapfb_put_mem_region(old_rg);
@@ -196,7 +196,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
pi->pos_x = ovli->pos_x;
pi->pos_y = ovli->pos_y;
- pi->enabled = ovli->enabled;
+ pi->enabled = ovl->is_enabled(ovl);
pi->channel_out = 0; /* xxx */
pi->mirror = 0;
pi->mem_idx = get_mem_idx(ofbi);
@@ -238,7 +238,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
continue;
for (j = 0; j < ofbi2->num_overlays; j++) {
- if (ofbi2->overlays[j]->info.enabled) {
+ struct omap_overlay *ovl;
+ ovl = ofbi2->overlays[j];
+ if (ovl->is_enabled(ovl)) {
r = -EBUSY;
goto out;
}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 70aa47d..91b49b5 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2067,6 +2067,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
if (ofbi->num_overlays > 0) {
struct omap_overlay *ovl = ofbi->overlays[0];
+ ovl->manager->apply(ovl->manager);
+
r = omapfb_overlay_enable(ovl, 1);
if (r) {
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 1694d51..e8d8cc7 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -473,7 +473,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
continue;
for (j = 0; j < ofbi2->num_overlays; j++) {
- if (ofbi2->overlays[j]->info.enabled) {
+ struct omap_overlay *ovl;
+ ovl = ofbi2->overlays[j];
+ if (ovl->is_enabled(ovl)) {
r = -EBUSY;
goto out;
}
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index fdf0ede..b03fb13 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -181,13 +181,10 @@ static inline void omapfb_unlock(struct omapfb2_device *fbdev)
static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
int enable)
{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
- if (info.enabled = enable)
- return 0;
- info.enabled = enable;
- return ovl->set_overlay_info(ovl, &info);
+ if (enable)
+ return ovl->enable(ovl);
+ else
+ return ovl->disable(ovl);
}
static inline struct omapfb2_mem_region *
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6e3e7a7..9d01ff6 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -352,8 +352,6 @@ struct omap_dss_cpr_coefs {
};
struct omap_overlay_info {
- bool enabled;
-
u32 paddr;
u32 p_uv_addr; /* for NV12 format */
u16 screen_width;
@@ -391,6 +389,10 @@ struct omap_overlay {
/* if true, info has been changed, but not applied() yet */
bool info_dirty;
+ int (*enable)(struct omap_overlay *ovl);
+ int (*disable)(struct omap_overlay *ovl);
+ bool (*is_enabled)(struct omap_overlay *ovl);
+
int (*set_manager)(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr);
int (*unset_manager)(struct omap_overlay *ovl);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 46/65] OMAPDSS: APPLY: rewrite register writing
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
The functions writing to the DISPC registers in apply.c are more complex
than needed. This patch cleans things up.
Two helper functions are added: need_isr(), which returns if an isr for
VSYNC is needed, and need_go(), which tells if there has been a write to
the shadow registers and we need to set the GO bit.
The functions that call the actual dispc write functions will set the
dirty and shadow_dirty flags themselves, instead of that being done on
the caller side. The writing functions also check if the dirty flag is
even set, and return immediately if not.
This allows us to clean up dss_write_regs().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 290 +++++++++++++++++---------------------
1 files changed, 130 insertions(+), 160 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 2c60e77..c4106b6 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -88,9 +88,6 @@ struct mgr_priv_data {
struct omap_overlay_manager_info info;
- bool manual_update;
- bool do_manual_update;
-
/* If true, GO bit is up and shadow registers cannot be written.
* Never true for manual update displays */
bool busy;
@@ -111,6 +108,8 @@ static spinlock_t data_lock;
/* lock for blocking functions */
static DEFINE_MUTEX(apply_lock);
+static void dss_register_vsync_isr(void);
+
static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
{
return &dss_data.ovl_priv_data_array[ovl->id];
@@ -136,6 +135,70 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
}
+static bool need_isr(void)
+{
+ const int num_mgrs = dss_feat_get_num_mgrs();
+ int i;
+
+ for (i = 0; i < num_mgrs; ++i) {
+ struct omap_overlay_manager *mgr;
+ struct mgr_priv_data *mp;
+ struct omap_overlay *ovl;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ if (!mp->enabled)
+ continue;
+
+ if (mgr_manual_update(mgr))
+ continue;
+
+ /* to catch GO bit going down */
+ if (mp->busy)
+ return true;
+
+ /* to write new values to registers */
+ if (mp->dirty)
+ return true;
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ struct ovl_priv_data *op;
+
+ op = get_ovl_priv(ovl);
+
+ if (!op->enabled)
+ continue;
+
+ /* to write new values to registers */
+ if (op->dirty || op->extra_info_dirty)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool need_go(struct omap_overlay_manager *mgr)
+{
+ struct omap_overlay *ovl;
+ struct mgr_priv_data *mp;
+ struct ovl_priv_data *op;
+
+ mp = get_mgr_priv(mgr);
+
+ if (mp->shadow_dirty)
+ return true;
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ op = get_ovl_priv(ovl);
+ if (op->shadow_dirty || op->shadow_extra_info_dirty)
+ return true;
+ }
+
+ return false;
+}
+
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
@@ -257,20 +320,19 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
return r;
}
-static int dss_ovl_write_regs(struct omap_overlay *ovl)
+static void dss_ovl_write_regs(struct omap_overlay *ovl)
{
- struct ovl_priv_data *op;
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
struct omap_overlay_info *oi;
bool ilace, replication;
int r;
DSSDBGF("%d", ovl->id);
- op = get_ovl_priv(ovl);
- oi = &op->info;
+ if (!op->enabled || !op->dirty)
+ return;
- if (!op->enabled)
- return 0;
+ oi = &op->info;
replication = dss_use_replication(ovl->manager->device, oi->color_mode);
@@ -280,15 +342,22 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
if (r) {
- /* this shouldn't happen */
+ /*
+ * We can't do much here, as this function can be called from
+ * vsync interrupt.
+ */
DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
- dispc_ovl_enable(ovl->id, 0);
- return r;
+
+ /* This will leave fifo configurations in a nonoptimal state */
+ op->enabled = false;
+ dispc_ovl_enable(ovl->id, false);
+ return;
}
dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
- return 0;
+ op->dirty = false;
+ op->shadow_dirty = true;
}
static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
@@ -297,141 +366,70 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
DSSDBGF("%d", ovl->id);
+ if (!op->extra_info_dirty)
+ return;
+
/* note: write also when op->enabled = false, so that the ovl gets
* disabled */
dispc_ovl_enable(ovl->id, op->enabled);
+
+ op->extra_info_dirty = false;
+ op->shadow_extra_info_dirty = true;
}
static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
{
- struct mgr_priv_data *mp;
- struct omap_overlay_manager_info *mi;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ struct omap_overlay *ovl;
DSSDBGF("%d", mgr->id);
- mp = get_mgr_priv(mgr);
- mi = &mp->info;
-
- dispc_mgr_setup(mgr->id, mi);
-}
-
-/* dss_write_regs() tries to write values from cache to shadow registers.
- * It writes only to those managers/overlays that are not busy.
- * returns 0 if everything could be written to shadow registers.
- * returns 1 if not everything could be written to shadow registers. */
-static int dss_write_regs(void)
-{
- struct omap_overlay *ovl;
- struct omap_overlay_manager *mgr;
- struct ovl_priv_data *op;
- struct mgr_priv_data *mp;
- const int num_ovls = dss_feat_get_num_ovls();
- const int num_mgrs = dss_feat_get_num_mgrs();
- int i;
- int r;
- bool mgr_go[MAX_DSS_MANAGERS] = { false };
- bool busy;
+ if (!mp->enabled)
+ return;
- r = 0;
- busy = false;
+ WARN_ON(mp->busy);
/* Commit overlay settings */
- for (i = 0; i < num_ovls; ++i) {
- ovl = omap_dss_get_overlay(i);
- op = get_ovl_priv(ovl);
-
- if (!op->dirty)
- continue;
-
- mp = get_mgr_priv(ovl->manager);
-
- if (mp->manual_update && !mp->do_manual_update)
- continue;
-
- if (mp->busy) {
- busy = true;
- continue;
- }
-
- r = dss_ovl_write_regs(ovl);
- if (r)
- DSSERR("dss_ovl_write_regs %d failed\n", i);
-
- op->dirty = false;
- op->shadow_dirty = true;
- mgr_go[op->channel] = true;
- }
-
- for (i = 0; i < num_ovls; ++i) {
- ovl = omap_dss_get_overlay(i);
- op = get_ovl_priv(ovl);
-
- if (!op->extra_info_dirty)
- continue;
-
- mp = get_mgr_priv(ovl->manager);
-
- if (mp->manual_update && !mp->do_manual_update)
- continue;
-
- if (mp->busy) {
- busy = true;
- continue;
- }
-
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ dss_ovl_write_regs(ovl);
dss_ovl_write_regs_extra(ovl);
-
- op->extra_info_dirty = false;
- op->shadow_extra_info_dirty = true;
- mgr_go[op->channel] = true;
}
- /* Commit manager settings */
- for (i = 0; i < num_mgrs; ++i) {
- mgr = omap_dss_get_overlay_manager(i);
- mp = get_mgr_priv(mgr);
-
- if (!mp->dirty)
- continue;
-
- if (mp->manual_update && !mp->do_manual_update)
- continue;
-
- if (mp->busy) {
- busy = true;
- continue;
- }
+ if (mp->dirty) {
+ dispc_mgr_setup(mgr->id, &mp->info);
- dss_mgr_write_regs(mgr);
mp->dirty = false;
mp->shadow_dirty = true;
- mgr_go[i] = true;
}
+}
+
+static void dss_write_regs(void)
+{
+ const int num_mgrs = omap_dss_get_num_overlay_managers();
+ int i;
- /* set GO */
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 (!mgr_go[i])
+ if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
continue;
- /* We don't need GO with manual update display. LCD iface will
- * always be turned off after frame, and new settings will be
- * taken in to use at next update */
- if (!mp->manual_update) {
+ dss_mgr_write_regs(mgr);
+
+ if (need_go(mgr)) {
mp->busy = true;
- dispc_mgr_go(i);
- }
- }
- if (busy)
- r = 1;
- else
- r = 0;
+ if (!dss_data.irq_enabled && need_isr())
+ dss_register_vsync_isr();
- return r;
+ dispc_mgr_go(mgr->id);
+ }
+ }
}
void dss_start_update(struct omap_overlay_manager *mgr)
@@ -443,9 +441,7 @@ void dss_start_update(struct omap_overlay_manager *mgr)
spin_lock_irqsave(&data_lock, flags);
- mp->do_manual_update = true;
- dss_write_regs();
- mp->do_manual_update = false;
+ dss_mgr_write_regs(mgr);
list_for_each_entry(ovl, &mgr->overlays, list) {
op = get_ovl_priv(ovl);
@@ -502,7 +498,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
struct ovl_priv_data *op;
const int num_ovls = dss_feat_get_num_ovls();
const int num_mgrs = dss_feat_get_num_mgrs();
- int i, r;
+ int i;
spin_lock(&data_lock);
@@ -536,31 +532,11 @@ static void dss_apply_irq_handler(void *data, u32 mask)
mp->shadow_dirty = false;
}
- r = dss_write_regs();
- if (r = 1)
- goto end;
-
- /* re-read busy flags */
- for (i = 0; i < num_mgrs; i++) {
- mgr = omap_dss_get_overlay_manager(i);
- mp = get_mgr_priv(mgr);
-
- mp->busy = dispc_mgr_go_busy(i);
- }
-
- /* keep running as long as there are busy managers, so that
- * we can collect overlay-applied information */
- for (i = 0; i < num_mgrs; ++i) {
- mgr = omap_dss_get_overlay_manager(i);
- mp = get_mgr_priv(mgr);
-
- if (mp->busy)
- goto end;
- }
+ dss_write_regs();
- dss_unregister_vsync_isr();
+ if (!need_isr())
+ dss_unregister_vsync_isr();
-end:
spin_unlock(&data_lock);
}
@@ -599,14 +575,9 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
if (!mgr->info_dirty)
return;
- if (!mgr->device)
- return;
-
mgr->info_dirty = false;
mp->dirty = true;
mp->info = mgr->info;
-
- mp->manual_update = mgr_manual_update(mgr);
}
static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
@@ -650,7 +621,6 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
int r;
unsigned long flags;
struct omap_overlay *ovl;
- struct mgr_priv_data *mp = get_mgr_priv(mgr);
DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
@@ -671,13 +641,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
list_for_each_entry(ovl, &mgr->overlays, list)
omap_dss_mgr_apply_ovl_fifos(ovl);
- r = 0;
- if (mp->enabled && !mgr_manual_update(mgr)) {
- if (!dss_data.irq_enabled)
- dss_register_vsync_isr();
-
- dss_write_regs();
- }
+ dss_write_regs();
spin_unlock_irqrestore(&data_lock, flags);
@@ -693,15 +657,17 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
mutex_lock(&apply_lock);
- if (!mgr_manual_update(mgr))
- dispc_mgr_enable(mgr->id, true);
-
spin_lock_irqsave(&data_lock, flags);
mp->enabled = true;
+ dss_write_regs();
+
spin_unlock_irqrestore(&data_lock, flags);
+ if (!mgr_manual_update(mgr))
+ dispc_mgr_enable(mgr->id, true);
+
mutex_unlock(&apply_lock);
}
@@ -971,6 +937,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
op->enabled = true;
op->extra_info_dirty = true;
+ dss_write_regs();
+
spin_unlock_irqrestore(&data_lock, flags);
mutex_unlock(&apply_lock);
@@ -999,6 +967,8 @@ int dss_ovl_disable(struct omap_overlay *ovl)
op->enabled = false;
op->extra_info_dirty = true;
+ dss_write_regs();
+
spin_unlock_irqrestore(&data_lock, flags);
mutex_unlock(&apply_lock);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 47/65] OMAPDSS: DISPC: add dispc_mgr_get_framedone_irq
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add dispc_mgr_get_framedone_irq() which returns the irq number for
FRAMEDONE for the given channel.
Note that the function returns always 0 for DIGIT channel, even if OMAP4
does have FRAMEDONE_TV interrupt. The reason for this is that this
function is currently used only to track manual updates, and thus
FRAMEDONE_TV is not needed.
If there's need in the future to also get the FRAMEDONE_TV this needs
revisiting. However, as FRAMEDONE_TV doesn't exist on OMAP2/3, the use
of this function for that purpose needs some extra code to handle the
OMAP2/3 case.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 14 ++++++++++++++
drivers/video/omap2/dss/dss.h | 1 +
2 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 27a2cff..8ce0c81 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -452,6 +452,20 @@ u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
}
}
+u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
+{
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ return DISPC_IRQ_FRAMEDONE;
+ case OMAP_DSS_CHANNEL_LCD2:
+ return DISPC_IRQ_FRAMEDONE2;
+ case OMAP_DSS_CHANNEL_DIGIT:
+ return 0;
+ default:
+ BUG();
+ }
+}
+
bool dispc_mgr_go_busy(enum omap_channel channel)
{
int bit;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b597485..c6caf2f 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -430,6 +430,7 @@ void dispc_ovl_set_channel_out(enum omap_plane plane,
void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
+u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
bool dispc_mgr_go_busy(enum omap_channel channel);
void dispc_mgr_go(enum omap_channel channel);
bool dispc_mgr_is_enabled(enum omap_channel channel);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 48/65] OMAPDSS: APPLY: add updating flag
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add "updating" flag to mgr_priv_data, which is used to track whether the
manager is currently actively working, i.e. updating the screen.
For auto-update displays updating is always true when the display is
enabled, but for manual update displays the flag is true only during
frame transfers.
The flag is used to manage registers properly, for example when updating
is false and a register for a manager is written, there's no need to set
shadow_dirty flag nor set the GO bit, as the settings will be taken into
use by the HW automatically when the output is enabled.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 79 +++++++++++++++++++++++++--------------
1 files changed, 51 insertions(+), 28 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index c4106b6..b2c0462 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -92,6 +92,9 @@ struct mgr_priv_data {
* Never true for manual update displays */
bool busy;
+ /* If true, dispc output is enabled */
+ bool updating;
+
/* If true, a display is enabled using this manager */
bool enabled;
};
@@ -151,28 +154,31 @@ static bool need_isr(void)
if (!mp->enabled)
continue;
- if (mgr_manual_update(mgr))
- continue;
-
- /* to catch GO bit going down */
- if (mp->busy)
- return true;
+ if (mgr_manual_update(mgr)) {
+ /* to catch FRAMEDONE */
+ if (mp->updating)
+ return true;
+ } else {
+ /* to catch GO bit going down */
+ if (mp->busy)
+ return true;
- /* to write new values to registers */
- if (mp->dirty)
- return true;
+ /* to write new values to registers */
+ if (mp->dirty)
+ return true;
- list_for_each_entry(ovl, &mgr->overlays, list) {
- struct ovl_priv_data *op;
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ struct ovl_priv_data *op;
- op = get_ovl_priv(ovl);
+ op = get_ovl_priv(ovl);
- if (!op->enabled)
- continue;
+ if (!op->enabled)
+ continue;
- /* to write new values to registers */
- if (op->dirty || op->extra_info_dirty)
- return true;
+ /* to write new values to registers */
+ if (op->dirty || op->extra_info_dirty)
+ return true;
+ }
}
}
@@ -325,6 +331,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
struct ovl_priv_data *op = get_ovl_priv(ovl);
struct omap_overlay_info *oi;
bool ilace, replication;
+ struct mgr_priv_data *mp;
int r;
DSSDBGF("%d", ovl->id);
@@ -356,13 +363,17 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
+ mp = get_mgr_priv(ovl->manager);
+
op->dirty = false;
- op->shadow_dirty = true;
+ if (mp->updating)
+ op->shadow_dirty = true;
}
static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
+ struct mgr_priv_data *mp;
DSSDBGF("%d", ovl->id);
@@ -374,8 +385,11 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
dispc_ovl_enable(ovl->id, op->enabled);
+ mp = get_mgr_priv(ovl->manager);
+
op->extra_info_dirty = false;
- op->shadow_extra_info_dirty = true;
+ if (mp->updating)
+ op->shadow_extra_info_dirty = true;
}
static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
@@ -400,7 +414,8 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
dispc_mgr_setup(mgr->id, &mp->info);
mp->dirty = false;
- mp->shadow_dirty = true;
+ if (mp->updating)
+ mp->shadow_dirty = true;
}
}
@@ -435,21 +450,18 @@ static void dss_write_regs(void)
void dss_start_update(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
- struct ovl_priv_data *op;
- struct omap_overlay *ovl;
unsigned long flags;
spin_lock_irqsave(&data_lock, flags);
+ WARN_ON(mp->updating);
+
dss_mgr_write_regs(mgr);
- list_for_each_entry(ovl, &mgr->overlays, list) {
- op = get_ovl_priv(ovl);
- op->shadow_dirty = false;
- op->shadow_extra_info_dirty = false;
- }
+ mp->updating = true;
- mp->shadow_dirty = false;
+ if (!dss_data.irq_enabled && need_isr())
+ dss_register_vsync_isr();
dispc_mgr_enable(mgr->id, true);
@@ -468,6 +480,9 @@ static void dss_register_vsync_isr(void)
for (i = 0; i < num_mgrs; ++i)
mask |= dispc_mgr_get_vsync_irq(i);
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_framedone_irq(i);
+
r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
@@ -484,6 +499,9 @@ static void dss_unregister_vsync_isr(void)
for (i = 0; i < num_mgrs; ++i)
mask |= dispc_mgr_get_vsync_irq(i);
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_framedone_irq(i);
+
r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
@@ -507,6 +525,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
mp = get_mgr_priv(mgr);
mp->busy = dispc_mgr_go_busy(i);
+ mp->updating = dispc_mgr_is_enabled(i);
}
for (i = 0; i < num_ovls; ++i) {
@@ -663,6 +682,9 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
dss_write_regs();
+ if (!mgr_manual_update(mgr))
+ mp->updating = true;
+
spin_unlock_irqrestore(&data_lock, flags);
if (!mgr_manual_update(mgr))
@@ -683,6 +705,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
spin_lock_irqsave(&data_lock, flags);
+ mp->updating = false;
mp->enabled = false;
spin_unlock_irqrestore(&data_lock, flags);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 49/65] OMAPDSS: APPLY: clean up isr_handler
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add a helper function mgr_clear_shadow_dirty(), which clears the
shadow_dirty flags for the given manager and for the overlays on that
manager.
This lets us simplify the code in the dss_apply_irq_handler().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 52 +++++++++++++++++++++------------------
1 files changed, 28 insertions(+), 24 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index b2c0462..601dbc7 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -508,47 +508,51 @@ static void dss_unregister_vsync_isr(void)
dss_data.irq_enabled = false;
}
-static void dss_apply_irq_handler(void *data, u32 mask)
+static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
{
struct omap_overlay *ovl;
- struct omap_overlay_manager *mgr;
struct mgr_priv_data *mp;
struct ovl_priv_data *op;
- const int num_ovls = dss_feat_get_num_ovls();
+
+ mp = get_mgr_priv(mgr);
+ mp->shadow_dirty = false;
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ op = get_ovl_priv(ovl);
+ op->shadow_dirty = false;
+ op->shadow_extra_info_dirty = false;
+ }
+}
+
+static void dss_apply_irq_handler(void *data, u32 mask)
+{
const int num_mgrs = dss_feat_get_num_mgrs();
int i;
spin_lock(&data_lock);
+ /* clear busy, updating flags, shadow_dirty flags */
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);
- mp->busy = dispc_mgr_go_busy(i);
- mp->updating = dispc_mgr_is_enabled(i);
- }
-
- for (i = 0; i < num_ovls; ++i) {
- ovl = omap_dss_get_overlay(i);
- op = get_ovl_priv(ovl);
-
- if (!op->enabled)
+ if (!mp->enabled)
continue;
- mp = get_mgr_priv(ovl->manager);
-
- if (!mp->busy) {
- op->shadow_dirty = false;
- op->shadow_extra_info_dirty = false;
- }
- }
+ mp->updating = dispc_mgr_is_enabled(i);
- for (i = 0; i < num_mgrs; ++i) {
- mgr = omap_dss_get_overlay_manager(i);
- mp = get_mgr_priv(mgr);
+ if (!mgr_manual_update(mgr)) {
+ mp->busy = dispc_mgr_go_busy(i);
- if (!mp->busy)
- mp->shadow_dirty = false;
+ if (!mp->busy)
+ mgr_clear_shadow_dirty(mgr);
+ } else {
+ if (!mp->updating)
+ mgr_clear_shadow_dirty(mgr);
+ }
}
dss_write_regs();
--
1.7.4.1
^ permalink raw reply related
* [PATCH 50/65] OMAPDSS: APPLY: move mgr->info to apply.c
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
struct omap_overlay_manager contains info and info_dirty fields, both of
which should be internal to apply.c.
This patch moves those fields into mgr_priv data, and names them
user_info and user_info_dirty.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 20 +++++++++++++-------
drivers/video/omap2/dss/manager.c | 35 +++++++++++++++++++++++++++++------
include/video/omapdss.h | 3 ---
3 files changed, 42 insertions(+), 16 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 601dbc7..de1ac24 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -78,6 +78,10 @@ struct ovl_priv_data {
};
struct mgr_priv_data {
+
+ bool user_info_dirty;
+ struct omap_overlay_manager_info user_info;
+
/* If true, cache changed, but not written to shadow registers. Set
* in apply(), cleared when registers written. */
bool dirty;
@@ -592,15 +596,15 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
if (mgr->device_changed) {
mgr->device_changed = false;
- mgr->info_dirty = true;
+ mp->user_info_dirty = true;
}
- if (!mgr->info_dirty)
+ if (!mp->user_info_dirty)
return;
- mgr->info_dirty = false;
+ mp->user_info_dirty = false;
mp->dirty = true;
- mp->info = mgr->info;
+ mp->info = mp->user_info;
}
static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
@@ -720,12 +724,13 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
int dss_mgr_set_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info)
{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
spin_lock_irqsave(&data_lock, flags);
- mgr->info = *info;
- mgr->info_dirty = true;
+ mp->user_info = *info;
+ mp->user_info_dirty = true;
spin_unlock_irqrestore(&data_lock, flags);
@@ -735,11 +740,12 @@ int dss_mgr_set_info(struct omap_overlay_manager *mgr,
void dss_mgr_get_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info)
{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
spin_lock_irqsave(&data_lock, flags);
- *info = mgr->info;
+ *info = mp->user_info;
spin_unlock_irqrestore(&data_lock, flags);
}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index d7fd494..8c967ef 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -104,7 +104,11 @@ put_device:
static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.default_color);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
}
static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
@@ -142,8 +146,11 @@ static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
char *buf)
{
enum omap_dss_trans_key_type key_type;
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
- key_type = mgr->info.trans_key_type;
+ key_type = info.trans_key_type;
BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
@@ -183,7 +190,11 @@ static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.trans_key);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
}
static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
@@ -215,7 +226,11 @@ static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_enabled);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
}
static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
@@ -247,10 +262,14 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
static ssize_t manager_alpha_blending_enabled_show(
struct omap_overlay_manager *mgr, char *buf)
{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
return snprintf(buf, PAGE_SIZE, "%d\n",
- mgr->info.partial_alpha_enabled);
+ info.partial_alpha_enabled);
}
static ssize_t manager_alpha_blending_enabled_store(
@@ -285,7 +304,11 @@ static ssize_t manager_alpha_blending_enabled_store(
static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.cpr_enable);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
}
static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 9d01ff6..0d5333f 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -430,11 +430,8 @@ struct omap_overlay_manager {
/* dynamic fields */
struct omap_dss_device *device;
- struct omap_overlay_manager_info info;
bool device_changed;
- /* if true, info has been changed but not applied() yet */
- bool info_dirty;
int (*set_device)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 51/65] OMAPDSS: APPLY: move ovl->info to apply.c
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
struct omap_overlayr contains info and info_dirty fields, both of which
should be internal to apply.c.
This patch moves those fields into ovl_priv data, and names them
user_info and user_info_dirty.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 51 ++++++++++++++++++++++++----
drivers/video/omap2/dss/overlay.c | 53 +++++++++++++++++++----------
drivers/video/omap2/omapfb/omapfb-ioctl.c | 12 +++---
drivers/video/omap2/omapfb/omapfb-main.c | 12 ++++--
include/video/omapdss.h | 3 --
5 files changed, 93 insertions(+), 38 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index de1ac24..eac0041 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -55,6 +55,10 @@
*/
struct ovl_priv_data {
+
+ bool user_info_dirty;
+ struct omap_overlay_info user_info;
+
/* If true, cache changed, but not written to shadow registers. Set
* in apply(), cleared when registers written. */
bool dirty;
@@ -129,7 +133,38 @@ 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();
+ int i;
+
spin_lock_init(&data_lock);
+
+ for (i = 0; i < num_ovls; ++i) {
+ struct ovl_priv_data *op;
+
+ op = &dss_data.ovl_priv_data_array[i];
+
+ op->info.global_alpha = 255;
+
+ switch (i) {
+ case 0:
+ op->info.zorder = 0;
+ break;
+ case 1:
+ op->info.zorder + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
+ break;
+ case 2:
+ op->info.zorder + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
+ break;
+ case 3:
+ op->info.zorder + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
+ break;
+ }
+
+ op->user_info = op->info;
+ }
}
static bool ovl_manual_update(struct omap_overlay *ovl)
@@ -575,15 +610,15 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
if (ovl->manager_changed) {
ovl->manager_changed = false;
- ovl->info_dirty = true;
+ op->user_info_dirty = true;
}
- if (!ovl->info_dirty)
+ if (!op->user_info_dirty)
return;
- ovl->info_dirty = false;
+ op->user_info_dirty = false;
op->dirty = true;
- op->info = ovl->info;
+ op->info = op->user_info;
op->channel = ovl->manager->id;
}
@@ -821,12 +856,13 @@ err:
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
spin_lock_irqsave(&data_lock, flags);
- ovl->info = *info;
- ovl->info_dirty = true;
+ op->user_info = *info;
+ op->user_info_dirty = true;
spin_unlock_irqrestore(&data_lock, flags);
@@ -836,11 +872,12 @@ int dss_ovl_set_info(struct omap_overlay *ovl,
void dss_ovl_get_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
spin_lock_irqsave(&data_lock, flags);
- *info = ovl->info;
+ *info = op->user_info;
spin_unlock_irqrestore(&data_lock, flags);
}
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 7d7cdf6..8d036e6 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -124,19 +124,31 @@ err:
static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- ovl->info.width, ovl->info.height);
+ info.width, info.height);
}
static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.screen_width);
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
}
static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- ovl->info.pos_x, ovl->info.pos_y);
+ info.pos_x, info.pos_y);
}
static ssize_t overlay_position_store(struct omap_overlay *ovl,
@@ -170,8 +182,12 @@ static ssize_t overlay_position_store(struct omap_overlay *ovl,
static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- ovl->info.out_width, ovl->info.out_height);
+ info.out_width, info.out_height);
}
static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
@@ -231,8 +247,12 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d\n",
- ovl->info.global_alpha);
+ info.global_alpha);
}
static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
@@ -269,8 +289,12 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d\n",
- ovl->info.pre_mult_alpha);
+ info.pre_mult_alpha);
}
static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
@@ -306,7 +330,11 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder);
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
}
static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
@@ -456,29 +484,18 @@ void dss_init_overlays(struct platform_device *pdev)
case 0:
ovl->name = "gfx";
ovl->id = OMAP_DSS_GFX;
- ovl->info.global_alpha = 255;
- ovl->info.zorder = 0;
break;
case 1:
ovl->name = "vid1";
ovl->id = OMAP_DSS_VIDEO1;
- ovl->info.global_alpha = 255;
- ovl->info.zorder - dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
break;
case 2:
ovl->name = "vid2";
ovl->id = OMAP_DSS_VIDEO2;
- ovl->info.global_alpha = 255;
- ovl->info.zorder - dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
break;
case 3:
ovl->name = "vid3";
ovl->id = OMAP_DSS_VIDEO3;
- ovl->info.global_alpha = 255;
- ovl->info.zorder - dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
break;
}
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 562b5cc..16ba619 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -189,19 +189,19 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
memset(pi, 0, sizeof(*pi));
} else {
struct omap_overlay *ovl;
- struct omap_overlay_info *ovli;
+ struct omap_overlay_info ovli;
ovl = ofbi->overlays[0];
- ovli = &ovl->info;
+ ovl->get_overlay_info(ovl, &ovli);
- pi->pos_x = ovli->pos_x;
- pi->pos_y = ovli->pos_y;
+ pi->pos_x = ovli.pos_x;
+ pi->pos_y = ovli.pos_y;
pi->enabled = ovl->is_enabled(ovl);
pi->channel_out = 0; /* xxx */
pi->mirror = 0;
pi->mem_idx = get_mem_idx(ofbi);
- pi->out_width = ovli->out_width;
- pi->out_height = ovli->out_height;
+ pi->out_width = ovli.out_width;
+ pi->out_height = ovli.out_height;
}
return 0;
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 91b49b5..46024ab 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -970,16 +970,20 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
outh = var->yres;
}
} else {
- outw = ovl->info.out_width;
- outh = ovl->info.out_height;
+ struct omap_overlay_info info;
+ ovl->get_overlay_info(ovl, &info);
+ outw = info.out_width;
+ outh = info.out_height;
}
if (init) {
posx = 0;
posy = 0;
} else {
- posx = ovl->info.pos_x;
- posy = ovl->info.pos_y;
+ struct omap_overlay_info info;
+ ovl->get_overlay_info(ovl, &info);
+ posx = info.pos_x;
+ posy = info.pos_y;
}
r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 0d5333f..2e2c53f 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -383,11 +383,8 @@ struct omap_overlay {
/* dynamic fields */
struct omap_overlay_manager *manager;
- struct omap_overlay_info info;
bool manager_changed;
- /* if true, info has been changed, but not applied() yet */
- bool info_dirty;
int (*enable)(struct omap_overlay *ovl);
int (*disable)(struct omap_overlay *ovl);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 52/65] OMAPDSS: APPLY: move channel-field to extra_info set
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Setting overlay's output channel is currently handled at the same time
as other overlay attributes. This is not right, as the normal attributes
should only affect one overlay and manager, but changing the channel
affects two managers.
This patch moves the channel field into the "extra_info" set, handled
together with enabled-status.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 21 +++++++--------------
include/video/omapdss.h | 2 --
2 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index eac0041..3e345d7 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -69,8 +69,6 @@ struct ovl_priv_data {
struct omap_overlay_info info;
- enum omap_channel channel;
-
u32 fifo_low;
u32 fifo_high;
@@ -78,7 +76,7 @@ struct ovl_priv_data {
bool shadow_extra_info_dirty;
bool enabled;
-
+ enum omap_channel channel;
};
struct mgr_priv_data {
@@ -384,8 +382,6 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
- dispc_ovl_set_channel_out(ovl->id, op->channel);
-
r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
if (r) {
/*
@@ -423,6 +419,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
* disabled */
dispc_ovl_enable(ovl->id, op->enabled);
+ dispc_ovl_set_channel_out(ovl->id, op->channel);
mp = get_mgr_priv(ovl->manager);
@@ -608,19 +605,12 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
op = get_ovl_priv(ovl);
- if (ovl->manager_changed) {
- ovl->manager_changed = false;
- op->user_info_dirty = true;
- }
-
if (!op->user_info_dirty)
return;
op->user_info_dirty = false;
op->dirty = true;
op->info = op->user_info;
-
- op->channel = ovl->manager->id;
}
static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
@@ -910,9 +900,11 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
goto err;
}
+ op->channel = mgr->id;
+ op->extra_info_dirty = true;
+
ovl->manager = mgr;
list_add_tail(&ovl->list, &mgr->overlays);
- ovl->manager_changed = true;
spin_unlock_irqrestore(&data_lock, flags);
@@ -960,9 +952,10 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
goto err;
}
+ op->channel = -1;
+
ovl->manager = NULL;
list_del(&ovl->list);
- ovl->manager_changed = true;
spin_unlock_irqrestore(&data_lock, flags);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2e2c53f..e629b0d 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -384,8 +384,6 @@ struct omap_overlay {
/* dynamic fields */
struct omap_overlay_manager *manager;
- bool manager_changed;
-
int (*enable)(struct omap_overlay *ovl);
int (*disable)(struct omap_overlay *ovl);
bool (*is_enabled)(struct omap_overlay *ovl);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 53/65] OMAPDSS: APPLY: move fifo thresholds to extra_info set
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Setting overlay's fifo thresholds is currently handled at the same time
as other overlay attributes. This is not right, as the normal attributes
should only affect one overlay and manager, but changing the fifo
thresholds are needed in cases like fifo-merge, where multiple managers
are affected.
This patch moves the channel field into the "extra_info" set, handled
together with channel and enabled-status.
This also lets us to calculate the fifos only when needed, specifically,
when an overlay or a manager is enabled.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 95 +++++++++++++++++++++++---------------
1 files changed, 57 insertions(+), 38 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 3e345d7..0e93ae5 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -69,14 +69,12 @@ struct ovl_priv_data {
struct omap_overlay_info info;
- u32 fifo_low;
- u32 fifo_high;
-
bool extra_info_dirty;
bool shadow_extra_info_dirty;
bool enabled;
enum omap_channel channel;
+ u32 fifo_low, fifo_high;
};
struct mgr_priv_data {
@@ -396,8 +394,6 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
return;
}
- dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
-
mp = get_mgr_priv(ovl->manager);
op->dirty = false;
@@ -420,6 +416,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
dispc_ovl_enable(ovl->id, op->enabled);
dispc_ovl_set_channel_out(ovl->id, op->channel);
+ dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
mp = get_mgr_priv(ovl->manager);
@@ -632,13 +629,42 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
mp->info = mp->user_info;
}
-static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
+int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
{
- struct ovl_priv_data *op;
+ int r;
+ unsigned long flags;
+ struct omap_overlay *ovl;
+
+ DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
+
+ r = dispc_runtime_get();
+ if (r)
+ return r;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ /* Configure overlays */
+ list_for_each_entry(ovl, &mgr->overlays, list)
+ omap_dss_mgr_apply_ovl(ovl);
+
+ /* Configure manager */
+ omap_dss_mgr_apply_mgr(mgr);
+
+ dss_write_regs();
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ dispc_runtime_put();
+
+ return r;
+}
+
+static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
struct omap_dss_device *dssdev;
u32 size, burst_size;
-
- op = get_ovl_priv(ovl);
+ u32 fifo_low, fifo_high;
dssdev = ovl->manager->device;
@@ -653,53 +679,42 @@ static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
case OMAP_DISPLAY_TYPE_VENC:
case OMAP_DISPLAY_TYPE_HDMI:
default_get_overlay_fifo_thresholds(ovl->id, size,
- burst_size, &op->fifo_low,
- &op->fifo_high);
+ 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, &op->fifo_low,
- &op->fifo_high);
+ burst_size, &fifo_low, &fifo_high);
break;
#endif
default:
BUG();
}
+
+ op->fifo_low = fifo_low;
+ op->fifo_high = fifo_high;
+ op->extra_info_dirty = true;
}
-int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
{
- int r;
- unsigned long flags;
struct omap_overlay *ovl;
+ struct ovl_priv_data *op;
+ struct mgr_priv_data *mp;
- DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
-
- r = dispc_runtime_get();
- if (r)
- return r;
-
- spin_lock_irqsave(&data_lock, flags);
-
- /* Configure overlays */
- list_for_each_entry(ovl, &mgr->overlays, list)
- omap_dss_mgr_apply_ovl(ovl);
-
- /* Configure manager */
- omap_dss_mgr_apply_mgr(mgr);
-
- /* Configure overlay fifos */
- list_for_each_entry(ovl, &mgr->overlays, list)
- omap_dss_mgr_apply_ovl_fifos(ovl);
+ mp = get_mgr_priv(mgr);
- dss_write_regs();
+ if (!mp->enabled)
+ return;
- spin_unlock_irqrestore(&data_lock, flags);
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ op = get_ovl_priv(ovl);
- dispc_runtime_put();
+ if (!op->enabled)
+ continue;
- return r;
+ dss_ovl_setup_fifo(ovl);
+ }
}
void dss_mgr_enable(struct omap_overlay_manager *mgr)
@@ -713,6 +728,8 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
mp->enabled = true;
+ dss_mgr_setup_fifos(mgr);
+
dss_write_regs();
if (!mgr_manual_update(mgr))
@@ -1000,6 +1017,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
op->enabled = true;
op->extra_info_dirty = true;
+ dss_ovl_setup_fifo(ovl);
+
dss_write_regs();
spin_unlock_irqrestore(&data_lock, flags);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 54/65] OMAPDSS: APPLY: rename dirty & shadow_dirty
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Rename ovl_priv_data's and mgr_priv_data's dirty and shadow_dirty fields
to info_dirty and shadow_info_dirty to better reflect what they mean.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 62 +++++++++++++++++----------------------
1 files changed, 27 insertions(+), 35 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 0e93ae5..fdd53b6 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -31,8 +31,10 @@
* We have 4 levels of cache for the dispc settings. First two are in SW and
* the latter two in HW.
*
+ * set_info()
+ * v
* +--------------------+
- * |overlay/manager_info|
+ * | user_info |
* +--------------------+
* v
* apply()
@@ -59,16 +61,11 @@ struct ovl_priv_data {
bool user_info_dirty;
struct omap_overlay_info user_info;
- /* If true, cache changed, but not written to shadow registers. Set
- * in apply(), cleared when registers written. */
- bool dirty;
- /* If true, shadow registers contain changed values not yet in real
- * registers. Set when writing to shadow registers, cleared at
- * VSYNC/EVSYNC */
- bool shadow_dirty;
-
+ bool info_dirty;
struct omap_overlay_info info;
+ bool shadow_info_dirty;
+
bool extra_info_dirty;
bool shadow_extra_info_dirty;
@@ -82,16 +79,11 @@ struct mgr_priv_data {
bool user_info_dirty;
struct omap_overlay_manager_info user_info;
- /* If true, cache changed, but not written to shadow registers. Set
- * in apply(), cleared when registers written. */
- bool dirty;
- /* If true, shadow registers contain changed values not yet in real
- * registers. Set when writing to shadow registers, cleared at
- * VSYNC/EVSYNC */
- bool shadow_dirty;
-
+ bool info_dirty;
struct omap_overlay_manager_info info;
+ bool shadow_info_dirty;
+
/* If true, GO bit is up and shadow registers cannot be written.
* Never true for manual update displays */
bool busy;
@@ -199,7 +191,7 @@ static bool need_isr(void)
return true;
/* to write new values to registers */
- if (mp->dirty)
+ if (mp->info_dirty)
return true;
list_for_each_entry(ovl, &mgr->overlays, list) {
@@ -211,7 +203,7 @@ static bool need_isr(void)
continue;
/* to write new values to registers */
- if (op->dirty || op->extra_info_dirty)
+ if (op->info_dirty || op->extra_info_dirty)
return true;
}
}
@@ -228,12 +220,12 @@ static bool need_go(struct omap_overlay_manager *mgr)
mp = get_mgr_priv(mgr);
- if (mp->shadow_dirty)
+ if (mp->shadow_info_dirty)
return true;
list_for_each_entry(ovl, &mgr->overlays, list) {
op = get_ovl_priv(ovl);
- if (op->shadow_dirty || op->shadow_extra_info_dirty)
+ if (op->shadow_info_dirty || op->shadow_extra_info_dirty)
return true;
}
@@ -264,8 +256,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
bool shadow_dirty, dirty;
spin_lock_irqsave(&data_lock, flags);
- dirty = mp->dirty;
- shadow_dirty = mp->shadow_dirty;
+ dirty = mp->info_dirty;
+ shadow_dirty = mp->shadow_info_dirty;
spin_unlock_irqrestore(&data_lock, flags);
if (!dirty && !shadow_dirty) {
@@ -327,8 +319,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
bool shadow_dirty, dirty;
spin_lock_irqsave(&data_lock, flags);
- dirty = op->dirty;
- shadow_dirty = op->shadow_dirty;
+ dirty = op->info_dirty;
+ shadow_dirty = op->shadow_info_dirty;
spin_unlock_irqrestore(&data_lock, flags);
if (!dirty && !shadow_dirty) {
@@ -371,7 +363,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
DSSDBGF("%d", ovl->id);
- if (!op->enabled || !op->dirty)
+ if (!op->enabled || !op->info_dirty)
return;
oi = &op->info;
@@ -396,9 +388,9 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
mp = get_mgr_priv(ovl->manager);
- op->dirty = false;
+ op->info_dirty = false;
if (mp->updating)
- op->shadow_dirty = true;
+ op->shadow_info_dirty = true;
}
static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
@@ -443,12 +435,12 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
dss_ovl_write_regs_extra(ovl);
}
- if (mp->dirty) {
+ if (mp->info_dirty) {
dispc_mgr_setup(mgr->id, &mp->info);
- mp->dirty = false;
+ mp->info_dirty = false;
if (mp->updating)
- mp->shadow_dirty = true;
+ mp->shadow_info_dirty = true;
}
}
@@ -548,11 +540,11 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
struct ovl_priv_data *op;
mp = get_mgr_priv(mgr);
- mp->shadow_dirty = false;
+ mp->shadow_info_dirty = false;
list_for_each_entry(ovl, &mgr->overlays, list) {
op = get_ovl_priv(ovl);
- op->shadow_dirty = false;
+ op->shadow_info_dirty = false;
op->shadow_extra_info_dirty = false;
}
}
@@ -606,7 +598,7 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
return;
op->user_info_dirty = false;
- op->dirty = true;
+ op->info_dirty = true;
op->info = op->user_info;
}
@@ -625,7 +617,7 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
return;
mp->user_info_dirty = false;
- mp->dirty = true;
+ mp->info_dirty = true;
mp->info = mp->user_info;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 55/65] OMAPDSS: APPLY: remove device_changed field
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
omap_overlay_manager contains device_changed field, which no longer has
any use. So remove the field and the few places where it is touched.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 7 -------
include/video/omapdss.h | 2 --
2 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index fdd53b6..916acd7 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -608,11 +608,6 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
mp = get_mgr_priv(mgr);
- if (mgr->device_changed) {
- mgr->device_changed = false;
- mp->user_info_dirty = true;
- }
-
if (!mp->user_info_dirty)
return;
@@ -807,7 +802,6 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
dssdev->manager = mgr;
mgr->device = dssdev;
- mgr->device_changed = true;
mutex_unlock(&apply_lock);
@@ -840,7 +834,6 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
mgr->device->manager = NULL;
mgr->device = NULL;
- mgr->device_changed = true;
mutex_unlock(&apply_lock);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index e629b0d..98fc026 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -426,8 +426,6 @@ struct omap_overlay_manager {
/* dynamic fields */
struct omap_dss_device *device;
- bool device_changed;
-
int (*set_device)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int (*unset_device)(struct omap_overlay_manager *mgr);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 56/65] OMAPDSS: APPLY: add dss_apply_ovl_enable()
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add a helper function dss_apply_ovl_enable(), which is similar to the
main apply() function: dss_apply_ovl_enable() applies the given overlay
enable-status to ovl_priv_data, and sets the dirty flag.
The difference between the helper function and the previous direct use
of the fields is that the helper function will not do anything if the
enable state is already the same as given in the parameter.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 19 +++++++++++++++----
1 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 916acd7..cfc17c0 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -646,6 +646,19 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
return r;
}
+static void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
+{
+ struct ovl_priv_data *op;
+
+ op = get_ovl_priv(ovl);
+
+ if (op->enabled = enable)
+ return;
+
+ op->enabled = enable;
+ op->extra_info_dirty = true;
+}
+
static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -999,8 +1012,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
spin_lock_irqsave(&data_lock, flags);
- op->enabled = true;
- op->extra_info_dirty = true;
+ dss_apply_ovl_enable(ovl, true);
dss_ovl_setup_fifo(ovl);
@@ -1031,8 +1043,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
spin_lock_irqsave(&data_lock, flags);
- op->enabled = false;
- op->extra_info_dirty = true;
+ dss_apply_ovl_enable(ovl, false);
dss_write_regs();
--
1.7.4.1
^ permalink raw reply related
* [PATCH 57/65] OMAPDSS: APPLY: skip enable/disable if already enabled/disabled
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add checks to dss_mgr_enable, dss_mgr_disable, dss_ovl_enable,
dss_ovl_disable that check if the state is already the same as given in
the parameters, and exit if so.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index cfc17c0..76b5b02 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -724,6 +724,9 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
mutex_lock(&apply_lock);
+ if (mp->enabled)
+ goto out;
+
spin_lock_irqsave(&data_lock, flags);
mp->enabled = true;
@@ -740,6 +743,7 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
if (!mgr_manual_update(mgr))
dispc_mgr_enable(mgr->id, true);
+out:
mutex_unlock(&apply_lock);
}
@@ -750,6 +754,9 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
mutex_lock(&apply_lock);
+ if (!mp->enabled)
+ goto out;
+
if (!mgr_manual_update(mgr))
dispc_mgr_enable(mgr->id, false);
@@ -760,6 +767,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
spin_unlock_irqrestore(&data_lock, flags);
+out:
mutex_unlock(&apply_lock);
}
@@ -1005,6 +1013,11 @@ int dss_ovl_enable(struct omap_overlay *ovl)
mutex_lock(&apply_lock);
+ if (op->enabled) {
+ r = 0;
+ goto err;
+ }
+
if (ovl->manager = NULL || ovl->manager->device = NULL) {
r = -EINVAL;
goto err;
@@ -1036,6 +1049,11 @@ int dss_ovl_disable(struct omap_overlay *ovl)
mutex_lock(&apply_lock);
+ if (!op->enabled) {
+ r = 0;
+ goto err;
+ }
+
if (ovl->manager = NULL || ovl->manager->device = NULL) {
r = -EINVAL;
goto err;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates()
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add wait_pending_extra_info_updates() function which can be used to wait
until any extra_info changes have been taken into use by the hardware.
This can be only called when holding the apply mutex, so that other
threads cannot insert new extra_info changes.
This will be used to handle fifo-configurations.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 70 +++++++++++++++++++++++++++++++++++++++
1 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 76b5b02..75db522 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -106,6 +106,7 @@ static struct {
static spinlock_t data_lock;
/* lock for blocking functions */
static DEFINE_MUTEX(apply_lock);
+static DECLARE_COMPLETION(extra_updated_completion);
static void dss_register_vsync_isr(void);
@@ -232,6 +233,70 @@ static bool need_go(struct omap_overlay_manager *mgr)
return false;
}
+/* returns true if an extra_info field is currently being updated */
+static bool extra_info_update_ongoing(void)
+{
+ const int num_ovls = omap_dss_get_num_overlays();
+ struct ovl_priv_data *op;
+ struct omap_overlay *ovl;
+ struct mgr_priv_data *mp;
+ int i;
+ bool eid;
+
+ for (i = 0; i < num_ovls; ++i) {
+ ovl = omap_dss_get_overlay(i);
+ op = get_ovl_priv(ovl);
+
+ if (!op->enabled)
+ continue;
+
+ mp = get_mgr_priv(ovl->manager);
+
+ if (!mp->enabled)
+ continue;
+
+ eid = op->extra_info_dirty || op->shadow_extra_info_dirty;
+
+ if (!eid)
+ continue;
+
+ if (ovl_manual_update(ovl) && !mp->updating)
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+/* wait until no extra_info updates are pending */
+static void wait_pending_extra_info_updates(void)
+{
+ bool updating;
+ unsigned long flags;
+ unsigned long t;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ updating = extra_info_update_ongoing();
+
+ if (!updating) {
+ spin_unlock_irqrestore(&data_lock, flags);
+ return;
+ }
+
+ init_completion(&extra_updated_completion);
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ t = msecs_to_jiffies(500);
+ wait_for_completion_timeout(&extra_updated_completion, t);
+
+ updating = extra_info_update_ongoing();
+
+ WARN_ON(updating);
+}
+
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
@@ -553,6 +618,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
{
const int num_mgrs = dss_feat_get_num_mgrs();
int i;
+ bool extra_updating;
spin_lock(&data_lock);
@@ -582,6 +648,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
dss_write_regs();
+ extra_updating = extra_info_update_ongoing();
+ if (!extra_updating)
+ complete_all(&extra_updated_completion);
+
if (!need_isr())
dss_unregister_vsync_isr();
--
1.7.4.1
^ permalink raw reply related
* [PATCH 59/65] OMAPDSS: APPLY: remove runtime_get
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
apply.c no longer touches any registers if an output is not enabled.
This means that we don't need to do dispc_runtime_get() anymore, and the
calls can be removed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 9 +--------
1 files changed, 1 insertions(+), 8 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 75db522..6a50ee0 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -688,16 +688,11 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
{
- int r;
unsigned long flags;
struct omap_overlay *ovl;
DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
- r = dispc_runtime_get();
- if (r)
- return r;
-
spin_lock_irqsave(&data_lock, flags);
/* Configure overlays */
@@ -711,9 +706,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
spin_unlock_irqrestore(&data_lock, flags);
- dispc_runtime_put();
-
- return r;
+ return 0;
}
static void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox