Commit 2accbe62 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Fix some more sync polarity issues. Don't support DTDs for stereoscopic modes.

Detail:
  c/ScrModes - Replace magic numbers used for sync polarities with HSync_Positive, VSync_Negative, etc. #defines. Fix GTF2 polarity to be correct. Fix CVT/CVT RB polarities to be correct (+ some incorrect code indentation). Make dtd_block_to_modedesc return true/false for success/failure so we can reject stereoscopic 3D modes.
Admin:
  Tested on Pandaboard


Version 0.48. Tagged as 'ScrModes-0_48'
parent 8f3400df
/* (0.47) /* (0.48)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1. * Last processed by srccommit version: 1.1.
* *
*/ */
#define Module_MajorVersion_CMHG 0.47 #define Module_MajorVersion_CMHG 0.48
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 24 Feb 2015 #define Module_Date_CMHG 24 Feb 2015
#define Module_MajorVersion "0.47" #define Module_MajorVersion "0.48"
#define Module_Version 47 #define Module_Version 48
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "24 Feb 2015" #define Module_Date "24 Feb 2015"
...@@ -18,6 +18,6 @@ ...@@ -18,6 +18,6 @@
#define Module_ComponentName "ScrModes" #define Module_ComponentName "ScrModes"
#define Module_ComponentPath "castle/RiscOS/Sources/Video/UserI/ScrModes" #define Module_ComponentPath "castle/RiscOS/Sources/Video/UserI/ScrModes"
#define Module_FullVersion "0.47" #define Module_FullVersion "0.48"
#define Module_HelpVersion "0.47 (24 Feb 2015)" #define Module_HelpVersion "0.48 (24 Feb 2015)"
#define Module_LibraryVersionInfo "0:47" #define Module_LibraryVersionInfo "0:48"
...@@ -94,11 +94,16 @@ static bool EDIDEnabled; ...@@ -94,11 +94,16 @@ static bool EDIDEnabled;
#define MAXKEYWORDLEN 14 #define MAXKEYWORDLEN 14
#define keyword(n) (keywordset + ((n) * (MAXKEYWORDLEN+1))) #define keyword(n) (keywordset + ((n) * (MAXKEYWORDLEN+1)))
#define HSync_Positive 0
#define HSync_Negative SyncPol_InvertHSync
#define VSync_Positive 0
#define VSync_Negative SyncPol_InvertVSync
/* HSync & VSync polarities for use by display_monitor_timings */ /* HSync & VSync polarities for use by display_monitor_timings */
#define PP 0 #define PP HSync_Positive+VSync_Positive
#define PN SyncPol_InvertVSync #define PN HSync_Positive+VSync_Negative
#define NP SyncPol_InvertHSync #define NP HSync_Negative+VSync_Positive
#define NN SyncPol_InvertHSync+SyncPol_InvertVSync #define NN HSync_Negative+VSync_Negative
/* These timings are taken from the Display Monitor Timings v1.0 r11 Spec */ /* These timings are taken from the Display Monitor Timings v1.0 r11 Spec */
...@@ -1899,7 +1904,13 @@ static void generate_mode_using_gtf(double h_pixels, double v_lines, double ip_f ...@@ -1899,7 +1904,13 @@ static void generate_mode_using_gtf(double h_pixels, double v_lines, double ip_f
mode_desc->definition.vpar[FR_FPCH] = (int) v_fporch; mode_desc->definition.vpar[FR_FPCH] = (int) v_fporch;
mode_desc->definition.pixel_khz = (int) round(pixel_freq * 1000); mode_desc->definition.pixel_khz = (int) round(pixel_freq * 1000);
mode_desc->definition.external_clock = -1; mode_desc->definition.external_clock = -1;
mode_desc->definition.syncpol = 1; /* H Pol. -ve, V Pol +veYes, */ if (timing_support == EDID_USE_GTF) {
mode_desc->definition.syncpol = HSync_Negative+VSync_Positive; /* Default GTF */
}
else
{
mode_desc->definition.syncpol = HSync_Positive+VSync_Negative; /* Secondary GTF */
}
mode_desc->definition.interlaced = int_rqd; mode_desc->definition.interlaced = int_rqd;
sprintf(mode_desc->definition.name, "%d x %d", (int)h_pixels, (int)v_lines); sprintf(mode_desc->definition.name, "%d x %d", (int)h_pixels, (int)v_lines);
...@@ -1967,8 +1978,12 @@ static void generate_mode_using_cvt_rb(double h_pixels, double v_lines, double i ...@@ -1967,8 +1978,12 @@ static void generate_mode_using_cvt_rb(double h_pixels, double v_lines, double i
} }
if (v_sync_rnd == 0) { if (v_sync_rnd == 0) {
#if DODEBUG
printf("Error - Cannot handle this aspect ratio\n"); printf("Error - Cannot handle this aspect ratio\n");
#endif
/* If this happens we should just ignore the mode */ /* If this happens we should just ignore the mode */
free(mode_desc);
return;
} }
/* The variable names used below are those in the VESA Coordinated Timings /* The variable names used below are those in the VESA Coordinated Timings
...@@ -2144,44 +2159,50 @@ static void generate_mode_using_cvt_rb(double h_pixels, double v_lines, double i ...@@ -2144,44 +2159,50 @@ static void generate_mode_using_cvt_rb(double h_pixels, double v_lines, double i
/* Find the number of lines in V_sync + back porch: */ /* Find the number of lines in V_sync + back porch: */
v_back_porch = (int) (act_vbi_lines - v_front_porch - v_sync_rnd); v_back_porch = (int) (act_vbi_lines - v_front_porch - v_sync_rnd);
} }
/* Calculate front and back porch */ /* Calculate front and back porch */
int h_back_porch = h_blank / 2; int h_back_porch = h_blank / 2;
int h_front_porch = h_blank - h_back_porch - h_sync; int h_front_porch = h_blank - h_back_porch - h_sync;
/* Now populate the mode definition block */ /* Now populate the mode definition block */
mode_desc->definition.xres = (int)h_pixels; mode_desc->definition.xres = (int)h_pixels;
mode_desc->definition.yres = (int)v_lines; mode_desc->definition.yres = (int)v_lines;
mode_desc->definition.hpar[FR_SYNC] = h_sync; mode_desc->definition.hpar[FR_SYNC] = h_sync;
mode_desc->definition.hpar[FR_BPCH] = h_back_porch; mode_desc->definition.hpar[FR_BPCH] = h_back_porch;
mode_desc->definition.hpar[FR_BDR1] = (int) left_margin; mode_desc->definition.hpar[FR_BDR1] = (int) left_margin;
mode_desc->definition.hpar[FR_DISP] = (int) h_pixels; mode_desc->definition.hpar[FR_DISP] = (int) h_pixels;
mode_desc->definition.hpar[FR_BDR2] = (int) right_margin; mode_desc->definition.hpar[FR_BDR2] = (int) right_margin;
mode_desc->definition.hpar[FR_FPCH] = h_front_porch; mode_desc->definition.hpar[FR_FPCH] = h_front_porch;
mode_desc->definition.vpar[FR_SYNC] = (int) v_sync_rnd; mode_desc->definition.vpar[FR_SYNC] = (int) v_sync_rnd;
mode_desc->definition.vpar[FR_BPCH] = v_back_porch; mode_desc->definition.vpar[FR_BPCH] = v_back_porch;
mode_desc->definition.vpar[FR_BDR1] = (int) top_margin; mode_desc->definition.vpar[FR_BDR1] = (int) top_margin;
if (int_rqd) { if (int_rqd) {
mode_desc->definition.vpar[FR_DISP] = (int) v_lines / 2; mode_desc->definition.vpar[FR_DISP] = (int) v_lines / 2;
} }
else else
{ {
mode_desc->definition.vpar[FR_DISP] = (int) v_lines; mode_desc->definition.vpar[FR_DISP] = (int) v_lines;
} }
mode_desc->definition.vpar[FR_BDR2] = (int) bot_margin; mode_desc->definition.vpar[FR_BDR2] = (int) bot_margin;
mode_desc->definition.vpar[FR_FPCH] = (int) v_front_porch; mode_desc->definition.vpar[FR_FPCH] = (int) v_front_porch;
mode_desc->definition.pixel_khz = (int) (act_pixel_freq * 1000); mode_desc->definition.pixel_khz = (int) (act_pixel_freq * 1000);
mode_desc->definition.external_clock = -1; mode_desc->definition.external_clock = -1;
mode_desc->definition.syncpol = 0; if (timing_support == EDID_USE_CVT) {
mode_desc->definition.interlaced = int_rqd; mode_desc->definition.syncpol = HSync_Negative+VSync_Positive;
}
sprintf(mode_desc->definition.name, "%d x %d", (int)h_pixels, (int)v_lines); else /* EDID_USE_CVTRB */
compute_modedescription(mode_desc); {
mode_desc->definition.syncpol = HSync_Positive+VSync_Negative;
if (add_proposed_mode(monitor, mode_desc) == 0) { }
free(mode_desc); mode_desc->definition.interlaced = int_rqd;
}
sprintf(mode_desc->definition.name, "%d x %d", (int)h_pixels, (int)v_lines);
compute_modedescription(mode_desc);
if (add_proposed_mode(monitor, mode_desc) == 0) {
free(mode_desc);
}
#if DODEBUG #if DODEBUG
display_mode_parameters(mode_desc); display_mode_parameters(mode_desc);
...@@ -2440,7 +2461,7 @@ static _kernel_oserror *generate_cvt3_timing(char cvt1, char cvt2, char cvt3, Mo ...@@ -2440,7 +2461,7 @@ static _kernel_oserror *generate_cvt3_timing(char cvt1, char cvt2, char cvt3, Mo
* dtd_data on entry should be a pointer to the first byte of the 18 byte * dtd_data on entry should be a pointer to the first byte of the 18 byte
* dtd block. * dtd block.
*/ */
static void dtd_block_to_modedesc(char* dtd_data, ModeDescriptionRef mode_desc) static bool dtd_block_to_modedesc(char* dtd_data, ModeDescriptionRef mode_desc)
{ {
#if DODEBUG #if DODEBUG
printf("Detailed timing descriptor:\n"); printf("Detailed timing descriptor:\n");
...@@ -2470,8 +2491,30 @@ static void dtd_block_to_modedesc(char* dtd_data, ModeDescriptionRef mode_desc) ...@@ -2470,8 +2491,30 @@ static void dtd_block_to_modedesc(char* dtd_data, ModeDescriptionRef mode_desc)
mode_desc->definition.vpar[FR_BDR2]; mode_desc->definition.vpar[FR_BDR2];
mode_desc->definition.pixel_khz = (dtd_data[0] + (dtd_data[1]<<8)) * 10; mode_desc->definition.pixel_khz = (dtd_data[0] + (dtd_data[1]<<8)) * 10;
mode_desc->definition.external_clock = -1; mode_desc->definition.external_clock = -1;
mode_desc->definition.syncpol = ((!((dtd_data[17]>>2) & 1)<<1) + !((dtd_data[17]>>1) & 1));
/* Only accept non-stereoscopic modes
* Technically we should check for sync here (since we only really support
* digital separate syncs), but for now we'll assume that misrepresenting
* the sync isn't going to cause major problems, as it will allow more
* modes to work (e.g. BenQ FP241W HDMI port advertises 1080p as being
* serrated sync-on-RGB, even though the monitor is perfectly happy with
* digital syncs)
*/
if ((dtd_data[17] & 0x60) != 0x00) {
#if DODEBUG
printf("Rejecting DTD due to unsupported frame format\n");
#endif
return false;
}
/* -----00- is negative-negative, start with that and then invert if necessary */
mode_desc->definition.syncpol = HSync_Negative+VSync_Negative;
if (dtd_data[17] & 4) {
mode_desc->definition.syncpol ^= VSync_Negative^VSync_Positive;
}
if (dtd_data[17] & 2) {
mode_desc->definition.syncpol ^= HSync_Negative^HSync_Positive;
}
/* If we are interlaced, we need to double the number of vertical pixels */ /* If we are interlaced, we need to double the number of vertical pixels */
if (mode_desc->definition.interlaced == 1) { if (mode_desc->definition.interlaced == 1) {
...@@ -2485,6 +2528,8 @@ static void dtd_block_to_modedesc(char* dtd_data, ModeDescriptionRef mode_desc) ...@@ -2485,6 +2528,8 @@ static void dtd_block_to_modedesc(char* dtd_data, ModeDescriptionRef mode_desc)
#if DODEBUG #if DODEBUG
display_mode_parameters(mode_desc); display_mode_parameters(mode_desc);
#endif #endif
return true;
} }
...@@ -2525,11 +2570,16 @@ static _kernel_oserror *process_cea_extension_type_3(EDIDExtensionBlockRef ext_b ...@@ -2525,11 +2570,16 @@ static _kernel_oserror *process_cea_extension_type_3(EDIDExtensionBlockRef ext_b
return error (ERR_NOSPACE, 0, 0, 0); return error (ERR_NOSPACE, 0, 0, 0);
} }
dtd_block_to_modedesc((char *) &(extdata[dtd_offset]), mp); if (!dtd_block_to_modedesc((char *) &(extdata[dtd_offset]), mp)) {
mp->priority = 3;
if (add_proposed_mode(new_monitor, mp) == 0) {
free(mp); free(mp);
} }
else
{
mp->priority = 3;
if (add_proposed_mode(new_monitor, mp) == 0) {
free(mp);
}
}
dtd_offset += 18; /* 18 is the size of a DTD block */ dtd_offset += 18; /* 18 is the size of a DTD block */
} }
...@@ -2569,11 +2619,16 @@ static _kernel_oserror *process_vtb_extension_block(EDIDExtensionBlockRef ext_bl ...@@ -2569,11 +2619,16 @@ static _kernel_oserror *process_vtb_extension_block(EDIDExtensionBlockRef ext_bl
return error (ERR_NOSPACE, 0, 0, 0); return error (ERR_NOSPACE, 0, 0, 0);
} }
dtd_block_to_modedesc((char *) &(extdata[0x5 + dtb_blockno*0x12]), mp); if (!dtd_block_to_modedesc((char *) &(extdata[0x5 + dtb_blockno*0x12]), mp)) {
mp->priority = 3;
if (add_proposed_mode(new_monitor, mp) == 0) {
free(mp); free(mp);
} }
else
{
mp->priority = 3;
if (add_proposed_mode(new_monitor, mp) == 0) {
free(mp);
}
}
} }
for (int cvt_blockno = 0; cvt_blockno < y; cvt_blockno++) for (int cvt_blockno = 0; cvt_blockno < y; cvt_blockno++)
...@@ -2723,23 +2778,26 @@ static _kernel_oserror *parseedid(char *ediddata, const char *file) ...@@ -2723,23 +2778,26 @@ static _kernel_oserror *parseedid(char *ediddata, const char *file)
return error (ERR_NOSPACE, 0, 0, 0); return error (ERR_NOSPACE, 0, 0, 0);
} }
dtd_block_to_modedesc((char *) &(edidblockref->data_block[blockno][0]), mp); if (!dtd_block_to_modedesc((char *) &(edidblockref->data_block[blockno][0]), mp)) {
#if DODEBUG
printf("Detailed Mode: %s, X: %i Y: %i\n", mp->definition.name,mp->definition.xres, mp->definition.yres);
#endif
if (add_proposed_mode(new_monitor, mp) == 0) {
free(mp); free(mp);
} }
else { else
/* The first block should define the preferred mode */ {
if (blockno == 0) { #if DODEBUG
new_preferred_mode = mp; printf("Detailed Mode: %s, X: %i Y: %i\n", mp->definition.name,mp->definition.xres, mp->definition.yres);
mp->priority = 0x01; #endif
if (add_proposed_mode(new_monitor, mp) == 0) {
free(mp);
} }
else { else {
mp->priority = 0x02; /* The first block should define the preferred mode */
if (blockno == 0) {
new_preferred_mode = mp;
mp->priority = 0x01;
}
else {
mp->priority = 0x02;
}
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment