Commit 18faa1b6 authored by Sumit Semwal's avatar Sumit Semwal Committed by Tomi Valkeinen

OMAP: DSS2: Introduce omap_channel as an omap_dss_device parameter, add 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: default avatarSumit Semwal <sumit.semwal@ti.com>
Signed-off-by: default avatarMukund Mittal <mmittal@ti.com>
Signed-off-by: default avatarSamreen <samreen@ti.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@nokia.com>
parent 6ced40bf
...@@ -358,6 +358,8 @@ struct omap_dss_device { ...@@ -358,6 +358,8 @@ struct omap_dss_device {
enum omap_display_type type; enum omap_display_type type;
enum omap_channel channel;
union { union {
struct { struct {
u8 data_lines; u8 data_lines;
......
...@@ -1610,8 +1610,8 @@ static int _dispc_setup_plane(enum omap_plane plane, ...@@ -1610,8 +1610,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
bool ilace, bool ilace,
enum omap_dss_rotation_type rotation_type, enum omap_dss_rotation_type rotation_type,
u8 rotation, int mirror, u8 rotation, int mirror,
u8 global_alpha, u8 global_alpha, u8 pre_mult_alpha,
u8 pre_mult_alpha) enum omap_channel channel)
{ {
const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
bool five_taps = 0; bool five_taps = 0;
...@@ -1667,8 +1667,8 @@ static int _dispc_setup_plane(enum omap_plane plane, ...@@ -1667,8 +1667,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
five_taps = height > out_height * 2; five_taps = height > out_height * 2;
if (!five_taps) { if (!five_taps) {
fclk = calc_fclk(OMAP_DSS_CHANNEL_LCD, width, height, fclk = calc_fclk(channel, width, height, out_width,
out_width, out_height); out_height);
/* Try 5-tap filter if 3-tap fclk is too high */ /* Try 5-tap filter if 3-tap fclk is too high */
if (cpu_is_omap34xx() && height > out_height && if (cpu_is_omap34xx() && height > out_height &&
...@@ -1682,9 +1682,8 @@ static int _dispc_setup_plane(enum omap_plane plane, ...@@ -1682,9 +1682,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
} }
if (five_taps) if (five_taps)
fclk = calc_fclk_five_taps(OMAP_DSS_CHANNEL_LCD, width, fclk = calc_fclk_five_taps(channel, width, height,
height, out_width, out_height, out_width, out_height, color_mode);
color_mode);
DSSDBG("required fclk rate = %lu Hz\n", fclk); DSSDBG("required fclk rate = %lu Hz\n", fclk);
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
...@@ -3331,17 +3330,17 @@ int dispc_setup_plane(enum omap_plane plane, ...@@ -3331,17 +3330,17 @@ int dispc_setup_plane(enum omap_plane plane,
bool ilace, bool ilace,
enum omap_dss_rotation_type rotation_type, enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror, u8 global_alpha, u8 rotation, bool mirror, u8 global_alpha,
u8 pre_mult_alpha) u8 pre_mult_alpha, enum omap_channel channel)
{ {
int r = 0; int r = 0;
DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " 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, plane, paddr, screen_width, pos_x, pos_y,
width, height, width, height,
out_width, out_height, out_width, out_height,
ilace, color_mode, ilace, color_mode,
rotation, mirror); rotation, mirror, channel);
enable_clocks(1); enable_clocks(1);
...@@ -3354,7 +3353,7 @@ int dispc_setup_plane(enum omap_plane plane, ...@@ -3354,7 +3353,7 @@ int dispc_setup_plane(enum omap_plane plane,
rotation_type, rotation_type,
rotation, mirror, rotation, mirror,
global_alpha, global_alpha,
pre_mult_alpha); pre_mult_alpha, channel);
enable_clocks(0); enable_clocks(0);
......
...@@ -359,8 +359,8 @@ int dispc_setup_plane(enum omap_plane plane, ...@@ -359,8 +359,8 @@ int dispc_setup_plane(enum omap_plane plane,
bool ilace, bool ilace,
enum omap_dss_rotation_type rotation_type, enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror, u8 rotation, bool mirror,
u8 global_alpha, u8 global_alpha, u8 pre_mult_alpha,
u8 pre_mult_alpha); enum omap_channel channel);
bool dispc_go_busy(enum omap_channel channel); bool dispc_go_busy(enum omap_channel channel);
void dispc_go(enum omap_channel channel); void dispc_go(enum omap_channel channel);
......
...@@ -513,11 +513,14 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) ...@@ -513,11 +513,14 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
unsigned long timeout = msecs_to_jiffies(500); unsigned long timeout = msecs_to_jiffies(500);
u32 irq; u32 irq;
if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
irq = DISPC_IRQ_EVSYNC_ODD; irq = DISPC_IRQ_EVSYNC_ODD;
else } else {
if (mgr->id == OMAP_DSS_CHANNEL_LCD)
irq = DISPC_IRQ_VSYNC; irq = DISPC_IRQ_VSYNC;
else
irq = DISPC_IRQ_VSYNC2;
}
return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
} }
...@@ -525,7 +528,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) ...@@ -525,7 +528,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{ {
unsigned long timeout = msecs_to_jiffies(500); unsigned long timeout = msecs_to_jiffies(500);
struct manager_cache_data *mc; struct manager_cache_data *mc;
enum omap_channel channel;
u32 irq; u32 irq;
int r; int r;
int i; int i;
...@@ -536,7 +538,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) ...@@ -536,7 +538,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
channel = OMAP_DSS_CHANNEL_DIGIT;
} else { } else {
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
enum omap_dss_update_mode mode; enum omap_dss_update_mode mode;
...@@ -544,11 +545,14 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) ...@@ -544,11 +545,14 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
if (mode != OMAP_DSS_UPDATE_AUTO) if (mode != OMAP_DSS_UPDATE_AUTO)
return 0; return 0;
irq = DISPC_IRQ_FRAMEDONE; irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
DISPC_IRQ_FRAMEDONE
: DISPC_IRQ_FRAMEDONE2;
} else { } 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]; mc = &dss_cache.manager_cache[mgr->id];
...@@ -595,7 +599,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) ...@@ -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) int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
{ {
unsigned long timeout = msecs_to_jiffies(500); unsigned long timeout = msecs_to_jiffies(500);
enum omap_channel channel;
struct overlay_cache_data *oc; struct overlay_cache_data *oc;
struct omap_dss_device *dssdev; struct omap_dss_device *dssdev;
u32 irq; u32 irq;
...@@ -612,7 +615,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) ...@@ -612,7 +615,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
channel = OMAP_DSS_CHANNEL_DIGIT;
} else { } else {
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
enum omap_dss_update_mode mode; enum omap_dss_update_mode mode;
...@@ -620,11 +622,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) ...@@ -620,11 +622,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
if (mode != OMAP_DSS_UPDATE_AUTO) if (mode != OMAP_DSS_UPDATE_AUTO)
return 0; return 0;
irq = DISPC_IRQ_FRAMEDONE; irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
DISPC_IRQ_FRAMEDONE
: DISPC_IRQ_FRAMEDONE2;
} else { } 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]; oc = &dss_cache.overlay_cache[ovl->id];
...@@ -844,7 +849,8 @@ static int configure_overlay(enum omap_plane plane) ...@@ -844,7 +849,8 @@ static int configure_overlay(enum omap_plane plane)
c->rotation, c->rotation,
c->mirror, c->mirror,
c->global_alpha, c->global_alpha,
c->pre_mult_alpha); c->pre_mult_alpha,
c->channel);
if (r) { if (r) {
/* this shouldn't happen */ /* this shouldn't happen */
...@@ -896,10 +902,10 @@ static int configure_dispc(void) ...@@ -896,10 +902,10 @@ static int configure_dispc(void)
r = 0; r = 0;
busy = false; busy = false;
mgr_busy[0] = dispc_go_busy(0); for (i = 0; i < num_mgrs; i++) {
mgr_busy[1] = dispc_go_busy(1); mgr_busy[i] = dispc_go_busy(i);
mgr_go[0] = false; mgr_go[i] = false;
mgr_go[1] = false; }
/* Commit overlay settings */ /* Commit overlay settings */
for (i = 0; i < num_ovls; ++i) { for (i = 0; i < num_ovls; ++i) {
...@@ -1158,9 +1164,10 @@ static void dss_apply_irq_handler(void *data, u32 mask) ...@@ -1158,9 +1164,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
const int num_mgrs = dss_feat_get_num_mgrs(); const int num_mgrs = dss_feat_get_num_mgrs();
int i, r; int i, r;
bool mgr_busy[MAX_DSS_MANAGERS]; bool mgr_busy[MAX_DSS_MANAGERS];
u32 irq_mask;
mgr_busy[0] = dispc_go_busy(0); for (i = 0; i < num_mgrs; i++)
mgr_busy[1] = dispc_go_busy(1); mgr_busy[i] = dispc_go_busy(i);
spin_lock(&dss_cache.lock); spin_lock(&dss_cache.lock);
...@@ -1181,8 +1188,8 @@ static void dss_apply_irq_handler(void *data, u32 mask) ...@@ -1181,8 +1188,8 @@ static void dss_apply_irq_handler(void *data, u32 mask)
goto end; goto end;
/* re-read busy flags */ /* re-read busy flags */
mgr_busy[0] = dispc_go_busy(0); for (i = 0; i < num_mgrs; i++)
mgr_busy[1] = dispc_go_busy(1); mgr_busy[i] = dispc_go_busy(i);
/* keep running as long as there are busy managers, so that /* keep running as long as there are busy managers, so that
* we can collect overlay-applied information */ * we can collect overlay-applied information */
...@@ -1191,9 +1198,12 @@ static void dss_apply_irq_handler(void *data, u32 mask) ...@@ -1191,9 +1198,12 @@ static void dss_apply_irq_handler(void *data, u32 mask)
goto end; goto end;
} }
omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
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_cache.irq_enabled = false;
end: end:
...@@ -1386,9 +1396,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) ...@@ -1386,9 +1396,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
r = 0; r = 0;
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
if (!dss_cache.irq_enabled) { if (!dss_cache.irq_enabled) {
r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, u32 mask;
DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
DISPC_IRQ_EVSYNC_EVEN); 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; dss_cache.irq_enabled = true;
} }
configure_dispc(); configure_dispc();
...@@ -1480,6 +1495,10 @@ int dss_init_overlay_managers(struct platform_device *pdev) ...@@ -1480,6 +1495,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->name = "tv"; mgr->name = "tv";
mgr->id = OMAP_DSS_CHANNEL_DIGIT; mgr->id = OMAP_DSS_CHANNEL_DIGIT;
break; break;
case 2:
mgr->name = "lcd2";
mgr->id = OMAP_DSS_CHANNEL_LCD2;
break;
} }
mgr->set_device = &omap_dss_set_device; mgr->set_device = &omap_dss_set_device;
......
...@@ -664,12 +664,22 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) ...@@ -664,12 +664,22 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
int i; int i;
struct omap_overlay_manager *lcd_mgr; struct omap_overlay_manager *lcd_mgr;
struct omap_overlay_manager *tv_mgr; struct omap_overlay_manager *tv_mgr;
struct omap_overlay_manager *lcd2_mgr = NULL;
struct omap_overlay_manager *mgr = NULL; struct omap_overlay_manager *mgr = NULL;
lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
if (dss_has_feature(FEAT_MGR_LCD2))
lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);
if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 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 || force) {
if (lcd_mgr->device) if (lcd_mgr->device)
lcd_mgr->unset_device(lcd_mgr); lcd_mgr->unset_device(lcd_mgr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment