aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/via/hw.c45
-rw-r--r--drivers/video/via/hw.h4
-rw-r--r--drivers/video/via/viafbdev.c24
-rw-r--r--drivers/video/via/viamode.c56
-rw-r--r--drivers/video/via/viamode.h2
5 files changed, 70 insertions, 61 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index c5e7833a5ae5..5e69c203163c 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -2035,40 +2035,24 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2035 2035
2036int viafb_get_pixclock(int hres, int vres, int vmode_refresh) 2036int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
2037{ 2037{
2038 int i;
2039 struct crt_mode_table *best; 2038 struct crt_mode_table *best;
2040 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2041 2039
2042 if (!vmode) 2040 best = viafb_get_best_mode(hres, vres, vmode_refresh);
2041 if (!best)
2043 return RES_640X480_60HZ_PIXCLOCK; 2042 return RES_640X480_60HZ_PIXCLOCK;
2044 2043
2045 best = &vmode->crtc[0];
2046 for (i = 1; i < vmode->mode_array; i++) {
2047 if (abs(vmode->crtc[i].refresh_rate - vmode_refresh)
2048 < abs(best->refresh_rate - vmode_refresh))
2049 best = &vmode->crtc[i];
2050 }
2051
2052 return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total) 2044 return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total)
2053 * 1000 / best->refresh_rate; 2045 * 1000 / best->refresh_rate;
2054} 2046}
2055 2047
2056int viafb_get_refresh(int hres, int vres, u32 long_refresh) 2048int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2057{ 2049{
2058 int i;
2059 struct crt_mode_table *best; 2050 struct crt_mode_table *best;
2060 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2061 2051
2062 if (!vmode) 2052 best = viafb_get_best_mode(hres, vres, long_refresh);
2053 if (!best)
2063 return 60; 2054 return 60;
2064 2055
2065 best = &vmode->crtc[0];
2066 for (i = 1; i < vmode->mode_array; i++) {
2067 if (abs(vmode->crtc[i].refresh_rate - long_refresh)
2068 < abs(best->refresh_rate - long_refresh))
2069 best = &vmode->crtc[i];
2070 }
2071
2072 if (abs(best->refresh_rate - long_refresh) > 3) { 2056 if (abs(best->refresh_rate - long_refresh) > 3) {
2073 if (hres == 1200 && vres == 900) 2057 if (hres == 1200 && vres == 900)
2074 return 49; /* OLPC DCON only supports 50 Hz */ 2058 return 49; /* OLPC DCON only supports 50 Hz */
@@ -2170,21 +2154,14 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2170} 2154}
2171 2155
2172/*According var's xres, yres fill var's other timing information*/ 2156/*According var's xres, yres fill var's other timing information*/
2173void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 2157void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
2174 struct VideoModeTable *vmode_tbl) 2158 struct crt_mode_table *mode)
2175{ 2159{
2176 struct crt_mode_table *crt_timing = NULL;
2177 struct display_timing crt_reg; 2160 struct display_timing crt_reg;
2178 int i = 0, index = 0;
2179 crt_timing = vmode_tbl->crtc;
2180 for (i = 0; i < vmode_tbl->mode_array; i++) {
2181 index = i;
2182 if (crt_timing[i].refresh_rate == refresh)
2183 break;
2184 }
2185 2161
2186 crt_reg = crt_timing[index].crtc; 2162 crt_reg = mode->crtc;
2187 var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh); 2163 var->pixclock = viafb_get_pixclock(var->xres, var->yres,
2164 mode->refresh_rate);
2188 var->left_margin = 2165 var->left_margin =
2189 crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end); 2166 crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
2190 var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr; 2167 var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
@@ -2194,8 +2171,8 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
2194 var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; 2171 var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
2195 var->vsync_len = crt_reg.ver_sync_end; 2172 var->vsync_len = crt_reg.ver_sync_end;
2196 var->sync = 0; 2173 var->sync = 0;
2197 if (crt_timing[index].h_sync_polarity == POSITIVE) 2174 if (mode->h_sync_polarity == POSITIVE)
2198 var->sync |= FB_SYNC_HOR_HIGH_ACT; 2175 var->sync |= FB_SYNC_HOR_HIGH_ACT;
2199 if (crt_timing[index].v_sync_polarity == POSITIVE) 2176 if (mode->v_sync_polarity == POSITIVE)
2200 var->sync |= FB_SYNC_VERT_HIGH_ACT; 2177 var->sync |= FB_SYNC_VERT_HIGH_ACT;
2201} 2178}
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 1fd8d98f7395..3b7e1496657b 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -661,8 +661,8 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
661 661
662int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, 662int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
663 struct VideoModeTable *vmode_tbl1, int video_bpp1); 663 struct VideoModeTable *vmode_tbl1, int video_bpp1);
664void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 664void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
665 struct VideoModeTable *vmode_tbl); 665 struct crt_mode_table *mode);
666void __devinit viafb_init_chip_info(int chip_type); 666void __devinit viafb_init_chip_info(int chip_type);
667void __devinit viafb_init_dac(int set_iga); 667void __devinit viafb_init_dac(int set_iga);
668int viafb_get_pixclock(int hres, int vres, int vmode_refresh); 668int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 3eaf607bdf48..0c0ef9568cf3 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -201,7 +201,6 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
201 struct fb_info *info) 201 struct fb_info *info)
202{ 202{
203 int depth, refresh; 203 int depth, refresh;
204 struct VideoModeTable *vmode_entry;
205 struct viafb_par *ppar = info->par; 204 struct viafb_par *ppar = info->par;
206 u32 line; 205 u32 line;
207 206
@@ -211,8 +210,10 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
211 if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) 210 if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
212 return -EINVAL; 211 return -EINVAL;
213 212
214 vmode_entry = viafb_get_mode(var->xres, var->yres); 213 /* the refresh rate is not important here, as we only want to know
215 if (!vmode_entry) { 214 * whether the resolution exists
215 */
216 if (!viafb_get_best_mode(var->xres, var->yres, 60)) {
216 DEBUG_MSG(KERN_INFO 217 DEBUG_MSG(KERN_INFO
217 "viafb: Mode %dx%dx%d not supported!!\n", 218 "viafb: Mode %dx%dx%d not supported!!\n",
218 var->xres, var->yres, var->bits_per_pixel); 219 var->xres, var->yres, var->bits_per_pixel);
@@ -254,7 +255,8 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
254 get_var_refresh(var)); 255 get_var_refresh(var));
255 256
256 /* Adjust var according to our driver's own table */ 257 /* Adjust var according to our driver's own table */
257 viafb_fill_var_timing_info(var, refresh, vmode_entry); 258 viafb_fill_var_timing_info(var,
259 viafb_get_best_mode(var->xres, var->yres, refresh));
258 if (var->accel_flags & FB_ACCELF_TEXT && 260 if (var->accel_flags & FB_ACCELF_TEXT &&
259 !ppar->shared->vdev->engine_mmio) 261 !ppar->shared->vdev->engine_mmio)
260 var->accel_flags = 0; 262 var->accel_flags = 0;
@@ -1816,9 +1818,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1816 default_var.xres_virtual = default_xres; 1818 default_var.xres_virtual = default_xres;
1817 default_var.yres_virtual = default_yres; 1819 default_var.yres_virtual = default_yres;
1818 default_var.bits_per_pixel = viafb_bpp; 1820 default_var.bits_per_pixel = viafb_bpp;
1819 viafb_fill_var_timing_info(&default_var, viafb_get_refresh( 1821 viafb_fill_var_timing_info(&default_var, viafb_get_best_mode(
1820 default_var.xres, default_var.yres, viafb_refresh), 1822 default_var.xres, default_var.yres, viafb_refresh));
1821 viafb_get_mode(default_var.xres, default_var.yres));
1822 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); 1823 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
1823 viafbinfo->var = default_var; 1824 viafbinfo->var = default_var;
1824 1825
@@ -1857,9 +1858,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1857 default_var.xres_virtual = viafb_second_xres; 1858 default_var.xres_virtual = viafb_second_xres;
1858 default_var.yres_virtual = viafb_second_yres; 1859 default_var.yres_virtual = viafb_second_yres;
1859 default_var.bits_per_pixel = viafb_bpp1; 1860 default_var.bits_per_pixel = viafb_bpp1;
1860 viafb_fill_var_timing_info(&default_var, viafb_get_refresh( 1861 viafb_fill_var_timing_info(&default_var, viafb_get_best_mode(
1861 default_var.xres, default_var.yres, viafb_refresh1), 1862 default_var.xres, default_var.yres, viafb_refresh1));
1862 viafb_get_mode(default_var.xres, default_var.yres));
1863 1863
1864 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); 1864 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
1865 viafb_check_var(&default_var, viafbinfo1); 1865 viafb_check_var(&default_var, viafbinfo1);
@@ -2032,9 +2032,9 @@ int __init viafb_init(void)
2032 return r; 2032 return r;
2033#endif 2033#endif
2034 if (parse_mode(viafb_mode, &dummy_x, &dummy_y) 2034 if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
2035 || !viafb_get_mode(dummy_x, dummy_y) 2035 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh)
2036 || parse_mode(viafb_mode1, &dummy_x, &dummy_y) 2036 || parse_mode(viafb_mode1, &dummy_x, &dummy_y)
2037 || !viafb_get_mode(dummy_x, dummy_y) 2037 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1)
2038 || viafb_bpp < 0 || viafb_bpp > 32 2038 || viafb_bpp < 0 || viafb_bpp > 32
2039 || viafb_bpp1 < 0 || viafb_bpp1 > 32 2039 || viafb_bpp1 < 0 || viafb_bpp1 > 32
2040 || parse_active_dev()) 2040 || parse_active_dev())
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
index 8a9f4fcb50e9..88096e5fa077 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/via/viamode.c
@@ -863,26 +863,56 @@ int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs);
863int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table); 863int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table);
864 864
865 865
866struct VideoModeTable *viafb_get_mode(int hres, int vres) 866static struct VideoModeTable *get_modes(struct VideoModeTable *vmt, int n,
867 int hres, int vres)
867{ 868{
868 u32 i; 869 int i;
869 for (i = 0; i < ARRAY_SIZE(viafb_modes); i++) 870
870 if (viafb_modes[i].mode_array && 871 for (i = 0; i < n; i++)
871 viafb_modes[i].crtc[0].crtc.hor_addr == hres && 872 if (vmt[i].mode_array &&
872 viafb_modes[i].crtc[0].crtc.ver_addr == vres) 873 vmt[i].crtc[0].crtc.hor_addr == hres &&
874 vmt[i].crtc[0].crtc.ver_addr == vres)
873 return &viafb_modes[i]; 875 return &viafb_modes[i];
874 876
875 return NULL; 877 return NULL;
876} 878}
877 879
880static struct crt_mode_table *get_best_mode(struct VideoModeTable *vmt,
881 int refresh)
882{
883 struct crt_mode_table *best;
884 int i;
885
886 if (!vmt)
887 return NULL;
888
889 best = &vmt->crtc[0];
890 for (i = 1; i < vmt->mode_array; i++) {
891 if (abs(vmt->crtc[i].refresh_rate - refresh)
892 < abs(best->refresh_rate - refresh))
893 best = &vmt->crtc[i];
894 }
895
896 return best;
897}
898
899struct VideoModeTable *viafb_get_mode(int hres, int vres)
900{
901 return get_modes(viafb_modes, ARRAY_SIZE(viafb_modes), hres, vres);
902}
903
904struct crt_mode_table *viafb_get_best_mode(int hres, int vres, int refresh)
905{
906 return get_best_mode(viafb_get_mode(hres, vres), refresh);
907}
908
878struct VideoModeTable *viafb_get_rb_mode(int hres, int vres) 909struct VideoModeTable *viafb_get_rb_mode(int hres, int vres)
879{ 910{
880 u32 i; 911 return get_modes(viafb_rb_modes, ARRAY_SIZE(viafb_rb_modes), hres,
881 for (i = 0; i < ARRAY_SIZE(viafb_rb_modes); i++) 912 vres);
882 if (viafb_rb_modes[i].mode_array && 913}
883 viafb_rb_modes[i].crtc[0].crtc.hor_addr == hres &&
884 viafb_rb_modes[i].crtc[0].crtc.ver_addr == vres)
885 return &viafb_rb_modes[i];
886 914
887 return NULL; 915struct crt_mode_table *viafb_get_best_rb_mode(int hres, int vres, int refresh)
916{
917 return get_best_mode(viafb_get_rb_mode(hres, vres), refresh);
888} 918}
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
index 3751289eb450..0396581b9775 100644
--- a/drivers/video/via/viamode.h
+++ b/drivers/video/via/viamode.h
@@ -61,6 +61,8 @@ extern struct patch_table res_patch_table[];
61extern struct VPITTable VPIT; 61extern struct VPITTable VPIT;
62 62
63struct VideoModeTable *viafb_get_mode(int hres, int vres); 63struct VideoModeTable *viafb_get_mode(int hres, int vres);
64struct crt_mode_table *viafb_get_best_mode(int hres, int vres, int refresh);
64struct VideoModeTable *viafb_get_rb_mode(int hres, int vres); 65struct VideoModeTable *viafb_get_rb_mode(int hres, int vres);
66struct crt_mode_table *viafb_get_best_rb_mode(int hres, int vres, int refresh);
65 67
66#endif /* __VIAMODE_H__ */ 68#endif /* __VIAMODE_H__ */