From c10383e5782f9e46f13967f2b46616bef1d388ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Sat, 8 Apr 2017 18:36:47 +0000 Subject: [PATCH] fix formatting --- BaS_gcc/video/fbmon.c | 356 +++++++++++++++++++++++++----------------- 1 file changed, 215 insertions(+), 141 deletions(-) diff --git a/BaS_gcc/video/fbmon.c b/BaS_gcc/video/fbmon.c index f3ec678..4552bc4 100644 --- a/BaS_gcc/video/fbmon.c +++ b/BaS_gcc/video/fbmon.c @@ -41,30 +41,34 @@ #define FBMON_FIX_HEADER 1 #define FBMON_FIX_INPUT 2 -struct broken_edid { +struct broken_edid +{ unsigned char manufacturer[4]; unsigned long model; unsigned long fix; }; -static struct broken_edid brokendb[] = { +static struct broken_edid brokendb[] = +{ /* DEC FR-PCXAV-YZ */ -{ - .manufacturer = "DEC", - .model = 0x073a, - .fix = FBMON_FIX_HEADER, -}, -/* ViewSonic PF775a */ -{ - .manufacturer = "VSC", - .model = 0x5a44, - .fix = FBMON_FIX_INPUT, -}, + { + .manufacturer = "DEC", + .model = 0x073a, + .fix = FBMON_FIX_HEADER, + }, + /* ViewSonic PF775a */ + { + .manufacturer = "VSC", + .model = 0x5a44, + .fix = FBMON_FIX_INPUT, + }, }; -static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00 - }; +static const unsigned char edid_v1_header[] = +{ + 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00 +}; static void copy_string(unsigned char *c, unsigned char *s) { @@ -82,37 +86,39 @@ static int32_t check_edid(unsigned char *edid) unsigned char *b; unsigned long model; int32_t i, fix = 0, ret = 0; + manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@'; manufacturer[1] = ((block[0] & 0x03) << 3) + ((block[1] & 0xe0) >> 5) + '@'; manufacturer[2] = (block[1] & 0x1f) + '@'; manufacturer[3] = 0; model = block[2] + (block[3] << 8); - for(i = 0; i < sizeof(brokendb)/sizeof(*brokendb); i++) + for (i = 0; i < sizeof(brokendb)/sizeof(*brokendb); i++) { - if(manufacturer[0] == brokendb[i].manufacturer[0] - && manufacturer[1] == brokendb[i].manufacturer[1] - && manufacturer[2] == brokendb[i].manufacturer[2] - && manufacturer[3] == brokendb[i].manufacturer[3] - && brokendb[i].model == model) + if (manufacturer[0] == brokendb[i].manufacturer[0] && + manufacturer[1] == brokendb[i].manufacturer[1] && + manufacturer[2] == brokendb[i].manufacturer[2] && + manufacturer[3] == brokendb[i].manufacturer[3] && + brokendb[i].model == model) { fix = brokendb[i].fix; break; } } - switch(fix) + switch (fix) { case FBMON_FIX_HEADER: - for(i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { if(edid[i] != edid_v1_header[i]) ret = fix; } break; + case FBMON_FIX_INPUT: b = edid + EDID_STRUCT_DISPLAY; /* Only if display is GTF capable will the input type be reset to analog */ - if(b[4] & 0x01 && b[0] & 0x80) + if (b[4] & 0x01 && b[0] & 0x80) ret = fix; break; } @@ -122,11 +128,13 @@ static int32_t check_edid(unsigned char *edid) static void fix_edid(unsigned char *edid, int32_t fix) { unsigned char *b; - switch(fix) + + switch (fix) { case FBMON_FIX_HEADER: memcpy(edid, edid_v1_header, 8); break; + case FBMON_FIX_INPUT: b = edid + EDID_STRUCT_DISPLAY; b[0] &= ~0x80; @@ -139,17 +147,18 @@ static int32_t edid_checksum(unsigned char *edid) { unsigned char i, csum = 0, all_null = 0; int32_t err = 0, fix = check_edid(edid); - if(fix) + + if (fix) fix_edid(edid, fix); - for(i = 0; i < EDID_LENGTH; i++) + for (i = 0; i < EDID_LENGTH; i++) { csum += edid[i]; all_null |= edid[i]; } - if((csum == 0x00) && all_null) + if ((csum == 0x00) && all_null) /* checksum passed, everything's good */ err = 1; - if(!err) + if (!err) dbg("edid bad checksum\r\n"); return err; } @@ -157,14 +166,15 @@ static int32_t edid_checksum(unsigned char *edid) static int32_t edid_check_header(unsigned char *edid) { int32_t i, err = 1, fix = check_edid(edid); - if(fix) + + if (fix) fix_edid(edid, fix); - for(i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { - if(edid[i] != edid_v1_header[i]) + if (edid[i] != edid_v1_header[i]) err = 0; } - if(!err) + if (!err) dbg("edid bad header\r\n"); return err; } @@ -189,11 +199,11 @@ static void parse_vendor_block(unsigned char *block, struct fb_monspecs *specs) static void get_dpms_capabilities(unsigned char flags, struct fb_monspecs *specs) { specs->dpms = 0; - if(flags & DPMS_ACTIVE_OFF) + if (flags & DPMS_ACTIVE_OFF) specs->dpms |= FB_DPMS_ACTIVE_OFF; - if(flags & DPMS_SUSPEND) + if (flags & DPMS_SUSPEND) specs->dpms |= FB_DPMS_SUSPEND; - if(flags & DPMS_STANDBY) + if (flags & DPMS_STANDBY) specs->dpms |= FB_DPMS_STANDBY; dbg(" DPMS: Active %s\r\n", (flags & DPMS_ACTIVE_OFF) ? "yes" : "no"); dbg(" Suspend: %s\r\n", (flags & DPMS_SUSPEND) ? "yes" : "no"); @@ -256,7 +266,7 @@ static void get_chroma(unsigned char *block, struct fb_monspecs *specs) static int32_t edid_is_serial_block(unsigned char *block) { - if((block[0] == 0x00) && (block[1] == 0x00) + if ((block[0] == 0x00) && (block[1] == 0x00) && (block[2] == 0x00) && (block[3] == 0xff) && (block[4] == 0x00)) return 1; else @@ -265,7 +275,7 @@ static int32_t edid_is_serial_block(unsigned char *block) static int32_t edid_is_ascii_block(unsigned char *block) { - if((block[0] == 0x00) && (block[1] == 0x00) + if ((block[0] == 0x00) && (block[1] == 0x00) && (block[2] == 0x00) && (block[3] == 0xfe) && (block[4] == 0x00)) return 1; else @@ -274,7 +284,7 @@ static int32_t edid_is_ascii_block(unsigned char *block) static int32_t edid_is_limits_block(unsigned char *block) { - if((block[0] == 0x00) && (block[1] == 0x00) + if ((block[0] == 0x00) && (block[1] == 0x00) && (block[2] == 0x00) && (block[3] == 0xfd) && (block[4] == 0x00)) return 1; else @@ -283,7 +293,7 @@ static int32_t edid_is_limits_block(unsigned char *block) static int32_t edid_is_monitor_block(unsigned char *block) { - if((block[0] == 0x00) && (block[1] == 0x00) + if ((block[0] == 0x00) && (block[1] == 0x00) && (block[2] == 0x00) && (block[3] == 0xfc) && (block[4] == 0x00)) return 1; else @@ -316,93 +326,93 @@ static int32_t get_est_timing(unsigned char *block, struct fb_videomode *mode) int32_t num = 0; unsigned char c; c = block[0]; - if(c&0x80) + if (c & 0x80) { calc_mode_timings(720, 400, 70, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; dbg(" 720x400@70Hz\r\n"); } - if(c&0x40) + if (c & 0x40) { calc_mode_timings(720, 400, 88, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; dbg(" 720x400@88Hz\r\n"); } - if(c&0x20) + if (c&0x20) { mode[num++] = vesa_modes[3]; dbg(" 640x480@60Hz\r\n"); } - if(c&0x10) + if (c & 0x10) { calc_mode_timings(640, 480, 67, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; dbg(" 640x480@67Hz\r\n"); } - if(c&0x08) + if (c & 0x08) { mode[num++] = vesa_modes[4]; dbg(" 640x480@72Hz\r\n"); } - if(c&0x04) + if (c & 0x04) { mode[num++] = vesa_modes[5]; dbg(" 640x480@75Hz\r\n"); } - if(c&0x02) + if (c & 0x02) { mode[num++] = vesa_modes[7]; dbg(" 800x600@56Hz\r\n"); } - if(c&0x01) + if (c & 0x01) { mode[num++] = vesa_modes[8]; dbg(" 800x600@60Hz\r\n"); } c = block[1]; - if(c&0x80) + if (c & 0x80) { mode[num++] = vesa_modes[9]; dbg(" 800x600@72Hz\r\n"); } - if(c&0x40) + if (c & 0x40) { mode[num++] = vesa_modes[10]; dbg(" 800x600@75Hz\r\n"); } - if(c&0x20) + if (c & 0x20) { calc_mode_timings(832, 624, 75, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; dbg(" 832x624@75Hz\r\n"); } - if(c&0x10) + if (c & 0x10) { mode[num++] = vesa_modes[12]; dbg(" 1024x768@87Hz Interlaced\r\n"); } - if(c&0x08) + if (c & 0x08) { mode[num++] = vesa_modes[13]; dbg(" 1024x768@60Hz\r\n"); } - if(c&0x04) + if (c & 0x04) { mode[num++] = vesa_modes[14]; dbg(" 1024x768@70Hz\r\n"); } - if(c&0x02) + if (c & 0x02) { mode[num++] = vesa_modes[15]; dbg(" 1024x768@75Hz\r\n"); } - if(c&0x01) + if (c & 0x01) { mode[num++] = vesa_modes[21]; dbg(" 1280x1024@75Hz\r\n"); } c = block[2]; - if(c&0x80) + if (c & 0x80) { mode[num++] = vesa_modes[17]; dbg(" 1152x870@75Hz\r\n"); @@ -421,18 +431,29 @@ static int32_t get_std_timing(unsigned char *block, struct fb_videomode *mode) ratio = (block[1] & 0xc0) >> 6; switch(ratio) { - case 0: yres = xres; break; - case 1: yres = (xres * 3)/4; break; - case 2: yres = (xres * 4)/5; break; - case 3: yres = (xres * 9)/16; break; + case 0: + yres = xres; + break; + + case 1: + yres = (xres * 3) / 4; + break; + + case 2: + yres = (xres * 4) / 5; + break; + + case 3: + yres = (xres * 9) / 16; + break; } refresh = (block[1] & 0x3f) + 60; dbg("%dx%d@ Hz\r\n",xres, yres, refresh); - for(i = 0; i < VESA_MODEDB_SIZE; i++) + for (i = 0; i < VESA_MODEDB_SIZE; i++) { - if(vesa_modes[i].xres == xres && vesa_modes[i].yres == yres - && vesa_modes[i].refresh == refresh) + if (vesa_modes[i].xres == xres && vesa_modes[i].yres == yres && + vesa_modes[i].refresh == refresh) { *mode = vesa_modes[i]; mode->flag |= FB_MODE_IS_STANDARD; @@ -446,7 +467,7 @@ static int32_t get_std_timing(unsigned char *block, struct fb_videomode *mode) static int32_t get_dst_timing(unsigned char *block, struct fb_videomode *mode) { int32_t j, num = 0; - for(j = 0; j < 6; j++, block+= STD_TIMING_DESCRIPTION_SIZE) + for (j = 0; j < 6; j++, block+= STD_TIMING_DESCRIPTION_SIZE) num += get_std_timing(block, &mode[num]); return num; } @@ -493,36 +514,40 @@ static struct fb_videomode *db_used[MAX_DB_ALLOC]; static struct fb_videomode *alloc_db(int32_t num) { int32_t i = 0; - if(!num) - return(NULL); - while(i < MAX_DB_ALLOC) + if (!num) + return NULL; + while (i < MAX_DB_ALLOC) { - if((db_used[i] == NULL) && ((i + num) <= MAX_DB_ALLOC)) + if ((db_used[i] == NULL) && ((i + num) <= MAX_DB_ALLOC)) { int32_t j; /* search contiguous num db free */ - for(j = 0; j < num; j++) + + for (j = 0; j < num; j++) { - if(db_used[i+j] != NULL) + if (db_used[i+j] != NULL) break; /* already used */ } - if(j >= num) + if (j >= num) { struct fb_videomode *p = &tab_db[i]; - for(j = 0; j < num; db_used[i+j] = p, j++); - return(p); + + for (j = 0; j < num; db_used[i+j] = p, j++); + + return p; } } i++; } - return(NULL); + return NULL; } static void free_db(struct fb_videomode *db) { int32_t i; - for(i = 0; i < MAX_DB_ALLOC; i++) + + for (i = 0; i < MAX_DB_ALLOC; i++) { - if(db_used[i] == db) + if (db_used[i] == db) db_used[i] = NULL; } } @@ -536,7 +561,7 @@ static void free_db(struct fb_videomode *db) */ void fb_destroy_modedb(struct fb_videomode *modedb) { - // Funcs_free(modedb); + // Funcs_free(modedb); free_db(modedb); } @@ -556,14 +581,17 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int32_t *dbsiz struct fb_videomode *mode, *m; unsigned char *block; int32_t num = 0, i; + // mode = Funcs_malloc(50 * sizeof(struct fb_videomode), 3); mode = alloc_db(50); - if(mode == NULL) + if (mode == NULL) return NULL; + memset((char *)mode, 0, 50 * sizeof(struct fb_videomode)); - if(edid == NULL || !edid_checksum(edid) || !edid_check_header(edid)) + if (edid == NULL || !edid_checksum(edid) || !edid_check_header(edid)) { fb_destroy_modedb(mode); + return NULL; } *dbsize = 0; @@ -572,22 +600,23 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int32_t *dbsiz num += get_est_timing(block, &mode[num]); dbg(" Standard Timings\r\n"); block = edid + STD_TIMING_DESCRIPTIONS_START; - for(i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) + for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) num += get_std_timing(block, &mode[num]); dbg(" Detailed Timings\r\n"); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; - for(i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) + for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { int32_t first = 1; - if(block[0] == 0x00 && block[1] == 0x00) + + if (block[0] == 0x00 && block[1] == 0x00) { - if(block[3] == 0xfa) + if (block[3] == 0xfa) num += get_dst_timing(block + 5, &mode[num]); } else { get_detailed_timing(block, &mode[num]); - if(first) + if (first) { mode[num].flag |= FB_MODE_IS_FIRST; first = 0; @@ -596,18 +625,20 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int32_t *dbsiz } } /* Yikes, EDID data is totally useless */ - if(!num) + if (!num) { fb_destroy_modedb(mode); + return NULL; } *dbsize = num; // m = Funcs_malloc(num * sizeof(struct fb_videomode), 3); m = alloc_db(num); - if(!m) + if (!m) return mode; memcpy(m, mode, num * sizeof(struct fb_videomode)); fb_destroy_modedb(mode); + return m; } @@ -615,9 +646,10 @@ static int32_t fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *sp { int32_t i, retval = 1; unsigned char *block; + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; dbg(" Monitor Operating Limits: "); - for(i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { if (edid_is_limits_block(block)) { @@ -633,33 +665,35 @@ static int32_t fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *sp } } /* estimate monitor limits based on modes supported */ - if(retval) + if (retval) { struct fb_videomode *modes; int32_t num_modes, i, hz, hscan, pixclock; + modes = fb_create_modedb(edid, &num_modes); - if(!modes) + if (!modes) { dbg("None Available\r\n"); + return 1; } retval = 0; - for(i = 0; i < num_modes; i++) + for (i = 0; i < num_modes; i++) { hz = modes[i].refresh; pixclock = PICOS2KHZ(modes[i].pixclock) * 1000; hscan = (modes[i].yres * 105 * hz + 5000)/100; - if(specs->dclkmax == 0 || specs->dclkmax < pixclock) + if (specs->dclkmax == 0 || specs->dclkmax < pixclock) specs->dclkmax = pixclock; - if(specs->dclkmin == 0 || specs->dclkmin > pixclock) + if (specs->dclkmin == 0 || specs->dclkmin > pixclock) specs->dclkmin = pixclock; - if(specs->hfmax == 0 || specs->hfmax < hscan) + if (specs->hfmax == 0 || specs->hfmax < hscan) specs->hfmax = hscan; - if(specs->hfmin == 0 || specs->hfmin > hscan) + if (specs->hfmin == 0 || specs->hfmin > hscan) specs->hfmin = hscan; - if(specs->vfmax == 0 || specs->vfmax < hz) + if (specs->vfmax == 0 || specs->vfmax < hz) specs->vfmax = hz; - if(specs->vfmin == 0 || specs->vfmin > hz) + if (specs->vfmin == 0 || specs->vfmin > hz) specs->vfmin = hz; } dbg("Extrapolated\r\n"); @@ -671,17 +705,20 @@ static int32_t fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *sp specs->vfmin, specs->vfmax, specs->dclkmax / 1000000); + return retval; } static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) { unsigned char c, *block; + block = edid + EDID_STRUCT_DISPLAY; fb_get_monitor_limits(edid, specs); c = block[0] & 0x80; specs->input = 0; - if(c) + + if (c) { specs->input |= FB_DISP_DDI; dbg(" Digital Display Input"); @@ -694,14 +731,17 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) //dbg(" Analog Display Input: Input Voltage - 0.700V/0.300V"); specs->input |= FB_DISP_ANA_700_300; break; + case 1: //dbg("0.714V/0.286V"); specs->input |= FB_DISP_ANA_714_286; break; + case 2: //dbg("1.000V/0.400V"); specs->input |= FB_DISP_ANA_1000_400; break; + case 3: //dbg("0.700V/0.000V"); specs->input |= FB_DISP_ANA_700_000; @@ -710,33 +750,38 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) } // dbg("Sync: "); c = block[0] & 0x10; - if(c) + if (c) { dbg(" Configurable signal level\r\n"); } c = block[0] & 0x0f; specs->signal = 0; - if(c & 0x10) + + if (c & 0x10) { //DPRINT("Blank to Blank "); specs->signal |= FB_SIGNAL_BLANK_BLANK; } - if(c & 0x08) + + if (c & 0x08) { //DPRINT("Separate "); specs->signal |= FB_SIGNAL_SEPARATE; } - if(c & 0x04) + + if (c & 0x04) { //DPRINT("Composite "); specs->signal |= FB_SIGNAL_COMPOSITE; } - if(c & 0x02) + + if (c & 0x02) { //DPRINT("Sync on Green "); specs->signal |= FB_SIGNAL_SYNC_ON_GREEN; } - if(c & 0x01) + + if (c & 0x01) { // DPRINT("Serration on "); specs->signal |= FB_SIGNAL_SERRATION_ON; @@ -749,20 +794,24 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) specs->gamma = c+100; dbg(" Gamma %d\r\n: ",specs->gamma / 100); get_dpms_capabilities(block[4], specs); + switch ((block[4] & 0x18) >> 3) { case 0: //DPRINT(" Monochrome/Grayscale\r\n"); specs->input |= FB_DISP_MONO; break; + case 1: //DPRINT(" RGB Color Display\r\n"); specs->input |= FB_DISP_RGB; break; + case 2: //DPRINT(" Non-RGB Multicolor Display\r\n"); specs->input |= FB_DISP_MULTI; break; + default: //DPRINT(" Unknown\r\n"); specs->input |= FB_DISP_UNKNOWN; @@ -771,17 +820,17 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) get_chroma(block, specs); specs->misc = 0; c = block[4] & 0x7; - if(c & 0x04) + if (c & 0x04) { dbg(" Default color format is primary\r\n"); specs->misc |= FB_MISC_PRIM_COLOR; } - if(c & 0x02) + if (c & 0x02) { dbg(" First DETAILED Timing is preferred\r\n"); specs->misc |= FB_MISC_1ST_DETAIL; } - if(c & 0x01) + if (c & 0x01) { dbg(" Display is GTF capable\r\n"); specs->gtf = 1; @@ -790,7 +839,7 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) static int32_t edid_is_timing_block(unsigned char *block) { - if((block[0] != 0x00) || (block[1] != 0x00) + if ((block[0] != 0x00) || (block[1] != 0x00) || (block[2] != 0x00) || (block[4] != 0x00)) return 1; else @@ -801,16 +850,17 @@ int32_t fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) { int32_t i; unsigned char *block; - if(edid == NULL || var == NULL) + + if (edid == NULL || var == NULL) return 1; - if(!(edid_checksum(edid))) + if (!(edid_checksum(edid))) return 1; - if(!(edid_check_header(edid))) + if (!(edid_check_header(edid))) return 1; block = edid + DETAILED_TIMING_DESCRIPTIONS_START; - for(i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { - if(edid_is_timing_block(block)) + if (edid_is_timing_block(block)) { var->xres = var->xres_virtual = H_ACTIVE; var->yres = var->yres_virtual = V_ACTIVE; @@ -824,14 +874,15 @@ int32_t fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) var->pixclock = PIXEL_CLOCK; var->pixclock /= 1000; var->pixclock = KHZ2PICOS(var->pixclock); - if(HSYNC_POSITIVE) + if (HSYNC_POSITIVE) var->sync |= FB_SYNC_HOR_HIGH_ACT; - if(VSYNC_POSITIVE) + if (VSYNC_POSITIVE) var->sync |= FB_SYNC_VERT_HIGH_ACT; return 0; } } dbg("edid no timing block\r\n"); + return 1; } @@ -839,13 +890,14 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) { unsigned char *block; int32_t i; - if(edid == NULL) + + if (edid == NULL) return; - if(!(edid_checksum(edid))) + if (!(edid_checksum(edid))) return; - if(!(edid_check_header(edid))) + if (!(edid_check_header(edid))) return; - if(specs->modedb != NULL) + if (specs->modedb != NULL) fb_destroy_modedb(specs->modedb); memset((char *)specs, 0, sizeof(struct fb_monspecs)); specs->version = edid[EDID_STRUCT_VERSION]; @@ -857,23 +909,23 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) parse_vendor_block(edid + ID_MANUFACTURER_NAME, specs); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; - for(i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { - if(edid_is_serial_block(block)) + if (edid_is_serial_block(block)) { copy_string(block, specs->serial_no); //DPRINT(" Serial Number: "); //DPRINT((void *)specs->serial_no); //DPRINT("\r\n"); } - else if(edid_is_ascii_block(block)) + else if (edid_is_ascii_block(block)) { copy_string(block, specs->ascii); //DPRINT(" ASCII Block: "); //DPRINT((void *)specs->ascii); //DPRINT("\r\n"); } - else if(edid_is_monitor_block(block)) + else if (edid_is_monitor_block(block)) { copy_string(block, specs->monitor); //DPRINT(" Monitor Name: "); @@ -900,7 +952,8 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) #define C_VAL 30 #define M_VAL 300 -struct __fb_timings { +struct __fb_timings +{ unsigned long dclk; unsigned long hfreq; unsigned long vfreq; @@ -930,9 +983,10 @@ struct __fb_timings { static unsigned long fb_get_vblank(unsigned long hfreq) { unsigned long vblank; + vblank = (hfreq * FLYBACK)/1000; vblank = (vblank + 500)/1000; - return (vblank + V_FRONTPORCH); + return vblank + V_FRONTPORCH; } /** @@ -958,19 +1012,22 @@ static unsigned long fb_get_vblank(unsigned long hfreq) static unsigned long fb_get_hblank_by_hfreq(unsigned long hfreq, unsigned long xres) { unsigned long c_val, m_val, duty_cycle, hblank; + c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + H_SCALEFACTOR) * 1000; m_val = (H_BLANKSCALE * H_GRADIENT)/256; m_val = (m_val * 1000000)/hfreq; duty_cycle = c_val - m_val; hblank = (xres * duty_cycle)/(100000 - duty_cycle); - return (hblank); + + return hblank; } /* Quick integer square root using binomial theorem (from Dr. Dobbs journal) */ static int32_t int32_t_sqrt(int32_t N) { unsigned long l2, u, v, u2, n; - if(N < 2) + + if (N < 2) return N; u = N; l2 = 0; @@ -980,6 +1037,7 @@ static int32_t int32_t_sqrt(int32_t N) u = 1L << l2; v = u; u2 = u << l2; + while (l2--) { v >>= 1; @@ -1018,6 +1076,7 @@ static int32_t int32_t_sqrt(int32_t N) static unsigned long fb_get_hblank_by_dclk(unsigned long dclk, unsigned long xres) { unsigned long duty_cycle, h_period, hblank; + dclk /= 1000; h_period = 100 - C_VAL; h_period *= h_period; @@ -1030,7 +1089,8 @@ static unsigned long fb_get_hblank_by_dclk(unsigned long dclk, unsigned long xre duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100; hblank = (xres * duty_cycle)/(100000 - duty_cycle) + 8; hblank &= ~15; - return (hblank); + + return hblank; } /** @@ -1049,9 +1109,11 @@ static unsigned long fb_get_hblank_by_dclk(unsigned long dclk, unsigned long xre static unsigned long fb_get_hfreq(unsigned long vfreq, unsigned long yres) { unsigned long divisor, hfreq; + divisor = (1000000 - (vfreq * FLYBACK))/1000; hfreq = (yres + V_FRONTPORCH) * vfreq * 1000; - return (hfreq/divisor); + + return hfreq / divisor; } static void fb_timings_vfreq(struct __fb_timings *timings) @@ -1124,11 +1186,12 @@ int32_t fb_get_mode(int32_t flags, uint32_t val, struct fb_var_screeninfo *var, struct __fb_timings timings; unsigned long interlace = 1, dscan = 1; unsigned long hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; + /* * If monspecs are invalid, use values that are enough * for 640x480@60 */ - if(!info->monspecs.hfmax || !info->monspecs.vfmax + if (!info->monspecs.hfmax || !info->monspecs.vfmax || !info->monspecs.dclkmax || info->monspecs.hfmax < info->monspecs.hfmin || info->monspecs.vfmax < info->monspecs.vfmin || info->monspecs.dclkmax < info->monspecs.dclkmin) { @@ -1148,52 +1211,61 @@ int32_t fb_get_mode(int32_t flags, uint32_t val, struct fb_var_screeninfo *var, memset((char *)&timings, 0, sizeof(struct __fb_timings)); timings.hactive = var->xres; timings.vactive = var->yres; - if(var->vmode & FB_VMODE_INTERLACED) + + if (var->vmode & FB_VMODE_INTERLACED) { timings.vactive /= 2; interlace = 2; } - if(var->vmode & FB_VMODE_DOUBLE) + + if (var->vmode & FB_VMODE_DOUBLE) { timings.vactive *= 2; dscan = 2; } - switch(flags & ~FB_IGNOREMON) + + switch (flags & ~FB_IGNOREMON) { case FB_MAXTIMINGS: /* maximize refresh rate */ timings.hfreq = hfmax; fb_timings_hfreq(&timings); - if(timings.vfreq > vfmax) + if (timings.vfreq > vfmax) { timings.vfreq = vfmax; fb_timings_vfreq(&timings); } - if(timings.dclk > dclkmax) + + if (timings.dclk > dclkmax) { timings.dclk = dclkmax; fb_timings_dclk(&timings); } break; + case FB_VSYNCTIMINGS: /* vrefresh driven */ timings.vfreq = val; fb_timings_vfreq(&timings); break; + case FB_HSYNCTIMINGS: /* hsync driven */ timings.hfreq = val; fb_timings_hfreq(&timings); break; + case FB_DCLKTIMINGS: /* pixelclock driven */ timings.dclk = PICOS2KHZ(val) * 1000; fb_timings_dclk(&timings); break; + default: return -1; // -EINVAL; } - if(!(flags & FB_IGNOREMON) + if (!(flags & FB_IGNOREMON) && (timings.vfreq < vfmin || timings.vfreq > vfmax || timings.hfreq < hfmin || timings.hfreq > hfmax || timings.dclk < dclkmin || timings.dclk > dclkmax)) return -1; //-EINVAL; + var->pixclock = KHZ2PICOS(timings.dclk/1000); var->hsync_len = (timings.htotal * 8)/100; var->right_margin = (timings.hblank/2) - var->hsync_len; @@ -1201,6 +1273,7 @@ int32_t fb_get_mode(int32_t flags, uint32_t val, struct fb_var_screeninfo *var, var->vsync_len = (3 * interlace)/dscan; var->lower_margin = (1 * interlace)/dscan; var->upper_margin = (timings.vblank * interlace)/dscan - (var->vsync_len + var->lower_margin); + return 0; } @@ -1224,7 +1297,7 @@ int32_t fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *in * If monspecs are invalid, use values that are enough * for 640x480@60 */ - if(!info->monspecs.hfmax || !info->monspecs.vfmax || !info->monspecs.dclkmax + if (!info->monspecs.hfmax || !info->monspecs.vfmax || !info->monspecs.dclkmax || info->monspecs.hfmax < info->monspecs.hfmin || info->monspecs.vfmax < info->monspecs.vfmin || info->monspecs.dclkmax < info->monspecs.dclkmin) @@ -1242,14 +1315,15 @@ int32_t fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *in dclkmin = info->monspecs.dclkmin; dclkmax = info->monspecs.dclkmax; } - if(!var->pixclock) + if (!var->pixclock) return -1; // -EINVAL; + pixclock = PICOS2KHZ(var->pixclock) * 1000; htotal = var->xres + var->right_margin + var->hsync_len + var->left_margin; vtotal = var->yres + var->lower_margin + var->vsync_len + var->upper_margin; - if(var->vmode & FB_VMODE_INTERLACED) + if (var->vmode & FB_VMODE_INTERLACED) vtotal /= 2; - if(var->vmode & FB_VMODE_DOUBLE) + if (var->vmode & FB_VMODE_DOUBLE) vtotal *= 2; hfreq = pixclock/htotal; vfreq = hfreq/vtotal;