diff options
author | Robert Marklund <robert.marklund@stericsson.com> | 2010-08-18 13:22:28 +0200 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2010-09-02 22:45:53 -0600 |
commit | a77c874f9b85691ea4af5362e2b5c9fc55a76acc (patch) | |
tree | 6e911eef3a565c2ffa8b284210586793ad5c8ce9 | |
parent | e43925f4db29bd19a8907b0cba1adde455f07a34 (diff) |
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>
-rwxr-xr-x | arch/arm/mach-ux500/Kconfig-arch | 14 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-mcde.c | 144 | ||||
-rw-r--r-- | drivers/video/av8100/av8100.c | 14 | ||||
-rwxr-xr-x | drivers/video/av8100/hdmi.c | 13 | ||||
-rw-r--r-- | drivers/video/mcde/display-ab8500.c | 1 | ||||
-rwxr-xr-x | drivers/video/mcde/display-av8100.c | 2 | ||||
-rw-r--r-- | drivers/video/mcde/display-generic_dsi.c | 17 | ||||
-rw-r--r-- | drivers/video/mcde/mcde_display.c | 6 | ||||
-rw-r--r-- | drivers/video/mcde/mcde_fb.c | 6 | ||||
-rw-r--r-- | drivers/video/mcde/mcde_hw.c | 251 | ||||
-rw-r--r-- | include/video/mcde.h | 35 | ||||
-rw-r--r-- | include/video/mcde_fb.h | 1 | ||||
-rw-r--r-- | kernel.spec | 5 |
13 files changed, 397 insertions, 112 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, diff --git a/drivers/video/av8100/av8100.c b/drivers/video/av8100/av8100.c index e4df11441a1..47e3c633deb 100644 --- a/drivers/video/av8100/av8100.c +++ b/drivers/video/av8100/av8100.c @@ -24,6 +24,7 @@ #include <linux/irq.h> #include <linux/timer.h> #include <linux/mutex.h> +#include <linux/slab.h> #include "av8100_regs.h" #include <video/av8100.h> @@ -80,6 +81,8 @@ DEFINE_MUTEX(av8100_hw_mutex); #define AV8100_DEBUG_EXTRA #define AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS #define CEC_ADDR_OFFSET 3 +#define AV8100_POWERON_WAITTIME1_MS 1 +#define AV8100_POWERON_WAITTIME2_MS 1 struct av8100_config_t { struct i2c_client *client; @@ -210,7 +213,7 @@ struct av8100_cea av8100_all_cea[29] = { /* cea id * cea_nr vtot vact vsbpp vslen * vsfp vpol htot hact hbp hslen hfp freq - * hpol rld bd uix4 pm pd */ + * hpol rld bd uix4 pm pd */ { "0 CUSTOM ", 0, 0, 0, 0, 0, 0, "-", 800, 640, 16, 96, 10, 25200000, @@ -853,7 +856,7 @@ static int av8100_globals_init(void) av8100_globals = kzalloc(sizeof(struct av8100_globals_t), GFP_KERNEL); if (!av8100_globals) { - dev_err(av8100dev, "%s: Alloc failure \n", __func__); + dev_err(av8100dev, "%s: Alloc failure\n", __func__); return AV8100_FAIL; } @@ -1646,6 +1649,10 @@ static int av8100_powerup1(void) /* Reset av8100 */ gpio_set_value(GPIO_AV8100_RSTN, 1); + + /* Need to wait before proceeding */ + mdelay(AV8100_POWERON_WAITTIME1_MS); + av8100_set_state(AV8100_OPMODE_STANDBY); /* Get chip version */ @@ -1696,6 +1703,9 @@ static int av8100_powerup2(void) return -EFAULT; } + /* Need to wait before proceeding */ + mdelay(AV8100_POWERON_WAITTIME2_MS); + av8100_set_state(AV8100_OPMODE_SCAN); return retval; diff --git a/drivers/video/av8100/hdmi.c b/drivers/video/av8100/hdmi.c index 14b15dedbf2..fd4324d5c4b 100755 --- a/drivers/video/av8100/hdmi.c +++ b/drivers/video/av8100/hdmi.c @@ -21,6 +21,8 @@ #include <linux/mutex.h> #include <linux/ctype.h> #include "hdmi_loc.h" +#include <linux/slab.h> +#include <linux/sched.h> #define SYSFS_EVENT_FILENAME "evread" @@ -1843,13 +1845,13 @@ int __init hdmi_init(void) hdmidev = hdmi_miscdev.this_device; - hdmidev->driver_data = + hdmi_driver_data = kzalloc(sizeof(struct hdmi_driver_data), GFP_KERNEL); - if (!hdmidev->driver_data) + if (!hdmi_driver_data) return -ENOMEM; - hdmi_driver_data = dev_get_drvdata(hdmidev); + dev_set_drvdata(hdmidev, hdmi_driver_data); /* Default sysfs file format is hextext */ hdmi_driver_data->store_as_hextext = true; @@ -1898,6 +1900,8 @@ hdmi_init_out: void hdmi_exit(void) { + struct hdmi_driver_data *hdmi_driver_data; + /* Deregister event callback */ av8100_hdmi_event_cb_set(NULL); @@ -1918,7 +1922,8 @@ void hdmi_exit(void) device_remove_file(hdmidev, &dev_attr_evclr); device_remove_file(hdmidev, &dev_attr_audiocfg); - kfree(hdmidev->driver_data); + hdmi_driver_data = dev_get_drvdata(hdmidev); + kfree(hdmi_driver_data); misc_deregister(&hdmi_miscdev); } diff --git a/drivers/video/mcde/display-ab8500.c b/drivers/video/mcde/display-ab8500.c index 426e23cbf60..cdce3bfa002 100644 --- a/drivers/video/mcde/display-ab8500.c +++ b/drivers/video/mcde/display-ab8500.c @@ -300,6 +300,7 @@ static int set_video_mode( set_power_mode(ddev, MCDE_DISPLAY_PM_STANDBY); mcde_chnl_set_col_convert(ddev->chnl_state, &pdata->rgb_2_yCbCr_convert); + mcde_chnl_stop_flow(ddev->chnl_state); res = mcde_chnl_set_video_mode(ddev->chnl_state, &ddev->video_mode); if (res < 0) { dev_warn(&ddev->dev, "%s:Failed to set video mode on channel\n", diff --git a/drivers/video/mcde/display-av8100.c b/drivers/video/mcde/display-av8100.c index 6de32c3ddf3..96fed0bf8ee 100755 --- a/drivers/video/mcde/display-av8100.c +++ b/drivers/video/mcde/display-av8100.c @@ -194,6 +194,8 @@ static int hdmi_set_video_mode( if (dev->port->pixel_format == MCDE_PORTPIXFMT_DSI_YCBCR422) mcde_chnl_set_col_convert(dev->chnl_state, &pdata->rgb_2_yCbCr_convert); + mcde_chnl_stop_flow(dev->chnl_state); + ret = mcde_chnl_set_video_mode(dev->chnl_state, &dev->video_mode); if (ret < 0) { dev_warn(&dev->dev, "Failed to set video mode\n"); diff --git a/drivers/video/mcde/display-generic_dsi.c b/drivers/video/mcde/display-generic_dsi.c index 15b8ccec59a..d445d806a6a 100644 --- a/drivers/video/mcde/display-generic_dsi.c +++ b/drivers/video/mcde/display-generic_dsi.c @@ -13,24 +13,23 @@ #include <linux/device.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/err.h> #include <video/mcde_display.h> #include <video/mcde_display-generic_dsi.h> static int generic_platform_enable(struct mcde_display_device *dev) { - int ret = 0; struct mcde_display_generic_platform_data *pdata = dev->dev.platform_data; dev_dbg(&dev->dev, "%s: Reset & power on generic display\n", __func__); if (pdata->regulator) { - ret = regulator_enable(pdata->regulator); - if (ret < 0) { + if (regulator_enable(pdata->regulator) < 0) { dev_err(&dev->dev, "%s:Failed to enable regulator\n" , __func__); - goto out; + return -EINVAL; } } if (pdata->reset_gpio) @@ -39,24 +38,24 @@ static int generic_platform_enable(struct mcde_display_device *dev) if (pdata->reset_gpio) gpio_set_value(pdata->reset_gpio, !pdata->reset_high); out: - return ret; + return 0; } static int generic_platform_disable(struct mcde_display_device *dev) { - int ret = 0; struct mcde_display_generic_platform_data *pdata = dev->dev.platform_data; dev_dbg(&dev->dev, "%s:Reset & power off generic display\n", __func__); if (pdata->regulator) { - ret = regulator_disable(pdata->regulator); - if (ret < 0) + if (regulator_disable(pdata->regulator) < 0) { dev_err(&dev->dev, "%s:Failed to disable regulator\n" , __func__); + return -EINVAL; + } } - return ret; + return 0; } static int __devinit generic_probe(struct mcde_display_device *dev) diff --git a/drivers/video/mcde/mcde_display.c b/drivers/video/mcde/mcde_display.c index 1537980dcaf..a3aff5021b9 100644 --- a/drivers/video/mcde/mcde_display.c +++ b/drivers/video/mcde/mcde_display.c @@ -205,7 +205,7 @@ static int mcde_display_set_synchronized_update_default( struct mcde_display_device *ddev, bool enable) { int ret = 0; - if (ddev->port->type == MCDE_PORTTYPE_DSI) { + if (ddev->port->type == MCDE_PORTTYPE_DSI && enable) { if (ddev->port->sync_src == MCDE_SYNCSRC_TE0 || ddev->port->sync_src == MCDE_SYNCSRC_TE1 || ddev->port->sync_src == MCDE_SYNCSRC_BTA) { @@ -216,7 +216,7 @@ static int mcde_display_set_synchronized_update_default( ret = -EINVAL; } } else { - ret = -EINVAL; + ret = 0; } if (ret < 0) { @@ -253,6 +253,8 @@ static int mcde_display_apply_config_default(struct mcde_display_device *ddev) } if (ddev->update_flags) { + if (ddev->update_flags & UPDATE_FLAG_VIDEO_MODE) + mcde_chnl_stop_flow(ddev->chnl_state); ret = mcde_chnl_apply(ddev->chnl_state); if (ret < 0) { dev_warn(&ddev->dev, "%s:Failed to apply to channel\n", diff --git a/drivers/video/mcde/mcde_fb.c b/drivers/video/mcde/mcde_fb.c index f9697d2e9df..b5515b85a18 100644 --- a/drivers/video/mcde/mcde_fb.c +++ b/drivers/video/mcde/mcde_fb.c @@ -376,7 +376,7 @@ static int check_var(struct fb_var_screeninfo *var, struct fb_info *fbi, ret = mcde_dss_try_video_mode(ddev, &vmode); if (ret < 0) { dev_vdbg(&(ddev->dev), "check_var failed " - "mcde_dss_try_video_mode with size = %x \n", ret); + "mcde_dss_try_video_mode with size = %x\n", ret); return ret; } vmode_to_var(&vmode, var); @@ -416,7 +416,7 @@ static int apply_var(struct fb_info *fbi, struct mcde_display_device *ddev) ret = reallocate_fb_mem(fbi, size); if (ret) { dev_vdbg(&(ddev->dev), "apply_var failed with" - "reallocate mem with size = %d \n", size); + "reallocate mem with size = %d\n", size); return ret; } fbi->fix.line_length = line_len; @@ -579,6 +579,8 @@ struct fb_info *mcde_fb_create(struct mcde_display_device *ddev, if (ret) goto ovly_enable_failed; + mfb->id = ddev->id; + /* Register framebuffer */ ret = register_framebuffer(fbi); if (ret) diff --git a/drivers/video/mcde/mcde_hw.c b/drivers/video/mcde/mcde_hw.c index 3a8f30aa91e..ef3bd0328d3 100644 --- a/drivers/video/mcde/mcde_hw.c +++ b/drivers/video/mcde/mcde_hw.c @@ -30,6 +30,7 @@ #include <mach/prcmu-fw-api.h> static void disable_channel(struct mcde_chnl_state *chnl); +static void watchdog_auto_sync_timer_function(unsigned long arg); #define MSEC_TO_JIFFIES(__x) (((__x) * HZ + HZ - 1) / 1000) @@ -47,13 +48,13 @@ static struct clk *clock_dsi; static struct clk *clock_mcde; static struct clk *clock_dsi_lp; -static inline u32 dsi_rreg(int __i, u32 __reg) +static inline u32 dsi_rreg(int i, u32 reg) { - return readl(dsiio[__i] + __reg); + return readl(dsiio[i] + reg); } -static inline void dsi_wreg(int __i, u32 __reg, u32 __val) +static inline void dsi_wreg(int i, u32 reg, u32 val) { - writel(__val, dsiio[__i] + __reg); + writel(val, dsiio[i] + reg); } #define dsi_rfld(__i, __reg, __fld) \ ((dsi_rreg(__i, __reg) & __reg##_##__fld##_MASK) >> \ @@ -63,13 +64,13 @@ static inline void dsi_wreg(int __i, u32 __reg, u32 __val) ~__reg##_##__fld##_MASK) | (((__val) << __reg##_##__fld##_SHIFT) & \ __reg##_##__fld##_MASK)) -static inline u32 mcde_rreg(u32 __reg) +static inline u32 mcde_rreg(u32 reg) { - return readl(mcdeio + __reg); + return readl(mcdeio + reg); } -static inline void mcde_wreg(u32 __reg, u32 __val) +static inline void mcde_wreg(u32 reg, u32 val) { - writel(__val, mcdeio + __reg); + writel(val, mcdeio + reg); } #define mcde_rfld(__reg, __fld) \ ((mcde_rreg(__reg) & __reg##_##__fld##_MASK) >> \ @@ -200,6 +201,8 @@ struct mcde_chnl_state { u32 transactionid_regs; u32 transactionid_hw; wait_queue_head_t waitq_hw; /* Waitq for transactionid_hw */ + /* Used as watchdog timer for auto sync feature */ + struct timer_list auto_sync_timer; enum mcde_display_power_mode power_mode; @@ -350,7 +353,6 @@ int mcde_chnl_set_video_mode(struct mcde_chnl_state *chnl, if (chnl == NULL || vmode == NULL) return -EINVAL; - disable_channel(chnl); chnl->vmode = *vmode; return 0; @@ -367,7 +369,7 @@ static void tv_video_mode_apply(struct mcde_chnl_state *chnl) chnl->tv_regs.fsl2 = chnl->vmode.vbp2; chnl->tv_regs.interlaced_en = chnl->vmode.interlaced; - if (chnl->port.phy.dpi.num_data_lanes == 4) + if (chnl->port.phy.dpi.bus_width == 4) chnl->tv_regs.tv_mode = MCDE_TVCRA_TVMODE_SDTV_656P_BE; else chnl->tv_regs.tv_mode = MCDE_TVCRA_TVMODE_SDTV_656P; @@ -525,6 +527,8 @@ static irqreturn_t mcde_irq_handler(int irq, void *dev) { int i; u32 irq_status; + bool trig = false; + struct mcde_chnl_state *chnl; /* Handle overlay irqs */ irq_status = mcde_rfld(MCDE_RISOVL, OVLFDRIS); @@ -540,32 +544,81 @@ static irqreturn_t mcde_irq_handler(int irq, void *dev) /* Handle channel irqs */ irq_status = mcde_rreg(MCDE_RISPP); if (irq_status & MCDE_RISPP_VCMPARIS_MASK) { - struct mcde_chnl_state *chnl = &channels[MCDE_CHNL_A]; + chnl = &channels[MCDE_CHNL_A]; chnl->transactionid_hw = chnl->transactionid_regs; wake_up(&chnl->waitq_hw); mcde_wfld(MCDE_RISPP, VCMPARIS, 1); + if (chnl->port.update_auto_trig && + chnl->port.sync_src == MCDE_SYNCSRC_OFF && + chnl->port.type == MCDE_PORTTYPE_DSI && + chnl->continous_running) { + mcde_wreg(MCDE_CHNL0SYNCHSW + + chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, + MCDE_CHNL0SYNCHSW_SW_TRIG(true)); + mod_timer(&chnl->auto_sync_timer, + jiffies + + msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG + * 1000)); + } } if (irq_status & MCDE_RISPP_VCMPBRIS_MASK) { - struct mcde_chnl_state *chnl = &channels[MCDE_CHNL_B]; + chnl = &channels[MCDE_CHNL_B]; chnl->transactionid_hw = chnl->transactionid_regs; wake_up(&chnl->waitq_hw); mcde_wfld(MCDE_RISPP, VCMPBRIS, 1); + if (chnl->port.update_auto_trig && + chnl->port.sync_src == MCDE_SYNCSRC_OFF && + chnl->port.type == MCDE_PORTTYPE_DSI && + chnl->continous_running) { + mcde_wreg(MCDE_CHNL0SYNCHSW + + chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, + MCDE_CHNL0SYNCHSW_SW_TRIG(true)); + mod_timer(&chnl->auto_sync_timer, + jiffies + + msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG + * 1000)); + } } if (irq_status & MCDE_RISPP_VCMPC0RIS_MASK) { - struct mcde_chnl_state *chnl = &channels[MCDE_CHNL_C0]; + chnl = &channels[MCDE_CHNL_C0]; chnl->transactionid_hw = chnl->transactionid_regs; wake_up(&chnl->waitq_hw); mcde_wfld(MCDE_RISPP, VCMPC0RIS, 1); + if (chnl->port.update_auto_trig && + chnl->port.sync_src == MCDE_SYNCSRC_OFF && + chnl->port.type == MCDE_PORTTYPE_DSI && + chnl->continous_running) { + mcde_wreg(MCDE_CHNL0SYNCHSW + + chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, + MCDE_CHNL0SYNCHSW_SW_TRIG(true)); + mod_timer(&chnl->auto_sync_timer, + jiffies + + msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG + * 1000)); + } } if (irq_status & MCDE_RISPP_VCMPC1RIS_MASK) { - struct mcde_chnl_state *chnl = &channels[MCDE_CHNL_C1]; + chnl = &channels[MCDE_CHNL_C1]; chnl->transactionid_hw = chnl->transactionid_regs; wake_up(&chnl->waitq_hw); mcde_wfld(MCDE_RISPP, VCMPC1RIS, 1); + if (chnl->port.update_auto_trig && + chnl->port.sync_src == MCDE_SYNCSRC_OFF && + chnl->port.type == MCDE_PORTTYPE_DSI && + chnl->continous_running) { + mcde_wreg(MCDE_CHNL0SYNCHSW + + chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, + MCDE_CHNL0SYNCHSW_SW_TRIG(true)); + mod_timer(&chnl->auto_sync_timer, + jiffies + + msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG + * 1000)); + } } for (i = 0; i < num_dsilinks; i++) { - bool trig = false; - struct mcde_chnl_state *chnl; + struct mcde_chnl_state *chnl_from_dsi; + + trig = false; irq_status = dsi_rfld(i, DSI_DIRECT_CMD_STS_FLAG, TE_RECEIVED_FLAG); if (irq_status) { @@ -582,13 +635,14 @@ static irqreturn_t mcde_irq_handler(int irq, void *dev) } if (!trig) continue; - chnl = find_channel_by_dsilink(i); - if (chnl) { + chnl_from_dsi = find_channel_by_dsilink(i); + if (chnl_from_dsi) { mcde_wreg(MCDE_CHNL0SYNCHSW + - chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, + chnl_from_dsi->id * + MCDE_CHNL0SYNCHSW_GROUPOFFSET, MCDE_CHNL0SYNCHSW_SW_TRIG(true)); dev_vdbg(&mcde_dev->dev, "SW TRIG DSI%d, chnl=%d\n", i, - chnl->id); + chnl_from_dsi->id); } } @@ -797,6 +851,23 @@ static void update_overlay_registers(u8 idx, struct ovly_regs *regs, #endif /* CONFIG_AV8100_SDTV */ if (regs->reset_buf_id) { + u32 sel_mod = MCDE_EXTSRC0CR_SEL_MOD_SOFTWARE_SEL; + if (port->update_auto_trig && port->type == MCDE_PORTTYPE_DSI) { + switch (port->sync_src) { + case MCDE_SYNCSRC_OFF: + sel_mod = MCDE_EXTSRC0CR_SEL_MOD_SOFTWARE_SEL; + break; + case MCDE_SYNCSRC_TE0: + case MCDE_SYNCSRC_TE1: + default: + sel_mod = MCDE_EXTSRC0CR_SEL_MOD_AUTO_TOGGLE; + } + } else if (port->type == MCDE_PORTTYPE_DPI) { + sel_mod = port->update_auto_trig ? + MCDE_EXTSRC0CR_SEL_MOD_AUTO_TOGGLE : + MCDE_EXTSRC0CR_SEL_MOD_SOFTWARE_SEL; + } + regs->reset_buf_id = false; mcde_wreg(MCDE_EXTSRC0CONF + idx * MCDE_EXTSRC0CONF_GROUPOFFSET, MCDE_EXTSRC0CONF_BUF_ID(0) | @@ -807,9 +878,7 @@ static void update_overlay_registers(u8 idx, struct ovly_regs *regs, MCDE_EXTSRC0CONF_BEBO(regs->bebo) | MCDE_EXTSRC0CONF_BEPO(false)); mcde_wreg(MCDE_EXTSRC0CR + idx * MCDE_EXTSRC0CR_GROUPOFFSET, - MCDE_EXTSRC0CR_SEL_MOD(port->update_auto_trig ? - MCDE_EXTSRC0CR_SEL_MOD_AUTO_TOGGLE : - MCDE_EXTSRC0CR_SEL_MOD_SOFTWARE_SEL) | + MCDE_EXTSRC0CR_SEL_MOD(sel_mod) | MCDE_EXTSRC0CR_MULTIOVL_CTRL_ENUM(PRIMARY) | MCDE_EXTSRC0CR_FS_DIV_DISABLE(false) | MCDE_EXTSRC0CR_FORCE_FS_DIV(false)); @@ -951,6 +1020,42 @@ static void enable_channel(struct mcde_chnl_state *chnl) } } +static int is_channel_enabled(struct mcde_chnl_state *chnl) +{ + switch (chnl->id) { + case MCDE_CHNL_A: + return mcde_rfld(MCDE_CRA0, FLOEN); + case MCDE_CHNL_B: + return mcde_rfld(MCDE_CRB0, FLOEN); + case MCDE_CHNL_C0: + return mcde_rfld(MCDE_CRC, FLOEN); + case MCDE_CHNL_C1: + return mcde_rfld(MCDE_CRC, FLOEN); + } + return 0; +} + +static void watchdog_auto_sync_timer_function(unsigned long arg) +{ + int i; + for (i = 0; i < ARRAY_SIZE(channels); i++) { + struct mcde_chnl_state *chnl = &channels[i]; + if (chnl->port.update_auto_trig && + chnl->port.sync_src == MCDE_SYNCSRC_OFF && + chnl->port.type == MCDE_PORTTYPE_DSI && + chnl->continous_running) { + mcde_wreg(MCDE_CHNL0SYNCHSW + + chnl->id + * MCDE_CHNL0SYNCHSW_GROUPOFFSET, + MCDE_CHNL0SYNCHSW_SW_TRIG(true)); + mod_timer(&chnl->auto_sync_timer, + jiffies + + msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG + * 1000)); + } + } +} + /* TODO get from register */ #define MCDE_CLK_FREQ_MHZ 160 @@ -960,14 +1065,30 @@ void update_channel_registers(enum mcde_chnl chnl_id, struct chnl_regs *regs, { u8 idx = chnl_id; u32 out_synch_src = MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER; + u32 src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE; dev_vdbg(&mcde_dev->dev, "%s\n", __func__); /* Channel */ - if (port->update_auto_trig && port->type != MCDE_PORTTYPE_DPI) { - out_synch_src = port->sync_src == MCDE_SYNCSRC_TE0 ? - MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_VSYNC0 : - MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_VSYNC1; + if (port->update_auto_trig && port->type == MCDE_PORTTYPE_DSI) { + switch (port->sync_src) { + case MCDE_SYNCSRC_TE0: + out_synch_src = MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_VSYNC0; + src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_OUTPUT; + break; + case MCDE_SYNCSRC_OFF: + src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE; + break; + case MCDE_SYNCSRC_TE1: + default: + out_synch_src = MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_VSYNC1; + src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_OUTPUT; + } + } else if (port->type == MCDE_PORTTYPE_DPI) { + src_synch = port->update_auto_trig ? + MCDE_CHNL0SYNCHMOD_SRC_SYNCH_OUTPUT : + MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE; } + mcde_wreg(MCDE_CHNL0CONF + idx * MCDE_CHNL0CONF_GROUPOFFSET, MCDE_CHNL0CONF_PPL(regs->ppl-1) | MCDE_CHNL0CONF_LPF(regs->lpf-1)); @@ -976,9 +1097,7 @@ void update_channel_registers(enum mcde_chnl chnl_id, struct chnl_regs *regs, MCDE_CHNL0STAT_CHNLRD(true)); mcde_wreg(MCDE_CHNL0SYNCHMOD + idx * MCDE_CHNL0SYNCHMOD_GROUPOFFSET, - MCDE_CHNL0SYNCHMOD_SRC_SYNCH(port->update_auto_trig ? - MCDE_CHNL0SYNCHMOD_SRC_SYNCH_OUTPUT : - MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE) | + MCDE_CHNL0SYNCHMOD_SRC_SYNCH(src_synch) | MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC(out_synch_src)); mcde_wreg(MCDE_CHNL0BCKGNDCOL + idx * MCDE_CHNL0BCKGNDCOL_GROUPOFFSET, MCDE_CHNL0BCKGNDCOL_B(255) | /* TODO: Temp */ @@ -1317,7 +1436,9 @@ int mcde_chnl_set_pixel_format(struct mcde_chnl_state *chnl, { if (!chnl->inuse) return -EINVAL; + chnl->pix_fmt = pix_fmt; + return 0; } @@ -1434,8 +1555,19 @@ static void chnl_update_continous(struct mcde_chnl_state *chnl) mcde_wfld(MCDE_CRC, SYCEN0, true); else if (chnl->port.sync_src == MCDE_SYNCSRC_TE1) mcde_wfld(MCDE_CRC, SYCEN1, true); - chnl->continous_running = true; + /* + * For main and secondary display, + * FLOWEN has to be set before a SOFTWARE TRIG + * Otherwise not overlay interrupt is triggerd + */ + enable_channel(chnl); + if (chnl->port.type == MCDE_PORTTYPE_DSI && + chnl->port.sync_src == MCDE_SYNCSRC_OFF) { + mod_timer(&chnl->auto_sync_timer, + jiffies + + msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG * 1000)); + } } } @@ -1446,6 +1578,18 @@ static void chnl_update_non_continous(struct mcde_chnl_state *chnl) if (chnl->transactionid_regs < chnl->transactionid) chnl_update_registers(chnl); + /* + * For main and secondary display, + * FLOWEN has to be set before a SOFTWARE TRIG + * Otherwise not overlay interrupt is triggerd + * However FLOWEN must not be triggered before SOFTWARE TRIG + * if rotation is enabled + */ + if (chnl->power_mode == MCDE_DISPLAY_PM_STANDBY || + (!is_channel_enabled(chnl) && !chnl->regs.roten)) + enable_channel(chnl); + + /* TODO: look at port sync source and synched_update */ if (chnl->regs.synchronized_update && chnl->power_mode == MCDE_DISPLAY_PM_ON) { @@ -1463,6 +1607,8 @@ static void chnl_update_non_continous(struct mcde_chnl_state *chnl) dev_vdbg(&mcde_dev->dev, "Channel update (no sync), chnl=%d\n", chnl->id); } + if (chnl->power_mode == MCDE_DISPLAY_PM_ON) + enable_channel(chnl); } static void chnl_update_overlay(struct mcde_chnl_state *chnl, @@ -1474,10 +1620,9 @@ static void chnl_update_overlay(struct mcde_chnl_state *chnl, update_overlay_address_registers(ovly->idx, &ovly->regs); if (ovly->regs.reset_buf_id) { - if (chnl->continous_running) - disable_channel(chnl); - else + if (!chnl->continous_running) wait_for_overlay(ovly); + update_overlay_registers(ovly->idx, &ovly->regs, &chnl->port, chnl->fifo, chnl->regs.x, chnl->regs.y, chnl->regs.ppl, chnl->regs.lpf, ovly->stride, @@ -1521,8 +1666,6 @@ int mcde_chnl_update(struct mcde_chnl_state *chnl, else chnl_update_non_continous(chnl); - enable_channel(chnl); - dev_vdbg(&mcde_dev->dev, "Channel updated, chnl=%d\n", chnl->id); return 0; } @@ -1539,6 +1682,11 @@ void mcde_chnl_put(struct mcde_chnl_state *chnl) update_channel_static_registers(chnl); } +void mcde_chnl_stop_flow(struct mcde_chnl_state *chnl) +{ + disable_channel(chnl); +} + /* MCDE overlays */ struct mcde_ovly_state *mcde_ovly_get(struct mcde_chnl_state *chnl) { @@ -1634,7 +1782,7 @@ void mcde_ovly_apply(struct mcde_ovly_state *ovly) ovly->regs.enabled = ovly->paddr != 0; ovly->regs.baseaddress0 = ovly->paddr; ovly->regs.baseaddress1 = ovly->paddr + ovly->stride; -/*TODO set to true if interlaced *//* REVIEW: Video mode interlaced? */ + /*TODO set to true if interlaced *//* REVIEW: Video mode interlaced? */ ovly->regs.reset_buf_id = !ovly->chnl->continous_running; switch (ovly->pix_fmt) {/* REVIEW: Extract to table */ case MCDE_OVLYPIXFMT_RGB565: @@ -2015,8 +2163,16 @@ out: return ret; } + static int __devexit mcde_remove(struct platform_device *pdev) { + struct mcde_chnl_state *chnl = &channels[0]; + for (; chnl < &channels[ARRAY_SIZE(channels)]; chnl++) { + if (del_timer(&chnl->auto_sync_timer)) + dev_vdbg(&mcde_dev->dev, + "%s timer could not be stopped\n" + , __func__); + } remove_clocks_and_power(pdev); return 0; } @@ -2026,7 +2182,7 @@ static int mcde_resume(struct platform_device *pdev) { int ret; struct mcde_chnl_state *chnl = &channels[0]; - dev_info(&pdev->dev, "Resume is called\n"); + dev_vdbg(&mcde_dev->dev, "%s\n", __func__); ret = enable_clocks_and_power(pdev); if (ret < 0) { dev_dbg(&pdev->dev, "%s: Enable clocks and power failed\n" @@ -2067,7 +2223,18 @@ clock_err: #ifdef CONFIG_PM static int mcde_suspend(struct platform_device *pdev, pm_message_t state) { - dev_info(&pdev->dev, "Suspend is called\n"); + struct mcde_chnl_state *chnl = &channels[0]; + + dev_vdbg(&mcde_dev->dev, "%s\n", __func__); + + /* This is added because of the auto sync feature */ + for (; chnl < &channels[ARRAY_SIZE(channels)]; chnl++) { + mcde_chnl_stop_flow(chnl); + if (del_timer(&chnl->auto_sync_timer)) + dev_vdbg(&mcde_dev->dev, + "%s timer could not be stopped\n" + , __func__); + } return disable_clocks_and_power(pdev); } #endif @@ -2087,8 +2254,7 @@ static struct platform_driver mcde_driver = { }, }; -/* REVIEW: __init? */ -int mcde_init(void) +int __init mcde_init(void) { int i; for (i = 0; i < ARRAY_SIZE(channels); i++) { @@ -2096,6 +2262,9 @@ int mcde_init(void) if (channels[i].ovly1) channels[i].ovly1->chnl = &channels[i]; init_waitqueue_head(&channels[i].waitq_hw); + init_timer(&channels[i].auto_sync_timer); + channels[i].auto_sync_timer.function = + watchdog_auto_sync_timer_function; } for (i = 0; i < ARRAY_SIZE(overlays); i++) init_waitqueue_head(&overlays[i].waitq_hw); diff --git a/include/video/mcde.h b/include/video/mcde.h index b682200edc7..f8a8fb2a213 100644 --- a/include/video/mcde.h +++ b/include/video/mcde.h @@ -11,13 +11,10 @@ #ifndef __MCDE__H__ #define __MCDE__H__ -#include <linux/fb.h> /* REVIEW: Remove */ - /* Physical interface types */ enum mcde_port_type { MCDE_PORTTYPE_DSI = 0, MCDE_PORTTYPE_DPI = 1, - MCDE_PORTTYPE_DBI = 2, /* REVIEW: Remove */ }; /* Interface mode */ @@ -78,8 +75,6 @@ enum mcde_chnl_path { MCDE_CHNLPATH_CHNLB_FIFOB_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 1, 2), /* Channel C0 */ - MCDE_CHNLPATH_CHNLC0_FIFOC0_DBI_0 = MCDE_CHNLPATH(MCDE_CHNL_C0, - MCDE_FIFO_C0, MCDE_PORTTYPE_DBI, 0, 0), MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 0), MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_C0, @@ -93,8 +88,6 @@ enum mcde_chnl_path { MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 1, 2), /* Channel C1 */ - MCDE_CHNLPATH_CHNLC1_FIFOC1_DBI_1 = MCDE_CHNLPATH(MCDE_CHNL_C1, - MCDE_FIFO_C1, MCDE_PORTTYPE_DBI, 0, 1), MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 0), MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_C1, @@ -115,19 +108,15 @@ enum mcde_sync_src { MCDE_SYNCSRC_TE0 = 1, /* MCDE ext TE0 */ MCDE_SYNCSRC_TE1 = 2, /* MCDE ext TE1 */ MCDE_SYNCSRC_BTA = 3, /* DSI BTA */ - MCDE_SYNCSRC_EXT = 4, /* GPIO, or other outside MCDE control */ -};/* REVIEW: Remove _EXT, not supported */ +}; /* Interface pixel formats (output) */ -/* REVIEW: Define formats */ +/* +* REVIEW: Define formats +* Add explanatory comments how the formats are ordered in memory +*/ enum mcde_port_pix_fmt { /* MIPI standard formats */ - MCDE_PORTPIXFMT_DBI_3BPP = 0x11,/* REVIEW: Remove */ - MCDE_PORTPIXFMT_DBI_8BPP = 0x12,/* REVIEW: Remove */ - MCDE_PORTPIXFMT_DBI_12BPP = 0x13,/* REVIEW: Remove */ - MCDE_PORTPIXFMT_DBI_16BPP = 0x15,/* REVIEW: Remove */ - MCDE_PORTPIXFMT_DBI_18BPP = 0x16,/* REVIEW: Remove */ - MCDE_PORTPIXFMT_DBI_24BPP = 0x17,/* REVIEW: Remove */ MCDE_PORTPIXFMT_DPI_16BPP_C1 = 0x21, MCDE_PORTPIXFMT_DPI_16BPP_C2 = 0x22, @@ -166,8 +155,7 @@ struct mcde_port { bool clk_cont; } dsi; struct { - bool chip_select;/* REVIEW: Used? Needed? */ - u8 num_data_lanes;/* REVIEW: Rename to bus_width? */ + u8 bus_width; } dpi; } phy; }; @@ -216,6 +204,9 @@ enum mcde_display_rotation { #define MCDE_PIXFETCH_MEDIUM_WTRMRKLVL 64 #define MCDE_PIXFETCH_SMALL_WTRMRKLVL 16 +/* In seconds */ +#define MCDE_AUTO_SYNC_WATCHDOG 5 + /* Video mode descriptor */ struct mcde_video_mode {/* REVIEW: Join 1 & 2 */ u32 xres; @@ -271,7 +262,7 @@ void mcde_chnl_set_col_convert(struct mcde_chnl_state *chnl, struct mcde_col_convert *col_convert); int mcde_chnl_set_video_mode(struct mcde_chnl_state *chnl, struct mcde_video_mode *vmode); -/* TODO: Remove rotbuf* parameters */ +/* TODO: Remove rotbuf* parameters when ESRAM allocator is implemented*/ int mcde_chnl_set_rotation(struct mcde_chnl_state *chnl, enum mcde_display_rotation rotation, u32 rotbuf1, u32 rotbuf2); int mcde_chnl_enable_synchronized_update(struct mcde_chnl_state *chnl, @@ -284,6 +275,8 @@ int mcde_chnl_update(struct mcde_chnl_state *chnl, struct mcde_rectangle *update_area); void mcde_chnl_put(struct mcde_chnl_state *chnl); +void mcde_chnl_stop_flow(struct mcde_chnl_state *chnl); + /* MCDE overlay */ struct mcde_ovly_state; @@ -358,7 +351,7 @@ struct mcde_platform_data { /* DSI */ int num_dsilinks; - /* DBI/DPI */ + /* DPI */ u8 outmux[5]; /* MCDE_CONF0.OUTMUXx */ u8 syncmux; /* MCDE_CONF0.SYNCMUXx */ @@ -368,7 +361,7 @@ struct mcde_platform_data { const char *clock_mcde_id; }; -int mcde_init(void); +int __init mcde_init(void); void mcde_exit(void); #endif /* __MCDE__H__ */ diff --git a/include/video/mcde_fb.h b/include/video/mcde_fb.h index 6d05f612184..8aa3d134e74 100644 --- a/include/video/mcde_fb.h +++ b/include/video/mcde_fb.h @@ -33,6 +33,7 @@ struct mcde_fb { struct mcde_overlay *ovlys[MCDE_FB_MAX_NUM_OVERLAYS]; u32 pseudo_palette[17]; enum mcde_ovly_pix_fmt pix_fmt; + int id; }; /* MCDE fbdev API */ diff --git a/kernel.spec b/kernel.spec index 6f23df05e1c..5e21c8811e9 100644 --- a/kernel.spec +++ b/kernel.spec @@ -377,7 +377,10 @@ BuildKernel() { # Set config make %{?_smp_mflags} mop500$(DEBUG)_power_defconfig # STE: Disable multibuffer and multitouch. - scripts/config --file .config --disable FB_MCDE_MULTIBUFFER --disable U8500_TSC_MULTITOUCH + scripts/config --file .config --enable DISPLAY_GENERIC_DSI_PRIMARY_AUTO_SYNC --enable DISPLAY_GENERIC_DSI_SECONDARY_AUTO_SYNC + # Does not exist in the 34 kernel yet + #scripts/config --file .config --disable U8500_TSC_MULTITOUCH + # STE: Enable conf for external sd-cards. scripts/config --file .config --enable LEVELSHIFTER_HREF_V1_PLUS # STE: Enable g_multi USB gadget with RNDIS, CDC Serial and Storage configuration. |