From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 19 Dec 2024 01:47:39 +0000 Subject: [PATCH] add wifi6 8852be driver --- kernel/drivers/gpu/drm/drm_modes.c | 662 ++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 462 insertions(+), 200 deletions(-) diff --git a/kernel/drivers/gpu/drm/drm_modes.c b/kernel/drivers/gpu/drm/drm_modes.c index 808345b..39b092e 100644 --- a/kernel/drivers/gpu/drm/drm_modes.c +++ b/kernel/drivers/gpu/drm/drm_modes.c @@ -30,14 +30,18 @@ * authorization from the copyright holder(s) and author(s). */ +#include <linux/ctype.h> #include <linux/list.h> #include <linux/list_sort.h> #include <linux/export.h> -#include <drm/drmP.h> -#include <drm/drm_crtc.h> + #include <video/of_videomode.h> #include <video/videomode.h> + +#include <drm/drm_crtc.h> +#include <drm/drm_device.h> #include <drm/drm_modes.h> +#include <drm/drm_print.h> #include "drm_crtc_internal.h" @@ -71,11 +75,6 @@ if (!nmode) return NULL; - if (drm_mode_object_add(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) { - kfree(nmode); - return NULL; - } - return nmode; } EXPORT_SYMBOL(drm_mode_create); @@ -91,8 +90,6 @@ { if (!mode) return; - - drm_mode_object_unregister(dev, &mode->base); kfree(mode); } @@ -160,6 +157,9 @@ int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; int interlace; u64 tmp; + + if (!hdisplay || !vdisplay) + return NULL; /* allocate the drm_display_mode structure. If failure, we will * return directly @@ -396,6 +396,9 @@ int hsync, hfront_porch, vodd_front_porch_lines; unsigned int tmp1, tmp2; + if (!hdisplay || !vdisplay) + return NULL; + drm_mode = drm_mode_create(dev); if (!drm_mode) return NULL; @@ -545,7 +548,7 @@ * Generalized Timing Formula is derived from: * * GTF Spreadsheet by Andy Morrish (1/5/97) - * available at http://www.vesa.org + * available at https://www.vesa.org * * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. * What I have done is to translate it by using integer calculation. @@ -663,22 +666,22 @@ * @bus_flags: information about pixelclk, sync and DE polarity will be stored * here * - * Sets DRM_BUS_FLAG_DE_(LOW|HIGH), DRM_BUS_FLAG_PIXDATA_(POS|NEG)EDGE and - * DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to DISPLAY_FLAGS + * Sets DRM_BUS_FLAG_DE_(LOW|HIGH), DRM_BUS_FLAG_PIXDATA_DRIVE_(POS|NEG)EDGE + * and DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to DISPLAY_FLAGS * found in @vm */ void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags) { *bus_flags = 0; if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) - *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE; + *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) - *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE; + *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; if (vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE) - *bus_flags |= DRM_BUS_FLAG_SYNC_POSEDGE; + *bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE; if (vm->flags & DISPLAY_FLAGS_SYNC_NEGEDGE) - *bus_flags |= DRM_BUS_FLAG_SYNC_NEGEDGE; + *bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE; if (vm->flags & DISPLAY_FLAGS_DE_LOW) *bus_flags |= DRM_BUS_FLAG_DE_LOW; @@ -717,8 +720,8 @@ if (bus_flags) drm_bus_flags_from_videomode(&vm, bus_flags); - pr_debug("%pOF: got %dx%d display mode from %s\n", - np, vm.hactive, vm.vactive, np->name); + pr_debug("%pOF: got %dx%d display mode\n", + np, vm.hactive, vm.vactive); drm_mode_debug_printmodeline(dmode); return 0; @@ -745,32 +748,6 @@ EXPORT_SYMBOL(drm_mode_set_name); /** - * drm_mode_hsync - get the hsync of a mode - * @mode: mode - * - * Returns: - * @modes's hsync rate in kHz, rounded to the nearest integer. Calculates the - * value first if it is not yet set. - */ -int drm_mode_hsync(const struct drm_display_mode *mode) -{ - unsigned int calc_val; - - if (mode->hsync) - return mode->hsync; - - if (mode->htotal <= 0) - return 0; - - calc_val = (mode->clock * 1000) / mode->htotal; /* hsync in Hz */ - calc_val += 500; /* round to 1000Hz */ - calc_val /= 1000; /* truncate to kHz */ - - return calc_val; -} -EXPORT_SYMBOL(drm_mode_hsync); - -/** * drm_mode_vrefresh - get the vrefresh of a mode * @mode: mode * @@ -780,26 +757,22 @@ */ int drm_mode_vrefresh(const struct drm_display_mode *mode) { - int refresh = 0; + unsigned int num, den; - if (mode->vrefresh > 0) - refresh = mode->vrefresh; - else if (mode->htotal > 0 && mode->vtotal > 0) { - unsigned int num, den; + if (mode->htotal == 0 || mode->vtotal == 0) + return 0; - num = mode->clock * 1000; - den = mode->htotal * mode->vtotal; + num = mode->clock; + den = mode->htotal * mode->vtotal; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - num *= 2; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - den *= 2; - if (mode->vscan > 1) - den *= mode->vscan; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + num *= 2; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + den *= 2; + if (mode->vscan > 1) + den *= mode->vscan; - refresh = DIV_ROUND_CLOSEST(num, den); - } - return refresh; + return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(num, 1000), den); } EXPORT_SYMBOL(drm_mode_vrefresh); @@ -912,11 +885,9 @@ */ void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src) { - int id = dst->base.id; struct list_head head = dst->head; *dst = *src; - dst->base.id = id; dst->head = head; } EXPORT_SYMBOL(drm_mode_copy); @@ -1282,7 +1253,7 @@ * @verbose: be verbose about it * * This helper function can be used to prune a display mode list after - * validation has been completed. All modes who's status is not MODE_OK will be + * validation has been completed. All modes whose status is not MODE_OK will be * removed from the list, and if @verbose the status code and mode name is also * printed to dmesg. */ @@ -1333,7 +1304,7 @@ if (diff) return diff; - diff = b->vrefresh - a->vrefresh; + diff = drm_mode_vrefresh(b) - drm_mode_vrefresh(a); if (diff) return diff; @@ -1415,6 +1386,305 @@ } EXPORT_SYMBOL(drm_connector_list_update); +static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr, + struct drm_cmdline_mode *mode) +{ + unsigned int bpp; + + if (str[0] != '-') + return -EINVAL; + + str++; + bpp = simple_strtol(str, end_ptr, 10); + if (*end_ptr == str) + return -EINVAL; + + mode->bpp = bpp; + mode->bpp_specified = true; + + return 0; +} + +static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr, + struct drm_cmdline_mode *mode) +{ + unsigned int refresh; + + if (str[0] != '@') + return -EINVAL; + + str++; + refresh = simple_strtol(str, end_ptr, 10); + if (*end_ptr == str) + return -EINVAL; + + mode->refresh = refresh; + mode->refresh_specified = true; + + return 0; +} + +static int drm_mode_parse_cmdline_extra(const char *str, int length, + bool freestanding, + const struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + int i; + + for (i = 0; i < length; i++) { + switch (str[i]) { + case 'i': + if (freestanding) + return -EINVAL; + + mode->interlace = true; + break; + case 'm': + if (freestanding) + return -EINVAL; + + mode->margins = true; + break; + case 'D': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && + (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) + mode->force = DRM_FORCE_ON; + else + mode->force = DRM_FORCE_ON_DIGITAL; + break; + case 'd': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + mode->force = DRM_FORCE_OFF; + break; + case 'e': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + mode->force = DRM_FORCE_ON; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length, + bool extras, + const struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + const char *str_start = str; + bool rb = false, cvt = false; + int xres = 0, yres = 0; + int remaining, i; + char *end_ptr; + + xres = simple_strtol(str, &end_ptr, 10); + if (end_ptr == str) + return -EINVAL; + + if (end_ptr[0] != 'x') + return -EINVAL; + end_ptr++; + + str = end_ptr; + yres = simple_strtol(str, &end_ptr, 10); + if (end_ptr == str) + return -EINVAL; + + remaining = length - (end_ptr - str_start); + if (remaining < 0) + return -EINVAL; + + for (i = 0; i < remaining; i++) { + switch (end_ptr[i]) { + case 'M': + cvt = true; + break; + case 'R': + rb = true; + break; + default: + /* + * Try to pass that to our extras parsing + * function to handle the case where the + * extras are directly after the resolution + */ + if (extras) { + int ret = drm_mode_parse_cmdline_extra(end_ptr + i, + 1, + false, + connector, + mode); + if (ret) + return ret; + } else { + return -EINVAL; + } + } + } + + mode->xres = xres; + mode->yres = yres; + mode->cvt = cvt; + mode->rb = rb; + + return 0; +} + +static int drm_mode_parse_cmdline_int(const char *delim, unsigned int *int_ret) +{ + const char *value; + char *endp; + + /* + * delim must point to the '=', otherwise it is a syntax error and + * if delim points to the terminating zero, then delim + 1 wil point + * past the end of the string. + */ + if (*delim != '=') + return -EINVAL; + + value = delim + 1; + *int_ret = simple_strtol(value, &endp, 10); + + /* Make sure we have parsed something */ + if (endp == value) + return -EINVAL; + + return 0; +} + +static int drm_mode_parse_panel_orientation(const char *delim, + struct drm_cmdline_mode *mode) +{ + const char *value; + + if (*delim != '=') + return -EINVAL; + + value = delim + 1; + delim = strchr(value, ','); + if (!delim) + delim = value + strlen(value); + + if (!strncmp(value, "normal", delim - value)) + mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; + else if (!strncmp(value, "upside_down", delim - value)) + mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; + else if (!strncmp(value, "left_side_up", delim - value)) + mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP; + else if (!strncmp(value, "right_side_up", delim - value)) + mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP; + else + return -EINVAL; + + return 0; +} + +static int drm_mode_parse_cmdline_options(const char *str, + bool freestanding, + const struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + unsigned int deg, margin, rotation = 0; + const char *delim, *option, *sep; + + option = str; + do { + delim = strchr(option, '='); + if (!delim) { + delim = strchr(option, ','); + + if (!delim) + delim = option + strlen(option); + } + + if (!strncmp(option, "rotate", delim - option)) { + if (drm_mode_parse_cmdline_int(delim, °)) + return -EINVAL; + + switch (deg) { + case 0: + rotation |= DRM_MODE_ROTATE_0; + break; + + case 90: + rotation |= DRM_MODE_ROTATE_90; + break; + + case 180: + rotation |= DRM_MODE_ROTATE_180; + break; + + case 270: + rotation |= DRM_MODE_ROTATE_270; + break; + + default: + return -EINVAL; + } + } else if (!strncmp(option, "reflect_x", delim - option)) { + rotation |= DRM_MODE_REFLECT_X; + } else if (!strncmp(option, "reflect_y", delim - option)) { + rotation |= DRM_MODE_REFLECT_Y; + } else if (!strncmp(option, "margin_right", delim - option)) { + if (drm_mode_parse_cmdline_int(delim, &margin)) + return -EINVAL; + + mode->tv_margins.right = margin; + } else if (!strncmp(option, "margin_left", delim - option)) { + if (drm_mode_parse_cmdline_int(delim, &margin)) + return -EINVAL; + + mode->tv_margins.left = margin; + } else if (!strncmp(option, "margin_top", delim - option)) { + if (drm_mode_parse_cmdline_int(delim, &margin)) + return -EINVAL; + + mode->tv_margins.top = margin; + } else if (!strncmp(option, "margin_bottom", delim - option)) { + if (drm_mode_parse_cmdline_int(delim, &margin)) + return -EINVAL; + + mode->tv_margins.bottom = margin; + } else if (!strncmp(option, "panel_orientation", delim - option)) { + if (drm_mode_parse_panel_orientation(delim, mode)) + return -EINVAL; + } else { + return -EINVAL; + } + sep = strchr(delim, ','); + option = sep + 1; + } while (sep); + + if (rotation && freestanding) + return -EINVAL; + + if (!(rotation & DRM_MODE_ROTATE_MASK)) + rotation |= DRM_MODE_ROTATE_0; + + /* Make sure there is exactly one rotation defined */ + if (!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK)) + return -EINVAL; + + mode->rotation_reflection = rotation; + + return 0; +} + +static const char * const drm_named_modes_whitelist[] = { + "NTSC", + "PAL", +}; + /** * drm_mode_parse_command_line_for_connector - parse command line modeline for connector * @mode_option: optional per connector mode option @@ -1430,6 +1700,10 @@ * * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd] * + * Additionals options can be provided following the mode, using a comma to + * separate each option. Valid options can be found in + * Documentation/fb/modedb.rst. + * * The intermediate drm_cmdline_mode structure is required to store additional * options from the command line modline like the force-enable/disable flag. * @@ -1437,150 +1711,140 @@ * True if a valid modeline has been parsed, false otherwise. */ bool drm_mode_parse_command_line_for_connector(const char *mode_option, - struct drm_connector *connector, + const struct drm_connector *connector, struct drm_cmdline_mode *mode) { const char *name; - unsigned int namelen; - bool res_specified = false, bpp_specified = false, refresh_specified = false; - unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; - bool yres_specified = false, cvt = false, rb = false; - bool interlace = false, margins = false, was_digit = false; - int i; - enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; + bool freestanding = false, parse_extras = false; + unsigned int bpp_off = 0, refresh_off = 0, options_off = 0; + unsigned int mode_end = 0; + const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; + const char *options_ptr = NULL; + char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL; + int i, len, ret; -#ifdef CONFIG_FB + memset(mode, 0, sizeof(*mode)); + mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; + if (!mode_option) - mode_option = fb_mode_option; -#endif - - if (!mode_option) { - mode->specified = false; return false; - } name = mode_option; - namelen = strlen(name); - for (i = namelen-1; i >= 0; i--) { - switch (name[i]) { - case '@': - if (!refresh_specified && !bpp_specified && - !yres_specified && !cvt && !rb && was_digit) { - refresh = simple_strtol(&name[i+1], NULL, 10); - refresh_specified = true; - was_digit = false; - } else - goto done; - break; - case '-': - if (!bpp_specified && !yres_specified && !cvt && - !rb && was_digit) { - bpp = simple_strtol(&name[i+1], NULL, 10); - bpp_specified = true; - was_digit = false; - } else - goto done; - break; - case 'x': - if (!yres_specified && was_digit) { - yres = simple_strtol(&name[i+1], NULL, 10); - yres_specified = true; - was_digit = false; - } else - goto done; - break; - case '0' ... '9': - was_digit = true; - break; - case 'M': - if (yres_specified || cvt || was_digit) - goto done; - cvt = true; - break; - case 'R': - if (yres_specified || cvt || rb || was_digit) - goto done; - rb = true; - break; - case 'm': - if (cvt || yres_specified || was_digit) - goto done; - margins = true; - break; - case 'i': - if (cvt || yres_specified || was_digit) - goto done; - interlace = true; - break; - case 'e': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; - force = DRM_FORCE_ON; - break; - case 'D': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; + /* Try to locate the bpp and refresh specifiers, if any */ + bpp_ptr = strchr(name, '-'); + if (bpp_ptr) + bpp_off = bpp_ptr - name; - if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && - (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) - force = DRM_FORCE_ON; - else - force = DRM_FORCE_ON_DIGITAL; - break; - case 'd': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; + refresh_ptr = strchr(name, '@'); + if (refresh_ptr) + refresh_off = refresh_ptr - name; - force = DRM_FORCE_OFF; + /* Locate the start of named options */ + options_ptr = strchr(name, ','); + if (options_ptr) + options_off = options_ptr - name; + + /* Locate the end of the name / resolution, and parse it */ + if (bpp_ptr) { + mode_end = bpp_off; + } else if (refresh_ptr) { + mode_end = refresh_off; + } else if (options_ptr) { + mode_end = options_off; + parse_extras = true; + } else { + mode_end = strlen(name); + parse_extras = true; + } + + /* First check for a named mode */ + for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) { + ret = str_has_prefix(name, drm_named_modes_whitelist[i]); + if (ret == mode_end) { + if (refresh_ptr) + return false; /* named + refresh is invalid */ + + strcpy(mode->name, drm_named_modes_whitelist[i]); + mode->specified = true; break; - default: - goto done; } } - if (i < 0 && yres_specified) { - char *ch; - xres = simple_strtol(name, &ch, 10); - if ((ch != NULL) && (*ch == 'x')) - res_specified = true; - else - i = ch - name; - } else if (!yres_specified && was_digit) { - /* catch mode that begins with digits but has no 'x' */ - i = 0; - } -done: - if (i >= 0) { - pr_warn("[drm] parse error at position %i in video mode '%s'\n", - i, name); - mode->specified = false; - return false; - } + /* No named mode? Check for a normal mode argument, e.g. 1024x768 */ + if (!mode->specified && isdigit(name[0])) { + ret = drm_mode_parse_cmdline_res_mode(name, mode_end, + parse_extras, + connector, + mode); + if (ret) + return false; - if (res_specified) { mode->specified = true; - mode->xres = xres; - mode->yres = yres; } - if (refresh_specified) { - mode->refresh_specified = true; - mode->refresh = refresh; + /* No mode? Check for freestanding extras and/or options */ + if (!mode->specified) { + unsigned int len = strlen(mode_option); + + if (bpp_ptr || refresh_ptr) + return false; /* syntax error */ + + if (len == 1 || (len >= 2 && mode_option[1] == ',')) + extra_ptr = mode_option; + else + options_ptr = mode_option - 1; + + freestanding = true; } - if (bpp_specified) { + if (bpp_ptr) { + ret = drm_mode_parse_cmdline_bpp(bpp_ptr, &bpp_end_ptr, mode); + if (ret) + return false; + mode->bpp_specified = true; - mode->bpp = bpp; } - mode->rb = rb; - mode->cvt = cvt; - mode->interlace = interlace; - mode->margins = margins; - mode->force = force; + + if (refresh_ptr) { + ret = drm_mode_parse_cmdline_refresh(refresh_ptr, + &refresh_end_ptr, mode); + if (ret) + return false; + + mode->refresh_specified = true; + } + + /* + * Locate the end of the bpp / refresh, and parse the extras + * if relevant + */ + if (bpp_ptr && refresh_ptr) + extra_ptr = max(bpp_end_ptr, refresh_end_ptr); + else if (bpp_ptr) + extra_ptr = bpp_end_ptr; + else if (refresh_ptr) + extra_ptr = refresh_end_ptr; + + if (extra_ptr) { + if (options_ptr) + len = options_ptr - extra_ptr; + else + len = strlen(extra_ptr); + + ret = drm_mode_parse_cmdline_extra(extra_ptr, len, freestanding, + connector, mode); + if (ret) + return false; + } + + if (options_ptr) { + ret = drm_mode_parse_cmdline_options(options_ptr + 1, + freestanding, + connector, mode); + if (ret) + return false; + } return true; } @@ -1635,13 +1899,6 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, const struct drm_display_mode *in) { - WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX || - in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX || - in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX || - in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX || - in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX, - "timing values too large for mode info\n"); - out->clock = in->clock; out->hdisplay = in->hdisplay; out->hsync_start = in->hsync_start; @@ -1653,7 +1910,7 @@ out->vsync_end = in->vsync_end; out->vtotal = in->vtotal; out->vscan = in->vscan; - out->vrefresh = in->vrefresh; + out->vrefresh = drm_mode_vrefresh(in); out->flags = in->flags; out->type = in->type; @@ -1670,8 +1927,11 @@ case HDMI_PICTURE_ASPECT_256_135: out->flags |= DRM_MODE_FLAG_PIC_AR_256_135; break; - case HDMI_PICTURE_ASPECT_RESERVED: default: + WARN(1, "Invalid aspect ratio (0%x) on mode\n", + in->picture_aspect_ratio); + fallthrough; + case HDMI_PICTURE_ASPECT_NONE: out->flags |= DRM_MODE_FLAG_PIC_AR_NONE; break; } @@ -1679,6 +1939,7 @@ strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); out->name[DRM_DISPLAY_MODE_LEN-1] = 0; } +EXPORT_SYMBOL_GPL(drm_mode_convert_to_umode); /** * drm_crtc_convert_umode - convert a modeinfo into a drm_display_mode @@ -1710,7 +1971,6 @@ out->vsync_end = in->vsync_end; out->vtotal = in->vtotal; out->vscan = in->vscan; - out->vrefresh = in->vrefresh; out->flags = in->flags; /* * Old xf86-video-vmware (possibly others too) used to @@ -1730,20 +1990,22 @@ switch (in->flags & DRM_MODE_FLAG_PIC_AR_MASK) { case DRM_MODE_FLAG_PIC_AR_4_3: - out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_4_3; + out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3; break; case DRM_MODE_FLAG_PIC_AR_16_9: - out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9; + out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9; break; case DRM_MODE_FLAG_PIC_AR_64_27: - out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_64_27; + out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27; break; case DRM_MODE_FLAG_PIC_AR_256_135: - out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_256_135; + out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135; break; - default: + case DRM_MODE_FLAG_PIC_AR_NONE: out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE; break; + default: + return -EINVAL; } out->status = drm_mode_validate_driver(dev, out); -- Gitblit v1.6.2