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
1 changed files with 45 additions and 3 deletions
|
|
@ -203,6 +203,9 @@ struct edp_panel_entry {
|
||||||
|
|
||||||
/** @name: Name of this panel (for printing to logs). */
|
/** @name: Name of this panel (for printing to logs). */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
/** @override_edid_mode: Override the mode obtained by edid. */
|
||||||
|
const struct drm_display_mode *override_edid_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct panel_edp {
|
struct panel_edp {
|
||||||
|
|
@ -301,6 +304,24 @@ static unsigned int panel_edp_get_display_modes(struct panel_edp *panel,
|
||||||
return num;
|
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,
|
static int panel_edp_get_non_edid_modes(struct panel_edp *panel,
|
||||||
struct drm_connector *connector)
|
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);
|
struct panel_edp *p = to_panel_edp(panel);
|
||||||
int num = 0;
|
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 */
|
/* probe EDID if a DDC bus is available */
|
||||||
if (p->ddc) {
|
if (p->ddc) {
|
||||||
|
|
@ -575,9 +599,18 @@ static int panel_edp_get_modes(struct drm_panel *panel,
|
||||||
|
|
||||||
if (!p->edid)
|
if (!p->edid)
|
||||||
p->edid = drm_get_edid(connector, p->ddc);
|
p->edid = drm_get_edid(connector, p->ddc);
|
||||||
|
if (p->edid) {
|
||||||
if (p->edid)
|
if (has_override_edid_mode) {
|
||||||
num += drm_add_edid_modes(connector, p->edid);
|
/*
|
||||||
|
* 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_mark_last_busy(panel->dev);
|
||||||
pm_runtime_put_autosuspend(panel->dev);
|
pm_runtime_put_autosuspend(panel->dev);
|
||||||
|
|
@ -1861,6 +1894,15 @@ static const struct panel_delay delay_200_500_e200 = {
|
||||||
.delay = _delay \
|
.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
|
* 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
|
* are detected by EDID. Entries here may point to entries in the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue