aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-08-06 21:51:41 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-08-06 21:51:41 -0400
commitebb29fb47e198787b8b47a74cb10334cd9647a9d (patch)
tree25ab6ed861e7ada2f2c063d4e18b4e9bb2edcd9d /drivers/video
parent42edcb162d67e8a88c7b873941c19eab689db272 (diff)
viafb: use information in var for modesetting
This patch starts to use the information in var for modesetting for CRT and DVI devices. This is the right thing as it allows us to use more generic modes than the ones predefined by VIA. We do not yet allow more generic modes as check_var still limits them to the predefined ones but with this patch applied it would be really easy to do so. A problem was VIAs SAMM mode as it has 2 different modes but just one frame buffer device. This is solved by creating a pseudo var which contains enough information to use it for modesetting. Hopefully one day we can use information in var for all modes that do not involve hardware scaling. Well I'd like to say that the chance of regressions is low but it is quite likely that the behaviour in some cases changed especially when SAMM is involved. I hope we made it better than before in particular the DVI frequency check was probably broken before and hopefully works better now. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/via/dvi.c30
-rw-r--r--drivers/video/via/dvi.h3
-rw-r--r--drivers/video/via/hw.c107
-rw-r--r--drivers/video/via/hw.h4
4 files changed, 61 insertions, 83 deletions
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index c7ff5c0e9c7e..9138e517267c 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -172,28 +172,20 @@ 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 */
175void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp, 175void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga)
176 int set_iga)
177{ 176{
178 struct VideoModeTable *rb_mode; 177 struct fb_var_screeninfo dvi_var = *var;
179 struct crt_mode_table *pDviTiming; 178 struct crt_mode_table *rb_mode;
180 unsigned long desirePixelClock, maxPixelClock; 179 int maxPixelClock;
181 pDviTiming = mode->crtc; 180
182 desirePixelClock = pDviTiming->refresh_rate 181 maxPixelClock = viaparinfo->shared->tmds_setting_info.max_pixel_clock;
183 * pDviTiming->crtc.hor_total * pDviTiming->crtc.ver_total 182 if (maxPixelClock && PICOS2KHZ(var->pixclock) / 1000 > maxPixelClock) {
184 / 1000000; 183 rb_mode = viafb_get_best_rb_mode(var->xres, var->yres, 60);
185 maxPixelClock = (unsigned long)viaparinfo->
186 tmds_setting_info->max_pixel_clock;
187
188 DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
189
190 if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
191 rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
192 mode->crtc[0].crtc.ver_addr);
193 if (rb_mode) 184 if (rb_mode)
194 mode = rb_mode; 185 viafb_fill_var_timing_info(&dvi_var, rb_mode);
195 } 186 }
196 viafb_fill_crtc_timing(mode, mode_bpp / 8, set_iga); 187
188 viafb_fill_crtc_timing(&dvi_var, iga);
197} 189}
198 190
199/* Sense DVI Connector */ 191/* Sense DVI Connector */
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
index f473dd010977..e2116aaf797a 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/via/dvi.h
@@ -59,7 +59,6 @@ void viafb_dvi_enable(void);
59bool __devinit viafb_tmds_trasmitter_identify(void); 59bool __devinit viafb_tmds_trasmitter_identify(void);
60void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, 60void __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);
62void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, 62void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga);
63 int set_iga);
64 63
65#endif /* __DVI_H__ */ 64#endif /* __DVI_H__ */
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index d7b9a9f32dee..6845c82db3cb 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1467,49 +1467,40 @@ 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
1470void viafb_fill_crtc_timing(struct VideoModeTable *video_mode, int bpp_byte, 1470static struct display_timing var_to_timing(const struct fb_var_screeninfo *var)
1471 int set_iga)
1472{ 1471{
1473 struct crt_mode_table *crt_table = video_mode->crtc; 1472 struct display_timing timing;
1474 struct display_timing crt_reg; 1473
1475 int i; 1474 timing.hor_addr = var->xres;
1476 int index = 0; 1475 timing.hor_sync_start = timing.hor_addr + var->right_margin;
1477 int h_addr, v_addr; 1476 timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
1478 u32 clock, refresh = viafb_refresh; 1477 timing.hor_total = timing.hor_sync_end + var->left_margin;
1479 1478 timing.hor_blank_start = timing.hor_addr;
1480 if (viafb_SAMM_ON && set_iga == IGA2) 1479 timing.hor_blank_end = timing.hor_total;
1481 refresh = viafb_refresh1; 1480 timing.ver_addr = var->yres;
1482 1481 timing.ver_sync_start = timing.ver_addr + var->lower_margin;
1483 for (i = 0; i < video_mode->mode_array; i++) { 1482 timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
1484 index = i; 1483 timing.ver_total = timing.ver_sync_end + var->upper_margin;
1484 timing.ver_blank_start = timing.ver_addr;
1485 timing.ver_blank_end = timing.ver_total;
1486 return timing;
1487}
1485 1488
1486 if (crt_table[i].refresh_rate == refresh) 1489void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga)
1487 break; 1490{
1488 } 1491 struct display_timing crt_reg = var_to_timing(var);
1489 1492
1490 crt_reg = crt_table[index].crtc; 1493 if (iga == IGA1)
1491 crt_reg.hor_blank_end += crt_reg.hor_blank_start;
1492 crt_reg.hor_sync_end += crt_reg.hor_sync_start;
1493 crt_reg.ver_blank_end += crt_reg.ver_blank_start;
1494 crt_reg.ver_sync_end += crt_reg.ver_sync_start;
1495 h_addr = crt_reg.hor_addr;
1496 v_addr = crt_reg.ver_addr;
1497 if (set_iga == IGA1)
1498 via_set_primary_timing(&crt_reg); 1494 via_set_primary_timing(&crt_reg);
1499 else if (set_iga == IGA2) 1495 else if (iga == IGA2)
1500 via_set_secondary_timing(&crt_reg); 1496 via_set_secondary_timing(&crt_reg);
1501 1497
1502 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); 1498 viafb_load_fetch_count_reg(var->xres, var->bits_per_pixel / 8, iga);
1503 1499 if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266
1504 /* load FIFO */ 1500 && viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)
1505 if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) 1501 viafb_load_FIFO_reg(iga, var->xres, var->yres);
1506 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
1507 viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
1508
1509 clock = crt_reg.hor_total * crt_reg.ver_total
1510 * crt_table[index].refresh_rate;
1511 viafb_set_vclock(clock, set_iga);
1512 1502
1503 viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);
1513} 1504}
1514 1505
1515void __devinit viafb_init_chip_info(int chip_type) 1506void __devinit viafb_init_chip_info(int chip_type)
@@ -1788,6 +1779,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
1788 u8 value, index, mask; 1779 u8 value, index, mask;
1789 struct crt_mode_table *crt_timing; 1780 struct crt_mode_table *crt_timing;
1790 struct crt_mode_table *crt_timing1 = NULL; 1781 struct crt_mode_table *crt_timing1 = NULL;
1782 struct fb_var_screeninfo var2;
1791 1783
1792 device_screen_off(); 1784 device_screen_off();
1793 crt_timing = vmode_tbl->crtc; 1785 crt_timing = vmode_tbl->crtc;
@@ -1894,17 +1886,24 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
1894 1886
1895 /* Clear On Screen */ 1887 /* Clear On Screen */
1896 1888
1889 if (viafb_dual_fb) {
1890 var2 = viafbinfo1->var;
1891 } else if (viafb_SAMM_ON) {
1892 viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
1893 vmode_tbl1->crtc->crtc.hor_addr,
1894 vmode_tbl1->crtc->crtc.ver_addr, viafb_refresh1));
1895 var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
1896 }
1897
1897 /* CRT set mode */ 1898 /* CRT set mode */
1898 if (viafb_CRT_ON) { 1899 if (viafb_CRT_ON) {
1899 if (viafb_SAMM_ON && 1900 if (viaparinfo->shared->iga2_devices & VIA_CRT
1900 viaparinfo->shared->iga2_devices & VIA_CRT) { 1901 && viafb_SAMM_ON)
1901 viafb_fill_crtc_timing(vmode_tbl1, video_bpp1 / 8, 1902 viafb_fill_crtc_timing(&var2, IGA2);
1902 IGA2); 1903 else
1903 } else { 1904 viafb_fill_crtc_timing(&viafbinfo->var,
1904 viafb_fill_crtc_timing(vmode_tbl, video_bpp / 8,
1905 (viaparinfo->shared->iga1_devices & VIA_CRT) 1905 (viaparinfo->shared->iga1_devices & VIA_CRT)
1906 ? IGA1 : IGA2); 1906 ? IGA1 : IGA2);
1907 }
1908 1907
1909 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode 1908 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
1910 to 8 alignment (1368),there is several pixels (2 pixels) 1909 to 8 alignment (1368),there is several pixels (2 pixels)
@@ -1918,22 +1917,12 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
1918 } 1917 }
1919 1918
1920 if (viafb_DVI_ON) { 1919 if (viafb_DVI_ON) {
1921 if (viafb_SAMM_ON && 1920 if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
1922 (viaparinfo->tmds_setting_info->iga_path == IGA2)) { 1921 && viafb_SAMM_ON)
1923 viafb_dvi_set_mode(viafb_get_mode 1922 viafb_dvi_set_mode(&var2, IGA2);
1924 (viaparinfo->tmds_setting_info->h_active, 1923 else
1925 viaparinfo->tmds_setting_info-> 1924 viafb_dvi_set_mode(&viafbinfo->var,
1926 v_active), 1925 viaparinfo->tmds_setting_info->iga_path);
1927 video_bpp1, viaparinfo->
1928 tmds_setting_info->iga_path);
1929 } else {
1930 viafb_dvi_set_mode(viafb_get_mode
1931 (viaparinfo->tmds_setting_info->h_active,
1932 viaparinfo->
1933 tmds_setting_info->v_active),
1934 video_bpp, viaparinfo->
1935 tmds_setting_info->iga_path);
1936 }
1937 } 1926 }
1938 1927
1939 if (viafb_LCD_ON) { 1928 if (viafb_LCD_ON) {
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 5516b025926b..46f65da11e77 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -637,9 +637,7 @@ extern int viafb_LCD_ON;
637extern int viafb_DVI_ON; 637extern int viafb_DVI_ON;
638extern int viafb_hotplug; 638extern int viafb_hotplug;
639 639
640void viafb_fill_crtc_timing(struct VideoModeTable *video_mode, int bpp_byte, 640void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga);
641 int set_iga);
642
643void viafb_set_vclock(u32 CLK, int set_iga); 641void viafb_set_vclock(u32 CLK, int set_iga);
644void viafb_load_reg(int timing_value, int viafb_load_reg_num, 642void viafb_load_reg(int timing_value, int viafb_load_reg_num,
645 struct io_register *reg, 643 struct io_register *reg,