summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 09:24:30 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 09:24:30 -0800
commite0c8453769fcaec654cd5870e84c63175658c842 (patch)
treee5f114f236689a8db8f44bcecb5c1f1e14462932 /drivers
parenta323ae93a74f669d890926187c68c711895e3454 (diff)
parentd6c2152b3efd73be265f426b5a1bb50ec436d999 (diff)
Merge tag 'fbdev-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
Pull fbdev changes from Tomi Valkeinen: - omapdss: add DRA7xxx SoC support - fbdev: support DMT (Display Monitor Timing) calculation * tag 'fbdev-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (40 commits) omapfb: Return error code when applying overlay settings fails OMAPDSS: DPI: DRA7xx support OMAPDSS: HDMI: Add DRA7xx support OMAPDSS: DISPC: program dispc polarities to control module OMAPDSS: DISPC: Add DRA7xx support OMAPDSS: Add Video PLLs for DRA7xx OMAPDSS: Add functions for external control of PLL OMAPDSS: DSS: Add DRA7xx base support Doc/DT: Add DT binding doc for DRA7xx DSS OMAPDSS: add define for DRA7xx HW version OMAPDSS: encoder-tpd12s015: Fix race issue with LS_OE OMAPDSS: OMAP5: fix digit output's allowed mgrs OMAPDSS: constify port arrays OMAPDSS: PLL: add dss_pll_wait_reset_done() OMAPDSS: Add enum dss_pll_id video: fbdev: fix sys_copyarea video/mmpfb: allow modular build fb: via: turn gpiolib and i2c selects into dependencies fbdev: ssd1307fb: return proper error code if write command fails fbdev: fix CVT vertical front and back porch values ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/console/Kconfig16
-rw-r--r--drivers/video/console/dummycon.c5
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/fbdev/Kconfig5
-rw-r--r--drivers/video/fbdev/aty/atyfb_base.c9
-rw-r--r--drivers/video/fbdev/core/fbcvt.c6
-rw-r--r--drivers/video/fbdev/core/fbmon.c103
-rw-r--r--drivers/video/fbdev/core/modedb.c111
-rw-r--r--drivers/video/fbdev/core/syscopyarea.c137
-rw-r--r--drivers/video/fbdev/geode/gx1fb_core.c6
-rw-r--r--drivers/video/fbdev/geode/gxfb_core.c6
-rw-r--r--drivers/video/fbdev/geode/lxfb_core.c6
-rw-r--r--drivers/video/fbdev/hgafb.c3
-rw-r--r--drivers/video/fbdev/mmp/Makefile4
-rw-r--r--drivers/video/fbdev/mmp/fb/Kconfig2
-rw-r--r--drivers/video/fbdev/ocfb.c2
-rw-r--r--drivers/video/fbdev/omap2/displays-new/Kconfig6
-rw-r--r--drivers/video/fbdev/omap2/displays-new/Makefile1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c2
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-opa362.c285
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c57
-rw-r--r--drivers/video/fbdev/omap2/dss/Makefile2
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c54
-rw-r--r--drivers/video/fbdev/omap2/dss/dpi.c26
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c219
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.h22
-rw-r--r--drivers/video/fbdev/omap2/dss/dss_features.c3
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_phy.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_pll.c6
-rw-r--r--drivers/video/fbdev/omap2/dss/omapdss-boot-init.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/pll.c10
-rw-r--r--drivers/video/fbdev/omap2/dss/video-pll.c211
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c7
-rw-r--r--drivers/video/fbdev/savage/savagefb.h12
-rw-r--r--drivers/video/fbdev/ssd1307fb.c86
-rw-r--r--drivers/video/fbdev/vt8500lcdfb.c4
-rw-r--r--drivers/video/vgastate.c82
39 files changed, 1223 insertions, 301 deletions
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fe1cd0148e13..ba97efc3bf70 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -77,18 +77,22 @@ config DUMMY_CONSOLE
config DUMMY_CONSOLE_COLUMNS
int "Initial number of console screen columns"
- depends on PARISC && DUMMY_CONSOLE
- default "160"
+ depends on DUMMY_CONSOLE && !ARM
+ default 160 if PARISC
+ default 80
help
- The default value is 160, which should fit a 1280x1024 monitor.
+ On PA-RISC, the default value is 160, which should fit a 1280x1024
+ monitor.
Select 80 if you use a 640x480 resolution by default.
config DUMMY_CONSOLE_ROWS
int "Initial number of console screen rows"
- depends on PARISC && DUMMY_CONSOLE
- default "64"
+ depends on DUMMY_CONSOLE && !ARM
+ default 64 if PARISC
+ default 25
help
- The default value is 64, which should fit a 1280x1024 monitor.
+ On PA-RISC, the default value is 64, which should fit a 1280x1024
+ monitor.
Select 25 if you use a 640x480 resolution by default.
config FRAMEBUFFER_CONSOLE
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index 40bec8d64b0a..0efc52f11ad0 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -20,13 +20,10 @@
#if defined(__arm__)
#define DUMMY_COLUMNS screen_info.orig_video_cols
#define DUMMY_ROWS screen_info.orig_video_lines
-#elif defined(__hppa__)
+#else
/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */
#define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS
#define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS
-#else
-#define DUMMY_COLUMNS 80
-#define DUMMY_ROWS 25
#endif
static const char *dummycon_startup(void)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index ea437245562e..b97210671a81 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -146,9 +146,6 @@ static const struct consw fb_con;
static int fbcon_set_origin(struct vc_data *);
-#define CURSOR_DRAW_DELAY (1)
-
-static int vbl_cursor_cnt;
static int fbcon_cursor_noblink;
#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
@@ -1329,7 +1326,6 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
- vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
static int scrollback_phys_max = 0;
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 4916c97216f8..b3dd417b4719 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1530,13 +1530,11 @@ config FB_SIS_315
config FB_VIA
tristate "VIA UniChrome (Pro) and Chrome9 display support"
- depends on FB && PCI && X86
+ depends on FB && PCI && X86 && GPIOLIB && I2C
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select I2C_ALGOBIT
- select I2C
- select GPIOLIB
help
This is the frame buffer device driver for Graphics chips of VIA
UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
@@ -2151,7 +2149,6 @@ config FB_PS3
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
- select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
---help---
Include support for the virtual frame buffer in the PS3 platform.
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index 37ec09b3fffd..8789e487b96e 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3948,7 +3948,7 @@ static struct notifier_block atyfb_reboot_notifier = {
.notifier_call = atyfb_reboot_notify,
};
-static const struct dmi_system_id atyfb_reboot_ids[] = {
+static const struct dmi_system_id atyfb_reboot_ids[] __initconst = {
{
.ident = "HP OmniBook 500",
.matches = {
@@ -3960,6 +3960,7 @@ static const struct dmi_system_id atyfb_reboot_ids[] = {
{ }
};
+static bool registered_notifier = false;
static int __init atyfb_init(void)
{
@@ -3982,15 +3983,17 @@ static int __init atyfb_init(void)
if (err1 && err2)
return -ENODEV;
- if (dmi_check_system(atyfb_reboot_ids))
+ if (dmi_check_system(atyfb_reboot_ids)) {
register_reboot_notifier(&atyfb_reboot_notifier);
+ registered_notifier = true;
+ }
return 0;
}
static void __exit atyfb_exit(void)
{
- if (dmi_check_system(atyfb_reboot_ids))
+ if (registered_notifier)
unregister_reboot_notifier(&atyfb_reboot_notifier);
#ifdef CONFIG_PCI
diff --git a/drivers/video/fbdev/core/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c
index 7cb715dfc0e1..55d2bd0ce5c0 100644
--- a/drivers/video/fbdev/core/fbcvt.c
+++ b/drivers/video/fbdev/core/fbcvt.c
@@ -369,9 +369,9 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
cvt.h_back_porch = cvt.hblank/2 + cvt.h_margin;
cvt.h_front_porch = cvt.hblank - cvt.hsync - cvt.h_back_porch +
2 * cvt.h_margin;
- cvt.v_back_porch = 3 + cvt.v_margin;
- cvt.v_front_porch = cvt.vtotal - cvt.yres/cvt.interlace -
- cvt.v_back_porch - cvt.vsync;
+ cvt.v_front_porch = 3 + cvt.v_margin;
+ cvt.v_back_porch = cvt.vtotal - cvt.yres/cvt.interlace -
+ cvt.v_front_porch - cvt.vsync;
fb_cvt_print_name(&cvt);
fb_cvt_convert_to_mode(&cvt, mode);
diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index 5b0e313849bd..95338593ebf4 100644
--- a/drivers/video/fbdev/core/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -496,56 +496,71 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
}
static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
- int ver, int rev)
+ int ver, int rev, const struct fb_monspecs *specs)
{
- int xres, yres = 0, refresh, ratio, i;
-
- xres = (block[0] + 31) * 8;
- if (xres <= 256)
- return 0;
+ int i;
- ratio = (block[1] & 0xc0) >> 6;
- switch (ratio) {
- case 0:
- /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
- if (ver < 1 || (ver == 1 && rev < 3))
- yres = xres;
- else
- yres = (xres * 10)/16;
- break;
- case 1:
- yres = (xres * 3)/4;
- break;
- case 2:
- yres = (xres * 4)/5;
- break;
- case 3:
- yres = (xres * 9)/16;
- break;
+ for (i = 0; i < DMT_SIZE; i++) {
+ u32 std_2byte_code = block[0] << 8 | block[1];
+ if (std_2byte_code == dmt_modes[i].std_2byte_code)
+ break;
}
- refresh = (block[1] & 0x3f) + 60;
-
- DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh);
- for (i = 0; i < VESA_MODEDB_SIZE; i++) {
- if (vesa_modes[i].xres == xres &&
- vesa_modes[i].yres == yres &&
- vesa_modes[i].refresh == refresh) {
- *mode = vesa_modes[i];
- mode->flag |= FB_MODE_IS_STANDARD;
- return 1;
+
+ if (i < DMT_SIZE && dmt_modes[i].mode) {
+ /* DMT mode found */
+ *mode = *dmt_modes[i].mode;
+ mode->flag |= FB_MODE_IS_STANDARD;
+ DPRINTK(" DMT id=%d\n", dmt_modes[i].dmt_id);
+
+ } else {
+ int xres, yres = 0, refresh, ratio;
+
+ xres = (block[0] + 31) * 8;
+ if (xres <= 256)
+ return 0;
+
+ ratio = (block[1] & 0xc0) >> 6;
+ switch (ratio) {
+ case 0:
+ /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
+ if (ver < 1 || (ver == 1 && rev < 3))
+ yres = xres;
+ else
+ yres = (xres * 10)/16;
+ break;
+ case 1:
+ yres = (xres * 3)/4;
+ break;
+ case 2:
+ yres = (xres * 4)/5;
+ break;
+ case 3:
+ yres = (xres * 9)/16;
+ break;
}
+ refresh = (block[1] & 0x3f) + 60;
+ DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh);
+
+ calc_mode_timings(xres, yres, refresh, mode);
}
- calc_mode_timings(xres, yres, refresh, mode);
+
+ /* Check the mode we got is within valid spec of the monitor */
+ if (specs && specs->dclkmax
+ && PICOS2KHZ(mode->pixclock) * 1000 > specs->dclkmax) {
+ DPRINTK(" mode exceed max DCLK\n");
+ return 0;
+ }
+
return 1;
}
-static int get_dst_timing(unsigned char *block,
- struct fb_videomode *mode, int ver, int rev)
+static int get_dst_timing(unsigned char *block, struct fb_videomode *mode,
+ int ver, int rev, const struct fb_monspecs *specs)
{
int j, num = 0;
for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
- num += get_std_timing(block, &mode[num], ver, rev);
+ num += get_std_timing(block, &mode[num], ver, rev, specs);
return num;
}
@@ -601,7 +616,8 @@ static void get_detailed_timing(unsigned char *block,
* This function builds a mode database using the contents of the EDID
* data
*/
-static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
+static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize,
+ const struct fb_monspecs *specs)
{
struct fb_videomode *mode, *m;
unsigned char *block;
@@ -643,12 +659,13 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
DPRINTK(" Standard Timings\n");
block = edid + STD_TIMING_DESCRIPTIONS_START;
for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
- num += get_std_timing(block, &mode[num], ver, rev);
+ num += get_std_timing(block, &mode[num], ver, rev, specs);
block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
- num += get_dst_timing(block + 5, &mode[num], ver, rev);
+ num += get_dst_timing(block + 5, &mode[num],
+ ver, rev, specs);
}
/* Yikes, EDID data is totally useless */
@@ -707,7 +724,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
int num_modes, hz, hscan, pixclock;
int vtotal, htotal;
- modes = fb_create_modedb(edid, &num_modes);
+ modes = fb_create_modedb(edid, &num_modes, specs);
if (!modes) {
DPRINTK("None Available\n");
return 1;
@@ -964,7 +981,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
DPRINTK(" Display Characteristics:\n");
get_monspecs(edid, specs);
- specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
+ specs->modedb = fb_create_modedb(edid, &specs->modedb_len, specs);
/*
* Workaround for buggy EDIDs that sets that the first
diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c
index 388f7971494b..7d07cf824b64 100644
--- a/drivers/video/fbdev/core/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
@@ -468,8 +468,119 @@ const struct fb_videomode vesa_modes[] = {
/* 33 1920x1440-75 VESA */
{ NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 34 1920x1200-60 RB VESA */
+ { NULL, 60, 1920, 1200, 6493, 80, 48, 26, 3, 32, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 35 1920x1200-60 VESA */
+ { NULL, 60, 1920, 1200, 5174, 336, 136, 36, 3, 200, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 36 1920x1200-75 VESA */
+ { NULL, 75, 1920, 1200, 4077, 344, 136, 46, 3, 208, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 37 1920x1200-85 VESA */
+ { NULL, 85, 1920, 1200, 3555, 352, 144, 53, 3, 208, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 38 2560x1600-60 RB VESA */
+ { NULL, 60, 2560, 1600, 3724, 80, 48, 37, 3, 32, 6,
+ FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 39 2560x1600-60 VESA */
+ { NULL, 60, 2560, 1600, 2869, 472, 192, 49, 3, 280, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 40 2560x1600-75 VESA */
+ { NULL, 75, 2560, 1600, 2256, 488, 208, 63, 3, 280, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 41 2560x1600-85 VESA */
+ { NULL, 85, 2560, 1600, 1979, 488, 208, 73, 3, 280, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 42 2560x1600-120 RB VESA */
+ { NULL, 120, 2560, 1600, 1809, 80, 48, 85, 3, 32, 6,
+ FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
};
EXPORT_SYMBOL(vesa_modes);
+
+const struct dmt_videomode dmt_modes[DMT_SIZE] = {
+ { 0x01, 0x0000, 0x000000, &vesa_modes[0] },
+ { 0x02, 0x3119, 0x000000, &vesa_modes[1] },
+ { 0x03, 0x0000, 0x000000, &vesa_modes[2] },
+ { 0x04, 0x3140, 0x000000, &vesa_modes[3] },
+ { 0x05, 0x314c, 0x000000, &vesa_modes[4] },
+ { 0x06, 0x314f, 0x000000, &vesa_modes[5] },
+ { 0x07, 0x3159, 0x000000, &vesa_modes[6] },
+ { 0x08, 0x0000, 0x000000, &vesa_modes[7] },
+ { 0x09, 0x4540, 0x000000, &vesa_modes[8] },
+ { 0x0a, 0x454c, 0x000000, &vesa_modes[9] },
+ { 0x0b, 0x454f, 0x000000, &vesa_modes[10] },
+ { 0x0c, 0x4559, 0x000000, &vesa_modes[11] },
+ { 0x0d, 0x0000, 0x000000, NULL },
+ { 0x0e, 0x0000, 0x000000, NULL },
+ { 0x0f, 0x0000, 0x000000, &vesa_modes[12] },
+ { 0x10, 0x6140, 0x000000, &vesa_modes[13] },
+ { 0x11, 0x614a, 0x000000, &vesa_modes[14] },
+ { 0x12, 0x614f, 0x000000, &vesa_modes[15] },
+ { 0x13, 0x6159, 0x000000, &vesa_modes[16] },
+ { 0x14, 0x0000, 0x000000, NULL },
+ { 0x15, 0x714f, 0x000000, &vesa_modes[17] },
+ { 0x16, 0x0000, 0x7f1c21, NULL },
+ { 0x17, 0x0000, 0x7f1c28, NULL },
+ { 0x18, 0x0000, 0x7f1c44, NULL },
+ { 0x19, 0x0000, 0x7f1c62, NULL },
+ { 0x1a, 0x0000, 0x000000, NULL },
+ { 0x1b, 0x0000, 0x8f1821, NULL },
+ { 0x1c, 0x8100, 0x8f1828, NULL },
+ { 0x1d, 0x810f, 0x8f1844, NULL },
+ { 0x1e, 0x8119, 0x8f1862, NULL },
+ { 0x1f, 0x0000, 0x000000, NULL },
+ { 0x20, 0x8140, 0x000000, &vesa_modes[18] },
+ { 0x21, 0x8159, 0x000000, &vesa_modes[19] },
+ { 0x22, 0x0000, 0x000000, NULL },
+ { 0x23, 0x8180, 0x000000, &vesa_modes[20] },
+ { 0x24, 0x818f, 0x000000, &vesa_modes[21] },
+ { 0x25, 0x8199, 0x000000, &vesa_modes[22] },
+ { 0x26, 0x0000, 0x000000, NULL },
+ { 0x27, 0x0000, 0x000000, NULL },
+ { 0x28, 0x0000, 0x000000, NULL },
+ { 0x29, 0x0000, 0x0c2021, NULL },
+ { 0x2a, 0x9040, 0x0c2028, NULL },
+ { 0x2b, 0x904f, 0x0c2044, NULL },
+ { 0x2c, 0x9059, 0x0c2062, NULL },
+ { 0x2d, 0x0000, 0x000000, NULL },
+ { 0x2e, 0x9500, 0xc11821, NULL },
+ { 0x2f, 0x9500, 0xc11828, NULL },
+ { 0x30, 0x950f, 0xc11844, NULL },
+ { 0x31, 0x9519, 0xc11868, NULL },
+ { 0x32, 0x0000, 0x000000, NULL },
+ { 0x33, 0xa940, 0x000000, &vesa_modes[23] },
+ { 0x34, 0xa945, 0x000000, &vesa_modes[24] },
+ { 0x35, 0xa94a, 0x000000, &vesa_modes[25] },
+ { 0x36, 0xa94f, 0x000000, &vesa_modes[26] },
+ { 0x37, 0xa959, 0x000000, &vesa_modes[27] },
+ { 0x38, 0x0000, 0x000000, NULL },
+ { 0x39, 0x0000, 0x0c2821, NULL },
+ { 0x3a, 0xb300, 0x0c2828, NULL },
+ { 0x3b, 0xb30f, 0x0c2844, NULL },
+ { 0x3c, 0xb319, 0x0c2868, NULL },
+ { 0x3d, 0x0000, 0x000000, NULL },
+ { 0x3e, 0xc140, 0x000000, &vesa_modes[28] },
+ { 0x3f, 0xc14f, 0x000000, &vesa_modes[29] },
+ { 0x40, 0x0000, 0x000000, NULL},
+ { 0x41, 0xc940, 0x000000, &vesa_modes[30] },
+ { 0x42, 0xc94f, 0x000000, &vesa_modes[31] },
+ { 0x43, 0x0000, 0x000000, NULL },
+ { 0x44, 0x0000, 0x572821, &vesa_modes[34] },
+ { 0x45, 0xd100, 0x572828, &vesa_modes[35] },
+ { 0x46, 0xd10f, 0x572844, &vesa_modes[36] },
+ { 0x47, 0xd119, 0x572862, &vesa_modes[37] },
+ { 0x48, 0x0000, 0x000000, NULL },
+ { 0x49, 0xd140, 0x000000, &vesa_modes[32] },
+ { 0x4a, 0xd14f, 0x000000, &vesa_modes[33] },
+ { 0x4b, 0x0000, 0x000000, NULL },
+ { 0x4c, 0x0000, 0x1f3821, &vesa_modes[38] },
+ { 0x4d, 0x0000, 0x1f3828, &vesa_modes[39] },
+ { 0x4e, 0x0000, 0x1f3844, &vesa_modes[40] },
+ { 0x4f, 0x0000, 0x1f3862, &vesa_modes[41] },
+ { 0x50, 0x0000, 0x000000, &vesa_modes[42] },
+};
+EXPORT_SYMBOL(dmt_modes);
#endif /* CONFIG_FB_MODE_HELPERS */
/**
diff --git a/drivers/video/fbdev/core/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c
index 844a32fd38ed..c1eda3190968 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -25,8 +25,8 @@
*/
static void
-bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
- const unsigned long *src, int src_idx, int bits, unsigned n)
+bitcpy(struct fb_info *p, unsigned long *dst, unsigned dst_idx,
+ const unsigned long *src, unsigned src_idx, int bits, unsigned n)
{
unsigned long first, last;
int const shift = dst_idx-src_idx;
@@ -86,15 +86,15 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
first &= last;
if (shift > 0) {
/* Single source word */
- *dst = comp(*src >> right, *dst, first);
+ *dst = comp(*src << left, *dst, first);
} else if (src_idx+n <= bits) {
/* Single source word */
- *dst = comp(*src << left, *dst, first);
+ *dst = comp(*src >> right, *dst, first);
} else {
/* 2 source words */
d0 = *src++;
d1 = *src;
- *dst = comp(d0 << left | d1 >> right, *dst,
+ *dst = comp(d0 >> right | d1 << left, *dst,
first);
}
} else {
@@ -109,13 +109,14 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
/* Leading bits */
if (shift > 0) {
/* Single source word */
- *dst = comp(d0 >> right, *dst, first);
+ *dst = comp(d0 << left, *dst, first);
dst++;
n -= bits - dst_idx;
} else {
/* 2 source words */
d1 = *src++;
- *dst = comp(d0 << left | *dst >> right, *dst, first);
+ *dst = comp(d0 >> right | d1 << left, *dst,
+ first);
d0 = d1;
dst++;
n -= bits - dst_idx;
@@ -126,36 +127,36 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
n /= bits;
while (n >= 4) {
d1 = *src++;
- *dst++ = d0 << left | d1 >> right;
+ *dst++ = d0 >> right | d1 << left;
d0 = d1;
d1 = *src++;
- *dst++ = d0 << left | d1 >> right;
+ *dst++ = d0 >> right | d1 << left;
d0 = d1;
d1 = *src++;
- *dst++ = d0 << left | d1 >> right;
+ *dst++ = d0 >> right | d1 << left;
d0 = d1;
d1 = *src++;
- *dst++ = d0 << left | d1 >> right;
+ *dst++ = d0 >> right | d1 << left;
d0 = d1;
n -= 4;
}
while (n--) {
d1 = *src++;
- *dst++ = d0 << left | d1 >> right;
+ *dst++ = d0 >> right | d1 << left;
d0 = d1;
}
/* Trailing bits */
- if (last) {
- if (m <= right) {
+ if (m) {
+ if (m <= bits - right) {
/* Single source word */
- *dst = comp(d0 << left, *dst, last);
+ d0 >>= right;
} else {
/* 2 source words */
d1 = *src;
- *dst = comp(d0 << left | d1 >> right,
- *dst, last);
+ d0 = d0 >> right | d1 << left;
}
+ *dst = comp(d0, *dst, last);
}
}
}
@@ -166,40 +167,35 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
*/
static void
-bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
- const unsigned long *src, int src_idx, int bits, unsigned n)
+bitcpy_rev(struct fb_info *p, unsigned long *dst, unsigned dst_idx,
+ const unsigned long *src, unsigned src_idx, unsigned bits,
+ unsigned n)
{
unsigned long first, last;
int shift;
- dst += (n-1)/bits;
- src += (n-1)/bits;
- if ((n-1) % bits) {
- dst_idx += (n-1) % bits;
- dst += dst_idx >> (ffs(bits) - 1);
- dst_idx &= bits - 1;
- src_idx += (n-1) % bits;
- src += src_idx >> (ffs(bits) - 1);
- src_idx &= bits - 1;
- }
+ dst += (dst_idx + n - 1) / bits;
+ src += (src_idx + n - 1) / bits;
+ dst_idx = (dst_idx + n - 1) % bits;
+ src_idx = (src_idx + n - 1) % bits;
shift = dst_idx-src_idx;
- first = FB_SHIFT_LOW(p, ~0UL, bits - 1 - dst_idx);
- last = ~(FB_SHIFT_LOW(p, ~0UL, bits - 1 - ((dst_idx-n) % bits)));
+ first = ~FB_SHIFT_HIGH(p, ~0UL, (dst_idx + 1) % bits);
+ last = FB_SHIFT_HIGH(p, ~0UL, (bits + dst_idx + 1 - n) % bits);
if (!shift) {
/* Same alignment for source and dest */
if ((unsigned long)dst_idx+1 >= n) {
/* Single word */
- if (last)
- first &= last;
- *dst = comp(*src, *dst, first);
+ if (first)
+ last &= first;
+ *dst = comp(*src, *dst, last);
} else {
/* Multiple destination words */
/* Leading bits */
- if (first != ~0UL) {
+ if (first) {
*dst = comp(*src, *dst, first);
dst--;
src--;
@@ -222,29 +218,29 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
while (n--)
*dst-- = *src--;
/* Trailing bits */
- if (last)
+ if (last != -1UL)
*dst = comp(*src, *dst, last);
}
} else {
/* Different alignment for source and dest */
- int const left = -shift & (bits-1);
- int const right = shift & (bits-1);
+ int const left = shift & (bits-1);
+ int const right = -shift & (bits-1);
if ((unsigned long)dst_idx+1 >= n) {
/* Single destination word */
- if (last)
- first &= last;
+ if (first)
+ last &= first;
if (shift < 0) {
/* Single source word */
- *dst = comp(*src << left, *dst, first);
+ *dst = comp(*src >> right, *dst, last);
} else if (1+(unsigned long)src_idx >= n) {
/* Single source word */
- *dst = comp(*src >> right, *dst, first);
+ *dst = comp(*src << left, *dst, last);
} else {
/* 2 source words */
- *dst = comp(*src >> right | *(src-1) << left,
- *dst, first);
+ *dst = comp(*src << left | *(src-1) >> right,
+ *dst, last);
}
} else {
/* Multiple destination words */
@@ -261,14 +257,18 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
/* Leading bits */
if (shift < 0) {
/* Single source word */
- *dst = comp(d0 << left, *dst, first);
+ d1 = d0;
+ d0 >>= right;
} else {
/* 2 source words */
d1 = *src--;
- *dst = comp(d0 >> right | d1 << left, *dst,
- first);
- d0 = d1;
+ d0 = d0 << left | d1 >> right;
}
+ if (!first)
+ *dst = d0;
+ else
+ *dst = comp(d0, *dst, first);
+ d0 = d1;
dst--;
n -= dst_idx+1;
@@ -277,36 +277,36 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
n /= bits;
while (n >= 4) {
d1 = *src--;
- *dst-- = d0 >> right | d1 << left;
+ *dst-- = d0 << left | d1 >> right;
d0 = d1;
d1 = *src--;
- *dst-- = d0 >> right | d1 << left;
+ *dst-- = d0 << left | d1 >> right;
d0 = d1;
d1 = *src--;
- *dst-- = d0 >> right | d1 << left;
+ *dst-- = d0 << left | d1 >> right;
d0 = d1;
d1 = *src--;
- *dst-- = d0 >> right | d1 << left;
+ *dst-- = d0 << left | d1 >> right;
d0 = d1;
n -= 4;
}
while (n--) {
d1 = *src--;
- *dst-- = d0 >> right | d1 << left;
+ *dst-- = d0 << left | d1 >> right;
d0 = d1;
}
/* Trailing bits */
- if (last) {
- if (m <= left) {
+ if (m) {
+ if (m <= bits - left) {
/* Single source word */
- *dst = comp(d0 >> right, *dst, last);
+ d0 <<= left;
} else {
/* 2 source words */
d1 = *src;
- *dst = comp(d0 >> right | d1 << left,
- *dst, last);
+ d0 = d0 << left | d1 >> right;
}
+ *dst = comp(d0, *dst, last);
}
}
}
@@ -317,9 +317,9 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
unsigned long const bits_per_line = p->fix.line_length*8u;
- unsigned long *dst = NULL, *src = NULL;
+ unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits