| .. | .. |
|---|
| 23 | 23 | */ |
|---|
| 24 | 24 | #include "priv.h" |
|---|
| 25 | 25 | |
|---|
| 26 | +#include <core/option.h> |
|---|
| 26 | 27 | #include <core/notify.h> |
|---|
| 27 | 28 | |
|---|
| 28 | 29 | static int |
|---|
| .. | .. |
|---|
| 182 | 183 | { } |
|---|
| 183 | 184 | }; |
|---|
| 184 | 185 | |
|---|
| 186 | +static enum dcb_gpio_func_name power_checks[] = { |
|---|
| 187 | + DCB_GPIO_THERM_EXT_POWER_EVENT, |
|---|
| 188 | + DCB_GPIO_POWER_ALERT, |
|---|
| 189 | + DCB_GPIO_EXT_POWER_LOW, |
|---|
| 190 | +}; |
|---|
| 191 | + |
|---|
| 185 | 192 | static int |
|---|
| 186 | 193 | nvkm_gpio_init(struct nvkm_subdev *subdev) |
|---|
| 187 | 194 | { |
|---|
| 188 | 195 | struct nvkm_gpio *gpio = nvkm_gpio(subdev); |
|---|
| 196 | + struct dcb_gpio_func func; |
|---|
| 197 | + int ret; |
|---|
| 198 | + int i; |
|---|
| 199 | + |
|---|
| 189 | 200 | if (dmi_check_system(gpio_reset_ids)) |
|---|
| 190 | 201 | nvkm_gpio_reset(gpio, DCB_GPIO_UNUSED); |
|---|
| 202 | + |
|---|
| 203 | + if (nvkm_boolopt(subdev->device->cfgopt, "NvPowerChecks", true)) { |
|---|
| 204 | + for (i = 0; i < ARRAY_SIZE(power_checks); ++i) { |
|---|
| 205 | + ret = nvkm_gpio_find(gpio, 0, power_checks[i], |
|---|
| 206 | + DCB_GPIO_UNUSED, &func); |
|---|
| 207 | + if (ret) |
|---|
| 208 | + continue; |
|---|
| 209 | + |
|---|
| 210 | + ret = nvkm_gpio_get(gpio, 0, func.func, func.line); |
|---|
| 211 | + if (!ret) |
|---|
| 212 | + continue; |
|---|
| 213 | + |
|---|
| 214 | + nvkm_error(&gpio->subdev, |
|---|
| 215 | + "GPU is missing power, check its power " |
|---|
| 216 | + "cables. Boot with " |
|---|
| 217 | + "nouveau.config=NvPowerChecks=0 to " |
|---|
| 218 | + "disable.\n"); |
|---|
| 219 | + return -EINVAL; |
|---|
| 220 | + } |
|---|
| 221 | + } |
|---|
| 222 | + |
|---|
| 191 | 223 | return 0; |
|---|
| 192 | 224 | } |
|---|
| 193 | 225 | |
|---|