summaryrefslogtreecommitdiff
path: root/drivers/video/omap2/dss
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss')
-rw-r--r--drivers/video/omap2/dss/dsi.c6
-rw-r--r--drivers/video/omap2/dss/dss.h3
-rw-r--r--drivers/video/omap2/dss/manager.c69
-rw-r--r--drivers/video/omap2/dss/rfbi.c2
4 files changed, 47 insertions, 33 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 32297b4f7abb..d0881e948bcf 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2860,7 +2860,8 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
}
int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h)
+ u16 *x, u16 *y, u16 *w, u16 *h,
+ bool enlarge_update_area)
{
u16 dw, dh;
@@ -2884,7 +2885,8 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
dsi_perf_mark_setup();
if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
- dss_setup_partial_planes(dssdev, x, y, w, h);
+ dss_setup_partial_planes(dssdev, x, y, w, h,
+ enlarge_update_area);
dispc_set_lcd_size(*w, *h);
}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 66e8e97d06a7..5c7940d5f282 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -199,7 +199,8 @@ int dss_init_overlay_managers(struct platform_device *pdev);
void dss_uninit_overlay_managers(struct platform_device *pdev);
int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
void dss_setup_partial_planes(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h);
+ u16 *x, u16 *y, u16 *w, u16 *h,
+ bool enlarge_update_area);
void dss_start_update(struct omap_dss_device *dssdev);
/* overlay */
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index a1d84ef65904..4b09fcb432b3 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -440,6 +440,10 @@ struct manager_cache_data {
/* manual update region */
u16 x, y, w, h;
+
+ /* enlarge the update area if the update area contains scaled
+ * overlays */
+ bool enlarge_update_area;
};
static struct {
@@ -721,6 +725,7 @@ static int configure_overlay(enum omap_plane plane)
u16 x, y, w, h;
u32 paddr;
int r;
+ u16 orig_w, orig_h, orig_outw, orig_outh;
DSSDBGF("%d", plane);
@@ -741,8 +746,16 @@ static int configure_overlay(enum omap_plane plane)
outh = c->out_height == 0 ? c->height : c->out_height;
paddr = c->paddr;
+ orig_w = w;
+ orig_h = h;
+ orig_outw = outw;
+ orig_outh = outh;
+
if (c->manual_update && mc->do_manual_update) {
unsigned bpp;
+ unsigned scale_x_m = w, scale_x_d = outw;
+ unsigned scale_y_m = h, scale_y_d = outh;
+
/* If the overlay is outside the update region, disable it */
if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
x, y, outw, outh)) {
@@ -773,39 +786,33 @@ static int configure_overlay(enum omap_plane plane)
BUG();
}
- if (dispc_is_overlay_scaled(c)) {
- /* If the overlay is scaled, the update area has
- * already been enlarged to cover the whole overlay. We
- * only need to adjust x/y here */
- x = c->pos_x - mc->x;
- y = c->pos_y - mc->y;
+ if (mc->x > c->pos_x) {
+ x = 0;
+ outw -= (mc->x - c->pos_x);
+ paddr += (mc->x - c->pos_x) *
+ scale_x_m / scale_x_d * bpp / 8;
} else {
- if (mc->x > c->pos_x) {
- x = 0;
- w -= (mc->x - c->pos_x);
- paddr += (mc->x - c->pos_x) * bpp / 8;
- } else {
- x = c->pos_x - mc->x;
- }
+ x = c->pos_x - mc->x;
+ }
- if (mc->y > c->pos_y) {
- y = 0;
- h -= (mc->y - c->pos_y);
- paddr += (mc->y - c->pos_y) * c->screen_width *
- bpp / 8;
- } else {
- y = c->pos_y - mc->y;
- }
+ if (mc->y > c->pos_y) {
+ y = 0;
+ outh -= (mc->y - c->pos_y);
+ paddr += (mc->y - c->pos_y) *
+ scale_y_m / scale_y_d *
+ c->screen_width * bpp / 8;
+ } else {
+ y = c->pos_y - mc->y;
+ }
- if (mc->w < (x+w))
- w -= (x+w) - (mc->w);
+ if (mc->w < (x + outw))
+ outw -= (x + outw) - (mc->w);
- if (mc->h < (y+h))
- h -= (y+h) - (mc->h);
+ if (mc->h < (y + outh))
+ outh -= (y + outh) - (mc->h);
- outw = w;
- outh = h;
- }
+ w = w * outw / orig_outw;
+ h = h * outh / orig_outh;
}
r = dispc_setup_plane(plane,
@@ -963,7 +970,7 @@ static void make_even(u16 *x, u16 *w)
/* Configure dispc for partial update. Return possibly modified update
* area */
void dss_setup_partial_planes(struct omap_dss_device *dssdev,
- u16 *xi, u16 *yi, u16 *wi, u16 *hi)
+ u16 *xi, u16 *yi, u16 *wi, u16 *hi, bool enlarge_update_area)
{
struct overlay_cache_data *oc;
struct manager_cache_data *mc;
@@ -1015,6 +1022,9 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
oc->dirty = true;
+ if (!enlarge_update_area)
+ continue;
+
if (!oc->enabled)
continue;
@@ -1074,6 +1084,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
mc = &dss_cache.manager_cache[mgr->id];
mc->do_manual_update = true;
+ mc->enlarge_update_area = enlarge_update_area;
mc->x = x;
mc->y = y;
mc->w = w;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index cc23f53cc62d..bbe62464e92d 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -886,7 +886,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
return -EINVAL;
if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
- dss_setup_partial_planes(dssdev, x, y, w, h);
+ dss_setup_partial_planes(dssdev, x, y, w, h, true);
dispc_set_lcd_size(*w, *h);
}