Generate EDID according to preferred resolution from VBE_DISPI interface.
Signed-off-by: Hiroshi Miura miurahr@linux.com --- vgasrc/bochsedid.c | 54 ++++++++++++++++++++++++++++++++++++++++++---------- vgasrc/bochsedid.h | 1 + vgasrc/bochsvga.c | 2 ++ 3 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/vgasrc/bochsedid.c b/vgasrc/bochsedid.c index 5a40593..6bea389 100644 --- a/vgasrc/bochsedid.c +++ b/vgasrc/bochsedid.c @@ -47,6 +47,23 @@ struct edid_monitor_range_limit edid_range_limit VAR16 = { 0x20,0x20 /* padding */ };
+u16 prefered_xres VAR16, prefered_yres VAR16; + +void bochs_init_preferred_resolution(u16 max_xres, u16 max_yres) { + + if (max_xres >= 1920 && max_yres >= 1200){ + max_xres = 1920; max_yres = 1200; + } else if (max_xres >= 1600 && max_yres >= 1200){ + max_xres = 1600; max_yres = 1200; + } else if (max_xres >= 1280 && max_yres >= 1024){ + max_xres = 1280; max_yres = 1024; + } else { + max_xres = 1152; max_yres = 864; + } + SET_VGA(prefered_xres,max_xres); + SET_VGA(prefered_yres,max_yres); +} + int bochs_read_edid_block0(u16 unit, u16 block, u16 seg, void *data, u8 next) { struct edid_info *info = data; @@ -90,18 +107,34 @@ int bochs_read_edid_block0(u16 unit, u16 block, u16 seg, void *data, u8 next) /* 720x400@70Hz, 720x400@88Hz, 640x480@60Hz, 640x480@67Hz, 640x480@72Hz, 640x480@75Hz, 800x600@56Hz, 800x600@60Hz, 800x600@72Hz, 800x600@75Hz, 832x624@75Hz, 1152x870@75Hz, not 1024x768@87Hz(I), 1024x768@60Hz, 1024x768@70Hz, 1024x768@75Hz, 1280x1024@75Hz */ - /* standard timings */ + /* standard timings & detailed timing block */ SET_FARVAR(seg, info->standard_timing[0], EDID_STD_640x480_85Hz); SET_FARVAR(seg, info->standard_timing[1], EDID_STD_800x600_85Hz); - SET_FARVAR(seg, info->standard_timing[2], EDID_STD_1024x768_85Hz); - SET_FARVAR(seg, info->standard_timing[3], EDID_STD_1280x720_70Hz); - SET_FARVAR(seg, info->standard_timing[4], EDID_STD_1280x960_60Hz); - SET_FARVAR(seg, info->standard_timing[5], EDID_STD_1440x900_60Hz); - SET_FARVAR(seg, info->standard_timing[6], EDID_STD_1600x1200_60Hz); - SET_FARVAR(seg, info->standard_timing[7], EDID_STD_NOP); - /* detailed timing blocks */ - memcpy_far(seg, &(info->desc[0].dtd), get_global_seg(), &edid_dtd_1600x1200, - sizeof (edid_dtd_1600x1200)); + if (GET_GLOBAL(prefered_xres) < 1280) { + SET_FARVAR(seg, info->standard_timing[2], EDID_STD_1024x768_85Hz); + SET_FARVAR(seg, info->standard_timing[3], EDID_STD_1152x864_70Hz); + memcpy_far(seg, &(info->desc[0].dtd), get_global_seg(), &edid_dtd_1152x864, + sizeof (struct edid_detailed_timing)); + } else if (GET_GLOBAL(prefered_xres) < 1600) { + SET_FARVAR(seg, info->standard_timing[2], EDID_STD_1024x768_85Hz); + SET_FARVAR(seg, info->standard_timing[3], EDID_STD_1280x1024_60Hz); + memcpy_far(seg, &(info->desc[0].dtd), get_global_seg(), &edid_dtd_1280x1024, + sizeof (struct edid_detailed_timing)); + } else if (GET_GLOBAL(prefered_xres) >= 1600 && GET_GLOBAL(prefered_xres) < 1920) { + SET_FARVAR(seg, info->standard_timing[2], EDID_STD_1440x900_60Hz); + SET_FARVAR(seg, info->standard_timing[3], EDID_STD_1600x1200_60Hz); + memcpy_far(seg, &(info->desc[0].dtd), get_global_seg(), &edid_dtd_1600x1200, + sizeof (struct edid_detailed_timing)); + } else { + SET_FARVAR(seg, info->standard_timing[2], EDID_STD_1440x900_60Hz); + SET_FARVAR(seg, info->standard_timing[3], EDID_STD_1920x1200_60Hz); + memcpy_far(seg, &(info->desc[0].dtd), get_global_seg(), &edid_dtd_1920x1200, + sizeof (struct edid_detailed_timing)); + } + for (i = 4; i < 8; i++) { /* FILL with NOP */ + SET_FARVAR(seg, info->standard_timing[i], EDID_STD_NOP); + } + /* detailed timing block here has already set with standard timings */ /* monitor range */ memcpy_far(seg, &(info->desc[1].mrld), get_global_seg(), &edid_range_limit, sizeof(edid_range_limit)); @@ -145,3 +178,4 @@ int bochs_read_edid(u16 unit, u16 block, u16 seg, void *data) return -1; } } + diff --git a/vgasrc/bochsedid.h b/vgasrc/bochsedid.h index 0f925df..be60f9f 100644 --- a/vgasrc/bochsedid.h +++ b/vgasrc/bochsedid.h @@ -131,6 +131,7 @@ struct edid_info { #define EDID_STD_1920x1200_60Hz 0x00D1 #define EDID_STD_NOP 0x0101
+void bochs_init_preferred_resolution(u16 max_xres, u16 max_yres); int bochs_get_ddc_capabilities(u16 unit); int bochs_read_edid(u16 unit, u16 block, u16 seg, void *data); #endif /* bochedid.h */ diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 2a8aeb1..72240c3 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -373,6 +373,7 @@ bochsvga_init(void) u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE); dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS); u16 max_xres = dispi_read(VBE_DISPI_INDEX_XRES); + u16 max_yres = dispi_read(VBE_DISPI_INDEX_YRES); u16 max_bpp = dispi_read(VBE_DISPI_INDEX_BPP); dispi_write(VBE_DISPI_INDEX_ENABLE, en); struct bochsvga_mode *m = bochsvga_modes; @@ -388,6 +389,7 @@ bochsvga_init(void) SET_VGA(m->mode, 0xffff); } } + bochs_init_preferred_resolution(max_xres, max_yres);
return 0; }