drm/panel-edp: Add override_edid_mode quirk for generic edp
[ Upstream commit 9f7843b515811aea6c56527eb195b622e9c01f12 ] Generic edp gets mode from edid. However, some panels report incorrect mode in this way, resulting in glitches on panel. Introduce a new quirk additional_mode to the generic edid to pick a correct hardcoded mode. Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20231117215056.1883314-2-hsinyi@chromium.org Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
055c849724
commit
3c2bd20dc9
@ -203,6 +203,9 @@ struct edp_panel_entry {
|
||||
|
||||
/** @name: Name of this panel (for printing to logs). */
|
||||
const char *name;
|
||||
|
||||
/** @override_edid_mode: Override the mode obtained by edid. */
|
||||
const struct drm_display_mode *override_edid_mode;
|
||||
};
|
||||
|
||||
struct panel_edp {
|
||||
@ -301,6 +304,24 @@ static unsigned int panel_edp_get_display_modes(struct panel_edp *panel,
|
||||
return num;
|
||||
}
|
||||
|
||||
static int panel_edp_override_edid_mode(struct panel_edp *panel,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_display_mode *override_mode)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, override_mode);
|
||||
if (!mode) {
|
||||
dev_err(panel->base.dev, "failed to add additional mode\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_set_name(mode);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int panel_edp_get_non_edid_modes(struct panel_edp *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
@ -568,6 +589,9 @@ static int panel_edp_get_modes(struct drm_panel *panel,
|
||||
{
|
||||
struct panel_edp *p = to_panel_edp(panel);
|
||||
int num = 0;
|
||||
bool has_override_edid_mode = p->detected_panel &&
|
||||
p->detected_panel != ERR_PTR(-EINVAL) &&
|
||||
p->detected_panel->override_edid_mode;
|
||||
|
||||
/* probe EDID if a DDC bus is available */
|
||||
if (p->ddc) {
|
||||
@ -575,9 +599,18 @@ static int panel_edp_get_modes(struct drm_panel *panel,
|
||||
|
||||
if (!p->edid)
|
||||
p->edid = drm_get_edid(connector, p->ddc);
|
||||
|
||||
if (p->edid)
|
||||
num += drm_add_edid_modes(connector, p->edid);
|
||||
if (p->edid) {
|
||||
if (has_override_edid_mode) {
|
||||
/*
|
||||
* override_edid_mode is specified. Use
|
||||
* override_edid_mode instead of from edid.
|
||||
*/
|
||||
num += panel_edp_override_edid_mode(p, connector,
|
||||
p->detected_panel->override_edid_mode);
|
||||
} else {
|
||||
num += drm_add_edid_modes(connector, p->edid);
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(panel->dev);
|
||||
pm_runtime_put_autosuspend(panel->dev);
|
||||
@ -1861,6 +1894,15 @@ static const struct panel_delay delay_200_500_e200 = {
|
||||
.delay = _delay \
|
||||
}
|
||||
|
||||
#define EDP_PANEL_ENTRY2(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name, _mode) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \
|
||||
product_id), \
|
||||
.delay = _delay, \
|
||||
.override_edid_mode = _mode \
|
||||
}
|
||||
|
||||
/*
|
||||
* This table is used to figure out power sequencing delays for panels that
|
||||
* are detected by EDID. Entries here may point to entries in the
|
||||
|
Loading…
Reference in New Issue
Block a user