[PATCH] drm/edid: add a quirk for two 240Hz Samsung monitors

Hamza Mahfooz hamza.mahfooz at amd.com
Thu Nov 2 19:00:37 UTC 2023


On 11/1/23 17:36, Alex Deucher wrote:
> On Wed, Nov 1, 2023 at 5:01 PM Hamza Mahfooz <hamza.mahfooz at amd.com> wrote:
>>
>> Without this fix the 5120x1440 at 240 timing of these monitors
>> leads to screen flickering.
>>
>> Cc: stable at vger.kernel.org # 6.1+
>> Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1442
>> Co-developed-by: Harry Wentland <harry.wentland at amd.com>
>> Signed-off-by: Harry Wentland <harry.wentland at amd.com>
>> Signed-off-by: Hamza Mahfooz <hamza.mahfooz at amd.com>
>> ---
>>   drivers/gpu/drm/drm_edid.c | 47 +++++++++++++++++++++++++++++++++++---
>>   1 file changed, 44 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index bca2af4fe1fc..3fdb8907f66b 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -89,6 +89,8 @@ static int oui(u8 first, u8 second, u8 third)
>>   #define EDID_QUIRK_NON_DESKTOP                 (1 << 12)
>>   /* Cap the DSC target bitrate to 15bpp */
>>   #define EDID_QUIRK_CAP_DSC_15BPP               (1 << 13)
>> +/* Fix up a particular 5120x1440 at 240Hz timing */
>> +#define EDID_QUIRK_FIXUP_5120_1440_240         (1 << 14)
> 
> What is wrong with the original timing that needs to be fixed?

Apparently, all of timing values for the 5120x1440 at 240 mode of these
monitors aren't set correctly (they are all lower than they should be)
in their EDIDs. For what it's worth, the windows driver has had a quirk
similar the one proposed in this patch for ~2 years.

> 
> Alex
> 
> 
>>
>>   #define MICROSOFT_IEEE_OUI     0xca125c
>>
>> @@ -170,6 +172,12 @@ static const struct edid_quirk {
>>          EDID_QUIRK('S', 'A', 'M', 596, EDID_QUIRK_PREFER_LARGE_60),
>>          EDID_QUIRK('S', 'A', 'M', 638, EDID_QUIRK_PREFER_LARGE_60),
>>
>> +       /* Samsung C49G95T */
>> +       EDID_QUIRK('S', 'A', 'M', 0x7053, EDID_QUIRK_FIXUP_5120_1440_240),
>> +
>> +       /* Samsung S49AG95 */
>> +       EDID_QUIRK('S', 'A', 'M', 0x71ac, EDID_QUIRK_FIXUP_5120_1440_240),
>> +
>>          /* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
>>          EDID_QUIRK('S', 'N', 'Y', 0x2541, EDID_QUIRK_FORCE_12BPC),
>>
>> @@ -6586,7 +6594,37 @@ static void update_display_info(struct drm_connector *connector,
>>          drm_edid_to_eld(connector, drm_edid);
>>   }
>>
>> -static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
>> +static void drm_mode_displayid_detailed_edid_quirks(struct drm_connector *connector,
>> +                                                   struct drm_display_mode *mode)
>> +{
>> +       unsigned int hsync_width;
>> +       unsigned int vsync_width;
>> +
>> +       if (connector->display_info.quirks & EDID_QUIRK_FIXUP_5120_1440_240) {
>> +               if (mode->hdisplay == 5120 && mode->vdisplay == 1440 &&
>> +                   mode->clock == 1939490) {
>> +                       hsync_width = mode->hsync_end - mode->hsync_start;
>> +                       vsync_width = mode->vsync_end - mode->vsync_start;
>> +
>> +                       mode->clock = 2018490;
>> +                       mode->hdisplay = 5120;
>> +                       mode->hsync_start = 5120 + 8;
>> +                       mode->hsync_end = 5120 + 8 + hsync_width;
>> +                       mode->htotal = 5200;
>> +
>> +                       mode->vdisplay = 1440;
>> +                       mode->vsync_start = 1440 + 165;
>> +                       mode->vsync_end = 1440 + 165 + vsync_width;
>> +                       mode->vtotal = 1619;
>> +
>> +                       drm_dbg_kms(connector->dev,
>> +                                   "[CONNECTOR:%d:%s] Samsung 240Hz mode quirk applied\n",
>> +                                   connector->base.id, connector->name);
>> +               }
>> +       }
>> +}
>> +
>> +static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_connector *connector,
>>                                                              struct displayid_detailed_timings_1 *timings,
>>                                                              bool type_7)
>>   {
>> @@ -6605,7 +6643,7 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d
>>          bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
>>          bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
>>
>> -       mode = drm_mode_create(dev);
>> +       mode = drm_mode_create(connector->dev);
>>          if (!mode)
>>                  return NULL;
>>
>> @@ -6628,6 +6666,9 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d
>>
>>          if (timings->flags & 0x80)
>>                  mode->type |= DRM_MODE_TYPE_PREFERRED;
>> +
>> +       drm_mode_displayid_detailed_edid_quirks(connector, mode);
>> +
>>          drm_mode_set_name(mode);
>>
>>          return mode;
>> @@ -6650,7 +6691,7 @@ static int add_displayid_detailed_1_modes(struct drm_connector *connector,
>>          for (i = 0; i < num_timings; i++) {
>>                  struct displayid_detailed_timings_1 *timings = &det->timings[i];
>>
>> -               newmode = drm_mode_displayid_detailed(connector->dev, timings, type_7);
>> +               newmode = drm_mode_displayid_detailed(connector, timings, type_7);
>>                  if (!newmode)
>>                          continue;
>>
>> --
>> 2.42.0
>>
-- 
Hamza



More information about the dri-devel mailing list