0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kernel.h>
0014
0015 #include "i810_regs.h"
0016 #include "i810.h"
0017
0018 struct mode_registers std_modes[] = {
0019
0020 { 25000, 0x0013, 0x0003, 0x40, 0x5F, 0x4F, 0x50, 0x82, 0x51, 0x9D,
0021 0x0B, 0x10, 0x40, 0xE9, 0x0B, 0xDF, 0x50, 0xE7, 0x04, 0x02,
0022 0x01, 0x01, 0x01, 0x00, 0x01, 0x22002000, 0x22004000, 0x22006000,
0023 0x22002000, 0x22004000, 0x22006000, 0xC0 },
0024
0025
0026 { 28000, 0x0053, 0x0010, 0x40, 0x61, 0x4F, 0x4F, 0x85, 0x52, 0x9A,
0027 0xF2, 0x10, 0x40, 0xE0, 0x03, 0xDF, 0x50, 0xDF, 0xF3, 0x01,
0028 0x01, 0x01, 0x01, 0x00, 0x01, 0x22002000, 0x22004000, 0x22005000,
0029 0x22002000, 0x22004000, 0x22005000, 0xC0 },
0030
0031
0032 { 31000, 0x0013, 0x0002, 0x40, 0x63, 0x4F, 0x4F, 0x87, 0x52, 0x97,
0033 0x06, 0x0F, 0x40, 0xE8, 0x0B, 0xDF, 0x50, 0xDF, 0x07, 0x02,
0034 0x01, 0x01, 0x01, 0x00, 0x01, 0x22003000, 0x22005000, 0x22007000,
0035 0x22003000, 0x22005000, 0x22007000, 0xC0 },
0036
0037
0038 { 31000, 0x0013, 0x0002, 0x40, 0x64, 0x4F, 0x4F, 0x88, 0x51, 0x99,
0039 0xF2, 0x10, 0x40, 0xE0, 0x03, 0xDF, 0x50, 0xDF, 0xF3, 0x01,
0040 0x01, 0x01, 0x01, 0x00, 0x01, 0x22003000, 0x22005000, 0x22007000,
0041 0x22003000, 0x22005000, 0x22007000, 0xC0 },
0042
0043
0044 { 36000, 0x0010, 0x0001, 0x40, 0x63, 0x4F, 0x4F, 0x87, 0x56, 0x9D,
0045 0xFB, 0x10, 0x40, 0xE0, 0x03, 0xDF, 0x50, 0xDF, 0xFC, 0x01,
0046 0x01, 0x01, 0x01, 0x00, 0x01, 0x22003000, 0x22005000, 0x22107000,
0047 0x22003000, 0x22005000, 0x22107000, 0xC0 },
0048
0049
0050 { 36000, 0x0010, 0x0001, 0x40, 0x7B, 0x63, 0x63, 0x9F, 0x66, 0x8F,
0051 0x6F, 0x10, 0x40, 0x58, 0x0A, 0x57, 0xC8, 0x57, 0x70, 0x02,
0052 0x02, 0x02, 0x02, 0x00, 0x01, 0x22003000, 0x22005000, 0x22107000,
0053 0x22003000, 0x22005000, 0x22107000, 0x00 },
0054
0055
0056 { 40000, 0x0008, 0x0001, 0x30, 0x7F, 0x63, 0x63, 0x83, 0x68, 0x18,
0057 0x72, 0x10, 0x40, 0x58, 0x0C, 0x57, 0xC8, 0x57, 0x73, 0x02,
0058 0x02, 0x02, 0x02, 0x00, 0x00, 0x22003000, 0x22006000, 0x22108000,
0059 0x22003000, 0x22006000, 0x22108000, 0x00 },
0060
0061
0062 { 45000, 0x0054, 0x0015, 0x30, 0x7D, 0x63, 0x63, 0x81, 0x68, 0x12,
0063 0x6f, 0x10, 0x40, 0x58, 0x0b, 0x57, 0x64, 0x57, 0x70, 0x02,
0064 0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22007000, 0x2210A000,
0065 0x22004000, 0x22007000, 0x2210A000, 0x00 },
0066
0067
0068 { 50000, 0x0017, 0x0004, 0x30, 0x7D, 0x63, 0x63, 0x81, 0x6A, 0x19,
0069 0x98, 0x10, 0x40, 0x7C, 0x02, 0x57, 0xC8, 0x57, 0x99, 0x02,
0070 0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22007000, 0x2210A000,
0071 0x22004000, 0x22007000, 0x2210A000, 0x00 },
0072
0073
0074 { 49000, 0x001F, 0x0006, 0x30, 0x7F, 0x63, 0x63, 0x83, 0x65, 0x0F,
0075 0x6F, 0x10, 0x40, 0x58, 0x0B, 0x57, 0xC8, 0x57, 0x70, 0x02,
0076 0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22007000, 0x2210B000,
0077 0x22004000, 0x22007000, 0x2210B000, 0x00 },
0078
0079
0080 { 56000, 0x0049, 0x000E, 0x30, 0x7E, 0x63, 0x63, 0x82, 0x67, 0x0F,
0081 0x75, 0x10, 0x40, 0x58, 0x0B, 0x57, 0xC8, 0x57, 0x76, 0x02,
0082 0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22108000, 0x2210b000,
0083 0x22004000, 0x22108000, 0x2210b000, 0x00 },
0084
0085
0086 { 65000, 0x003F, 0x000A, 0x30, 0xA3, 0x7F, 0x7F, 0x87, 0x83, 0x94,
0087 0x24, 0x10, 0x40, 0x02, 0x08, 0xFF, 0x80, 0xFF, 0x25, 0x03,
0088 0x02, 0x03, 0x02, 0x00, 0x00, 0x22005000, 0x22109000, 0x2220D000,
0089 0x22005000, 0x22109000, 0x2220D000, 0xC0 },
0090
0091
0092 { 75000, 0x0017, 0x0002, 0x30, 0xA1, 0x7F, 0x7F, 0x85, 0x82, 0x93,
0093 0x24, 0x10, 0x40, 0x02, 0x08, 0xFF, 0x80, 0xFF, 0x25, 0x03,
0094 0x02, 0x03, 0x02, 0x00, 0x00, 0x22005000, 0x2210A000, 0x2220F000,
0095 0x22005000, 0x2210A000, 0x2220F000, 0xC0 },
0096
0097
0098 { 78000, 0x0050, 0x0017, 0x20, 0x9F, 0x7F, 0x7F, 0x83, 0x81, 0x8D,
0099 0x1E, 0x10, 0x40, 0x00, 0x03, 0xFF, 0x80, 0xFF, 0x1F, 0x03,
0100 0x02, 0x03, 0x02, 0x00, 0x00, 0x22006000, 0x2210B000, 0x22210000,
0101 0x22006000, 0x2210B000, 0x22210000, 0x00 },
0102
0103
0104 { 94000, 0x003D, 0x000E, 0x20, 0xA7, 0x7F, 0x7F, 0x8B, 0x85, 0x91,
0105 0x26, 0x10, 0x40, 0x00, 0x03, 0xFF, 0x80, 0xFF, 0x27, 0x03,
0106 0x02, 0x03, 0x02, 0x00, 0x00, 0x22007000, 0x2220E000, 0x22212000,
0107 0x22007000, 0x2220E000, 0x22212000, 0x00 },
0108
0109
0110 { 80000, 0x0008, 0x0001, 0x20, 0xB3, 0x8F, 0x8F, 0x97, 0x93, 0x9f,
0111 0x87, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5f, 0x88, 0x03,
0112 0x03, 0x03, 0x03, 0x00, 0x00, 0x2220C000, 0x22210000, 0x22415000,
0113 0x2220C000, 0x22210000, 0x22415000, 0x00 },
0114
0115
0116 { 96000, 0x000a, 0x0001, 0x20, 0xbb, 0x8F, 0x8F, 0x9f, 0x98, 0x87,
0117 0x82, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x83, 0x03,
0118 0x03, 0x03, 0x03, 0x00, 0x00, 0x22107000, 0x22210000, 0x22415000,
0119 0x22107000, 0x22210000, 0x22415000, 0x00 },
0120
0121
0122 { 99000, 0x001f, 0x0006, 0x20, 0xbb, 0x8F, 0x8F, 0x9f, 0x98, 0x87,
0123 0x83, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x84, 0x03,
0124 0x03, 0x03, 0x03, 0x00, 0x00, 0x22107000, 0x22210000, 0x22415000,
0125 0x22107000, 0x22210000, 0x22415000, 0x00 },
0126
0127
0128 { 108000, 0x0010, 0x0002, 0x20, 0xC3, 0x8F, 0x8F, 0x87, 0x97, 0x07,
0129 0x82, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x83, 0x03,
0130 0x03, 0x03, 0x03, 0x00, 0x01, 0x22107000, 0x22210000, 0x22415000,
0131 0x22107000, 0x22210000, 0x22415000, 0x00 },
0132
0133
0134 { 121000, 0x006D, 0x0014, 0x20, 0xc0, 0x8F, 0x8F, 0x84, 0x97, 0x07,
0135 0x93, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x94, 0x03,
0136 0x03, 0x03, 0x03, 0x00, 0x01, 0x2220C000, 0x22210000, 0x22415000,
0137 0x2220C000, 0x22210000, 0x22415000, 0x0 },
0138
0139
0140 { 108000, 0x0010, 0x0002, 0x20, 0xDC, 0x9F, 0x9F, 0x80, 0xAB, 0x99,
0141 0xE6, 0x10, 0x40, 0xC0, 0x03, 0xBF, 0xA0, 0xBF, 0xE7, 0x03,
0142 0x03, 0x03, 0x03, 0x00, 0x01, 0x2210A000, 0x22210000, 0x22415000,
0143 0x2210A000, 0x22210000, 0x22415000, 0x00 },
0144
0145
0146 { 129000, 0x0029, 0x0006, 0x20, 0xD3, 0x9F, 0x9F, 0x97, 0xaa, 0x1b,
0147 0xE8, 0x10, 0x40, 0xC0, 0x03, 0xBF, 0xA0, 0xBF, 0xE9, 0x03,
0148 0x03, 0x03, 0x03, 0x00, 0x01, 0x2210A000, 0x22210000, 0x2241B000,
0149 0x2210A000, 0x22210000, 0x2241B000, 0x00 },
0150
0151
0152 { 148000, 0x0042, 0x0009, 0x20, 0xD3, 0x9F, 0x9F, 0x97, 0xA7, 0x1B,
0153 0xF1, 0x10, 0x40, 0xC0, 0x03, 0xBF, 0xA0, 0xBF, 0xF2, 0x03,
0154 0x03, 0x03, 0x03, 0x00, 0x01, 0x2210A000, 0x22220000, 0x2241D000,
0155 0x2210A000, 0x22220000, 0x2241D000, 0x00 },
0156
0157
0158 { 162000, 0x0019, 0x0006, 0x10, 0x09, 0xC7, 0xC7, 0x8D, 0xcf, 0x07,
0159 0xE0, 0x10, 0x40, 0xB0, 0x03, 0xAF, 0xC8, 0xAF, 0xE1, 0x04,
0160 0x04, 0x04, 0x04, 0x01, 0x00, 0x2210b000, 0x22416000, 0x44419000,
0161 0x2210b000, 0x22416000, 0x44419000, 0x00 },
0162
0163
0164 { 175000, 0x005d, 0x0018, 0x10, 0x09, 0xC7, 0xC7, 0x8D, 0xcf, 0x07,
0165 0xE0, 0x10, 0x40, 0xB0, 0x03, 0xAF, 0xC8, 0xAF, 0xE1, 0x04,
0166 0x04, 0x04, 0x04, 0x01, 0x00, 0x2210c000, 0x22416000, 0x44419000,
0167 0x2210c000, 0x22416000, 0x44419000, 0x00 },
0168
0169
0170 { 189000, 0x003D, 0x000e, 0x10, 0x09, 0xC7, 0xC7, 0x8d, 0xcf, 0x07,
0171 0xE0, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xE1, 0x04,
0172 0x04, 0x04, 0x04, 0x01, 0x00, 0x2220e000, 0x22416000, 0x44419000,
0173 0x2220e000, 0x22416000, 0x44419000, 0x00 },
0174
0175
0176 { 195000, 0x003f, 0x000e, 0x10, 0x0b, 0xC7, 0xC7, 0x8f, 0xd5, 0x0b,
0177 0xE1, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xe2, 0x04, 0x04,
0178 0x04, 0x04, 0x01, 0x00, 0x2220e000, 0x22416000, 0x44419000,
0179 0x2220e000, 0x22416000, 0x44419000, 0x00 },
0180
0181
0182 { 202000, 0x0024, 0x0007, 0x10, 0x09, 0xC7, 0xC7, 0x8d, 0xcf, 0x07,
0183 0xE0, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xE1, 0x04, 0x04,
0184 0x04, 0x04, 0x01, 0x00, 0x2220e000, 0x22416000, 0x44419000,
0185 0x2220e000, 0x22416000, 0x44419000, 0x00 },
0186
0187
0188 { 229000, 0x0029, 0x0007, 0x10, 0x09, 0xC7, 0xC7, 0x8d, 0xcf, 0x07,
0189 0xE0, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xE1, 0x04, 0x04,
0190 0x04, 0x04, 0x01, 0x00, 0x22210000, 0x22416000, 0x0,
0191 0x22210000, 0x22416000, 0x0, 0x00 },
0192 };
0193
0194 void round_off_xres(u32 *xres)
0195 {
0196 if (*xres <= 640)
0197 *xres = 640;
0198 else if (*xres <= 800)
0199 *xres = 800;
0200 else if (*xres <= 1024)
0201 *xres = 1024;
0202 else if (*xres <= 1152)
0203 *xres = 1152;
0204 else if (*xres <= 1280)
0205 *xres = 1280;
0206 else
0207 *xres = 1600;
0208 }
0209
0210 inline void round_off_yres(u32 *xres, u32 *yres)
0211 {
0212 *yres = (*xres * 3) >> 2;
0213 }
0214
0215 static int i810fb_find_best_mode(u32 xres, u32 yres, u32 pixclock)
0216 {
0217 u32 diff = 0, diff_best = 0xFFFFFFFF, i = 0, i_best = 0;
0218 u8 hfl = (u8) ((xres >> 3) - 1);
0219
0220 for (i = 0; i < ARRAY_SIZE(std_modes); i++) {
0221 if (std_modes[i].cr01 == hfl) {
0222 if (std_modes[i].pixclock <= pixclock)
0223 diff = pixclock - std_modes[i].pixclock;
0224 if (diff < diff_best) {
0225 i_best = i;
0226 diff_best = diff;
0227 }
0228 }
0229 }
0230 return i_best;
0231 }
0232
0233 void i810fb_encode_registers(const struct fb_var_screeninfo *var,
0234 struct i810fb_par *par, u32 xres, u32 yres)
0235 {
0236 u32 i_best = i810fb_find_best_mode(xres, yres, par->regs.pixclock);
0237
0238 par->regs = std_modes[i_best];
0239
0240
0241 par->ovract = ((xres + var->right_margin + var->hsync_len +
0242 var->left_margin - 32) | ((xres - 32) << 16));
0243 }
0244
0245 void i810fb_fill_var_timings(struct fb_var_screeninfo *var)
0246 {
0247 u32 total, xres, yres;
0248 u32 mode, pixclock;
0249
0250 xres = var->xres;
0251 yres = var->yres;
0252
0253 pixclock = 1000000000 / var->pixclock;
0254 mode = i810fb_find_best_mode(xres, yres, pixclock);
0255
0256 total = (std_modes[mode].cr00 | (std_modes[mode].cr35 & 1) << 8) + 3;
0257 total <<= 3;
0258
0259 var->pixclock = 1000000000 / std_modes[mode].pixclock;
0260 var->right_margin = (std_modes[mode].cr04 << 3) - xres;
0261 var->hsync_len = ((std_modes[mode].cr05 & 0x1F) -
0262 (std_modes[mode].cr04 & 0x1F)) << 3;
0263 var->left_margin = (total - (xres + var->right_margin +
0264 var->hsync_len));
0265 var->sync = FB_SYNC_ON_GREEN;
0266 if (~(std_modes[mode].msr & (1 << 6)))
0267 var->sync |= FB_SYNC_HOR_HIGH_ACT;
0268 if (~(std_modes[mode].msr & (1 << 7)))
0269 var->sync |= FB_SYNC_VERT_HIGH_ACT;
0270
0271 total = (std_modes[mode].cr06 | (std_modes[mode].cr30 & 0xF) << 8) + 2;
0272 var->lower_margin = (std_modes[mode].cr10 |
0273 (std_modes[mode].cr32 & 0x0F) << 8) - yres;
0274 var->vsync_len = (std_modes[mode].cr11 & 0x0F) -
0275 (var->lower_margin & 0x0F);
0276 var->upper_margin = total - (yres + var->lower_margin + var->vsync_len);
0277 }
0278
0279 u32 i810_get_watermark(struct fb_var_screeninfo *var,
0280 struct i810fb_par *par)
0281 {
0282 struct mode_registers *params = &par->regs;
0283 u32 wmark = 0;
0284
0285 if (par->mem_freq == 100) {
0286 switch (var->bits_per_pixel) {
0287 case 8:
0288 wmark = params->bpp8_100;
0289 break;
0290 case 16:
0291 wmark = params->bpp16_100;
0292 break;
0293 case 24:
0294 case 32:
0295 wmark = params->bpp24_100;
0296 }
0297 } else {
0298 switch (var->bits_per_pixel) {
0299 case 8:
0300 wmark = params->bpp8_133;
0301 break;
0302 case 16:
0303 wmark = params->bpp16_133;
0304 break;
0305 case 24:
0306 case 32:
0307 wmark = params->bpp24_133;
0308 }
0309 }
0310 return wmark;
0311 }
0312