diff --git a/projects/Rockchip/patches/linux/RK3326/020-elida-refresh-rates.patch b/projects/Rockchip/patches/linux/RK3326/020-elida-refresh-rates.patch new file mode 100644 index 000000000..fc4490dee --- /dev/null +++ b/projects/Rockchip/patches/linux/RK3326/020-elida-refresh-rates.patch @@ -0,0 +1,79 @@ +diff --git a/drivers/gpu/drm/panel/panel-elida-kd35t133.c b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +index ad7628053e1b..0be014aa7292 100644 +--- a/drivers/gpu/drm/panel/panel-elida-kd35t133.c ++++ b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +@@ -177,8 +177,9 @@ static int kd35t133_prepare(struct drm_panel *panel) + return ret; + } + +-static const struct drm_display_mode default_mode = { +- .hdisplay = 320, ++/* drm_display_mode template without clock as it is variable */ ++static const struct drm_display_mode mode_template = { ++ .hdisplay = 320, + .hsync_start = 320 + 130, + .hsync_end = 320 + 130 + 4, + .htotal = 320 + 130 + 4 + 130, +@@ -186,31 +187,49 @@ static const struct drm_display_mode default_mode = { + .vsync_start = 480 + 2, + .vsync_end = 480 + 2 + 1, + .vtotal = 480 + 2 + 1 + 2, +- .clock = 17000, + .width_mm = 42, + .height_mm = 82, + }; + ++static const int pixel_clocks[] = { ++ 14118, /* 49.84 Hz PAL everything */ ++ 15545, /* 54.88 Hz Arcade: Midway, Toaplan, R-Type */ ++ 16286, /* 57.50 Hz Arcade: Toaplan, more? */ ++ 16917, /* 59.73 Hz GB/GBC/GBA */ ++ 16976, /* 59.935 Hz NTSC MS/MD/GG/PS */ ++ 17022, /* 60.01 Hz NTSC NES/SNES */ ++ 21375, /* 75.47 Hz Wonderswan(Color) */ ++}; ++ + static int kd35t133_get_modes(struct drm_panel *panel, + struct drm_connector *connector) + { + struct kd35t133 *ctx = panel_to_kd35t133(panel); ++ struct drm_display_mode mode_tmp; + struct drm_display_mode *mode; +- +- mode = drm_mode_duplicate(connector->dev, &default_mode); +- if (!mode) { +- dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n", +- default_mode.hdisplay, default_mode.vdisplay, +- drm_mode_vrefresh(&default_mode)); +- return -ENOMEM; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(pixel_clocks); i++) { ++ mode_tmp = mode_template; ++ mode_tmp.clock = pixel_clocks[i]; ++ mode = drm_mode_duplicate(connector->dev, &mode_tmp); ++ if (!mode) { ++ dev_err(ctx->dev, "Failed to add mode %u\n", ++ drm_mode_vrefresh(mode)); ++ return -ENOMEM; ++ } ++ drm_mode_set_name(mode); ++ ++ mode->type = DRM_MODE_TYPE_DRIVER; ++ if (pixel_clocks[i] == pixel_clocks[4]) ++ mode->type |= DRM_MODE_TYPE_PREFERRED; ++ ++ drm_mode_probed_add(connector, mode); ++ connector->display_info.width_mm = mode->width_mm; ++ connector->display_info.height_mm = mode->height_mm; + } + +- drm_mode_set_name(mode); + +- mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; +- connector->display_info.width_mm = mode->width_mm; +- connector->display_info.height_mm = mode->height_mm; +- drm_mode_probed_add(connector, mode); + /* + * TODO: Remove once all drm drivers call + * drm_connector_set_orientation_from_panel()