diff options
author | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2011-10-19 16:32:50 -0400 |
---|---|---|
committer | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2012-02-10 14:28:39 -0500 |
commit | 532f9169db21fbffd07cc44075c7ea1859c07806 (patch) | |
tree | 2d8a5eb0e44592f1ee91da056d86acff9085de30 /drivers/video/via | |
parent | 561c9079ea1de24f8d49c73391811c547d1b2636 (diff) |
viafb: make single framebuffer multiple adapter mode work
This patch implementes this mode (viafb_SAMM_ON set and
viafb_dual_fb not set) in a useful way for CRT and DVI devices.
The same content is shown on both devices in different video modes.
The first (primary) resolution must not be bigger than the secondary
one and determines the visible region. The same content is shown
centered on the secondary output.
Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers/video/via')
-rw-r--r-- | drivers/video/via/dvi.c | 5 | ||||
-rw-r--r-- | drivers/video/via/dvi.h | 3 | ||||
-rw-r--r-- | drivers/video/via/hw.c | 41 | ||||
-rw-r--r-- | drivers/video/via/hw.h | 3 |
4 files changed, 30 insertions, 22 deletions
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 9138e517267c..3312c81e861c 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c | |||
@@ -172,7 +172,8 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | /* DVI Set Mode */ | 174 | /* DVI Set Mode */ |
175 | void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga) | 175 | void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, |
176 | u16 cxres, u16 cyres, int iga) | ||
176 | { | 177 | { |
177 | struct fb_var_screeninfo dvi_var = *var; | 178 | struct fb_var_screeninfo dvi_var = *var; |
178 | struct crt_mode_table *rb_mode; | 179 | struct crt_mode_table *rb_mode; |
@@ -185,7 +186,7 @@ void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga) | |||
185 | viafb_fill_var_timing_info(&dvi_var, rb_mode); | 186 | viafb_fill_var_timing_info(&dvi_var, rb_mode); |
186 | } | 187 | } |
187 | 188 | ||
188 | viafb_fill_crtc_timing(&dvi_var, iga); | 189 | viafb_fill_crtc_timing(&dvi_var, cxres, cyres, iga); |
189 | } | 190 | } |
190 | 191 | ||
191 | /* Sense DVI Connector */ | 192 | /* Sense DVI Connector */ |
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index e2116aaf797a..db757850c216 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h | |||
@@ -59,6 +59,7 @@ void viafb_dvi_enable(void); | |||
59 | bool __devinit viafb_tmds_trasmitter_identify(void); | 59 | bool __devinit viafb_tmds_trasmitter_identify(void); |
60 | void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, | 60 | void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, |
61 | struct tmds_setting_information *tmds_setting); | 61 | struct tmds_setting_information *tmds_setting); |
62 | void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga); | 62 | void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, |
63 | u16 cxres, u16 cyres, int iga); | ||
63 | 64 | ||
64 | #endif /* __DVI_H__ */ | 65 | #endif /* __DVI_H__ */ |
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 399d50754c43..e8725c5235c8 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
@@ -1467,28 +1467,31 @@ void viafb_set_vclock(u32 clk, int set_iga) | |||
1467 | via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ | 1467 | via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ |
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | static struct display_timing var_to_timing(const struct fb_var_screeninfo *var) | 1470 | static struct display_timing var_to_timing(const struct fb_var_screeninfo *var, u16 cxres, u16 cyres) |
1471 | { | 1471 | { |
1472 | struct display_timing timing; | 1472 | struct display_timing timing; |
1473 | u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2; | ||
1473 | 1474 | ||
1474 | timing.hor_addr = var->xres; | 1475 | timing.hor_addr = cxres; |
1475 | timing.hor_sync_start = timing.hor_addr + var->right_margin; | 1476 | timing.hor_sync_start = timing.hor_addr + var->right_margin + dx; |
1476 | timing.hor_sync_end = timing.hor_sync_start + var->hsync_len; | 1477 | timing.hor_sync_end = timing.hor_sync_start + var->hsync_len; |
1477 | timing.hor_total = timing.hor_sync_end + var->left_margin; | 1478 | timing.hor_total = timing.hor_sync_end + var->left_margin + dx; |
1478 | timing.hor_blank_start = timing.hor_addr; | 1479 | timing.hor_blank_start = timing.hor_addr + dx; |
1479 | timing.hor_blank_end = timing.hor_total; | 1480 | timing.hor_blank_end = timing.hor_total - dy; |
1480 | timing.ver_addr = var->yres; | 1481 | timing.ver_addr = cyres; |
1481 | timing.ver_sync_start = timing.ver_addr + var->lower_margin; | 1482 | timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy; |
1482 | timing.ver_sync_end = timing.ver_sync_start + var->vsync_len; | 1483 | timing.ver_sync_end = timing.ver_sync_start + var->vsync_len; |
1483 | timing.ver_total = timing.ver_sync_end + var->upper_margin; | 1484 | timing.ver_total = timing.ver_sync_end + var->upper_margin + dy; |
1484 | timing.ver_blank_start = timing.ver_addr; | 1485 | timing.ver_blank_start = timing.ver_addr + dy; |
1485 | timing.ver_blank_end = timing.ver_total; | 1486 | timing.ver_blank_end = timing.ver_total - dy; |
1486 | return timing; | 1487 | return timing; |
1487 | } | 1488 | } |
1488 | 1489 | ||
1489 | void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga) | 1490 | void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, |
1491 | u16 cxres, u16 cyres, int iga) | ||
1490 | { | 1492 | { |
1491 | struct display_timing crt_reg = var_to_timing(var); | 1493 | struct display_timing crt_reg = var_to_timing(var, |
1494 | cxres ? cxres : var->xres, cyres ? cyres : var->yres); | ||
1492 | 1495 | ||
1493 | if (iga == IGA1) | 1496 | if (iga == IGA1) |
1494 | via_set_primary_timing(&crt_reg); | 1497 | via_set_primary_timing(&crt_reg); |
@@ -1842,7 +1845,7 @@ static void hw_init(void) | |||
1842 | 1845 | ||
1843 | int viafb_setmode(int video_bpp, int video_bpp1) | 1846 | int viafb_setmode(int video_bpp, int video_bpp1) |
1844 | { | 1847 | { |
1845 | int j; | 1848 | int j, cxres = 0, cyres = 0; |
1846 | int port; | 1849 | int port; |
1847 | u32 devices = viaparinfo->shared->iga1_devices | 1850 | u32 devices = viaparinfo->shared->iga1_devices |
1848 | | viaparinfo->shared->iga2_devices; | 1851 | | viaparinfo->shared->iga2_devices; |
@@ -1891,6 +1894,8 @@ int viafb_setmode(int video_bpp, int video_bpp1) | |||
1891 | } else if (viafb_SAMM_ON) { | 1894 | } else if (viafb_SAMM_ON) { |
1892 | viafb_fill_var_timing_info(&var2, viafb_get_best_mode( | 1895 | viafb_fill_var_timing_info(&var2, viafb_get_best_mode( |
1893 | viafb_second_xres, viafb_second_yres, viafb_refresh1)); | 1896 | viafb_second_xres, viafb_second_yres, viafb_refresh1)); |
1897 | cxres = viafbinfo->var.xres; | ||
1898 | cyres = viafbinfo->var.yres; | ||
1894 | var2.bits_per_pixel = viafbinfo->var.bits_per_pixel; | 1899 | var2.bits_per_pixel = viafbinfo->var.bits_per_pixel; |
1895 | } | 1900 | } |
1896 | 1901 | ||
@@ -1898,9 +1903,9 @@ int viafb_setmode(int video_bpp, int video_bpp1) | |||
1898 | if (viafb_CRT_ON) { | 1903 | if (viafb_CRT_ON) { |
1899 | if (viaparinfo->shared->iga2_devices & VIA_CRT | 1904 | if (viaparinfo->shared->iga2_devices & VIA_CRT |
1900 | && viafb_SAMM_ON) | 1905 | && viafb_SAMM_ON) |
1901 | viafb_fill_crtc_timing(&var2, IGA2); | 1906 | viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2); |
1902 | else | 1907 | else |
1903 | viafb_fill_crtc_timing(&viafbinfo->var, | 1908 | viafb_fill_crtc_timing(&viafbinfo->var, 0, 0, |
1904 | (viaparinfo->shared->iga1_devices & VIA_CRT) | 1909 | (viaparinfo->shared->iga1_devices & VIA_CRT) |
1905 | ? IGA1 : IGA2); | 1910 | ? IGA1 : IGA2); |
1906 | 1911 | ||
@@ -1918,9 +1923,9 @@ int viafb_setmode(int video_bpp, int video_bpp1) | |||
1918 | if (viafb_DVI_ON) { | 1923 | if (viafb_DVI_ON) { |
1919 | if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2 | 1924 | if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2 |
1920 | && viafb_SAMM_ON) | 1925 | && viafb_SAMM_ON) |
1921 | viafb_dvi_set_mode(&var2, IGA2); | 1926 | viafb_dvi_set_mode(&var2, cxres, cyres, IGA2); |
1922 | else | 1927 | else |
1923 | viafb_dvi_set_mode(&viafbinfo->var, | 1928 | viafb_dvi_set_mode(&viafbinfo->var, 0, 0, |
1924 | viaparinfo->tmds_setting_info->iga_path); | 1929 | viaparinfo->tmds_setting_info->iga_path); |
1925 | } | 1930 | } |
1926 | 1931 | ||
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 4db5b6e8d8d0..f8129e49aa2c 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h | |||
@@ -637,7 +637,8 @@ extern int viafb_LCD_ON; | |||
637 | extern int viafb_DVI_ON; | 637 | extern int viafb_DVI_ON; |
638 | extern int viafb_hotplug; | 638 | extern int viafb_hotplug; |
639 | 639 | ||
640 | void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga); | 640 | void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, |
641 | u16 cxres, u16 cyres, int iga); | ||
641 | void viafb_set_vclock(u32 CLK, int set_iga); | 642 | void viafb_set_vclock(u32 CLK, int set_iga); |
642 | void viafb_load_reg(int timing_value, int viafb_load_reg_num, | 643 | void viafb_load_reg(int timing_value, int viafb_load_reg_num, |
643 | struct io_register *reg, | 644 | struct io_register *reg, |