move generic parts of EDID handling (structure, checksumming) to generic location
This commit is contained in:
parent
e03f549b3e
commit
25d884a52a
5 changed files with 92 additions and 87 deletions
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
Preferred resolution detection for VBE.
|
Preferred resolution detection for VBE.
|
||||||
|
|
||||||
|
* grub-core/video/video.c (grub_video_edid_checksum): New function.
|
||||||
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info):
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info):
|
||||||
New function.
|
Likewise.
|
||||||
(grub_vbe_bios_get_ddc_capabilities): Likewise.
|
(grub_vbe_bios_get_ddc_capabilities): Likewise.
|
||||||
(grub_vbe_bios_read_edid): Likewise.
|
(grub_vbe_bios_read_edid): Likewise.
|
||||||
(grub_vbe_edid_checksum): Likewise.
|
|
||||||
(grub_vbe_get_preferred_mode): Likewise. Try EDID followed by the
|
(grub_vbe_get_preferred_mode): Likewise. Try EDID followed by the
|
||||||
Flat Panel extension, in line with the X.org VESA driver.
|
Flat Panel extension, in line with the X.org VESA driver.
|
||||||
(grub_video_vbe_setup): When the mode is "auto", try to get the
|
(grub_video_vbe_setup): When the mode is "auto", try to get the
|
||||||
|
@ -14,9 +14,10 @@
|
||||||
than the preferred mode (some BIOSes expose a preferred mode that is
|
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
|
not in their mode list!). If this fails, fall back to 640x480 as a
|
||||||
safe conservative choice.
|
safe conservative choice.
|
||||||
|
* include/grub/video.h (struct grub_vbe_edid_info): New structure.
|
||||||
|
(grub_video_edid_checksum): Add prototype.
|
||||||
* include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New
|
* include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New
|
||||||
structure.
|
structure.
|
||||||
(struct grub_vbe_edid_info): Likewise.
|
|
||||||
(grub_vbe_bios_get_flat_panel_info): Add prototype.
|
(grub_vbe_bios_get_flat_panel_info): Add prototype.
|
||||||
(grub_vbe_bios_get_ddc_capabilities): Likewise.
|
(grub_vbe_bios_get_ddc_capabilities): Likewise.
|
||||||
(grub_vbe_bios_read_edid): Likewise.
|
(grub_vbe_bios_read_edid): Likewise.
|
||||||
|
|
|
@ -308,7 +308,7 @@ grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level)
|
||||||
|
|
||||||
/* Call VESA BIOS 0x4f15 to read EDID information, return status. */
|
/* Call VESA BIOS 0x4f15 to read EDID information, return status. */
|
||||||
grub_vbe_status_t
|
grub_vbe_status_t
|
||||||
grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_info)
|
grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_info)
|
||||||
{
|
{
|
||||||
struct grub_bios_int_registers regs;
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
@ -377,31 +377,12 @@ grub_vbe_probe (struct grub_vbe_info_block *info_block)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_vbe_edid_checksum (struct grub_vbe_edid_info *edid_info)
|
|
||||||
{
|
|
||||||
const char *edid_bytes = (const char *) edid_info;
|
|
||||||
int i;
|
|
||||||
char checksum = 0;
|
|
||||||
|
|
||||||
/* Check EDID checksum. */
|
|
||||||
for (i = 0; i < 128; ++i)
|
|
||||||
checksum += edid_bytes[i];
|
|
||||||
|
|
||||||
if (checksum != 0)
|
|
||||||
return grub_error (GRUB_ERR_BAD_DEVICE,
|
|
||||||
"invalid EDID checksum %d", checksum);
|
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height)
|
grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height)
|
||||||
{
|
{
|
||||||
grub_vbe_status_t status;
|
grub_vbe_status_t status;
|
||||||
grub_uint8_t ddc_level;
|
grub_uint8_t ddc_level;
|
||||||
struct grub_vbe_edid_info edid_info;
|
struct grub_video_edid_info edid_info;
|
||||||
struct grub_vbe_flat_panel_info flat_panel_info;
|
struct grub_vbe_flat_panel_info flat_panel_info;
|
||||||
|
|
||||||
if (controller_info.version >= 0x200
|
if (controller_info.version >= 0x200
|
||||||
|
@ -412,10 +393,10 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height)
|
||||||
/* Bit 1 in the Feature Support field indicates that the first
|
/* Bit 1 in the Feature Support field indicates that the first
|
||||||
Detailed Timing Description is the preferred timing mode. */
|
Detailed Timing Description is the preferred timing mode. */
|
||||||
if (status == GRUB_VBE_STATUS_OK
|
if (status == GRUB_VBE_STATUS_OK
|
||||||
&& grub_vbe_edid_checksum (&edid_info) == GRUB_ERR_NONE
|
&& grub_video_edid_checksum (&edid_info) == GRUB_ERR_NONE
|
||||||
&& edid_info.version == 1 /* we don't understand later versions */
|
&& edid_info.version == 1 /* we don't understand later versions */
|
||||||
&& (edid_info.feature_support
|
&& (edid_info.feature_support
|
||||||
& GRUB_VBE_EDID_FEATURE_PREFERRED_TIMING_MODE)
|
& GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE)
|
||||||
&& edid_info.detailed_timings[0].pixel_clock)
|
&& edid_info.detailed_timings[0].pixel_clock)
|
||||||
{
|
{
|
||||||
*width = edid_info.detailed_timings[0].horizontal_active_lo
|
*width = edid_info.detailed_timings[0].horizontal_active_lo
|
||||||
|
|
|
@ -374,6 +374,25 @@ grub_video_get_active_render_target (struct grub_video_render_target **target)
|
||||||
return grub_video_adapter_active->get_active_render_target (target);
|
return grub_video_adapter_active->get_active_render_target (target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_video_edid_checksum (struct grub_video_edid_info *edid_info)
|
||||||
|
{
|
||||||
|
const char *edid_bytes = (const char *) edid_info;
|
||||||
|
int i;
|
||||||
|
char checksum = 0;
|
||||||
|
|
||||||
|
/* Check EDID checksum. */
|
||||||
|
for (i = 0; i < 128; ++i)
|
||||||
|
checksum += edid_bytes[i];
|
||||||
|
|
||||||
|
if (checksum != 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||||
|
"invalid EDID checksum %d", checksum);
|
||||||
|
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse <width>x<height>[x<depth>]*/
|
/* Parse <width>x<height>[x<depth>]*/
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
parse_modespec (const char *current_mode, int *width, int *height, int *depth)
|
parse_modespec (const char *current_mode, int *width, int *height, int *depth)
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#ifndef GRUB_VBE_MACHINE_HEADER
|
#ifndef GRUB_VBE_MACHINE_HEADER
|
||||||
#define GRUB_VBE_MACHINE_HEADER 1
|
#define GRUB_VBE_MACHINE_HEADER 1
|
||||||
|
|
||||||
|
#include <grub/video.h>
|
||||||
|
|
||||||
/* Default video mode to be used. */
|
/* Default video mode to be used. */
|
||||||
#define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101
|
#define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101
|
||||||
|
|
||||||
|
@ -184,66 +186,6 @@ struct grub_vbe_flat_panel_info
|
||||||
grub_uint8_t reserved[14];
|
grub_uint8_t reserved[14];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_vbe_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_VBE_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));
|
|
||||||
|
|
||||||
/* Prototypes for helper functions. */
|
/* Prototypes for helper functions. */
|
||||||
/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */
|
/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */
|
||||||
grub_vbe_status_t
|
grub_vbe_status_t
|
||||||
|
@ -280,7 +222,7 @@ grub_vbe_status_t
|
||||||
grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level);
|
grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level);
|
||||||
/* Call VESA BIOS 0x4f15 to read EDID information, return status. */
|
/* Call VESA BIOS 0x4f15 to read EDID information, return status. */
|
||||||
grub_vbe_status_t
|
grub_vbe_status_t
|
||||||
grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_data);
|
grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_data);
|
||||||
|
|
||||||
grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *width);
|
grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *width);
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,66 @@ struct grub_video_palette_data
|
||||||
grub_uint8_t a; /* Reserved bits value (0-255). */
|
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
|
typedef enum grub_video_driver_id
|
||||||
{
|
{
|
||||||
GRUB_VIDEO_DRIVER_NONE,
|
GRUB_VIDEO_DRIVER_NONE,
|
||||||
|
@ -423,6 +483,8 @@ 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_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 EXPORT_FUNC (grub_video_set_mode) (const char *modestring,
|
grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring,
|
||||||
unsigned int modemask,
|
unsigned int modemask,
|
||||||
unsigned int modevalue);
|
unsigned int modevalue);
|
||||||
|
|
Loading…
Add table
Reference in a new issue