diff options
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r-- | drivers/video/via/hw.c | 130 |
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 | ||
1470 | static struct display_timing var_to_timing(const struct fb_var_screeninfo *var) | 1470 | struct 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 | ||
1489 | void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga) | 1491 | void 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 | ||
1761 | static u8 get_sync(struct fb_info *info) | 1748 | static 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 | ||
1847 | int viafb_setmode(int video_bpp, int video_bpp1) | 1834 | int 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 | ||
2024 | int viafb_get_refresh(int hres, int vres, u32 long_refresh) | 2013 | int 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 | ||
2042 | static void device_off(void) | 2031 | static 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*/ | ||
2133 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, | 2121 | void 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 | } |