Commit 36800dfd authored by John Ballance's avatar John Ballance
Browse files

Made safer to deploy in current ROMS, and added further stuff to generated mdf

Detail:
  Added several things
  1) Readedid routine not called in module initialise.
  2) Flag added to determine whether old loadmodefile usage, or new readedid usage.
     Defaults to loadmodefile mode until a readedid command with no parameters,
     then swirches to edid reading mode. Reverts again if loadmodefile command is used.
  3) Tidied up error message when graphicsv fails to read the edid due to connectivity
     issues.
  4) Added hex dump of edid data blocks read to end of a saved mdf file.
  5) Implemented read of second ans subsequent 128 byte edid blocks, if required.

Admin:
  tested in imx rom

Version 0.41. Tagged as 'ScrModes-0_41'
parent f2073d25
...@@ -26,3 +26,4 @@ E23:Es wird eine Zahl erwartet. ...@@ -26,3 +26,4 @@ E23:Es wird eine Zahl erwartet.
E24:Es wurde ein zu großer Parameterwert angegeben. E24:Es wurde ein zu großer Parameterwert angegeben.
E25:EDID checksum is incorrect (block %0 of %1 failed) - cannot read monitor settings E25:EDID checksum is incorrect (block %0 of %1 failed) - cannot read monitor settings
E26:Unable to read EDID - does this hardware support it? E26:Unable to read EDID - does this hardware support it?
E27:EDID channel communications error.
...@@ -26,3 +26,4 @@ E23:Number expected ...@@ -26,3 +26,4 @@ E23:Number expected
E24:Overlarge value for parameter E24:Overlarge value for parameter
E25:EDID checksum is incorrect (block %0 of %1 failed) - cannot read monitor settings E25:EDID checksum is incorrect (block %0 of %1 failed) - cannot read monitor settings
E26:Unable to read EDID - does this hardware support it? E26:Unable to read EDID - does this hardware support it?
E27:EDID channel communications error.
/* (0.40) /* (0.41)
* *
* 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.40 #define Module_MajorVersion_CMHG 0.41
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 10 Feb 2015 #define Module_Date_CMHG 11 Feb 2015
#define Module_MajorVersion "0.40" #define Module_MajorVersion "0.41"
#define Module_Version 40 #define Module_Version 41
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "10 Feb 2015" #define Module_Date "11 Feb 2015"
#define Module_ApplicationDate "10-Feb-15" #define Module_ApplicationDate "11-Feb-15"
#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.40" #define Module_FullVersion "0.41"
#define Module_HelpVersion "0.40 (10 Feb 2015)" #define Module_HelpVersion "0.41 (11 Feb 2015)"
#define Module_LibraryVersionInfo "0:40" #define Module_LibraryVersionInfo "0:41"
...@@ -49,6 +49,11 @@ static int timing_support = EDID_USE_DMT; ...@@ -49,6 +49,11 @@ static int timing_support = EDID_USE_DMT;
#define DODEBUG 0 #define DODEBUG 0
#endif #endif
/* switch to define whether EDID is computed, or whether only traditional *
* loadmodefile activity happens. EDID activity enabled by a ReadEDID *
* command, and disabled by a LoadModeFile command */
static bool EDIDEnabled;
/* Uncomment the next line and set the value to force a particular timing calculation type */ /* Uncomment the next line and set the value to force a particular timing calculation type */
//#define FORCE_TIMINGS EDID_USE_CVTRB //#define FORCE_TIMINGS EDID_USE_CVTRB
...@@ -1461,6 +1466,7 @@ static _kernel_oserror *loadtextMDF (const char *file) ...@@ -1461,6 +1466,7 @@ static _kernel_oserror *loadtextMDF (const char *file)
{ {
_kernel_oserror *res; _kernel_oserror *res;
MonitorDescriptionRef new_monitor; MonitorDescriptionRef new_monitor;
EDIDEnabled = 0; /* disable any automatic edid stuff */
debug printf ("file opened OK\n"); debug printf ("file opened OK\n");
res = parse_modefile (&new_monitor); res = parse_modefile (&new_monitor);
...@@ -2281,11 +2287,14 @@ static int get_extd_type(EDIDBlockRef edidblockref, int block_no) ...@@ -2281,11 +2287,14 @@ static int get_extd_type(EDIDBlockRef edidblockref, int block_no)
static _kernel_oserror *parseedid(char *ediddata, FILE *f) static _kernel_oserror *parseedid(char *ediddata, FILE *f)
{ {
_kernel_oserror *res; _kernel_oserror *res = NULL;
MonitorDescriptionRef new_monitor; MonitorDescriptionRef new_monitor;
ModeDescriptionRef new_preferred_mode = NULL; /* No preferred mode */ ModeDescriptionRef new_preferred_mode = NULL; /* No preferred mode */
EDIDBlockRef edidblockref = (EDIDBlockRef) ediddata; EDIDBlockRef edidblockref = (EDIDBlockRef) ediddata;
int RangeBlock = 0; /* edid block containing timimg limits */ int RangeBlock = 0; /* edid block containing timimg limits */
if(!EDIDEnabled) { /* only if needed!! */
return res;
}
/* OK, commit to reading a monitor description - go allocate space */ /* OK, commit to reading a monitor description - go allocate space */
new_monitor = (MonitorDescriptionRef) malloc (sizeof(MonitorDescription)); new_monitor = (MonitorDescriptionRef) malloc (sizeof(MonitorDescription));
...@@ -2297,7 +2306,7 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f) ...@@ -2297,7 +2306,7 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f)
strcpy(new_monitor->name,"Display"); strcpy(new_monitor->name,"Display");
new_monitor->dpms_state = -1; /* DPMS -1 = Indicates not available */ new_monitor->dpms_state = -1; /* DPMS -1 = Indicates not available */
new_monitor->lcd_support = 0; /* 'CRT by default' - what does this do??? */ new_monitor->lcd_support = 0; /* 'CRT by default' - what does this do???*/
new_monitor->output_format = -1; /* Output format */ new_monitor->output_format = -1; /* Output format */
new_monitor->external_clock = -1; /* External clock not present */ new_monitor->external_clock = -1; /* External clock not present */
new_monitor->modelist = NULL; /* Make sure the mode list is initially nil. */ new_monitor->modelist = NULL; /* Make sure the mode list is initially nil. */
...@@ -2526,8 +2535,7 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f) ...@@ -2526,8 +2535,7 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f)
#if DODEBUG #if DODEBUG
printf("Modes sorted\n"); printf("Modes sorted\n");
#endif #endif
if(f) if(f) {
{
fprintf(f,"# Monitor description file for %s\n",new_monitor->name); fprintf(f,"# Monitor description file for %s\n",new_monitor->name);
fprintf(f,"# Created by ScrModes %s\n",Module_VersionString); fprintf(f,"# Created by ScrModes %s\n",Module_VersionString);
fprintf(f,"# (EDID specified modes only, no calculated modes)\n\n"); fprintf(f,"# (EDID specified modes only, no calculated modes)\n\n");
...@@ -2550,35 +2558,49 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f) ...@@ -2550,35 +2558,49 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f)
fprintf(f,"# Uses %s frequency pixel clocks\n", ((edidblockref->feature_support & 1) == 1)?"Continuous":"Specific"); fprintf(f,"# Uses %s frequency pixel clocks\n", ((edidblockref->feature_support & 1) == 1)?"Continuous":"Specific");
char *rules="unknown"; char *rules="unknown";
switch(timing_support) switch(timing_support) {
{
case EDID_USE_CVT:rules="CVT";break; case EDID_USE_CVT:rules="CVT";break;
case EDID_USE_DMT:rules="DMT";break; case EDID_USE_DMT:rules="DMT";break;
case EDID_USE_CVTRB:rules="CVTRB";break; case EDID_USE_CVTRB:rules="CVTRB";break;
case EDID_USE_GTF:rules="GTF";break; case EDID_USE_GTF:rules="GTF";break;
case EDID_USE_GTF2:rules="GTF2";break; case EDID_USE_GTF2:rules="GTF2";break;
} }
fprintf(f,"# Use %s timing rules\n",rules); fprintf(f,"# Use %s timing rules\n#\n",rules);
fprintf(f,"file_format:1\nmonitor_title:%s\nDPMS_state:%d\n",new_monitor->name,(new_monitor->dpms_state==-1)?0:new_monitor->dpms_state); fprintf(f,"file_format:1\nmonitor_title:%s\n",new_monitor->name);
if(new_monitor->dpms_state!=-1) {
fprintf(f,"DPMS_state:%d\n",new_monitor->dpms_state);
}
ModeDescriptionRef this = new_monitor->modelist; ModeDescriptionRef this = new_monitor->modelist;
do do {
{ fprintf(f,"\n# Mode: %d x %d @ %dHz",this->definition.hpar[FR_DISP],this->definition.vpar[FR_DISP],this->frame_hz);
fprintf(f,"\n# Mode: %d x %d @ %dHz",this->definition.hpar[FR_DISP],this->definition.vpar[FR_DISP],this->frame_hz); float tmp =(float)(this->definition.hpar[0]+this->definition.hpar[1]+this->definition.hpar[2]+this->definition.hpar[3]+this->definition.hpar[4]+this->definition.hpar[5]);
float tmp =(float)(this->definition.hpar[0]+this->definition.hpar[1]+this->definition.hpar[2]+this->definition.hpar[3]+this->definition.hpar[4]+this->definition.hpar[5]); fprintf(f,"\n# Bounds: H %3.2fkHz, V %3.2f, DClock %3.2fMHz",((float)(this->definition.pixel_khz))/tmp,(float)(this->frame_hz),(float)(this->definition.pixel_khz)/1000);
fprintf(f,"\n# Bounds: H %3.2fkHz, V %3.2f, DClock %3.2fMHz",((float)(this->definition.pixel_khz))/tmp,(float)(this->frame_hz),(float)(this->definition.pixel_khz)/1000); fprintf(f,"\nstartmode");
fprintf(f,"\nstartmode"); fprintf(f,"\n mode_name:%d x %d",this->definition.hpar[FR_DISP],this->definition.vpar[FR_DISP]);
fprintf(f,"\n mode_name:%d x %d",this->definition.hpar[FR_DISP],this->definition.vpar[FR_DISP]); fprintf(f,"\n x_res:%d",this->definition.hpar[FR_DISP]);
fprintf(f,"\n x_res:%d",this->definition.hpar[FR_DISP]); fprintf(f,"\n y_res:%d",this->definition.vpar[FR_DISP]);
fprintf(f,"\n y_res:%d",this->definition.vpar[FR_DISP]); fprintf(f,"\n pixel_rate:%d",this->definition.pixel_khz);
fprintf(f,"\n pixel_rate:%d",this->definition.pixel_khz); fprintf(f,"\n h_timings:%d,%d,%d,%d,%d,%d",this->definition.hpar[0],this->definition.hpar[1],this->definition.hpar[2],this->definition.hpar[3],this->definition.hpar[4],this->definition.hpar[5]);
fprintf(f,"\n h_timings:%d,%d,%d,%d,%d,%d",this->definition.hpar[0],this->definition.hpar[1],this->definition.hpar[2],this->definition.hpar[3],this->definition.hpar[4],this->definition.hpar[5]); fprintf(f,"\n v_timings:%d,%d,%d,%d,%d,%d",this->definition.vpar[0],this->definition.vpar[1],this->definition.vpar[2],this->definition.vpar[3],this->definition.vpar[4],this->definition.vpar[5]);
fprintf(f,"\n v_timings:%d,%d,%d,%d,%d,%d",this->definition.vpar[0],this->definition.vpar[1],this->definition.vpar[2],this->definition.vpar[3],this->definition.vpar[4],this->definition.vpar[5]); fprintf(f,"\n sync_pol:%d",this->definition.syncpol);
fprintf(f,"\n sync_pol:%d",this->definition.syncpol); if (this->definition.interlaced == 1) {
fprintf(f,"\nEndMode\n"); fprintf(f,"\n interlaced:");
this = this->next; /* will be NULL at list end*/ }
fprintf(f,"\nEndMode\n");
this = this->next; /* will be NULL at list end*/
} while (this); } while (this);
fprintf(f,"#End\n"); /* now fo hex dump of EDID block */
fprintf(f,"# EDID block dump\n#\n");
for (int i=0; i<(edidblockref->extension_block_count+1)*0x80;i+=16) {
fprintf(f,"# %02x %02x %02x %02x %02x %02x %02x %02x",
ediddata[i],ediddata[i+1],ediddata[i+2],ediddata[i+3],
ediddata[i+4],ediddata[i+5],ediddata[i+6],ediddata[i+7]);
fprintf(f," %02x %02x %02x %02x %02x %02x %02x %02x\n",
ediddata[i+8],ediddata[i+9],ediddata[i+10],ediddata[i+11],
ediddata[i+12],ediddata[i+13],ediddata[i+14],ediddata[i+15]);
}
fprintf(f,"#\n#End\n");
} }
else else
{ {
...@@ -2591,46 +2613,44 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f) ...@@ -2591,46 +2613,44 @@ static _kernel_oserror *parseedid(char *ediddata, FILE *f)
} }
res = set_monitortype (MONITOR_FILE); res = set_monitortype (MONITOR_FILE);
if (res != NULL) if (res != NULL) {
{ _kernel_oserror *res2;
_kernel_oserror *res2; debug printf ("setting of monitor type to type `FILE' failed\n");
debug printf ("setting of monitor type to type `FILE' failed\n"); res2 = restore_monitortype (); /* restore old value */
res2 = restore_monitortype (); /* restore old value */ if (res2 != NULL)
if (res2 != NULL) {
{ debug printf ("couldn't reset monitor type to CMOS default!\n");
debug printf ("couldn't reset monitor type to CMOS default!\n"); }
}
} }
else else {
{ _kernel_swi_regs regs;
_kernel_swi_regs regs; release_currentmonitor ();
release_currentmonitor (); current_monitor = new_monitor;
current_monitor = new_monitor;
/* Set up the mode specifier */
/* Set up the mode specifier */ preferred_mode->bit0 = 1;
preferred_mode->bit0 = 1; preferred_mode->format = 0;
preferred_mode->format = 0; preferred_mode->xresol = new_preferred_mode->definition.hpar[FR_DISP];
preferred_mode->xresol = new_preferred_mode->definition.hpar[FR_DISP]; preferred_mode->yresol = new_preferred_mode->definition.vpar[FR_DISP];
preferred_mode->yresol = new_preferred_mode->definition.vpar[FR_DISP]; preferred_mode->depth = 5;
preferred_mode->depth = 5; preferred_mode->framerate = new_preferred_mode->frame_hz;
preferred_mode->framerate = new_preferred_mode->frame_hz; preferred_mode->param[0].index = -1;
preferred_mode->param[0].index = -1;
/* Set the preferred sync type from video input definition bit 3. */
/* Set the preferred sync type from video input definition bit 3. */ /* (ref EDID spec table 3.11) */
/* (ref EDID spec table 3.11) */ if ((edidblockref->video_input_definition & 0x8) == 0x8) {
if ((edidblockref->video_input_definition & 0x8) == 0x8) { preferred_sync_type = 0;
preferred_sync_type = 0; }
} else {
else { preferred_sync_type = 1;
preferred_sync_type = 1; }
}
debug printf("Monitor type changed\n");
debug printf("Monitor type changed\n");
/* Newly defined monitor, announce it */
/* Newly defined monitor, announce it */ regs.r[1] = Service_ModeFileChanged;
regs.r[1] = Service_ModeFileChanged; _kernel_swi (OS_ServiceCall, &regs, &regs);
_kernel_swi (OS_ServiceCall, &regs, &regs); debug printf("Service_ModeFileChanged issued\n");
debug printf("Service_ModeFileChanged issued\n");
} }
} }
...@@ -2710,38 +2730,46 @@ static _kernel_oserror *loadmodefile (const char *file) ...@@ -2710,38 +2730,46 @@ static _kernel_oserror *loadmodefile (const char *file)
return res; return res;
} }
static _kernel_oserror *readedid (const char *file) static _kernel_oserror *readedidblock (EDIDBlockRef edidblock, int count)
{ {
_kernel_oserror *res; _kernel_oserror *res;
FILE *f = NULL;
EDIDBlockRef edidblock = (EDIDBlockRef) malloc(128);
if (edidblock == NULL) {
return error (ERR_NOSPACE, 0, 0, 0);
}
if (file)
{
f = fopen (file, "w");
}
debug printf ("ReadEDID called\n");
int iic_code = (0xa1 << 16) | (0 << 0); int iic_code = (0xa1 << 16) | (0 << 0);
int op_code = (0 << 24) | (0 << 16) | (14 << 0); int op_code = (0 << 24) | (0 << 16) | (14 << 0);
res = _swix(OS_CallAVector, _INR(0,2) | _IN(4) | _IN(9) | _OUT(0) | _OUT(4), iic_code, edidblock, 0x80, op_code, 42, &iic_code, &op_code); res = _swix(OS_CallAVector, _INR(0,2) | _IN(4) | _IN(9) | _OUT(0) | _OUT(4), iic_code, edidblock, 0x80*count, op_code, 42, &iic_code, &op_code);
/* If GraphicsV 14 was not claimed, R4 (op_code) should return /* If GraphicsV 14 was not claimed, R4 (op_code) should return
unchanged in which case we need to alert the user that the unchanged in which case we need to alert the user that the
hardware doesn't like EDID :-( */ hardware doesn't like EDID :-( */
if (iic_code != 0) { if (iic_code != 0) {
res = error (iic_code, 0, 0, 0); /*res = error (iic_code, 0, 0, 0);*/
res = error (ERR_IICOPFAIL, 0, 0, 0);
} }
/* An 'EDID read not supported' error will trump an IIC failure. */ /* An 'EDID read not supported' error will trump an IIC failure. */
if (op_code != 0) { if (op_code != 0) {
res = error (ERR_CANTREADEDID, 0, 0, 0); res = error (ERR_CANTREADEDID, 0, 0, 0);
} }
return res;
}
static _kernel_oserror *readedid (int displaynum, const char *file)
{
_kernel_oserror *res;
FILE *f = NULL;
EDIDBlockRef edidblock = (EDIDBlockRef) malloc(128);
if (edidblock == NULL) {
return error (ERR_NOSPACE, 0, 0, 0);
}
if (file)
{
f = fopen (file, "w");
}
debug printf ("ReadEDID called\n");
res = readedidblock (edidblock, 1);
/* Check the block is valid */ /* Check the block is valid */
if (!res) { if (!res) {
...@@ -2764,6 +2792,8 @@ static _kernel_oserror *readedid (const char *file) ...@@ -2764,6 +2792,8 @@ static _kernel_oserror *readedid (const char *file)
res = error (ERR_NOSPACE, 0, 0, 0); res = error (ERR_NOSPACE, 0, 0, 0);
/* TO DO NOW READ THE ADDITIONAL EDID DATA HERE */ /* TO DO NOW READ THE ADDITIONAL EDID DATA HERE */
res = readedidblock (edidblock, edidblock->extension_block_count + 1);
/* Check the block is valid */ /* Check the block is valid */
if (!res) { if (!res) {
res = Check_EDID_Checksum((char *)edidblock, EDID_Check_AllBlocks); res = Check_EDID_Checksum((char *)edidblock, EDID_Check_AllBlocks);
...@@ -2773,8 +2803,9 @@ static _kernel_oserror *readedid (const char *file) ...@@ -2773,8 +2803,9 @@ static _kernel_oserror *readedid (const char *file)
} }
if (!res) { if (!res) {
debug printf ("Parsing EDID block\n"); debug printf ("Parsing EDID block\n");
res = parseedid(ediddata,f); EDIDEnabled = 1;
res = parseedid(ediddata,f);
} }
if(f) { if(f) {
...@@ -3465,7 +3496,7 @@ static void service_displaychanged (_kernel_swi_regs *regs) ...@@ -3465,7 +3496,7 @@ static void service_displaychanged (_kernel_swi_regs *regs)
driver-specific things which we store. driver-specific things which we store.
At the moment all the driver-specific stuff happens during the At the moment all the driver-specific stuff happens during the
enumerate/translate calls, so there's nothing to do. */ enumerate/translate calls, so there's nothing to do. */
res = readedid(NULL); res = readedid(0,NULL);
break; break;
case DisplayChanged_Changed: case DisplayChanged_Changed:
...@@ -3508,8 +3539,7 @@ _kernel_oserror *ScreenModes_initialise(const char *cmd_tail, int podule_base, v ...@@ -3508,8 +3539,7 @@ _kernel_oserror *ScreenModes_initialise(const char *cmd_tail, int podule_base, v
UNUSED(cmd_tail); UNUSED(cmd_tail);
UNUSED(podule_base); UNUSED(podule_base);
UNUSED(pw); UNUSED(pw);
EDIDEnabled = 0; /* not enabled on module boot */
readedid(NULL);
return NULL; return NULL;
} }
...@@ -3574,7 +3604,7 @@ _kernel_oserror *ScreenModes_cmdhandler (const char *arg_string, int argc, int c ...@@ -3574,7 +3604,7 @@ _kernel_oserror *ScreenModes_cmdhandler (const char *arg_string, int argc, int c
result = loadmodefile (arg_string); result = loadmodefile (arg_string);
break; break;
case CMD_ReadEDID: case CMD_ReadEDID:
result = readedid (arg_string); result = readedid (0,arg_string);
break; break;
default: default:
return NULL; return NULL;
......
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