drm/panel: simple: Support panels with HPD where HPD isn't connected
Some eDP panels that are designed to be always connected to a board use their HPD signal to signal that they've finished powering on and they're ready to be talked to. However, for various reasons it's possible that the HPD signal from the panel isn't actually hooked up. In the case where the HPD isn't hooked up you can look at the timing diagram on the panel datasheet and insert a delay for the maximum amount of time that the HPD might take to come up. Let's add support in simple-panel for this concept. At the moment we will co-opt the existing "prepare" delay to keep track of the delay and we'll use a boolean to specify that a given panel should only apply the delay if the "no-hpd" property was specified. Reviewed-by: Sean Paul <sean@poorly.run> Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20181025222134.174583-2-dianders@chromium.org
This commit is contained in:
Родитель
cb028e4912
Коммит
2ed3e9510f
|
@ -56,6 +56,8 @@ struct panel_desc {
|
||||||
/**
|
/**
|
||||||
* @prepare: the time (in milliseconds) that it takes for the panel to
|
* @prepare: the time (in milliseconds) that it takes for the panel to
|
||||||
* become ready and start receiving video data
|
* become ready and start receiving video data
|
||||||
|
* @hpd_absent_delay: Add this to the prepare delay if we know Hot
|
||||||
|
* Plug Detect isn't used.
|
||||||
* @enable: the time (in milliseconds) that it takes for the panel to
|
* @enable: the time (in milliseconds) that it takes for the panel to
|
||||||
* display the first valid frame after starting to receive
|
* display the first valid frame after starting to receive
|
||||||
* video data
|
* video data
|
||||||
|
@ -66,6 +68,7 @@ struct panel_desc {
|
||||||
*/
|
*/
|
||||||
struct {
|
struct {
|
||||||
unsigned int prepare;
|
unsigned int prepare;
|
||||||
|
unsigned int hpd_absent_delay;
|
||||||
unsigned int enable;
|
unsigned int enable;
|
||||||
unsigned int disable;
|
unsigned int disable;
|
||||||
unsigned int unprepare;
|
unsigned int unprepare;
|
||||||
|
@ -79,6 +82,7 @@ struct panel_simple {
|
||||||
struct drm_panel base;
|
struct drm_panel base;
|
||||||
bool prepared;
|
bool prepared;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
bool no_hpd;
|
||||||
|
|
||||||
const struct panel_desc *desc;
|
const struct panel_desc *desc;
|
||||||
|
|
||||||
|
@ -202,6 +206,7 @@ static int panel_simple_unprepare(struct drm_panel *panel)
|
||||||
static int panel_simple_prepare(struct drm_panel *panel)
|
static int panel_simple_prepare(struct drm_panel *panel)
|
||||||
{
|
{
|
||||||
struct panel_simple *p = to_panel_simple(panel);
|
struct panel_simple *p = to_panel_simple(panel);
|
||||||
|
unsigned int delay;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (p->prepared)
|
if (p->prepared)
|
||||||
|
@ -215,8 +220,11 @@ static int panel_simple_prepare(struct drm_panel *panel)
|
||||||
|
|
||||||
gpiod_set_value_cansleep(p->enable_gpio, 1);
|
gpiod_set_value_cansleep(p->enable_gpio, 1);
|
||||||
|
|
||||||
if (p->desc->delay.prepare)
|
delay = p->desc->delay.prepare;
|
||||||
msleep(p->desc->delay.prepare);
|
if (p->no_hpd)
|
||||||
|
delay += p->desc->delay.hpd_absent_delay;
|
||||||
|
if (delay)
|
||||||
|
msleep(delay);
|
||||||
|
|
||||||
p->prepared = true;
|
p->prepared = true;
|
||||||
|
|
||||||
|
@ -305,6 +313,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
|
||||||
panel->prepared = false;
|
panel->prepared = false;
|
||||||
panel->desc = desc;
|
panel->desc = desc;
|
||||||
|
|
||||||
|
panel->no_hpd = of_property_read_bool(dev->of_node, "no-hpd");
|
||||||
|
|
||||||
panel->supply = devm_regulator_get(dev, "power");
|
panel->supply = devm_regulator_get(dev, "power");
|
||||||
if (IS_ERR(panel->supply))
|
if (IS_ERR(panel->supply))
|
||||||
return PTR_ERR(panel->supply);
|
return PTR_ERR(panel->supply);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче