Skip to content

Commit f5aa7d4

Browse files
committed
drm/bridge: parade-ps8640: Provide wait_hpd_asserted() in struct drm_dp_aux
This implements the callback added by the patch ("drm/dp: Add wait_hpd_asserted() callback to struct drm_dp_aux"). With this change and all the two "DP AUX Endpoint" drivers changed to use wait_hpd_asserted(), we no longer need to have an long delay in the AUX transfer function. It's up to the panel code to make sure that the panel is powered now. If someone tried to call the aux transfer function without making sure the panel is powered we'll just get a normal transfer failure. We'll still keep the wait for HPD in the pre_enable() function. Though it's probably not actually needed there, this driver is used in the old mode (pre-DP AUX Endpoints) and it may be important for those cases. If nothing else, it shouldn't cause any big problems. NOTE: When handling the timeout for HPD we start the timer _after_ we've runtime resumed the device. This is definitely important for the panel on my homestar which comes up 170 ms after we start timing (the panel specifies 200 ms max). It's a little unclear how much of this extra time is due to some internal state machine in the parade firmware vs. debouncing but it seems to work for the two test cases I have to do it this way. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20220614145327.v4.4.Ie827321ce263be52fdb8c1276f6f8cc00d78029f@changeid
1 parent 3b5765d commit f5aa7d4

1 file changed

Lines changed: 26 additions & 13 deletions

File tree

drivers/gpu/drm/bridge/parade-ps8640.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,23 +169,35 @@ static bool ps8640_of_panel_on_aux_bus(struct device *dev)
169169
return true;
170170
}
171171

172-
static int ps8640_ensure_hpd(struct ps8640 *ps_bridge)
172+
static int _ps8640_wait_hpd_asserted(struct ps8640 *ps_bridge, unsigned long wait_us)
173173
{
174174
struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
175-
struct device *dev = &ps_bridge->page[PAGE2_TOP_CNTL]->dev;
176175
int status;
177-
int ret;
178176

179177
/*
180178
* Apparently something about the firmware in the chip signals that
181179
* HPD goes high by reporting GPIO9 as high (even though HPD isn't
182180
* actually connected to GPIO9).
183181
*/
184-
ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
185-
status & PS_GPIO9, 20 * 1000, 200 * 1000);
182+
return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
183+
status & PS_GPIO9, wait_us / 10, wait_us);
184+
}
186185

187-
if (ret < 0)
188-
dev_warn(dev, "HPD didn't go high: %d\n", ret);
186+
static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
187+
{
188+
struct ps8640 *ps_bridge = aux_to_ps8640(aux);
189+
struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev;
190+
int ret;
191+
192+
/*
193+
* Note that this function is called by code that has already powered
194+
* the panel. We have to power ourselves up but we don't need to worry
195+
* about powering the panel.
196+
*/
197+
pm_runtime_get_sync(dev);
198+
ret = _ps8640_wait_hpd_asserted(ps_bridge, wait_us);
199+
pm_runtime_mark_last_busy(dev);
200+
pm_runtime_put_autosuspend(dev);
189201

190202
return ret;
191203
}
@@ -324,9 +336,7 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
324336
int ret;
325337

326338
pm_runtime_get_sync(dev);
327-
ret = ps8640_ensure_hpd(ps_bridge);
328-
if (!ret)
329-
ret = ps8640_aux_transfer_msg(aux, msg);
339+
ret = ps8640_aux_transfer_msg(aux, msg);
330340
pm_runtime_mark_last_busy(dev);
331341
pm_runtime_put_autosuspend(dev);
332342

@@ -370,8 +380,8 @@ static int __maybe_unused ps8640_resume(struct device *dev)
370380
* Mystery 200 ms delay for the "MCU to be ready". It's unclear if
371381
* this is truly necessary since the MCU will already signal that
372382
* things are "good to go" by signaling HPD on "gpio 9". See
373-
* ps8640_ensure_hpd(). For now we'll keep this mystery delay just in
374-
* case.
383+
* _ps8640_wait_hpd_asserted(). For now we'll keep this mystery delay
384+
* just in case.
375385
*/
376386
msleep(200);
377387

@@ -407,7 +417,9 @@ static void ps8640_pre_enable(struct drm_bridge *bridge)
407417
int ret;
408418

409419
pm_runtime_get_sync(dev);
410-
ps8640_ensure_hpd(ps_bridge);
420+
ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000);
421+
if (ret < 0)
422+
dev_warn(dev, "HPD didn't go high: %d\n", ret);
411423

412424
/*
413425
* The Manufacturer Command Set (MCS) is a device dependent interface
@@ -683,6 +695,7 @@ static int ps8640_probe(struct i2c_client *client)
683695
ps_bridge->aux.name = "parade-ps8640-aux";
684696
ps_bridge->aux.dev = dev;
685697
ps_bridge->aux.transfer = ps8640_aux_transfer;
698+
ps_bridge->aux.wait_hpd_asserted = ps8640_wait_hpd_asserted;
686699
drm_dp_aux_init(&ps_bridge->aux);
687700

688701
pm_runtime_enable(dev);

0 commit comments

Comments
 (0)