diff options
Diffstat (limited to 'drivers/gpu/drm/panel/panel-edp.c')
-rw-r--r-- | drivers/gpu/drm/panel/panel-edp.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index a189982601a4..cdb154c8b866 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -39,6 +39,7 @@ #include <drm/display/drm_dp_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_device.h> +#include <drm/drm_edid.h> #include <drm/drm_panel.h> /** @@ -417,6 +418,11 @@ static int panel_edp_get_hpd_gpio(struct device *dev, struct panel_edp *p) return 0; } +static bool panel_edp_can_read_hpd(struct panel_edp *p) +{ + return !p->no_hpd && (p->hpd_gpio || (p->aux && p->aux->wait_hpd_asserted)); +} + static int panel_edp_prepare_once(struct panel_edp *p) { struct device *dev = p->base.dev; @@ -441,17 +447,21 @@ static int panel_edp_prepare_once(struct panel_edp *p) if (delay) msleep(delay); - if (p->hpd_gpio) { + if (panel_edp_can_read_hpd(p)) { if (p->desc->delay.hpd_absent) hpd_wait_us = p->desc->delay.hpd_absent * 1000UL; else hpd_wait_us = 2000000; - err = readx_poll_timeout(gpiod_get_value_cansleep, p->hpd_gpio, - hpd_asserted, hpd_asserted, - 1000, hpd_wait_us); - if (hpd_asserted < 0) - err = hpd_asserted; + if (p->hpd_gpio) { + err = readx_poll_timeout(gpiod_get_value_cansleep, + p->hpd_gpio, hpd_asserted, + hpd_asserted, 1000, hpd_wait_us); + if (hpd_asserted < 0) + err = hpd_asserted; + } else { + err = p->aux->wait_hpd_asserted(p->aux, hpd_wait_us); + } if (err) { if (err != -ETIMEDOUT) @@ -532,18 +542,22 @@ static int panel_edp_enable(struct drm_panel *panel) /* * If there is a "prepare_to_enable" delay then that's supposed to be * the delay from HPD going high until we can turn the backlight on. - * However, we can only count this if HPD is handled by the panel - * driver, not if it goes to a dedicated pin on the controller. + * However, we can only count this if HPD is readable by the panel + * driver. + * * If we aren't handling the HPD pin ourselves then the best we * can do is assume that HPD went high immediately before we were - * called (and link training took zero time). + * called (and link training took zero time). Note that "no-hpd" + * actually counts as handling HPD ourselves since we're doing the + * worst case delay (in prepare) ourselves. * * NOTE: if we ever end up in this "if" statement then we're * guaranteed that the panel_edp_wait() call below will do no delay. * It already handles that case, though, so we don't need any special * code for it. */ - if (p->desc->delay.prepare_to_enable && !p->hpd_gpio && !p->no_hpd) + if (p->desc->delay.prepare_to_enable && + !panel_edp_can_read_hpd(p) && !p->no_hpd) delay = max(delay, p->desc->delay.prepare_to_enable); if (delay) @@ -586,7 +600,10 @@ static int panel_edp_get_modes(struct drm_panel *panel, else if (!num) dev_warn(p->base.dev, "No display modes\n"); - /* set up connector's "panel orientation" property */ + /* + * TODO: Remove once all drm drivers call + * drm_connector_set_orientation_from_panel() + */ drm_connector_set_panel_orientation(connector, p->orientation); return num; @@ -609,6 +626,13 @@ static int panel_edp_get_timings(struct drm_panel *panel, return p->desc->num_timings; } +static enum drm_panel_orientation panel_edp_get_orientation(struct drm_panel *panel) +{ + struct panel_edp *p = to_panel_edp(panel); + + return p->orientation; +} + static int detected_panel_show(struct seq_file *s, void *data) { struct drm_panel *panel = s->private; @@ -637,6 +661,7 @@ static const struct drm_panel_funcs panel_edp_funcs = { .prepare = panel_edp_prepare, .enable = panel_edp_enable, .get_modes = panel_edp_get_modes, + .get_orientation = panel_edp_get_orientation, .get_timings = panel_edp_get_timings, .debugfs_init = panel_edp_debugfs_init, }; @@ -1860,6 +1885,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('K', 'D', 'B', 0x0624, &kingdisplay_kd116n21_30nv_a010.delay, "116N21-30NV-A010"), EDP_PANEL_ENTRY('K', 'D', 'B', 0x1120, &delay_200_500_e80_d50, "116N29-30NK-C007"), + EDP_PANEL_ENTRY('S', 'H', 'P', 0x1511, &delay_200_500_e50, "LQ140M1JW48"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &sharp_lq140m1jw46.delay, "LQ140M1JW46"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"), |