]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
move more EDID-handling functions to generic code, and make videoinfo display EDID...
authorColin Watson <cjwatson@ubuntu.com>
Tue, 14 Dec 2010 18:03:34 +0000 (18:03 +0000)
committerColin Watson <cjwatson@ubuntu.com>
Tue, 14 Dec 2010 18:03:34 +0000 (18:03 +0000)
ChangeLog.vbe-autodetect
grub-core/commands/videoinfo.c
grub-core/video/i386/pc/vbe.c
grub-core/video/video.c
include/grub/video.h

index 0d96fc0a21a1c2d299796034bac98c47a1b87c37..355ce00f62e67eeb90aa76eb468f93b00c0ed395 100644 (file)
@@ -3,24 +3,33 @@
        Preferred resolution detection for VBE.
 
        * grub-core/video/video.c (grub_video_edid_checksum): New function.
+       (grub_video_get_edid): Likewise.
+       (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):
-       Likewise.
+       New function.
        (grub_vbe_bios_get_ddc_capabilities): Likewise.
        (grub_vbe_bios_read_edid): Likewise.
-       (grub_vbe_get_preferred_mode): Likewise.  Try EDID followed by the
-       Flat Panel extension, in line with the X.org VESA driver.
+       (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.
        (grub_video_edid_checksum): Add prototype.
+       (grub_video_get_edid): Likewise.
+       (grub_video_edid_preferred_mode): Likewise.
        * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New
        structure.
        (grub_vbe_bios_get_flat_panel_info): Add prototype.
        (grub_vbe_bios_get_ddc_capabilities): Likewise.
        (grub_vbe_bios_read_edid): Likewise.
 
+       * 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.
index 10f77915bf7bc020f6375d890fcebe57f2d20211..56df943ec8109b543f1e10f8c7078d134da1944a 100644 (file)
@@ -77,6 +77,30 @@ hook (const struct grub_video_mode_info *info)
   return 0;
 }
 
+static void
+print_edid (struct grub_video_edid_info *edid_info)
+{
+  unsigned int edid_width, edid_height;
+
+  if (grub_video_edid_checksum (edid_info))
+    {
+      grub_printf ("  EDID checksum invalid\n");
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  grub_printf ("  EDID version: %u.%u\n",
+              edid_info->version, edid_info->revision);
+  if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height)
+       == GRUB_ERR_NONE)
+    grub_printf ("    Preferred mode: %ux%u\n", edid_width, edid_height);
+  else
+    {
+      grub_printf ("    No preferred mode available\n");
+      grub_errno = GRUB_ERR_NONE;
+    }
+}
+
 static grub_err_t
 grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
                    int argc, char **args)
@@ -120,6 +144,8 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
 
   FOR_VIDEO_ADAPTERS (adapter)
   {
+    struct grub_video_edid_info edid_info;
+
     grub_printf ("Adapter '%s':\n", adapter->name);
 
     if (!adapter->iterate)
@@ -143,6 +169,11 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
 
     adapter->iterate (hook);
 
+    if (adapter->get_edid (&edid_info) == GRUB_ERR_NONE)
+      print_edid (&edid_info);
+    else
+      grub_errno = GRUB_ERR_NONE;
+
     if (adapter->id != id)
       {
        if (adapter->fini ())
index e2dcc151e9decfd7a481dc22e9c27a3305b8e595..c6bb733a943757c27cb199731c44fe60135e7731 100644 (file)
@@ -389,26 +389,12 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height)
       && (grub_vbe_bios_get_ddc_capabilities (&ddc_level) & 0xff)
         == GRUB_VBE_STATUS_OK)
     {
-      status = grub_vbe_bios_read_edid (&edid_info);
-      /* Bit 1 in the Feature Support field indicates that the first
-         Detailed Timing Description is the preferred timing mode.  */
-      if (status == GRUB_VBE_STATUS_OK
-         && grub_video_edid_checksum (&edid_info) == GRUB_ERR_NONE
-         && edid_info.version == 1 /* we don't understand later versions */
-         && (edid_info.feature_support
-             & GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE)
-         && edid_info.detailed_timings[0].pixel_clock)
-       {
-         *width = edid_info.detailed_timings[0].horizontal_active_lo
-                  | (((unsigned int)
-                      (edid_info.detailed_timings[0].horizontal_hi & 0xf0))
-                     << 4);
-         *height = edid_info.detailed_timings[0].vertical_active_lo
-                   | (((unsigned int)
-                       (edid_info.detailed_timings[0].vertical_hi & 0xf0))
-                      << 4);
-         return GRUB_ERR_NONE;
-       }
+      if (grub_video_get_edid (&edid_info) == GRUB_ERR_NONE
+         && grub_video_edid_preferred_mode (&edid_info, width, height)
+             == GRUB_ERR_NONE)
+       return GRUB_ERR_NONE;
+
+      grub_errno = GRUB_ERR_NONE;
     }
 
   status = grub_vbe_bios_get_flat_panel_info (&flat_panel_info);
@@ -978,6 +964,15 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
   return grub_video_fb_get_info_and_fini (mode_info, framebuf);
 }
 
+static grub_err_t
+grub_video_vbe_get_edid (struct grub_video_edid_info *edid_info)
+{
+  if (grub_vbe_bios_read_edid (edid_info) != GRUB_VBE_STATUS_OK)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "EDID information not available");
+
+  return GRUB_ERR_NONE;
+}
+
 static void
 grub_video_vbe_print_adapter_specific_info (void)
 {
@@ -1022,6 +1017,7 @@ static struct grub_video_adapter grub_video_vbe_adapter =
     .set_active_render_target = grub_video_fb_set_active_render_target,
     .get_active_render_target = grub_video_fb_get_active_render_target,
     .iterate = grub_video_vbe_iterate,
+    .get_edid = grub_video_vbe_get_edid,
     .print_adapter_specific_info = grub_video_vbe_print_adapter_specific_info,
 
     .next = 0
index f3ecab94d380d605e44713fa4d1cb37393973fdb..84e98bb6790d2f91c6f8cdf2dba46fbceb6351c7 100644 (file)
@@ -393,6 +393,49 @@ grub_video_edid_checksum (struct grub_video_edid_info *edid_info)
   return grub_errno;
 }
 
+grub_err_t
+grub_video_get_edid (struct grub_video_edid_info *edid_info)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  if (! grub_video_adapter_active->get_edid)
+    return grub_error (GRUB_ERR_BAD_DEVICE,
+                      "EDID information unavailable for this video mode");
+
+  if (grub_video_adapter_active->get_edid (edid_info) != GRUB_ERR_NONE)
+    return grub_errno;
+  if (grub_video_edid_checksum (edid_info) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_edid_preferred_mode (struct grub_video_edid_info *edid_info,
+                               unsigned int *width, unsigned int *height)
+{
+  /* Bit 1 in the Feature Support field indicates that the first
+     Detailed Timing Description is the preferred timing mode.  */
+  if (edid_info->version == 1 /* we don't understand later versions */
+      && (edid_info->feature_support
+         & GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE)
+      && edid_info->detailed_timings[0].pixel_clock)
+    {
+      *width = edid_info->detailed_timings[0].horizontal_active_lo
+              | (((unsigned int)
+                  (edid_info->detailed_timings[0].horizontal_hi & 0xf0))
+                 << 4);
+      *height = edid_info->detailed_timings[0].vertical_active_lo
+               | (((unsigned int)
+                   (edid_info->detailed_timings[0].vertical_hi & 0xf0))
+                  << 4);
+      return GRUB_ERR_NONE;
+    }
+
+  return grub_error (GRUB_ERR_BAD_DEVICE, "no preferred mode available");
+}
+
 /* Parse <width>x<height>[x<depth>]*/
 static grub_err_t
 parse_modespec (const char *current_mode, int *width, int *height, int *depth)
index 2cf1424c44acdee3855cdc113f5ea5e6467e6628..2251ed5f494c046304929f94add4c4517728a78b 100644 (file)
@@ -371,6 +371,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;
@@ -484,6 +486,10 @@ 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_get_edid (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,