aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r--drivers/video/via/hw.c130
1 files changed, 55 insertions, 75 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 8497727d66de..898590db5e14 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1467,28 +1467,32 @@ 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
1470static struct display_timing var_to_timing(const struct fb_var_screeninfo *var) 1470struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
1471 u16 cxres, u16 cyres)
1471{ 1472{
1472 struct display_timing timing; 1473 struct display_timing timing;
1474 u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
1473 1475
1474 timing.hor_addr = var->xres; 1476 timing.hor_addr = cxres;
1475 timing.hor_sync_start = timing.hor_addr + var->right_margin; 1477 timing.hor_sync_start = timing.hor_addr + var->right_margin + dx;
1476 timing.hor_sync_end = timing.hor_sync_start + var->hsync_len; 1478 timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
1477 timing.hor_total = timing.hor_sync_end + var->left_margin; 1479 timing.hor_total = timing.hor_sync_end + var->left_margin + dx;
1478 timing.hor_blank_start = timing.hor_addr; 1480 timing.hor_blank_start = timing.hor_addr + dx;
1479 timing.hor_blank_end = timing.hor_total; 1481 timing.hor_blank_end = timing.hor_total - dx;
1480 timing.ver_addr = var->yres; 1482 timing.ver_addr = cyres;
1481 timing.ver_sync_start = timing.ver_addr + var->lower_margin; 1483 timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy;
1482 timing.ver_sync_end = timing.ver_sync_start + var->vsync_len; 1484 timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
1483 timing.ver_total = timing.ver_sync_end + var->upper_margin; 1485 timing.ver_total = timing.ver_sync_end + var->upper_margin + dy;
1484 timing.ver_blank_start = timing.ver_addr; 1486 timing.ver_blank_start = timing.ver_addr + dy;
1485 timing.ver_blank_end = timing.ver_total; 1487 timing.ver_blank_end = timing.ver_total - dy;
1486 return timing; 1488 return timing;
1487} 1489}
1488 1490
1489void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga) 1491void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
1492 u16 cxres, u16 cyres, int iga)
1490{ 1493{
1491 struct display_timing crt_reg = var_to_timing(var); 1494 struct display_timing crt_reg = var_to_timing(var,
1495 cxres ? cxres : var->xres, cyres ? cyres : var->yres);
1492 1496
1493 if (iga == IGA1) 1497 if (iga == IGA1)
1494 via_set_primary_timing(&crt_reg); 1498 via_set_primary_timing(&crt_reg);
@@ -1526,13 +1530,6 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
1526 if (flag == 0) { 1530 if (flag == 0) {
1527 viaparinfo->tmds_setting_info->h_active = hres; 1531 viaparinfo->tmds_setting_info->h_active = hres;
1528 viaparinfo->tmds_setting_info->v_active = vres; 1532 viaparinfo->tmds_setting_info->v_active = vres;
1529
1530 viaparinfo->lvds_setting_info->h_active = hres;
1531 viaparinfo->lvds_setting_info->v_active = vres;
1532 viaparinfo->lvds_setting_info->bpp = bpp;
1533 viaparinfo->lvds_setting_info2->h_active = hres;
1534 viaparinfo->lvds_setting_info2->v_active = vres;
1535 viaparinfo->lvds_setting_info2->bpp = bpp;
1536 } else { 1533 } else {
1537 1534
1538 if (viaparinfo->tmds_setting_info->iga_path == IGA2) { 1535 if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
@@ -1540,16 +1537,6 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
1540 viaparinfo->tmds_setting_info->v_active = vres; 1537 viaparinfo->tmds_setting_info->v_active = vres;
1541 } 1538 }
1542 1539
1543 if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
1544 viaparinfo->lvds_setting_info->h_active = hres;
1545 viaparinfo->lvds_setting_info->v_active = vres;
1546 viaparinfo->lvds_setting_info->bpp = bpp;
1547 }
1548 if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
1549 viaparinfo->lvds_setting_info2->h_active = hres;
1550 viaparinfo->lvds_setting_info2->v_active = vres;
1551 viaparinfo->lvds_setting_info2->bpp = bpp;
1552 }
1553 } 1540 }
1554} 1541}
1555 1542
@@ -1758,13 +1745,13 @@ static void set_display_channel(void)
1758 } 1745 }
1759} 1746}
1760 1747
1761static u8 get_sync(struct fb_info *info) 1748static u8 get_sync(struct fb_var_screeninfo *var)
1762{ 1749{
1763 u8 polarity = 0; 1750 u8 polarity = 0;
1764 1751
1765 if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) 1752 if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
1766 polarity |= VIA_HSYNC_NEGATIVE; 1753 polarity |= VIA_HSYNC_NEGATIVE;
1767 if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT)) 1754 if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
1768 polarity |= VIA_VSYNC_NEGATIVE; 1755 polarity |= VIA_VSYNC_NEGATIVE;
1769 return polarity; 1756 return polarity;
1770} 1757}
@@ -1844,9 +1831,9 @@ static void hw_init(void)
1844 load_fix_bit_crtc_reg(); 1831 load_fix_bit_crtc_reg();
1845} 1832}
1846 1833
1847int viafb_setmode(int video_bpp, int video_bpp1) 1834int viafb_setmode(void)
1848{ 1835{
1849 int j; 1836 int j, cxres = 0, cyres = 0;
1850 int port; 1837 int port;
1851 u32 devices = viaparinfo->shared->iga1_devices 1838 u32 devices = viaparinfo->shared->iga1_devices
1852 | viaparinfo->shared->iga2_devices; 1839 | viaparinfo->shared->iga2_devices;
@@ -1895,6 +1882,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
1895 } else if (viafb_SAMM_ON) { 1882 } else if (viafb_SAMM_ON) {
1896 viafb_fill_var_timing_info(&var2, viafb_get_best_mode( 1883 viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
1897 viafb_second_xres, viafb_second_yres, viafb_refresh1)); 1884 viafb_second_xres, viafb_second_yres, viafb_refresh1));
1885 cxres = viafbinfo->var.xres;
1886 cyres = viafbinfo->var.yres;
1898 var2.bits_per_pixel = viafbinfo->var.bits_per_pixel; 1887 var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
1899 } 1888 }
1900 1889
@@ -1902,9 +1891,9 @@ int viafb_setmode(int video_bpp, int video_bpp1)
1902 if (viafb_CRT_ON) { 1891 if (viafb_CRT_ON) {
1903 if (viaparinfo->shared->iga2_devices & VIA_CRT 1892 if (viaparinfo->shared->iga2_devices & VIA_CRT
1904 && viafb_SAMM_ON) 1893 && viafb_SAMM_ON)
1905 viafb_fill_crtc_timing(&var2, IGA2); 1894 viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2);
1906 else 1895 else
1907 viafb_fill_crtc_timing(&viafbinfo->var, 1896 viafb_fill_crtc_timing(&viafbinfo->var, 0, 0,
1908 (viaparinfo->shared->iga1_devices & VIA_CRT) 1897 (viaparinfo->shared->iga1_devices & VIA_CRT)
1909 ? IGA1 : IGA2); 1898 ? IGA1 : IGA2);
1910 1899
@@ -1922,17 +1911,17 @@ int viafb_setmode(int video_bpp, int video_bpp1)
1922 if (viafb_DVI_ON) { 1911 if (viafb_DVI_ON) {
1923 if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2 1912 if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
1924 && viafb_SAMM_ON) 1913 && viafb_SAMM_ON)
1925 viafb_dvi_set_mode(&var2, IGA2); 1914 viafb_dvi_set_mode(&var2, cxres, cyres, IGA2);
1926 else 1915 else
1927 viafb_dvi_set_mode(&viafbinfo->var, 1916 viafb_dvi_set_mode(&viafbinfo->var, 0, 0,
1928 viaparinfo->tmds_setting_info->iga_path); 1917 viaparinfo->tmds_setting_info->iga_path);
1929 } 1918 }
1930 1919
1931 if (viafb_LCD_ON) { 1920 if (viafb_LCD_ON) {
1932 if (viafb_SAMM_ON && 1921 if (viafb_SAMM_ON &&
1933 (viaparinfo->lvds_setting_info->iga_path == IGA2)) { 1922 (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
1934 viaparinfo->lvds_setting_info->bpp = video_bpp1; 1923 viafb_lcd_set_mode(&var2, cxres, cyres,
1935 viafb_lcd_set_mode(viaparinfo->lvds_setting_info, 1924 viaparinfo->lvds_setting_info,
1936 &viaparinfo->chip_info->lvds_chip_info); 1925 &viaparinfo->chip_info->lvds_chip_info);
1937 } else { 1926 } else {
1938 /* IGA1 doesn't have LCD scaling, so set it center. */ 1927 /* IGA1 doesn't have LCD scaling, so set it center. */
@@ -1940,16 +1929,16 @@ int viafb_setmode(int video_bpp, int video_bpp1)
1940 viaparinfo->lvds_setting_info->display_method = 1929 viaparinfo->lvds_setting_info->display_method =
1941 LCD_CENTERING; 1930 LCD_CENTERING;
1942 } 1931 }
1943 viaparinfo->lvds_setting_info->bpp = video_bpp; 1932 viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
1944 viafb_lcd_set_mode(viaparinfo->lvds_setting_info, 1933 viaparinfo->lvds_setting_info,
1945 &viaparinfo->chip_info->lvds_chip_info); 1934 &viaparinfo->chip_info->lvds_chip_info);
1946 } 1935 }
1947 } 1936 }
1948 if (viafb_LCD2_ON) { 1937 if (viafb_LCD2_ON) {
1949 if (viafb_SAMM_ON && 1938 if (viafb_SAMM_ON &&
1950 (viaparinfo->lvds_setting_info2->iga_path == IGA2)) { 1939 (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
1951 viaparinfo->lvds_setting_info2->bpp = video_bpp1; 1940 viafb_lcd_set_mode(&var2, cxres, cyres,
1952 viafb_lcd_set_mode(viaparinfo->lvds_setting_info2, 1941 viaparinfo->lvds_setting_info2,
1953 &viaparinfo->chip_info->lvds_chip_info2); 1942 &viaparinfo->chip_info->lvds_chip_info2);
1954 } else { 1943 } else {
1955 /* IGA1 doesn't have LCD scaling, so set it center. */ 1944 /* IGA1 doesn't have LCD scaling, so set it center. */
@@ -1957,8 +1946,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
1957 viaparinfo->lvds_setting_info2->display_method = 1946 viaparinfo->lvds_setting_info2->display_method =
1958 LCD_CENTERING; 1947 LCD_CENTERING;
1959 } 1948 }
1960 viaparinfo->lvds_setting_info2->bpp = video_bpp; 1949 viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
1961 viafb_lcd_set_mode(viaparinfo->lvds_setting_info2, 1950 viaparinfo->lvds_setting_info2,
1962 &viaparinfo->chip_info->lvds_chip_info2); 1951 &viaparinfo->chip_info->lvds_chip_info2);
1963 } 1952 }
1964 } 1953 }
@@ -1971,7 +1960,7 @@ int viafb_setmode(int video_bpp, int video_bpp1)
1971 if (!viafb_hotplug) { 1960 if (!viafb_hotplug) {
1972 viafb_hotplug_Xres = viafbinfo->var.xres; 1961 viafb_hotplug_Xres = viafbinfo->var.xres;
1973 viafb_hotplug_Yres = viafbinfo->var.yres; 1962 viafb_hotplug_Yres = viafbinfo->var.yres;
1974 viafb_hotplug_bpp = video_bpp; 1963 viafb_hotplug_bpp = viafbinfo->var.bits_per_pixel;
1975 viafb_hotplug_refresh = viafb_refresh; 1964 viafb_hotplug_refresh = viafb_refresh;
1976 1965
1977 if (viafb_DVI_ON) 1966 if (viafb_DVI_ON)
@@ -1980,13 +1969,13 @@ int viafb_setmode(int video_bpp, int video_bpp1)
1980 viafb_DeviceStatus = CRT_Device; 1969 viafb_DeviceStatus = CRT_Device;
1981 } 1970 }
1982 device_on(); 1971 device_on();
1983 if (!viafb_dual_fb) 1972 if (!viafb_SAMM_ON)
1984 via_set_sync_polarity(devices, get_sync(viafbinfo)); 1973 via_set_sync_polarity(devices, get_sync(&viafbinfo->var));
1985 else { 1974 else {
1986 via_set_sync_polarity(viaparinfo->shared->iga1_devices, 1975 via_set_sync_polarity(viaparinfo->shared->iga1_devices,
1987 get_sync(viafbinfo)); 1976 get_sync(&viafbinfo->var));
1988 via_set_sync_polarity(viaparinfo->shared->iga2_devices, 1977 via_set_sync_polarity(viaparinfo->shared->iga2_devices,
1989 get_sync(viafbinfo1)); 1978 get_sync(&var2));
1990 } 1979 }
1991 1980
1992 clock.set_engine_pll_state(VIA_STATE_ON); 1981 clock.set_engine_pll_state(VIA_STATE_ON);
@@ -2023,20 +2012,20 @@ int viafb_setmode(int video_bpp, int video_bpp1)
2023 2012
2024int viafb_get_refresh(int hres, int vres, u32 long_refresh) 2013int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2025{ 2014{
2026 struct crt_mode_table *best; 2015 const struct fb_videomode *best;
2027 2016
2028 best = viafb_get_best_mode(hres, vres, long_refresh); 2017 best = viafb_get_best_mode(hres, vres, long_refresh);
2029 if (!best) 2018 if (!best)
2030 return 60; 2019 return 60;
2031 2020
2032 if (abs(best->refresh_rate - long_refresh) > 3) { 2021 if (abs(best->refresh - long_refresh) > 3) {
2033 if (hres == 1200 && vres == 900) 2022 if (hres == 1200 && vres == 900)
2034 return 49; /* OLPC DCON only supports 50 Hz */ 2023 return 49; /* OLPC DCON only supports 50 Hz */
2035 else 2024 else
2036 return 60; 2025 return 60;
2037 } 2026 }
2038 2027
2039 return best->refresh_rate; 2028 return best->refresh;
2040} 2029}
2041 2030
2042static void device_off(void) 2031static void device_off(void)
@@ -2129,26 +2118,17 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2129 } 2118 }
2130} 2119}
2131 2120
2132/*According var's xres, yres fill var's other timing information*/
2133void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, 2121void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
2134 struct crt_mode_table *mode) 2122 const struct fb_videomode *mode)
2135{ 2123{
2136 struct display_timing crt_reg; 2124 var->pixclock = mode->pixclock;
2137 2125 var->xres = mode->xres;
2138 crt_reg = mode->crtc; 2126 var->yres = mode->yres;
2139 var->pixclock = 1000000000 / (crt_reg.hor_total * crt_reg.ver_total) 2127 var->left_margin = mode->left_margin;
2140 * 1000 / mode->refresh_rate; 2128 var->right_margin = mode->right_margin;
2141 var->left_margin = 2129 var->hsync_len = mode->hsync_len;
2142 crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end); 2130 var->upper_margin = mode->upper_margin;
2143 var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr; 2131 var->lower_margin = mode->lower_margin;
2144 var->hsync_len = crt_reg.hor_sync_end; 2132 var->vsync_len = mode->vsync_len;
2145 var->upper_margin = 2133 var->sync = mode->sync;
2146 crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
2147 var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
2148 var->vsync_len = crt_reg.ver_sync_end;
2149 var->sync = 0;
2150 if (mode->h_sync_polarity == POSITIVE)
2151 var->sync |= FB_SYNC_HOR_HIGH_ACT;
2152 if (mode->v_sync_polarity == POSITIVE)
2153 var->sync |= FB_SYNC_VERT_HIGH_ACT;
2154} 2134}