aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/hw.c
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-08-06 19:04:43 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-08-06 19:22:49 -0400
commit94715ba97508dd42919a7525e362efb00dde1271 (patch)
tree9ad5e92149e59eed1b0385a950608608d7df0494 /drivers/video/via/hw.c
parent363699722a2a6801d098693fa15bc3b68d6b4f31 (diff)
viafb: add new funcions to select a single mode
This patch introduces 2 new functions for selecting a single mode based on hres, vres and refresh rate and changes some uses to use those. The advantage is that it is less error prone than doing the selection based on refresh rate everywhere and allows replacing the modetable structure. This includes a little change that users may notice: If a refresh rate was given as module parameters but does not exist in the modetable prior to this patch a refresh rate of 60 was assumed and after this patch the closest supported refresh rate to the one provided by the user is used. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r--drivers/video/via/hw.c45
1 files changed, 11 insertions, 34 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}