Preferred resolution detection for VBE.

* grub-core/video/video.c (grub_video_edid_checksum): New function.
(grub_video_edid_preferred_mode): Likewise.  Try EDID followed by
the Flat Panel extension, in line with the X.org VESA driver.
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info):
New function.
(grub_vbe_bios_get_ddc_capabilities): Likewise.
(grub_vbe_bios_read_edid): Likewise.
(grub_vbe_get_preferred_mode): Likewise.
(grub_video_vbe_setup): When the mode is "auto", try to get the
preferred mode from VBE, and use the largest mode that is no larger
than the preferred mode (some BIOSes expose a preferred mode that is
not in their mode list!).  If this fails, fall back to 640x480 as a
safe conservative choice.
(grub_video_vbe_get_edid): New function.
(grub_video_vbe_adapter): Add get_edid.
* include/grub/video.h (struct grub_vbe_edid_info): New structure.
(struct grub_video_adapter): Add get_edid.
(grub_video_edid_checksum): Add prototype.
(grub_video_edid_preferred_mode): Likewise.
* include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New
structure.

* grub-core/commands/videoinfo.c (print_edid): New function.
(grub_cmd_videoinfo): Print EDID if available.

* util/grub.d/00_header.in (GRUB_GFXMODE): Default to "auto".  This
is more appropriate on a wider range of platforms than 640x480.
* docs/grub.texi (Simple configuration): Update GRUB_GFXMODE
documentation.
This commit is contained in:
Colin Watson 2011-07-21 19:46:44 +01:00
commit 8fc4fa45c5
8 changed files with 333 additions and 6 deletions

View file

@ -19,6 +19,8 @@
#ifndef GRUB_VBE_MACHINE_HEADER
#define GRUB_VBE_MACHINE_HEADER 1
#include <grub/video.h>
/* Default video mode to be used. */
#define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101
@ -169,6 +171,21 @@ struct grub_vbe_palette_data
grub_uint8_t alignment;
} __attribute__ ((packed));
struct grub_vbe_flat_panel_info
{
grub_uint16_t horizontal_size;
grub_uint16_t vertical_size;
grub_uint16_t panel_type;
grub_uint8_t red_bpp;
grub_uint8_t green_bpp;
grub_uint8_t blue_bpp;
grub_uint8_t reserved_bpp;
grub_uint32_t reserved_offscreen_mem_size;
grub_vbe_farptr_t reserved_offscreen_mem_ptr;
grub_uint8_t reserved[14];
} __attribute__ ((packed));
/* Prototypes for helper functions. */
/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */
grub_vbe_status_t

View file

@ -210,6 +210,66 @@ struct grub_video_palette_data
grub_uint8_t a; /* Reserved bits value (0-255). */
};
struct grub_video_edid_info
{
grub_uint8_t header[8];
grub_uint16_t manufacturer_id;
grub_uint16_t product_id;
grub_uint32_t serial_number;
grub_uint8_t week_of_manufacture;
grub_uint8_t year_of_manufacture;
grub_uint8_t version;
grub_uint8_t revision;
grub_uint8_t video_input_definition;
grub_uint8_t max_horizontal_image_size;
grub_uint8_t max_vertical_image_size;
grub_uint8_t display_gamma;
grub_uint8_t feature_support;
#define GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1)
grub_uint8_t red_green_lo;
grub_uint8_t blue_white_lo;
grub_uint8_t red_x_hi;
grub_uint8_t red_y_hi;
grub_uint8_t green_x_hi;
grub_uint8_t green_y_hi;
grub_uint8_t blue_x_hi;
grub_uint8_t blue_y_hi;
grub_uint8_t white_x_hi;
grub_uint8_t white_y_hi;
grub_uint8_t established_timings_1;
grub_uint8_t established_timings_2;
grub_uint8_t manufacturer_reserved_timings;
grub_uint16_t standard_timings[8];
struct {
grub_uint16_t pixel_clock;
/* Only valid if the pixel clock is non-null. */
grub_uint8_t horizontal_active_lo;
grub_uint8_t horizontal_blanking_lo;
grub_uint8_t horizontal_hi;
grub_uint8_t vertical_active_lo;
grub_uint8_t vertical_blanking_lo;
grub_uint8_t vertical_hi;
grub_uint8_t horizontal_sync_offset_lo;
grub_uint8_t horizontal_sync_pulse_width_lo;
grub_uint8_t vertical_sync_lo;
grub_uint8_t sync_hi;
grub_uint8_t horizontal_image_size_lo;
grub_uint8_t vertical_image_size_lo;
grub_uint8_t image_size_hi;
grub_uint8_t horizontal_border;
grub_uint8_t vertical_border;
grub_uint8_t flags;
} detailed_timings[4];
grub_uint8_t extension_flag;
grub_uint8_t checksum;
} __attribute__ ((packed));
typedef enum grub_video_driver_id
{
GRUB_VIDEO_DRIVER_NONE,
@ -312,6 +372,8 @@ struct grub_video_adapter
int (*iterate) (int (*hook) (const struct grub_video_mode_info *info));
grub_err_t (*get_edid) (struct grub_video_edid_info *edid_info);
void (*print_adapter_specific_info) (void);
};
typedef struct grub_video_adapter *grub_video_adapter_t;
@ -424,6 +486,11 @@ grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_
grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
grub_err_t grub_video_edid_checksum (struct grub_video_edid_info *edid_info);
grub_err_t grub_video_edid_preferred_mode (struct grub_video_edid_info *edid_info,
unsigned int *width,
unsigned int *height);
grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring,
unsigned int modemask,
unsigned int modevalue);