diff --git a/Documentation/devicetree/bindings/video/ti,dra7-dss.txt b/Documentation/devicetree/bindings/video/ti,dra7-dss.txt new file mode 100644 index 000000000000..f33a05137b0e --- /dev/null +++ b/Documentation/devicetree/bindings/video/ti,dra7-dss.txt @@ -0,0 +1,69 @@ +Texas Instruments DRA7x Display Subsystem +========================================= + +See Documentation/devicetree/bindings/video/ti,omap-dss.txt for generic +description about OMAP Display Subsystem bindings. + +DSS Core +-------- + +Required properties: +- compatible: "ti,dra7-dss" +- reg: address and length of the register spaces for 'dss' +- ti,hwmods: "dss_core" +- clocks: handle to fclk +- clock-names: "fck" +- syscon: phandle to control module core syscon node + +Optional properties: + +Some DRA7xx SoCs have one dedicated video PLL, some have two. These properties +can be used to describe the video PLLs: + +- reg: address and length of the register spaces for 'pll1_clkctrl', + 'pll1', 'pll2_clkctrl', 'pll2' +- clocks: handle to video1 pll clock and video2 pll clock +- clock-names: "video1_clk" and "video2_clk" + +Required nodes: +- DISPC + +Optional nodes: +- DSS Submodules: HDMI +- Video port for DPI output + +DPI Endpoint required properties: +- data-lines: number of lines used + + +DISPC +----- + +Required properties: +- compatible: "ti,dra7-dispc" +- reg: address and length of the register space +- ti,hwmods: "dss_dispc" +- interrupts: the DISPC interrupt +- clocks: handle to fclk +- clock-names: "fck" + +HDMI +---- + +Required properties: +- compatible: "ti,dra7-hdmi" +- reg: addresses and lengths of the register spaces for 'wp', 'pll', 'phy', + 'core' +- reg-names: "wp", "pll", "phy", "core" +- interrupts: the HDMI interrupt line +- ti,hwmods: "dss_hdmi" +- vdda-supply: vdda power supply +- clocks: handles to fclk and pll clock +- clock-names: "fck", "sys_clk" + +Optional nodes: +- Video port for HDMI output + +HDMI Endpoint optional properties: +- lanes: list of 8 pin numbers for the HDMI lanes: CLK+, CLK-, D0+, D0-, + D1+, D1-, D2+, D2-. (default: 0,1,2,3,4,5,6,7) diff --git a/Documentation/devicetree/bindings/video/ti,opa362.txt b/Documentation/devicetree/bindings/video/ti,opa362.txt new file mode 100644 index 000000000000..f96083c0bd17 --- /dev/null +++ b/Documentation/devicetree/bindings/video/ti,opa362.txt @@ -0,0 +1,38 @@ +OPA362 analog video amplifier + +Required properties: +- compatible: "ti,opa362" +- enable-gpios: enable/disable output gpio + +Required node: +- Video port 0 for opa362 input +- Video port 1 for opa362 output + +Example: + +tv_amp: opa362 { + compatible = "ti,opa362"; + enable-gpios = <&gpio1 23 0>; /* GPIO to enable video out amplifier */ + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + opa_in: endpoint@0 { + remote-endpoint = <&venc_out>; + }; + }; + + port@1 { + reg = <1>; + opa_out: endpoint@0 { + remote-endpoint = <&tv_connector_in>; + }; + }; + }; +}; + + + 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; + int i; - 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; + 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 >> 3; - int dst_idx = 0, src_idx = 0, rev_copy = 0; + unsigned dst_idx = 0, src_idx = 0, rev_copy = 0; if (p->state != FBINFO_STATE_RUNNING) return; @@ -334,8 +334,7 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area) /* split the base of the framebuffer into a long-aligned address and the index of the first bit */ - dst = src = (unsigned long *)((unsigned long)p->screen_base & - ~(bytes-1)); + base = (unsigned long *)((unsigned long)p->screen_base & ~(bytes-1)); dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1)); /* add offset of source and target area */ dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel; @@ -348,20 +347,14 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area) while (height--) { dst_idx -= bits_per_line; src_idx -= bits_per_line; - dst += dst_idx >> (ffs(bits) - 1); - dst_idx &= (bytes - 1); - src += src_idx >> (ffs(bits) - 1); - src_idx &= (bytes - 1); - bitcpy_rev(p, dst, dst_idx, src, src_idx, bits, + bitcpy_rev(p, base + (dst_idx / bits), dst_idx % bits, + base + (src_idx / bits), src_idx % bits, bits, width*p->var.bits_per_pixel); } } else { while (height--) { - dst += dst_idx >> (ffs(bits) - 1); - dst_idx &= (bytes - 1); - src += src_idx >> (ffs(bits) - 1); - src_idx &= (bytes - 1); - bitcpy(p, dst, dst_idx, src, src_idx, bits, + bitcpy(p, base + (dst_idx / bits), dst_idx % bits, + base + (src_idx / bits), src_idx % bits, bits, width*p->var.bits_per_pixel); dst_idx += bits_per_line; src_idx += bits_per_line; diff --git a/drivers/video/fbdev/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c index 2794ba11f332..9bee8744c438 100644 --- a/drivers/video/fbdev/geode/gx1fb_core.c +++ b/drivers/video/fbdev/geode/gx1fb_core.c @@ -374,10 +374,8 @@ static int gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id) release_mem_region(gx1_gx_base() + 0x8300, 0x100); } - if (info) { - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); return ret; } diff --git a/drivers/video/fbdev/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c index 1790f14bab15..124d7c7e2d14 100644 --- a/drivers/video/fbdev/geode/gxfb_core.c +++ b/drivers/video/fbdev/geode/gxfb_core.c @@ -444,10 +444,8 @@ static int gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_release_region(pdev, 1); } - if (info) { - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); return ret; } diff --git a/drivers/video/fbdev/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c index 9e1d19d673a1..138da6cb6cbc 100644 --- a/drivers/video/fbdev/geode/lxfb_core.c +++ b/drivers/video/fbdev/geode/lxfb_core.c @@ -577,10 +577,8 @@ err: pci_release_region(pdev, 3); } - if (info) { - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); return ret; } diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c index 5ff9fe2116a4..15d3ccff2965 100644 --- a/drivers/video/fbdev/hgafb.c +++ b/drivers/video/fbdev/hgafb.c @@ -417,8 +417,7 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset < 0 || - var->yoffset >= info->var.yres_virtual || + if (var->yoffset >= info->var.yres_virtual || var->xoffset) return -EINVAL; } else { diff --git a/drivers/video/fbdev/mmp/Makefile b/drivers/video/fbdev/mmp/Makefile index a014cb358bf8..924dd0930cc7 100644 --- a/drivers/video/fbdev/mmp/Makefile +++ b/drivers/video/fbdev/mmp/Makefile @@ -1 +1,3 @@ -obj-y += core.o hw/ panel/ fb/ +obj-$(CONFIG_MMP_DISP) += mmp_disp.o hw/ panel/ fb/ + +mmp_disp-y += core.o diff --git a/drivers/video/fbdev/mmp/fb/Kconfig b/drivers/video/fbdev/mmp/fb/Kconfig index 9b0141f105f5..985e1a7cd254 100644 --- a/drivers/video/fbdev/mmp/fb/Kconfig +++ b/drivers/video/fbdev/mmp/fb/Kconfig @@ -1,7 +1,7 @@ if MMP_DISP config MMP_FB - bool "fb driver for Marvell MMP Display Subsystem" + tristate "fb driver for Marvell MMP Display Subsystem" depends on FB select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c index 7f9dc9bec309..de9819660ca0 100644 --- a/drivers/video/fbdev/ocfb.c +++ b/drivers/video/fbdev/ocfb.c @@ -61,7 +61,7 @@ struct ocfb_dev { /* flag indicating whether the regs are little endian accessed */ int little_endian; /* Physical and virtual addresses of framebuffer */ - phys_addr_t fb_phys; + dma_addr_t fb_phys; void __iomem *fb_virt; u32 pseudo_palette[PALETTE_SIZE]; }; diff --git a/drivers/video/fbdev/omap2/displays-new/Kconfig b/drivers/video/fbdev/omap2/displays-new/Kconfig index e6cfc38160d3..574710141a61 100644 --- a/drivers/video/fbdev/omap2/displays-new/Kconfig +++ b/drivers/video/fbdev/omap2/displays-new/Kconfig @@ -1,6 +1,12 @@ menu "OMAP Display Device Drivers (new device model)" depends on OMAP2_DSS +config DISPLAY_ENCODER_OPA362 + tristate "OPA362 external analog amplifier" + help + Driver for OPA362 external analog TV amplifier controlled + through a GPIO. + config DISPLAY_ENCODER_TFP410 tristate "TFP410 DPI to DVI Encoder" help diff --git a/drivers/video/fbdev/omap2/displays-new/Makefile b/drivers/video/fbdev/omap2/displays-new/Makefile index 0323a8a1c682..9aa176bfbf2e 100644 --- a/drivers/video/fbdev/omap2/displays-new/Makefile +++ b/drivers/video/fbdev/omap2/displays-new/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_DISPLAY_ENCODER_OPA362) += encoder-opa362.o obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o diff --git a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c index 9a2b5ce58545..8511c648a15c 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c @@ -208,7 +208,7 @@ static int tvc_probe_pdata(struct platform_device *pdev) ddata->in = in; ddata->connector_type = pdata->connector_type; - ddata->invert_polarity = ddata->invert_polarity; + ddata->invert_polarity = pdata->invert_polarity; dssdev = &ddata->dssdev; dssdev->name = pdata->name; diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c b/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c new file mode 100644 index 000000000000..84a6b3367124 --- /dev/null +++ b/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c @@ -0,0 +1,285 @@ +/* + * OPA362 analog video amplifier with output/power control + * + * Copyright (C) 2014 Golden Delicious Computers + * Author: H. Nikolaus Schaller + * + * based on encoder-tfp410 + * + * Copyright (C) 2013 Texas Instruments + * Author: Tomi Valkeinen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include