summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/backlight/lcd.c2
-rw-r--r--drivers/video/console/Kconfig9
-rw-r--r--drivers/video/console/Makefile12
-rw-r--r--drivers/video/console/fbcon.c10
-rw-r--r--drivers/video/matrox/g450_pll.c3
-rw-r--r--drivers/video/modedb.c5
-rw-r--r--drivers/video/mxc/Kconfig4
-rw-r--r--drivers/video/mxc/Makefile1
-rw-r--r--drivers/video/mxc/mxc_elcdif_fb.c73
-rw-r--r--drivers/video/mxc/mxc_epdc_fb.c630
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c306
-rw-r--r--drivers/video/mxc/tve.c7
-rw-r--r--drivers/video/s3c-fb.c2
-rw-r--r--drivers/video/sis/vstruct.h2
-rw-r--r--drivers/video/uvesafb.c6
15 files changed, 426 insertions, 646 deletions
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b6449470106c..a482dd7b0311 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -56,7 +56,7 @@ static int fb_notifier_callback(struct notifier_block *self,
static int lcd_register_fb(struct lcd_device *ld)
{
- memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif));
+ memset(&ld->fb_notif, 0, sizeof(ld->fb_notif));
ld->fb_notif.notifier_call = fb_notifier_callback;
return fb_register_client(&ld->fb_notif);
}
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 2f50a80b413e..979b5a18588c 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -67,16 +67,9 @@ config SGI_NEWPORT_CONSOLE
# bool 'IODC console' CONFIG_IODC_CONSOLE
-config PROM_CONSOLE
- bool "PROM console"
- depends on SPARC
- help
- Say Y to build a console driver for Sun machines that uses the
- terminal emulation built into their console PROMS.
-
config DUMMY_CONSOLE
bool
- depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
+ depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
default y
config DUMMY_CONSOLE_COLUMNS
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index ac46cc3f6a2a..a862e9173ebe 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -22,7 +22,6 @@ font-objs += $(font-objs-y)
obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o
obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o
-obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o
obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
@@ -40,14 +39,3 @@ obj-$(CONFIG_FB_STI) += sticore.o font.o
ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
obj-$(CONFIG_USB_SISUSBVGA) += font.o
endif
-
-# Targets that kbuild needs to know about
-targets := promcon_tbl.c
-
-quiet_cmd_conmakehash = CNMKHSH $@
- cmd_conmakehash = scripts/conmakehash $< | \
- sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \
- -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@
-
-$(obj)/promcon_tbl.c: $(src)/prom.uni
- $(call cmd,conmakehash)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3a44695b9c09..29ff5ea3cc3c 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -114,6 +114,7 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1;
static int fbcon_is_default = 1;
static int fbcon_has_exited;
static int primary_device = -1;
+static int fbcon_has_console_bind;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
static int map_override;
@@ -544,6 +545,8 @@ static int fbcon_takeover(int show_logo)
con2fb_map[i] = -1;
}
info_idx = -1;
+ } else {
+ fbcon_has_console_bind = 1;
}
return err;
@@ -2923,6 +2926,10 @@ static int fbcon_unbind(void)
ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
fbcon_is_default);
+
+ if (!ret)
+ fbcon_has_console_bind = 0;
+
return ret;
}
#else
@@ -2936,6 +2943,9 @@ static int fbcon_fb_unbind(int idx)
{
int i, new_idx = -1, ret = 0;
+ if (!fbcon_has_console_bind)
+ return 0;
+
for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map[i] != idx &&
con2fb_map[i] != -1) {
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c
index d42346e7fdda..3dcb6d218f7c 100644
--- a/drivers/video/matrox/g450_pll.c
+++ b/drivers/video/matrox/g450_pll.c
@@ -341,7 +341,8 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
M1064_XDVICLKCTRL_C1DVICLKEN |
M1064_XDVICLKCTRL_DVILOOPCTL |
M1064_XDVICLKCTRL_P1LOOPBWDTCTL;
- matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp);
+ /* Setting this breaks PC systems so don't do it */
+ /* matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp); */
matroxfb_DAC_out(PMINFO M1064_XPWRCTRL,
xpwrctrl);
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 9c4739c8b19c..34e4e7995169 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -35,11 +35,6 @@ EXPORT_SYMBOL_GPL(fb_mode_option);
*/
static const struct fb_videomode modedb[] = {
- {
- /* 800x480 @ 60 Hz, 31.5 kHz hsync */
- "LQ070Y3DG3B", 60, 800, 480, 44000, 0, 50, 25, 10, 128, 10,
- FB_SYNC_EXT,FB_VMODE_NONINTERLACED
- },
{
/* 640x400 @ 70 Hz, 31.5 kHz hsync */
NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
diff --git a/drivers/video/mxc/Kconfig b/drivers/video/mxc/Kconfig
index 42f990ac3499..e86e6d86b978 100644
--- a/drivers/video/mxc/Kconfig
+++ b/drivers/video/mxc/Kconfig
@@ -38,10 +38,6 @@ config FB_MXC_CLAA_WVGA_SYNC_PANEL
depends on FB_MXC_SYNC_PANEL
tristate "CLAA WVGA Panel"
-config FB_MXC_SII9022
- depends on FB_MXC_SYNC_PANEL
- tristate "Si Image SII9022 DVI/HDMI Interface Chip"
-
config FB_MXC_CH7026
depends on FB_MXC_SYNC_PANEL
tristate "Chrontel CH7026 VGA Interface Chip"
diff --git a/drivers/video/mxc/Makefile b/drivers/video/mxc/Makefile
index d823ab29f030..b47b3f77cd80 100644
--- a/drivers/video/mxc/Makefile
+++ b/drivers/video/mxc/Makefile
@@ -21,4 +21,3 @@ obj-$(CONFIG_FB_MXC_TVOUT_TVE) += tve.o
obj-$(CONFIG_FB_MXC_CH7026) += mxcfb_ch7026.o
#obj-$(CONFIG_FB_MODE_HELPERS) += mxc_edid.o
obj-$(CONFIG_VIDEO_AD9389) += ad9389.o
-obj-$(CONFIG_FB_MXC_SII9022) += mxcfb_sii9022.o
diff --git a/drivers/video/mxc/mxc_elcdif_fb.c b/drivers/video/mxc/mxc_elcdif_fb.c
index e163edb7bfb9..44587d28c7f9 100644
--- a/drivers/video/mxc/mxc_elcdif_fb.c
+++ b/drivers/video/mxc/mxc_elcdif_fb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -64,8 +64,7 @@
#define ELCDIF_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R')
struct mxc_elcdif_fb_data {
- int cur_blank;
- int next_blank;
+ int is_blank;
int output_pix_fmt;
int elcdif_mode;
ssize_t mem_size;
@@ -518,7 +517,7 @@ static inline void mxc_init_elcdif(void)
return;
}
-int mxc_elcdif_frame_addr_setup(dma_addr_t phys)
+static inline int mxc_elcdif_dma_init(dma_addr_t phys)
{
int ret = 0;
@@ -807,7 +806,7 @@ static int mxc_elcdif_fb_set_par(struct fb_info *fbi)
return -ENOMEM;
}
- if (data->next_blank != FB_BLANK_UNBLANK)
+ if (data->is_blank)
return 0;
/* init next panel */
@@ -846,7 +845,7 @@ static int mxc_elcdif_fb_set_par(struct fb_info *fbi)
data->output_pix_fmt,
sig_cfg,
1);
- mxc_elcdif_frame_addr_setup(fbi->fix.smem_start);
+ mxc_elcdif_dma_init(fbi->fix.smem_start);
mxc_elcdif_run();
mxc_elcdif_blank_panel(FB_BLANK_UNBLANK);
@@ -951,7 +950,7 @@ static int mxc_elcdif_fb_wait_for_vsync(u32 channel, struct fb_info *info)
(struct mxc_elcdif_fb_data *)info->par;
int ret = 0;
- if (data->cur_blank != FB_BLANK_UNBLANK) {
+ if (data->is_blank) {
dev_err(info->device, "can't wait for VSYNC when fb "
"is blank\n");
return -EINVAL;
@@ -991,15 +990,6 @@ static int mxc_elcdif_fb_ioctl(struct fb_info *info, unsigned int cmd,
if (!get_user(channel, (__u32 __user *) arg))
ret = mxc_elcdif_fb_wait_for_vsync(channel, info);
break;
- case MXCFB_GET_FB_BLANK:
- {
- struct mxc_elcdif_fb_data *data =
- (struct mxc_elcdif_fb_data *)info->par;
-
- if (put_user(data->cur_blank, (__u32 __user *)arg))
- return -EFAULT;
- break;
- }
default:
break;
}
@@ -1012,28 +1002,22 @@ static int mxc_elcdif_fb_blank(int blank, struct fb_info *info)
(struct mxc_elcdif_fb_data *)info->par;
int ret = 0;
- if (data->cur_blank == blank)
+ if (data->is_blank == (blank != FB_BLANK_UNBLANK))
return ret;
- data->next_blank = blank;
-
- if (!g_elcdif_pix_clk_enable) {
- clk_enable(g_elcdif_pix_clk);
- g_elcdif_pix_clk_enable = true;
+ if (blank == FB_BLANK_UNBLANK) {
+ if (!g_elcdif_pix_clk_enable) {
+ clk_enable(g_elcdif_pix_clk);
+ g_elcdif_pix_clk_enable = true;
+ }
}
ret = mxc_elcdif_blank_panel(blank);
if (ret == 0)
- data->cur_blank = blank;
+ data->is_blank = (blank != FB_BLANK_UNBLANK);
else
return ret;
- if (blank == FB_BLANK_UNBLANK) {
- ret = mxc_elcdif_fb_set_par(info);
- if (ret)
- return ret;
- }
-
- if (data->cur_blank != FB_BLANK_UNBLANK) {
+ if (data->is_blank) {
if (g_elcdif_axi_clk_enable) {
clk_disable(g_elcdif_axi_clk);
g_elcdif_axi_clk_enable = false;
@@ -1064,7 +1048,7 @@ static int mxc_elcdif_fb_pan_display(struct fb_var_screeninfo *var,
int ret = 0;
unsigned long base;
- if (data->cur_blank != FB_BLANK_UNBLANK) {
+ if (data->is_blank) {
dev_err(info->device, "can't do pan display when fb "
"is blank\n");
return -EINVAL;
@@ -1187,7 +1171,7 @@ static int mxc_elcdif_fb_probe(struct platform_device *pdev)
}
data = (struct mxc_elcdif_fb_data *)fbi->par;
- data->cur_blank = data->next_blank = FB_BLANK_UNBLANK;
+ data->is_blank = false;
fbi->var.activate = FB_ACTIVATE_NOW;
fbi->fbops = &mxc_elcdif_fb_ops;
@@ -1350,9 +1334,9 @@ static int mxc_elcdif_fb_suspend(struct platform_device *pdev,
acquire_console_sem();
fb_set_suspend(fbi, 1);
- saved_blank = data->cur_blank;
+ saved_blank = data->is_blank;
mxc_elcdif_fb_blank(FB_BLANK_POWERDOWN, fbi);
- data->next_blank = saved_blank;
+ data->is_blank = saved_blank;
if (!g_elcdif_pix_clk_enable) {
clk_enable(g_elcdif_pix_clk);
g_elcdif_pix_clk_enable = true;
@@ -1363,11 +1347,7 @@ static int mxc_elcdif_fb_suspend(struct platform_device *pdev,
clk_disable(g_elcdif_pix_clk);
g_elcdif_pix_clk_enable = false;
}
- if (g_elcdif_axi_clk_enable) {
- clk_disable(g_elcdif_axi_clk);
- g_elcdif_axi_clk_enable = false;
- }
- release_console_sem();
+
return 0;
}
@@ -1377,7 +1357,20 @@ static int mxc_elcdif_fb_resume(struct platform_device *pdev)
struct mxc_elcdif_fb_data *data = (struct mxc_elcdif_fb_data *)fbi->par;
acquire_console_sem();
- mxc_elcdif_fb_blank(data->next_blank, fbi);
+ if (!g_elcdif_pix_clk_enable) {
+ clk_enable(g_elcdif_pix_clk);
+ g_elcdif_pix_clk_enable = true;
+ }
+ mxc_init_elcdif();
+ mxc_elcdif_init_panel();
+ mxc_elcdif_dma_init(fbi->fix.smem_start);
+ mxc_elcdif_run();
+ if (g_elcdif_pix_clk_enable) {
+ clk_disable(g_elcdif_pix_clk);
+ g_elcdif_pix_clk_enable = false;
+ }
+ if (!data->is_blank)
+ mxc_elcdif_fb_blank(FB_BLANK_UNBLANK, fbi);
fb_set_suspend(fbi, 0);
release_console_sem();
diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c
index e9aa9fc72f9c..27f9faa64e53 100644
--- a/drivers/video/mxc/mxc_epdc_fb.c
+++ b/drivers/video/mxc/mxc_epdc_fb.c
@@ -21,6 +21,8 @@
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
*/
+/*#define NO_POWERDOWN*/
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
@@ -55,7 +57,6 @@
/*#define DEFAULT_PANEL_HW_INIT*/
#define NUM_SCREENS 2
-#define NUM_SCREENS_X 16
#define EPDC_NUM_LUTS 16
#define EPDC_MAX_NUM_UPDATES 20
#define INVALID_LUT -1
@@ -71,7 +72,20 @@
#define POWER_STATE_ON 1
static unsigned long default_bpp = 16;
-static unsigned long g_num_screens = NUM_SCREENS;
+
+struct mxc_epdc_platform_fb_entry {
+ char name[16];
+ u16 x_res;
+ u16 y_res;
+ u16 bpp;
+ u32 cycle_time_ns;
+ struct list_head link;
+};
+
+struct mxc_epdc_platform_fb_data {
+ struct list_head list;
+ struct mxc_epdc_platform_fb_entry *cur;
+};
struct update_marker_data {
u32 update_marker;
@@ -99,15 +113,13 @@ struct update_data_list {
struct mxc_epdc_fb_data {
struct fb_info info;
u32 pseudo_palette[16];
- char *fb_panel_str;
struct list_head list;
- struct mxc_epdc_fb_mode *cur_mode;
- struct mxc_epdc_fb_platform_data *pdata;
+ struct mxc_epdc_platform_fb_entry *cur;
int blank;
+ ssize_t mem_size;
ssize_t map_size;
dma_addr_t phys_start;
u32 fb_offset;
- int default_bpp;
int native_width;
int native_height;
int epdc_irq;
@@ -143,10 +155,9 @@ struct mxc_epdc_fb_data {
struct update_marker_data update_marker_array[EPDC_MAX_NUM_UPDATES];
u32 lut_update_type[EPDC_NUM_LUTS];
struct completion updates_done;
- struct delayed_work epdc_done_work;
+ struct work_struct epdc_done_work;
struct mutex power_mutex;
bool powering_down;
- int pwrdown_delay;
/* FB elements related to PxP DMA */
struct completion pxp_tx_cmpl;
@@ -191,12 +202,35 @@ struct mxcfb_waveform_data_file {
void __iomem *epdc_base;
+#define NUM_PANELS 1
+
+static struct fb_videomode panel_modes[NUM_PANELS] = {
+ {
+ /* 800x600 @ 60 Hz , pixel clk @ 20MHz */
+ "E-INK SVGA", 60, 800, 600, 50000, 8, 142, 4, 10, 20, 4,
+ 0,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+/*
+ * This is a temporary placeholder
+ * Ultimately, this declaration will be off in a panel-specific file,
+ * and will include implementations for all of the panel functions
+ */
+static struct mxc_epdc_platform_fb_entry ed060sc4_fb_entry = {
+ .name = "ed060sc4",
+ .x_res = 800,
+ .y_res = 600,
+ .bpp = 16,
+ .cycle_time_ns = 200,
+};
+
/* forward declaration */
static int mxc_epdc_fb_blank(int blank, struct fb_info *info);
static int mxc_epdc_fb_init_hw(struct fb_info *info);
static int pxp_process_update(struct mxc_epdc_fb_data *fb_data,
- struct mxcfb_rect *update_region,
- int x_start_offs);
+ struct mxcfb_rect *update_region);
static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat);
static void draw_mode0(struct mxc_epdc_fb_data *fb_data);
@@ -392,6 +426,47 @@ static inline void dump_all_updates(struct mxc_epdc_fb_data *fb_data) {}
#endif
+void check_waveform(u32 *wv_buf_orig, u32 *wv_buf_cur, u32 wv_buf_size)
+{
+ int i;
+ bool is_mismatch = false;
+ for (i = 0; i < wv_buf_size; i++) {
+ if (wv_buf_orig[i] != wv_buf_cur[i]) {
+ is_mismatch = true;
+ printk
+ ("Waveform mismatch - wv_buf_orig[%d] = 0x%x, wv_buf_cur[%d] = 0x%x\n",
+ i, wv_buf_orig[i], i, wv_buf_cur[i]);
+ }
+ }
+
+ if (!is_mismatch)
+ printk("No mismatches!\n");
+}
+
+static struct fb_var_screeninfo mxc_epdc_fb_default __devinitdata = {
+ .activate = FB_ACTIVATE_TEST,
+ .height = -1,
+ .width = -1,
+ .pixclock = 20000,
+ .left_margin = 8,
+ .right_margin = 142,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo mxc_epdc_fb_fix __devinitdata = {
+ .id = "mxc_epdc_fb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
+ .line_length = 800 * 2,
+};
/********************************************************
* Start Low-Level EPDC Functions
@@ -579,10 +654,9 @@ static void epdc_set_vertical_timing(u32 vert_start, u32 vert_end,
void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
{
- struct mxc_epdc_fb_mode *epdc_mode = fb_data->cur_mode;
+ struct mxc_epdc_platform_fb_entry *pentry = fb_data->cur;
struct fb_var_screeninfo *screeninfo = &fb_data->info.var;
u32 reg_val;
- int num_ce;
/* Reset */
__raw_writel(EPDC_CTRL_SFTRST, EPDC_CTRL_SET);
@@ -624,7 +698,7 @@ void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
epdc_set_temp(8);
/* EPDC_RES */
- epdc_set_screen_res(epdc_mode->vmode->xres, epdc_mode->vmode->yres);
+ epdc_set_screen_res(pentry->x_res, pentry->y_res);
/*
* EPDC_TCE_CTRL
@@ -639,7 +713,7 @@ void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
* PIXELS_PER_SDCLK = 4
*/
reg_val =
- ((epdc_mode->vscan_holdoff << EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET) &
+ ((4 << EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET) &
EPDC_TCE_CTRL_VSCAN_HOLDOFF_MASK)
| EPDC_TCE_CTRL_PIXELS_PER_SDCLK_4;
__raw_writel(reg_val, EPDC_TCE_CTRL);
@@ -657,13 +731,13 @@ void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
/* EPDC_TCE_OE */
reg_val =
- ((epdc_mode->sdoed_width << EPDC_TCE_OE_SDOED_WIDTH_OFFSET) &
+ ((10 << EPDC_TCE_OE_SDOED_WIDTH_OFFSET) &
EPDC_TCE_OE_SDOED_WIDTH_MASK)
- | ((epdc_mode->sdoed_delay << EPDC_TCE_OE_SDOED_DLY_OFFSET) &
+ | ((20 << EPDC_TCE_OE_SDOED_DLY_OFFSET) &
EPDC_TCE_OE_SDOED_DLY_MASK)
- | ((epdc_mode->sdoez_width << EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET) &
+ | ((10 << EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET) &
EPDC_TCE_OE_SDOEZ_WIDTH_MASK)
- | ((epdc_mode->sdoez_delay << EPDC_TCE_OE_SDOEZ_DLY_OFFSET) &
+ | ((20 << EPDC_TCE_OE_SDOEZ_DLY_OFFSET) &
EPDC_TCE_OE_SDOEZ_DLY_MASK);
__raw_writel(reg_val, EPDC_TCE_OE);
@@ -672,17 +746,17 @@ void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
/* EPDC_TCE_TIMING2 */
reg_val =
- ((epdc_mode->gdclk_hp_offs << EPDC_TCE_TIMING2_GDCLK_HP_OFFSET) &
+ ((480 << EPDC_TCE_TIMING2_GDCLK_HP_OFFSET) &
EPDC_TCE_TIMING2_GDCLK_HP_MASK)
- | ((epdc_mode->gdsp_offs << EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET) &
+ | ((20 << EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET) &
EPDC_TCE_TIMING2_GDSP_OFFSET_MASK);
__raw_writel(reg_val, EPDC_TCE_TIMING2);
/* EPDC_TCE_TIMING3 */
reg_val =
- ((epdc_mode->gdoe_offs << EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET) &
+ ((0 << EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET) &
EPDC_TCE_TIMING3_GDOE_OFFSET_MASK)
- | ((epdc_mode->gdclk_offs << EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET) &
+ | ((1 << EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET) &
EPDC_TCE_TIMING3_GDCLK_OFFSET_MASK);
__raw_writel(reg_val, EPDC_TCE_TIMING3);
@@ -695,14 +769,10 @@ void epdc_init_settings(struct mxc_epdc_fb_data *fb_data)
* SDDO_INVERT = DISABLED
* PIXELS_PER_CE = display horizontal resolution
*/
- num_ce = epdc_mode->num_ce;
- if (num_ce == 0)
- num_ce = 1;
reg_val = EPDC_TCE_SDCFG_SDCLK_HOLD | EPDC_TCE_SDCFG_SDSHR
- | ((num_ce << EPDC_TCE_SDCFG_NUM_CE_OFFSET) &
- EPDC_TCE_SDCFG_NUM_CE_MASK)
+ | ((1 << EPDC_TCE_SDCFG_NUM_CE_OFFSET) & EPDC_TCE_SDCFG_NUM_CE_MASK)
| EPDC_TCE_SDCFG_SDDO_REFORMAT_FLIP_PIXELS
- | ((epdc_mode->vmode->xres/num_ce << EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET) &
+ | ((pentry->x_res << EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET) &
EPDC_TCE_SDCFG_PIXELS_PER_CE_MASK);
__raw_writel(reg_val, EPDC_TCE_SDCFG);
@@ -760,10 +830,6 @@ static void epdc_powerup(struct mxc_epdc_fb_data *fb_data)
dev_dbg(fb_data->dev, "EPDC Powerup\n");
- /* Enable pins used by EPDC */
- if (fb_data->pdata->enable_pins)
- fb_data->pdata->enable_pins();
-
/* Enable clocks to EPDC */
clk_enable(fb_data->epdc_clk_axi);
clk_enable(fb_data->epdc_clk_pix);
@@ -803,10 +869,6 @@ static void epdc_powerdown(struct mxc_epdc_fb_data *fb_data)
clk_disable(fb_data->epdc_clk_pix);
clk_disable(fb_data->epdc_clk_axi);
- /* Disable pins used by EPDC (to prevent leakage current) */
- if (fb_data->pdata->disable_pins)
- fb_data->pdata->disable_pins();
-
fb_data->power_state = POWER_STATE_OFF;
fb_data->powering_down = false;
@@ -1013,7 +1075,7 @@ static int mxc_epdc_fb_set_par(struct fb_info *info)
break;
}
}
- pxp_conf->s0_param.width = screeninfo->xres_virtual;
+ pxp_conf->s0_param.width = screeninfo->xres;
pxp_conf->s0_param.height = screeninfo->yres;
pxp_conf->s0_param.color_key = -1;
pxp_conf->s0_param.color_key_enable = false;
@@ -1032,24 +1094,19 @@ static int mxc_epdc_fb_set_par(struct fb_info *info)
* an initialization request.
*/
if (!fb_data->hw_ready) {
- for (i = 0; i < fb_data->pdata->num_modes; i++) {
- struct fb_videomode *vmode =
- fb_data->pdata->epdc_mode[i].vmode;
- /* Check resolution for a match
- with supported panel types */
- if ((screeninfo->xres != vmode->xres) ||
- (screeninfo->yres != vmode->yres))
+ for (i = 0; i < NUM_PANELS; i++) {
+ /* Check resolution for a match with supported panel types */
+ if ((screeninfo->xres != panel_modes[i].xres) ||
+ (screeninfo->yres != panel_modes[i].yres))
continue;
- fb_data->cur_mode = &fb_data->pdata->epdc_mode[i];
-
/* Found a match - Grab timing params */
- screeninfo->left_margin = vmode->left_margin;
- screeninfo->right_margin = vmode->right_margin;
- screeninfo->upper_margin = vmode->upper_margin;
- screeninfo->lower_margin = vmode->lower_margin;
- screeninfo->hsync_len = vmode->hsync_len;
- screeninfo->vsync_len = vmode->vsync_len;
+ screeninfo->left_margin = panel_modes[i].left_margin;
+ screeninfo->right_margin = panel_modes[i].right_margin;
+ screeninfo->upper_margin = panel_modes[i].upper_margin;
+ screeninfo->lower_margin = panel_modes[i].lower_margin;
+ screeninfo->hsync_len = panel_modes[i].hsync_len;
+ screeninfo->vsync_len = panel_modes[i].vsync_len;
/* Initialize EPDC settings and init panel */
ret =
@@ -1183,13 +1240,15 @@ static int mxc_epdc_fb_check_var(struct fb_var_screeninfo *var,
switch (var->rotate) {
case FB_ROTATE_UR:
case FB_ROTATE_UD:
- var->xres = fb_data->native_width;
+ var->xres = var->xres_virtual = fb_data->native_width;
var->yres = fb_data->native_height;
+ var->yres_virtual = var->yres * 2;
break;
case FB_ROTATE_CW:
case FB_ROTATE_CCW:
- var->xres = fb_data->native_height;
+ var->xres = var->xres_virtual = fb_data->native_height;
var->yres = fb_data->native_width;
+ var->yres_virtual = var->yres * 2;
break;
default:
/* Invalid rotation value */
@@ -1198,9 +1257,6 @@ static int mxc_epdc_fb_check_var(struct fb_var_screeninfo *var,
return -EINVAL;
}
- var->xres_virtual = ALIGN(var->xres, 32);
- var->yres_virtual = ALIGN(var->yres, 128) * g_num_screens;
-
var->height = -1;
var->width = -1;
@@ -1282,7 +1338,7 @@ static int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
u32 offset_from_8, bytes_per_pixel;
u32 post_rotation_xcoord, post_rotation_ycoord, width_pxp_blocks;
u32 pxp_input_offs, pxp_output_offs, pxp_output_shift;
- int x_start_offs = 0;
+ int adj_left, adj_top;
u32 hist_stat = 0;
int temp_index;
bool wait_for_power = false;
@@ -1384,7 +1440,7 @@ static int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
src_width = upd_data->alt_buffer_data.width;
src_upd_region = &upd_data->alt_buffer_data.alt_update_region;
} else {
- src_width = fb_data->info.var.xres_virtual;
+ src_width = fb_data->info.var.xres;
src_upd_region = screen_upd_region;
}
@@ -1411,21 +1467,11 @@ static int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
pxp_upd_region.left = 0;
}
- /*
- * We want PxP processing region to start at the first pixel
- * that we have to process in each row, but PxP alignment
- * restricts the input mem address to be 32-bit aligned
- *
- * We work around this by using x_start_offs to offset
- * to offset from our starting pixel location to the
- * first pixel that is in the relevant update region
- * for each row.
- */
- x_start_offs = pxp_upd_region.left & 0x7;
-
/* Update region to meet 8x8 pixel requirement */
- pxp_upd_region.width = ALIGN(src_upd_region->width, 8);
- pxp_upd_region.height = ALIGN(src_upd_region->height, 8);
+ adj_left = pxp_upd_region.left & 0x7;
+ adj_top = pxp_upd_region.top & 0x7;
+ pxp_upd_region.width = ALIGN(src_upd_region->width + adj_left, 8);
+ pxp_upd_region.height = ALIGN(src_upd_region->height + adj_top, 8);
pxp_upd_region.top &= ~0x7;
pxp_upd_region.left &= ~0x7;
@@ -1484,8 +1530,7 @@ static int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
mutex_lock(&fb_data->pxp_mutex);
/* This is a blocking call, so upon return PxP tx should be done */
- ret = pxp_process_update(fb_data, &pxp_upd_region,
- x_start_offs);
+ ret = pxp_process_update(fb_data, &pxp_upd_region);
if (ret) {
dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
mutex_unlock(&fb_data->pxp_mutex);
@@ -1644,97 +1689,52 @@ static int mxc_epdc_fb_wait_update_complete(u32 update_marker,
return 0;
}
-static int mxc_epdc_fb_set_pwrdown_delay(u32 pwrdown_delay,
- struct fb_info *info)
-{
- struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
-
- fb_data->pwrdown_delay = pwrdown_delay;
-
- return 0;
-}
-
static int mxc_epdc_fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
void __user *argp = (void __user *)arg;
+ struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ struct mxcfb_waveform_modes modes;
+ int temperature;
+ u32 auto_mode = 0;
+ struct mxcfb_update_data upd_data;
+ u32 update_marker = 0;
int ret = -EINVAL;
switch (cmd) {
case MXCFB_SET_WAVEFORM_MODES:
- {
- struct mxcfb_waveform_modes modes;
- struct mxc_epdc_fb_data *fb_data =
- (struct mxc_epdc_fb_data *)info;
- if (!copy_from_user(&modes, argp, sizeof(modes))) {
- memcpy(&fb_data->wv_modes, &modes,
- sizeof(modes));
- ret = 0;
- }
- break;
+ if (!copy_from_user(&modes, argp, sizeof(modes))) {
+ memcpy(&fb_data->wv_modes, &modes, sizeof(modes));
+ ret = 0;
}
+ break;
case MXCFB_SET_TEMPERATURE:
- {
- int temperature;
- if (!get_user(temperature, (int32_t __user *) arg))
- ret =
- mxc_epdc_fb_set_temperature(temperature,
- info);
- break;
- }
+ if (!get_user(temperature, (int32_t __user *) arg))
+ ret =
+ mxc_epdc_fb_set_temperature(temperature,
+ info);
+ break;
case MXCFB_SET_AUTO_UPDATE_MODE:
- {
- u32 auto_mode = 0;
- if (!get_user(auto_mode, (__u32 __user *) arg))
- ret =
- mxc_epdc_fb_set_auto_update(auto_mode,
- info);
- break;
- }
+ if (!get_user(auto_mode, (__u32 __user *) arg))
+ ret =
+ mxc_epdc_fb_set_auto_update(auto_mode, info);
+ break;
case MXCFB_SEND_UPDATE:
- {
- struct mxcfb_update_data upd_data;
- if (!copy_from_user(&upd_data, argp,
- sizeof(upd_data))) {
- ret = mxc_epdc_fb_send_update(&upd_data, info);
- if (ret == 0 && copy_to_user(argp, &upd_data,
- sizeof(upd_data)))
- ret = -EFAULT;
- } else {
+ if (!copy_from_user(&upd_data, argp, sizeof(upd_data))) {
+ ret = mxc_epdc_fb_send_update(&upd_data, info);
+ if (ret == 0 && copy_to_user(argp, &upd_data, sizeof(upd_data)))
ret = -EFAULT;
- }
-
- break;
- }
- case MXCFB_WAIT_FOR_UPDATE_COMPLETE:
- {
- u32 update_marker = 0;
- if (!get_user(update_marker, (__u32 __user *) arg))
- ret =
- mxc_epdc_fb_wait_update_complete(update_marker,
- info);
- break;
- }
-
- case MXCFB_SET_PWRDOWN_DELAY:
- {
- int delay = 0;
- if (!get_user(delay, (__u32 __user *) arg))
- ret =
- mxc_epdc_fb_set_pwrdown_delay(delay, info);
- break;
+ } else {
+ ret = -EFAULT;
}
- case MXCFB_GET_PWRDOWN_DELAY:
- {
- struct mxc_epdc_fb_data *fb_data =
- (struct mxc_epdc_fb_data *)info;
- if (put_user(fb_data->pwrdown_delay,
- (int __user *)argp))
- ret = -EFAULT;
- ret = 0;
- break;
- }
+ break;
+ case MXCFB_WAIT_FOR_UPDATE_COMPLETE:
+ if (!get_user(update_marker, (__u32 __user *) arg))
+ ret =
+ mxc_epdc_fb_wait_update_complete(update_marker,
+ info);
+ break;
default:
break;
}
@@ -1833,6 +1833,10 @@ static int mxc_epdc_fb_blank(int blank, struct fb_info *info)
case FB_BLANK_NORMAL:
mxc_epdc_fb_disable(fb_data);
break;
+ case FB_BLANK_UNBLANK:
+ epdc_powerup(fb_data);
+ mxc_epdc_fb_set_par(info);
+ break;
}
return 0;
}
@@ -1841,6 +1845,8 @@ static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ struct mxcfb_update_data update;
+ int ret = 0;
u_int y_bottom;
dev_dbg(info->device, "%s: var->xoffset %d, info->var.xoffset %d\n",
@@ -1867,6 +1873,25 @@ static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var,
fb_data->fb_offset = (var->yoffset * var->xres_virtual + var->xoffset)
* (var->bits_per_pixel) / 8;
+ /* Update to new view of FB */
+ update.update_region.left = 0;
+ update.update_region.width = fb_data->info.var.xres;
+ update.update_region.top = 0;
+ update.update_region.height = fb_data->info.var.yres;
+ update.waveform_mode = WAVEFORM_MODE_AUTO;
+ update.update_mode = UPDATE_MODE_FULL;
+ update.update_marker = PAN_UPDATE_MARKER;
+ update.temp = TEMP_USE_AMBIENT;
+ update.use_alt_buffer = false;
+
+ mxc_epdc_fb_send_update(&update, &fb_data->info);
+
+ /* Block on initial update */
+ ret = mxc_epdc_fb_wait_update_complete(update.update_marker, info);
+ if (ret < 0)
+ dev_err(fb_data->dev,
+ "Wait for update complete failed. Error = 0x%x", ret);
+
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
@@ -1875,7 +1900,7 @@ static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var,
else
info->var.vmode &= ~FB_VMODE_YWRAP;
- return 0;
+ return ret;
}
static struct fb_ops mxc_epdc_fb_ops = {
@@ -1893,15 +1918,14 @@ static struct fb_ops mxc_epdc_fb_ops = {
};
static struct fb_deferred_io mxc_epdc_fb_defio = {
- .delay = HZ,
+ .delay = HZ / 2,
.deferred_io = mxc_epdc_fb_deferred_io,
};
static void epdc_done_work_func(struct work_struct *work)
{
struct mxc_epdc_fb_data *fb_data =
- container_of(work, struct mxc_epdc_fb_data,
- epdc_done_work.work);
+ container_of(work, struct mxc_epdc_fb_data, epdc_done_work);
epdc_powerdown(fb_data);
}
@@ -2015,17 +2039,16 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
(fb_data->cur_update == NULL) &&
!epdc_any_luts_active()) {
- if (fb_data->pwrdown_delay != FB_POWERDOWN_DISABLE) {
- /*
- * Set variable to prevent overlapping
- * enable/disable requests
- */
- fb_data->powering_down = true;
-
- /* Schedule task to disable EPDC HW until next update */
- schedule_delayed_work(&fb_data->epdc_done_work,
- msecs_to_jiffies(fb_data->pwrdown_delay));
- }
+#ifndef NO_POWERDOWN
+ /*
+ * Set variable to prevent overlapping
+ * enable/disable requests
+ */
+ fb_data->powering_down = true;
+
+ /* Schedule task to disable EPDC HW until next update */
+ schedule_work(&fb_data->epdc_done_work);
+#endif
if (fb_data->waiting_for_idle)
complete(&fb_data->updates_done);
@@ -2241,25 +2264,15 @@ static void draw_mode0(struct mxc_epdc_fb_data *fb_data)
static int mxc_epdc_fb_init_hw(struct fb_info *info)
{
struct mxc_epdc_fb_data *fb_data = (struct mxc_epdc_fb_data *)info;
+ u32 wv_buf_size;
const struct firmware *fw;
- char *fw_str = "imx/epdc";
struct mxcfb_update_data update;
struct mxcfb_waveform_data_file *wv_file;
int wv_data_offs;
int ret;
int i;
- /*
- * Create fw search string based on ID string in selected videomode.
- * Format is "imx/epdc_[panel string].fw"
- */
- if (fb_data->cur_mode) {
- strcat(fw_str, "_");
- strcat(fw_str, fb_data->cur_mode->vmode->name);
- strcat(fw_str, ".fw");
- }
-
- ret = request_firmware(&fw, fw_str, fb_data->dev);
+ ret = request_firmware(&fw, "imx/epdc.fw", fb_data->dev);
if (ret) {
printk(KERN_ERR "Failed to load image imx/epdc.ihex err %d\n",
ret);
@@ -2280,20 +2293,20 @@ static int mxc_epdc_fb_init_hw(struct fb_info *info)
/* Get offset and size for waveform data */
wv_data_offs = sizeof(wv_file->wdh) + fb_data->trt_entries + 1;
- fb_data->waveform_buffer_size = fw->size - wv_data_offs;
+ wv_buf_size = fw->size - wv_data_offs;
/* Allocate memory for waveform data */
- fb_data->waveform_buffer_virt = dma_alloc_coherent(fb_data->dev,
- fb_data->waveform_buffer_size,
- &fb_data->waveform_buffer_phys,
- GFP_DMA);
+ fb_data->waveform_buffer_virt = dma_alloc_coherent(fb_data->dev, wv_buf_size,
+ &fb_data->waveform_buffer_phys,
+ GFP_DMA);
if (fb_data->waveform_buffer_virt == NULL) {
dev_err(fb_data->dev, "Can't allocate mem for waveform!\n");
ret = -ENOMEM;
}
- memcpy(fb_data->waveform_buffer_virt, (u8 *)(fw->data) + wv_data_offs,
- fb_data->waveform_buffer_size);
+ memcpy(fb_data->waveform_buffer_virt, (u8 *)(fw->data) + wv_data_offs, wv_buf_size);
+ check_waveform((u32 *)(fw->data + wv_data_offs),
+ fb_data->waveform_buffer_virt, wv_buf_size / 4);
release_firmware(fw);
@@ -2302,7 +2315,7 @@ static int mxc_epdc_fb_init_hw(struct fb_info *info)
/* Enable pix clk for EPDC */
clk_enable(fb_data->epdc_clk_pix);
- clk_set_rate(fb_data->epdc_clk_pix, fb_data->cur_mode->vmode->pixclock);
+ clk_set_rate(fb_data->epdc_clk_pix, 17700000);
epdc_init_sequence(fb_data);
@@ -2373,23 +2386,14 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
struct mxc_epdc_fb_data *fb_data;
struct resource *res;
struct fb_info *info;
- char *options, *opt;
- char *panel_str = NULL;
- char name[] = "mxcepdcfb";
- struct fb_videomode *vmode;
- int xres_virt, yres_virt, buf_size;
- struct fb_var_screeninfo *var_info;
- struct fb_fix_screeninfo *fix_info;
+ struct mxc_epdc_platform_fb_data *pdata;
+ struct mxc_epdc_platform_fb_entry *pentry;
struct pxp_config_data *pxp_conf;
struct pxp_proc_data *proc_data;
struct scatterlist *sg;
struct update_data_list *upd_list;
struct update_data_list *plist, *temp_list;
int i;
- unsigned long x_mem_size = 0;
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
- struct mxcfb_update_data update;
-#endif
fb_data = (struct mxc_epdc_fb_data *)framebuffer_alloc(
sizeof(struct mxc_epdc_fb_data), &pdev->dev);
@@ -2398,54 +2402,10 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
goto out;
}
- /* Get platform data and check validity */
- fb_data->pdata = pdev->dev.platform_data;
- if ((fb_data->pdata == NULL) || (fb_data->pdata->num_modes < 1)
- || (fb_data->pdata->epdc_mode == NULL)
- || (fb_data->pdata->epdc_mode->vmode == NULL)) {
- ret = -EINVAL;
- goto out_fbdata;
- }
-
- if (fb_get_options(name, &options)) {
- ret = -ENODEV;
- goto out_fbdata;
- }
-
- if (options)
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
-
- if (!strncmp(opt, "bpp=", 4))
- fb_data->default_bpp =
- simple_strtoul(opt + 4, NULL, 0);
- else if (!strncmp(opt, "x_mem=", 6))
- x_mem_size =
- simple_strtoul(opt + 6, NULL, 0);
- else
- panel_str = opt;
- }
-
fb_data->dev = &pdev->dev;
-
- if (!fb_data->default_bpp)
- fb_data->default_bpp = 16;
-
- /* Set default (first defined mode) before searching for a match */
- fb_data->cur_mode = &fb_data->pdata->epdc_mode[0];
-
- if (panel_str)
- for (i = 0; i < fb_data->pdata->num_modes; i++)
- if (!strcmp(fb_data->pdata->epdc_mode[i].vmode->name,
- panel_str)) {
- fb_data->cur_mode =
- &fb_data->pdata->epdc_mode[i];
- break;
- }
-
- vmode = fb_data->cur_mode->vmode;
-
+ /* We want to use hard-coded structure defined in this file */
+ pentry = &ed060sc4_fb_entry;
+ fb_data->cur = pentry;
platform_set_drvdata(pdev, fb_data);
info = &fb_data->info;
@@ -2454,24 +2414,12 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
if (ret)
goto out_fbdata;
- dev_dbg(&pdev->dev, "resolution %dx%d, bpp %d\n",
- fb_data->cur_mode->vmode->xres,
- fb_data->cur_mode->vmode->yres, fb_data->default_bpp);
-
- /*
- * GPU alignment restrictions dictate framebuffer parameters:
- * - 32-byte alignment for buffer width
- * - 128-byte alignment for buffer height
- * => 4K buffer alignment for buffer start
- */
- xres_virt = ALIGN(vmode->xres, 32);
- yres_virt = ALIGN(vmode->yres, 128);
- buf_size = xres_virt * yres_virt * fb_data->default_bpp/8;
+ dev_dbg(&pdev->dev, "resolution %dx%d, bpp %d\n", pentry->x_res,
+ pentry->y_res, pentry->bpp);
- if (x_mem_size > 0)
- g_num_screens = NUM_SCREENS_X;
+ fb_data->mem_size = pentry->x_res * pentry->y_res * pentry->bpp/8;
- fb_data->map_size = PAGE_ALIGN(buf_size) * g_num_screens;
+ fb_data->map_size = PAGE_ALIGN(fb_data->mem_size) * NUM_SCREENS;
dev_dbg(&pdev->dev, "memory to allocate: %d\n", fb_data->map_size);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2499,69 +2447,49 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "allocated at %p:0x%x\n", info->screen_base,
fb_data->phys_start);
- var_info = &info->var;
-
- var_info->activate = FB_ACTIVATE_TEST;
- var_info->bits_per_pixel = fb_data->default_bpp;
- var_info->xres = vmode->xres;
- var_info->yres = vmode->yres;
- var_info->xres_virtual = xres_virt;
- /* Additional screens allow for panning and buffer flipping */
- var_info->yres_virtual = yres_virt * g_num_screens;
-
- var_info->pixclock = vmode->pixclock;
- var_info->left_margin = vmode->left_margin;
- var_info->right_margin = vmode->right_margin;
- var_info->upper_margin = vmode->upper_margin;
- var_info->lower_margin = vmode->lower_margin;
- var_info->hsync_len = vmode->hsync_len;
- var_info->vsync_len = vmode->vsync_len;
- var_info->vmode = FB_VMODE_NONINTERLACED;
-
- switch (fb_data->default_bpp) {
+ mxc_epdc_fb_default.bits_per_pixel = pentry->bpp;
+ mxc_epdc_fb_default.xres = pentry->x_res;
+ mxc_epdc_fb_default.yres = pentry->y_res;
+ mxc_epdc_fb_default.xres_virtual = pentry->x_res;
+ mxc_epdc_fb_default.yres_virtual = pentry->y_res * 2; /* FB doubled in virtual space */
+
+ mxc_epdc_fb_fix.smem_start = fb_data->phys_start;
+ mxc_epdc_fb_fix.smem_len = mxc_epdc_fb_default.yres_virtual
+ * pentry->x_res * 2 * pentry->bpp / 8;
+ mxc_epdc_fb_fix.ypanstep = 0;
+
+ switch (pentry->bpp) {
case 32:
case 24:
- var_info->red.offset = 16;
- var_info->red.length = 8;
- var_info->green.offset = 8;
- var_info->green.length = 8;
- var_info->blue.offset = 0;
- var_info->blue.length = 8;
+ mxc_epdc_fb_default.red.offset = 16;
+ mxc_epdc_fb_default.red.length = 8;
+ mxc_epdc_fb_default.green.offset = 8;
+ mxc_epdc_fb_default.green.length = 8;
+ mxc_epdc_fb_default.blue.offset = 0;
+ mxc_epdc_fb_default.blue.length = 8;
break;
case 16:
- var_info->red.offset = 11;
- var_info->red.length = 5;
- var_info->green.offset = 5;
- var_info->green.length = 6;
- var_info->blue.offset = 0;
- var_info->blue.length = 5;
+ mxc_epdc_fb_default.red.offset = 11;
+ mxc_epdc_fb_default.red.length = 5;
+ mxc_epdc_fb_default.green.offset = 5;
+ mxc_epdc_fb_default.green.length = 6;
+ mxc_epdc_fb_default.blue.offset = 0;
+ mxc_epdc_fb_default.blue.length = 5;
break;
default:
- dev_err(&pdev->dev, "unsupported bitwidth %d\n",
- fb_data->default_bpp);
+ dev_err(&pdev->dev, "unsupported bitwidth %d\n", pentry->bpp);
ret = -EINVAL;
goto out_dma_fb;
}
- fix_info = &info->fix;
-
- strcpy(fix_info->id, "mxc_epdc_fb");
- fix_info->type = FB_TYPE_PACKED_PIXELS;
- fix_info->visual = FB_VISUAL_TRUECOLOR;
- fix_info->xpanstep = 0;
- fix_info->ypanstep = 0;
- fix_info->ywrapstep = 0;
- fix_info->accel = FB_ACCEL_NONE;
- fix_info->smem_start = fb_data->phys_start;
- fix_info->smem_len = fb_data->map_size;
- fix_info->ypanstep = 0;
-
- fb_data->native_width = vmode->xres;
- fb_data->native_height = vmode->yres;
+ fb_data->native_width = pentry->x_res;
+ fb_data->native_height = pentry->y_res;
info->fbops = &mxc_epdc_fb_ops;
+ info->var = mxc_epdc_fb_default;
+ info->fix = mxc_epdc_fb_fix;
info->var.activate = FB_ACTIVATE_NOW;
info->pseudo_palette = fb_data->pseudo_palette;
info->screen_size = info->fix.smem_len;
@@ -2633,7 +2561,7 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
upd_list->size, upd_list->phys_addr);
}
- fb_data->working_buffer_size = vmode->yres * vmode->xres * 2;
+ fb_data->working_buffer_size = pentry->y_res * pentry->x_res * 2;
/* Allocate memory for EPDC working buffer */
fb_data->working_buffer_virt =
dma_alloc_coherent(&pdev->dev, fb_data->working_buffer_size,
@@ -2644,13 +2572,11 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
goto out_upd_buffers;
}
- /* Initialize EPDC pins */
- if (fb_data->pdata->get_pins)
- fb_data->pdata->get_pins();
-
fb_data->epdc_clk_axi = clk_get(fb_data->dev, "epdc_axi");
fb_data->epdc_clk_pix = clk_get(fb_data->dev, "epdc_pix");
+ clk_set_rate(fb_data->epdc_clk_axi, 200000000);
+
fb_data->in_init = false;
fb_data->hw_ready = false;
@@ -2691,11 +2617,10 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
fb_data->epdc_irq, ret);
- ret = -ENODEV;
goto out_dma_work_buf;
}
- INIT_DELAYED_WORK(&fb_data->epdc_done_work, epdc_done_work_func);
+ INIT_WORK(&fb_data->epdc_done_work, epdc_done_work_func);
info->fbdefio = &mxc_epdc_fb_defio;
#ifdef CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE
@@ -2706,17 +2631,15 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
fb_data->display_regulator = regulator_get(NULL, "DISPLAY");
if (IS_ERR(fb_data->display_regulator)) {
dev_err(&pdev->dev, "Unable to get display PMIC regulator."
- "err = 0x%x\n", (int)fb_data->display_regulator);
- ret = -ENODEV;
- goto out_irq;
+ "err = 0x%x\n", fb_data->display_regulator);
+ goto out_dma_work_buf;
}
fb_data->vcom_regulator = regulator_get(NULL, "VCOM");
if (IS_ERR(fb_data->vcom_regulator)) {
regulator_put(fb_data->display_regulator);
dev_err(&pdev->dev, "Unable to get VCOM regulator."
- "err = 0x%x\n", (int)fb_data->vcom_regulator);
- ret = -ENODEV;
- goto out_irq;
+ "err = 0x%x\n", fb_data->vcom_regulator);
+ goto out_dma_work_buf;
}
if (device_create_file(info->dev, &fb_attrs[0]))
@@ -2763,7 +2686,7 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
* Parameters should match FB format/width/height
*/
pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_RGB565;
- pxp_conf->s0_param.width = fb_data->info.var.xres_virtual;
+ pxp_conf->s0_param.width = fb_data->info.var.xres;
pxp_conf->s0_param.height = fb_data->info.var.yres;
pxp_conf->s0_param.color_key = -1;
pxp_conf->s0_param.color_key_enable = false;
@@ -2772,7 +2695,7 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
* Initialize OL0 channel parameters
* No overlay will be used for PxP operation
*/
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 8; i++) {
pxp_conf->ol_param[i].combine_enable = false;
pxp_conf->ol_param[i].width = 0;
pxp_conf->ol_param[i].height = 0;
@@ -2816,54 +2739,33 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
fb_data->blank = FB_BLANK_UNBLANK;
fb_data->power_state = POWER_STATE_OFF;
fb_data->powering_down = false;
- fb_data->pwrdown_delay = 0;
/* Register FB */
ret = register_framebuffer(info);
if (ret) {
dev_err(&pdev->dev,
"register_framebuffer failed with error %d\n", ret);
- goto out_dmaengine;
+ goto out_irq;
}
#ifdef DEFAULT_PANEL_HW_INIT
ret = mxc_epdc_fb_init_hw((struct fb_info *)fb_data);
if (ret) {
- dev_err(&pdev->dev, "Failed to initialize HW!\n");
+ dev_err(&pdev->dev, "Failed to read firmware!\n");
+ goto out_dmaengine;
}
#endif
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
- /* If FB console included, update display to show logo */
- update.update_region.left = 0;
- update.update_region.width = info->var.xres;
- update.update_region.top = 0;
- update.update_region.height = info->var.yres;
- update.update_mode = UPDATE_MODE_PARTIAL;
- update.waveform_mode = WAVEFORM_MODE_AUTO;
- update.update_marker = INIT_UPDATE_MARKER;
- update.temp = TEMP_USE_AMBIENT;
- update.use_alt_buffer = false;
-
- mxc_epdc_fb_send_update(&update, info);
-
- ret = mxc_epdc_fb_wait_update_complete(update.update_marker, info);
- if (ret < 0)
- dev_err(fb_data->dev,
- "Wait for update complete failed. Error = 0x%x", ret);
-#endif
-
goto out;
out_dmaengine:
dmaengine_put();
+ unregister_framebuffer(&fb_data->info);
out_irq:
free_irq(fb_data->epdc_irq, fb_data);
out_dma_work_buf:
- dma_free_writecombine(&pdev->dev, fb_data->working_buffer_size,
+ dma_free_writecombine(&pdev->dev, pentry->y_res * pentry->x_res / 2,
fb_data->working_buffer_virt, fb_data->working_buffer_phys);
- if (fb_data->pdata->put_pins)
- fb_data->pdata->put_pins();
out_upd_buffers:
list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list->list, list) {
list_del(&plist->list);
@@ -2898,29 +2800,19 @@ static int mxc_epdc_fb_remove(struct platform_device *pdev)
unregister_framebuffer(&fb_data->info);
free_irq(fb_data->epdc_irq, fb_data);
- dma_free_writecombine(&pdev->dev, fb_data->working_buffer_size,
- fb_data->working_buffer_virt,
- fb_data->working_buffer_phys);
- if (fb_data->waveform_buffer_virt != NULL)
- dma_free_writecombine(&pdev->dev, fb_data->waveform_buffer_size,
- fb_data->waveform_buffer_virt,
- fb_data->waveform_buffer_phys);
+ dma_free_writecombine(&pdev->dev, fb_data->working_buffer_size, fb_data->working_buffer_virt,
+ fb_data->working_buffer_phys);
+ dma_free_writecombine(&pdev->dev, fb_data->waveform_buffer_size, fb_data->waveform_buffer_virt,
+ fb_data->waveform_buffer_phys);
list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list->list, list) {
list_del(&plist->list);
dma_free_writecombine(&pdev->dev, plist->size, plist->virt_addr,
plist->phys_addr);
kfree(plist);
}
-#ifdef CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE
- fb_deferred_io_cleanup(&fb_data->info);
-#endif
-
dma_free_writecombine(&pdev->dev, fb_data->map_size, fb_data->info.screen_base,
fb_data->phys_start);
- if (fb_data->pdata->put_pins)
- fb_data->pdata->put_pins();
-
/* Release PxP-related resources */
if (fb_data->pxp_chan != NULL)
dma_release_channel(&fb_data->pxp_chan->dma_chan);
@@ -3011,6 +2903,8 @@ static int pxp_chan_init(struct mxc_epdc_fb_data *fb_data)
fb_data->pxp_chan = to_pxp_channel(chan);
+ dev_dbg(fb_data->dev, "dma_chan = 0x%x\n", fb_data->pxp_chan->dma_chan);
+
fb_data->pxp_chan->client = fb_data;
init_completion(&fb_data->pxp_tx_cmpl);
@@ -3024,8 +2918,7 @@ static int pxp_chan_init(struct mxc_epdc_fb_data *fb_data)
* Note: This is a blocking call, so upon return the PxP tx should be complete.
*/
static int pxp_process_update(struct mxc_epdc_fb_data *fb_data,
- struct mxcfb_rect *update_region,
- int x_start_offs)
+ struct mxcfb_rect *update_region)
{
dma_cookie_t cookie;
struct scatterlist *sg = fb_data->sg;
@@ -3035,7 +2928,6 @@ static int pxp_process_update(struct mxc_epdc_fb_data *fb_data,
struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
struct pxp_proc_data *proc_data = &fb_data->pxp_conf.proc_data;
int i, ret;
- int length;
dev_dbg(fb_data->dev, "Starting PxP Send Buffer\n");
@@ -3086,7 +2978,7 @@ static int pxp_process_update(struct mxc_epdc_fb_data *fb_data,
* probe() and should not need to be changed.
*/
proc_data->srect.top = update_region->top;
- proc_data->srect.left = update_region->left + x_start_offs;
+ proc_data->srect.left = update_region->left;
proc_data->srect.width = update_region->width;
proc_data->srect.height = update_region->height;
@@ -3108,7 +3000,7 @@ static int pxp_process_update(struct mxc_epdc_fb_data *fb_data,
pxp_conf->out_param.height = update_region->height;
desc = to_tx_desc(txd);
- length = desc->len;
+ int length = desc->len;
for (i = 0; i < length; i++) {
if (i == 0) {/* S0 */
memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index cc48e62637ca..be907a956365 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -43,7 +43,6 @@
#include <linux/io.h>
#include <linux/ipu.h>
#include <linux/mxcfb.h>
-#include <linux/earlysuspend.h>
#include <asm/mach-types.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
@@ -101,10 +100,9 @@ enum {
BOTH_OFF
};
-#define FB_DEVICE_NUM 3
static bool g_dp_in_use;
LIST_HEAD(fb_alloc_list);
-static struct fb_info *mxcfb_info[FB_DEVICE_NUM];
+static struct fb_info *mxcfb_info[3];
static uint32_t bpp_to_pixfmt(struct fb_info *fbi)
{
@@ -172,11 +170,12 @@ static int _setup_disp_channel1(struct fb_info *fbi)
for (i = 0; i < num_registered_fb; i++) {
mxc_fbi_tmp = (struct mxcfb_info *)
- (registered_fb[i]->par);
+ (registered_fb[i]->par);
if (mxc_fbi_tmp->ipu_ch == MEM_BG_SYNC) {
- fbi->var.vmode = registered_fb[i]->var.vmode;
+ fbi->var.vmode =
+ registered_fb[i]->var.vmode;
mxc_fbi->ipu_di_pix_fmt =
- mxc_fbi_tmp->ipu_di_pix_fmt;
+ mxc_fbi_tmp->ipu_di_pix_fmt;
break;
}
}
@@ -233,7 +232,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
}
mxc_fbi->cur_ipu_buf = 1;
- sema_init(&mxc_fbi->flip_sem, 0);
+ sema_init(&mxc_fbi->flip_sem, 1);
if (mxc_fbi->alpha_chan_en) {
mxc_fbi->cur_ipu_alpha_buf = 1;
sema_init(&mxc_fbi->alpha_flip_sem, 1);
@@ -247,7 +246,8 @@ static int _setup_disp_channel2(struct fb_info *fbi)
IPU_ROTATE_NONE,
fbi->fix.smem_start +
(fbi->fix.line_length * fbi->var.yres),
- fbi->fix.smem_start, 0, 0);
+ fbi->fix.smem_start,
+ 0, 0);
if (retval) {
dev_err(fbi->device,
"ipu_init_channel_buffer error %d\n", retval);
@@ -317,36 +317,30 @@ static int mxcfb_set_par(struct fb_info *fbi)
mxc_fbi->alpha_phy_addr1);
mxc_fbi->alpha_virt_addr0 =
- dma_alloc_coherent(fbi->device,
- alpha_mem_len,
- &mxc_fbi->alpha_phy_addr0,
- GFP_DMA | GFP_KERNEL);
+ dma_alloc_coherent(fbi->device,
+ alpha_mem_len,
+ &mxc_fbi->alpha_phy_addr0,
+ GFP_DMA | GFP_KERNEL);
mxc_fbi->alpha_virt_addr1 =
- dma_alloc_coherent(fbi->device,
- alpha_mem_len,
- &mxc_fbi->alpha_phy_addr1,
- GFP_DMA | GFP_KERNEL);
+ dma_alloc_coherent(fbi->device,
+ alpha_mem_len,
+ &mxc_fbi->alpha_phy_addr1,
+ GFP_DMA | GFP_KERNEL);
if (mxc_fbi->alpha_virt_addr0 == NULL ||
mxc_fbi->alpha_virt_addr1 == NULL) {
dev_err(fbi->device, "mxcfb: dma alloc for"
" alpha buffer failed.\n");
if (mxc_fbi->alpha_virt_addr0)
dma_free_coherent(fbi->device,
- mxc_fbi->
- alpha_mem_len,
- mxc_fbi->
- alpha_virt_addr0,
- mxc_fbi->
- alpha_phy_addr0);
+ mxc_fbi->alpha_mem_len,
+ mxc_fbi->alpha_virt_addr0,
+ mxc_fbi->alpha_phy_addr0);
if (mxc_fbi->alpha_virt_addr1)
dma_free_coherent(fbi->device,
- mxc_fbi->
- alpha_mem_len,
- mxc_fbi->
- alpha_virt_addr1,
- mxc_fbi->
- alpha_phy_addr1);
+ mxc_fbi->alpha_mem_len,
+ mxc_fbi->alpha_virt_addr1,
+ mxc_fbi->alpha_phy_addr1);
return -ENOMEM;
}
mxc_fbi->alpha_mem_len = alpha_mem_len;
@@ -374,7 +368,7 @@ static int mxcfb_set_par(struct fb_info *fbi)
else
out_pixel_fmt = IPU_PIX_FMT_RGB666;
}
- if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */
+ if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */
sig_cfg.odd_field_first = true;
if ((fbi->var.sync & FB_SYNC_EXT) || mxc_fbi->ipu_ext_clk)
sig_cfg.ext_clk = true;
@@ -482,7 +476,8 @@ static int swap_channels(struct fb_info *fbi)
ch_to = MEM_BG_SYNC;
for (i = 0; i < num_registered_fb; i++) {
- mxc_fbi_to = (struct mxcfb_info *)mxcfb_info[i]->par;
+ mxc_fbi_to =
+ (struct mxcfb_info *)mxcfb_info[i]->par;
if (mxc_fbi_to->ipu_ch == ch_to) {
fbi_to = mxcfb_info[i];
break;
@@ -547,14 +542,14 @@ static int swap_channels(struct fb_info *fbi)
}
if (ipu_request_irq(mxc_fbi_from->ipu_ch_irq, mxcfb_irq_handler, 0,
- MXCFB_NAME, fbi) != 0) {
+ MXCFB_NAME, fbi) != 0) {
dev_err(fbi->device, "Error registering irq %d\n",
mxc_fbi_from->ipu_ch_irq);
return -EBUSY;
}
ipu_disable_irq(mxc_fbi_from->ipu_ch_irq);
if (ipu_request_irq(mxc_fbi_to->ipu_ch_irq, mxcfb_irq_handler, 0,
- MXCFB_NAME, fbi_to) != 0) {
+ MXCFB_NAME, fbi_to) != 0) {
dev_err(fbi_to->device, "Error registering irq %d\n",
mxc_fbi_to->ipu_ch_irq);
return -EBUSY;
@@ -577,35 +572,6 @@ static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
u32 vtotal;
u32 htotal;
- /* fg should not bigger than bg */
- if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
- struct fb_info *fbi_tmp;
- struct mxcfb_info *mxc_fbi_tmp;
- int i, bg_xres, bg_yres;
- int16_t pos_x, pos_y;
-
- bg_xres = var->xres;
- bg_yres = var->yres;
-
- for (i = 0; i < num_registered_fb; i++) {
- fbi_tmp = registered_fb[i];
- mxc_fbi_tmp = (struct mxcfb_info *)
- (fbi_tmp->par);
- if (mxc_fbi_tmp->ipu_ch == MEM_BG_SYNC) {
- bg_xres = fbi_tmp->var.xres;
- bg_yres = fbi_tmp->var.yres;
- break;
- }
- }
-
- ipu_disp_get_window_pos(mxc_fbi->ipu_ch, &pos_x, &pos_y);
-
- if ((var->xres + pos_x) > bg_xres)
- var->xres = bg_xres - pos_x;
- if ((var->yres + pos_y) > bg_yres)
- var->yres = bg_yres - pos_y;
- }
-
if (var->xres_virtual < var->xres)
var->xres_virtual = var->xres;
if (var->yres_virtual < var->yres)
@@ -782,7 +748,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
}
if (ipu_disp_set_global_alpha(mxc_fbi->ipu_ch,
- (bool) ga.enable,
+ (bool)ga.enable,
ga.alpha)) {
retval = -EINVAL;
break;
@@ -809,7 +775,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
}
if (ipu_disp_set_global_alpha(mxc_fbi->ipu_ch,
- !(bool) la.enable, 0)) {
+ !(bool)la.enable, 0)) {
retval = -EINVAL;
break;
}
@@ -824,11 +790,8 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
for (i = 0; i < num_registered_fb; i++) {
char *idstr = registered_fb[i]->fix.id;
- if (strcmp(idstr, video_plane_idstr) ==
- 0) {
- ((struct mxcfb_info
- *)(registered_fb[i]->par))->
- alpha_chan_en = false;
+ if (strcmp(idstr, video_plane_idstr) == 0) {
+ ((struct mxcfb_info *)(registered_fb[i]->par))->alpha_chan_en = false;
break;
}
}
@@ -856,8 +819,8 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
uint32_t ipu_alp_ch_irq;
if (!(((mxc_fbi->ipu_ch == MEM_FG_SYNC) ||
- (mxc_fbi->ipu_ch == MEM_BG_SYNC)) &&
- (mxc_fbi->alpha_chan_en))) {
+ (mxc_fbi->ipu_ch == MEM_BG_SYNC)) &&
+ (mxc_fbi->alpha_chan_en))) {
dev_err(fbi->device,
"Should use background or overlay "
"framebuffer to set the alpha buffer "
@@ -884,10 +847,11 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
down(&mxc_fbi->alpha_flip_sem);
mxc_fbi->cur_ipu_alpha_buf =
- !mxc_fbi->cur_ipu_alpha_buf;
+ !mxc_fbi->cur_ipu_alpha_buf;
if (ipu_update_channel_buffer(mxc_fbi->ipu_ch,
IPU_ALPHA_IN_BUFFER,
- mxc_fbi->cur_ipu_alpha_buf,
+ mxc_fbi->
+ cur_ipu_alpha_buf,
base) == 0) {
ipu_select_buffer(mxc_fbi->ipu_ch,
IPU_ALPHA_IN_BUFFER,
@@ -925,9 +889,9 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
break;
}
retval = ipu_disp_set_gamma_correction(mxc_fbi->ipu_ch,
- gamma.enable,
- gamma.constk,
- gamma.slopek);
+ gamma.enable,
+ gamma.constk,
+ gamma.slopek);
break;
}
case MXCFB_WAIT_FOR_VSYNC:
@@ -937,8 +901,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
int i;
for (i = 0; i < num_registered_fb; i++) {
bg_mxcfbi =
- ((struct mxcfb_info
- *)(registered_fb[i]->par));
+ ((struct mxcfb_info *)(registered_fb[i]->par));
if (bg_mxcfbi->ipu_ch == MEM_BG_SYNC)
break;
@@ -958,10 +921,8 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
ipu_clear_irq(mxc_fbi->ipu_ch_irq);
mxc_fbi->wait4vsync = 1;
ipu_enable_irq(mxc_fbi->ipu_ch_irq);
- retval =
- wait_for_completion_interruptible_timeout(&mxc_fbi->
- vsync_complete,
- 1 * HZ);
+ retval = wait_for_completion_interruptible_timeout(
+ &mxc_fbi->vsync_complete, 1 * HZ);
if (retval == 0) {
dev_err(fbi->device,
"MXCFB_WAIT_FOR_VSYNC: timeout %d\n",
@@ -971,7 +932,6 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
} else if (retval > 0) {
retval = 0;
}
-
break;
}
case FBIO_ALLOC:
@@ -1052,8 +1012,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
for (i = 0; i < num_registered_fb; i++) {
bg_mxcfbi =
- ((struct mxcfb_info *)(registered_fb[i]->
- par));
+ ((struct mxcfb_info *)(registered_fb[i]->par));
if (bg_mxcfbi->ipu_ch == MEM_BG_SYNC) {
bg_fbi = registered_fb[i];
@@ -1072,15 +1031,13 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
if (bg_fbi->var.xres < fbi->var.xres)
pos.x = 0;
else
- pos.x =
- bg_fbi->var.xres - fbi->var.xres;
+ pos.x = bg_fbi->var.xres - fbi->var.xres;
}
if (fbi->var.yres + pos.y > bg_fbi->var.yres) {
if (bg_fbi->var.yres < fbi->var.yres)
pos.y = 0;
else
- pos.y =
- bg_fbi->var.yres - fbi->var.yres;
+ pos.y = bg_fbi->var.yres - fbi->var.yres;
}
retval = ipu_disp_set_window_pos(mxc_fbi->ipu_ch,
@@ -1095,7 +1052,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case MXCFB_GET_FB_IPU_CHAN:
{
struct mxcfb_info *mxc_fbi =
- (struct mxcfb_info *)fbi->par;
+ (struct mxcfb_info *)fbi->par;
if (put_user(mxc_fbi->ipu_ch, argp))
return -EFAULT;
@@ -1104,7 +1061,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case MXCFB_GET_DIFMT:
{
struct mxcfb_info *mxc_fbi =
- (struct mxcfb_info *)fbi->par;
+ (struct mxcfb_info *)fbi->par;
if (put_user(mxc_fbi->ipu_di_pix_fmt, argp))
return -EFAULT;
@@ -1113,18 +1070,9 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case MXCFB_GET_FB_IPU_DI:
{
struct mxcfb_info *mxc_fbi =
- (struct mxcfb_info *)fbi->par;
-
- if (put_user(mxc_fbi->ipu_di, argp))
- return -EFAULT;
- break;
- }
- case MXCFB_GET_FB_BLANK:
- {
- struct mxcfb_info *mxc_fbi =
(struct mxcfb_info *)fbi->par;
- if (put_user(mxc_fbi->cur_blank, argp))
+ if (put_user(mxc_fbi->ipu_di, argp))
return -EFAULT;
break;
}
@@ -1177,7 +1125,7 @@ static int
mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par,
- *mxc_graphic_fbi = NULL;
+ *mxc_graphic_fbi = NULL;
u_int y_bottom;
unsigned long base, active_alpha_phy_addr = 0;
bool loc_alpha_en = false;
@@ -1198,7 +1146,7 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
int j;
for (j = 0; j < num_registered_fb; j++) {
bg_mxcfbi =
- ((struct mxcfb_info *)(registered_fb[j]->par));
+ ((struct mxcfb_info *)(registered_fb[j]->par));
if (bg_mxcfbi->ipu_ch == MEM_BG_SYNC)
break;
@@ -1228,13 +1176,13 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
if ((strcmp(idstr, "DISP3 BG") == 0 ||
strcmp(idstr, "DISP3 FG") == 0) &&
((struct mxcfb_info *)
- (registered_fb[i]->par))->alpha_chan_en) {
+ (registered_fb[i]->par))->alpha_chan_en) {
loc_alpha_en = true;
mxc_graphic_fbi = (struct mxcfb_info *)
- (registered_fb[i]->par);
+ (registered_fb[i]->par);
active_alpha_phy_addr = mxc_fbi->cur_ipu_buf ?
- mxc_graphic_fbi->alpha_phy_addr1 :
- mxc_graphic_fbi->alpha_phy_addr0;
+ mxc_graphic_fbi->alpha_phy_addr1 :
+ mxc_graphic_fbi->alpha_phy_addr0;
dev_dbg(info->device, "Updating SDC graphic "
"buf %d address=0x%08lX\n",
mxc_fbi->cur_ipu_buf,
@@ -1244,7 +1192,7 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
}
}
- init_completion(&mxc_fbi->vsync_complete);
+ down(&mxc_fbi->flip_sem);
mxc_fbi->cur_ipu_buf = !mxc_fbi->cur_ipu_buf;
@@ -1278,7 +1226,6 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
return -EBUSY;
}
- down(&mxc_fbi->flip_sem);
dev_dbg(info->device, "Update complete\n");
info->var.xoffset = var->xoffset;
@@ -1312,9 +1259,9 @@ static int mxcfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
len = fbi->fix.smem_len - offset;
vma->vm_pgoff = (fbi->fix.smem_start + offset) >> PAGE_SHIFT;
} else if ((vma->vm_pgoff ==
- (mxc_fbi->alpha_phy_addr0 >> PAGE_SHIFT)) ||
+ (mxc_fbi->alpha_phy_addr0 >> PAGE_SHIFT)) ||
(vma->vm_pgoff ==
- (mxc_fbi->alpha_phy_addr1 >> PAGE_SHIFT))) {
+ (mxc_fbi->alpha_phy_addr1 >> PAGE_SHIFT))) {
len = mxc_fbi->alpha_mem_len;
} else {
list_for_each_entry(mem, &fb_alloc_list, list) {
@@ -1375,8 +1322,23 @@ static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id)
ipu_disable_irq(irq);
mxc_fbi->wait4vsync = 0;
} else {
- up(&mxc_fbi->flip_sem);
- ipu_disable_irq(irq);
+ if (!ipu_check_buffer_busy(mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, mxc_fbi->cur_ipu_buf)
+ || (mxc_fbi->waitcnt > 2)) {
+ /*
+ * This interrupt come after pan display select
+ * cur_ipu_buf buffer, this buffer should become
+ * idle after show. If it keep busy, clear it manually.
+ */
+ if (mxc_fbi->waitcnt > 2)
+ ipu_clear_buffer_ready(mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER,
+ mxc_fbi->cur_ipu_buf);
+ up(&mxc_fbi->flip_sem);
+ ipu_disable_irq(irq);
+ mxc_fbi->waitcnt = 0;
+ } else
+ mxc_fbi->waitcnt++;
}
return IRQ_HANDLED;
}
@@ -1394,10 +1356,14 @@ static irqreturn_t mxcfb_alpha_irq_handler(int irq, void *dev_id)
/*
* Suspends the framebuffer and blanks the screen. Power management support
*/
-static void mxcfb_suspend_one(struct fb_info *fbi)
+static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
{
+ struct fb_info *fbi = platform_get_drvdata(pdev);
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
int saved_blank;
+#ifdef CONFIG_FB_MXC_LOW_PWR_DISPLAY
+ void *fbmem;
+#endif
acquire_console_sem();
fb_set_suspend(fbi, 1);
@@ -1405,44 +1371,26 @@ static void mxcfb_suspend_one(struct fb_info *fbi)
mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
mxc_fbi->next_blank = saved_blank;
release_console_sem();
+
+ return 0;
}
/*
* Resumes the framebuffer and unblanks the screen. Power management support
*/
-static void mxcfb_resume_one(struct fb_info *fbi)
+static int mxcfb_resume(struct platform_device *pdev)
{
+ struct fb_info *fbi = platform_get_drvdata(pdev);
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
acquire_console_sem();
mxcfb_blank(mxc_fbi->next_blank, fbi);
fb_set_suspend(fbi, 0);
release_console_sem();
-}
-
-#ifndef CONFIG_HAS_EARLYSUSPEND
-
-static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct fb_info *fbi = platform_get_drvdata(pdev);
-
- if (fbi && (strcmp(fbi->fix.id, "DISP3 FG") == 0))
- mxcfb_suspend_one(fbi);
return 0;
}
-static int mxcfb_resume(struct platform_device *pdev)
-{
- struct fb_info *fbi = platform_get_drvdata(pdev);
-
- if (fbi && (strcmp(fbi->fix.id, "DISP3 FG") == 0))
- mxcfb_resume_one(fbi);
-
- return 0;
-}
-#endif
-
/*
* Main framebuffer functions
*/
@@ -1461,12 +1409,12 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
{
if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
fbi->fix.smem_len = fbi->var.yres_virtual *
- fbi->fix.line_length;
+ fbi->fix.line_length;
fbi->screen_base = dma_alloc_writecombine(fbi->device,
- fbi->fix.smem_len,
- (dma_addr_t *) & fbi->fix.
- smem_start, GFP_DMA);
+ fbi->fix.smem_len,
+ (dma_addr_t *)&fbi->fix.smem_start,
+ GFP_DMA);
if (fbi->screen_base == 0) {
dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
fbi->fix.smem_len = 0;
@@ -1572,13 +1520,15 @@ static ssize_t swap_disp_chan(struct device *dev,
int i;
for (i = 0; i < num_registered_fb; i++) {
- fg_mxcfbi = (struct mxcfb_info *)mxcfb_info[i]->par;
+ fg_mxcfbi =
+ (struct mxcfb_info *)mxcfb_info[i]->par;
if (fg_mxcfbi->ipu_ch == MEM_FG_SYNC)
break;
else
fg_mxcfbi = NULL;
}
- if (!fg_mxcfbi || fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {
+ if (!fg_mxcfbi ||
+ fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {
dev_err(dev,
"Can not switch while fb2(fb-fg) is on.\n");
release_console_sem();
@@ -1592,7 +1542,6 @@ static ssize_t swap_disp_chan(struct device *dev,
release_console_sem();
return count;
}
-
DEVICE_ATTR(fsl_disp_property, 644, show_disp_chan, swap_disp_chan);
/*!
@@ -1652,7 +1601,7 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfb_alpha_irq_handler, 0,
MXCFB_NAME, fbi) != 0) {
dev_err(&pdev->dev, "Error registering BG "
- "alpha irq handler.\n");
+ "alpha irq handler.\n");
ret = -EBUSY;
goto err1;
}
@@ -1665,7 +1614,7 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfb_alpha_irq_handler, 0,
MXCFB_NAME, fbi) != 0) {
dev_err(&pdev->dev, "Error registering BG "
- "alpha irq handler.\n");
+ "alpha irq handler.\n");
ret = -EBUSY;
goto err1;
}
@@ -1683,7 +1632,7 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfb_alpha_irq_handler, 0,
MXCFB_NAME, fbi) != 0) {
dev_err(&pdev->dev, "Error registering FG alpha irq "
- "handler.\n");
+ "handler.\n");
ret = -EBUSY;
goto err1;
}
@@ -1703,8 +1652,7 @@ static int mxcfb_probe(struct platform_device *pdev)
if (res && res->end) {
fbi->fix.smem_len = res->end - res->start + 1;
fbi->fix.smem_start = res->start;
- fbi->screen_base =
- ioremap(fbi->fix.smem_start, fbi->fix.smem_len);
+ fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len);
}
/* Need dummy values until real panel is configured */
@@ -1729,21 +1677,15 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfbi->fb_mode_str = plat_data->mode_str;
if (mxcfbi->fb_mode_str) {
-
#ifdef CONFIG_MODULE_CCXMX51
if ((mstr = strstr(mxcfbi->fb_mode_str, "VGA@")) != NULL)
mxcfbi->fb_mode_str = mstr + 4;
#endif
-
- ret =
- fb_find_mode(&fbi->var, fbi, mxcfbi->fb_mode_str, NULL, 0,
- NULL, mxcfbi->default_bpp);
- if ((!ret || (ret > 2)) && plat_data && plat_data->mode
- && plat_data->num_modes)
- fb_find_mode(&fbi->var, fbi, mxcfbi->fb_mode_str,
- plat_data->mode, plat_data->num_modes,
- NULL, mxcfbi->default_bpp);
-
+ ret = fb_find_mode(&fbi->var, fbi, mxcfbi->fb_mode_str, NULL, 0, NULL,
+ mxcfbi->default_bpp);
+ if ((!ret || (ret > 2)) && plat_data && plat_data->mode && plat_data->num_modes)
+ fb_find_mode(&fbi->var, fbi, mxcfbi->fb_mode_str, plat_data->mode,
+ plat_data->num_modes, NULL, mxcfbi->default_bpp);
#ifdef CONFIG_MODULE_CCXMX51
/* This improves the VGA modes on the CCWi-i.MX51 */
if (mstr != NULL) {
@@ -1758,8 +1700,7 @@ static int mxcfb_probe(struct platform_device *pdev)
pm_set_vt_switch(vt_switch);
/* Default Y virtual size is 2x panel size */
- fbi->var.yres_virtual = ((fbi->var.yres + 127) & ~127) * 2;
- fbi->var.xres_virtual = (fbi->var.xres + 31) & ~31;
+ fbi->var.yres_virtual = fbi->var.yres * 3;
mxcfb_set_fix(fbi);
@@ -1780,12 +1721,12 @@ static int mxcfb_probe(struct platform_device *pdev)
return 0;
- err2:
+err2:
ipu_free_irq(mxcfbi->ipu_ch_irq, fbi);
- err1:
+err1:
fb_dealloc_cmap(&fbi->cmap);
framebuffer_release(fbi);
- err0:
+err0:
return ret;
}
@@ -1818,10 +1759,8 @@ static struct platform_driver mxcfb_driver = {
},
.probe = mxcfb_probe,
.remove = mxcfb_remove,
-#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = mxcfb_suspend,
.resume = mxcfb_resume,
-#endif
};
/*
@@ -1886,7 +1825,8 @@ static int mxcfb_option_setup(struct fb_info *info, char *options)
continue;
}
if (!strncmp(opt, "bpp=", 4))
- mxcfbi->default_bpp = simple_strtoul(opt + 4, NULL, 0);
+ mxcfbi->default_bpp =
+ simple_strtoul(opt + 4, NULL, 0);
else
mxcfbi->fb_mode_str = opt;
}
@@ -1894,32 +1834,6 @@ static int mxcfb_option_setup(struct fb_info *info, char *options)
return 0;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void mxcfb_early_suspend(struct early_suspend *h)
-{
- int i;
- for (i = FB_DEVICE_NUM - 1; i >= 0; i--) {
- if (mxcfb_info[i])
- mxcfb_suspend_one(mxcfb_info[i]);
- }
-}
-
-static void mxcfb_later_resume(struct early_suspend *h)
-{
- int i;
- for (i = 0; i < FB_DEVICE_NUM; i++) {
- if (mxcfb_info[i])
- mxcfb_resume_one(mxcfb_info[i]);
- }
-}
-
-struct early_suspend fbdrv_earlysuspend = {
- .level = EARLY_SUSPEND_LEVEL_DISABLE_FB,
- .suspend = mxcfb_early_suspend,
- .resume = mxcfb_later_resume,
-};
-#endif
-
/*!
* Main entry function for the framebuffer. The function registers the power
* management callback functions with the kernel and also registers the MXCFB
@@ -1929,17 +1843,11 @@ struct early_suspend fbdrv_earlysuspend = {
*/
int __init mxcfb_init(void)
{
- int ret;
-
- ret = platform_driver_register(&mxcfb_driver);
- if (!ret)
- register_early_suspend(&fbdrv_earlysuspend);
- return ret;
+ return platform_driver_register(&mxcfb_driver);
}
void mxcfb_exit(void)
{
- unregister_early_suspend(&fbdrv_earlysuspend);
platform_driver_unregister(&mxcfb_driver);
}
diff --git a/drivers/video/mxc/tve.c b/drivers/video/mxc/tve.c
index 793b470cdce4..b1982f868e8c 100644
--- a/drivers/video/mxc/tve.c
+++ b/drivers/video/mxc/tve.c
@@ -513,9 +513,12 @@ static irqreturn_t tve_detect_handler(int irq, void *data)
/* Re-construct clk for tve display */
static inline void tve_recfg_fb(struct fb_info *fbi)
{
+ struct fb_var_screeninfo var;
+
+ memset(&var, 0, sizeof(var));
+ fb_videomode_to_var(&var, fbi->mode);
fbi->flags &= ~FBINFO_MISC_USEREVENT;
- fbi->var.activate |= FB_ACTIVATE_FORCE;
- fb_set_var(fbi, &fbi->var);
+ fb_set_var(fbi, &var);
}
int tve_fb_event(struct notifier_block *nb, unsigned long val, void *v)
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 5a72083dc67c..adf9632c6b1f 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1036,7 +1036,7 @@ static int s3c_fb_resume(struct platform_device *pdev)
static struct platform_driver s3c_fb_driver = {
.probe = s3c_fb_probe,
- .remove = s3c_fb_remove,
+ .remove = __devexit_p(s3c_fb_remove),
.suspend = s3c_fb_suspend,
.resume = s3c_fb_resume,
.driver = {
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
index 705c85360526..bef4aae388d0 100644
--- a/drivers/video/sis/vstruct.h
+++ b/drivers/video/sis/vstruct.h
@@ -342,7 +342,7 @@ struct SiS_Private
unsigned short SiS_RY4COE;
unsigned short SiS_LCDHDES;
unsigned short SiS_LCDVDES;
- unsigned short SiS_DDC_Port;
+ SISIOADDRESS SiS_DDC_Port;
unsigned short SiS_DDC_Index;
unsigned short SiS_DDC_Data;
unsigned short SiS_DDC_NData;
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index ca5b4643a401..e35232a18571 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -67,12 +67,14 @@ static DEFINE_MUTEX(uvfb_lock);
* find the kernel part of the task struct, copy the registers and
* the buffer contents and then complete the task.
*/
-static void uvesafb_cn_callback(void *data)
+static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
- struct cn_msg *msg = data;
struct uvesafb_task *utask;
struct uvesafb_ktask *task;
+ if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
+ return;
+
if (msg->seq >= UVESAFB_TASKS_MAX)
return;