mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 20:23:57 +08:00
drm/nouveau/disp: move eDP panel power handling
We need to do this earlier to prevent aux channel timeouts in resume paths on certain systems. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
606557708f
commit
f6d52b2172
@ -409,26 +409,11 @@ static struct nouveau_encoder *
|
||||
nouveau_connector_ddc_detect(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
struct nvkm_gpio *gpio = nvxx_gpio(&drm->client.device);
|
||||
struct nouveau_encoder *nv_encoder = NULL, *found = NULL;
|
||||
struct drm_encoder *encoder;
|
||||
int i, ret, panel = -ENODEV;
|
||||
int i, ret;
|
||||
bool switcheroo_ddc = false;
|
||||
|
||||
/* eDP panels need powering on by us (if the VBIOS doesn't default it
|
||||
* to on) before doing any AUX channel transactions. LVDS panel power
|
||||
* is handled by the SOR itself, and not required for LVDS DDC.
|
||||
*/
|
||||
if (nv_connector->type == DCB_CONNECTOR_eDP) {
|
||||
panel = nvkm_gpio_get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
|
||||
if (panel == 0) {
|
||||
nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
|
||||
msleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
drm_connector_for_each_possible_encoder(connector, encoder, i) {
|
||||
nv_encoder = nouveau_encoder(encoder);
|
||||
|
||||
@ -462,12 +447,6 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
|
||||
break;
|
||||
}
|
||||
|
||||
/* eDP panel not detected, restore panel power GPIO to previous
|
||||
* state to avoid confusing the SOR for other output types.
|
||||
*/
|
||||
if (!found && panel == 0)
|
||||
nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bios/init.h>
|
||||
#include <subdev/gpio.h>
|
||||
#include <subdev/i2c.h>
|
||||
|
||||
#include <nvif/event.h>
|
||||
@ -491,7 +492,7 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
|
||||
{
|
||||
struct nvkm_i2c_aux *aux = dp->aux;
|
||||
@ -505,7 +506,7 @@ nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
|
||||
|
||||
if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, dp->dpcd,
|
||||
sizeof(dp->dpcd)))
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dp->present) {
|
||||
@ -515,6 +516,7 @@ nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
|
||||
}
|
||||
|
||||
atomic_set(&dp->lt.done, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -555,9 +557,38 @@ nvkm_dp_fini(struct nvkm_outp *outp)
|
||||
static void
|
||||
nvkm_dp_init(struct nvkm_outp *outp)
|
||||
{
|
||||
struct nvkm_gpio *gpio = outp->disp->engine.subdev.device->gpio;
|
||||
struct nvkm_dp *dp = nvkm_dp(outp);
|
||||
|
||||
nvkm_notify_put(&dp->outp.conn->hpd);
|
||||
nvkm_dp_enable(dp, true);
|
||||
|
||||
/* eDP panels need powering on by us (if the VBIOS doesn't default it
|
||||
* to on) before doing any AUX channel transactions. LVDS panel power
|
||||
* is handled by the SOR itself, and not required for LVDS DDC.
|
||||
*/
|
||||
if (dp->outp.conn->info.type == DCB_CONNECTOR_eDP) {
|
||||
int power = nvkm_gpio_get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
|
||||
if (power == 0)
|
||||
nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
|
||||
|
||||
/* We delay here unconditionally, even if already powered,
|
||||
* because some laptop panels having a significant resume
|
||||
* delay before the panel begins responding.
|
||||
*
|
||||
* This is likely a bit of a hack, but no better idea for
|
||||
* handling this at the moment.
|
||||
*/
|
||||
msleep(300);
|
||||
|
||||
/* If the eDP panel can't be detected, we need to restore
|
||||
* the panel power GPIO to avoid breaking another output.
|
||||
*/
|
||||
if (!nvkm_dp_enable(dp, true) && power == 0)
|
||||
nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 0);
|
||||
} else {
|
||||
nvkm_dp_enable(dp, true);
|
||||
}
|
||||
|
||||
nvkm_notify_get(&dp->hpd);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user