Skip to content

Commit

Permalink
OMAP: DSS2: Introduce omap_channel as an omap_dss_device parameter, a…
Browse files Browse the repository at this point in the history
…dd new overlay manager.

A panel connects to one of the overlay managers of DSS through some interface block.
On OMAP4, specifying the type of the display is not sufficient to conclude which manager
the panel should be connected to.
Hence, a new member 'channel' is introduced in omap_dss_device structure to determine
which manager the panel uses. The dss_recheck_connections() called in dss_driver_probe()
uses this channel parameter to set the correct manager to the corresponding omap_dss_device.

The channel parameter is used only once to ensure the correct managers are set for each
panel. The parameter dssdev->manager->id will take care of ensuring that the panel and
then the interface driver configures the correct DISPC channel.

Also, add a new Overlay Manager in manager.c, make other changes needed for LCD2 channel.

Signed-off-by: Sumit Semwal <sumit.semwal@ti.com>
Signed-off-by: Mukund Mittal <mmittal@ti.com>
Signed-off-by: Samreen <samreen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
  • Loading branch information
Sumit Semwal authored and Tomi Valkeinen committed Jan 10, 2011
1 parent 6ced40b commit 18faa1b
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 44 deletions.
2 changes: 2 additions & 0 deletions arch/arm/plat-omap/include/plat/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ struct omap_dss_device {

enum omap_display_type type;

enum omap_channel channel;

union {
struct {
u8 data_lines;
Expand Down
21 changes: 10 additions & 11 deletions drivers/video/omap2/dss/dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1610,8 +1610,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
bool ilace,
enum omap_dss_rotation_type rotation_type,
u8 rotation, int mirror,
u8 global_alpha,
u8 pre_mult_alpha)
u8 global_alpha, u8 pre_mult_alpha,
enum omap_channel channel)
{
const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
bool five_taps = 0;
Expand Down Expand Up @@ -1667,8 +1667,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
five_taps = height > out_height * 2;

if (!five_taps) {
fclk = calc_fclk(OMAP_DSS_CHANNEL_LCD, width, height,
out_width, out_height);
fclk = calc_fclk(channel, width, height, out_width,
out_height);

/* Try 5-tap filter if 3-tap fclk is too high */
if (cpu_is_omap34xx() && height > out_height &&
Expand All @@ -1682,9 +1682,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
}

if (five_taps)
fclk = calc_fclk_five_taps(OMAP_DSS_CHANNEL_LCD, width,
height, out_width, out_height,
color_mode);
fclk = calc_fclk_five_taps(channel, width, height,
out_width, out_height, color_mode);

DSSDBG("required fclk rate = %lu Hz\n", fclk);
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
Expand Down Expand Up @@ -3331,17 +3330,17 @@ int dispc_setup_plane(enum omap_plane plane,
bool ilace,
enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror, u8 global_alpha,
u8 pre_mult_alpha)
u8 pre_mult_alpha, enum omap_channel channel)
{
int r = 0;

DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
"%dx%d, ilace %d, cmode %x, rot %d, mir %d\n",
"%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
plane, paddr, screen_width, pos_x, pos_y,
width, height,
out_width, out_height,
ilace, color_mode,
rotation, mirror);
rotation, mirror, channel);

enable_clocks(1);

Expand All @@ -3354,7 +3353,7 @@ int dispc_setup_plane(enum omap_plane plane,
rotation_type,
rotation, mirror,
global_alpha,
pre_mult_alpha);
pre_mult_alpha, channel);

enable_clocks(0);

Expand Down
4 changes: 2 additions & 2 deletions drivers/video/omap2/dss/dss.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,8 @@ int dispc_setup_plane(enum omap_plane plane,
bool ilace,
enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror,
u8 global_alpha,
u8 pre_mult_alpha);
u8 global_alpha, u8 pre_mult_alpha,
enum omap_channel channel);

bool dispc_go_busy(enum omap_channel channel);
void dispc_go(enum omap_channel channel);
Expand Down
77 changes: 48 additions & 29 deletions drivers/video/omap2/dss/manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,19 +513,21 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
unsigned long timeout = msecs_to_jiffies(500);
u32 irq;

if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
irq = DISPC_IRQ_EVSYNC_ODD;
else
irq = DISPC_IRQ_VSYNC;

} else {
if (mgr->id == OMAP_DSS_CHANNEL_LCD)
irq = DISPC_IRQ_VSYNC;
else
irq = DISPC_IRQ_VSYNC2;
}
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;
enum omap_channel channel;
u32 irq;
int r;
int i;
Expand All @@ -536,19 +538,21 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)

if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
channel = OMAP_DSS_CHANNEL_DIGIT;
} else {
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
enum omap_dss_update_mode mode;
mode = dssdev->driver->get_update_mode(dssdev);
if (mode != OMAP_DSS_UPDATE_AUTO)
return 0;

irq = DISPC_IRQ_FRAMEDONE;
irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
DISPC_IRQ_FRAMEDONE
: DISPC_IRQ_FRAMEDONE2;
} else {
irq = DISPC_IRQ_VSYNC;
irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
DISPC_IRQ_VSYNC
: DISPC_IRQ_VSYNC2;
}
channel = OMAP_DSS_CHANNEL_LCD;
}

mc = &dss_cache.manager_cache[mgr->id];
Expand Down Expand Up @@ -595,7 +599,6 @@ static 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);
enum omap_channel channel;
struct overlay_cache_data *oc;
struct omap_dss_device *dssdev;
u32 irq;
Expand All @@ -612,19 +615,21 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)

if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
channel = OMAP_DSS_CHANNEL_DIGIT;
} else {
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
enum omap_dss_update_mode mode;
mode = dssdev->driver->get_update_mode(dssdev);
if (mode != OMAP_DSS_UPDATE_AUTO)
return 0;

irq = DISPC_IRQ_FRAMEDONE;
irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
DISPC_IRQ_FRAMEDONE
: DISPC_IRQ_FRAMEDONE2;
} else {
irq = DISPC_IRQ_VSYNC;
irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
DISPC_IRQ_VSYNC
: DISPC_IRQ_VSYNC2;
}
channel = OMAP_DSS_CHANNEL_LCD;
}

oc = &dss_cache.overlay_cache[ovl->id];
Expand Down Expand Up @@ -844,7 +849,8 @@ static int configure_overlay(enum omap_plane plane)
c->rotation,
c->mirror,
c->global_alpha,
c->pre_mult_alpha);
c->pre_mult_alpha,
c->channel);

if (r) {
/* this shouldn't happen */
Expand Down Expand Up @@ -896,10 +902,10 @@ static int configure_dispc(void)
r = 0;
busy = false;

mgr_busy[0] = dispc_go_busy(0);
mgr_busy[1] = dispc_go_busy(1);
mgr_go[0] = false;
mgr_go[1] = false;
for (i = 0; i < num_mgrs; i++) {
mgr_busy[i] = dispc_go_busy(i);
mgr_go[i] = false;
}

/* Commit overlay settings */
for (i = 0; i < num_ovls; ++i) {
Expand Down Expand Up @@ -1158,9 +1164,10 @@ 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;

mgr_busy[0] = dispc_go_busy(0);
mgr_busy[1] = dispc_go_busy(1);
for (i = 0; i < num_mgrs; i++)
mgr_busy[i] = dispc_go_busy(i);

spin_lock(&dss_cache.lock);

Expand All @@ -1181,8 +1188,8 @@ static void dss_apply_irq_handler(void *data, u32 mask)
goto end;

/* re-read busy flags */
mgr_busy[0] = dispc_go_busy(0);
mgr_busy[1] = dispc_go_busy(1);
for (i = 0; i < num_mgrs; i++)
mgr_busy[i] = dispc_go_busy(i);

/* keep running as long as there are busy managers, so that
* we can collect overlay-applied information */
Expand All @@ -1191,9 +1198,12 @@ static void dss_apply_irq_handler(void *data, u32 mask)
goto end;
}

omap_dispc_unregister_isr(dss_apply_irq_handler, NULL,
DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
DISPC_IRQ_EVSYNC_EVEN);
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:
Expand Down Expand Up @@ -1386,9 +1396,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
r = 0;
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
if (!dss_cache.irq_enabled) {
r = omap_dispc_register_isr(dss_apply_irq_handler, NULL,
DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
DISPC_IRQ_EVSYNC_EVEN);
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();
Expand Down Expand Up @@ -1480,6 +1495,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->name = "tv";
mgr->id = OMAP_DSS_CHANNEL_DIGIT;
break;
case 2:
mgr->name = "lcd2";
mgr->id = OMAP_DSS_CHANNEL_LCD2;
break;
}

mgr->set_device = &omap_dss_set_device;
Expand Down
14 changes: 12 additions & 2 deletions drivers/video/omap2/dss/overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,12 +664,22 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
int i;
struct omap_overlay_manager *lcd_mgr;
struct omap_overlay_manager *tv_mgr;
struct omap_overlay_manager *lcd2_mgr = NULL;
struct omap_overlay_manager *mgr = NULL;

lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);

if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
if (dss_has_feature(FEAT_MGR_LCD2))
lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);

if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
if (!lcd2_mgr->device || force) {
if (lcd2_mgr->device)
lcd2_mgr->unset_device(lcd2_mgr);
lcd2_mgr->set_device(lcd2_mgr, dssdev);
mgr = lcd2_mgr;
}
} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
if (!lcd_mgr->device || force) {
if (lcd_mgr->device)
lcd_mgr->unset_device(lcd_mgr);
Expand Down

0 comments on commit 18faa1b

Please sign in to comment.