summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Menzynski <mmenzyns@redhat.com>2019-07-18 10:07:39 +0200
committerBen Skeggs <bskeggs@redhat.com>2019-08-23 12:55:33 +1000
commit72251fac062c0b4fe98670ec9e3db3f0702c50ae (patch)
tree3a6475b93a7d8806d0673867106189be2842be26
parente79ef1c0076ad82bab6915ada633a9d0efcb73fa (diff)
drm/nouveau/gpio: fail if gpu external power is missing
Currently, nouveau doesn't check if GPU is missing power. This patch makes nouveau fail when this happens on latest GPUs. It checks GPIO function 121 (External Power Emergency), which should detect power problems on GPU initialization. This can be disabled with nouveau.config=NvPowerChecks=1 Tested on TU104, GP106 and GF100. v3: * Add config override for disabling power checks Signed-off-by: Mark Menzynski <mmenzyns@redhat.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c30
2 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index 3f74b2726cf2..d036cdc45201 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -7,6 +7,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_TVDAC0 = 0x0c,
DCB_GPIO_TVDAC1 = 0x2d,
DCB_GPIO_FAN_SENSE = 0x3d,
+ DCB_GPIO_EXT_POWER_LOW = 0x79,
DCB_GPIO_LOGO_LED_PWM = 0x84,
DCB_GPIO_UNUSED = 0xff,
DCB_GPIO_VID0 = 0x04,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
index 1399d923d446..1337a110c0e3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
@@ -23,6 +23,7 @@
*/
#include "priv.h"
+#include <core/option.h>
#include <core/notify.h>
static int
@@ -182,12 +183,41 @@ static const struct dmi_system_id gpio_reset_ids[] = {
{ }
};
+static enum dcb_gpio_func_name power_checks[] = {
+ DCB_GPIO_EXT_POWER_LOW,
+};
+
static int
nvkm_gpio_init(struct nvkm_subdev *subdev)
{
struct nvkm_gpio *gpio = nvkm_gpio(subdev);
+ struct dcb_gpio_func func;
+ int ret;
+ int i;
+
if (dmi_check_system(gpio_reset_ids))
nvkm_gpio_reset(gpio, DCB_GPIO_UNUSED);
+
+ if (nvkm_boolopt(subdev->device->cfgopt, "NvPowerChecks", true)) {
+ for (i = 0; i < ARRAY_SIZE(power_checks); ++i) {
+ ret = nvkm_gpio_find(gpio, 0, power_checks[i],
+ DCB_GPIO_UNUSED, &func);
+ if (ret)
+ continue;
+
+ ret = nvkm_gpio_get(gpio, 0, func.func, func.line);
+ if (!ret)
+ continue;
+
+ nvkm_error(&gpio->subdev,
+ "GPU is missing power, check its power "
+ "cables. Boot with "
+ "nouveau.config=NvPowerChecks=0 to "
+ "disable.\n");
+ return -EINVAL;
+ }
+ }
+
return 0;
}