* [PATCH 00/65] OMAPDSS: manager/apply improvements
@ 2011-11-22 9:20 Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 01/65] OMAPDSS: DISPC: add missing prototype Tomi Valkeinen
` (64 more replies)
0 siblings, 65 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:20 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
I started writing this patch series to get DSS's fifo-merge feature working,
but in the end the series grew a bit...
The reason why fifo-merge is tricky is that enabling or disabling the
fifo-merge affects multiple overlays and overlay managers at the same time. In
practice this means we need to enable and disable fifo-merge in steps, doing
first one thing, then waiting for the changes to be synchronized with all the
overlay managers, then doing another thing, etc... This could be done with a
complex state machine, or more simply with blocking functions.
The basic idea to get this done is to divide ovl & mgr functions into two sets.
First set is non-blocking, using only spinlocks, and used to change settings
which affect only that one ovl or mgr. set/get_info() and apply() functions are
in this set. The second set may block. The rest of the functions are in this
set, for example overlay enable/disable.
To get there wasn't as simple as I thought, so the patch series grew. I am
quite content with the end result, though, as it cleans up the whole
apply-mechanism of omapdss rather lot, and the locking scheme should finally be
valid. There are still holes in the locking scheme, related to the panel
drivers, but the locks in apply.c should be solid.
Almost all of the changes are not visible to the users of the omapdss, but some
changes are visible. The notable changes to the users of omapdss in this series
are:
* Overlays enable/disable is no longer handled through the overlay_info struct,
but functions. The overlay struct contains enable, disable and is_enabled
functions to handle that. Note: enable and disable may block!
* Ovl/mgr infos are no longer visible directly, but need to be gotten with the
get_info functions.
* Partial update for manual update displays has been removed. To my knowledge
partial update is not used, it doesn't work exactly right, using it requires
the user to know limitations about the underlying HW, and lastly and most
importantly, it makes the configuration code really messy.
And the original reason for this series, fifo-merge, is actually still missing.
There are some problems with it when using two displays at the same time, and
it's still under study. Also OMAP4's more advanced fifo-configuration is under
work, and I plan to push both of those later. For those interested, the current
fifo-merge patches can be found from my git tree, on top of this series, from:
git://gitorious.org/linux-omap-dss2/linux.git manager-work
Tomi
Tomi Valkeinen (65):
OMAPDSS: DISPC: add missing prototype
OMAPDSS: Remove old fifomerge hacks
OMAPDSS: remove L4_EXAMPLE code
OMAPDSS: DISPC: make dispc_ovl_set_channel_out() public
OMAPDSS: DISPC: make dispc_ovl_set_fifo_threshold() public
OMAPDSS: remove partial update from the overlay manager
OMAPDSS: remove partial update from DSI
OMAPDSS: remove partial update from panel-taal
OMAPDSS: pass ovl manager to dss_start_update
OMAPDSS: DISPC: handle 0 out_width/out_height in ovl_setup()
OMAPDSS: handle ilace/replication when configuring overlay
OMAPDSS: separate FIFO threshold setup from ovl_setup
OMAPDSS: separate overlay channel from ovl_setup
OMAPDSS: setup manager with dispc_mgr_setup()
OMAPDSS: DISPC: remove unused functions
OMAPDSS: remove unneeded dss_ovl_wait_for_go()
OMAPDSS: add ovl/mgr_manual_update() helpers
OMAPDSS: split omap_dss_mgr_apply() to smaller funcs
OMAPDSS: apply affects only one overlay manager
OMAPDSS: create apply.c
OMAPDSS: hide manager's enable/disable()
OMAPDSS: APPLY: track whether a manager is enabled
OMAPDSS: APPLY: skip isr register and config for manual update
displays
OMAPDSS: APPLY: skip isr register and config for disabled displays
OMAPDSS: APPLY: cleanup dss_start_update
OMAPDSS: store overlays in an array
OMAPDSS: store managers in an array
OMAPDSS: store overlays in a list for each manager
OMAPDSS: APPLY: separate vsync isr register/unregister
OMAPDSS: DISPC: Add dispc_mgr_get_vsync_irq()
OMAPDSS: APPLY: use dispc_mgr_get_vsync_irq()
OMAPDSS: APPLY: configure_* funcs take ovl/manager as args
OMAPDSS: APPLY: rename overlay_cache_data
OMAPDSS: APPLY: rename manager_cache_data
OMAPDSS: APPLY: move spinlock outside the struct
OMAPDSS: APPLY: rename dss_cache to dss_data
OMAPDSS: APPLY: move ovl funcs to apply.c
OMAPDSS: APPLY: move mgr funcs to apply.c
OMAPDSS: remove ovl/mgr check-code temporarily
OMAPDSS: APPLY: add mutex
OMAPDSS: APPLY: add missing uses of spinlock
OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays
OMAPDSS: APPLY: move mgr->enabled to mgr_priv_data
OMAPDSS: APPLY: add busy field to mgr_priv_data
OMAPDSS: APPLY: rewrite overlay enable/disable
OMAPDSS: APPLY: rewrite register writing
OMAPDSS: DISPC: add dispc_mgr_get_framedone_irq
OMAPDSS: APPLY: add updating flag
OMAPDSS: APPLY: clean up isr_handler
OMAPDSS: APPLY: move mgr->info to apply.c
OMAPDSS: APPLY: move ovl->info to apply.c
OMAPDSS: APPLY: move channel-field to extra_info set
OMAPDSS: APPLY: move fifo thresholds to extra_info set
OMAPDSS: APPLY: rename dirty & shadow_dirty
OMAPDSS: APPLY: remove device_changed field
OMAPDSS: APPLY: add dss_apply_ovl_enable()
OMAPDSS: APPLY: skip enable/disable if already enabled/disabled
OMAPDSS: APPLY: add wait_pending_extra_info_updates()
OMAPDSS: APPLY: remove runtime_get
OMAPDSS: Add comments about blocking of ovl/mgr functions
OMAPDSS: APPLY: add dss_ovl_simple_check()
OMAPDSS: APPLY: add dss_mgr_simple_check()
OMAPDSS: APPLY: add checking of ovls/mgrs settings
OMAPDSS: APPLY: add return value to dss_mgr_enable()
OMAPDSS: check the return value of dss_mgr_enable()
drivers/media/video/omap/omap_vout.c | 33 +-
drivers/video/omap2/displays/panel-taal.c | 38 +-
drivers/video/omap2/dss/Makefile | 3 +-
drivers/video/omap2/dss/apply.c | 1420 +++++++++++++++++++++++++++++
drivers/video/omap2/dss/core.c | 2 +
drivers/video/omap2/dss/dispc.c | 191 ++--
drivers/video/omap2/dss/dpi.c | 7 +-
drivers/video/omap2/dss/dsi.c | 169 ++--
drivers/video/omap2/dss/dss.h | 64 +-
drivers/video/omap2/dss/hdmi.c | 13 +-
drivers/video/omap2/dss/manager.c | 1153 +----------------------
drivers/video/omap2/dss/overlay.c | 357 ++------
drivers/video/omap2/dss/rfbi.c | 1 -
drivers/video/omap2/dss/sdi.c | 8 +-
drivers/video/omap2/dss/venc.c | 28 +-
drivers/video/omap2/omapfb/omapfb-ioctl.c | 42 +-
drivers/video/omap2/omapfb/omapfb-main.c | 14 +-
drivers/video/omap2/omapfb/omapfb-sysfs.c | 4 +-
drivers/video/omap2/omapfb/omapfb.h | 11 +-
include/video/omapdss.h | 52 +-
20 files changed, 1891 insertions(+), 1719 deletions(-)
create mode 100644 drivers/video/omap2/dss/apply.c
--
1.7.4.1
^ permalink raw reply [flat|nested] 91+ messages in thread
* [PATCH 01/65] OMAPDSS: DISPC: add missing prototype
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 02/65] OMAPDSS: Remove old fifomerge hacks Tomi Valkeinen
` (63 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
dispc_mgr_is_enabled() was missing a prototype in dss.h
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dss.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6308fc5..3310f10 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -414,6 +414,7 @@ void dispc_mgr_set_cpr_coef(enum omap_channel channel,
struct omap_dss_cpr_coefs *coefs);
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);
void dispc_mgr_enable(enum omap_channel channel, bool enable);
bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 02/65] OMAPDSS: Remove old fifomerge hacks
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 01/65] OMAPDSS: DISPC: add missing prototype Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 03/65] OMAPDSS: remove L4_EXAMPLE code Tomi Valkeinen
` (62 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Once in a time omapdss had basic support for fifomerge. Fifomerge was
removed as the implementation didn't work properly, and a proper
implementation is a complex problem.
However, some unused fifo-merge related code was left behind. This patch
removes those.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/manager.c | 26 +-------------------------
1 files changed, 1 insertions(+), 25 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 6e63845..1be5f47 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -1313,8 +1313,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
struct manager_cache_data *mc;
int i;
struct omap_overlay *ovl;
- int num_planes_enabled = 0;
- bool use_fifomerge;
unsigned long flags;
int r;
@@ -1347,11 +1345,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
continue;
}
- if (!ovl->info_dirty) {
- if (oc->enabled)
- ++num_planes_enabled;
+ if (!ovl->info_dirty)
continue;
- }
dssdev = ovl->manager->device;
@@ -1375,8 +1370,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
oc->channel = ovl->manager->id;
oc->enabled = true;
-
- ++num_planes_enabled;
}
/* Configure managers */
@@ -1406,21 +1399,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
}
- /* XXX TODO: Try to get fifomerge working. The problem is that it
- * affects both managers, not individually but at the same time. This
- * means the change has to be well synchronized. I guess the proper way
- * is to have a two step process for fifo merge:
- * fifomerge enable:
- * 1. disable other planes, leaving one plane enabled
- * 2. wait until the planes are disabled on HW
- * 3. config merged fifo thresholds, enable fifomerge
- * fifomerge disable:
- * 1. config unmerged fifo thresholds, disable fifomerge
- * 2. wait until fifo changes are in HW
- * 3. enable planes
- */
- use_fifomerge = false;
-
/* Configure overlay fifos */
for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
struct omap_dss_device *dssdev;
@@ -1436,8 +1414,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
dssdev = ovl->manager->device;
size = dispc_ovl_get_fifo_size(ovl->id);
- if (use_fifomerge)
- size *= 3;
burst_size = dispc_ovl_get_burst_size(ovl->id);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 03/65] OMAPDSS: remove L4_EXAMPLE code
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 01/65] OMAPDSS: DISPC: add missing prototype Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 02/65] OMAPDSS: Remove old fifomerge hacks Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 04/65] OMAPDSS: DISPC: make dispc_ovl_set_channel_out() public Tomi Valkeinen
` (61 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Some old example code has been left lying around. Remove the example
code.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dss.h | 3 ---
drivers/video/omap2/dss/overlay.c | 36 ------------------------------------
2 files changed, 0 insertions(+), 39 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 3310f10..7d2b6dd 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -192,9 +192,6 @@ 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);
-#ifdef L4_EXAMPLE
-void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
-#endif
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
/* DSS */
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index ab8e40e..d15b826 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -641,15 +641,6 @@ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
mgr->overlays = dispc_overlays;
}
-#ifdef L4_EXAMPLE
-static struct omap_overlay *l4_overlays[1];
-void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr)
-{
- mgr->num_overlays = 1;
- mgr->overlays = l4_overlays;
-}
-#endif
-
void dss_init_overlays(struct platform_device *pdev)
{
int i, r;
@@ -716,33 +707,6 @@ void dss_init_overlays(struct platform_device *pdev)
dispc_overlays[i] = ovl;
}
-
-#ifdef L4_EXAMPLE
- {
- struct omap_overlay *ovl;
- ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
-
- BUG_ON(ovl = NULL);
-
- ovl->name = "l4";
- ovl->supported_modes = OMAP_DSS_COLOR_RGB24U;
-
- 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;
-
- omap_dss_add_overlay(ovl);
-
- r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
- &pdev->dev.kobj, "overlayl4");
-
- if (r)
- DSSERR("failed to create sysfs file\n");
-
- l4_overlays[0] = ovl;
- }
-#endif
}
/* connect overlays to the new device, if not already connected. if force
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 04/65] OMAPDSS: DISPC: make dispc_ovl_set_channel_out() public
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (2 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 03/65] OMAPDSS: remove L4_EXAMPLE code Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 05/65] OMAPDSS: DISPC: make dispc_ovl_set_fifo_threshold() public Tomi Valkeinen
` (60 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Make dispc_ovl_set_channel_out() public so that later patches can handle
changing overlay's manager.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 3 +--
drivers/video/omap2/dss/dss.h | 2 ++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5c81533..b2865ef 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -875,8 +875,7 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
}
-static void dispc_ovl_set_channel_out(enum omap_plane plane,
- enum omap_channel channel)
+void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
{
int shift;
u32 val;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7d2b6dd..f899f0f 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -402,6 +402,8 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
bool ilace, enum omap_channel channel, bool replication,
u32 fifo_low, u32 fifo_high);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
+void dispc_ovl_set_channel_out(enum omap_plane plane,
+ enum omap_channel channel);
void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 05/65] OMAPDSS: DISPC: make dispc_ovl_set_fifo_threshold() public
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (3 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 04/65] OMAPDSS: DISPC: make dispc_ovl_set_channel_out() public Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 06/65] OMAPDSS: remove partial update from the overlay manager Tomi Valkeinen
` (59 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Make dispc_ovl_set_fifo_threshold() public so that later patches can
handle overlay fifo configuration.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 3 +--
drivers/video/omap2/dss/dss.h | 1 +
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b2865ef..7387e23 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1056,8 +1056,7 @@ u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
return dispc.fifo_size[plane];
}
-static void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low,
- u32 high)
+void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
{
u8 hi_start, hi_end, lo_start, lo_end;
u32 unit;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f899f0f..313a7ca 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -396,6 +396,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
struct dispc_clock_info *cinfo);
+void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
u32 dispc_ovl_get_burst_size(enum omap_plane plane);
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 06/65] OMAPDSS: remove partial update from the overlay manager
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (4 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 05/65] OMAPDSS: DISPC: make dispc_ovl_set_fifo_threshold() public Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 11:53 ` [PATCH 06/65] OMAPDSS: remove partial update from the overlay Archit Taneja
2011-11-22 9:21 ` [PATCH 07/65] OMAPDSS: remove partial update from DSI Tomi Valkeinen
` (58 subsequent siblings)
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Partial update for manual update displays has never worked quite well:
* The HW has limitations on the update area, and the x and width need to
be even.
* Showing a part of a scaled overlay causes artifacts.
* Makes the management of dispc very complex
Considering the above points and the fact that partial update is not
used anywhere, this and the following patches remove the partial update
support. This will greatly simplify the following re-write of the apply
mechanism to get proper locking and additional features like fifo-merge.
This patch removes the partial update from the manager.c.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 2 -
drivers/video/omap2/dss/dss.h | 3 -
drivers/video/omap2/dss/manager.c | 333 +------------------------------------
drivers/video/omap2/dss/rfbi.c | 1 -
4 files changed, 6 insertions(+), 333 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 5abf8e7..787cebd 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4172,8 +4172,6 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
dsi_perf_mark_setup(dsidev);
- dss_setup_partial_planes(dssdev, x, y, w, h,
- enlarge_update_area);
dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
return 0;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 313a7ca..7f6a612 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -182,9 +182,6 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
int dss_init_overlay_managers(struct platform_device *pdev);
void dss_uninit_overlay_managers(struct platform_device *pdev);
int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
-void dss_setup_partial_planes(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h,
- bool enlarge_update_area);
void dss_start_update(struct omap_dss_device *dssdev);
/* overlay */
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 1be5f47..c616f85 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -530,13 +530,6 @@ struct manager_cache_data {
bool manual_update;
bool do_manual_update;
-
- /* manual update region */
- u16 x, y, w, h;
-
- /* enlarge the update area if the update area contains scaled
- * overlays */
- bool enlarge_update_area;
};
static struct {
@@ -762,65 +755,11 @@ static int overlay_enabled(struct omap_overlay *ovl)
return ovl->info.enabled && ovl->manager && ovl->manager->device;
}
-/* Is rect1 a subset of rect2? */
-static bool rectangle_subset(int x1, int y1, int w1, int h1,
- int x2, int y2, int w2, int h2)
-{
- if (x1 < x2 || y1 < y2)
- return false;
-
- if (x1 + w1 > x2 + w2)
- return false;
-
- if (y1 + h1 > y2 + h2)
- return false;
-
- return true;
-}
-
-/* Do rect1 and rect2 overlap? */
-static bool rectangle_intersects(int x1, int y1, int w1, int h1,
- int x2, int y2, int w2, int h2)
-{
- if (x1 >= x2 + w2)
- return false;
-
- if (x2 >= x1 + w1)
- return false;
-
- if (y1 >= y2 + h2)
- return false;
-
- if (y2 >= y1 + h1)
- return false;
-
- return true;
-}
-
-static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc)
-{
- struct omap_overlay_info *oi = &oc->info;
-
- if (oi->out_width != 0 && oi->width != oi->out_width)
- return true;
-
- if (oi->out_height != 0 && oi->height != oi->out_height)
- return true;
-
- return false;
-}
-
static int configure_overlay(enum omap_plane plane)
{
struct overlay_cache_data *c;
- struct manager_cache_data *mc;
- struct omap_overlay_info *oi, new_oi;
- struct omap_overlay_manager_info *mi;
- u16 outw, outh;
- u16 x, y, w, h;
- u32 paddr;
+ struct omap_overlay_info *oi;
int r;
- u16 orig_w, orig_h, orig_outw, orig_outh;
DSSDBGF("%d", plane);
@@ -832,120 +771,7 @@ static int configure_overlay(enum omap_plane plane)
return 0;
}
- mc = &dss_cache.manager_cache[c->channel];
- mi = &mc->info;
-
- x = oi->pos_x;
- y = oi->pos_y;
- w = oi->width;
- h = oi->height;
- outw = oi->out_width = 0 ? oi->width : oi->out_width;
- outh = oi->out_height = 0 ? oi->height : oi->out_height;
- paddr = oi->paddr;
-
- orig_w = w;
- orig_h = h;
- orig_outw = outw;
- orig_outh = outh;
-
- if (mc->manual_update && mc->do_manual_update) {
- unsigned bpp;
- unsigned scale_x_m = w, scale_x_d = outw;
- unsigned scale_y_m = h, scale_y_d = outh;
-
- /* If the overlay is outside the update region, disable it */
- if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
- x, y, outw, outh)) {
- dispc_ovl_enable(plane, 0);
- return 0;
- }
-
- switch (oi->color_mode) {
- case OMAP_DSS_COLOR_NV12:
- bpp = 8;
- break;
- case OMAP_DSS_COLOR_RGB16:
- case OMAP_DSS_COLOR_ARGB16:
- case OMAP_DSS_COLOR_YUV2:
- case OMAP_DSS_COLOR_UYVY:
- case OMAP_DSS_COLOR_RGBA16:
- case OMAP_DSS_COLOR_RGBX16:
- case OMAP_DSS_COLOR_ARGB16_1555:
- case OMAP_DSS_COLOR_XRGB16_1555:
- bpp = 16;
- break;
-
- case OMAP_DSS_COLOR_RGB24P:
- bpp = 24;
- break;
-
- case OMAP_DSS_COLOR_RGB24U:
- case OMAP_DSS_COLOR_ARGB32:
- case OMAP_DSS_COLOR_RGBA32:
- case OMAP_DSS_COLOR_RGBX32:
- bpp = 32;
- break;
-
- default:
- BUG();
- }
-
- if (mc->x > oi->pos_x) {
- x = 0;
- outw -= (mc->x - oi->pos_x);
- paddr += (mc->x - oi->pos_x) *
- scale_x_m / scale_x_d * bpp / 8;
- } else {
- x = oi->pos_x - mc->x;
- }
-
- if (mc->y > oi->pos_y) {
- y = 0;
- outh -= (mc->y - oi->pos_y);
- paddr += (mc->y - oi->pos_y) *
- scale_y_m / scale_y_d *
- oi->screen_width * bpp / 8;
- } else {
- y = oi->pos_y - mc->y;
- }
-
- if (mc->w < (x + outw))
- outw -= (x + outw) - (mc->w);
-
- if (mc->h < (y + outh))
- outh -= (y + outh) - (mc->h);
-
- w = w * outw / orig_outw;
- h = h * outh / orig_outh;
-
- /* YUV mode overlay's input width has to be even and the
- * algorithm above may adjust the width to be odd.
- *
- * Here we adjust the width if needed, preferring to increase
- * the width if the original width was bigger.
- */
- if ((w & 1) &&
- (oi->color_mode = OMAP_DSS_COLOR_YUV2 ||
- oi->color_mode = OMAP_DSS_COLOR_UYVY)) {
- if (orig_w > w)
- w += 1;
- else
- w -= 1;
- }
- }
-
- new_oi = *oi;
-
- /* update new_oi members which could have been possibly updated */
- new_oi.pos_x = x;
- new_oi.pos_y = y;
- new_oi.width = w;
- new_oi.height = h;
- new_oi.out_width = outw;
- new_oi.out_height = outh;
- new_oi.paddr = paddr;
-
- r = dispc_ovl_setup(plane, &new_oi, c->ilace, c->channel,
+ r = dispc_ovl_setup(plane, oi, c->ilace, c->channel,
c->replication, c->fifo_low, c->fifo_high);
if (r) {
/* this shouldn't happen */
@@ -1070,170 +896,23 @@ static int configure_dispc(void)
return r;
}
-/* Make the coordinates even. There are some strange problems with OMAP and
- * partial DSI update when the update widths are odd. */
-static void make_even(u16 *x, u16 *w)
-{
- u16 x1, x2;
-
- x1 = *x;
- x2 = *x + *w;
-
- x1 &= ~1;
- x2 = ALIGN(x2, 2);
-
- *x = x1;
- *w = x2 - x1;
-}
-
-/* Configure dispc for partial update. Return possibly modified update
- * area */
-void dss_setup_partial_planes(struct omap_dss_device *dssdev,
- u16 *xi, u16 *yi, u16 *wi, u16 *hi, bool enlarge_update_area)
+void dss_start_update(struct omap_dss_device *dssdev)
{
- struct overlay_cache_data *oc;
struct manager_cache_data *mc;
- struct omap_overlay_info *oi;
+ struct overlay_cache_data *oc;
const int num_ovls = dss_feat_get_num_ovls();
+ const int num_mgrs = dss_feat_get_num_mgrs();
struct omap_overlay_manager *mgr;
int i;
- u16 x, y, w, h;
- unsigned long flags;
- bool area_changed;
-
- x = *xi;
- y = *yi;
- w = *wi;
- h = *hi;
-
- DSSDBG("dispc_setup_partial_planes %d,%d %dx%d\n",
- *xi, *yi, *wi, *hi);
mgr = dssdev->manager;
- if (!mgr) {
- DSSDBG("no manager\n");
- return;
- }
-
- make_even(&x, &w);
-
- spin_lock_irqsave(&dss_cache.lock, flags);
-
- /*
- * Execute the outer loop until the inner loop has completed
- * once without increasing the update area. This will ensure that
- * all scaled overlays end up completely within the update area.
- */
- do {
- area_changed = false;
-
- /* We need to show the whole overlay if it is scaled. So look
- * for those, and make the update area larger if found.
- * Also mark the overlay cache dirty */
- for (i = 0; i < num_ovls; ++i) {
- unsigned x1, y1, x2, y2;
- unsigned outw, outh;
-
- oc = &dss_cache.overlay_cache[i];
- oi = &oc->info;
-
- if (oc->channel != mgr->id)
- continue;
-
- oc->dirty = true;
-
- if (!enlarge_update_area)
- continue;
-
- if (!oc->enabled)
- continue;
-
- if (!dispc_is_overlay_scaled(oc))
- continue;
-
- outw = oi->out_width = 0 ?
- oi->width : oi->out_width;
- outh = oi->out_height = 0 ?
- oi->height : oi->out_height;
-
- /* is the overlay outside the update region? */
- if (!rectangle_intersects(x, y, w, h,
- oi->pos_x, oi->pos_y,
- outw, outh))
- continue;
-
- /* if the overlay totally inside the update region? */
- if (rectangle_subset(oi->pos_x, oi->pos_y, outw, outh,
- x, y, w, h))
- continue;
-
- if (x > oi->pos_x)
- x1 = oi->pos_x;
- else
- x1 = x;
-
- if (y > oi->pos_y)
- y1 = oi->pos_y;
- else
- y1 = y;
-
- if ((x + w) < (oi->pos_x + outw))
- x2 = oi->pos_x + outw;
- else
- x2 = x + w;
-
- if ((y + h) < (oi->pos_y + outh))
- y2 = oi->pos_y + outh;
- else
- y2 = y + h;
-
- x = x1;
- y = y1;
- w = x2 - x1;
- h = y2 - y1;
-
- make_even(&x, &w);
-
- DSSDBG("changing upd area due to ovl(%d) "
- "scaling %d,%d %dx%d\n",
- i, x, y, w, h);
-
- area_changed = true;
- }
- } while (area_changed);
-
mc = &dss_cache.manager_cache[mgr->id];
- mc->do_manual_update = true;
- mc->enlarge_update_area = enlarge_update_area;
- mc->x = x;
- mc->y = y;
- mc->w = w;
- mc->h = h;
+ mc->do_manual_update = true;
configure_dispc();
-
mc->do_manual_update = false;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- *xi = x;
- *yi = y;
- *wi = w;
- *hi = h;
-}
-
-void dss_start_update(struct omap_dss_device *dssdev)
-{
- struct manager_cache_data *mc;
- struct overlay_cache_data *oc;
- const int num_ovls = dss_feat_get_num_ovls();
- const int num_mgrs = dss_feat_get_num_mgrs();
- struct omap_overlay_manager *mgr;
- int i;
-
- mgr = dssdev->manager;
-
for (i = 0; i < num_ovls; ++i) {
oc = &dss_cache.overlay_cache[i];
if (oc->channel != mgr->id)
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 1130c60..814bb95 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -784,7 +784,6 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
if (*w = 0 || *h = 0)
return -EINVAL;
- dss_setup_partial_planes(dssdev, x, y, w, h, true);
dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
return 0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 07/65] OMAPDSS: remove partial update from DSI
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (5 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 06/65] OMAPDSS: remove partial update from the overlay manager Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 08/65] OMAPDSS: remove partial update from panel-taal Tomi Valkeinen
` (57 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Partial update for manual update displays has never worked quite well:
* The HW has limitations on the update area, and the x and width need to
be even.
* Showing a part of a scaled overlay causes artifacts.
* Makes the management of dispc very complex
Considering the above points and the fact that partial update is not
used anywhere, this and the following patches remove the partial update
support. This will greatly simplify the following re-write of the apply
mechanism to get proper locking and additional features like fifo-merge.
This patch removes the partial update from the dsi.c.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays/panel-taal.c | 16 ++----
drivers/video/omap2/dss/dsi.c | 79 +++++++---------------------
include/video/omapdss.h | 7 +--
3 files changed, 25 insertions(+), 77 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 80c3f6a..0aa6c5d 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1394,12 +1394,8 @@ static irqreturn_t taal_te_isr(int irq, void *data)
if (old) {
cancel_delayed_work(&td->te_timeout_work);
- r = omap_dsi_update(dssdev, td->channel,
- td->update_region.x,
- td->update_region.y,
- td->update_region.w,
- td->update_region.h,
- taal_framedone_cb, dssdev);
+ r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
+ dssdev);
if (r)
goto err;
}
@@ -1444,10 +1440,6 @@ static int taal_update(struct omap_dss_device *dssdev,
goto err;
}
- r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
- if (r)
- goto err;
-
r = taal_set_update_window(td, x, y, w, h);
if (r)
goto err;
@@ -1462,8 +1454,8 @@ static int taal_update(struct omap_dss_device *dssdev,
msecs_to_jiffies(250));
atomic_set(&td->do_update, 1);
} else {
- r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
- taal_framedone_cb, dssdev);
+ r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
+ dssdev);
if (r)
goto err;
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 787cebd..9ef04ff 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -236,11 +236,6 @@ enum dsi_lane {
DSI_DATA4_N = 1 << 9,
};
-struct dsi_update_region {
- u16 x, y, w, h;
- struct omap_dss_device *device;
-};
-
struct dsi_irq_stats {
unsigned long last_reset;
unsigned irq_count;
@@ -290,7 +285,9 @@ struct dsi_data {
struct dsi_isr_tables isr_tables_copy;
int update_channel;
- struct dsi_update_region update_region;
+#ifdef DEBUG
+ unsigned update_bytes;
+#endif
bool te_enabled;
bool ulps_enabled;
@@ -454,7 +451,6 @@ static void dsi_perf_mark_start(struct platform_device *dsidev)
static void dsi_perf_show(struct platform_device *dsidev, const char *name)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- struct omap_dss_device *dssdev = dsi->update_region.device;
ktime_t t, setup_time, trans_time;
u32 total_bytes;
u32 setup_us, trans_us, total_us;
@@ -476,9 +472,7 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
total_us = setup_us + trans_us;
- total_bytes = dsi->update_region.w *
- dsi->update_region.h *
- dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+ total_bytes = dsi->update_bytes;
printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
"%u bytes, %u kbytes/sec\n",
@@ -4006,7 +4000,7 @@ void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel)
EXPORT_SYMBOL(dsi_video_mode_disable);
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
- u16 x, u16 y, u16 w, u16 h)
+ u16 w, u16 h)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4021,8 +4015,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
const unsigned channel = dsi->update_channel;
const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
- DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
- x, y, w, h);
+ DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
@@ -4146,64 +4139,27 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
#endif
}
-int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h,
- bool enlarge_update_area)
+int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
+ void (*callback)(int, void *), void *data)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u16 dw, dh;
- dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
- if (*x > dw || *y > dh)
- return -EINVAL;
-
- if (*x + *w > dw)
- return -EINVAL;
-
- if (*y + *h > dh)
- return -EINVAL;
-
- if (*w = 1)
- return -EINVAL;
-
- if (*w = 0 || *h = 0)
- return -EINVAL;
-
dsi_perf_mark_setup(dsidev);
- dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
-
- return 0;
-}
-EXPORT_SYMBOL(omap_dsi_prepare_update);
-
-int omap_dsi_update(struct omap_dss_device *dssdev,
- int channel,
- u16 x, u16 y, u16 w, u16 h,
- void (*callback)(int, void *), void *data)
-{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-
dsi->update_channel = channel;
- /* OMAP DSS cannot send updates of odd widths.
- * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
- * here to make sure we catch erroneous updates. Otherwise we'll only
- * see rather obscure HW error happening, as DSS halts. */
- BUG_ON(x % 2 = 1);
-
dsi->framedone_callback = callback;
dsi->framedone_data = data;
- dsi->update_region.x = x;
- dsi->update_region.y = y;
- dsi->update_region.w = w;
- dsi->update_region.h = h;
- dsi->update_region.device = dssdev;
+ dssdev->driver->get_resolution(dssdev, &dw, &dh);
- dsi_update_screen_dispc(dssdev, x, y, w, h);
+#ifdef DEBUG
+ dsi->update_bytes = dw * dh *
+ dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+#endif
+ dsi_update_screen_dispc(dssdev, dw, dh);
return 0;
}
@@ -4216,6 +4172,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
int r;
if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_CMD_MODE) {
+ u16 dw, dh;
u32 irq;
struct omap_video_timings timings = {
.hsw = 1,
@@ -4226,6 +4183,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
.vbp = 0,
};
+ dssdev->driver->get_resolution(dssdev, &dw, &dh);
+ timings.x_res = dw;
+ timings.y_res = dh;
+
irq = dssdev->manager->id = OMAP_DSS_CHANNEL_LCD ?
DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 378c7ed..60bf426 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -662,12 +662,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable);
int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
-int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h,
- bool enlarge_update_area);
-int omap_dsi_update(struct omap_dss_device *dssdev,
- int channel,
- u16 x, u16 y, u16 w, u16 h,
+int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
void (*callback)(int, void *), void *data);
int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 08/65] OMAPDSS: remove partial update from panel-taal
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (6 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 07/65] OMAPDSS: remove partial update from DSI Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 11:55 ` Archit Taneja
2011-11-22 9:21 ` [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update Tomi Valkeinen
` (56 subsequent siblings)
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Partial update for manual update displays has never worked quite well:
* The HW has limitations on the update area, and the x and width need to
be even.
* Showing a part of a scaled overlay causes artifacts.
* Makes the management of dispc very complex
Considering the above points and the fact that partial update is not
used anywhere, this and the following patches remove the partial update
support. This will greatly simplify the following re-write of the apply
mechanism to get proper locking and additional features like fifo-merge.
This patch removes the partial update from the panel-taal.c.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays/panel-taal.c | 16 ++++------------
1 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 0aa6c5d..dd64bd1 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -198,12 +198,6 @@ struct taal_data {
bool te_enabled;
atomic_t do_update;
- struct {
- u16 x;
- u16 y;
- u16 w;
- u16 h;
- } update_region;
int channel;
struct delayed_work te_timeout_work;
@@ -1440,16 +1434,14 @@ static int taal_update(struct omap_dss_device *dssdev,
goto err;
}
- r = taal_set_update_window(td, x, y, w, h);
+ /* XXX no need to send this every frame, but dsi break if not done */
+ r = taal_set_update_window(td, 0, 0,
+ td->panel_config->timings.x_res,
+ td->panel_config->timings.y_res);
if (r)
goto err;
if (td->te_enabled && panel_data->use_ext_te) {
- td->update_region.x = x;
- td->update_region.y = y;
- td->update_region.w = w;
- td->update_region.h = h;
- barrier();
schedule_delayed_work(&td->te_timeout_work,
msecs_to_jiffies(250));
atomic_set(&td->do_update, 1);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (7 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 08/65] OMAPDSS: remove partial update from panel-taal Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-23 5:55 ` Archit Taneja
2011-11-22 9:21 ` [PATCH 10/65] OMAPDSS: DISPC: handle 0 out_width/out_height in ovl_setup() Tomi Valkeinen
` (55 subsequent siblings)
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
dss_start_update() takes currently the dss device as a parameter. Change
the parameter to ovl manager, as that is what the dss_start_update()
actually needs.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 2 +-
drivers/video/omap2/dss/dss.h | 2 +-
drivers/video/omap2/dss/manager.c | 7 ++-----
3 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 9ef04ff..e5a2dcc 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4063,7 +4063,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
msecs_to_jiffies(250));
BUG_ON(r = 0);
- dss_start_update(dssdev);
+ dss_start_update(dssdev->manager);
if (dsi->te_enabled) {
/* disable LP_RX_TO, so that we can receive TE. Time to wait
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7f6a612..0937bd8 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -182,7 +182,7 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
int dss_init_overlay_managers(struct platform_device *pdev);
void dss_uninit_overlay_managers(struct platform_device *pdev);
int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
-void dss_start_update(struct omap_dss_device *dssdev);
+void dss_start_update(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 c616f85..bc28bfa 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -896,17 +896,14 @@ static int configure_dispc(void)
return r;
}
-void dss_start_update(struct omap_dss_device *dssdev)
+void dss_start_update(struct omap_overlay_manager *mgr)
{
struct manager_cache_data *mc;
struct overlay_cache_data *oc;
const int num_ovls = dss_feat_get_num_ovls();
const int num_mgrs = dss_feat_get_num_mgrs();
- struct omap_overlay_manager *mgr;
int i;
- mgr = dssdev->manager;
-
mc = &dss_cache.manager_cache[mgr->id];
mc->do_manual_update = true;
@@ -929,7 +926,7 @@ void dss_start_update(struct omap_dss_device *dssdev)
mc->shadow_dirty = false;
}
- dssdev->manager->enable(dssdev->manager);
+ mgr->enable(mgr);
}
static void dss_apply_irq_handler(void *data, u32 mask)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 10/65] OMAPDSS: DISPC: handle 0 out_width/out_height in ovl_setup()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (8 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 11/65] OMAPDSS: handle ilace/replication when configuring overlay Tomi Valkeinen
` (54 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Overlay out_width/height are set to 0 when scaling is not used by the
users of omapdss. Currently ovl_setup() expects the caller of
ovl_setup() to convert those zero values to width or height.
This patch makes ovl_setup() accept zero values for out_width/height,
making calling ovl_setup() a bit simpler as the overlay_info can be
just passed to this function without modifications.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 22 +++++++++++++---------
1 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 7387e23..49f97db 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1781,6 +1781,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
s32 pix_inc;
u16 frame_height = oi->height;
unsigned int field_offset = 0;
+ u16 outw, outh;
DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
"%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d "
@@ -1792,25 +1793,28 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
if (oi->paddr = 0)
return -EINVAL;
- if (ilace && oi->height = oi->out_height)
+ outw = oi->out_width = 0 ? oi->width : oi->out_width;
+ outh = oi->out_height = 0 ? oi->height : oi->out_height;
+
+ if (ilace && oi->height = outh)
fieldmode = 1;
if (ilace) {
if (fieldmode)
oi->height /= 2;
oi->pos_y /= 2;
- oi->out_height /= 2;
+ outh /= 2;
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
"out_height %d\n",
- oi->height, oi->pos_y, oi->out_height);
+ oi->height, oi->pos_y, outh);
}
if (!dss_feat_color_mode_supported(plane, oi->color_mode))
return -EINVAL;
r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
- oi->out_width, oi->out_height, oi->color_mode,
+ outw, outh, oi->color_mode,
&five_taps);
if (r)
return r;
@@ -1828,10 +1832,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
* so the integer part must be added to the base address of the
* bottom field.
*/
- if (!oi->height || oi->height = oi->out_height)
+ if (!oi->height || oi->height = outh)
field_offset = 0;
else
- field_offset = oi->height / oi->out_height / 2;
+ field_offset = oi->height / outh / 2;
}
/* Fields are independent but interleaved in memory. */
@@ -1867,7 +1871,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
dispc_ovl_set_pix_inc(plane, pix_inc);
DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
- oi->height, oi->out_width, oi->out_height);
+ oi->height, outw, outh);
dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
@@ -1875,10 +1879,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_ovl_set_scaling(plane, oi->width, oi->height,
- oi->out_width, oi->out_height,
+ outw, outh,
ilace, five_taps, fieldmode,
oi->color_mode, oi->rotation);
- dispc_ovl_set_vid_size(plane, oi->out_width, oi->out_height);
+ dispc_ovl_set_vid_size(plane, outw, outh);
dispc_ovl_set_vid_color_conv(plane, cconv);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 11/65] OMAPDSS: handle ilace/replication when configuring overlay
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (9 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 10/65] OMAPDSS: DISPC: handle 0 out_width/out_height in ovl_setup() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 12/65] OMAPDSS: separate FIFO threshold setup from ovl_setup Tomi Valkeinen
` (53 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Move the configuration of interlace and replication from
omap_dss_mgr_apply() to configure_overlay(). This removes the need to
store the values into the cache data.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/manager.c | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index bc28bfa..626f6b7 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -510,8 +510,6 @@ struct overlay_cache_data {
struct omap_overlay_info info;
enum omap_channel channel;
- bool replication;
- bool ilace;
u32 fifo_low;
u32 fifo_high;
@@ -757,8 +755,10 @@ static int overlay_enabled(struct omap_overlay *ovl)
static int configure_overlay(enum omap_plane plane)
{
+ struct omap_overlay *ovl;
struct overlay_cache_data *c;
struct omap_overlay_info *oi;
+ bool ilace, replication;
int r;
DSSDBGF("%d", plane);
@@ -771,8 +771,14 @@ static int configure_overlay(enum omap_plane plane)
return 0;
}
- r = dispc_ovl_setup(plane, oi, c->ilace, c->channel,
- c->replication, c->fifo_low, c->fifo_high);
+ ovl = omap_dss_get_overlay(plane);
+
+ replication = dss_use_replication(ovl->manager->device, oi->color_mode);
+
+ ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
+
+ r = dispc_ovl_setup(plane, oi, ilace, c->channel,
+ replication, c->fifo_low, c->fifo_high);
if (r) {
/* this shouldn't happen */
DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
@@ -1038,11 +1044,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
oc->dirty = true;
oc->info = ovl->info;
- oc->replication - dss_use_replication(dssdev, ovl->info.color_mode);
-
- oc->ilace = dssdev->type = OMAP_DISPLAY_TYPE_VENC;
-
oc->channel = ovl->manager->id;
oc->enabled = true;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 12/65] OMAPDSS: separate FIFO threshold setup from ovl_setup
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (10 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 11/65] OMAPDSS: handle ilace/replication when configuring overlay Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 13/65] OMAPDSS: separate overlay channel " Tomi Valkeinen
` (52 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Overlay FIFO thresholds are configured with ovl_setup, with all the
other overlay attributes. This patch separates FIFO threshold setup so
that we can later configure FIFO thresholds only when needed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 10 ++++------
drivers/video/omap2/dss/dss.h | 3 +--
drivers/video/omap2/dss/manager.c | 5 +++--
3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 49f97db..55cfbc9 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1769,8 +1769,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
}
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool ilace, enum omap_channel channel, bool replication,
- u32 fifo_low, u32 fifo_high)
+ bool ilace, enum omap_channel channel, bool replication)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
bool five_taps = false;
@@ -1784,11 +1783,11 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
u16 outw, outh;
DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
- "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d "
- "fifo_low %d fifo high %d\n", plane, oi->paddr, oi->p_uv_addr,
+ "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
+ plane, oi->paddr, oi->p_uv_addr,
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
- oi->mirror, ilace, channel, replication, fifo_low, fifo_high);
+ oi->mirror, ilace, channel, replication);
if (oi->paddr = 0)
return -EINVAL;
@@ -1896,7 +1895,6 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
dispc_ovl_set_channel_out(plane, channel);
dispc_ovl_enable_replication(plane, replication);
- dispc_ovl_set_fifo_threshold(plane, fifo_low, fifo_high);
return 0;
}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 0937bd8..61001c3 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -397,8 +397,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
u32 dispc_ovl_get_burst_size(enum omap_plane plane);
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool ilace, enum omap_channel channel, bool replication,
- u32 fifo_low, u32 fifo_high);
+ bool ilace, enum omap_channel channel, bool replication);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_ovl_set_channel_out(enum omap_plane plane,
enum omap_channel channel);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 626f6b7..b47c1fa 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -777,8 +777,7 @@ static int configure_overlay(enum omap_plane plane)
ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
- r = dispc_ovl_setup(plane, oi, ilace, c->channel,
- replication, c->fifo_low, c->fifo_high);
+ r = dispc_ovl_setup(plane, oi, ilace, c->channel, replication);
if (r) {
/* this shouldn't happen */
DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
@@ -786,6 +785,8 @@ static int configure_overlay(enum omap_plane plane)
return r;
}
+ dispc_ovl_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
+
dispc_ovl_enable(plane, 1);
return 0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 13/65] OMAPDSS: separate overlay channel from ovl_setup
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (11 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 12/65] OMAPDSS: separate FIFO threshold setup from ovl_setup Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 14/65] OMAPDSS: setup manager with dispc_mgr_setup() Tomi Valkeinen
` (51 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Overlay channel is configured with ovl_setup, with all the other overlay
attriutes. This patch separates overlay channel setup so that we can
later configure the channel only when needed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 40 ++++++++++++++++++++++++++++++++++--
drivers/video/omap2/dss/dss.h | 2 +-
drivers/video/omap2/dss/manager.c | 4 ++-
3 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 55cfbc9..ab86a78 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -922,6 +922,39 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
}
+static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
+{
+ int shift;
+ u32 val;
+ enum omap_channel channel;
+
+ switch (plane) {
+ case OMAP_DSS_GFX:
+ shift = 8;
+ break;
+ case OMAP_DSS_VIDEO1:
+ case OMAP_DSS_VIDEO2:
+ case OMAP_DSS_VIDEO3:
+ shift = 16;
+ break;
+ default:
+ BUG();
+ }
+
+ val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
+
+ if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (FLD_GET(val, 31, 30) = 0)
+ channel = FLD_GET(val, shift, shift);
+ else
+ channel = OMAP_DSS_CHANNEL_LCD2;
+ } else {
+ channel = FLD_GET(val, shift, shift);
+ }
+
+ return channel;
+}
+
static void dispc_ovl_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
@@ -1769,7 +1802,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
}
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool ilace, enum omap_channel channel, bool replication)
+ bool ilace, bool replication)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
bool five_taps = false;
@@ -1781,6 +1814,9 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
u16 frame_height = oi->height;
unsigned int field_offset = 0;
u16 outw, outh;
+ enum omap_channel channel;
+
+ channel = dispc_ovl_get_channel_out(plane);
DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
"%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
@@ -1892,8 +1928,6 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
- dispc_ovl_set_channel_out(plane, channel);
-
dispc_ovl_enable_replication(plane, replication);
return 0;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 61001c3..bc1b2cc 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -397,7 +397,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
u32 dispc_ovl_get_burst_size(enum omap_plane plane);
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool ilace, enum omap_channel channel, bool replication);
+ bool ilace, bool replication);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_ovl_set_channel_out(enum omap_plane plane,
enum omap_channel channel);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index b47c1fa..42740d3 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -777,7 +777,9 @@ static int configure_overlay(enum omap_plane plane)
ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
- r = dispc_ovl_setup(plane, oi, ilace, c->channel, replication);
+ dispc_ovl_set_channel_out(plane, c->channel);
+
+ r = dispc_ovl_setup(plane, oi, ilace, replication);
if (r) {
/* this shouldn't happen */
DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 14/65] OMAPDSS: setup manager with dispc_mgr_setup()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (12 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 13/65] OMAPDSS: separate overlay channel " Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 15/65] OMAPDSS: DISPC: remove unused functions Tomi Valkeinen
` (50 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Change manager configuration to be similar to overlay configuration by
creating dispc_mgr_setup() which takes omap_overlay_manager_info as
parameter.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 26 ++++++++++++++++++++------
drivers/video/omap2/dss/dss.h | 11 ++---------
drivers/video/omap2/dss/manager.c | 9 +--------
3 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ab86a78..3f2efdc 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -996,7 +996,7 @@ void dispc_enable_gamma_table(bool enable)
REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
}
-void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
{
u16 reg;
@@ -1010,7 +1010,7 @@ void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
REG_FLD_MOD(reg, enable, 15, 15);
}
-void dispc_mgr_set_cpr_coef(enum omap_channel channel,
+static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
struct omap_dss_cpr_coefs *coefs)
{
u32 coef_r, coef_g, coef_b;
@@ -2158,7 +2158,7 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
}
-void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
+static void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
{
dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
}
@@ -2176,7 +2176,7 @@ u32 dispc_mgr_get_default_color(enum omap_channel channel)
return l;
}
-void dispc_mgr_set_trans_key(enum omap_channel ch,
+static void dispc_mgr_set_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type type,
u32 trans_key)
{
@@ -2209,7 +2209,7 @@ void dispc_mgr_get_trans_key(enum omap_channel ch,
*trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
}
-void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
+static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
{
if (ch = OMAP_DSS_CHANNEL_LCD)
REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
@@ -2219,7 +2219,8 @@ void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
}
-void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
+static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
+ bool enable)
{
if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
return;
@@ -2263,6 +2264,19 @@ bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
return enabled;
}
+void dispc_mgr_setup(enum omap_channel channel,
+ struct omap_overlay_manager_info *info)
+{
+ dispc_mgr_set_default_color(channel, info->default_color);
+ dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
+ dispc_mgr_enable_trans_key(channel, info->trans_enabled);
+ dispc_mgr_enable_alpha_fixed_zorder(channel,
+ info->partial_alpha_enabled);
+ if (dss_has_feature(FEAT_CPR)) {
+ dispc_mgr_enable_cpr(channel, info->cpr_enable);
+ dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
+ }
+}
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index bc1b2cc..3e01bba 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -405,9 +405,6 @@ 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);
-void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable);
-void dispc_mgr_set_cpr_coef(enum omap_channel channel,
- struct omap_dss_cpr_coefs *coefs);
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);
@@ -418,16 +415,10 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
enum omap_lcd_display_type type);
-void dispc_mgr_set_default_color(enum omap_channel channel, u32 color);
u32 dispc_mgr_get_default_color(enum omap_channel channel);
-void dispc_mgr_set_trans_key(enum omap_channel ch,
- enum omap_dss_trans_key_type type,
- u32 trans_key);
void dispc_mgr_get_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type *type,
u32 *trans_key);
-void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable);
-void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable);
bool dispc_mgr_trans_key_enabled(enum omap_channel ch);
bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch);
void dispc_mgr_set_lcd_timings(enum omap_channel channel,
@@ -440,6 +431,8 @@ int dispc_mgr_set_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
+void dispc_mgr_setup(enum omap_channel channel,
+ struct omap_overlay_manager_info *info);
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 42740d3..fc19f01 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -803,14 +803,7 @@ static void configure_manager(enum omap_channel channel)
/* picking info from the cache */
mi = &dss_cache.manager_cache[channel].info;
- dispc_mgr_set_default_color(channel, mi->default_color);
- dispc_mgr_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
- dispc_mgr_enable_trans_key(channel, mi->trans_enabled);
- dispc_mgr_enable_alpha_fixed_zorder(channel, mi->partial_alpha_enabled);
- if (dss_has_feature(FEAT_CPR)) {
- dispc_mgr_enable_cpr(channel, mi->cpr_enable);
- dispc_mgr_set_cpr_coef(channel, &mi->cpr_coefs);
- }
+ dispc_mgr_setup(channel, mi);
}
/* configure_dispc() tries to write values from cache to shadow registers.
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 15/65] OMAPDSS: DISPC: remove unused functions
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (13 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 14/65] OMAPDSS: setup manager with dispc_mgr_setup() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 16/65] OMAPDSS: remove unneeded dss_ovl_wait_for_go() Tomi Valkeinen
` (49 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Remove unused functions:
dispc_mgr_get_default_color
dispc_mgr_get_trans_key
dispc_mgr_trans_key_enabled
dispc_mgr_alpha_fixed_zorder_enabled
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 65 ---------------------------------------
drivers/video/omap2/dss/dss.h | 6 ---
2 files changed, 0 insertions(+), 71 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 3f2efdc..5ac00a2 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2163,19 +2163,6 @@ static void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
}
-u32 dispc_mgr_get_default_color(enum omap_channel channel)
-{
- u32 l;
-
- BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT &&
- channel != OMAP_DSS_CHANNEL_LCD &&
- channel != OMAP_DSS_CHANNEL_LCD2);
-
- l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
-
- return l;
-}
-
static void dispc_mgr_set_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type type,
u32 trans_key)
@@ -2190,25 +2177,6 @@ static void dispc_mgr_set_trans_key(enum omap_channel ch,
dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
}
-void dispc_mgr_get_trans_key(enum omap_channel ch,
- enum omap_dss_trans_key_type *type,
- u32 *trans_key)
-{
- if (type) {
- if (ch = OMAP_DSS_CHANNEL_LCD)
- *type = REG_GET(DISPC_CONFIG, 11, 11);
- else if (ch = OMAP_DSS_CHANNEL_DIGIT)
- *type = REG_GET(DISPC_CONFIG, 13, 13);
- else if (ch = OMAP_DSS_CHANNEL_LCD2)
- *type = REG_GET(DISPC_CONFIG2, 11, 11);
- else
- BUG();
- }
-
- if (trans_key)
- *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
-}
-
static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
{
if (ch = OMAP_DSS_CHANNEL_LCD)
@@ -2231,39 +2199,6 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
}
-bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch)
-{
- bool enabled;
-
- if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
- return false;
-
- if (ch = OMAP_DSS_CHANNEL_LCD)
- enabled = REG_GET(DISPC_CONFIG, 18, 18);
- else if (ch = OMAP_DSS_CHANNEL_DIGIT)
- enabled = REG_GET(DISPC_CONFIG, 19, 19);
- else
- BUG();
-
- return enabled;
-}
-
-bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
-{
- bool enabled;
-
- if (ch = OMAP_DSS_CHANNEL_LCD)
- enabled = REG_GET(DISPC_CONFIG, 10, 10);
- else if (ch = OMAP_DSS_CHANNEL_DIGIT)
- enabled = REG_GET(DISPC_CONFIG, 12, 12);
- else if (ch = OMAP_DSS_CHANNEL_LCD2)
- enabled = REG_GET(DISPC_CONFIG2, 10, 10);
- else
- BUG();
-
- return enabled;
-}
-
void dispc_mgr_setup(enum omap_channel channel,
struct omap_overlay_manager_info *info)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 3e01bba..2d6081e 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -415,12 +415,6 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
enum omap_lcd_display_type type);
-u32 dispc_mgr_get_default_color(enum omap_channel channel);
-void dispc_mgr_get_trans_key(enum omap_channel ch,
- enum omap_dss_trans_key_type *type,
- u32 *trans_key);
-bool dispc_mgr_trans_key_enabled(enum omap_channel ch);
-bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch);
void dispc_mgr_set_lcd_timings(enum omap_channel channel,
struct omap_video_timings *timings);
void dispc_mgr_set_pol_freq(enum omap_channel channel,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 16/65] OMAPDSS: remove unneeded dss_ovl_wait_for_go()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (14 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 15/65] OMAPDSS: DISPC: remove unused functions Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 17/65] OMAPDSS: add ovl/mgr_manual_update() helpers Tomi Valkeinen
` (48 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
There's an unnecessary wrapper function, dss_ovl_wait_for_go(), which
does nothing else than call dss_mgr_wait_for_go_ovl(). The
dss_ovl_wait_for_go() function can be removed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/overlay.c | 7 +------
1 files changed, 1 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index d15b826..0ab14fa 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -548,11 +548,6 @@ static void dss_ovl_get_overlay_info(struct omap_overlay *ovl,
*info = ovl->info;
}
-static int dss_ovl_wait_for_go(struct omap_overlay *ovl)
-{
- return dss_mgr_wait_for_go_ovl(ovl);
-}
-
static int omap_dss_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr)
{
@@ -689,7 +684,7 @@ void dss_init_overlays(struct platform_device *pdev)
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->wait_for_go = &dss_ovl_wait_for_go;
+ ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
ovl->supported_modes --
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 17/65] OMAPDSS: add ovl/mgr_manual_update() helpers
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (15 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 16/65] OMAPDSS: remove unneeded dss_ovl_wait_for_go() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 18/65] OMAPDSS: split omap_dss_mgr_apply() to smaller funcs Tomi Valkeinen
` (47 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Add helper functions ovl_manual_update() and mgr_manual_update() which
return whether the overlay or manager is used with a manual update
display.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/manager.c | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index fc19f01..e8838d3 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -538,7 +538,15 @@ static struct {
bool irq_enabled;
} dss_cache;
+static bool ovl_manual_update(struct omap_overlay *ovl)
+{
+ return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+}
+static bool mgr_manual_update(struct omap_overlay_manager *mgr)
+{
+ return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+}
static int omap_dss_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev)
@@ -627,7 +635,7 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
+ if (mgr_manual_update(mgr))
return 0;
if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
@@ -696,7 +704,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
+ if (ovl_manual_update(ovl))
return 0;
if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
@@ -1047,8 +1055,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
/* Configure managers */
list_for_each_entry(mgr, &manager_list, list) {
- struct omap_dss_device *dssdev;
-
mc = &dss_cache.manager_cache[mgr->id];
if (mgr->device_changed) {
@@ -1062,14 +1068,11 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
if (!mgr->device)
continue;
- dssdev = mgr->device;
-
mgr->info_dirty = false;
mc->dirty = true;
mc->info = mgr->info;
- mc->manual_update - dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+ mc->manual_update = mgr_manual_update(mgr);
}
/* Configure overlay fifos */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 18/65] OMAPDSS: split omap_dss_mgr_apply() to smaller funcs
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (16 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 17/65] OMAPDSS: add ovl/mgr_manual_update() helpers Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 19/65] OMAPDSS: apply affects only one overlay manager Tomi Valkeinen
` (46 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Split omap_dss_mgr_apply() into smaller functions for clarity.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/manager.c | 168 +++++++++++++++++++++----------------
1 files changed, 94 insertions(+), 74 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e8838d3..3aca2b4 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -993,107 +993,92 @@ end:
spin_unlock(&dss_cache.lock);
}
-static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
{
struct overlay_cache_data *oc;
- struct manager_cache_data *mc;
- int i;
- struct omap_overlay *ovl;
- unsigned long flags;
- int r;
-
- DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
+ struct omap_dss_device *dssdev;
- r = dispc_runtime_get();
- if (r)
- return r;
+ oc = &dss_cache.overlay_cache[ovl->id];
- spin_lock_irqsave(&dss_cache.lock, flags);
+ if (ovl->manager_changed) {
+ ovl->manager_changed = false;
+ ovl->info_dirty = true;
+ }
- /* Configure overlays */
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
- struct omap_dss_device *dssdev;
+ if (!overlay_enabled(ovl)) {
+ if (oc->enabled) {
+ oc->enabled = false;
+ oc->dirty = true;
+ }
+ return 0;
+ }
- ovl = omap_dss_get_overlay(i);
+ if (!ovl->info_dirty)
+ return 0;
- oc = &dss_cache.overlay_cache[ovl->id];
+ dssdev = ovl->manager->device;
- if (ovl->manager_changed) {
- ovl->manager_changed = false;
- ovl->info_dirty = true;
+ if (dss_check_overlay(ovl, dssdev)) {
+ if (oc->enabled) {
+ oc->enabled = false;
+ oc->dirty = true;
}
+ return -EINVAL;
+ }
- if (!overlay_enabled(ovl)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
- }
- continue;
- }
+ ovl->info_dirty = false;
+ oc->dirty = true;
+ oc->info = ovl->info;
- if (!ovl->info_dirty)
- continue;
+ oc->channel = ovl->manager->id;
- dssdev = ovl->manager->device;
+ oc->enabled = true;
- if (dss_check_overlay(ovl, dssdev)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
- }
- continue;
- }
+ return 0;
+}
- ovl->info_dirty = false;
- oc->dirty = true;
- oc->info = ovl->info;
+static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
+{
+ struct manager_cache_data *mc;
- oc->channel = ovl->manager->id;
+ mc = &dss_cache.manager_cache[mgr->id];
- oc->enabled = true;
+ if (mgr->device_changed) {
+ mgr->device_changed = false;
+ mgr->info_dirty = true;
}
- /* Configure managers */
- list_for_each_entry(mgr, &manager_list, list) {
- mc = &dss_cache.manager_cache[mgr->id];
-
- if (mgr->device_changed) {
- mgr->device_changed = false;
- mgr->info_dirty = true;
- }
+ if (!mgr->info_dirty)
+ return;
- if (!mgr->info_dirty)
- continue;
+ if (!mgr->device)
+ return;
- if (!mgr->device)
- continue;
+ mgr->info_dirty = false;
+ mc->dirty = true;
+ mc->info = mgr->info;
- mgr->info_dirty = false;
- mc->dirty = true;
- mc->info = mgr->info;
-
- mc->manual_update = mgr_manual_update(mgr);
- }
-
- /* Configure overlay fifos */
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
- struct omap_dss_device *dssdev;
- u32 size, burst_size;
+ mc->manual_update = mgr_manual_update(mgr);
+}
- ovl = omap_dss_get_overlay(i);
+static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
+{
+ struct overlay_cache_data *oc;
+ struct omap_dss_device *dssdev;
+ u32 size, burst_size;
- oc = &dss_cache.overlay_cache[ovl->id];
+ oc = &dss_cache.overlay_cache[ovl->id];
- if (!oc->enabled)
- continue;
+ if (!oc->enabled)
+ return;
- dssdev = ovl->manager->device;
+ dssdev = ovl->manager->device;
- size = dispc_ovl_get_fifo_size(ovl->id);
+ size = dispc_ovl_get_fifo_size(ovl->id);
- burst_size = dispc_ovl_get_burst_size(ovl->id);
+ burst_size = dispc_ovl_get_burst_size(ovl->id);
- switch (dssdev->type) {
+ switch (dssdev->type) {
case OMAP_DISPLAY_TYPE_DPI:
case OMAP_DISPLAY_TYPE_DBI:
case OMAP_DISPLAY_TYPE_SDI:
@@ -1112,7 +1097,42 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
#endif
default:
BUG();
- }
+ }
+}
+
+static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+{
+ int i, r;
+ unsigned long flags;
+
+ DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
+
+ r = dispc_runtime_get();
+ if (r)
+ return r;
+
+ spin_lock_irqsave(&dss_cache.lock, flags);
+
+ /* Configure overlays */
+ for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ struct omap_overlay *ovl;
+
+ ovl = omap_dss_get_overlay(i);
+
+ omap_dss_mgr_apply_ovl(ovl);
+ }
+
+ /* Configure managers */
+ list_for_each_entry(mgr, &manager_list, list)
+ omap_dss_mgr_apply_mgr(mgr);
+
+ /* Configure overlay fifos */
+ for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ struct omap_overlay *ovl;
+
+ ovl = omap_dss_get_overlay(i);
+
+ omap_dss_mgr_apply_ovl_fifos(ovl);
}
r = 0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 19/65] OMAPDSS: apply affects only one overlay manager
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (17 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 18/65] OMAPDSS: split omap_dss_mgr_apply() to smaller funcs Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 20/65] OMAPDSS: create apply.c Tomi Valkeinen
` (45 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
omap_dss_mgr_apply currently applies settings to all overlays and
overlay managers. The reason for this was to support cases where
configuration changes affecting multiple managers are made. However, the
current code doesn't support changing such configurations, so the
functionality is not needed.
Change the apply to affect only the manager given as an argument, and
the overlays attached to that manager.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/manager.c | 19 ++++++++++++-------
1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 3aca2b4..5c120ac 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -1114,23 +1114,28 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
spin_lock_irqsave(&dss_cache.lock, flags);
/* Configure overlays */
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ for (i = 0; i < mgr->num_overlays; ++i) {
struct omap_overlay *ovl;
- ovl = omap_dss_get_overlay(i);
+ ovl = mgr->overlays[i];
+
+ if (ovl->manager != mgr)
+ continue;
omap_dss_mgr_apply_ovl(ovl);
}
- /* Configure managers */
- list_for_each_entry(mgr, &manager_list, list)
- omap_dss_mgr_apply_mgr(mgr);
+ /* Configure manager */
+ omap_dss_mgr_apply_mgr(mgr);
/* Configure overlay fifos */
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ for (i = 0; i < mgr->num_overlays; ++i) {
struct omap_overlay *ovl;
- ovl = omap_dss_get_overlay(i);
+ ovl = mgr->overlays[i];
+
+ if (ovl->manager != mgr)
+ continue;
omap_dss_mgr_apply_ovl_fifos(ovl);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 20/65] OMAPDSS: create apply.c
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (18 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 19/65] OMAPDSS: apply affects only one overlay manager Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 21/65] OMAPDSS: hide manager's enable/disable() Tomi Valkeinen
` (44 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Create a new file, apply.c, and move code about handling the
apply-mechanism and configuration of the managers and overlays from
manager.c to apply.c.
Not all related code is moved in this patch, but only the core
apply/configure functions. The later patches move rest of the code from
overlay.c and manager.c, adding necessary locking at the same time.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/Makefile | 3 +-
drivers/video/omap2/dss/apply.c | 656 +++++++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/core.c | 2 +
drivers/video/omap2/dss/dss.h | 9 +-
drivers/video/omap2/dss/manager.c | 621 -----------------------------------
5 files changed, 667 insertions(+), 624 deletions(-)
create mode 100644 drivers/video/omap2/dss/apply.c
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index bd34ac5..8594522 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
-omapdss-y := core.o dss.o dss_features.o dispc.o display.o manager.o overlay.o
+omapdss-y := core.o dss.o dss_features.o dispc.o display.o manager.o overlay.o \
+ apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
new file mode 100644
index 0000000..32dc6e6
--- /dev/null
+++ b/drivers/video/omap2/dss/apply.c
@@ -0,0 +1,656 @@
+/*
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "APPLY"
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/jiffies.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+
+/*
+ * We have 4 levels of cache for the dispc settings. First two are in SW and
+ * the latter two in HW.
+ *
+ * +--------------------+
+ * |overlay/manager_info|
+ * +--------------------+
+ * v
+ * apply()
+ * v
+ * +--------------------+
+ * | dss_cache |
+ * +--------------------+
+ * v
+ * configure()
+ * v
+ * +--------------------+
+ * | shadow registers |
+ * +--------------------+
+ * v
+ * VFP or lcd/digit_enable
+ * v
+ * +--------------------+
+ * | registers |
+ * +--------------------+
+ */
+
+struct overlay_cache_data {
+ /* 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 enabled;
+
+ struct omap_overlay_info info;
+
+ enum omap_channel channel;
+
+ u32 fifo_low;
+ u32 fifo_high;
+};
+
+struct manager_cache_data {
+ /* 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;
+
+ struct omap_overlay_manager_info info;
+
+ bool manual_update;
+ bool do_manual_update;
+};
+
+static struct {
+ spinlock_t lock;
+ struct overlay_cache_data overlay_cache[MAX_DSS_OVERLAYS];
+ struct manager_cache_data manager_cache[MAX_DSS_MANAGERS];
+
+ bool irq_enabled;
+} dss_cache;
+
+void dss_apply_init(void)
+{
+ spin_lock_init(&dss_cache.lock);
+}
+
+static bool ovl_manual_update(struct omap_overlay *ovl)
+{
+ return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+}
+
+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);
+ struct manager_cache_data *mc;
+ u32 irq;
+ int r;
+ int i;
+ struct omap_dss_device *dssdev = mgr->device;
+
+ if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ if (mgr_manual_update(mgr))
+ return 0;
+
+ if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
+ || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
+ irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
+ } else {
+ irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
+ DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
+ }
+
+ mc = &dss_cache.manager_cache[mgr->id];
+ i = 0;
+ while (1) {
+ unsigned long flags;
+ bool shadow_dirty, dirty;
+
+ spin_lock_irqsave(&dss_cache.lock, flags);
+ dirty = mc->dirty;
+ shadow_dirty = mc->shadow_dirty;
+ spin_unlock_irqrestore(&dss_cache.lock, flags);
+
+ if (!dirty && !shadow_dirty) {
+ r = 0;
+ break;
+ }
+
+ /* 4 iterations is the worst case:
+ * 1 - initial iteration, dirty = true (between VFP and VSYNC)
+ * 2 - first VSYNC, dirty = true
+ * 3 - dirty = false, shadow_dirty = true
+ * 4 - shadow_dirty = false */
+ if (i++ = 3) {
+ DSSERR("mgr(%d)->wait_for_go() not finishing\n",
+ mgr->id);
+ r = 0;
+ break;
+ }
+
+ r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+ if (r = -ERESTARTSYS)
+ break;
+
+ if (r) {
+ DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
+ break;
+ }
+ }
+
+ return r;
+}
+
+int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
+{
+ unsigned long timeout = msecs_to_jiffies(500);
+ struct overlay_cache_data *oc;
+ struct omap_dss_device *dssdev;
+ u32 irq;
+ int r;
+ int i;
+
+ if (!ovl->manager)
+ return 0;
+
+ dssdev = ovl->manager->device;
+
+ if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ if (ovl_manual_update(ovl))
+ return 0;
+
+ if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
+ || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
+ irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
+ } else {
+ irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
+ DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
+ }
+
+ oc = &dss_cache.overlay_cache[ovl->id];
+ i = 0;
+ while (1) {
+ unsigned long flags;
+ bool shadow_dirty, dirty;
+
+ spin_lock_irqsave(&dss_cache.lock, flags);
+ dirty = oc->dirty;
+ shadow_dirty = oc->shadow_dirty;
+ spin_unlock_irqrestore(&dss_cache.lock, flags);
+
+ if (!dirty && !shadow_dirty) {
+ r = 0;
+ break;
+ }
+
+ /* 4 iterations is the worst case:
+ * 1 - initial iteration, dirty = true (between VFP and VSYNC)
+ * 2 - first VSYNC, dirty = true
+ * 3 - dirty = false, shadow_dirty = true
+ * 4 - shadow_dirty = false */
+ if (i++ = 3) {
+ DSSERR("ovl(%d)->wait_for_go() not finishing\n",
+ ovl->id);
+ r = 0;
+ break;
+ }
+
+ r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+ if (r = -ERESTARTSYS)
+ break;
+
+ if (r) {
+ DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
+ break;
+ }
+ }
+
+ return r;
+}
+
+static int configure_overlay(enum omap_plane plane)
+{
+ struct omap_overlay *ovl;
+ struct overlay_cache_data *c;
+ struct omap_overlay_info *oi;
+ bool ilace, replication;
+ int r;
+
+ DSSDBGF("%d", plane);
+
+ c = &dss_cache.overlay_cache[plane];
+ oi = &c->info;
+
+ if (!c->enabled) {
+ dispc_ovl_enable(plane, 0);
+ return 0;
+ }
+
+ ovl = omap_dss_get_overlay(plane);
+
+ replication = dss_use_replication(ovl->manager->device, oi->color_mode);
+
+ ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
+
+ dispc_ovl_set_channel_out(plane, c->channel);
+
+ r = dispc_ovl_setup(plane, oi, ilace, replication);
+ if (r) {
+ /* this shouldn't happen */
+ DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
+ dispc_ovl_enable(plane, 0);
+ return r;
+ }
+
+ dispc_ovl_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
+
+ dispc_ovl_enable(plane, 1);
+
+ return 0;
+}
+
+static void configure_manager(enum omap_channel channel)
+{
+ struct omap_overlay_manager_info *mi;
+
+ DSSDBGF("%d", channel);
+
+ /* picking info from the cache */
+ mi = &dss_cache.manager_cache[channel].info;
+
+ dispc_mgr_setup(channel, mi);
+}
+
+/* configure_dispc() 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 configure_dispc(void)
+{
+ struct overlay_cache_data *oc;
+ struct manager_cache_data *mc;
+ const int num_ovls = dss_feat_get_num_ovls();
+ 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 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) {
+ oc = &dss_cache.overlay_cache[i];
+ mc = &dss_cache.manager_cache[oc->channel];
+
+ if (!oc->dirty)
+ continue;
+
+ if (mc->manual_update && !mc->do_manual_update)
+ continue;
+
+ if (mgr_busy[oc->channel]) {
+ busy = true;
+ continue;
+ }
+
+ r = configure_overlay(i);
+ if (r)
+ DSSERR("configure_overlay %d failed\n", i);
+
+ oc->dirty = false;
+ oc->shadow_dirty = true;
+ mgr_go[oc->channel] = true;
+ }
+
+ /* Commit manager settings */
+ for (i = 0; i < num_mgrs; ++i) {
+ mc = &dss_cache.manager_cache[i];
+
+ if (!mc->dirty)
+ continue;
+
+ if (mc->manual_update && !mc->do_manual_update)
+ continue;
+
+ if (mgr_busy[i]) {
+ busy = true;
+ continue;
+ }
+
+ configure_manager(i);
+ mc->dirty = false;
+ mc->shadow_dirty = true;
+ mgr_go[i] = true;
+ }
+
+ /* set GO */
+ for (i = 0; i < num_mgrs; ++i) {
+ mc = &dss_cache.manager_cache[i];
+
+ if (!mgr_go[i])
+ 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 (!mc->manual_update)
+ dispc_mgr_go(i);
+ }
+
+ if (busy)
+ r = 1;
+ else
+ r = 0;
+
+ return r;
+}
+
+void dss_start_update(struct omap_overlay_manager *mgr)
+{
+ struct manager_cache_data *mc;
+ struct overlay_cache_data *oc;
+ const int num_ovls = dss_feat_get_num_ovls();
+ const int num_mgrs = dss_feat_get_num_mgrs();
+ int i;
+
+ mc = &dss_cache.manager_cache[mgr->id];
+
+ mc->do_manual_update = true;
+ configure_dispc();
+ mc->do_manual_update = false;
+
+ for (i = 0; i < num_ovls; ++i) {
+ oc = &dss_cache.overlay_cache[i];
+ if (oc->channel != mgr->id)
+ continue;
+
+ oc->shadow_dirty = false;
+ }
+
+ for (i = 0; i < num_mgrs; ++i) {
+ mc = &dss_cache.manager_cache[i];
+ if (mgr->id != i)
+ continue;
+
+ mc->shadow_dirty = false;
+ }
+
+ mgr->enable(mgr);
+}
+
+static void dss_apply_irq_handler(void *data, u32 mask)
+{
+ struct manager_cache_data *mc;
+ struct overlay_cache_data *oc;
+ 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];
+ u32 irq_mask;
+
+ for (i = 0; i < num_mgrs; i++)
+ mgr_busy[i] = dispc_mgr_go_busy(i);
+
+ spin_lock(&dss_cache.lock);
+
+ for (i = 0; i < num_ovls; ++i) {
+ oc = &dss_cache.overlay_cache[i];
+ if (!mgr_busy[oc->channel])
+ oc->shadow_dirty = false;
+ }
+
+ for (i = 0; i < num_mgrs; ++i) {
+ mc = &dss_cache.manager_cache[i];
+ if (!mgr_busy[i])
+ mc->shadow_dirty = false;
+ }
+
+ r = configure_dispc();
+ if (r = 1)
+ goto end;
+
+ /* re-read busy flags */
+ for (i = 0; i < num_mgrs; i++)
+ mgr_busy[i] = 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])
+ goto end;
+ }
+
+ irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
+ DISPC_IRQ_EVSYNC_EVEN;
+ if (dss_has_feature(FEAT_MGR_LCD2))
+ irq_mask |= DISPC_IRQ_VSYNC2;
+
+ omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
+ dss_cache.irq_enabled = false;
+
+end:
+ spin_unlock(&dss_cache.lock);
+}
+
+static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
+{
+ struct overlay_cache_data *oc;
+ struct omap_dss_device *dssdev;
+
+ oc = &dss_cache.overlay_cache[ovl->id];
+
+ if (ovl->manager_changed) {
+ ovl->manager_changed = false;
+ ovl->info_dirty = true;
+ }
+
+ if (!overlay_enabled(ovl)) {
+ if (oc->enabled) {
+ oc->enabled = false;
+ oc->dirty = true;
+ }
+ return 0;
+ }
+
+ if (!ovl->info_dirty)
+ return 0;
+
+ dssdev = ovl->manager->device;
+
+ if (dss_check_overlay(ovl, dssdev)) {
+ if (oc->enabled) {
+ oc->enabled = false;
+ oc->dirty = true;
+ }
+ return -EINVAL;
+ }
+
+ ovl->info_dirty = false;
+ oc->dirty = true;
+ oc->info = ovl->info;
+
+ oc->channel = ovl->manager->id;
+
+ oc->enabled = true;
+
+ return 0;
+}
+
+static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
+{
+ struct manager_cache_data *mc;
+
+ mc = &dss_cache.manager_cache[mgr->id];
+
+ if (mgr->device_changed) {
+ mgr->device_changed = false;
+ mgr->info_dirty = true;
+ }
+
+ if (!mgr->info_dirty)
+ return;
+
+ if (!mgr->device)
+ return;
+
+ mgr->info_dirty = false;
+ mc->dirty = true;
+ mc->info = mgr->info;
+
+ mc->manual_update = mgr_manual_update(mgr);
+}
+
+static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
+{
+ struct overlay_cache_data *oc;
+ struct omap_dss_device *dssdev;
+ u32 size, burst_size;
+
+ oc = &dss_cache.overlay_cache[ovl->id];
+
+ if (!oc->enabled)
+ return;
+
+ dssdev = ovl->manager->device;
+
+ size = dispc_ovl_get_fifo_size(ovl->id);
+
+ burst_size = dispc_ovl_get_burst_size(ovl->id);
+
+ switch (dssdev->type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+ case OMAP_DISPLAY_TYPE_DBI:
+ case OMAP_DISPLAY_TYPE_SDI:
+ case OMAP_DISPLAY_TYPE_VENC:
+ case OMAP_DISPLAY_TYPE_HDMI:
+ default_get_overlay_fifo_thresholds(ovl->id, size,
+ burst_size, &oc->fifo_low,
+ &oc->fifo_high);
+ break;
+#ifdef CONFIG_OMAP2_DSS_DSI
+ case OMAP_DISPLAY_TYPE_DSI:
+ dsi_get_overlay_fifo_thresholds(ovl->id, size,
+ burst_size, &oc->fifo_low,
+ &oc->fifo_high);
+ break;
+#endif
+ default:
+ BUG();
+ }
+}
+
+int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+{
+ int i, r;
+ unsigned long flags;
+
+ DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
+
+ r = dispc_runtime_get();
+ if (r)
+ return r;
+
+ spin_lock_irqsave(&dss_cache.lock, flags);
+
+ /* Configure overlays */
+ for (i = 0; i < mgr->num_overlays; ++i) {
+ struct omap_overlay *ovl;
+
+ ovl = mgr->overlays[i];
+
+ if (ovl->manager != mgr)
+ continue;
+
+ omap_dss_mgr_apply_ovl(ovl);
+ }
+
+ /* Configure manager */
+ omap_dss_mgr_apply_mgr(mgr);
+
+ /* Configure overlay fifos */
+ for (i = 0; i < mgr->num_overlays; ++i) {
+ struct omap_overlay *ovl;
+
+ ovl = mgr->overlays[i];
+
+ if (ovl->manager != mgr)
+ continue;
+
+ omap_dss_mgr_apply_ovl_fifos(ovl);
+ }
+
+ r = 0;
+ if (!dss_cache.irq_enabled) {
+ u32 mask;
+
+ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
+ DISPC_IRQ_EVSYNC_EVEN;
+ if (dss_has_feature(FEAT_MGR_LCD2))
+ mask |= DISPC_IRQ_VSYNC2;
+
+ r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
+
+ if (r)
+ DSSERR("failed to register apply isr\n");
+
+ dss_cache.irq_enabled = true;
+ }
+
+ configure_dispc();
+
+ spin_unlock_irqrestore(&dss_cache.lock, flags);
+
+ dispc_runtime_put();
+
+ return r;
+}
+
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 86ec12e..5c46430 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -178,6 +178,8 @@ static int omap_dss_probe(struct platform_device *pdev)
dss_features_init();
+ dss_apply_init();
+
dss_init_overlay_managers(pdev);
dss_init_overlays(pdev);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 2d6081e..6fbbee4 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -163,6 +163,13 @@ struct bus_type *dss_get_bus(void);
struct regulator *dss_get_vdds_dsi(void);
struct regulator *dss_get_vdds_sdi(void);
+/* apply */
+void dss_apply_init(void);
+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);
+
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
@@ -181,8 +188,6 @@ 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_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
-void dss_start_update(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 5c120ac..f9e691b 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -26,11 +26,9 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
@@ -469,85 +467,6 @@ static struct kobj_type manager_ktype = {
.default_attrs = manager_sysfs_attrs,
};
-/*
- * We have 4 levels of cache for the dispc settings. First two are in SW and
- * the latter two in HW.
- *
- * +--------------------+
- * |overlay/manager_info|
- * +--------------------+
- * v
- * apply()
- * v
- * +--------------------+
- * | dss_cache |
- * +--------------------+
- * v
- * configure()
- * v
- * +--------------------+
- * | shadow registers |
- * +--------------------+
- * v
- * VFP or lcd/digit_enable
- * v
- * +--------------------+
- * | registers |
- * +--------------------+
- */
-
-struct overlay_cache_data {
- /* 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 enabled;
-
- struct omap_overlay_info info;
-
- enum omap_channel channel;
-
- u32 fifo_low;
- u32 fifo_high;
-};
-
-struct manager_cache_data {
- /* 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;
-
- struct omap_overlay_manager_info info;
-
- bool manual_update;
- bool do_manual_update;
-};
-
-static struct {
- spinlock_t lock;
- struct overlay_cache_data overlay_cache[MAX_DSS_OVERLAYS];
- struct manager_cache_data manager_cache[MAX_DSS_MANAGERS];
-
- bool irq_enabled;
-} dss_cache;
-
-static bool ovl_manual_update(struct omap_overlay *ovl)
-{
- return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
-}
-
-static bool mgr_manual_update(struct omap_overlay_manager *mgr)
-{
- return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
-}
-
static int omap_dss_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev)
{
@@ -623,544 +542,6 @@ 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_mgr_wait_for_go(struct omap_overlay_manager *mgr)
-{
- unsigned long timeout = msecs_to_jiffies(500);
- struct manager_cache_data *mc;
- u32 irq;
- int r;
- int i;
- struct omap_dss_device *dssdev = mgr->device;
-
- if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
- return 0;
-
- if (mgr_manual_update(mgr))
- return 0;
-
- if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
- || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
- irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
- } else {
- irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
- DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
- }
-
- mc = &dss_cache.manager_cache[mgr->id];
- i = 0;
- while (1) {
- unsigned long flags;
- bool shadow_dirty, dirty;
-
- spin_lock_irqsave(&dss_cache.lock, flags);
- dirty = mc->dirty;
- shadow_dirty = mc->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- if (!dirty && !shadow_dirty) {
- r = 0;
- break;
- }
-
- /* 4 iterations is the worst case:
- * 1 - initial iteration, dirty = true (between VFP and VSYNC)
- * 2 - first VSYNC, dirty = true
- * 3 - dirty = false, shadow_dirty = true
- * 4 - shadow_dirty = false */
- if (i++ = 3) {
- DSSERR("mgr(%d)->wait_for_go() not finishing\n",
- mgr->id);
- r = 0;
- break;
- }
-
- r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
- if (r = -ERESTARTSYS)
- break;
-
- if (r) {
- DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
- break;
- }
- }
-
- return r;
-}
-
-int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
-{
- unsigned long timeout = msecs_to_jiffies(500);
- struct overlay_cache_data *oc;
- struct omap_dss_device *dssdev;
- u32 irq;
- int r;
- int i;
-
- if (!ovl->manager)
- return 0;
-
- dssdev = ovl->manager->device;
-
- if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
- return 0;
-
- if (ovl_manual_update(ovl))
- return 0;
-
- if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
- || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
- irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
- } else {
- irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
- DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
- }
-
- oc = &dss_cache.overlay_cache[ovl->id];
- i = 0;
- while (1) {
- unsigned long flags;
- bool shadow_dirty, dirty;
-
- spin_lock_irqsave(&dss_cache.lock, flags);
- dirty = oc->dirty;
- shadow_dirty = oc->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- if (!dirty && !shadow_dirty) {
- r = 0;
- break;
- }
-
- /* 4 iterations is the worst case:
- * 1 - initial iteration, dirty = true (between VFP and VSYNC)
- * 2 - first VSYNC, dirty = true
- * 3 - dirty = false, shadow_dirty = true
- * 4 - shadow_dirty = false */
- if (i++ = 3) {
- DSSERR("ovl(%d)->wait_for_go() not finishing\n",
- ovl->id);
- r = 0;
- break;
- }
-
- r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
- if (r = -ERESTARTSYS)
- break;
-
- if (r) {
- DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
- break;
- }
- }
-
- return r;
-}
-
-static int overlay_enabled(struct omap_overlay *ovl)
-{
- return ovl->info.enabled && ovl->manager && ovl->manager->device;
-}
-
-static int configure_overlay(enum omap_plane plane)
-{
- struct omap_overlay *ovl;
- struct overlay_cache_data *c;
- struct omap_overlay_info *oi;
- bool ilace, replication;
- int r;
-
- DSSDBGF("%d", plane);
-
- c = &dss_cache.overlay_cache[plane];
- oi = &c->info;
-
- if (!c->enabled) {
- dispc_ovl_enable(plane, 0);
- return 0;
- }
-
- ovl = omap_dss_get_overlay(plane);
-
- replication = dss_use_replication(ovl->manager->device, oi->color_mode);
-
- ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
-
- dispc_ovl_set_channel_out(plane, c->channel);
-
- r = dispc_ovl_setup(plane, oi, ilace, replication);
- if (r) {
- /* this shouldn't happen */
- DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
- dispc_ovl_enable(plane, 0);
- return r;
- }
-
- dispc_ovl_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
-
- dispc_ovl_enable(plane, 1);
-
- return 0;
-}
-
-static void configure_manager(enum omap_channel channel)
-{
- struct omap_overlay_manager_info *mi;
-
- DSSDBGF("%d", channel);
-
- /* picking info from the cache */
- mi = &dss_cache.manager_cache[channel].info;
-
- dispc_mgr_setup(channel, mi);
-}
-
-/* configure_dispc() 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 configure_dispc(void)
-{
- struct overlay_cache_data *oc;
- struct manager_cache_data *mc;
- const int num_ovls = dss_feat_get_num_ovls();
- 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 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) {
- oc = &dss_cache.overlay_cache[i];
- mc = &dss_cache.manager_cache[oc->channel];
-
- if (!oc->dirty)
- continue;
-
- if (mc->manual_update && !mc->do_manual_update)
- continue;
-
- if (mgr_busy[oc->channel]) {
- busy = true;
- continue;
- }
-
- r = configure_overlay(i);
- if (r)
- DSSERR("configure_overlay %d failed\n", i);
-
- oc->dirty = false;
- oc->shadow_dirty = true;
- mgr_go[oc->channel] = true;
- }
-
- /* Commit manager settings */
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
-
- if (!mc->dirty)
- continue;
-
- if (mc->manual_update && !mc->do_manual_update)
- continue;
-
- if (mgr_busy[i]) {
- busy = true;
- continue;
- }
-
- configure_manager(i);
- mc->dirty = false;
- mc->shadow_dirty = true;
- mgr_go[i] = true;
- }
-
- /* set GO */
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
-
- if (!mgr_go[i])
- 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 (!mc->manual_update)
- dispc_mgr_go(i);
- }
-
- if (busy)
- r = 1;
- else
- r = 0;
-
- return r;
-}
-
-void dss_start_update(struct omap_overlay_manager *mgr)
-{
- struct manager_cache_data *mc;
- struct overlay_cache_data *oc;
- const int num_ovls = dss_feat_get_num_ovls();
- const int num_mgrs = dss_feat_get_num_mgrs();
- int i;
-
- mc = &dss_cache.manager_cache[mgr->id];
-
- mc->do_manual_update = true;
- configure_dispc();
- mc->do_manual_update = false;
-
- for (i = 0; i < num_ovls; ++i) {
- oc = &dss_cache.overlay_cache[i];
- if (oc->channel != mgr->id)
- continue;
-
- oc->shadow_dirty = false;
- }
-
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
- if (mgr->id != i)
- continue;
-
- mc->shadow_dirty = false;
- }
-
- mgr->enable(mgr);
-}
-
-static void dss_apply_irq_handler(void *data, u32 mask)
-{
- struct manager_cache_data *mc;
- struct overlay_cache_data *oc;
- 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];
- u32 irq_mask;
-
- for (i = 0; i < num_mgrs; i++)
- mgr_busy[i] = dispc_mgr_go_busy(i);
-
- spin_lock(&dss_cache.lock);
-
- for (i = 0; i < num_ovls; ++i) {
- oc = &dss_cache.overlay_cache[i];
- if (!mgr_busy[oc->channel])
- oc->shadow_dirty = false;
- }
-
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
- if (!mgr_busy[i])
- mc->shadow_dirty = false;
- }
-
- r = configure_dispc();
- if (r = 1)
- goto end;
-
- /* re-read busy flags */
- for (i = 0; i < num_mgrs; i++)
- mgr_busy[i] = 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])
- goto end;
- }
-
- irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- irq_mask |= DISPC_IRQ_VSYNC2;
-
- omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
- dss_cache.irq_enabled = false;
-
-end:
- spin_unlock(&dss_cache.lock);
-}
-
-static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
-{
- struct overlay_cache_data *oc;
- struct omap_dss_device *dssdev;
-
- oc = &dss_cache.overlay_cache[ovl->id];
-
- if (ovl->manager_changed) {
- ovl->manager_changed = false;
- ovl->info_dirty = true;
- }
-
- if (!overlay_enabled(ovl)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
- }
- return 0;
- }
-
- if (!ovl->info_dirty)
- return 0;
-
- dssdev = ovl->manager->device;
-
- if (dss_check_overlay(ovl, dssdev)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
- }
- return -EINVAL;
- }
-
- ovl->info_dirty = false;
- oc->dirty = true;
- oc->info = ovl->info;
-
- oc->channel = ovl->manager->id;
-
- oc->enabled = true;
-
- return 0;
-}
-
-static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
-{
- struct manager_cache_data *mc;
-
- mc = &dss_cache.manager_cache[mgr->id];
-
- if (mgr->device_changed) {
- mgr->device_changed = false;
- mgr->info_dirty = true;
- }
-
- if (!mgr->info_dirty)
- return;
-
- if (!mgr->device)
- return;
-
- mgr->info_dirty = false;
- mc->dirty = true;
- mc->info = mgr->info;
-
- mc->manual_update = mgr_manual_update(mgr);
-}
-
-static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
-{
- struct overlay_cache_data *oc;
- struct omap_dss_device *dssdev;
- u32 size, burst_size;
-
- oc = &dss_cache.overlay_cache[ovl->id];
-
- if (!oc->enabled)
- return;
-
- dssdev = ovl->manager->device;
-
- size = dispc_ovl_get_fifo_size(ovl->id);
-
- burst_size = dispc_ovl_get_burst_size(ovl->id);
-
- switch (dssdev->type) {
- case OMAP_DISPLAY_TYPE_DPI:
- case OMAP_DISPLAY_TYPE_DBI:
- case OMAP_DISPLAY_TYPE_SDI:
- case OMAP_DISPLAY_TYPE_VENC:
- case OMAP_DISPLAY_TYPE_HDMI:
- default_get_overlay_fifo_thresholds(ovl->id, size,
- burst_size, &oc->fifo_low,
- &oc->fifo_high);
- break;
-#ifdef CONFIG_OMAP2_DSS_DSI
- case OMAP_DISPLAY_TYPE_DSI:
- dsi_get_overlay_fifo_thresholds(ovl->id, size,
- burst_size, &oc->fifo_low,
- &oc->fifo_high);
- break;
-#endif
- default:
- BUG();
- }
-}
-
-static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
-{
- int i, r;
- unsigned long flags;
-
- DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
-
- r = dispc_runtime_get();
- if (r)
- return r;
-
- spin_lock_irqsave(&dss_cache.lock, flags);
-
- /* Configure overlays */
- for (i = 0; i < mgr->num_overlays; ++i) {
- struct omap_overlay *ovl;
-
- ovl = mgr->overlays[i];
-
- if (ovl->manager != mgr)
- continue;
-
- omap_dss_mgr_apply_ovl(ovl);
- }
-
- /* Configure manager */
- omap_dss_mgr_apply_mgr(mgr);
-
- /* Configure overlay fifos */
- for (i = 0; i < mgr->num_overlays; ++i) {
- struct omap_overlay *ovl;
-
- ovl = mgr->overlays[i];
-
- if (ovl->manager != mgr)
- continue;
-
- omap_dss_mgr_apply_ovl_fifos(ovl);
- }
-
- r = 0;
- if (!dss_cache.irq_enabled) {
- u32 mask;
-
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- mask |= DISPC_IRQ_VSYNC2;
-
- r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
- dss_cache.irq_enabled = true;
- }
- configure_dispc();
-
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- dispc_runtime_put();
-
- return r;
-}
-
static int dss_check_manager(struct omap_overlay_manager *mgr)
{
if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
@@ -1226,8 +607,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
{
int i, r;
- spin_lock_init(&dss_cache.lock);
-
INIT_LIST_HEAD(&manager_list);
num_managers = 0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 21/65] OMAPDSS: hide manager's enable/disable()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (19 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 20/65] OMAPDSS: create apply.c Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 22/65] OMAPDSS: APPLY: track whether a manager is enabled Tomi Valkeinen
` (43 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
omap_overlay_manager struct contains enable() and disable() functions.
However, these are only meant to be used from inside omapdss, and thus
it's bad to expose the functions.
This patch adds dss_mgr_enable() and dss_mgr_disable() functions to
apply.c, which handle enabling and disabling the output.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 12 +++++++++++-
drivers/video/omap2/dss/dpi.c | 4 ++--
drivers/video/omap2/dss/dsi.c | 4 ++--
drivers/video/omap2/dss/dss.h | 2 ++
drivers/video/omap2/dss/hdmi.c | 6 +++---
drivers/video/omap2/dss/manager.c | 15 ---------------
drivers/video/omap2/dss/sdi.c | 4 ++--
drivers/video/omap2/dss/venc.c | 4 ++--
include/video/omapdss.h | 3 ---
9 files changed, 24 insertions(+), 30 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 32dc6e6..ebc0ae1 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -424,7 +424,7 @@ void dss_start_update(struct omap_overlay_manager *mgr)
mc->shadow_dirty = false;
}
- mgr->enable(mgr);
+ dispc_mgr_enable(mgr->id, true);
}
static void dss_apply_irq_handler(void *data, u32 mask)
@@ -654,3 +654,13 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
return r;
}
+void dss_mgr_enable(struct omap_overlay_manager *mgr)
+{
+ dispc_mgr_enable(mgr->id, true);
+}
+
+void dss_mgr_disable(struct omap_overlay_manager *mgr)
+{
+ dispc_mgr_enable(mgr->id, false);
+}
+
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 976ac23..79c4df3 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -223,7 +223,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
mdelay(2);
- dssdev->manager->enable(dssdev->manager);
+ dss_mgr_enable(dssdev->manager);
return 0;
@@ -249,7 +249,7 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
if (dpi_use_dsi_pll(dssdev)) {
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index e5a2dcc..08d3de90 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3976,7 +3976,7 @@ int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel)
dsi_vc_enable(dsidev, channel, true);
dsi_if_enable(dsidev, true);
- dssdev->manager->enable(dssdev->manager);
+ dss_mgr_enable(dssdev->manager);
return 0;
}
@@ -3995,7 +3995,7 @@ void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel)
dsi_vc_enable(dsidev, channel, true);
dsi_if_enable(dsidev, true);
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
}
EXPORT_SYMBOL(dsi_video_mode_disable);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6fbbee4..66fed79 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -169,6 +169,8 @@ 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);
/* display */
int dss_suspend_all_devices(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index c56378c..e245a2b 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -333,7 +333,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
if (r)
return r;
- dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
+ dss_mgr_disable(dssdev->manager);
p = &dssdev->panel.timings;
@@ -387,7 +387,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
- dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
+ dss_mgr_enable(dssdev->manager);
return 0;
err:
@@ -397,7 +397,7 @@ err:
static void hdmi_power_off(struct omap_dss_device *dssdev)
{
- dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
+ dss_mgr_disable(dssdev->manager);
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index f9e691b..780a307 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -585,18 +585,6 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
*info = mgr->info;
}
-static int dss_mgr_enable(struct omap_overlay_manager *mgr)
-{
- dispc_mgr_enable(mgr->id, 1);
- return 0;
-}
-
-static int dss_mgr_disable(struct omap_overlay_manager *mgr)
-{
- dispc_mgr_enable(mgr->id, 0);
- return 0;
-}
-
static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
{
++num_managers;
@@ -640,9 +628,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->wait_for_go = &dss_mgr_wait_for_go;
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
- mgr->enable = &dss_mgr_enable;
- mgr->disable = &dss_mgr_disable;
-
mgr->caps = 0;
mgr->supported_displays dss_feat_get_supported_displays(mgr->id);
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 40305ad..02da8be 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -123,7 +123,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
goto err_sdi_enable;
mdelay(2);
- dssdev->manager->enable(dssdev->manager);
+ dss_mgr_enable(dssdev->manager);
return 0;
@@ -145,7 +145,7 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
{
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
dss_sdi_disable();
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7533458..101fcd7 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -447,7 +447,7 @@ static void venc_power_on(struct omap_dss_device *dssdev)
if (dssdev->platform_enable)
dssdev->platform_enable(dssdev);
- dssdev->manager->enable(dssdev->manager);
+ dss_mgr_enable(dssdev->manager);
}
static void venc_power_off(struct omap_dss_device *dssdev)
@@ -455,7 +455,7 @@ static void venc_power_off(struct omap_dss_device *dssdev)
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 60bf426..04741cd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -448,9 +448,6 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr);
int (*wait_for_go)(struct omap_overlay_manager *mgr);
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
-
- int (*enable)(struct omap_overlay_manager *mgr);
- int (*disable)(struct omap_overlay_manager *mgr);
};
struct omap_dss_device {
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 22/65] OMAPDSS: APPLY: track whether a manager is enabled
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (20 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 21/65] OMAPDSS: hide manager's enable/disable() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 23/65] OMAPDSS: APPLY: skip isr register and config for manual update displays Tomi Valkeinen
` (42 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Add "enabled" field to struct omap_overlay_manager, which tells if the
output is enabled or not. This will be used in apply.c in the following
patches.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 2 ++
include/video/omapdss.h | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index ebc0ae1..9af5809 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -657,10 +657,12 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
void dss_mgr_enable(struct omap_overlay_manager *mgr)
{
dispc_mgr_enable(mgr->id, true);
+ mgr->enabled = true;
}
void dss_mgr_disable(struct omap_overlay_manager *mgr)
{
dispc_mgr_enable(mgr->id, false);
+ mgr->enabled = false;
}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 04741cd..d61efc3 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -432,6 +432,8 @@ 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 [flat|nested] 91+ messages in thread
* [PATCH 23/65] OMAPDSS: APPLY: skip isr register and config for manual update displays
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (21 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 22/65] OMAPDSS: APPLY: track whether a manager is enabled Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 24/65] OMAPDSS: APPLY: skip isr register and config for disabled displays Tomi Valkeinen
` (41 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
The mechanism to cache manager and overlay settings and configure them
into the HW registers in VSYNC is meant only for auto-update displays,
as it doesn't make sense (and doesn't work) for manual-update displays.
This patchs adds a check so that we skip the above for manual update
displays.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 27 +++++++++++++++------------
1 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 9af5809..04f3ff5 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -629,23 +629,26 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
}
r = 0;
- if (!dss_cache.irq_enabled) {
- u32 mask;
+ if (!mgr_manual_update(mgr)) {
+ if (!dss_cache.irq_enabled) {
+ u32 mask;
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- mask |= DISPC_IRQ_VSYNC2;
+ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
+ DISPC_IRQ_EVSYNC_EVEN;
+ if (dss_has_feature(FEAT_MGR_LCD2))
+ mask |= DISPC_IRQ_VSYNC2;
- r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
+ r = omap_dispc_register_isr(dss_apply_irq_handler,
+ NULL, mask);
- if (r)
- DSSERR("failed to register apply isr\n");
+ if (r)
+ DSSERR("failed to register apply isr\n");
- dss_cache.irq_enabled = true;
- }
+ dss_cache.irq_enabled = true;
+ }
- configure_dispc();
+ configure_dispc();
+ }
spin_unlock_irqrestore(&dss_cache.lock, flags);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 24/65] OMAPDSS: APPLY: skip isr register and config for disabled displays
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (22 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 23/65] OMAPDSS: APPLY: skip isr register and config for manual update displays Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 25/65] OMAPDSS: APPLY: cleanup dss_start_update Tomi Valkeinen
` (40 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
There's no need to register the vsync ISR and configure the hardware if
the overlay manager is disabled, so this patch adds a check for disabled
managers to the omap_dss_mgr_apply() function.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 04f3ff5..cf68c9e 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -629,7 +629,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
}
r = 0;
- if (!mgr_manual_update(mgr)) {
+ if (mgr->enabled && !mgr_manual_update(mgr)) {
if (!dss_cache.irq_enabled) {
u32 mask;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 25/65] OMAPDSS: APPLY: cleanup dss_start_update
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (23 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 24/65] OMAPDSS: APPLY: skip isr register and config for disabled displays Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 26/65] OMAPDSS: store overlays in an array Tomi Valkeinen
` (39 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
dss_start_update() has a loop, of which sole purpose is to find the
manager used for this update. The whole loop is extra, as we already
know the manager.
Remove the loop.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 10 ++--------
1 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index cf68c9e..cfcf816 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -399,7 +399,6 @@ void dss_start_update(struct omap_overlay_manager *mgr)
struct manager_cache_data *mc;
struct overlay_cache_data *oc;
const int num_ovls = dss_feat_get_num_ovls();
- const int num_mgrs = dss_feat_get_num_mgrs();
int i;
mc = &dss_cache.manager_cache[mgr->id];
@@ -416,13 +415,8 @@ void dss_start_update(struct omap_overlay_manager *mgr)
oc->shadow_dirty = false;
}
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
- if (mgr->id != i)
- continue;
-
- mc->shadow_dirty = false;
- }
+ mc = &dss_cache.manager_cache[mgr->id];
+ mc->shadow_dirty = false;
dispc_mgr_enable(mgr->id, true);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 26/65] OMAPDSS: store overlays in an array
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (24 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 25/65] OMAPDSS: APPLY: cleanup dss_start_update Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 27/65] OMAPDSS: store managers " Tomi Valkeinen
` (38 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Overlays are stored in a linked list. There's no need for this list, as
an array would do just as fine.
This patch changes the code to use an array for overlays.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/overlay.c | 49 +++++++++++++------------------------
1 files changed, 17 insertions(+), 32 deletions(-)
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 0ab14fa..ccd6127 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -38,7 +38,7 @@
#include "dss_features.h"
static int num_overlays;
-static struct list_head overlay_list;
+static struct omap_overlay *overlays;
static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
{
@@ -610,24 +610,13 @@ EXPORT_SYMBOL(omap_dss_get_num_overlays);
struct omap_overlay *omap_dss_get_overlay(int num)
{
- int i = 0;
- struct omap_overlay *ovl;
+ if (num >= num_overlays)
+ return NULL;
- list_for_each_entry(ovl, &overlay_list, list) {
- if (i++ = num)
- return ovl;
- }
-
- return NULL;
+ return &overlays[num];
}
EXPORT_SYMBOL(omap_dss_get_overlay);
-static void omap_dss_add_overlay(struct omap_overlay *overlay)
-{
- ++num_overlays;
- list_add_tail(&overlay->list, &overlay_list);
-}
-
static struct omap_overlay *dispc_overlays[MAX_DSS_OVERLAYS];
void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
@@ -640,15 +629,15 @@ void dss_init_overlays(struct platform_device *pdev)
{
int i, r;
- INIT_LIST_HEAD(&overlay_list);
+ num_overlays = dss_feat_get_num_ovls();
- num_overlays = 0;
+ overlays = kzalloc(sizeof(struct omap_overlay) * num_overlays,
+ GFP_KERNEL);
- for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
- struct omap_overlay *ovl;
- ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
+ BUG_ON(overlays = NULL);
- BUG_ON(ovl = NULL);
+ for (i = 0; i < num_overlays; ++i) {
+ struct omap_overlay *ovl = &overlays[i];
switch (i) {
case 0:
@@ -690,15 +679,11 @@ void dss_init_overlays(struct platform_device *pdev)
ovl->supported_modes dss_feat_get_supported_color_modes(ovl->id);
- omap_dss_add_overlay(ovl);
-
r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
&pdev->dev.kobj, "overlay%d", i);
- if (r) {
+ if (r)
DSSERR("failed to create sysfs file\n");
- continue;
- }
dispc_overlays[i] = ovl;
}
@@ -765,17 +750,17 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
void dss_uninit_overlays(struct platform_device *pdev)
{
- struct omap_overlay *ovl;
+ int i;
+
+ for (i = 0; i < num_overlays; ++i) {
+ struct omap_overlay *ovl = &overlays[i];
- while (!list_empty(&overlay_list)) {
- ovl = list_first_entry(&overlay_list,
- struct omap_overlay, list);
- list_del(&ovl->list);
kobject_del(&ovl->kobj);
kobject_put(&ovl->kobj);
- kfree(ovl);
}
+ kfree(overlays);
+ overlays = NULL;
num_overlays = 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 27/65] OMAPDSS: store managers in an array
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (25 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 26/65] OMAPDSS: store overlays in an array Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 28/65] OMAPDSS: store overlays in a list for each manager Tomi Valkeinen
` (37 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Overlay managers are stored in a linked list. There's no need for this
list, as an array would do just as fine.
This patch changes the code to use an array for overlay managers.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/manager.c | 49 +++++++++++++------------------------
include/video/omapdss.h | 1 -
2 files changed, 17 insertions(+), 33 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 780a307..a08cc6e 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -34,7 +34,7 @@
#include "dss_features.h"
static int num_managers;
-static struct list_head manager_list;
+static struct omap_overlay_manager *managers;
static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
{
@@ -585,25 +585,19 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
*info = mgr->info;
}
-static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
-{
- ++num_managers;
- list_add_tail(&manager->list, &manager_list);
-}
-
int dss_init_overlay_managers(struct platform_device *pdev)
{
int i, r;
- INIT_LIST_HEAD(&manager_list);
+ num_managers = dss_feat_get_num_mgrs();
- num_managers = 0;
+ managers = kzalloc(sizeof(struct omap_overlay_manager) * num_managers,
+ GFP_KERNEL);
- for (i = 0; i < dss_feat_get_num_mgrs(); ++i) {
- struct omap_overlay_manager *mgr;
- mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+ BUG_ON(managers = NULL);
- BUG_ON(mgr = NULL);
+ for (i = 0; i < num_managers; ++i) {
+ struct omap_overlay_manager *mgr = &managers[i];
switch (i) {
case 0:
@@ -634,15 +628,11 @@ int dss_init_overlay_managers(struct platform_device *pdev)
dss_overlay_setup_dispc_manager(mgr);
- omap_dss_add_overlay_manager(mgr);
-
r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
&pdev->dev.kobj, "manager%d", i);
- if (r) {
+ if (r)
DSSERR("failed to create sysfs file\n");
- continue;
- }
}
return 0;
@@ -650,17 +640,17 @@ int dss_init_overlay_managers(struct platform_device *pdev)
void dss_uninit_overlay_managers(struct platform_device *pdev)
{
- struct omap_overlay_manager *mgr;
+ int i;
+
+ for (i = 0; i < num_managers; ++i) {
+ struct omap_overlay_manager *mgr = &managers[i];
- while (!list_empty(&manager_list)) {
- mgr = list_first_entry(&manager_list,
- struct omap_overlay_manager, list);
- list_del(&mgr->list);
kobject_del(&mgr->kobj);
kobject_put(&mgr->kobj);
- kfree(mgr);
}
+ kfree(managers);
+ managers = NULL;
num_managers = 0;
}
@@ -672,15 +662,10 @@ EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
{
- int i = 0;
- struct omap_overlay_manager *mgr;
-
- list_for_each_entry(mgr, &manager_list, list) {
- if (i++ = num)
- return mgr;
- }
+ if (num >= num_managers)
+ return NULL;
- return NULL;
+ return &managers[num];
}
EXPORT_SYMBOL(omap_dss_get_overlay_manager);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index d61efc3..fd5a96c 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -418,7 +418,6 @@ struct omap_overlay_manager_info {
struct omap_overlay_manager {
struct kobject kobj;
- struct list_head list;
/* static fields */
const char *name;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 28/65] OMAPDSS: store overlays in a list for each manager
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (26 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 27/65] OMAPDSS: store managers " Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 29/65] OMAPDSS: APPLY: separate vsync isr register/unregister Tomi Valkeinen
` (36 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Current way of handling overlay-manager links is a bit strange: each
manager has a static array, containing pointers to all the overlays
(even those used by other managers). The overlays contain a pointer to
the manager being used.
This patch makes the system a bit saner: each manager has a linked list
of overlays, and only the overlays linked to that manager are in the
list.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 33 +++++++--------------------------
drivers/video/omap2/dss/manager.c | 10 ++++------
drivers/video/omap2/dss/overlay.c | 12 ++----------
include/video/omapdss.h | 3 +--
4 files changed, 14 insertions(+), 44 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index cfcf816..cca5732 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -398,8 +398,7 @@ void dss_start_update(struct omap_overlay_manager *mgr)
{
struct manager_cache_data *mc;
struct overlay_cache_data *oc;
- const int num_ovls = dss_feat_get_num_ovls();
- int i;
+ struct omap_overlay *ovl;
mc = &dss_cache.manager_cache[mgr->id];
@@ -407,11 +406,8 @@ void dss_start_update(struct omap_overlay_manager *mgr)
configure_dispc();
mc->do_manual_update = false;
- for (i = 0; i < num_ovls; ++i) {
- oc = &dss_cache.overlay_cache[i];
- if (oc->channel != mgr->id)
- continue;
-
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ oc = &dss_cache.overlay_cache[ovl->id];
oc->shadow_dirty = false;
}
@@ -584,8 +580,9 @@ static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
{
- int i, r;
+ int r;
unsigned long flags;
+ struct omap_overlay *ovl;
DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
@@ -596,31 +593,15 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
spin_lock_irqsave(&dss_cache.lock, flags);
/* Configure overlays */
- for (i = 0; i < mgr->num_overlays; ++i) {
- struct omap_overlay *ovl;
-
- ovl = mgr->overlays[i];
-
- if (ovl->manager != mgr)
- continue;
-
+ 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 */
- for (i = 0; i < mgr->num_overlays; ++i) {
- struct omap_overlay *ovl;
-
- ovl = mgr->overlays[i];
-
- if (ovl->manager != mgr)
- continue;
-
+ list_for_each_entry(ovl, &mgr->overlays, list)
omap_dss_mgr_apply_ovl_fifos(ovl);
- }
r = 0;
if (mgr->enabled && !mgr_manual_update(mgr)) {
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index a08cc6e..62bcc38 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -470,8 +470,8 @@ static struct kobj_type manager_ktype = {
static int omap_dss_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev)
{
- int i;
int r;
+ struct omap_overlay *ovl;
if (dssdev->manager) {
DSSERR("display '%s' already has a manager '%s'\n",
@@ -485,10 +485,8 @@ static int omap_dss_set_device(struct omap_overlay_manager *mgr,
return -EINVAL;
}
- for (i = 0; i < mgr->num_overlays; i++) {
- struct omap_overlay *ovl = mgr->overlays[i];
-
- if (ovl->manager != mgr || !ovl->info.enabled)
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ if (!ovl->info.enabled)
continue;
r = dss_check_overlay(ovl, dssdev);
@@ -626,7 +624,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->supported_displays dss_feat_get_supported_displays(mgr->id);
- dss_overlay_setup_dispc_manager(mgr);
+ INIT_LIST_HEAD(&mgr->overlays);
r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
&pdev->dev.kobj, "manager%d", i);
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index ccd6127..3c94065 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -566,6 +566,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
}
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
@@ -597,6 +598,7 @@ static int omap_dss_unset_manager(struct omap_overlay *ovl)
}
ovl->manager = NULL;
+ list_del(&ovl->list);
ovl->manager_changed = true;
return 0;
@@ -617,14 +619,6 @@ struct omap_overlay *omap_dss_get_overlay(int num)
}
EXPORT_SYMBOL(omap_dss_get_overlay);
-static struct omap_overlay *dispc_overlays[MAX_DSS_OVERLAYS];
-
-void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
-{
- mgr->num_overlays = dss_feat_get_num_ovls();
- mgr->overlays = dispc_overlays;
-}
-
void dss_init_overlays(struct platform_device *pdev)
{
int i, r;
@@ -684,8 +678,6 @@ void dss_init_overlays(struct platform_device *pdev)
if (r)
DSSERR("failed to create sysfs file\n");
-
- dispc_overlays[i] = ovl;
}
}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index fd5a96c..eaeca89 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -423,8 +423,7 @@ struct omap_overlay_manager {
const char *name;
enum omap_channel id;
enum omap_overlay_manager_caps caps;
- int num_overlays;
- struct omap_overlay **overlays;
+ struct list_head overlays;
enum omap_display_type supported_displays;
/* dynamic fields */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 29/65] OMAPDSS: APPLY: separate vsync isr register/unregister
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (27 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 28/65] OMAPDSS: store overlays in a list for each manager Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 30/65] OMAPDSS: DISPC: Add dispc_mgr_get_vsync_irq() Tomi Valkeinen
` (35 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Create separate functions for the vsync isr register/unregister code for
cleaner code.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 61 +++++++++++++++++++++++---------------
1 files changed, 37 insertions(+), 24 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index cca5732..6aad0fd 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -417,6 +417,40 @@ void dss_start_update(struct omap_overlay_manager *mgr)
dispc_mgr_enable(mgr->id, true);
}
+static void dss_apply_irq_handler(void *data, u32 mask);
+
+static void dss_register_vsync_isr(void)
+{
+ u32 mask;
+ int r;
+
+ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
+ DISPC_IRQ_EVSYNC_EVEN;
+ if (dss_has_feature(FEAT_MGR_LCD2))
+ mask |= DISPC_IRQ_VSYNC2;
+
+ r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
+ WARN_ON(r);
+
+ dss_cache.irq_enabled = true;
+}
+
+static void dss_unregister_vsync_isr(void)
+{
+ u32 mask;
+ int r;
+
+ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
+ DISPC_IRQ_EVSYNC_EVEN;
+ if (dss_has_feature(FEAT_MGR_LCD2))
+ mask |= DISPC_IRQ_VSYNC2;
+
+ r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
+ WARN_ON(r);
+
+ dss_cache.irq_enabled = false;
+}
+
static void dss_apply_irq_handler(void *data, u32 mask)
{
struct manager_cache_data *mc;
@@ -425,7 +459,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
const int num_mgrs = dss_feat_get_num_mgrs();
int i, r;
bool mgr_busy[MAX_DSS_MANAGERS];
- u32 irq_mask;
for (i = 0; i < num_mgrs; i++)
mgr_busy[i] = dispc_mgr_go_busy(i);
@@ -459,13 +492,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
goto end;
}
- irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- irq_mask |= DISPC_IRQ_VSYNC2;
-
- omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
- dss_cache.irq_enabled = false;
+ dss_unregister_vsync_isr();
end:
spin_unlock(&dss_cache.lock);
@@ -605,22 +632,8 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
r = 0;
if (mgr->enabled && !mgr_manual_update(mgr)) {
- if (!dss_cache.irq_enabled) {
- u32 mask;
-
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- mask |= DISPC_IRQ_VSYNC2;
-
- r = omap_dispc_register_isr(dss_apply_irq_handler,
- NULL, mask);
-
- if (r)
- DSSERR("failed to register apply isr\n");
-
- dss_cache.irq_enabled = true;
- }
+ if (!dss_cache.irq_enabled)
+ dss_register_vsync_isr();
configure_dispc();
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 30/65] OMAPDSS: DISPC: Add dispc_mgr_get_vsync_irq()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (28 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 29/65] OMAPDSS: APPLY: separate vsync isr register/unregister Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 31/65] OMAPDSS: APPLY: use dispc_mgr_get_vsync_irq() Tomi Valkeinen
` (34 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Add dispc_mgr_get_vsync_irq() which returns the irq number for vsync on
the given channel.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 14 ++++++++++++++
drivers/video/omap2/dss/dss.h | 2 +-
2 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5ac00a2..27a2cff 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -438,6 +438,20 @@ static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
return mgr ? mgr->device : NULL;
}
+u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
+{
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ return DISPC_IRQ_VSYNC;
+ case OMAP_DSS_CHANNEL_LCD2:
+ return DISPC_IRQ_VSYNC2;
+ case OMAP_DSS_CHANNEL_DIGIT:
+ return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
+ 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 66fed79..5a6f1db 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -409,9 +409,9 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_ovl_set_channel_out(enum omap_plane plane,
enum omap_channel channel);
-
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);
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 [flat|nested] 91+ messages in thread
* [PATCH 31/65] OMAPDSS: APPLY: use dispc_mgr_get_vsync_irq()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (29 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 30/65] OMAPDSS: DISPC: Add dispc_mgr_get_vsync_irq() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 32/65] OMAPDSS: APPLY: configure_* funcs take ovl/manager as args Tomi Valkeinen
` (33 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Use dispc_mgr_get_vsync_irq() to get the interrupt numbers for vsync,
instead of hardcoding the values depending on the display type.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 36 ++++++++++++------------------------
1 files changed, 12 insertions(+), 24 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 6aad0fd..84ac2d4 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -131,13 +131,7 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
if (mgr_manual_update(mgr))
return 0;
- if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
- || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
- irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
- } else {
- irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
- DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
- }
+ irq = dispc_mgr_get_vsync_irq(mgr->id);
mc = &dss_cache.manager_cache[mgr->id];
i = 0;
@@ -200,13 +194,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
if (ovl_manual_update(ovl))
return 0;
- if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
- || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
- irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
- } else {
- irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
- DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
- }
+ irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
oc = &dss_cache.overlay_cache[ovl->id];
i = 0;
@@ -421,13 +409,13 @@ static void dss_apply_irq_handler(void *data, u32 mask);
static void dss_register_vsync_isr(void)
{
+ const int num_mgrs = dss_feat_get_num_mgrs();
u32 mask;
- int r;
+ int r, i;
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- mask |= DISPC_IRQ_VSYNC2;
+ mask = 0;
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_vsync_irq(i);
r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
@@ -437,13 +425,13 @@ static void dss_register_vsync_isr(void)
static void dss_unregister_vsync_isr(void)
{
+ const int num_mgrs = dss_feat_get_num_mgrs();
u32 mask;
- int r;
+ int r, i;
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- mask |= DISPC_IRQ_VSYNC2;
+ mask = 0;
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_vsync_irq(i);
r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 32/65] OMAPDSS: APPLY: configure_* funcs take ovl/manager as args
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (30 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 31/65] OMAPDSS: APPLY: use dispc_mgr_get_vsync_irq() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 33/65] OMAPDSS: APPLY: rename overlay_cache_data Tomi Valkeinen
` (32 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Make configure_overlay() and configure_manager() take overlay/manager
pointer as an argument, instead of the ovl/mgr id. This will be useful
with the future patches.
Also rename the functions to be a bit more informative:
dss_ovl_write_regs, dss_mgr_write_regs, dss_write_regs.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 54 +++++++++++++++++++-------------------
1 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 84ac2d4..1c97069 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -41,7 +41,7 @@
* | dss_cache |
* +--------------------+
* v
- * configure()
+ * write_regs()
* v
* +--------------------+
* | shadow registers |
@@ -237,65 +237,63 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
return r;
}
-static int configure_overlay(enum omap_plane plane)
+static int dss_ovl_write_regs(struct omap_overlay *ovl)
{
- struct omap_overlay *ovl;
struct overlay_cache_data *c;
struct omap_overlay_info *oi;
bool ilace, replication;
int r;
- DSSDBGF("%d", plane);
+ DSSDBGF("%d", ovl->id);
- c = &dss_cache.overlay_cache[plane];
+ c = &dss_cache.overlay_cache[ovl->id];
oi = &c->info;
if (!c->enabled) {
- dispc_ovl_enable(plane, 0);
+ dispc_ovl_enable(ovl->id, 0);
return 0;
}
- ovl = omap_dss_get_overlay(plane);
-
replication = dss_use_replication(ovl->manager->device, oi->color_mode);
ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
- dispc_ovl_set_channel_out(plane, c->channel);
+ dispc_ovl_set_channel_out(ovl->id, c->channel);
- r = dispc_ovl_setup(plane, oi, ilace, replication);
+ r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
if (r) {
/* this shouldn't happen */
- DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
- dispc_ovl_enable(plane, 0);
+ DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
+ dispc_ovl_enable(ovl->id, 0);
return r;
}
- dispc_ovl_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
+ dispc_ovl_set_fifo_threshold(ovl->id, c->fifo_low, c->fifo_high);
- dispc_ovl_enable(plane, 1);
+ dispc_ovl_enable(ovl->id, 1);
return 0;
}
-static void configure_manager(enum omap_channel channel)
+static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
{
struct omap_overlay_manager_info *mi;
- DSSDBGF("%d", channel);
+ DSSDBGF("%d", mgr->id);
- /* picking info from the cache */
- mi = &dss_cache.manager_cache[channel].info;
+ mi = &dss_cache.manager_cache[mgr->id].info;
- dispc_mgr_setup(channel, mi);
+ dispc_mgr_setup(mgr->id, mi);
}
-/* configure_dispc() tries to write values from cache to shadow registers.
+/* 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 configure_dispc(void)
+static int dss_write_regs(void)
{
+ struct omap_overlay *ovl;
+ struct omap_overlay_manager *mgr;
struct overlay_cache_data *oc;
struct manager_cache_data *mc;
const int num_ovls = dss_feat_get_num_ovls();
@@ -316,6 +314,7 @@ static int configure_dispc(void)
/* Commit overlay settings */
for (i = 0; i < num_ovls; ++i) {
+ ovl = omap_dss_get_overlay(i);
oc = &dss_cache.overlay_cache[i];
mc = &dss_cache.manager_cache[oc->channel];
@@ -330,9 +329,9 @@ static int configure_dispc(void)
continue;
}
- r = configure_overlay(i);
+ r = dss_ovl_write_regs(ovl);
if (r)
- DSSERR("configure_overlay %d failed\n", i);
+ DSSERR("dss_ovl_write_regs %d failed\n", i);
oc->dirty = false;
oc->shadow_dirty = true;
@@ -341,6 +340,7 @@ static int configure_dispc(void)
/* Commit manager settings */
for (i = 0; i < num_mgrs; ++i) {
+ mgr = omap_dss_get_overlay_manager(i);
mc = &dss_cache.manager_cache[i];
if (!mc->dirty)
@@ -354,7 +354,7 @@ static int configure_dispc(void)
continue;
}
- configure_manager(i);
+ dss_mgr_write_regs(mgr);
mc->dirty = false;
mc->shadow_dirty = true;
mgr_go[i] = true;
@@ -391,7 +391,7 @@ void dss_start_update(struct omap_overlay_manager *mgr)
mc = &dss_cache.manager_cache[mgr->id];
mc->do_manual_update = true;
- configure_dispc();
+ dss_write_regs();
mc->do_manual_update = false;
list_for_each_entry(ovl, &mgr->overlays, list) {
@@ -465,7 +465,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
mc->shadow_dirty = false;
}
- r = configure_dispc();
+ r = dss_write_regs();
if (r = 1)
goto end;
@@ -623,7 +623,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
if (!dss_cache.irq_enabled)
dss_register_vsync_isr();
- configure_dispc();
+ dss_write_regs();
}
spin_unlock_irqrestore(&dss_cache.lock, flags);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 33/65] OMAPDSS: APPLY: rename overlay_cache_data
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (31 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 32/65] OMAPDSS: APPLY: configure_* funcs take ovl/manager as args Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 34/65] OMAPDSS: APPLY: rename manager_cache_data Tomi Valkeinen
` (31 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
overlay_cache_data is not a suitable name for the struct. It is more of
a private data for the overlay.
Rename the struct to ovl_priv_data, and add a function,
get_ovl_priv(ovl), to get a pointer to the data.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 99 +++++++++++++++++++++------------------
1 files changed, 53 insertions(+), 46 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 1c97069..d07bcc9 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -54,7 +54,7 @@
* +--------------------+
*/
-struct overlay_cache_data {
+struct ovl_priv_data {
/* If true, cache changed, but not written to shadow registers. Set
* in apply(), cleared when registers written. */
bool dirty;
@@ -90,12 +90,17 @@ struct manager_cache_data {
static struct {
spinlock_t lock;
- struct overlay_cache_data overlay_cache[MAX_DSS_OVERLAYS];
+ struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
struct manager_cache_data manager_cache[MAX_DSS_MANAGERS];
bool irq_enabled;
} dss_cache;
+static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
+{
+ return &dss_cache.ovl_priv_data_array[ovl->id];
+}
+
void dss_apply_init(void)
{
spin_lock_init(&dss_cache.lock);
@@ -177,7 +182,7 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
{
unsigned long timeout = msecs_to_jiffies(500);
- struct overlay_cache_data *oc;
+ struct ovl_priv_data *op;
struct omap_dss_device *dssdev;
u32 irq;
int r;
@@ -196,15 +201,15 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
- oc = &dss_cache.overlay_cache[ovl->id];
+ op = get_ovl_priv(ovl);
i = 0;
while (1) {
unsigned long flags;
bool shadow_dirty, dirty;
spin_lock_irqsave(&dss_cache.lock, flags);
- dirty = oc->dirty;
- shadow_dirty = oc->shadow_dirty;
+ dirty = op->dirty;
+ shadow_dirty = op->shadow_dirty;
spin_unlock_irqrestore(&dss_cache.lock, flags);
if (!dirty && !shadow_dirty) {
@@ -239,17 +244,17 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
static int dss_ovl_write_regs(struct omap_overlay *ovl)
{
- struct overlay_cache_data *c;
+ struct ovl_priv_data *op;
struct omap_overlay_info *oi;
bool ilace, replication;
int r;
DSSDBGF("%d", ovl->id);
- c = &dss_cache.overlay_cache[ovl->id];
- oi = &c->info;
+ op = get_ovl_priv(ovl);
+ oi = &op->info;
- if (!c->enabled) {
+ if (!op->enabled) {
dispc_ovl_enable(ovl->id, 0);
return 0;
}
@@ -258,7 +263,7 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
- dispc_ovl_set_channel_out(ovl->id, c->channel);
+ dispc_ovl_set_channel_out(ovl->id, op->channel);
r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
if (r) {
@@ -268,7 +273,7 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
return r;
}
- dispc_ovl_set_fifo_threshold(ovl->id, c->fifo_low, c->fifo_high);
+ dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
dispc_ovl_enable(ovl->id, 1);
@@ -294,7 +299,7 @@ static int dss_write_regs(void)
{
struct omap_overlay *ovl;
struct omap_overlay_manager *mgr;
- struct overlay_cache_data *oc;
+ struct ovl_priv_data *op;
struct manager_cache_data *mc;
const int num_ovls = dss_feat_get_num_ovls();
const int num_mgrs = dss_feat_get_num_mgrs();
@@ -315,16 +320,16 @@ static int dss_write_regs(void)
/* Commit overlay settings */
for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
- oc = &dss_cache.overlay_cache[i];
- mc = &dss_cache.manager_cache[oc->channel];
+ op = get_ovl_priv(ovl);
+ mc = &dss_cache.manager_cache[op->channel];
- if (!oc->dirty)
+ if (!op->dirty)
continue;
if (mc->manual_update && !mc->do_manual_update)
continue;
- if (mgr_busy[oc->channel]) {
+ if (mgr_busy[op->channel]) {
busy = true;
continue;
}
@@ -333,9 +338,9 @@ static int dss_write_regs(void)
if (r)
DSSERR("dss_ovl_write_regs %d failed\n", i);
- oc->dirty = false;
- oc->shadow_dirty = true;
- mgr_go[oc->channel] = true;
+ op->dirty = false;
+ op->shadow_dirty = true;
+ mgr_go[op->channel] = true;
}
/* Commit manager settings */
@@ -385,7 +390,7 @@ static int dss_write_regs(void)
void dss_start_update(struct omap_overlay_manager *mgr)
{
struct manager_cache_data *mc;
- struct overlay_cache_data *oc;
+ struct ovl_priv_data *op;
struct omap_overlay *ovl;
mc = &dss_cache.manager_cache[mgr->id];
@@ -395,8 +400,8 @@ void dss_start_update(struct omap_overlay_manager *mgr)
mc->do_manual_update = false;
list_for_each_entry(ovl, &mgr->overlays, list) {
- oc = &dss_cache.overlay_cache[ovl->id];
- oc->shadow_dirty = false;
+ op = get_ovl_priv(ovl);
+ op->shadow_dirty = false;
}
mc = &dss_cache.manager_cache[mgr->id];
@@ -441,8 +446,9 @@ static void dss_unregister_vsync_isr(void)
static void dss_apply_irq_handler(void *data, u32 mask)
{
+ struct omap_overlay *ovl;
struct manager_cache_data *mc;
- struct overlay_cache_data *oc;
+ 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;
@@ -454,9 +460,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
spin_lock(&dss_cache.lock);
for (i = 0; i < num_ovls; ++i) {
- oc = &dss_cache.overlay_cache[i];
- if (!mgr_busy[oc->channel])
- oc->shadow_dirty = false;
+ ovl = omap_dss_get_overlay(i);
+ op = get_ovl_priv(ovl);
+ if (!mgr_busy[op->channel])
+ op->shadow_dirty = false;
}
for (i = 0; i < num_mgrs; ++i) {
@@ -488,10 +495,10 @@ end:
static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
{
- struct overlay_cache_data *oc;
+ struct ovl_priv_data *op;
struct omap_dss_device *dssdev;
- oc = &dss_cache.overlay_cache[ovl->id];
+ op = get_ovl_priv(ovl);
if (ovl->manager_changed) {
ovl->manager_changed = false;
@@ -499,9 +506,9 @@ static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
}
if (!overlay_enabled(ovl)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
+ if (op->enabled) {
+ op->enabled = false;
+ op->dirty = true;
}
return 0;
}
@@ -512,20 +519,20 @@ static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
dssdev = ovl->manager->device;
if (dss_check_overlay(ovl, dssdev)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
+ if (op->enabled) {
+ op->enabled = false;
+ op->dirty = true;
}
return -EINVAL;
}
ovl->info_dirty = false;
- oc->dirty = true;
- oc->info = ovl->info;
+ op->dirty = true;
+ op->info = ovl->info;
- oc->channel = ovl->manager->id;
+ op->channel = ovl->manager->id;
- oc->enabled = true;
+ op->enabled = true;
return 0;
}
@@ -556,13 +563,13 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
{
- struct overlay_cache_data *oc;
+ struct ovl_priv_data *op;
struct omap_dss_device *dssdev;
u32 size, burst_size;
- oc = &dss_cache.overlay_cache[ovl->id];
+ op = get_ovl_priv(ovl);
- if (!oc->enabled)
+ if (!op->enabled)
return;
dssdev = ovl->manager->device;
@@ -578,14 +585,14 @@ 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, &oc->fifo_low,
- &oc->fifo_high);
+ burst_size, &op->fifo_low,
+ &op->fifo_high);
break;
#ifdef CONFIG_OMAP2_DSS_DSI
case OMAP_DISPLAY_TYPE_DSI:
dsi_get_overlay_fifo_thresholds(ovl->id, size,
- burst_size, &oc->fifo_low,
- &oc->fifo_high);
+ burst_size, &op->fifo_low,
+ &op->fifo_high);
break;
#endif
default:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 34/65] OMAPDSS: APPLY: rename manager_cache_data
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (32 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 33/65] OMAPDSS: APPLY: rename overlay_cache_data Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct Tomi Valkeinen
` (30 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
manager_cache_data is not a suitable name for the struct. It is more of
a private data for the manager.
Rename the struct to mgr_priv_data, and add a function,
get_mgr_priv(mgr), to get a pointer to the data.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 72 +++++++++++++++++++++-----------------
1 files changed, 40 insertions(+), 32 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d07bcc9..23c723a 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -73,7 +73,7 @@ struct ovl_priv_data {
u32 fifo_high;
};
-struct manager_cache_data {
+struct mgr_priv_data {
/* If true, cache changed, but not written to shadow registers. Set
* in apply(), cleared when registers written. */
bool dirty;
@@ -91,7 +91,7 @@ struct manager_cache_data {
static struct {
spinlock_t lock;
struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
- struct manager_cache_data manager_cache[MAX_DSS_MANAGERS];
+ struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
bool irq_enabled;
} dss_cache;
@@ -101,6 +101,11 @@ static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
return &dss_cache.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];
+}
+
void dss_apply_init(void)
{
spin_lock_init(&dss_cache.lock);
@@ -124,7 +129,7 @@ static int overlay_enabled(struct omap_overlay *ovl)
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
- struct manager_cache_data *mc;
+ struct mgr_priv_data *mp;
u32 irq;
int r;
int i;
@@ -138,15 +143,15 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
irq = dispc_mgr_get_vsync_irq(mgr->id);
- mc = &dss_cache.manager_cache[mgr->id];
+ mp = get_mgr_priv(mgr);
i = 0;
while (1) {
unsigned long flags;
bool shadow_dirty, dirty;
spin_lock_irqsave(&dss_cache.lock, flags);
- dirty = mc->dirty;
- shadow_dirty = mc->shadow_dirty;
+ dirty = mp->dirty;
+ shadow_dirty = mp->shadow_dirty;
spin_unlock_irqrestore(&dss_cache.lock, flags);
if (!dirty && !shadow_dirty) {
@@ -282,11 +287,13 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
{
+ struct mgr_priv_data *mp;
struct omap_overlay_manager_info *mi;
DSSDBGF("%d", mgr->id);
- mi = &dss_cache.manager_cache[mgr->id].info;
+ mp = get_mgr_priv(mgr);
+ mi = &mp->info;
dispc_mgr_setup(mgr->id, mi);
}
@@ -300,7 +307,7 @@ static int dss_write_regs(void)
struct omap_overlay *ovl;
struct omap_overlay_manager *mgr;
struct ovl_priv_data *op;
- struct manager_cache_data *mc;
+ 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;
@@ -321,12 +328,13 @@ static int dss_write_regs(void)
for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
op = get_ovl_priv(ovl);
- mc = &dss_cache.manager_cache[op->channel];
if (!op->dirty)
continue;
- if (mc->manual_update && !mc->do_manual_update)
+ mp = get_mgr_priv(ovl->manager);
+
+ if (mp->manual_update && !mp->do_manual_update)
continue;
if (mgr_busy[op->channel]) {
@@ -346,12 +354,12 @@ static int dss_write_regs(void)
/* Commit manager settings */
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
- mc = &dss_cache.manager_cache[i];
+ mp = get_mgr_priv(mgr);
- if (!mc->dirty)
+ if (!mp->dirty)
continue;
- if (mc->manual_update && !mc->do_manual_update)
+ if (mp->manual_update && !mp->do_manual_update)
continue;
if (mgr_busy[i]) {
@@ -360,14 +368,15 @@ static int dss_write_regs(void)
}
dss_mgr_write_regs(mgr);
- mc->dirty = false;
- mc->shadow_dirty = true;
+ mp->dirty = false;
+ mp->shadow_dirty = true;
mgr_go[i] = true;
}
/* set GO */
for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
if (!mgr_go[i])
continue;
@@ -375,7 +384,7 @@ 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 (!mc->manual_update)
+ if (!mp->manual_update)
dispc_mgr_go(i);
}
@@ -389,23 +398,20 @@ static int dss_write_regs(void)
void dss_start_update(struct omap_overlay_manager *mgr)
{
- struct manager_cache_data *mc;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
struct ovl_priv_data *op;
struct omap_overlay *ovl;
- mc = &dss_cache.manager_cache[mgr->id];
-
- mc->do_manual_update = true;
+ mp->do_manual_update = true;
dss_write_regs();
- mc->do_manual_update = false;
+ mp->do_manual_update = false;
list_for_each_entry(ovl, &mgr->overlays, list) {
op = get_ovl_priv(ovl);
op->shadow_dirty = false;
}
- mc = &dss_cache.manager_cache[mgr->id];
- mc->shadow_dirty = false;
+ mp->shadow_dirty = false;
dispc_mgr_enable(mgr->id, true);
}
@@ -447,7 +453,8 @@ static void dss_unregister_vsync_isr(void)
static void dss_apply_irq_handler(void *data, u32 mask)
{
struct omap_overlay *ovl;
- struct manager_cache_data *mc;
+ struct omap_overlay_manager *mgr;
+ struct mgr_priv_data *mp;
struct ovl_priv_data *op;
const int num_ovls = dss_feat_get_num_ovls();
const int num_mgrs = dss_feat_get_num_mgrs();
@@ -467,9 +474,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
}
for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
if (!mgr_busy[i])
- mc->shadow_dirty = false;
+ mp->shadow_dirty = false;
}
r = dss_write_regs();
@@ -539,9 +547,9 @@ static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
{
- struct manager_cache_data *mc;
+ struct mgr_priv_data *mp;
- mc = &dss_cache.manager_cache[mgr->id];
+ mp = get_mgr_priv(mgr);
if (mgr->device_changed) {
mgr->device_changed = false;
@@ -555,10 +563,10 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
return;
mgr->info_dirty = false;
- mc->dirty = true;
- mc->info = mgr->info;
+ mp->dirty = true;
+ mp->info = mgr->info;
- mc->manual_update = mgr_manual_update(mgr);
+ mp->manual_update = mgr_manual_update(mgr);
}
static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (33 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 34/65] OMAPDSS: APPLY: rename manager_cache_data Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-23 9:37 ` Archit Taneja
2011-11-23 10:29 ` Sergey Kibrik
2011-11-22 9:21 ` [PATCH 36/65] OMAPDSS: APPLY: rename dss_cache to dss_data Tomi Valkeinen
` (29 subsequent siblings)
64 siblings, 2 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 36/65] OMAPDSS: APPLY: rename dss_cache to dss_data
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (34 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 37/65] OMAPDSS: APPLY: move ovl funcs to apply.c Tomi Valkeinen
` (28 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 37/65] OMAPDSS: APPLY: move ovl funcs to apply.c
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (35 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 36/65] OMAPDSS: APPLY: rename dss_cache to dss_data Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 38/65] OMAPDSS: APPLY: move mgr " Tomi Valkeinen
` (27 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 38/65] OMAPDSS: APPLY: move mgr funcs to apply.c
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (36 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 37/65] OMAPDSS: APPLY: move ovl funcs to apply.c Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 39/65] OMAPDSS: remove ovl/mgr check-code temporarily Tomi Valkeinen
` (26 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 39/65] OMAPDSS: remove ovl/mgr check-code temporarily
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (37 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 38/65] OMAPDSS: APPLY: move mgr " Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 40/65] OMAPDSS: APPLY: add mutex Tomi Valkeinen
` (25 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 40/65] OMAPDSS: APPLY: add mutex
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (38 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 39/65] OMAPDSS: remove ovl/mgr check-code temporarily Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-23 9:49 ` Archit Taneja
2011-11-22 9:21 ` [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock Tomi Valkeinen
` (24 subsequent siblings)
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (39 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 40/65] OMAPDSS: APPLY: add mutex Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-23 9:57 ` Archit Taneja
2011-11-22 9:21 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays Tomi Valkeinen
` (23 subsequent siblings)
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (40 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-23 10:22 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
2011-11-22 9:21 ` [PATCH 43/65] OMAPDSS: APPLY: move mgr->enabled to mgr_priv_data Tomi Valkeinen
` (22 subsequent siblings)
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 43/65] OMAPDSS: APPLY: move mgr->enabled to mgr_priv_data
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (41 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 44/65] OMAPDSS: APPLY: add busy field " Tomi Valkeinen
` (21 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 44/65] OMAPDSS: APPLY: add busy field to mgr_priv_data
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (42 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 43/65] OMAPDSS: APPLY: move mgr->enabled to mgr_priv_data Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 45/65] OMAPDSS: APPLY: rewrite overlay enable/disable Tomi Valkeinen
` (20 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 45/65] OMAPDSS: APPLY: rewrite overlay enable/disable
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (43 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 44/65] OMAPDSS: APPLY: add busy field " Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 46/65] OMAPDSS: APPLY: rewrite register writing Tomi Valkeinen
` (19 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 46/65] OMAPDSS: APPLY: rewrite register writing
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (44 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 45/65] OMAPDSS: APPLY: rewrite overlay enable/disable Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 47/65] OMAPDSS: DISPC: add dispc_mgr_get_framedone_irq Tomi Valkeinen
` (18 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 47/65] OMAPDSS: DISPC: add dispc_mgr_get_framedone_irq
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (45 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 46/65] OMAPDSS: APPLY: rewrite register writing Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 48/65] OMAPDSS: APPLY: add updating flag Tomi Valkeinen
` (17 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 48/65] OMAPDSS: APPLY: add updating flag
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (46 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 47/65] OMAPDSS: DISPC: add dispc_mgr_get_framedone_irq Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 49/65] OMAPDSS: APPLY: clean up isr_handler Tomi Valkeinen
` (16 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 49/65] OMAPDSS: APPLY: clean up isr_handler
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (47 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 48/65] OMAPDSS: APPLY: add updating flag Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 50/65] OMAPDSS: APPLY: move mgr->info to apply.c Tomi Valkeinen
` (15 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 50/65] OMAPDSS: APPLY: move mgr->info to apply.c
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (48 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 49/65] OMAPDSS: APPLY: clean up isr_handler Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 51/65] OMAPDSS: APPLY: move ovl->info " Tomi Valkeinen
` (14 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 51/65] OMAPDSS: APPLY: move ovl->info to apply.c
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (49 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 50/65] OMAPDSS: APPLY: move mgr->info to apply.c Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 52/65] OMAPDSS: APPLY: move channel-field to extra_info set Tomi Valkeinen
` (13 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 52/65] OMAPDSS: APPLY: move channel-field to extra_info set
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (50 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 51/65] OMAPDSS: APPLY: move ovl->info " Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 53/65] OMAPDSS: APPLY: move fifo thresholds " Tomi Valkeinen
` (12 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 53/65] OMAPDSS: APPLY: move fifo thresholds to extra_info set
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (51 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 52/65] OMAPDSS: APPLY: move channel-field to extra_info set Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 54/65] OMAPDSS: APPLY: rename dirty & shadow_dirty Tomi Valkeinen
` (11 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 54/65] OMAPDSS: APPLY: rename dirty & shadow_dirty
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (52 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 53/65] OMAPDSS: APPLY: move fifo thresholds " Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 55/65] OMAPDSS: APPLY: remove device_changed field Tomi Valkeinen
` (10 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 55/65] OMAPDSS: APPLY: remove device_changed field
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (53 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 54/65] OMAPDSS: APPLY: rename dirty & shadow_dirty Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 56/65] OMAPDSS: APPLY: add dss_apply_ovl_enable() Tomi Valkeinen
` (9 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 56/65] OMAPDSS: APPLY: add dss_apply_ovl_enable()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (54 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 55/65] OMAPDSS: APPLY: remove device_changed field Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 57/65] OMAPDSS: APPLY: skip enable/disable if already enabled/disabled Tomi Valkeinen
` (8 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 57/65] OMAPDSS: APPLY: skip enable/disable if already enabled/disabled
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (55 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 56/65] OMAPDSS: APPLY: add dss_apply_ovl_enable() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates() Tomi Valkeinen
` (7 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (56 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 57/65] OMAPDSS: APPLY: skip enable/disable if already enabled/disabled Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-12-07 13:19 ` Archit Taneja
2011-11-22 9:21 ` [PATCH 59/65] OMAPDSS: APPLY: remove runtime_get Tomi Valkeinen
` (6 subsequent siblings)
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 59/65] OMAPDSS: APPLY: remove runtime_get
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (57 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates() Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 60/65] OMAPDSS: Add comments about blocking of ovl/mgr functions Tomi Valkeinen
` (5 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
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 [flat|nested] 91+ messages in thread
* [PATCH 60/65] OMAPDSS: Add comments about blocking of ovl/mgr functions
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (58 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 59/65] OMAPDSS: APPLY: remove runtime_get Tomi Valkeinen
@ 2011-11-22 9:21 ` Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 61/65] OMAPDSS: APPLY: add dss_ovl_simple_check() Tomi Valkeinen
` (4 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Add comments specifying what ovl/mgr functions may block.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
include/video/omapdss.h | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 98fc026..39862b8 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -384,6 +384,17 @@ struct omap_overlay {
/* dynamic fields */
struct omap_overlay_manager *manager;
+ /*
+ * The following functions do not block:
+ *
+ * is_enabled
+ * set_overlay_info
+ * get_overlay_info
+ *
+ * The rest of the functions may block and cannot be called from
+ * interrupt context
+ */
+
int (*enable)(struct omap_overlay *ovl);
int (*disable)(struct omap_overlay *ovl);
bool (*is_enabled)(struct omap_overlay *ovl);
@@ -426,6 +437,17 @@ struct omap_overlay_manager {
/* dynamic fields */
struct omap_dss_device *device;
+ /*
+ * The following functions do not block:
+ *
+ * set_manager_info
+ * get_manager_info
+ * apply
+ *
+ * The rest of the functions may block and cannot be called from
+ * interrupt context
+ */
+
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 [flat|nested] 91+ messages in thread
* [PATCH 61/65] OMAPDSS: APPLY: add dss_ovl_simple_check()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (59 preceding siblings ...)
2011-11-22 9:21 ` [PATCH 60/65] OMAPDSS: Add comments about blocking of ovl/mgr functions Tomi Valkeinen
@ 2011-11-22 9:22 ` Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 62/65] OMAPDSS: APPLY: add dss_mgr_simple_check() Tomi Valkeinen
` (3 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:22 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Add dss_ovl_simple_check() which is used to check the validity of
certain overlay attributes. Only attributes that can be checked
independently, without knowing the display being used, is done here
(thus "simple").
We can use this function in dss_ovl_set_info().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 40 +++++++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 6a50ee0..c1c4597 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -928,12 +928,52 @@ err:
}
+static int dss_ovl_simple_check(struct omap_overlay *ovl,
+ const struct omap_overlay_info *info)
+{
+ if (info->paddr = 0) {
+ DSSERR("check_overlay: paddr cannot be 0\n");
+ return -EINVAL;
+ }
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) = 0) {
+ if (info->out_width != 0 && info->width != info->out_width) {
+ DSSERR("check_overlay: overlay %d doesn't support "
+ "scaling\n", ovl->id);
+ return -EINVAL;
+ }
+
+ if (info->out_height != 0 && info->height != info->out_height) {
+ DSSERR("check_overlay: overlay %d doesn't support "
+ "scaling\n", ovl->id);
+ return -EINVAL;
+ }
+ }
+
+ if ((ovl->supported_modes & info->color_mode) = 0) {
+ DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
+ ovl->id, info->color_mode);
+ return -EINVAL;
+ }
+
+ if (info->zorder >= omap_dss_get_num_overlays()) {
+ DSSERR("check_overlay: zorder %d too high\n", info->zorder);
+ return -EINVAL;
+ }
+
+ return 0;
+}
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;
+ int r;
+
+ r = dss_ovl_simple_check(ovl, info);
+ if (r)
+ return r;
spin_lock_irqsave(&data_lock, flags);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 62/65] OMAPDSS: APPLY: add dss_mgr_simple_check()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (60 preceding siblings ...)
2011-11-22 9:22 ` [PATCH 61/65] OMAPDSS: APPLY: add dss_ovl_simple_check() Tomi Valkeinen
@ 2011-11-22 9:22 ` Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings Tomi Valkeinen
` (2 subsequent siblings)
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:22 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Add dss_mgr_simple_check() which is used to check the validity of
certain manager attributes. Only attributes that can be checked
independently, without knowing the display being used, is done here
(thus "simple").
We can use this function in dss_mgr_set_info().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index c1c4597..5d933b9 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -834,11 +834,35 @@ out:
mutex_unlock(&apply_lock);
}
+static int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
+ const struct omap_overlay_manager_info *info)
+{
+ 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 (info->partial_alpha_enabled && info->trans_enabled
+ && info->trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) {
+ DSSERR("check_manager: illegal transparency key\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
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;
+ int r;
+
+ r = dss_mgr_simple_check(mgr, info);
+ if (r)
+ return r;
spin_lock_irqsave(&data_lock, flags);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (61 preceding siblings ...)
2011-11-22 9:22 ` [PATCH 62/65] OMAPDSS: APPLY: add dss_mgr_simple_check() Tomi Valkeinen
@ 2011-11-22 9:22 ` Tomi Valkeinen
2011-12-07 13:17 ` Archit Taneja
2011-11-22 9:22 ` [PATCH 64/65] OMAPDSS: APPLY: add return value to dss_mgr_enable() Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 65/65] OMAPDSS: check the return value of dss_mgr_enable() Tomi Valkeinen
64 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:22 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Add checks for overlay and manager settings. The checks are a bit
complex, as we need to observe the bigger picture instead of overlays
and managers independently. Things like the used display and the zorder
of other overlays affect the validity of the settings.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 215 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 212 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 5d933b9..72afa85 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -166,6 +166,169 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
}
+/* Check if overlay parameters are compatible with display */
+static int dss_ovl_check(struct omap_overlay *ovl,
+ struct omap_overlay_info *info, struct omap_dss_device *dssdev)
+{
+ u16 outw, outh;
+ u16 dw, dh;
+
+ if (dssdev = NULL)
+ return 0;
+
+ dssdev->driver->get_resolution(dssdev, &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) {
+ DSSERR("overlay %d horizontally not inside the display area "
+ "(%d + %d >= %d)\n",
+ ovl->id, info->pos_x, outw, dw);
+ return -EINVAL;
+ }
+
+ if (dh < info->pos_y + outh) {
+ DSSERR("overlay %d vertically not inside the display area "
+ "(%d + %d >= %d)\n",
+ ovl->id, info->pos_y, outh, dh);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
+ struct omap_overlay_info **overlay_infos)
+{
+ struct omap_overlay *ovl1, *ovl2;
+ struct ovl_priv_data *op1, *op2;
+ struct omap_overlay_info *info1, *info2;
+
+ list_for_each_entry(ovl1, &mgr->overlays, list) {
+ op1 = get_ovl_priv(ovl1);
+ info1 = overlay_infos[ovl1->id];
+
+ if (info1 = NULL)
+ continue;
+
+ list_for_each_entry(ovl2, &mgr->overlays, list) {
+ if (ovl1 = ovl2)
+ continue;
+
+ op2 = get_ovl_priv(ovl2);
+ info2 = overlay_infos[ovl2->id];
+
+ if (info2 = NULL)
+ continue;
+
+ if (info1->zorder = info2->zorder) {
+ DSSERR("overlays %d and %d have the same "
+ "zorder %d\n",
+ ovl1->id, ovl2->id, info1->zorder);
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int dss_mgr_check(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev,
+ struct omap_overlay_manager_info *info,
+ struct omap_overlay_info **overlay_infos)
+{
+ struct omap_overlay *ovl;
+ int r;
+
+ if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) {
+ r = dss_mgr_check_zorder(mgr, overlay_infos);
+ if (r)
+ return r;
+ }
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ struct omap_overlay_info *oi;
+ int r;
+
+ oi = overlay_infos[ovl->id];
+
+ if (oi = NULL)
+ continue;
+
+ r = dss_ovl_check(ovl, oi, dssdev);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+static int dss_check_settings_low(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev, bool applying)
+{
+ struct omap_overlay_info *oi;
+ struct omap_overlay_manager_info *mi;
+ struct omap_overlay *ovl;
+ struct omap_overlay_info *ois[MAX_DSS_OVERLAYS];
+ struct ovl_priv_data *op;
+ struct mgr_priv_data *mp;
+
+ mp = get_mgr_priv(mgr);
+
+ if (applying && mp->user_info_dirty)
+ mi = &mp->user_info;
+ else
+ mi = &mp->info;
+
+ /* collect the infos to be tested into the array */
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ op = get_ovl_priv(ovl);
+
+ if (!op->enabled)
+ oi = NULL;
+ else if (applying && op->user_info_dirty)
+ oi = &op->user_info;
+ else
+ oi = &op->info;
+
+ ois[ovl->id] = oi;
+ }
+
+ return dss_mgr_check(mgr, dssdev, mi, ois);
+}
+
+/*
+ * check manager and overlay settings using overlay_info from data->info
+ */
+static int dss_check_settings(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev)
+{
+ return dss_check_settings_low(mgr, dssdev, false);
+}
+
+/*
+ * check manager and overlay settings using overlay_info from ovl->info if
+ * dirty and from data->info otherwise
+ */
+static int dss_check_settings_apply(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev)
+{
+ return dss_check_settings_low(mgr, dssdev, true);
+}
+
static bool need_isr(void)
{
const int num_mgrs = dss_feat_get_num_mgrs();
@@ -517,6 +680,7 @@ static void dss_write_regs(void)
for (i = 0; i < num_mgrs; ++i) {
struct omap_overlay_manager *mgr;
struct mgr_priv_data *mp;
+ int r;
mgr = omap_dss_get_overlay_manager(i);
mp = get_mgr_priv(mgr);
@@ -524,6 +688,13 @@ static void dss_write_regs(void)
if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
continue;
+ r = dss_check_settings(mgr, mgr->device);
+ if (r) {
+ DSSERR("cannot write registers for manager %s: "
+ "illegal configuration\n", mgr->name);
+ continue;
+ }
+
dss_mgr_write_regs(mgr);
if (need_go(mgr)) {
@@ -541,11 +712,19 @@ void dss_start_update(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
+ int r;
spin_lock_irqsave(&data_lock, flags);
WARN_ON(mp->updating);
+ r = dss_check_settings(mgr, mgr->device);
+ if (r) {
+ DSSERR("cannot start manual update: illegal configuration\n");
+ spin_unlock_irqrestore(&data_lock, flags);
+ return;
+ }
+
dss_mgr_write_regs(mgr);
mp->updating = true;
@@ -690,11 +869,19 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
{
unsigned long flags;
struct omap_overlay *ovl;
+ int r;
DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
spin_lock_irqsave(&data_lock, flags);
+ r = dss_check_settings_apply(mgr, mgr->device);
+ if (r) {
+ spin_unlock_irqrestore(&data_lock, flags);
+ DSSERR("failed to apply settings: illegal configuration.\n");
+ return r;
+ }
+
/* Configure overlays */
list_for_each_entry(ovl, &mgr->overlays, list)
omap_dss_mgr_apply_ovl(ovl);
@@ -784,6 +971,7 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
+ int r;
mutex_lock(&apply_lock);
@@ -793,6 +981,16 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
spin_lock_irqsave(&data_lock, flags);
mp->enabled = true;
+ r = dss_check_settings(mgr, mgr->device);
+ mp->enabled = false;
+ if (r) {
+ DSSERR("failed to enable manager %d: check_settings failed\n",
+ mgr->id);
+ spin_unlock_irqrestore(&data_lock, flags);
+ goto out;
+ }
+
+ mp->enabled = true;
dss_mgr_setup_fifos(mgr);
@@ -1142,16 +1340,25 @@ int dss_ovl_enable(struct omap_overlay *ovl)
if (op->enabled) {
r = 0;
- goto err;
+ goto err1;
}
if (ovl->manager = NULL || ovl->manager->device = NULL) {
r = -EINVAL;
- goto err;
+ goto err1;
}
spin_lock_irqsave(&data_lock, flags);
+ op->enabled = true;
+ r = dss_check_settings(ovl->manager, ovl->manager->device);
+ op->enabled = false;
+ if (r) {
+ DSSERR("failed to enable overlay %d: check_settings failed\n",
+ ovl->id);
+ goto err2;
+ }
+
dss_apply_ovl_enable(ovl, true);
dss_ovl_setup_fifo(ovl);
@@ -1163,7 +1370,9 @@ int dss_ovl_enable(struct omap_overlay *ovl)
mutex_unlock(&apply_lock);
return 0;
-err:
+err2:
+ spin_unlock_irqrestore(&data_lock, flags);
+err1:
mutex_unlock(&apply_lock);
return r;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 64/65] OMAPDSS: APPLY: add return value to dss_mgr_enable()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (62 preceding siblings ...)
2011-11-22 9:22 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings Tomi Valkeinen
@ 2011-11-22 9:22 ` Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 65/65] OMAPDSS: check the return value of dss_mgr_enable() Tomi Valkeinen
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:22 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Now that dss_mgr_enable() can fail due to checks, make it return the
error value.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 12 +++++++++---
drivers/video/omap2/dss/dss.h | 2 +-
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 72afa85..1ce4c00 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -967,7 +967,7 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
}
}
-void dss_mgr_enable(struct omap_overlay_manager *mgr)
+int dss_mgr_enable(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
@@ -986,8 +986,7 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
if (r) {
DSSERR("failed to enable manager %d: check_settings failed\n",
mgr->id);
- spin_unlock_irqrestore(&data_lock, flags);
- goto out;
+ goto err;
}
mp->enabled = true;
@@ -1006,6 +1005,13 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
out:
mutex_unlock(&apply_lock);
+
+ return 0;
+
+err:
+ spin_unlock_irqrestore(&data_lock, flags);
+ mutex_unlock(&apply_lock);
+ return r;
}
void dss_mgr_disable(struct omap_overlay_manager *mgr)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index c6caf2f..f91eba3 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -170,7 +170,7 @@ 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);
+int 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);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* [PATCH 65/65] OMAPDSS: check the return value of dss_mgr_enable()
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
` (63 preceding siblings ...)
2011-11-22 9:22 ` [PATCH 64/65] OMAPDSS: APPLY: add return value to dss_mgr_enable() Tomi Valkeinen
@ 2011-11-22 9:22 ` Tomi Valkeinen
64 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 9:22 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Now that dss_mgr_enable returns an error value, check it in all the
places dss_mgr_enable is used, and bail out properly.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dpi.c | 5 ++++-
drivers/video/omap2/dss/dsi.c | 11 ++++++++++-
drivers/video/omap2/dss/hdmi.c | 9 ++++++++-
drivers/video/omap2/dss/sdi.c | 6 +++++-
drivers/video/omap2/dss/venc.c | 26 +++++++++++++++++++++++---
5 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 79c4df3..395d658 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -223,10 +223,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
mdelay(2);
- dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err_mgr_enable;
return 0;
+err_mgr_enable:
err_set_mode:
if (dpi_use_dsi_pll(dssdev))
dsi_pll_uninit(dpi.dsidev, true);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index a35f3fb..57fda24 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3945,6 +3945,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
u8 data_type;
u16 word_count;
+ int r;
if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_VIDEO_MODE) {
switch (dssdev->panel.dsi_pix_fmt) {
@@ -3979,7 +3980,15 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
dsi_if_enable(dsidev, true);
}
- dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r) {
+ if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_VIDEO_MODE) {
+ dsi_if_enable(dsidev, false);
+ dsi_vc_enable(dsidev, channel, false);
+ }
+
+ return r;
+ }
return 0;
}
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index e245a2b..b064762 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -387,9 +387,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
- dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err_mgr_enable;
return 0;
+
+err_mgr_enable:
+ hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
+ hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
+ hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
err:
hdmi_runtime_put();
return -EIO;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 02da8be..8266ca0 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -123,10 +123,14 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
goto err_sdi_enable;
mdelay(2);
- dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err_mgr_enable;
return 0;
+err_mgr_enable:
+ dss_sdi_disable();
err_sdi_enable:
err_set_dispc_clock_div:
err_set_dss_clock_div:
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 101fcd7..b3e9f90 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -417,9 +417,10 @@ static const struct venc_config *venc_timings_to_config(
BUG();
}
-static void venc_power_on(struct omap_dss_device *dssdev)
+static int venc_power_on(struct omap_dss_device *dssdev)
{
u32 l;
+ int r;
venc_reset();
venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
@@ -447,7 +448,22 @@ static void venc_power_on(struct omap_dss_device *dssdev)
if (dssdev->platform_enable)
dssdev->platform_enable(dssdev);
- dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err;
+
+ return 0;
+
+err:
+ venc_write_reg(VENC_OUTPUT_CONTROL, 0);
+ dss_set_dac_pwrdn_bgz(0);
+
+ if (dssdev->platform_disable)
+ dssdev->platform_disable(dssdev);
+
+ regulator_disable(venc.vdda_dac_reg);
+
+ return r;
}
static void venc_power_off(struct omap_dss_device *dssdev)
@@ -504,7 +520,9 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
if (r)
goto err1;
- venc_power_on(dssdev);
+ r = venc_power_on(dssdev);
+ if (r)
+ goto err2;
venc.wss_data = 0;
@@ -512,6 +530,8 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
mutex_unlock(&venc.venc_lock);
return 0;
+err2:
+ venc_runtime_put();
err1:
omap_dss_stop_device(dssdev);
err0:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 91+ messages in thread
* Re: [PATCH 06/65] OMAPDSS: remove partial update from the overlay
2011-11-22 9:21 ` [PATCH 06/65] OMAPDSS: remove partial update from the overlay manager Tomi Valkeinen
@ 2011-11-22 11:53 ` Archit Taneja
0 siblings, 0 replies; 91+ messages in thread
From: Archit Taneja @ 2011-11-22 11:53 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> Partial update for manual update displays has never worked quite well:
> * The HW has limitations on the update area, and the x and width need to
> be even.
There are also some issues with partial update on OMAP4 even when 'x and
width are even'. There seems to be DISPC timeouts when the update area
is too small. Its easy to reproduce it by running the 'rect' test for a
while. For those who are interested, the rect testcase can be found in:
git://gitorious.org/linux-omap-dss2/omapfb-tests.git
Archit
> * Showing a part of a scaled overlay causes artifacts.
> * Makes the management of dispc very complex
>
> Considering the above points and the fact that partial update is not
> used anywhere, this and the following patches remove the partial update
> support. This will greatly simplify the following re-write of the apply
> mechanism to get proper locking and additional features like fifo-merge.
>
> This patch removes the partial update from the manager.c.
>
> Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
> ---
> drivers/video/omap2/dss/dsi.c | 2 -
> drivers/video/omap2/dss/dss.h | 3 -
> drivers/video/omap2/dss/manager.c | 333 +------------------------------------
> drivers/video/omap2/dss/rfbi.c | 1 -
> 4 files changed, 6 insertions(+), 333 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> index 5abf8e7..787cebd 100644
> --- a/drivers/video/omap2/dss/dsi.c
> +++ b/drivers/video/omap2/dss/dsi.c
> @@ -4172,8 +4172,6 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
>
> dsi_perf_mark_setup(dsidev);
>
> - dss_setup_partial_planes(dssdev, x, y, w, h,
> - enlarge_update_area);
> dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
>
> return 0;
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 313a7ca..7f6a612 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -182,9 +182,6 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
> int dss_init_overlay_managers(struct platform_device *pdev);
> void dss_uninit_overlay_managers(struct platform_device *pdev);
> int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
> -void dss_setup_partial_planes(struct omap_dss_device *dssdev,
> - u16 *x, u16 *y, u16 *w, u16 *h,
> - bool enlarge_update_area);
> void dss_start_update(struct omap_dss_device *dssdev);
>
> /* overlay */
> diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
> index 1be5f47..c616f85 100644
> --- a/drivers/video/omap2/dss/manager.c
> +++ b/drivers/video/omap2/dss/manager.c
> @@ -530,13 +530,6 @@ struct manager_cache_data {
>
> bool manual_update;
> bool do_manual_update;
> -
> - /* manual update region */
> - u16 x, y, w, h;
> -
> - /* enlarge the update area if the update area contains scaled
> - * overlays */
> - bool enlarge_update_area;
> };
>
> static struct {
> @@ -762,65 +755,11 @@ static int overlay_enabled(struct omap_overlay *ovl)
> return ovl->info.enabled&& ovl->manager&& ovl->manager->device;
> }
>
> -/* Is rect1 a subset of rect2? */
> -static bool rectangle_subset(int x1, int y1, int w1, int h1,
> - int x2, int y2, int w2, int h2)
> -{
> - if (x1< x2 || y1< y2)
> - return false;
> -
> - if (x1 + w1> x2 + w2)
> - return false;
> -
> - if (y1 + h1> y2 + h2)
> - return false;
> -
> - return true;
> -}
> -
> -/* Do rect1 and rect2 overlap? */
> -static bool rectangle_intersects(int x1, int y1, int w1, int h1,
> - int x2, int y2, int w2, int h2)
> -{
> - if (x1>= x2 + w2)
> - return false;
> -
> - if (x2>= x1 + w1)
> - return false;
> -
> - if (y1>= y2 + h2)
> - return false;
> -
> - if (y2>= y1 + h1)
> - return false;
> -
> - return true;
> -}
> -
> -static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc)
> -{
> - struct omap_overlay_info *oi =&oc->info;
> -
> - if (oi->out_width != 0&& oi->width != oi->out_width)
> - return true;
> -
> - if (oi->out_height != 0&& oi->height != oi->out_height)
> - return true;
> -
> - return false;
> -}
> -
> static int configure_overlay(enum omap_plane plane)
> {
> struct overlay_cache_data *c;
> - struct manager_cache_data *mc;
> - struct omap_overlay_info *oi, new_oi;
> - struct omap_overlay_manager_info *mi;
> - u16 outw, outh;
> - u16 x, y, w, h;
> - u32 paddr;
> + struct omap_overlay_info *oi;
> int r;
> - u16 orig_w, orig_h, orig_outw, orig_outh;
>
> DSSDBGF("%d", plane);
>
> @@ -832,120 +771,7 @@ static int configure_overlay(enum omap_plane plane)
> return 0;
> }
>
> - mc =&dss_cache.manager_cache[c->channel];
> - mi =&mc->info;
> -
> - x = oi->pos_x;
> - y = oi->pos_y;
> - w = oi->width;
> - h = oi->height;
> - outw = oi->out_width = 0 ? oi->width : oi->out_width;
> - outh = oi->out_height = 0 ? oi->height : oi->out_height;
> - paddr = oi->paddr;
> -
> - orig_w = w;
> - orig_h = h;
> - orig_outw = outw;
> - orig_outh = outh;
> -
> - if (mc->manual_update&& mc->do_manual_update) {
> - unsigned bpp;
> - unsigned scale_x_m = w, scale_x_d = outw;
> - unsigned scale_y_m = h, scale_y_d = outh;
> -
> - /* If the overlay is outside the update region, disable it */
> - if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
> - x, y, outw, outh)) {
> - dispc_ovl_enable(plane, 0);
> - return 0;
> - }
> -
> - switch (oi->color_mode) {
> - case OMAP_DSS_COLOR_NV12:
> - bpp = 8;
> - break;
> - case OMAP_DSS_COLOR_RGB16:
> - case OMAP_DSS_COLOR_ARGB16:
> - case OMAP_DSS_COLOR_YUV2:
> - case OMAP_DSS_COLOR_UYVY:
> - case OMAP_DSS_COLOR_RGBA16:
> - case OMAP_DSS_COLOR_RGBX16:
> - case OMAP_DSS_COLOR_ARGB16_1555:
> - case OMAP_DSS_COLOR_XRGB16_1555:
> - bpp = 16;
> - break;
> -
> - case OMAP_DSS_COLOR_RGB24P:
> - bpp = 24;
> - break;
> -
> - case OMAP_DSS_COLOR_RGB24U:
> - case OMAP_DSS_COLOR_ARGB32:
> - case OMAP_DSS_COLOR_RGBA32:
> - case OMAP_DSS_COLOR_RGBX32:
> - bpp = 32;
> - break;
> -
> - default:
> - BUG();
> - }
> -
> - if (mc->x> oi->pos_x) {
> - x = 0;
> - outw -= (mc->x - oi->pos_x);
> - paddr += (mc->x - oi->pos_x) *
> - scale_x_m / scale_x_d * bpp / 8;
> - } else {
> - x = oi->pos_x - mc->x;
> - }
> -
> - if (mc->y> oi->pos_y) {
> - y = 0;
> - outh -= (mc->y - oi->pos_y);
> - paddr += (mc->y - oi->pos_y) *
> - scale_y_m / scale_y_d *
> - oi->screen_width * bpp / 8;
> - } else {
> - y = oi->pos_y - mc->y;
> - }
> -
> - if (mc->w< (x + outw))
> - outw -= (x + outw) - (mc->w);
> -
> - if (mc->h< (y + outh))
> - outh -= (y + outh) - (mc->h);
> -
> - w = w * outw / orig_outw;
> - h = h * outh / orig_outh;
> -
> - /* YUV mode overlay's input width has to be even and the
> - * algorithm above may adjust the width to be odd.
> - *
> - * Here we adjust the width if needed, preferring to increase
> - * the width if the original width was bigger.
> - */
> - if ((w& 1)&&
> - (oi->color_mode = OMAP_DSS_COLOR_YUV2 ||
> - oi->color_mode = OMAP_DSS_COLOR_UYVY)) {
> - if (orig_w> w)
> - w += 1;
> - else
> - w -= 1;
> - }
> - }
> -
> - new_oi = *oi;
> -
> - /* update new_oi members which could have been possibly updated */
> - new_oi.pos_x = x;
> - new_oi.pos_y = y;
> - new_oi.width = w;
> - new_oi.height = h;
> - new_oi.out_width = outw;
> - new_oi.out_height = outh;
> - new_oi.paddr = paddr;
> -
> - r = dispc_ovl_setup(plane,&new_oi, c->ilace, c->channel,
> + r = dispc_ovl_setup(plane, oi, c->ilace, c->channel,
> c->replication, c->fifo_low, c->fifo_high);
> if (r) {
> /* this shouldn't happen */
> @@ -1070,170 +896,23 @@ static int configure_dispc(void)
> return r;
> }
>
> -/* Make the coordinates even. There are some strange problems with OMAP and
> - * partial DSI update when the update widths are odd. */
> -static void make_even(u16 *x, u16 *w)
> -{
> - u16 x1, x2;
> -
> - x1 = *x;
> - x2 = *x + *w;
> -
> - x1&= ~1;
> - x2 = ALIGN(x2, 2);
> -
> - *x = x1;
> - *w = x2 - x1;
> -}
> -
> -/* Configure dispc for partial update. Return possibly modified update
> - * area */
> -void dss_setup_partial_planes(struct omap_dss_device *dssdev,
> - u16 *xi, u16 *yi, u16 *wi, u16 *hi, bool enlarge_update_area)
> +void dss_start_update(struct omap_dss_device *dssdev)
> {
> - struct overlay_cache_data *oc;
> struct manager_cache_data *mc;
> - struct omap_overlay_info *oi;
> + struct overlay_cache_data *oc;
> const int num_ovls = dss_feat_get_num_ovls();
> + const int num_mgrs = dss_feat_get_num_mgrs();
> struct omap_overlay_manager *mgr;
> int i;
> - u16 x, y, w, h;
> - unsigned long flags;
> - bool area_changed;
> -
> - x = *xi;
> - y = *yi;
> - w = *wi;
> - h = *hi;
> -
> - DSSDBG("dispc_setup_partial_planes %d,%d %dx%d\n",
> - *xi, *yi, *wi, *hi);
>
> mgr = dssdev->manager;
>
> - if (!mgr) {
> - DSSDBG("no manager\n");
> - return;
> - }
> -
> - make_even(&x,&w);
> -
> - spin_lock_irqsave(&dss_cache.lock, flags);
> -
> - /*
> - * Execute the outer loop until the inner loop has completed
> - * once without increasing the update area. This will ensure that
> - * all scaled overlays end up completely within the update area.
> - */
> - do {
> - area_changed = false;
> -
> - /* We need to show the whole overlay if it is scaled. So look
> - * for those, and make the update area larger if found.
> - * Also mark the overlay cache dirty */
> - for (i = 0; i< num_ovls; ++i) {
> - unsigned x1, y1, x2, y2;
> - unsigned outw, outh;
> -
> - oc =&dss_cache.overlay_cache[i];
> - oi =&oc->info;
> -
> - if (oc->channel != mgr->id)
> - continue;
> -
> - oc->dirty = true;
> -
> - if (!enlarge_update_area)
> - continue;
> -
> - if (!oc->enabled)
> - continue;
> -
> - if (!dispc_is_overlay_scaled(oc))
> - continue;
> -
> - outw = oi->out_width = 0 ?
> - oi->width : oi->out_width;
> - outh = oi->out_height = 0 ?
> - oi->height : oi->out_height;
> -
> - /* is the overlay outside the update region? */
> - if (!rectangle_intersects(x, y, w, h,
> - oi->pos_x, oi->pos_y,
> - outw, outh))
> - continue;
> -
> - /* if the overlay totally inside the update region? */
> - if (rectangle_subset(oi->pos_x, oi->pos_y, outw, outh,
> - x, y, w, h))
> - continue;
> -
> - if (x> oi->pos_x)
> - x1 = oi->pos_x;
> - else
> - x1 = x;
> -
> - if (y> oi->pos_y)
> - y1 = oi->pos_y;
> - else
> - y1 = y;
> -
> - if ((x + w)< (oi->pos_x + outw))
> - x2 = oi->pos_x + outw;
> - else
> - x2 = x + w;
> -
> - if ((y + h)< (oi->pos_y + outh))
> - y2 = oi->pos_y + outh;
> - else
> - y2 = y + h;
> -
> - x = x1;
> - y = y1;
> - w = x2 - x1;
> - h = y2 - y1;
> -
> - make_even(&x,&w);
> -
> - DSSDBG("changing upd area due to ovl(%d) "
> - "scaling %d,%d %dx%d\n",
> - i, x, y, w, h);
> -
> - area_changed = true;
> - }
> - } while (area_changed);
> -
> mc =&dss_cache.manager_cache[mgr->id];
> - mc->do_manual_update = true;
> - mc->enlarge_update_area = enlarge_update_area;
> - mc->x = x;
> - mc->y = y;
> - mc->w = w;
> - mc->h = h;
>
> + mc->do_manual_update = true;
> configure_dispc();
> -
> mc->do_manual_update = false;
>
> - spin_unlock_irqrestore(&dss_cache.lock, flags);
> -
> - *xi = x;
> - *yi = y;
> - *wi = w;
> - *hi = h;
> -}
> -
> -void dss_start_update(struct omap_dss_device *dssdev)
> -{
> - struct manager_cache_data *mc;
> - struct overlay_cache_data *oc;
> - const int num_ovls = dss_feat_get_num_ovls();
> - const int num_mgrs = dss_feat_get_num_mgrs();
> - struct omap_overlay_manager *mgr;
> - int i;
> -
> - mgr = dssdev->manager;
> -
> for (i = 0; i< num_ovls; ++i) {
> oc =&dss_cache.overlay_cache[i];
> if (oc->channel != mgr->id)
> diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
> index 1130c60..814bb95 100644
> --- a/drivers/video/omap2/dss/rfbi.c
> +++ b/drivers/video/omap2/dss/rfbi.c
> @@ -784,7 +784,6 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
> if (*w = 0 || *h = 0)
> return -EINVAL;
>
> - dss_setup_partial_planes(dssdev, x, y, w, h, true);
> dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
>
> return 0;
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 08/65] OMAPDSS: remove partial update from panel-taal
2011-11-22 9:21 ` [PATCH 08/65] OMAPDSS: remove partial update from panel-taal Tomi Valkeinen
@ 2011-11-22 11:55 ` Archit Taneja
2011-11-22 12:32 ` Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-11-22 11:55 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> Partial update for manual update displays has never worked quite well:
> * The HW has limitations on the update area, and the x and width need to
> be even.
> * Showing a part of a scaled overlay causes artifacts.
> * Makes the management of dispc very complex
>
> Considering the above points and the fact that partial update is not
> used anywhere, this and the following patches remove the partial update
> support. This will greatly simplify the following re-write of the apply
> mechanism to get proper locking and additional features like fifo-merge.
>
> This patch removes the partial update from the panel-taal.c.
>
> Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
> ---
> drivers/video/omap2/displays/panel-taal.c | 16 ++++------------
> 1 files changed, 4 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
> index 0aa6c5d..dd64bd1 100644
> --- a/drivers/video/omap2/displays/panel-taal.c
> +++ b/drivers/video/omap2/displays/panel-taal.c
> @@ -198,12 +198,6 @@ struct taal_data {
> bool te_enabled;
>
> atomic_t do_update;
> - struct {
> - u16 x;
> - u16 y;
> - u16 w;
> - u16 h;
> - } update_region;
> int channel;
>
> struct delayed_work te_timeout_work;
> @@ -1440,16 +1434,14 @@ static int taal_update(struct omap_dss_device *dssdev,
> goto err;
> }
>
> - r = taal_set_update_window(td, x, y, w, h);
> + /* XXX no need to send this every frame, but dsi break if not done */
> + r = taal_set_update_window(td, 0, 0,
> + td->panel_config->timings.x_res,
> + td->panel_config->timings.y_res);
How about sending a null short packet, and a BTA after that. This will
keep automatic TE mode in place, and we'll need to send 1 short packet
instead of 2 long packets every frame.
We should of course do this if we aren't planning to get partial update
back in the near future.
Archit
> if (r)
> goto err;
>
> if (td->te_enabled&& panel_data->use_ext_te) {
> - td->update_region.x = x;
> - td->update_region.y = y;
> - td->update_region.w = w;
> - td->update_region.h = h;
> - barrier();
> schedule_delayed_work(&td->te_timeout_work,
> msecs_to_jiffies(250));
> atomic_set(&td->do_update, 1);
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 08/65] OMAPDSS: remove partial update from panel-taal
2011-11-22 11:55 ` Archit Taneja
@ 2011-11-22 12:32 ` Tomi Valkeinen
2011-11-23 5:51 ` Archit Taneja
0 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-22 12:32 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 803 bytes --]
On Tue, 2011-11-22 at 17:23 +0530, Archit Taneja wrote:
> > - r = taal_set_update_window(td, x, y, w, h);
> > + /* XXX no need to send this every frame, but dsi break if not
> done */
> > + r = taal_set_update_window(td, 0, 0,
> > + td->panel_config->timings.x_res,
> > + td->panel_config->timings.y_res);
>
> How about sending a null short packet, and a BTA after that. This
> will
> keep automatic TE mode in place, and we'll need to send 1 short
> packet
> instead of 2 long packets every frame.
To be honest, I didn't spend any time with this. True, sending a null
packet and BTA instead of the 2 long packets is possible. But probably
even better would be to track the TE status, and send a BTA only when
needed.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 08/65] OMAPDSS: remove partial update from panel-taal
2011-11-22 12:32 ` Tomi Valkeinen
@ 2011-11-23 5:51 ` Archit Taneja
0 siblings, 0 replies; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 5:51 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Tuesday 22 November 2011 06:02 PM, Tomi Valkeinen wrote:
> On Tue, 2011-11-22 at 17:23 +0530, Archit Taneja wrote:
>>> - r = taal_set_update_window(td, x, y, w, h);
>>> + /* XXX no need to send this every frame, but dsi break if not
>> done */
>>> + r = taal_set_update_window(td, 0, 0,
>>> + td->panel_config->timings.x_res,
>>> + td->panel_config->timings.y_res);
>>
>> How about sending a null short packet, and a BTA after that. This
>> will
>> keep automatic TE mode in place, and we'll need to send 1 short
>> packet
>> instead of 2 long packets every frame.
>
> To be honest, I didn't spend any time with this. True, sending a null
> packet and BTA instead of the 2 long packets is possible. But probably
> even better would be to track the TE status, and send a BTA only when
> needed.
Right, if we maintain the TE status, we may not need to send a packet at
all, so I guess we could stick with this for now, and remove it once we
start maintaining the number of BTAs we have sent to the panel.
Archit
>
> Tomi
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update
2011-11-22 9:21 ` [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update Tomi Valkeinen
@ 2011-11-23 5:55 ` Archit Taneja
2011-11-23 7:32 ` Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 5:55 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> dss_start_update() takes currently the dss device as a parameter. Change
> the parameter to ovl manager, as that is what the dss_start_update()
> actually needs.
Minor comment: We could rename dss_start_update() to
dss_mgr_start_update() to stick to the new way of telling if this
function is meant for an overlay or a manager.
Archit
>
> Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
> ---
> drivers/video/omap2/dss/dsi.c | 2 +-
> drivers/video/omap2/dss/dss.h | 2 +-
> drivers/video/omap2/dss/manager.c | 7 ++-----
> 3 files changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> index 9ef04ff..e5a2dcc 100644
> --- a/drivers/video/omap2/dss/dsi.c
> +++ b/drivers/video/omap2/dss/dsi.c
> @@ -4063,7 +4063,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
> msecs_to_jiffies(250));
> BUG_ON(r = 0);
>
> - dss_start_update(dssdev);
> + dss_start_update(dssdev->manager);
>
> if (dsi->te_enabled) {
> /* disable LP_RX_TO, so that we can receive TE. Time to wait
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 7f6a612..0937bd8 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -182,7 +182,7 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
> int dss_init_overlay_managers(struct platform_device *pdev);
> void dss_uninit_overlay_managers(struct platform_device *pdev);
> int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
> -void dss_start_update(struct omap_dss_device *dssdev);
> +void dss_start_update(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 c616f85..bc28bfa 100644
> --- a/drivers/video/omap2/dss/manager.c
> +++ b/drivers/video/omap2/dss/manager.c
> @@ -896,17 +896,14 @@ static int configure_dispc(void)
> return r;
> }
>
> -void dss_start_update(struct omap_dss_device *dssdev)
> +void dss_start_update(struct omap_overlay_manager *mgr)
> {
> struct manager_cache_data *mc;
> struct overlay_cache_data *oc;
> const int num_ovls = dss_feat_get_num_ovls();
> const int num_mgrs = dss_feat_get_num_mgrs();
> - struct omap_overlay_manager *mgr;
> int i;
>
> - mgr = dssdev->manager;
> -
> mc =&dss_cache.manager_cache[mgr->id];
>
> mc->do_manual_update = true;
> @@ -929,7 +926,7 @@ void dss_start_update(struct omap_dss_device *dssdev)
> mc->shadow_dirty = false;
> }
>
> - dssdev->manager->enable(dssdev->manager);
> + mgr->enable(mgr);
> }
>
> static void dss_apply_irq_handler(void *data, u32 mask)
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update
2011-11-23 5:55 ` Archit Taneja
@ 2011-11-23 7:32 ` Tomi Valkeinen
0 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-23 7:32 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 522 bytes --]
On Wed, 2011-11-23 at 11:23 +0530, Archit Taneja wrote:
> On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> > dss_start_update() takes currently the dss device as a parameter. Change
> > the parameter to ovl manager, as that is what the dss_start_update()
> > actually needs.
>
> Minor comment: We could rename dss_start_update() to
> dss_mgr_start_update() to stick to the new way of telling if this
> function is meant for an overlay or a manager.
Good point, I'll make the change.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
2011-11-22 9:21 ` [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct Tomi Valkeinen
@ 2011-11-23 9:37 ` Archit Taneja
2011-11-23 9:39 ` Archit Taneja
2011-11-23 10:29 ` Sergey Kibrik
1 sibling, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 9:37 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> 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;
Minor comment: The name 'data_lock' doesn't tell much that its
protecting the dss_cache struct. Probably 'cache_lock' or
'priv_data_lock' or something like that may be more informative.
Archit
> +
> 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();
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
2011-11-23 9:37 ` Archit Taneja
@ 2011-11-23 9:39 ` Archit Taneja
0 siblings, 0 replies; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 9:39 UTC (permalink / raw)
To: Archit Taneja; +Cc: Tomi Valkeinen, linux-fbdev, linux-omap, archit
On Wednesday 23 November 2011 02:55 PM, Archit Taneja wrote:
<snip>
>
> Minor comment: The name 'data_lock' doesn't tell much that its
> protecting the dss_cache struct. Probably 'cache_lock' or
> 'priv_data_lock' or something like that may be more informative.
>
> Archit
Ah, just saw the next patch, you renamed dss_cache to dss_data, so
'data_lock' seems to make more sense now.
Archit
>
>> +
>> 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();
>>
>
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 40/65] OMAPDSS: APPLY: add mutex
2011-11-22 9:21 ` [PATCH 40/65] OMAPDSS: APPLY: add mutex Tomi Valkeinen
@ 2011-11-23 9:49 ` Archit Taneja
2011-11-23 10:17 ` Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 9:49 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
Hi,
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> 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.
Small sentence issue above, both groups are called the 'other group'.
>
> 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.
Previously, when we changed the links between 'overlay->managers' and
'manager->devices', it wasn't protected by a lock. Why is it needed now?
As an example, suppose we are changing a manager's device to some other
display. Is this lock preventing someone else to get the older
'mgr->device' rather than the new one?
Archit
>
> 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;
> }
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock
2011-11-22 9:21 ` [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock Tomi Valkeinen
@ 2011-11-23 9:57 ` Archit Taneja
2011-11-23 10:12 ` Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 9:57 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> 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);
> }
The get/set info functions for overlays and managers only modify the
omap_overlay_info or manager_info structs, these aren't really a part of
'dss_data', they only become a part of dss_data only when we call
mgr->apply().
So, are we protecting these functions so that 2 users of the same
overlay don't see incorrect info values?
Archit
>
> int dss_ovl_set_manager(struct omap_overlay *ovl,
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock
2011-11-23 9:57 ` Archit Taneja
@ 2011-11-23 10:12 ` Tomi Valkeinen
0 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-23 10:12 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 1663 bytes --]
On Wed, 2011-11-23 at 15:26 +0530, Archit Taneja wrote:
> On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> > 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);
> > }
>
> The get/set info functions for overlays and managers only modify the
> omap_overlay_info or manager_info structs, these aren't really a part of
> 'dss_data', they only become a part of dss_data only when we call
> mgr->apply().
>
> So, are we protecting these functions so that 2 users of the same
> overlay don't see incorrect info values?
True, at this point the data_lock is a bit vague, and is protecting also
the info fields in omap_overlay and omap_overlay_manager.
A lock is needed, though, as otherwise the info struct may be only
partial. E.g. somebody calls set_info, which is half way copying the
values, and somebody else calls apply or get_info.
In the next patches the infos will be moved into the dss_data, and then
using dss_lock spin lock makes more sense.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 40/65] OMAPDSS: APPLY: add mutex
2011-11-23 9:49 ` Archit Taneja
@ 2011-11-23 10:17 ` Tomi Valkeinen
0 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-23 10:17 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 2410 bytes --]
On Wed, 2011-11-23 at 15:18 +0530, Archit Taneja wrote:
> Hi,
>
> On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> > 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.
>
> Small sentence issue above, both groups are called the 'other group'.
Thanks, fixed.
> >
> > 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.
>
> Previously, when we changed the links between 'overlay->managers' and
> 'manager->devices', it wasn't protected by a lock. Why is it needed now?
Previously many places were missing a lock =).
> As an example, suppose we are changing a manager's device to some other
> display. Is this lock preventing someone else to get the older
> 'mgr->device' rather than the new one?
Hmm. We need some lock there, that's for sure, as set/unset manager are
changing the manager's list of overlays. However, it is also protected
by the spinlock, so in that sense mutex is not necessary.
I have to say I'm not sure if mutex is needed at this point. However,
consider the end result when fifo-merge is used:
dss_ovl_enable() will take the mutex, then it does the configuration in
multiple steps, doing multiple spin_lock & spin_unlocks, waiting in
between.
If we had only a spinlock in set/unset_manager, the manager could be
changed while dss_ovl_enable is doing the process of enabling the
overlay.
So I may have added mutexes or spinlocks a bit early in the series to
some places, but I don't see any harm in that. It'd be rather difficult
to try to find the exact spots where a lock becomes a requirement.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode
2011-11-22 9:21 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays Tomi Valkeinen
@ 2011-11-23 10:22 ` Archit Taneja
2011-11-23 10:42 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 10:22 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> 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.
dsi_video_mode_enable() doesn't only enable the DISPC output, it also
sends the long packet header to start video mode transfer.
I think it would be better if we had 2 separate functions, one which
starts/stops DSI video mode, and the other which enables/disables the
DISPC video port.
This way, a manual update panel would need to call only
dsi_enable/disable_video_output(which just enables or disables the
manager), whereas a video mode panel will need to call both.
This is just a suggestion though. It's probably okay to have both in the
same function too. We might have to separate them out later if we were
planning to standardise mipi dsi across SoCs.
Archit
>
> 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 {
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
2011-11-22 9:21 ` [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct Tomi Valkeinen
2011-11-23 9:37 ` Archit Taneja
@ 2011-11-23 10:29 ` Sergey Kibrik
2011-11-23 10:47 ` Tomi Valkeinen
1 sibling, 1 reply; 91+ messages in thread
From: Sergey Kibrik @ 2011-11-23 10:29 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On 11/22/2011 11:21 AM, Tomi Valkeinen wrote:
> 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.
a small question: isn't it clearer to keep lock inside struct, so it would be easier to read code? Say, if we meet
> spin_lock_irqsave(&dss_cache.lock, flags);
in code we already aware of what struct being actually protected, and in case of external lock it's not that obvious
--
regards,
Sergey
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd
2011-11-23 10:22 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
@ 2011-11-23 10:42 ` Tomi Valkeinen
2011-11-23 11:20 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
0 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-23 10:42 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 3031 bytes --]
On Wed, 2011-11-23 at 15:40 +0530, Archit Taneja wrote:
> On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> > 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.
>
> dsi_video_mode_enable() doesn't only enable the DISPC output, it also
> sends the long packet header to start video mode transfer.
>
> I think it would be better if we had 2 separate functions, one which
> starts/stops DSI video mode, and the other which enables/disables the
> DISPC video port.
>
> This way, a manual update panel would need to call only
> dsi_enable/disable_video_output(which just enables or disables the
> manager), whereas a video mode panel will need to call both.
>
> This is just a suggestion though. It's probably okay to have both in the
> same function too. We might have to separate them out later if we were
> planning to standardise mipi dsi across SoCs.
If you think from the panel driver's point of view, it doesn't know
about DISPC. It just wants to enable the video stream (on video mode
displays).
If we had two functions, could only the first be used? I.e. is it
possible to just enable the video mode transfer, without enabling DISPC?
If not, I'm not sure what would be the use for two separate functions.
And even if it can, I'm not sure what use it would be to enable only the
video mode output without the actual pixel data from DISPC.
It is true that the function in thsi patch is not the best one. For
command mode display it's more about reserving the ovl manager for use
than actually enabling it. Then again, how I thought the function's
purpose was that it enables the DSI video output, but because for
command mode there's need to trigger the actual frame transfer later,
the function doesn't start the pixel feed for command mode displays. It
just "prepares" the output.
But even if we had the functions separated, the function called by video
mode and command mode displays would be different, as for the former one
it enables the pixel stream, and for latter one it just reserves the
output.
So, I'm fine with changing the function, but the reasoning for what
functions we have and what they do should come from the panel driver's
perspective, not because of OMAP DSS's HW details.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
2011-11-23 10:29 ` Sergey Kibrik
@ 2011-11-23 10:47 ` Tomi Valkeinen
0 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-23 10:47 UTC (permalink / raw)
To: Sergey Kibrik; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 1276 bytes --]
On Wed, 2011-11-23 at 12:29 +0200, Sergey Kibrik wrote:
> On 11/22/2011 11:21 AM, Tomi Valkeinen wrote:
> > 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.
>
> a small question: isn't it clearer to keep lock inside struct, so it would be easier to read code? Say, if we meet
>
> > spin_lock_irqsave(&dss_cache.lock, flags);
>
> in code we already aware of what struct being actually protected, and in case of external lock it's not that obvious
But if you meet code like:
op = get_ovl_priv(ovl);
You don't see that the data is inside the struct protected with the
spinlock. So you still need to understand what it protects, and what the
above function returns.
But I see your point. I'm not sure which way is better. I thought it
like this: the lock protects a struct, but if the lock is inside the
struct, the lock would protect also itself. Which it doesn't.
That said, I'm fine with both ways. It doesn't matter much. I didn't
really look for any established patterns for this in the kernel code,
but if everybody else have their locks inside the structs they protect,
then obviously we should also.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode
2011-11-23 10:42 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd Tomi Valkeinen
@ 2011-11-23 11:20 ` Archit Taneja
2011-11-23 11:27 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 11:20 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Wednesday 23 November 2011 04:12 PM, Tomi Valkeinen wrote:
> On Wed, 2011-11-23 at 15:40 +0530, Archit Taneja wrote:
>> On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
>>> 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.
>>
>> dsi_video_mode_enable() doesn't only enable the DISPC output, it also
>> sends the long packet header to start video mode transfer.
>>
>> I think it would be better if we had 2 separate functions, one which
>> starts/stops DSI video mode, and the other which enables/disables the
>> DISPC video port.
>>
>> This way, a manual update panel would need to call only
>> dsi_enable/disable_video_output(which just enables or disables the
>> manager), whereas a video mode panel will need to call both.
>>
>> This is just a suggestion though. It's probably okay to have both in the
>> same function too. We might have to separate them out later if we were
>> planning to standardise mipi dsi across SoCs.
>
> If you think from the panel driver's point of view, it doesn't know
> about DISPC. It just wants to enable the video stream (on video mode
> displays).
>
> If we had two functions, could only the first be used? I.e. is it
> possible to just enable the video mode transfer, without enabling DISPC?
> If not, I'm not sure what would be the use for two separate functions.
> And even if it can, I'm not sure what use it would be to enable only the
> video mode output without the actual pixel data from DISPC.
>
> It is true that the function in thsi patch is not the best one. For
> command mode display it's more about reserving the ovl manager for use
> than actually enabling it. Then again, how I thought the function's
> purpose was that it enables the DSI video output, but because for
> command mode there's need to trigger the actual frame transfer later,
> the function doesn't start the pixel feed for command mode displays. It
> just "prepares" the output.
>
> But even if we had the functions separated, the function called by video
> mode and command mode displays would be different, as for the former one
> it enables the pixel stream, and for latter one it just reserves the
> output.
>
> So, I'm fine with changing the function, but the reasoning for what
> functions we have and what they do should come from the panel driver's
> perspective, not because of OMAP DSS's HW details.
If you look from the panel driver's perspective, we shouldn't split this.
I think it would be best to stuff the 'video mode enabling and manager
enabling' functionality in omapdss_dsi_display_enable() itself, the
panel driver shouldn't need to call a function separately to enable
video mode for the panel. This way we would be more along the lines of
the dpi driver, where dpi_display_enable() enables the manager in the end.
I guess we can leave this the way you are doing it currently, and move
this code into dsi_display_enable() code later on.
Archit
>
> Tomi
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd
2011-11-23 11:20 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
@ 2011-11-23 11:27 ` Tomi Valkeinen
2011-11-23 12:25 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
0 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-11-23 11:27 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 712 bytes --]
On Wed, 2011-11-23 at 16:38 +0530, Archit Taneja wrote:
>
> I think it would be best to stuff the 'video mode enabling and
> manager
> enabling' functionality in omapdss_dsi_display_enable() itself, the
> panel driver shouldn't need to call a function separately to enable
> video mode for the panel. This way we would be more along the lines
> of
> the dpi driver, where dpi_display_enable() enables the manager in the
> end.
But we need to configure the panel between enabling the DSI interface
and enabling the video output, so we can't combine those two functions.
For DPI things are simpler, as enabling the interface and the video
output are more or less the same thing.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode
2011-11-23 11:27 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd Tomi Valkeinen
@ 2011-11-23 12:25 ` Archit Taneja
0 siblings, 0 replies; 91+ messages in thread
From: Archit Taneja @ 2011-11-23 12:25 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Wednesday 23 November 2011 04:57 PM, Tomi Valkeinen wrote:
> On Wed, 2011-11-23 at 16:38 +0530, Archit Taneja wrote:
>>
>> I think it would be best to stuff the 'video mode enabling and
>> manager
>> enabling' functionality in omapdss_dsi_display_enable() itself, the
>> panel driver shouldn't need to call a function separately to enable
>> video mode for the panel. This way we would be more along the lines
>> of
>> the dpi driver, where dpi_display_enable() enables the manager in the
>> end.
>
> But we need to configure the panel between enabling the DSI interface
> and enabling the video output, so we can't combine those two functions.
Oh okay, that's right, we can't start video mode before preparing the panel.
Archit
>
> For DPI things are simpler, as enabling the interface and the video
> output are more or less the same thing.
>
> Tomi
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 58/65] OMAPDSS: APPLY: add
2011-12-07 13:19 ` Archit Taneja
@ 2011-12-07 13:15 ` Tomi Valkeinen
0 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-12-07 13:15 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap
[-- Attachment #1: Type: text/plain, Size: 1103 bytes --]
On Wed, 2011-12-07 at 18:37 +0530, Archit Taneja wrote:
> On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> > +/* 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);
> > +}
>
> This function isn't used, are you planning to use it later?
Yes, it's used with the fifo-merge stuff. It could be added later, but
as it's related to the extra_info stuff, I think it fits better here
than with the fifo merge series.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings
2011-11-22 9:22 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings Tomi Valkeinen
@ 2011-12-07 13:17 ` Archit Taneja
2011-12-08 8:29 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-12-07 13:17 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
Hi,
On Tuesday 22 November 2011 02:52 PM, Tomi Valkeinen wrote:
> Add checks for overlay and manager settings. The checks are a bit
> complex, as we need to observe the bigger picture instead of overlays
> and managers independently. Things like the used display and the zorder
> of other overlays affect the validity of the settings.
Minor comment:
dss_ovl_check, dss_mgr_check and dss_mgr_check_zorder don't really
qualify as functions which do actual applying of configurations, they
could be moved from apply.c to manager.c and overlay.c.
Archit
>
> Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
> ---
> drivers/video/omap2/dss/apply.c | 215 ++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 212 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
> index 5d933b9..72afa85 100644
> --- a/drivers/video/omap2/dss/apply.c
> +++ b/drivers/video/omap2/dss/apply.c
> @@ -166,6 +166,169 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
> return mgr->device->caps& OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
> }
>
> +/* Check if overlay parameters are compatible with display */
> +static int dss_ovl_check(struct omap_overlay *ovl,
> + struct omap_overlay_info *info, struct omap_dss_device *dssdev)
> +{
> + u16 outw, outh;
> + u16 dw, dh;
> +
> + if (dssdev = NULL)
> + return 0;
> +
> + dssdev->driver->get_resolution(dssdev,&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) {
> + DSSERR("overlay %d horizontally not inside the display area "
> + "(%d + %d>= %d)\n",
> + ovl->id, info->pos_x, outw, dw);
> + return -EINVAL;
> + }
> +
> + if (dh< info->pos_y + outh) {
> + DSSERR("overlay %d vertically not inside the display area "
> + "(%d + %d>= %d)\n",
> + ovl->id, info->pos_y, outh, dh);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
> + struct omap_overlay_info **overlay_infos)
> +{
> + struct omap_overlay *ovl1, *ovl2;
> + struct ovl_priv_data *op1, *op2;
> + struct omap_overlay_info *info1, *info2;
> +
> + list_for_each_entry(ovl1,&mgr->overlays, list) {
> + op1 = get_ovl_priv(ovl1);
> + info1 = overlay_infos[ovl1->id];
> +
> + if (info1 = NULL)
> + continue;
> +
> + list_for_each_entry(ovl2,&mgr->overlays, list) {
> + if (ovl1 = ovl2)
> + continue;
> +
> + op2 = get_ovl_priv(ovl2);
> + info2 = overlay_infos[ovl2->id];
> +
> + if (info2 = NULL)
> + continue;
> +
> + if (info1->zorder = info2->zorder) {
> + DSSERR("overlays %d and %d have the same "
> + "zorder %d\n",
> + ovl1->id, ovl2->id, info1->zorder);
> + return -EINVAL;
> + }
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int dss_mgr_check(struct omap_overlay_manager *mgr,
> + struct omap_dss_device *dssdev,
> + struct omap_overlay_manager_info *info,
> + struct omap_overlay_info **overlay_infos)
> +{
> + struct omap_overlay *ovl;
> + int r;
> +
> + if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) {
> + r = dss_mgr_check_zorder(mgr, overlay_infos);
> + if (r)
> + return r;
> + }
> +
> + list_for_each_entry(ovl,&mgr->overlays, list) {
> + struct omap_overlay_info *oi;
> + int r;
> +
> + oi = overlay_infos[ovl->id];
> +
> + if (oi = NULL)
> + continue;
> +
> + r = dss_ovl_check(ovl, oi, dssdev);
> + if (r)
> + return r;
> + }
> +
> + return 0;
> +}
> +static int dss_check_settings_low(struct omap_overlay_manager *mgr,
> + struct omap_dss_device *dssdev, bool applying)
> +{
> + struct omap_overlay_info *oi;
> + struct omap_overlay_manager_info *mi;
> + struct omap_overlay *ovl;
> + struct omap_overlay_info *ois[MAX_DSS_OVERLAYS];
> + struct ovl_priv_data *op;
> + struct mgr_priv_data *mp;
> +
> + mp = get_mgr_priv(mgr);
> +
> + if (applying&& mp->user_info_dirty)
> + mi =&mp->user_info;
> + else
> + mi =&mp->info;
> +
> + /* collect the infos to be tested into the array */
> + list_for_each_entry(ovl,&mgr->overlays, list) {
> + op = get_ovl_priv(ovl);
> +
> + if (!op->enabled)
> + oi = NULL;
> + else if (applying&& op->user_info_dirty)
> + oi =&op->user_info;
> + else
> + oi =&op->info;
> +
> + ois[ovl->id] = oi;
> + }
> +
> + return dss_mgr_check(mgr, dssdev, mi, ois);
> +}
> +
> +/*
> + * check manager and overlay settings using overlay_info from data->info
> + */
> +static int dss_check_settings(struct omap_overlay_manager *mgr,
> + struct omap_dss_device *dssdev)
> +{
> + return dss_check_settings_low(mgr, dssdev, false);
> +}
> +
> +/*
> + * check manager and overlay settings using overlay_info from ovl->info if
> + * dirty and from data->info otherwise
> + */
> +static int dss_check_settings_apply(struct omap_overlay_manager *mgr,
> + struct omap_dss_device *dssdev)
> +{
> + return dss_check_settings_low(mgr, dssdev, true);
> +}
> +
> static bool need_isr(void)
> {
> const int num_mgrs = dss_feat_get_num_mgrs();
> @@ -517,6 +680,7 @@ static void dss_write_regs(void)
> for (i = 0; i< num_mgrs; ++i) {
> struct omap_overlay_manager *mgr;
> struct mgr_priv_data *mp;
> + int r;
>
> mgr = omap_dss_get_overlay_manager(i);
> mp = get_mgr_priv(mgr);
> @@ -524,6 +688,13 @@ static void dss_write_regs(void)
> if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
> continue;
>
> + r = dss_check_settings(mgr, mgr->device);
> + if (r) {
> + DSSERR("cannot write registers for manager %s: "
> + "illegal configuration\n", mgr->name);
> + continue;
> + }
> +
> dss_mgr_write_regs(mgr);
>
> if (need_go(mgr)) {
> @@ -541,11 +712,19 @@ void dss_start_update(struct omap_overlay_manager *mgr)
> {
> struct mgr_priv_data *mp = get_mgr_priv(mgr);
> unsigned long flags;
> + int r;
>
> spin_lock_irqsave(&data_lock, flags);
>
> WARN_ON(mp->updating);
>
> + r = dss_check_settings(mgr, mgr->device);
> + if (r) {
> + DSSERR("cannot start manual update: illegal configuration\n");
> + spin_unlock_irqrestore(&data_lock, flags);
> + return;
> + }
> +
> dss_mgr_write_regs(mgr);
>
> mp->updating = true;
> @@ -690,11 +869,19 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
> {
> unsigned long flags;
> struct omap_overlay *ovl;
> + int r;
>
> DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
>
> spin_lock_irqsave(&data_lock, flags);
>
> + r = dss_check_settings_apply(mgr, mgr->device);
> + if (r) {
> + spin_unlock_irqrestore(&data_lock, flags);
> + DSSERR("failed to apply settings: illegal configuration.\n");
> + return r;
> + }
> +
> /* Configure overlays */
> list_for_each_entry(ovl,&mgr->overlays, list)
> omap_dss_mgr_apply_ovl(ovl);
> @@ -784,6 +971,7 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
> {
> struct mgr_priv_data *mp = get_mgr_priv(mgr);
> unsigned long flags;
> + int r;
>
> mutex_lock(&apply_lock);
>
> @@ -793,6 +981,16 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr)
> spin_lock_irqsave(&data_lock, flags);
>
> mp->enabled = true;
> + r = dss_check_settings(mgr, mgr->device);
> + mp->enabled = false;
> + if (r) {
> + DSSERR("failed to enable manager %d: check_settings failed\n",
> + mgr->id);
> + spin_unlock_irqrestore(&data_lock, flags);
> + goto out;
> + }
> +
> + mp->enabled = true;
>
> dss_mgr_setup_fifos(mgr);
>
> @@ -1142,16 +1340,25 @@ int dss_ovl_enable(struct omap_overlay *ovl)
>
> if (op->enabled) {
> r = 0;
> - goto err;
> + goto err1;
> }
>
> if (ovl->manager = NULL || ovl->manager->device = NULL) {
> r = -EINVAL;
> - goto err;
> + goto err1;
> }
>
> spin_lock_irqsave(&data_lock, flags);
>
> + op->enabled = true;
> + r = dss_check_settings(ovl->manager, ovl->manager->device);
> + op->enabled = false;
> + if (r) {
> + DSSERR("failed to enable overlay %d: check_settings failed\n",
> + ovl->id);
> + goto err2;
> + }
> +
> dss_apply_ovl_enable(ovl, true);
>
> dss_ovl_setup_fifo(ovl);
> @@ -1163,7 +1370,9 @@ int dss_ovl_enable(struct omap_overlay *ovl)
> mutex_unlock(&apply_lock);
>
> return 0;
> -err:
> +err2:
> + spin_unlock_irqrestore(&data_lock, flags);
> +err1:
> mutex_unlock(&apply_lock);
> return r;
> }
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates()
2011-11-22 9:21 ` [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates() Tomi Valkeinen
@ 2011-12-07 13:19 ` Archit Taneja
2011-12-07 13:15 ` [PATCH 58/65] OMAPDSS: APPLY: add Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-12-07 13:19 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote:
> 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);
> +}
This function isn't used, are you planning to use it later?
Archit
> +
> 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();
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs
2011-12-07 13:17 ` Archit Taneja
@ 2011-12-08 8:29 ` Tomi Valkeinen
2011-12-13 10:14 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings Archit Taneja
0 siblings, 1 reply; 91+ messages in thread
From: Tomi Valkeinen @ 2011-12-08 8:29 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 984 bytes --]
On Wed, 2011-12-07 at 18:35 +0530, Archit Taneja wrote:
> Hi,
>
> On Tuesday 22 November 2011 02:52 PM, Tomi Valkeinen wrote:
> > Add checks for overlay and manager settings. The checks are a bit
> > complex, as we need to observe the bigger picture instead of overlays
> > and managers independently. Things like the used display and the zorder
> > of other overlays affect the validity of the settings.
>
> Minor comment:
>
> dss_ovl_check, dss_mgr_check and dss_mgr_check_zorder don't really
> qualify as functions which do actual applying of configurations, they
> could be moved from apply.c to manager.c and overlay.c.
I had the check functions in apply.c because they used apply.c's
internal datastructures.
However, looking the functions now, only dss_mgr_check_zorder() used the
internal datas, and the function doesn't even use those variables for
anything =).
So you're right, they can be moved to manager.c and overlay.c, thanks.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings
2011-12-08 8:29 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs Tomi Valkeinen
@ 2011-12-13 10:14 ` Archit Taneja
2011-12-13 11:16 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs Tomi Valkeinen
0 siblings, 1 reply; 91+ messages in thread
From: Archit Taneja @ 2011-12-13 10:14 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
Hi,
On Thursday 08 December 2011 01:59 PM, Tomi Valkeinen wrote:
> On Wed, 2011-12-07 at 18:35 +0530, Archit Taneja wrote:
>> Hi,
>>
>> On Tuesday 22 November 2011 02:52 PM, Tomi Valkeinen wrote:
>>> Add checks for overlay and manager settings. The checks are a bit
>>> complex, as we need to observe the bigger picture instead of overlays
>>> and managers independently. Things like the used display and the zorder
>>> of other overlays affect the validity of the settings.
>>
>> Minor comment:
>>
>> dss_ovl_check, dss_mgr_check and dss_mgr_check_zorder don't really
>> qualify as functions which do actual applying of configurations, they
>> could be moved from apply.c to manager.c and overlay.c.
>
> I had the check functions in apply.c because they used apply.c's
> internal datastructures.
>
> However, looking the functions now, only dss_mgr_check_zorder() used the
> internal datas, and the function doesn't even use those variables for
> anything =).
Also, the function dss_mgr_check() takes 'struct
omap_overlay_manager_info *info' as a parameter but doesn't use it. We
might want to remove that too.
Archit
>
> So you're right, they can be moved to manager.c and overlay.c, thanks.
>
> Tomi
>
^ permalink raw reply [flat|nested] 91+ messages in thread
* Re: [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs
2011-12-13 10:14 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings Archit Taneja
@ 2011-12-13 11:16 ` Tomi Valkeinen
0 siblings, 0 replies; 91+ messages in thread
From: Tomi Valkeinen @ 2011-12-13 11:16 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 1361 bytes --]
On Tue, 2011-12-13 at 15:32 +0530, Archit Taneja wrote:
> Hi,
>
> On Thursday 08 December 2011 01:59 PM, Tomi Valkeinen wrote:
> > On Wed, 2011-12-07 at 18:35 +0530, Archit Taneja wrote:
> >> Hi,
> >>
> >> On Tuesday 22 November 2011 02:52 PM, Tomi Valkeinen wrote:
> >>> Add checks for overlay and manager settings. The checks are a bit
> >>> complex, as we need to observe the bigger picture instead of overlays
> >>> and managers independently. Things like the used display and the zorder
> >>> of other overlays affect the validity of the settings.
> >>
> >> Minor comment:
> >>
> >> dss_ovl_check, dss_mgr_check and dss_mgr_check_zorder don't really
> >> qualify as functions which do actual applying of configurations, they
> >> could be moved from apply.c to manager.c and overlay.c.
> >
> > I had the check functions in apply.c because they used apply.c's
> > internal datastructures.
> >
> > However, looking the functions now, only dss_mgr_check_zorder() used the
> > internal datas, and the function doesn't even use those variables for
> > anything =).
>
> Also, the function dss_mgr_check() takes 'struct
> omap_overlay_manager_info *info' as a parameter but doesn't use it. We
> might want to remove that too.
Right. And the dss_ovl/mgr_simple_check() functions could also be moved
outside apply.c.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 91+ messages in thread
end of thread, other threads:[~2011-12-13 11:16 UTC | newest]
Thread overview: 91+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-22 9:20 [PATCH 00/65] OMAPDSS: manager/apply improvements Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 01/65] OMAPDSS: DISPC: add missing prototype Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 02/65] OMAPDSS: Remove old fifomerge hacks Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 03/65] OMAPDSS: remove L4_EXAMPLE code Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 04/65] OMAPDSS: DISPC: make dispc_ovl_set_channel_out() public Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 05/65] OMAPDSS: DISPC: make dispc_ovl_set_fifo_threshold() public Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 06/65] OMAPDSS: remove partial update from the overlay manager Tomi Valkeinen
2011-11-22 11:53 ` [PATCH 06/65] OMAPDSS: remove partial update from the overlay Archit Taneja
2011-11-22 9:21 ` [PATCH 07/65] OMAPDSS: remove partial update from DSI Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 08/65] OMAPDSS: remove partial update from panel-taal Tomi Valkeinen
2011-11-22 11:55 ` Archit Taneja
2011-11-22 12:32 ` Tomi Valkeinen
2011-11-23 5:51 ` Archit Taneja
2011-11-22 9:21 ` [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update Tomi Valkeinen
2011-11-23 5:55 ` Archit Taneja
2011-11-23 7:32 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 10/65] OMAPDSS: DISPC: handle 0 out_width/out_height in ovl_setup() Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 11/65] OMAPDSS: handle ilace/replication when configuring overlay Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 12/65] OMAPDSS: separate FIFO threshold setup from ovl_setup Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 13/65] OMAPDSS: separate overlay channel " Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 14/65] OMAPDSS: setup manager with dispc_mgr_setup() Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 15/65] OMAPDSS: DISPC: remove unused functions Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 16/65] OMAPDSS: remove unneeded dss_ovl_wait_for_go() Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 17/65] OMAPDSS: add ovl/mgr_manual_update() helpers Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 18/65] OMAPDSS: split omap_dss_mgr_apply() to smaller funcs Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 19/65] OMAPDSS: apply affects only one overlay manager Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 20/65] OMAPDSS: create apply.c Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 21/65] OMAPDSS: hide manager's enable/disable() Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 22/65] OMAPDSS: APPLY: track whether a manager is enabled Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 23/65] OMAPDSS: APPLY: skip isr register and config for manual update displays Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 24/65] OMAPDSS: APPLY: skip isr register and config for disabled displays Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 25/65] OMAPDSS: APPLY: cleanup dss_start_update Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 26/65] OMAPDSS: store overlays in an array Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 27/65] OMAPDSS: store managers " Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 28/65] OMAPDSS: store overlays in a list for each manager Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 29/65] OMAPDSS: APPLY: separate vsync isr register/unregister Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 30/65] OMAPDSS: DISPC: Add dispc_mgr_get_vsync_irq() Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 31/65] OMAPDSS: APPLY: use dispc_mgr_get_vsync_irq() Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 32/65] OMAPDSS: APPLY: configure_* funcs take ovl/manager as args Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 33/65] OMAPDSS: APPLY: rename overlay_cache_data Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 34/65] OMAPDSS: APPLY: rename manager_cache_data Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct Tomi Valkeinen
2011-11-23 9:37 ` Archit Taneja
2011-11-23 9:39 ` Archit Taneja
2011-11-23 10:29 ` Sergey Kibrik
2011-11-23 10:47 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 36/65] OMAPDSS: APPLY: rename dss_cache to dss_data Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 37/65] OMAPDSS: APPLY: move ovl funcs to apply.c Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 38/65] OMAPDSS: APPLY: move mgr " Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 39/65] OMAPDSS: remove ovl/mgr check-code temporarily Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 40/65] OMAPDSS: APPLY: add mutex Tomi Valkeinen
2011-11-23 9:49 ` Archit Taneja
2011-11-23 10:17 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock Tomi Valkeinen
2011-11-23 9:57 ` Archit Taneja
2011-11-23 10:12 ` Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays Tomi Valkeinen
2011-11-23 10:22 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
2011-11-23 10:42 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd Tomi Valkeinen
2011-11-23 11:20 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
2011-11-23 11:27 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd Tomi Valkeinen
2011-11-23 12:25 ` [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode Archit Taneja
2011-11-22 9:21 ` [PATCH 43/65] OMAPDSS: APPLY: move mgr->enabled to mgr_priv_data Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 44/65] OMAPDSS: APPLY: add busy field " Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 45/65] OMAPDSS: APPLY: rewrite overlay enable/disable Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 46/65] OMAPDSS: APPLY: rewrite register writing Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 47/65] OMAPDSS: DISPC: add dispc_mgr_get_framedone_irq Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 48/65] OMAPDSS: APPLY: add updating flag Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 49/65] OMAPDSS: APPLY: clean up isr_handler Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 50/65] OMAPDSS: APPLY: move mgr->info to apply.c Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 51/65] OMAPDSS: APPLY: move ovl->info " Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 52/65] OMAPDSS: APPLY: move channel-field to extra_info set Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 53/65] OMAPDSS: APPLY: move fifo thresholds " Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 54/65] OMAPDSS: APPLY: rename dirty & shadow_dirty Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 55/65] OMAPDSS: APPLY: remove device_changed field Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 56/65] OMAPDSS: APPLY: add dss_apply_ovl_enable() Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 57/65] OMAPDSS: APPLY: skip enable/disable if already enabled/disabled Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates() Tomi Valkeinen
2011-12-07 13:19 ` Archit Taneja
2011-12-07 13:15 ` [PATCH 58/65] OMAPDSS: APPLY: add Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 59/65] OMAPDSS: APPLY: remove runtime_get Tomi Valkeinen
2011-11-22 9:21 ` [PATCH 60/65] OMAPDSS: Add comments about blocking of ovl/mgr functions Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 61/65] OMAPDSS: APPLY: add dss_ovl_simple_check() Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 62/65] OMAPDSS: APPLY: add dss_mgr_simple_check() Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings Tomi Valkeinen
2011-12-07 13:17 ` Archit Taneja
2011-12-08 8:29 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs Tomi Valkeinen
2011-12-13 10:14 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings Archit Taneja
2011-12-13 11:16 ` [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 64/65] OMAPDSS: APPLY: add return value to dss_mgr_enable() Tomi Valkeinen
2011-11-22 9:22 ` [PATCH 65/65] OMAPDSS: check the return value of dss_mgr_enable() Tomi Valkeinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).