aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorRobert Marklund <robert.marklund@stericsson.com>2010-08-18 13:22:28 +0200
committerJohn Rigby <john.rigby@linaro.org>2010-09-02 22:45:53 -0600
commita77c874f9b85691ea4af5362e2b5c9fc55a76acc (patch)
tree6e911eef3a565c2ffa8b284210586793ad5c8ce9 /arch/arm
parente43925f4db29bd19a8907b0cba1adde455f07a34 (diff)
downloadlinux-2.6.34-ux500-a77c874f9b85691ea4af5362e2b5c9fc55a76acc.tar.gz
MCDE Fixes: Added http://gerrit.lud.stericsson.com/gerrit/#change,3792 patchset Added patch set: http://gerrit.lud.stericsson.com/gerrit/#change,3751 Enabled single buffered fb in config.
Change-Id: I59ed2dcd1d45f896177f0f3be425b158f03fd0ee Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/4097 Tested-by: Robert MARKLUND <robert.marklund@stericsson.com> Reviewed-by: Robert ROSENGREN <robert.rosengren@stericsson.com>
Diffstat (limited to 'arch/arm')
-rwxr-xr-xarch/arm/mach-ux500/Kconfig-arch14
-rw-r--r--arch/arm/mach-ux500/board-mop500-mcde.c144
2 files changed, 128 insertions, 30 deletions
diff --git a/arch/arm/mach-ux500/Kconfig-arch b/arch/arm/mach-ux500/Kconfig-arch
index 3e6d35c5c46..8e478c923dd 100755
--- a/arch/arm/mach-ux500/Kconfig-arch
+++ b/arch/arm/mach-ux500/Kconfig-arch
@@ -55,6 +55,13 @@ config DISPLAY_GENERIC_DSI_PRIMARY_VSYNC
help
Say yes to enable v-sync for primary display
+config DISPLAY_GENERIC_DSI_PRIMARY_AUTO_SYNC
+ bool "Enable auto sync for primary display"
+ depends on DISPLAY_GENERIC_DSI_PRIMARY
+ default n
+ help
+ Say yes to enable auto sync for primary display
+
config DISPLAY_GENERIC_DSI_SECONDARY
bool "Sub display support"
depends on MACH_U8500_MOP && FB_MCDE
@@ -70,6 +77,13 @@ config DISPLAY_GENERIC_DSI_SECONDARY_VSYNC
help
Say yes to enable v-sync for secondary display
+config DISPLAY_GENERIC_DSI_SECONDARY_AUTO_SYNC
+ bool "Enable auto sync for secondary display"
+ depends on DISPLAY_GENERIC_DSI_SECONDARY
+ default n
+ help
+ Say yes to enable auto sync for secondary display
+
config DISPLAY_AB8500_TERTIARY
bool "AB8500 TVout display support"
depends on MACH_U8500_MOP && !AV8100_SDTV && FB_MCDE
diff --git a/arch/arm/mach-ux500/board-mop500-mcde.c b/arch/arm/mach-ux500/board-mop500-mcde.c
index eb13cbf9a5e..e8e0acb440b 100644
--- a/arch/arm/mach-ux500/board-mop500-mcde.c
+++ b/arch/arm/mach-ux500/board-mop500-mcde.c
@@ -21,6 +21,10 @@
#define DSI_UNIT_INTERVAL_1 0x9
#define DSI_UNIT_INTERVAL_2 0x6
+#define PRIMARY_DISPLAY_ID 0
+#define SECONDARY_DISPLAY_ID 1
+#define TERTIARY_DISPLAY_ID 2
+
static bool rotate_main = true;
static bool display_initialized_during_boot;
@@ -54,8 +58,13 @@ static struct mcde_port port0 = {
.pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
.ifc = 1,
.link = 0,
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_AUTO_SYNC
+ .sync_src = MCDE_SYNCSRC_OFF,
+ .update_auto_trig = true,
+#else
.sync_src = MCDE_SYNCSRC_BTA,
.update_auto_trig = false,
+#endif
.phy = {
.dsi = {
.virt_id = 0,
@@ -78,7 +87,7 @@ struct mcde_display_generic_platform_data generic_display0_pdata = {
struct mcde_display_device generic_display0 = {
.name = "mcde_disp_generic",
- .id = 0,
+ .id = PRIMARY_DISPLAY_ID,
.port = &port0,
.chnl_id = MCDE_CHNL_A,
.fifo = MCDE_FIFO_C0,
@@ -106,8 +115,13 @@ static struct mcde_port subdisplay_port = {
.pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
.ifc = 1,
.link = 1,
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY_AUTO_SYNC
+ .sync_src = MCDE_SYNCSRC_OFF,
+ .update_auto_trig = true,
+#else
.sync_src = MCDE_SYNCSRC_BTA,
.update_auto_trig = false,
+#endif
.phy = {
.dsi = {
.virt_id = 0,
@@ -131,7 +145,7 @@ static struct mcde_display_generic_platform_data generic_subdisplay_pdata = {
static struct mcde_display_device generic_subdisplay = {
.name = "mcde_disp_generic_subdisplay",
- .id = 1,
+ .id = SECONDARY_DISPLAY_ID,
.port = &subdisplay_port,
.chnl_id = MCDE_CHNL_C1,
.fifo = MCDE_FIFO_C1,
@@ -237,7 +251,7 @@ alt_func_failed:
static struct mcde_display_device tvout_ab8500_display = {
.name = "mcde_tv_ab8500",
- .id = 2,
+ .id = TERTIARY_DISPLAY_ID,
.port = &port_tvout1,
.chnl_id = MCDE_CHNL_B,
.fifo = MCDE_FIFO_B,
@@ -347,7 +361,7 @@ alt_func_failed:
static struct mcde_display_device av8100_hdmi = {
.name = "av8100_hdmi",
- .id = 2,
+ .id = TERTIARY_DISPLAY_ID,
.port = &port2,
.chnl_id = MCDE_CHNL_B,
.fifo = MCDE_FIFO_B,
@@ -376,29 +390,40 @@ static int display_registered_callback(struct notifier_block *nb,
{
struct mcde_display_device *ddev = dev;
u16 width, height;
+ u16 virtual_width, virtual_height;
bool rotate;
if (event != MCDE_DSS_EVENT_DISPLAY_REGISTERED)
return 0;
- if (ddev->id < 0 || ddev->id >= ARRAY_SIZE(fbs))
+ if (ddev->id < PRIMARY_DISPLAY_ID || ddev->id >= ARRAY_SIZE(fbs))
return 0;
mcde_dss_get_native_resolution(ddev, &width, &height);
- rotate = (ddev->id == 0 && rotate_main);
- if (rotate) {
- u16 tmp = height;
- height = width;
- width = tmp;
- }
+ rotate = (ddev->id == PRIMARY_DISPLAY_ID && rotate_main);
+ if (rotate)
+ swap(width, height);
+
+ virtual_width = width;
+ virtual_height = height * 2;
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_AUTO_SYNC
+ if (ddev->id == PRIMARY_DISPLAY_ID)
+ virtual_height = height;
+#endif
+
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY_AUTO_SYNC
+ if (ddev->id == SECONDARY_DISPLAY_ID)
+ virtual_height = height;
+#endif
/* Create frame buffer */
fbs[ddev->id] = mcde_fb_create(ddev,
width, height,
- width, height * 2,
+ virtual_width, virtual_height,
ddev->default_pixel_format,
rotate ? FB_ROTATE_CW : FB_ROTATE_UR);
+
if (IS_ERR(fbs[ddev->id]))
pr_warning("Failed to create fb for display %s\n", ddev->name);
else
@@ -411,6 +436,8 @@ static struct notifier_block display_nb = {
.notifier_call = display_registered_callback,
};
+#if defined(CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_AUTO_SYNC) || \
+ defined(CONFIG_DISPLAY_GENERIC_DSI_SECONDARY_AUTO_SYNC)
static int framebuffer_registered_callback(struct notifier_block *nb,
unsigned long event, void *data)
{
@@ -419,28 +446,85 @@ static int framebuffer_registered_callback(struct notifier_block *nb,
struct fb_info *info;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
+ struct mcde_fb *mfb;
+ u8 *addr;
+ int i;
+
+ if (event != FB_EVENT_FB_REGISTERED)
+ return 0;
+
+ if (!event_data)
+ return 0;
- if (event == FB_EVENT_FB_REGISTERED &&
- !display_initialized_during_boot) {
- if (event_data) {
- u8 *addr;
- info = event_data->info;
- if (!lock_fb_info(info))
- return -ENODEV;
- var = info->var;
- fix = info->fix;
- addr = ioremap(fix.smem_start,
- var.yres_virtual * fix.line_length);
- memset(addr, 0x00,
- var.yres_virtual * fix.line_length);
- var.yoffset = var.yoffset ? 0 : var.yres;
- if (info->fbops->fb_pan_display)
- ret = info->fbops->fb_pan_display(&var, info);
- unlock_fb_info(info);
- }
+ info = event_data->info;
+ mfb = to_mcde_fb(info);
+ var = info->var;
+ fix = info->fix;
+ addr = ioremap(fix.smem_start,
+ var.yres_virtual * fix.line_length);
+ memset(addr, 0x00,
+ var.yres_virtual * fix.line_length);
+ /* Apply overlay info */
+ for (i = 0; i < mfb->num_ovlys; i++) {
+ struct mcde_overlay *ovly = mfb->ovlys[i];
+ struct mcde_overlay_info ovly_info;
+ struct mcde_fb *mfb = to_mcde_fb(info);
+ memset(&ovly_info, 0, sizeof(ovly_info));
+ ovly_info.paddr = fix.smem_start +
+ fix.line_length * var.yoffset;
+ if (ovly_info.paddr + fix.line_length * var.yres
+ > fix.smem_start + fix.smem_len)
+ ovly_info.paddr = fix.smem_start;
+ ovly_info.fmt = mfb->pix_fmt;
+ ovly_info.stride = fix.line_length;
+ ovly_info.w = var.xres;
+ ovly_info.h = var.yres;
+ ovly_info.dirty.w = var.xres;
+ ovly_info.dirty.h = var.yres;
+ (void) mcde_dss_apply_overlay(ovly, &ovly_info);
+ ret = mcde_dss_update_overlay(ovly);
}
+
return ret;
}
+#else
+static int framebuffer_registered_callback(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ int ret = 0;
+ struct fb_event *event_data = data;
+ struct fb_info *info;
+ struct fb_var_screeninfo var;
+ struct fb_fix_screeninfo fix;
+ struct mcde_fb *mfb;
+ u8 *addr;
+
+ if (event != FB_EVENT_FB_REGISTERED)
+ return 0;
+
+ if (!event_data)
+ return 0;
+
+ info = event_data->info;
+ mfb = to_mcde_fb(info);
+ if (mfb->id == 0 && display_initialized_during_boot)
+ goto out;
+
+
+ var = info->var;
+ fix = info->fix;
+ addr = ioremap(fix.smem_start,
+ var.yres_virtual * fix.line_length);
+ memset(addr, 0x00,
+ var.yres_virtual * fix.line_length);
+ var.yoffset = var.yoffset ? 0 : var.yres;
+ if (info->fbops->fb_pan_display)
+ ret = info->fbops->fb_pan_display(&var, info);
+out:
+ return ret;
+}
+#endif
+
static struct notifier_block framebuffer_nb = {
.notifier_call = framebuffer_registered_callback,