Skip to content

Commit

Permalink
OMAPDSS: APPLY: Add manager timings as extra_info in private data
Browse files Browse the repository at this point in the history
DISPC manager size and DISPC manager blanking parameters(for LCD managers)
follow the shadow register programming model. Currently, they are programmed
directly by the interface drivers.

To configure manager timings using APPLY, there is a need to introduce extra
info flags for managers, similar to what is done for overlays. This is needed
because timings aren't a part of overlay_manager_info struct configured by a
user of DSS, they are configured internally by the interface or panel drivers.

Add dirty and shadow_dirty extra_info flags for managers, update these flags
at the appropriate places. Rewrite the function extra_info_update_ongoing()
slightly as checking for manager's extra_info flags can simplify the code a bit.

Create function dss_mgr_set_timings() which applies the new manager timings to
extra_info.

Signed-off-by: Archit Taneja <archit@ti.com>
  • Loading branch information
Archit Taneja authored and Tomi Valkeinen committed May 9, 2012
1 parent 408d9db commit 45324a2
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 13 deletions.
96 changes: 83 additions & 13 deletions drivers/video/omap2/dss/apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ struct mgr_priv_data {

/* If true, a display is enabled using this manager */
bool enabled;

bool extra_info_dirty;
bool shadow_extra_info_dirty;

struct omap_video_timings timings;
};

static struct {
Expand Down Expand Up @@ -261,6 +266,20 @@ static bool need_isr(void)
if (mp->shadow_info_dirty)
return true;

/*
* NOTE: we don't check extra_info flags for disabled
* managers, once the manager is enabled, the extra_info
* related manager changes will be taken in by HW.
*/

/* to write new values to registers */
if (mp->extra_info_dirty)
return true;

/* to set GO bit */
if (mp->shadow_extra_info_dirty)
return true;

list_for_each_entry(ovl, &mgr->overlays, list) {
struct ovl_priv_data *op;

Expand Down Expand Up @@ -305,7 +324,7 @@ static bool need_go(struct omap_overlay_manager *mgr)

mp = get_mgr_priv(mgr);

if (mp->shadow_info_dirty)
if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty)
return true;

list_for_each_entry(ovl, &mgr->overlays, list) {
Expand All @@ -320,29 +339,32 @@ static bool need_go(struct omap_overlay_manager *mgr)
/* returns true if an extra_info field is currently being updated */
static bool extra_info_update_ongoing(void)
{
const int num_ovls = omap_dss_get_num_overlays();
struct ovl_priv_data *op;
struct omap_overlay *ovl;
struct mgr_priv_data *mp;
const int num_mgrs = dss_feat_get_num_mgrs();
int i;

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

if (!ovl->manager)
continue;
for (i = 0; i < num_mgrs; ++i) {
struct omap_overlay_manager *mgr;
struct omap_overlay *ovl;
struct mgr_priv_data *mp;

mp = get_mgr_priv(ovl->manager);
mgr = omap_dss_get_overlay_manager(i);
mp = get_mgr_priv(mgr);

if (!mp->enabled)
continue;

if (!mp->updating)
continue;

if (op->extra_info_dirty || op->shadow_extra_info_dirty)
if (mp->extra_info_dirty || mp->shadow_extra_info_dirty)
return true;

list_for_each_entry(ovl, &mgr->overlays, list) {
struct ovl_priv_data *op = get_ovl_priv(ovl);

if (op->extra_info_dirty || op->shadow_extra_info_dirty)
return true;
}
}

return false;
Expand Down Expand Up @@ -601,6 +623,22 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
}
}

static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);

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

if (!mp->extra_info_dirty)
return;

dispc_mgr_set_timings(mgr->id, &mp->timings);

mp->extra_info_dirty = false;
if (mp->updating)
mp->shadow_extra_info_dirty = true;
}

static void dss_write_regs_common(void)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
Expand Down Expand Up @@ -654,6 +692,7 @@ static void dss_write_regs(void)
}

dss_mgr_write_regs(mgr);
dss_mgr_write_regs_extra(mgr);
}
}

Expand Down Expand Up @@ -693,6 +732,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)

mp = get_mgr_priv(mgr);
mp->shadow_info_dirty = false;
mp->shadow_extra_info_dirty = false;

list_for_each_entry(ovl, &mgr->overlays, list) {
op = get_ovl_priv(ovl);
Expand All @@ -719,6 +759,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
}

dss_mgr_write_regs(mgr);
dss_mgr_write_regs_extra(mgr);

dss_write_regs_common();

Expand Down Expand Up @@ -1225,6 +1266,35 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
return r;
}

static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
struct omap_video_timings *timings)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);

mp->timings = *timings;
mp->extra_info_dirty = true;
}

void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
struct omap_video_timings *timings)
{
unsigned long flags;

mutex_lock(&apply_lock);

spin_lock_irqsave(&data_lock, flags);

dss_apply_mgr_timings(mgr, timings);

dss_write_regs();
dss_set_go_bits();

spin_unlock_irqrestore(&data_lock, flags);

wait_pending_extra_info_updates();

mutex_unlock(&apply_lock);
}

int dss_ovl_set_info(struct omap_overlay *ovl,
struct omap_overlay_info *info)
Expand Down
2 changes: 2 additions & 0 deletions drivers/video/omap2/dss/dss.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
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);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
struct omap_video_timings *timings);

bool dss_ovl_is_enabled(struct omap_overlay *ovl);
int dss_ovl_enable(struct omap_overlay *ovl);
Expand Down

0 comments on commit 45324a2

Please sign in to comment.