Generate EDID according to preferred resolution
from VBE_DISPI interface.
Signed-off-by: Hiroshi Miura <[email protected]>
---
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;
}
--
1.7.9.5
_______________________________________________
SeaBIOS mailing list
[email protected]
http://www.seabios.org/mailman/listinfo/seabios