Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 284940
b: refs/heads/master
c: aaa874a
h: refs/heads/master
v: v3
  • Loading branch information
Tomi Valkeinen committed Dec 2, 2011
1 parent ce00889 commit c7a6967
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 83 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 43a972d96b6ea2b9e3d6b55b9724c9f61d802c68
refs/heads/master: aaa874a985158383c4b394c687c716ef26288741
33 changes: 15 additions & 18 deletions trunk/drivers/media/video/omap/omap_vout.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout,
"%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
"rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
"out_height=%d rotation_type=%d screen_width=%d\n",
__func__, info.enabled, info.paddr, info.width, info.height,
__func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height,
info.color_mode, info.rotation, info.mirror, info.pos_x,
info.pos_y, info.out_width, info.out_height, info.rotation_type,
info.screen_width);
Expand Down Expand Up @@ -942,12 +942,8 @@ static int omap_vout_release(struct file *file)
/* Disable all the overlay managers connected with this interface */
for (i = 0; i < ovid->num_overlays; i++) {
struct omap_overlay *ovl = ovid->overlays[i];
if (ovl->manager && ovl->manager->device) {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
info.enabled = 0;
ovl->set_overlay_info(ovl, &info);
}
if (ovl->manager && ovl->manager->device)
ovl->disable(ovl);
}
/* Turn off the pipeline */
ret = omapvid_apply_changes(vout);
Expand Down Expand Up @@ -1667,7 +1663,6 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
if (ovl->manager && ovl->manager->device) {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
info.enabled = 1;
info.paddr = addr;
if (ovl->set_overlay_info(ovl, &info)) {
ret = -EINVAL;
Expand All @@ -1686,6 +1681,16 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
if (ret)
v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");

for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];

if (ovl->manager && ovl->manager->device) {
ret = ovl->enable(ovl);
if (ret)
goto streamon_err1;
}
}

ret = 0;

streamon_err1:
Expand Down Expand Up @@ -1715,16 +1720,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];

if (ovl->manager && ovl->manager->device) {
struct omap_overlay_info info;

ovl->get_overlay_info(ovl, &info);
info.enabled = 0;
ret = ovl->set_overlay_info(ovl, &info);
if (ret)
v4l2_err(&vout->vid_dev->v4l2_dev,
"failed to update overlay info in streamoff\n");
}
if (ovl->manager && ovl->manager->device)
ovl->disable(ovl);
}

/* Turn of the pipeline */
Expand Down
163 changes: 135 additions & 28 deletions trunk/drivers/video/omap2/dss/apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,18 @@ struct ovl_priv_data {
* VSYNC/EVSYNC */
bool shadow_dirty;

bool enabled;

struct omap_overlay_info info;

enum omap_channel channel;

u32 fifo_low;
u32 fifo_high;

bool extra_info_dirty;
bool shadow_extra_info_dirty;

bool enabled;

};

struct mgr_priv_data {
Expand Down Expand Up @@ -132,11 +136,6 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
}

static int overlay_enabled(struct omap_overlay *ovl)
{
return ovl->info.enabled && ovl->manager && ovl->manager->device;
}

int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
Expand Down Expand Up @@ -270,10 +269,8 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
op = get_ovl_priv(ovl);
oi = &op->info;

if (!op->enabled) {
dispc_ovl_enable(ovl->id, 0);
if (!op->enabled)
return 0;
}

replication = dss_use_replication(ovl->manager->device, oi->color_mode);

Expand All @@ -291,11 +288,21 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)

dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);

dispc_ovl_enable(ovl->id, 1);

return 0;
}

static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);

DSSDBGF("%d", ovl->id);

/* note: write also when op->enabled == false, so that the ovl gets
* disabled */

dispc_ovl_enable(ovl->id, op->enabled);
}

static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp;
Expand Down Expand Up @@ -356,6 +363,30 @@ static int dss_write_regs(void)
mgr_go[op->channel] = true;
}

for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
op = get_ovl_priv(ovl);

if (!op->extra_info_dirty)
continue;

mp = get_mgr_priv(ovl->manager);

if (mp->manual_update && !mp->do_manual_update)
continue;

if (mp->busy) {
busy = true;
continue;
}

dss_ovl_write_regs_extra(ovl);

op->extra_info_dirty = false;
op->shadow_extra_info_dirty = true;
mgr_go[op->channel] = true;
}

/* Commit manager settings */
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
Expand Down Expand Up @@ -419,6 +450,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
list_for_each_entry(ovl, &mgr->overlays, list) {
op = get_ovl_priv(ovl);
op->shadow_dirty = false;
op->shadow_extra_info_dirty = false;
}

mp->shadow_dirty = false;
Expand Down Expand Up @@ -490,8 +522,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)

mp = get_mgr_priv(ovl->manager);

if (!mp->busy)
if (!mp->busy) {
op->shadow_dirty = false;
op->shadow_extra_info_dirty = false;
}
}

for (i = 0; i < num_mgrs; ++i) {
Expand Down Expand Up @@ -541,14 +575,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
ovl->info_dirty = true;
}

if (!overlay_enabled(ovl)) {
if (op->enabled) {
op->enabled = false;
op->dirty = true;
}
return;
}

if (!ovl->info_dirty)
return;

Expand All @@ -557,8 +583,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
op->info = ovl->info;

op->channel = ovl->manager->id;

op->enabled = true;
}

static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
Expand Down Expand Up @@ -593,9 +617,6 @@ static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)

op = get_ovl_priv(ovl);

if (!op->enabled)
return;

dssdev = ovl->manager->device;

size = dispc_ovl_get_fifo_size(ovl->id);
Expand Down Expand Up @@ -828,6 +849,8 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
int r;

if (!mgr)
Expand All @@ -842,7 +865,10 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
goto err;
}

if (ovl->info.enabled) {
spin_lock_irqsave(&data_lock, flags);

if (op->enabled) {
spin_unlock_irqrestore(&data_lock, flags);
DSSERR("overlay has to be disabled to change the manager\n");
r = -EINVAL;
goto err;
Expand All @@ -852,6 +878,8 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
list_add_tail(&ovl->list, &mgr->overlays);
ovl->manager_changed = true;

spin_unlock_irqrestore(&data_lock, flags);

/* XXX: When there is an overlay on a DSI manual update display, and
* the overlay is first disabled, then moved to tv, and enabled, we
* seem to get SYNC_LOST_DIGIT error.
Expand All @@ -875,6 +903,8 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,

int dss_ovl_unset_manager(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
int r;

mutex_lock(&apply_lock);
Expand All @@ -885,7 +915,10 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
goto err;
}

if (ovl->info.enabled) {
spin_lock_irqsave(&data_lock, flags);

if (op->enabled) {
spin_unlock_irqrestore(&data_lock, flags);
DSSERR("overlay has to be disabled to unset the manager\n");
r = -EINVAL;
goto err;
Expand All @@ -895,9 +928,83 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
list_del(&ovl->list);
ovl->manager_changed = true;

spin_unlock_irqrestore(&data_lock, flags);

mutex_unlock(&apply_lock);

return 0;
err:
mutex_unlock(&apply_lock);
return r;
}

bool dss_ovl_is_enabled(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
bool e;

spin_lock_irqsave(&data_lock, flags);

e = op->enabled;

spin_unlock_irqrestore(&data_lock, flags);

return e;
}

int dss_ovl_enable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
int r;

mutex_lock(&apply_lock);

if (ovl->manager == NULL || ovl->manager->device == NULL) {
r = -EINVAL;
goto err;
}

spin_lock_irqsave(&data_lock, flags);

op->enabled = true;
op->extra_info_dirty = true;

spin_unlock_irqrestore(&data_lock, flags);

mutex_unlock(&apply_lock);

return 0;
err:
mutex_unlock(&apply_lock);
return r;
}

int dss_ovl_disable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
int r;

mutex_lock(&apply_lock);

if (ovl->manager == NULL || ovl->manager->device == NULL) {
r = -EINVAL;
goto err;
}

spin_lock_irqsave(&data_lock, flags);

op->enabled = false;
op->extra_info_dirty = true;

spin_unlock_irqrestore(&data_lock, flags);

mutex_unlock(&apply_lock);

return 0;

err:
mutex_unlock(&apply_lock);
return r;
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/video/omap2/dss/dss.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);

bool dss_ovl_is_enabled(struct omap_overlay *ovl);
int dss_ovl_enable(struct omap_overlay *ovl);
int dss_ovl_disable(struct omap_overlay *ovl);
int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info);
void dss_ovl_get_info(struct omap_overlay *ovl,
Expand Down
Loading

0 comments on commit c7a6967

Please sign in to comment.