* [PATCH 11/65] OMAPDSS: handle ilace/replication when configuring overlay
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 12/65] OMAPDSS: separate FIFO threshold setup from ovl_setup
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 13/65] OMAPDSS: separate overlay channel from ovl_setup
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 14/65] OMAPDSS: setup manager with dispc_mgr_setup()
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 15/65] OMAPDSS: DISPC: remove unused functions
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 16/65] OMAPDSS: remove unneeded dss_ovl_wait_for_go()
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 17/65] OMAPDSS: add ovl/mgr_manual_update() helpers
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add 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
* [PATCH 18/65] OMAPDSS: split omap_dss_mgr_apply() to smaller funcs
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 19/65] OMAPDSS: apply affects only one overlay manager
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
omap_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
* [PATCH 20/65] OMAPDSS: create apply.c
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 21/65] OMAPDSS: hide manager's enable/disable()
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 22/65] OMAPDSS: APPLY: track whether a manager is enabled
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add "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
* [PATCH 23/65] OMAPDSS: APPLY: skip isr register and config for manual update displays
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
The 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
* [PATCH 24/65] OMAPDSS: APPLY: skip isr register and config for disabled displays
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 25/65] OMAPDSS: APPLY: cleanup dss_start_update
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
dss_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
* [PATCH 26/65] OMAPDSS: store overlays in an array
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Overlays are 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
* [PATCH 27/65] OMAPDSS: store managers in an array
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 28/65] OMAPDSS: store overlays in a list for each manager
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 29/65] OMAPDSS: APPLY: separate vsync isr register/unregister
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 30/65] OMAPDSS: DISPC: Add dispc_mgr_get_vsync_irq()
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
Add dispc_mgr_get_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
* [PATCH 31/65] OMAPDSS: APPLY: use dispc_mgr_get_vsync_irq()
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 32/65] OMAPDSS: APPLY: configure_* funcs take ovl/manager as args
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 33/65] OMAPDSS: APPLY: rename overlay_cache_data
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 34/65] OMAPDSS: APPLY: rename manager_cache_data
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
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
* [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
From: Tomi Valkeinen @ 2011-11-22 9:21 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1321953724-6350-1-git-send-email-tomi.valkeinen@ti.com>
dss_cache struct contains a spinlock used to protect the struct. A more
logical place for the spinlock is outside the struct that it is
protecting. So move it there.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 22 ++++++++++++----------
1 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 23c723a..17639c0 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -89,13 +89,15 @@ struct mgr_priv_data {
};
static struct {
- spinlock_t lock;
struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
bool irq_enabled;
} dss_cache;
+/* protects dss_cache */
+static spinlock_t data_lock;
+
static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
{
return &dss_cache.ovl_priv_data_array[ovl->id];
@@ -108,7 +110,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
void dss_apply_init(void)
{
- spin_lock_init(&dss_cache.lock);
+ spin_lock_init(&data_lock);
}
static bool ovl_manual_update(struct omap_overlay *ovl)
@@ -149,10 +151,10 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
unsigned long flags;
bool shadow_dirty, dirty;
- spin_lock_irqsave(&dss_cache.lock, flags);
+ spin_lock_irqsave(&data_lock, flags);
dirty = mp->dirty;
shadow_dirty = mp->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
+ spin_unlock_irqrestore(&data_lock, flags);
if (!dirty && !shadow_dirty) {
r = 0;
@@ -212,10 +214,10 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
unsigned long flags;
bool shadow_dirty, dirty;
- spin_lock_irqsave(&dss_cache.lock, flags);
+ spin_lock_irqsave(&data_lock, flags);
dirty = op->dirty;
shadow_dirty = op->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
+ spin_unlock_irqrestore(&data_lock, flags);
if (!dirty && !shadow_dirty) {
r = 0;
@@ -464,7 +466,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
for (i = 0; i < num_mgrs; i++)
mgr_busy[i] = dispc_mgr_go_busy(i);
- spin_lock(&dss_cache.lock);
+ spin_lock(&data_lock);
for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
@@ -498,7 +500,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
dss_unregister_vsync_isr();
end:
- spin_unlock(&dss_cache.lock);
+ spin_unlock(&data_lock);
}
static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
@@ -620,7 +622,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
if (r)
return r;
- spin_lock_irqsave(&dss_cache.lock, flags);
+ spin_lock_irqsave(&data_lock, flags);
/* Configure overlays */
list_for_each_entry(ovl, &mgr->overlays, list)
@@ -641,7 +643,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
dss_write_regs();
}
- spin_unlock_irqrestore(&dss_cache.lock, flags);
+ spin_unlock_irqrestore(&data_lock, flags);
dispc_runtime_put();
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox