drm-misc-fixes for v6.19 final: nouveau ------- Revert adding atomic commit functions as it regresses pre-nv50. Fix bugs exposed by enabling 570 firmware. gma500 ------ Revert a regression caused by vblank changes. mgag200 ------- Replace a busy loop with a polling loop to fix that blocking 1 cpu for 300 ms roughly every 20 minutes. bridge ------ imx8mp-hdmi-pa: Use runtime pm to fix a bug in channel ordering.
Unified · Split
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/of_platform.h> | 9 | #include <linux/of_platform.h> |
| 10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
| 11 | #include <linux/pm_runtime.h> | ||
| 11 | #include <linux/regmap.h> | 12 | #include <linux/regmap.h> |
| 12 | #include <drm/bridge/dw_hdmi.h> | 13 | #include <drm/bridge/dw_hdmi.h> |
| 13 | #include <sound/asoundef.h> | 14 | #include <sound/asoundef.h> |
| @@ -33,6 +34,7 @@ · 19 unmodified lines | |||
| 33 | 34 | ||
| 34 | struct imx8mp_hdmi_pai { | 35 | struct imx8mp_hdmi_pai { |
| 35 | struct regmap *regmap; | 36 | struct regmap *regmap; |
| 37 | struct device *dev; | ||
| 36 | }; | 38 | }; |
| 37 | 39 | ||
| 38 | static void imx8mp_hdmi_pai_enable(struct dw_hdmi *dw_hdmi, int channel, | 40 | static void imx8mp_hdmi_pai_enable(struct dw_hdmi *dw_hdmi, int channel, |
| @@ -43,6 +45,9 @@ static void imx8mp_hdmi_pai_enable(struct dw_hdmi *dw_hdmi, int channel, · 4 unmodified lines | |||
| 43 | struct imx8mp_hdmi_pai *hdmi_pai = pdata->priv_audio; | 45 | struct imx8mp_hdmi_pai *hdmi_pai = pdata->priv_audio; |
| 44 | int val; | 46 | int val; |
| 45 | 47 | ||
| 48 | if (pm_runtime_resume_and_get(hdmi_pai->dev) < 0) | ||
| 49 | return; | ||
| 50 | |||
| 46 | /* PAI set control extended */ | 51 | /* PAI set control extended */ |
| 47 | val = WTMK_HIGH(3) | WTMK_LOW(3); | 52 | val = WTMK_HIGH(3) | WTMK_LOW(3); |
| 48 | val |= NUM_CH(channel); | 53 | val |= NUM_CH(channel); |
| @@ -85,6 +90,8 @@ static void imx8mp_hdmi_pai_disable(struct dw_hdmi *dw_hdmi) · 36 unmodified lines | |||
| 85 | 90 | ||
| 86 | /* Stop PAI */ | 91 | /* Stop PAI */ |
| 87 | regmap_write(hdmi_pai->regmap, HTX_PAI_CTRL, 0); | 92 | regmap_write(hdmi_pai->regmap, HTX_PAI_CTRL, 0); |
| 93 | |||
| 94 | pm_runtime_put_sync(hdmi_pai->dev); | ||
| 88 | } | 95 | } |
| 89 | 96 | ||
| 90 | static const struct regmap_config imx8mp_hdmi_pai_regmap_config = { | 97 | static const struct regmap_config imx8mp_hdmi_pai_regmap_config = { |
| @@ -101,6 +108,7 @@ static int imx8mp_hdmi_pai_bind(struct device *dev, struct device *master, void · 10 unmodified lines | |||
| 101 | struct imx8mp_hdmi_pai *hdmi_pai; | 108 | struct imx8mp_hdmi_pai *hdmi_pai; |
| 102 | struct resource *res; | 109 | struct resource *res; |
| 103 | void __iomem *base; | 110 | void __iomem *base; |
| 111 | int ret; | ||
| 104 | 112 | ||
| 105 | hdmi_pai = devm_kzalloc(dev, sizeof(*hdmi_pai), GFP_KERNEL); | 113 | hdmi_pai = devm_kzalloc(dev, sizeof(*hdmi_pai), GFP_KERNEL); |
| 106 | if (!hdmi_pai) | 114 | if (!hdmi_pai) |
| @@ -121,6 +129,13 @@ static int imx8mp_hdmi_pai_bind(struct device *dev, struct device *master, void · 14 unmodified lines | |||
| 121 | plat_data->disable_audio = imx8mp_hdmi_pai_disable; | 129 | plat_data->disable_audio = imx8mp_hdmi_pai_disable; |
| 122 | plat_data->priv_audio = hdmi_pai; | 130 | plat_data->priv_audio = hdmi_pai; |
| 123 | 131 | ||
| 132 | hdmi_pai->dev = dev; | ||
| 133 | ret = devm_pm_runtime_enable(dev); | ||
| 134 | if (ret < 0) { | ||
| 135 | dev_err(dev, "failed to enable PM runtime: %d\n", ret); | ||
| 136 | return ret; | ||
| 137 | } | ||
| 138 | |||
| 124 | return 0; | 139 | return 0; |
| 125 | } | 140 | } |
| 126 | 141 | ||
| @@ -250,7 +250,6 @@ static irqreturn_t gma_irq_handler(int irq, void *arg) · 249 unmodified lines | |||
| 250 | void gma_irq_preinstall(struct drm_device *dev) | 250 | void gma_irq_preinstall(struct drm_device *dev) |
| 251 | { | 251 | { |
| 252 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); | 252 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
| 253 | struct drm_crtc *crtc; | ||
| 254 | unsigned long irqflags; | 253 | unsigned long irqflags; |
| 255 | 254 | ||
| 256 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); | 255 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); |
| @@ -261,15 +260,10 @@ void gma_irq_preinstall(struct drm_device *dev) · 4 unmodified lines | |||
| 261 | PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE); | 260 | PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE); |
| 262 | PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); | 261 | PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); |
| 263 | 262 | ||
| 264 | drm_for_each_crtc(crtc, dev) { | 263 | if (dev->vblank[0].enabled) |
| 265 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc); | 264 | dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; |
| 266 | 265 | if (dev->vblank[1].enabled) | |
| 267 | if (vblank->enabled) { | 266 | dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; |
| 268 | u32 mask = drm_crtc_index(crtc) ? _PSB_VSYNC_PIPEB_FLAG : | ||
| 269 | _PSB_VSYNC_PIPEA_FLAG; | ||
| 270 | dev_priv->vdc_irq_mask |= mask; | ||
| 271 | } | ||
| 272 | } | ||
| 273 | 267 | ||
| 274 | /* Revisit this area - want per device masks ? */ | 268 | /* Revisit this area - want per device masks ? */ |
| 275 | if (dev_priv->ops->hotplug) | 269 | if (dev_priv->ops->hotplug) |
| @@ -284,8 +278,8 @@ void gma_irq_preinstall(struct drm_device *dev) · 8 unmodified lines | |||
| 284 | void gma_irq_postinstall(struct drm_device *dev) | 278 | void gma_irq_postinstall(struct drm_device *dev) |
| 285 | { | 279 | { |
| 286 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); | 280 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
| 287 | struct drm_crtc *crtc; | ||
| 288 | unsigned long irqflags; | 281 | unsigned long irqflags; |
| 282 | unsigned int i; | ||
| 289 | 283 | ||
| 290 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); | 284 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); |
| 291 | 285 | ||
| @@ -298,13 +292,11 @@ void gma_irq_postinstall(struct drm_device *dev) · 6 unmodified lines | |||
| 298 | PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); | 292 | PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); |
| 299 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); | 293 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); |
| 300 | 294 | ||
| 301 | drm_for_each_crtc(crtc, dev) { | 295 | for (i = 0; i < dev->num_crtcs; ++i) { |
| 302 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc); | 296 | if (dev->vblank[i].enabled) |
| 303 | 297 | gma_enable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); | |
| 304 | if (vblank->enabled) | ||
| 305 | gma_enable_pipestat(dev_priv, drm_crtc_index(crtc), PIPE_VBLANK_INTERRUPT_ENABLE); | ||
| 306 | else | 298 | else |
| 307 | gma_disable_pipestat(dev_priv, drm_crtc_index(crtc), PIPE_VBLANK_INTERRUPT_ENABLE); | 299 | gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); |
| 308 | } | 300 | } |
| 309 | 301 | ||
| 310 | if (dev_priv->ops->hotplug_enable) | 302 | if (dev_priv->ops->hotplug_enable) |
| @@ -345,8 +337,8 @@ void gma_irq_uninstall(struct drm_device *dev) · 34 unmodified lines | |||
| 345 | { | 337 | { |
| 346 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); | 338 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
| 347 | struct pci_dev *pdev = to_pci_dev(dev->dev); | 339 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
| 348 | struct drm_crtc *crtc; | ||
| 349 | unsigned long irqflags; | 340 | unsigned long irqflags; |
| 341 | unsigned int i; | ||
| 350 | 342 | ||
| 351 | if (!dev_priv->irq_enabled) | 343 | if (!dev_priv->irq_enabled) |
| 352 | return; | 344 | return; |
| @@ -358,11 +350,9 @@ void gma_irq_uninstall(struct drm_device *dev) · 5 unmodified lines | |||
| 358 | 350 | ||
| 359 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); | 351 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); |
| 360 | 352 | ||
| 361 | drm_for_each_crtc(crtc, dev) { | 353 | for (i = 0; i < dev->num_crtcs; ++i) { |
| 362 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc); | 354 | if (dev->vblank[i].enabled) |
| 363 | 355 | gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); | |
| 364 | if (vblank->enabled) | ||
| 365 | gma_disable_pipestat(dev_priv, drm_crtc_index(crtc), PIPE_VBLANK_INTERRUPT_ENABLE); | ||
| 366 | } | 356 | } |
| 367 | 357 | ||
| 368 | dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | | 358 | dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | |
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | ||
| 3 | #include <linux/delay.h> | 3 | #include <linux/delay.h> |
| 4 | #include <linux/iopoll.h> | ||
| 4 | 5 | ||
| 5 | #include <drm/drm_atomic_helper.h> | 6 | #include <drm/drm_atomic_helper.h> |
| 6 | #include <drm/drm_edid.h> | 7 | #include <drm/drm_edid.h> |
| @@ -12,7 +13,7 @@ · 5 unmodified lines | |||
| 12 | void mgag200_bmc_stop_scanout(struct mga_device *mdev) | 13 | void mgag200_bmc_stop_scanout(struct mga_device *mdev) |
| 13 | { | 14 | { |
| 14 | u8 tmp; | 15 | u8 tmp; |
| 15 | int iter_max; | 16 | int ret; |
| 16 | 17 | ||
| 17 | /* | 18 | /* |
| 18 | * 1 - The first step is to inform the BMC of an upcoming mode | 19 | * 1 - The first step is to inform the BMC of an upcoming mode |
| @@ -42,30 +43,22 @@ void mgag200_bmc_stop_scanout(struct mga_device *mdev) · 23 unmodified lines | |||
| 42 | 43 | ||
| 43 | /* | 44 | /* |
| 44 | * 3a- The third step is to verify if there is an active scan. | 45 | * 3a- The third step is to verify if there is an active scan. |
| 45 | * We are waiting for a 0 on remhsyncsts <XSPAREREG<0>). | 46 | * We are waiting for a 0 on remhsyncsts (<XSPAREREG<0>). |
| 46 | */ | 47 | */ |
| 47 | iter_max = 300; | 48 | ret = read_poll_timeout(RREG_DAC, tmp, !(tmp & 0x1), |
| 48 | while (!(tmp & 0x1) && iter_max) { | 49 | 1000, 300000, false, |
| 49 | WREG8(DAC_INDEX, MGA1064_SPAREREG); | 50 | MGA1064_SPAREREG); |
| 50 | tmp = RREG8(DAC_DATA); | 51 | if (ret == -ETIMEDOUT) |
| 51 | udelay(1000); | 52 | return; |
| 52 | iter_max--; | ||
| 53 | } | ||
| 54 | 53 | ||
| 55 | /* | 54 | /* |
| 56 | * 3b- This step occurs only if the remove is actually | 55 | * 3b- This step occurs only if the remote BMC is actually |
| 57 | * scanning. We are waiting for the end of the frame which is | 56 | * scanning. We are waiting for the end of the frame which is |
| 58 | * a 1 on remvsyncsts (XSPAREREG<1>) | 57 | * a 1 on remvsyncsts (XSPAREREG<1>) |
| 59 | */ | 58 | */ |
| 60 | if (iter_max) { | 59 | (void)read_poll_timeout(RREG_DAC, tmp, (tmp & 0x2), |
| 61 | iter_max = 300; | 60 | 1000, 300000, false, |
| 62 | while ((tmp & 0x2) && iter_max) { | 61 | MGA1064_SPAREREG); |
| 63 | WREG8(DAC_INDEX, MGA1064_SPAREREG); | ||
| 64 | tmp = RREG8(DAC_DATA); | ||
| 65 | udelay(1000); | ||
| 66 | iter_max--; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } | 62 | } |
| 70 | 63 | ||
| 71 | void mgag200_bmc_start_scanout(struct mga_device *mdev) | 64 | void mgag200_bmc_start_scanout(struct mga_device *mdev) |
| @@ -111,6 +111,12 @@ · 110 unmodified lines | |||
| 111 | #define DAC_INDEX 0x3c00 | 111 | #define DAC_INDEX 0x3c00 |
| 112 | #define DAC_DATA 0x3c0a | 112 | #define DAC_DATA 0x3c0a |
| 113 | 113 | ||
| 114 | #define RREG_DAC(reg) \ | ||
| 115 | ({ \ | ||
| 116 | WREG8(DAC_INDEX, reg); \ | ||
| 117 | RREG8(DAC_DATA); \ | ||
| 118 | }) \ | ||
| 119 | |||
| 114 | #define WREG_DAC(reg, v) \ | 120 | #define WREG_DAC(reg, v) \ |
| 115 | do { \ | 121 | do { \ |
| 116 | WREG8(DAC_INDEX, reg); \ | 122 | WREG8(DAC_INDEX, reg); \ |
| @@ -11,7 +11,7 @@ struct nvif_client { · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | int nvif_client_ctor(struct nvif_client *parent, const char *name, struct nvif_client *); | 12 | int nvif_client_ctor(struct nvif_client *parent, const char *name, struct nvif_client *); |
| 13 | void nvif_client_dtor(struct nvif_client *); | 13 | void nvif_client_dtor(struct nvif_client *); |
| 14 | int nvif_client_suspend(struct nvif_client *); | 14 | int nvif_client_suspend(struct nvif_client *, bool); |
| 15 | int nvif_client_resume(struct nvif_client *); | 15 | int nvif_client_resume(struct nvif_client *); |
| 16 | 16 | ||
| 17 | /*XXX*/ | 17 | /*XXX*/ |
| @@ -8,7 +8,7 @@ struct nvif_driver { · 7 unmodified lines | |||
| 8 | const char *name; | 8 | const char *name; |
| 9 | int (*init)(const char *name, u64 device, const char *cfg, | 9 | int (*init)(const char *name, u64 device, const char *cfg, |
| 10 | const char *dbg, void **priv); | 10 | const char *dbg, void **priv); |
| 11 | int (*suspend)(void *priv); | 11 | int (*suspend)(void *priv, bool runtime); |
| 12 | int (*resume)(void *priv); | 12 | int (*resume)(void *priv); |
| 13 | int (*ioctl)(void *priv, void *data, u32 size, void **hack); | 13 | int (*ioctl)(void *priv, void *data, u32 size, void **hack); |
| 14 | void __iomem *(*map)(void *priv, u64 handle, u32 size); | 14 | void __iomem *(*map)(void *priv, u64 handle, u32 size); |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #ifndef __NVKM_DEVICE_H__ | 2 | #ifndef __NVKM_DEVICE_H__ |
| 3 | #define __NVKM_DEVICE_H__ | 3 | #define __NVKM_DEVICE_H__ |
| 4 | #include <core/oclass.h> | 4 | #include <core/oclass.h> |
| 5 | #include <core/suspend_state.h> | ||
| 5 | #include <core/intr.h> | 6 | #include <core/intr.h> |
| 6 | enum nvkm_subdev_type; | 7 | enum nvkm_subdev_type; |
| 7 | 8 | ||
| @@ -93,7 +94,7 @@ struct nvkm_device_func { · 85 unmodified lines | |||
| 93 | void *(*dtor)(struct nvkm_device *); | 94 | void *(*dtor)(struct nvkm_device *); |
| 94 | int (*preinit)(struct nvkm_device *); | 95 | int (*preinit)(struct nvkm_device *); |
| 95 | int (*init)(struct nvkm_device *); | 96 | int (*init)(struct nvkm_device *); |
| 96 | void (*fini)(struct nvkm_device *, bool suspend); | 97 | void (*fini)(struct nvkm_device *, enum nvkm_suspend_state suspend); |
| 97 | int (*irq)(struct nvkm_device *); | 98 | int (*irq)(struct nvkm_device *); |
| 98 | resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id); | 99 | resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id); |
| 99 | resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id); | 100 | resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id); |
| @@ -20,7 +20,7 @@ struct nvkm_engine_func { · 19 unmodified lines | |||
| 20 | int (*oneinit)(struct nvkm_engine *); | 20 | int (*oneinit)(struct nvkm_engine *); |
| 21 | int (*info)(struct nvkm_engine *, u64 mthd, u64 *data); | 21 | int (*info)(struct nvkm_engine *, u64 mthd, u64 *data); |
| 22 | int (*init)(struct nvkm_engine *); | 22 | int (*init)(struct nvkm_engine *); |
| 23 | int (*fini)(struct nvkm_engine *, bool suspend); | 23 | int (*fini)(struct nvkm_engine *, enum nvkm_suspend_state suspend); |
| 24 | int (*reset)(struct nvkm_engine *); | 24 | int (*reset)(struct nvkm_engine *); |
| 25 | int (*nonstall)(struct nvkm_engine *); | 25 | int (*nonstall)(struct nvkm_engine *); |
| 26 | void (*intr)(struct nvkm_engine *); | 26 | void (*intr)(struct nvkm_engine *); |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #ifndef __NVKM_OBJECT_H__ | 2 | #ifndef __NVKM_OBJECT_H__ |
| 3 | #define __NVKM_OBJECT_H__ | 3 | #define __NVKM_OBJECT_H__ |
| 4 | #include <core/oclass.h> | 4 | #include <core/oclass.h> |
| 5 | #include <core/suspend_state.h> | ||
| 5 | struct nvkm_event; | 6 | struct nvkm_event; |
| 6 | struct nvkm_gpuobj; | 7 | struct nvkm_gpuobj; |
| 7 | struct nvkm_uevent; | 8 | struct nvkm_uevent; |
| @@ -27,7 +28,7 @@ enum nvkm_object_map { · 19 unmodified lines | |||
| 27 | struct nvkm_object_func { | 28 | struct nvkm_object_func { |
| 28 | void *(*dtor)(struct nvkm_object *); | 29 | void *(*dtor)(struct nvkm_object *); |
| 29 | int (*init)(struct nvkm_object *); | 30 | int (*init)(struct nvkm_object *); |
| 30 | int (*fini)(struct nvkm_object *, bool suspend); | 31 | int (*fini)(struct nvkm_object *, enum nvkm_suspend_state suspend); |
| 31 | int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size); | 32 | int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size); |
| 32 | int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **); | 33 | int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **); |
| 33 | int (*map)(struct nvkm_object *, void *argv, u32 argc, | 34 | int (*map)(struct nvkm_object *, void *argv, u32 argc, |
| @@ -49,7 +50,7 @@ int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size, · 15 unmodified lines | |||
| 49 | void nvkm_object_del(struct nvkm_object **); | 50 | void nvkm_object_del(struct nvkm_object **); |
| 50 | void *nvkm_object_dtor(struct nvkm_object *); | 51 | void *nvkm_object_dtor(struct nvkm_object *); |
| 51 | int nvkm_object_init(struct nvkm_object *); | 52 | int nvkm_object_init(struct nvkm_object *); |
| 52 | int nvkm_object_fini(struct nvkm_object *, bool suspend); | 53 | int nvkm_object_fini(struct nvkm_object *, enum nvkm_suspend_state); |
| 53 | int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size); | 54 | int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size); |
| 54 | int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **); | 55 | int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **); |
| 55 | int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc, | 56 | int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc, |
| @@ -13,7 +13,7 @@ struct nvkm_oproxy { · 12 unmodified lines | |||
| 13 | struct nvkm_oproxy_func { | 13 | struct nvkm_oproxy_func { |
| 14 | void (*dtor[2])(struct nvkm_oproxy *); | 14 | void (*dtor[2])(struct nvkm_oproxy *); |
| 15 | int (*init[2])(struct nvkm_oproxy *); | 15 | int (*init[2])(struct nvkm_oproxy *); |
| 16 | int (*fini[2])(struct nvkm_oproxy *, bool suspend); | 16 | int (*fini[2])(struct nvkm_oproxy *, enum nvkm_suspend_state suspend); |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | void nvkm_oproxy_ctor(const struct nvkm_oproxy_func *, | 19 | void nvkm_oproxy_ctor(const struct nvkm_oproxy_func *, |
| @@ -40,7 +40,7 @@ struct nvkm_subdev_func { · 39 unmodified lines | |||
| 40 | int (*oneinit)(struct nvkm_subdev *); | 40 | int (*oneinit)(struct nvkm_subdev *); |
| 41 | int (*info)(struct nvkm_subdev *, u64 mthd, u64 *data); | 41 | int (*info)(struct nvkm_subdev *, u64 mthd, u64 *data); |
| 42 | int (*init)(struct nvkm_subdev *); | 42 | int (*init)(struct nvkm_subdev *); |
| 43 | int (*fini)(struct nvkm_subdev *, bool suspend); | 43 | int (*fini)(struct nvkm_subdev *, enum nvkm_suspend_state suspend); |
| 44 | void (*intr)(struct nvkm_subdev *); | 44 | void (*intr)(struct nvkm_subdev *); |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| @@ -65,7 +65,7 @@ void nvkm_subdev_unref(struct nvkm_subdev *); · 18 unmodified lines | |||
| 65 | int nvkm_subdev_preinit(struct nvkm_subdev *); | 65 | int nvkm_subdev_preinit(struct nvkm_subdev *); |
| 66 | int nvkm_subdev_oneinit(struct nvkm_subdev *); | 66 | int nvkm_subdev_oneinit(struct nvkm_subdev *); |
| 67 | int nvkm_subdev_init(struct nvkm_subdev *); | 67 | int nvkm_subdev_init(struct nvkm_subdev *); |
| 68 | int nvkm_subdev_fini(struct nvkm_subdev *, bool suspend); | 68 | int nvkm_subdev_fini(struct nvkm_subdev *, enum nvkm_suspend_state suspend); |
| 69 | int nvkm_subdev_info(struct nvkm_subdev *, u64, u64 *); | 69 | int nvkm_subdev_info(struct nvkm_subdev *, u64, u64 *); |
| 70 | void nvkm_subdev_intr(struct nvkm_subdev *); | 70 | void nvkm_subdev_intr(struct nvkm_subdev *); |
| 71 | 71 | ||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* SPDX-License-Identifier: MIT */ | ||
| 2 | #ifndef __NVKM_SUSPEND_STATE_H__ | ||
| 3 | #define __NVKM_SUSPEND_STATE_H__ | ||
| 4 | |||
| 5 | enum nvkm_suspend_state { | ||
| 6 | NVKM_POWEROFF, | ||
| 7 | NVKM_SUSPEND, | ||
| 8 | NVKM_RUNTIME_SUSPEND, | ||
| 9 | }; | ||
| 10 | |||
| 11 | #endif | ||
| @@ -44,6 +44,9 @@ typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 rep · 43 unmodified lines | |||
| 44 | * NVKM_GSP_RPC_REPLY_NOWAIT - If specified, immediately return to the | 44 | * NVKM_GSP_RPC_REPLY_NOWAIT - If specified, immediately return to the |
| 45 | * caller after the GSP RPC command is issued. | 45 | * caller after the GSP RPC command is issued. |
| 46 | * | 46 | * |
| 47 | * NVKM_GSP_RPC_REPLY_NOSEQ - If specified, exactly like NOWAIT | ||
| 48 | * but don't emit RPC sequence number. | ||
| 49 | * | ||
| 47 | * NVKM_GSP_RPC_REPLY_RECV - If specified, wait and receive the entire GSP | 50 | * NVKM_GSP_RPC_REPLY_RECV - If specified, wait and receive the entire GSP |
| 48 | * RPC message after the GSP RPC command is issued. | 51 | * RPC message after the GSP RPC command is issued. |
| 49 | * | 52 | * |
| @@ -53,6 +56,7 @@ typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 rep · 3 unmodified lines | |||
| 53 | */ | 56 | */ |
| 54 | enum nvkm_gsp_rpc_reply_policy { | 57 | enum nvkm_gsp_rpc_reply_policy { |
| 55 | NVKM_GSP_RPC_REPLY_NOWAIT = 0, | 58 | NVKM_GSP_RPC_REPLY_NOWAIT = 0, |
| 59 | NVKM_GSP_RPC_REPLY_NOSEQ, | ||
| 56 | NVKM_GSP_RPC_REPLY_RECV, | 60 | NVKM_GSP_RPC_REPLY_RECV, |
| 57 | NVKM_GSP_RPC_REPLY_POLL, | 61 | NVKM_GSP_RPC_REPLY_POLL, |
| 58 | }; | 62 | }; |
| @@ -242,6 +246,8 @@ struct nvkm_gsp { · 183 unmodified lines | |||
| 242 | /* The size of the registry RPC */ | 246 | /* The size of the registry RPC */ |
| 243 | size_t registry_rpc_size; | 247 | size_t registry_rpc_size; |
| 244 | 248 | ||
| 249 | u32 rpc_seq; | ||
| 250 | |||
| 245 | #ifdef CONFIG_DEBUG_FS | 251 | #ifdef CONFIG_DEBUG_FS |
| 246 | /* | 252 | /* |
| 247 | * Logging buffers in debugfs. The wrapper objects need to remain | 253 | * Logging buffers in debugfs. The wrapper objects need to remain |
| @@ -352,8 +352,6 @@ nouveau_user_framebuffer_create(struct drm_device *dev, · 351 unmodified lines | |||
| 352 | 352 | ||
| 353 | static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { | 353 | static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { |
| 354 | .fb_create = nouveau_user_framebuffer_create, | 354 | .fb_create = nouveau_user_framebuffer_create, |
| 355 | .atomic_commit = drm_atomic_helper_commit, | ||
| 356 | .atomic_check = drm_atomic_helper_check, | ||
| 357 | }; | 355 | }; |
| 358 | 356 | ||
| 359 | 357 | ||
| @@ -983,7 +983,7 @@ nouveau_do_suspend(struct nouveau_drm *drm, bool runtime) · 982 unmodified lines | |||
| 983 | } | 983 | } |
| 984 | 984 | ||
| 985 | NV_DEBUG(drm, "suspending object tree...\n"); | 985 | NV_DEBUG(drm, "suspending object tree...\n"); |
| 986 | ret = nvif_client_suspend(&drm->_client); | 986 | ret = nvif_client_suspend(&drm->_client, runtime); |
| 987 | if (ret) | 987 | if (ret) |
| 988 | goto fail_client; | 988 | goto fail_client; |
| 989 | 989 | ||
| @@ -62,10 +62,16 @@ nvkm_client_resume(void *priv) · 61 unmodified lines | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static int | 64 | static int |
| 65 | nvkm_client_suspend(void *priv) | 65 | nvkm_client_suspend(void *priv, bool runtime) |
| 66 | { | 66 | { |
| 67 | struct nvkm_client *client = priv; | 67 | struct nvkm_client *client = priv; |
| 68 | return nvkm_object_fini(&client->object, true); | 68 | enum nvkm_suspend_state state; |
| 69 | |||
| 70 | if (runtime) | ||
| 71 | state = NVKM_RUNTIME_SUSPEND; | ||
| 72 | else | ||
| 73 | state = NVKM_SUSPEND; | ||
| 74 | return nvkm_object_fini(&client->object, state); | ||
| 69 | } | 75 | } |
| 70 | 76 | ||
| 71 | static int | 77 | static int |
| @@ -30,9 +30,9 @@ · 29 unmodified lines | |||
| 30 | #include <nvif/if0000.h> | 30 | #include <nvif/if0000.h> |
| 31 | 31 | ||
| 32 | int | 32 | int |
| 33 | nvif_client_suspend(struct nvif_client *client) | 33 | nvif_client_suspend(struct nvif_client *client, bool runtime) |
| 34 | { | 34 | { |
| 35 | return client->driver->suspend(client->object.priv); | 35 | return client->driver->suspend(client->object.priv, runtime); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | int | 38 | int |
| @@ -41,7 +41,7 @@ nvkm_engine_reset(struct nvkm_engine *engine) · 40 unmodified lines | |||
| 41 | if (engine->func->reset) | 41 | if (engine->func->reset) |
| 42 | return engine->func->reset(engine); | 42 | return engine->func->reset(engine); |
| 43 | 43 | ||
| 44 | nvkm_subdev_fini(&engine->subdev, false); | 44 | nvkm_subdev_fini(&engine->subdev, NVKM_POWEROFF); |
| 45 | return nvkm_subdev_init(&engine->subdev); | 45 | return nvkm_subdev_init(&engine->subdev); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| @@ -98,7 +98,7 @@ nvkm_engine_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data) · 50 unmodified lines | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static int | 100 | static int |
| 101 | nvkm_engine_fini(struct nvkm_subdev *subdev, bool suspend) | 101 | nvkm_engine_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 102 | { | 102 | { |
| 103 | struct nvkm_engine *engine = nvkm_engine(subdev); | 103 | struct nvkm_engine *engine = nvkm_engine(subdev); |
| 104 | if (engine->func->fini) | 104 | if (engine->func->fini) |
| @@ -141,7 +141,7 @@ nvkm_ioctl_new(struct nvkm_client *client, · 140 unmodified lines | |||
| 141 | } | 141 | } |
| 142 | ret = -EEXIST; | 142 | ret = -EEXIST; |
| 143 | } | 143 | } |
| 144 | nvkm_object_fini(object, false); | 144 | nvkm_object_fini(object, NVKM_POWEROFF); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | nvkm_object_del(&object); | 147 | nvkm_object_del(&object); |
| @@ -160,7 +160,7 @@ nvkm_ioctl_del(struct nvkm_client *client, · 12 unmodified lines | |||
| 160 | nvif_ioctl(object, "delete size %d\n", size); | 160 | nvif_ioctl(object, "delete size %d\n", size); |
| 161 | if (!(ret = nvif_unvers(ret, &data, &size, args->none))) { | 161 | if (!(ret = nvif_unvers(ret, &data, &size, args->none))) { |
| 162 | nvif_ioctl(object, "delete\n"); | 162 | nvif_ioctl(object, "delete\n"); |
| 163 | nvkm_object_fini(object, false); | 163 | nvkm_object_fini(object, NVKM_POWEROFF); |
| 164 | nvkm_object_del(&object); | 164 | nvkm_object_del(&object); |
| 165 | } | 165 | } |
| 166 | 166 | ||
| @@ -142,13 +142,25 @@ nvkm_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *gpuobj, · 141 unmodified lines | |||
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | int | 144 | int |
| 145 | nvkm_object_fini(struct nvkm_object *object, bool suspend) | 145 | nvkm_object_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 146 | { | 146 | { |
| 147 | const char *action = suspend ? "suspend" : "fini"; | 147 | const char *action; |
| 148 | struct nvkm_object *child; | 148 | struct nvkm_object *child; |
| 149 | s64 time; | 149 | s64 time; |
| 150 | int ret; | 150 | int ret; |
| 151 | 151 | ||
| 152 | switch (suspend) { | ||
| 153 | case NVKM_POWEROFF: | ||
| 154 | default: | ||
| 155 | action = "fini"; | ||
| 156 | break; | ||
| 157 | case NVKM_SUSPEND: | ||
| 158 | action = "suspend"; | ||
| 159 | break; | ||
| 160 | case NVKM_RUNTIME_SUSPEND: | ||
| 161 | action = "runtime"; | ||
| 162 | break; | ||
| 163 | } | ||
| 152 | nvif_debug(object, "%s children...\n", action); | 164 | nvif_debug(object, "%s children...\n", action); |
| 153 | time = ktime_to_us(ktime_get()); | 165 | time = ktime_to_us(ktime_get()); |
| 154 | list_for_each_entry_reverse(child, &object->tree, head) { | 166 | list_for_each_entry_reverse(child, &object->tree, head) { |
| @@ -212,11 +224,11 @@ nvkm_object_init(struct nvkm_object *object) · 57 unmodified lines | |||
| 212 | 224 | ||
| 213 | fail_child: | 225 | fail_child: |
| 214 | list_for_each_entry_continue_reverse(child, &object->tree, head) | 226 | list_for_each_entry_continue_reverse(child, &object->tree, head) |
| 215 | nvkm_object_fini(child, false); | 227 | nvkm_object_fini(child, NVKM_POWEROFF); |
| 216 | fail: | 228 | fail: |
| 217 | nvif_error(object, "init failed with %d\n", ret); | 229 | nvif_error(object, "init failed with %d\n", ret); |
| 218 | if (object->func->fini) | 230 | if (object->func->fini) |
| 219 | object->func->fini(object, false); | 231 | object->func->fini(object, NVKM_POWEROFF); |
| 220 | return ret; | 232 | return ret; |
| 221 | } | 233 | } |
| 222 | 234 | ||
| @@ -87,7 +87,7 @@ nvkm_oproxy_uevent(struct nvkm_object *object, void *argv, u32 argc, · 86 unmodified lines | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | static int | 89 | static int |
| 90 | nvkm_oproxy_fini(struct nvkm_object *object, bool suspend) | 90 | nvkm_oproxy_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 91 | { | 91 | { |
| 92 | struct nvkm_oproxy *oproxy = nvkm_oproxy(object); | 92 | struct nvkm_oproxy *oproxy = nvkm_oproxy(object); |
| 93 | int ret; | 93 | int ret; |
| @@ -51,12 +51,24 @@ nvkm_subdev_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data) · 50 unmodified lines | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | int | 53 | int |
| 54 | nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) | 54 | nvkm_subdev_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 55 | { | 55 | { |
| 56 | struct nvkm_device *device = subdev->device; | 56 | struct nvkm_device *device = subdev->device; |
| 57 | const char *action = suspend ? "suspend" : subdev->use.enabled ? "fini" : "reset"; | 57 | const char *action; |
| 58 | s64 time; | 58 | s64 time; |
| 59 | 59 | ||
| 60 | switch (suspend) { | ||
| 61 | case NVKM_POWEROFF: | ||
| 62 | default: | ||
| 63 | action = subdev->use.enabled ? "fini" : "reset"; | ||
| 64 | break; | ||
| 65 | case NVKM_SUSPEND: | ||
| 66 | action = "suspend"; | ||
| 67 | break; | ||
| 68 | case NVKM_RUNTIME_SUSPEND: | ||
| 69 | action = "runtime"; | ||
| 70 | break; | ||
| 71 | } | ||
| 60 | nvkm_trace(subdev, "%s running...\n", action); | 72 | nvkm_trace(subdev, "%s running...\n", action); |
| 61 | time = ktime_to_us(ktime_get()); | 73 | time = ktime_to_us(ktime_get()); |
| 62 | 74 | ||
| @@ -186,7 +198,7 @@ void · 123 unmodified lines | |||
| 186 | nvkm_subdev_unref(struct nvkm_subdev *subdev) | 198 | nvkm_subdev_unref(struct nvkm_subdev *subdev) |
| 187 | { | 199 | { |
| 188 | if (refcount_dec_and_mutex_lock(&subdev->use.refcount, &subdev->use.mutex)) { | 200 | if (refcount_dec_and_mutex_lock(&subdev->use.refcount, &subdev->use.mutex)) { |
| 189 | nvkm_subdev_fini(subdev, false); | 201 | nvkm_subdev_fini(subdev, NVKM_POWEROFF); |
| 190 | mutex_unlock(&subdev->use.mutex); | 202 | mutex_unlock(&subdev->use.mutex); |
| 191 | } | 203 | } |
| 192 | } | 204 | } |
| @@ -73,7 +73,7 @@ nvkm_uevent_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc) · 72 unmodified lines | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static int | 75 | static int |
| 76 | nvkm_uevent_fini(struct nvkm_object *object, bool suspend) | 76 | nvkm_uevent_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 77 | { | 77 | { |
| 78 | struct nvkm_uevent *uevent = nvkm_uevent(object); | 78 | struct nvkm_uevent *uevent = nvkm_uevent(object); |
| 79 | 79 | ||
| @@ -46,7 +46,7 @@ ga100_ce_nonstall(struct nvkm_engine *engine) · 45 unmodified lines | |||
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | int | 48 | int |
| 49 | ga100_ce_fini(struct nvkm_engine *engine, bool suspend) | 49 | ga100_ce_fini(struct nvkm_engine *engine, enum nvkm_suspend_state suspend) |
| 50 | { | 50 | { |
| 51 | nvkm_inth_block(&engine->subdev.inth); | 51 | nvkm_inth_block(&engine->subdev.inth); |
| 52 | return 0; | 52 | return 0; |
| @@ -14,7 +14,7 @@ extern const struct nvkm_object_func gv100_ce_cclass; · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | int ga100_ce_oneinit(struct nvkm_engine *); | 15 | int ga100_ce_oneinit(struct nvkm_engine *); |
| 16 | int ga100_ce_init(struct nvkm_engine *); | 16 | int ga100_ce_init(struct nvkm_engine *); |
| 17 | int ga100_ce_fini(struct nvkm_engine *, bool); | 17 | int ga100_ce_fini(struct nvkm_engine *, enum nvkm_suspend_state); |
| 18 | int ga100_ce_nonstall(struct nvkm_engine *); | 18 | int ga100_ce_nonstall(struct nvkm_engine *); |
| 19 | 19 | ||
| 20 | u32 gb202_ce_grce_mask(struct nvkm_device *); | 20 | u32 gb202_ce_grce_mask(struct nvkm_device *); |
| @@ -2936,13 +2936,25 @@ nvkm_device_engine(struct nvkm_device *device, int type, int inst) · 2935 unmodified lines | |||
| 2936 | } | 2936 | } |
| 2937 | 2937 | ||
| 2938 | int | 2938 | int |
| 2939 | nvkm_device_fini(struct nvkm_device *device, bool suspend) | 2939 | nvkm_device_fini(struct nvkm_device *device, enum nvkm_suspend_state suspend) |
| 2940 | { | 2940 | { |
| 2941 | const char *action = suspend ? "suspend" : "fini"; | 2941 | const char *action; |
| 2942 | struct nvkm_subdev *subdev; | 2942 | struct nvkm_subdev *subdev; |
| 2943 | int ret; | 2943 | int ret; |
| 2944 | s64 time; | 2944 | s64 time; |
| 2945 | 2945 | ||
| 2946 | switch (suspend) { | ||
| 2947 | case NVKM_POWEROFF: | ||
| 2948 | default: | ||
| 2949 | action = "fini"; | ||
| 2950 | break; | ||
| 2951 | case NVKM_SUSPEND: | ||
| 2952 | action = "suspend"; | ||
| 2953 | break; | ||
| 2954 | case NVKM_RUNTIME_SUSPEND: | ||
| 2955 | action = "runtime"; | ||
| 2956 | break; | ||
| 2957 | } | ||
| 2946 | nvdev_trace(device, "%s running...\n", action); | 2958 | nvdev_trace(device, "%s running...\n", action); |
| 2947 | time = ktime_to_us(ktime_get()); | 2959 | time = ktime_to_us(ktime_get()); |
| 2948 | 2960 | ||
| @@ -3032,7 +3044,7 @@ nvkm_device_init(struct nvkm_device *device) · 83 unmodified lines | |||
| 3032 | if (ret) | 3044 | if (ret) |
| 3033 | return ret; | 3045 | return ret; |
| 3034 | 3046 | ||
| 3035 | nvkm_device_fini(device, false); | 3047 | nvkm_device_fini(device, NVKM_POWEROFF); |
| 3036 | 3048 | ||
| 3037 | nvdev_trace(device, "init running...\n"); | 3049 | nvdev_trace(device, "init running...\n"); |
| 3038 | time = ktime_to_us(ktime_get()); | 3050 | time = ktime_to_us(ktime_get()); |
| @@ -3060,9 +3072,9 @@ nvkm_device_init(struct nvkm_device *device) · 21 unmodified lines | |||
| 3060 | 3072 | ||
| 3061 | fail_subdev: | 3073 | fail_subdev: |
| 3062 | list_for_each_entry_from(subdev, &device->subdev, head) | 3074 | list_for_each_entry_from(subdev, &device->subdev, head) |
| 3063 | nvkm_subdev_fini(subdev, false); | 3075 | nvkm_subdev_fini(subdev, NVKM_POWEROFF); |
| 3064 | fail: | 3076 | fail: |
| 3065 | nvkm_device_fini(device, false); | 3077 | nvkm_device_fini(device, NVKM_POWEROFF); |
| 3066 | 3078 | ||
| 3067 | nvdev_error(device, "init failed with %d\n", ret); | 3079 | nvdev_error(device, "init failed with %d\n", ret); |
| 3068 | return ret; | 3080 | return ret; |
| @@ -1605,10 +1605,10 @@ nvkm_device_pci_irq(struct nvkm_device *device) · 1604 unmodified lines | |||
| 1605 | } | 1605 | } |
| 1606 | 1606 | ||
| 1607 | static void | 1607 | static void |
| 1608 | nvkm_device_pci_fini(struct nvkm_device *device, bool suspend) | 1608 | nvkm_device_pci_fini(struct nvkm_device *device, enum nvkm_suspend_state suspend) |
| 1609 | { | 1609 | { |
| 1610 | struct nvkm_device_pci *pdev = nvkm_device_pci(device); | 1610 | struct nvkm_device_pci *pdev = nvkm_device_pci(device); |
| 1611 | if (suspend) { | 1611 | if (suspend != NVKM_POWEROFF) { |
| 1612 | pci_disable_device(pdev->pdev); | 1612 | pci_disable_device(pdev->pdev); |
| 1613 | pdev->suspend = true; | 1613 | pdev->suspend = true; |
| 1614 | } | 1614 | } |
| @@ -56,5 +56,5 @@ int nvkm_device_ctor(const struct nvkm_device_func *, · 55 unmodified lines | |||
| 56 | const char *name, const char *cfg, const char *dbg, | 56 | const char *name, const char *cfg, const char *dbg, |
| 57 | struct nvkm_device *); | 57 | struct nvkm_device *); |
| 58 | int nvkm_device_init(struct nvkm_device *); | 58 | int nvkm_device_init(struct nvkm_device *); |
| 59 | int nvkm_device_fini(struct nvkm_device *, bool suspend); | 59 | int nvkm_device_fini(struct nvkm_device *, enum nvkm_suspend_state suspend); |
| 60 | #endif | 60 | #endif |
| @@ -218,7 +218,7 @@ nvkm_udevice_map(struct nvkm_object *object, void *argv, u32 argc, · 217 unmodified lines | |||
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | static int | 220 | static int |
| 221 | nvkm_udevice_fini(struct nvkm_object *object, bool suspend) | 221 | nvkm_udevice_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 222 | { | 222 | { |
| 223 | struct nvkm_udevice *udev = nvkm_udevice(object); | 223 | struct nvkm_udevice *udev = nvkm_udevice(object); |
| 224 | struct nvkm_device *device = udev->device; | 224 | struct nvkm_device *device = udev->device; |
| @@ -99,13 +99,13 @@ nvkm_disp_intr(struct nvkm_engine *engine) · 98 unmodified lines | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static int | 101 | static int |
| 102 | nvkm_disp_fini(struct nvkm_engine *engine, bool suspend) | 102 | nvkm_disp_fini(struct nvkm_engine *engine, enum nvkm_suspend_state suspend) |
| 103 | { | 103 | { |
| 104 | struct nvkm_disp *disp = nvkm_disp(engine); | 104 | struct nvkm_disp *disp = nvkm_disp(engine); |
| 105 | struct nvkm_outp *outp; | 105 | struct nvkm_outp *outp; |
| 106 | 106 | ||
| 107 | if (disp->func->fini) | 107 | if (disp->func->fini) |
| 108 | disp->func->fini(disp, suspend); | 108 | disp->func->fini(disp, suspend != NVKM_POWEROFF); |
| 109 | 109 | ||
| 110 | list_for_each_entry(outp, &disp->outps, head) { | 110 | list_for_each_entry(outp, &disp->outps, head) { |
| 111 | if (outp->func->fini) | 111 | if (outp->func->fini) |
| @@ -128,7 +128,7 @@ nvkm_disp_chan_child_get(struct nvkm_object *object, int index, struct nvkm_ocla · 127 unmodified lines | |||
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | static int | 130 | static int |
| 131 | nvkm_disp_chan_fini(struct nvkm_object *object, bool suspend) | 131 | nvkm_disp_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 132 | { | 132 | { |
| 133 | struct nvkm_disp_chan *chan = nvkm_disp_chan(object); | 133 | struct nvkm_disp_chan *chan = nvkm_disp_chan(object); |
| 134 | 134 | ||
| @@ -93,13 +93,13 @@ nvkm_falcon_intr(struct nvkm_engine *engine) · 92 unmodified lines | |||
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static int | 95 | static int |
| 96 | nvkm_falcon_fini(struct nvkm_engine *engine, bool suspend) | 96 | nvkm_falcon_fini(struct nvkm_engine *engine, enum nvkm_suspend_state suspend) |
| 97 | { | 97 | { |
| 98 | struct nvkm_falcon *falcon = nvkm_falcon(engine); | 98 | struct nvkm_falcon *falcon = nvkm_falcon(engine); |
| 99 | struct nvkm_device *device = falcon->engine.subdev.device; | 99 | struct nvkm_device *device = falcon->engine.subdev.device; |
| 100 | const u32 base = falcon->addr; | 100 | const u32 base = falcon->addr; |
| 101 | 101 | ||
| 102 | if (!suspend) { | 102 | if (suspend == NVKM_POWEROFF) { |
| 103 | nvkm_memory_unref(&falcon->core); | 103 | nvkm_memory_unref(&falcon->core); |
| 104 | if (falcon->external) { | 104 | if (falcon->external) { |
| 105 | vfree(falcon->data.data); | 105 | vfree(falcon->data.data); |
| @@ -122,7 +122,7 @@ nvkm_fifo_class_get(struct nvkm_oclass *oclass, int index, const struct nvkm_dev · 121 unmodified lines | |||
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static int | 124 | static int |
| 125 | nvkm_fifo_fini(struct nvkm_engine *engine, bool suspend) | 125 | nvkm_fifo_fini(struct nvkm_engine *engine, enum nvkm_suspend_state suspend) |
| 126 | { | 126 | { |
| 127 | struct nvkm_fifo *fifo = nvkm_fifo(engine); | 127 | struct nvkm_fifo *fifo = nvkm_fifo(engine); |
| 128 | struct nvkm_runl *runl; | 128 | struct nvkm_runl *runl; |
| @@ -72,7 +72,7 @@ struct nvkm_uobj { · 71 unmodified lines | |||
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | static int | 74 | static int |
| 75 | nvkm_uchan_object_fini_1(struct nvkm_oproxy *oproxy, bool suspend) | 75 | nvkm_uchan_object_fini_1(struct nvkm_oproxy *oproxy, enum nvkm_suspend_state suspend) |
| 76 | { | 76 | { |
| 77 | struct nvkm_uobj *uobj = container_of(oproxy, typeof(*uobj), oproxy); | 77 | struct nvkm_uobj *uobj = container_of(oproxy, typeof(*uobj), oproxy); |
| 78 | struct nvkm_chan *chan = uobj->chan; | 78 | struct nvkm_chan *chan = uobj->chan; |
| @@ -87,7 +87,7 @@ nvkm_uchan_object_fini_1(struct nvkm_oproxy *oproxy, bool suspend) · 8 unmodified lines | |||
| 87 | nvkm_chan_cctx_bind(chan, ectx->engn, NULL); | 87 | nvkm_chan_cctx_bind(chan, ectx->engn, NULL); |
| 88 | 88 | ||
| 89 | if (refcount_dec_and_test(&ectx->uses)) | 89 | if (refcount_dec_and_test(&ectx->uses)) |
| 90 | nvkm_object_fini(ectx->object, false); | 90 | nvkm_object_fini(ectx->object, NVKM_POWEROFF); |
| 91 | mutex_unlock(&chan->cgrp->mutex); | 91 | mutex_unlock(&chan->cgrp->mutex); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| @@ -269,7 +269,7 @@ nvkm_uchan_map(struct nvkm_object *object, void *argv, u32 argc, · 175 unmodified lines | |||
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | static int | 271 | static int |
| 272 | nvkm_uchan_fini(struct nvkm_object *object, bool suspend) | 272 | nvkm_uchan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 273 | { | 273 | { |
| 274 | struct nvkm_chan *chan = nvkm_uchan(object)->chan; | 274 | struct nvkm_chan *chan = nvkm_uchan(object)->chan; |
| 275 | 275 | ||
| @@ -168,11 +168,11 @@ nvkm_gr_init(struct nvkm_engine *engine) · 167 unmodified lines | |||
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static int | 170 | static int |
| 171 | nvkm_gr_fini(struct nvkm_engine *engine, bool suspend) | 171 | nvkm_gr_fini(struct nvkm_engine *engine, enum nvkm_suspend_state suspend) |
| 172 | { | 172 | { |
| 173 | struct nvkm_gr *gr = nvkm_gr(engine); | 173 | struct nvkm_gr *gr = nvkm_gr(engine); |
| 174 | if (gr->func->fini) | 174 | if (gr->func->fini) |
| 175 | return gr->func->fini(gr, suspend); | 175 | return gr->func->fini(gr, suspend != NVKM_POWEROFF); |
| 176 | return 0; | 176 | return 0; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| @@ -2330,7 +2330,7 @@ gf100_gr_reset(struct nvkm_gr *base) · 2329 unmodified lines | |||
| 2330 | 2330 | ||
| 2331 | WARN_ON(gf100_gr_fecs_halt_pipeline(gr)); | 2331 | WARN_ON(gf100_gr_fecs_halt_pipeline(gr)); |
| 2332 | 2332 | ||
| 2333 | subdev->func->fini(subdev, false); | 2333 | subdev->func->fini(subdev, NVKM_POWEROFF); |
| 2334 | nvkm_mc_disable(device, subdev->type, subdev->inst); | 2334 | nvkm_mc_disable(device, subdev->type, subdev->inst); |
| 2335 | if (gr->func->gpccs.reset) | 2335 | if (gr->func->gpccs.reset) |
| 2336 | gr->func->gpccs.reset(gr); | 2336 | gr->func->gpccs.reset(gr); |
| @@ -1158,7 +1158,7 @@ nv04_gr_chan_dtor(struct nvkm_object *object) · 1157 unmodified lines | |||
| 1158 | } | 1158 | } |
| 1159 | 1159 | ||
| 1160 | static int | 1160 | static int |
| 1161 | nv04_gr_chan_fini(struct nvkm_object *object, bool suspend) | 1161 | nv04_gr_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 1162 | { | 1162 | { |
| 1163 | struct nv04_gr_chan *chan = nv04_gr_chan(object); | 1163 | struct nv04_gr_chan *chan = nv04_gr_chan(object); |
| 1164 | struct nv04_gr *gr = chan->gr; | 1164 | struct nv04_gr *gr = chan->gr; |
| @@ -951,7 +951,7 @@ nv10_gr_context_switch(struct nv10_gr *gr) · 950 unmodified lines | |||
| 951 | } | 951 | } |
| 952 | 952 | ||
| 953 | static int | 953 | static int |
| 954 | nv10_gr_chan_fini(struct nvkm_object *object, bool suspend) | 954 | nv10_gr_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 955 | { | 955 | { |
| 956 | struct nv10_gr_chan *chan = nv10_gr_chan(object); | 956 | struct nv10_gr_chan *chan = nv10_gr_chan(object); |
| 957 | struct nv10_gr *gr = chan->gr; | 957 | struct nv10_gr *gr = chan->gr; |
| @@ -27,7 +27,7 @@ nv20_gr_chan_init(struct nvkm_object *object) · 26 unmodified lines | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | int | 29 | int |
| 30 | nv20_gr_chan_fini(struct nvkm_object *object, bool suspend) | 30 | nv20_gr_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 31 | { | 31 | { |
| 32 | struct nv20_gr_chan *chan = nv20_gr_chan(object); | 32 | struct nv20_gr_chan *chan = nv20_gr_chan(object); |
| 33 | struct nv20_gr *gr = chan->gr; | 33 | struct nv20_gr *gr = chan->gr; |
| @@ -31,5 +31,5 @@ struct nv20_gr_chan { · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | void *nv20_gr_chan_dtor(struct nvkm_object *); | 32 | void *nv20_gr_chan_dtor(struct nvkm_object *); |
| 33 | int nv20_gr_chan_init(struct nvkm_object *); | 33 | int nv20_gr_chan_init(struct nvkm_object *); |
| 34 | int nv20_gr_chan_fini(struct nvkm_object *, bool); | 34 | int nv20_gr_chan_fini(struct nvkm_object *, enum nvkm_suspend_state); |
| 35 | #endif | 35 | #endif |
| @@ -89,7 +89,7 @@ nv40_gr_chan_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent, · 88 unmodified lines | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static int | 91 | static int |
| 92 | nv40_gr_chan_fini(struct nvkm_object *object, bool suspend) | 92 | nv40_gr_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 93 | { | 93 | { |
| 94 | struct nv40_gr_chan *chan = nv40_gr_chan(object); | 94 | struct nv40_gr_chan *chan = nv40_gr_chan(object); |
| 95 | struct nv40_gr *gr = chan->gr; | 95 | struct nv40_gr *gr = chan->gr; |
| @@ -101,7 +101,7 @@ nv40_gr_chan_fini(struct nvkm_object *object, bool suspend) · 5 unmodified lines | |||
| 101 | nvkm_mask(device, 0x400720, 0x00000001, 0x00000000); | 101 | nvkm_mask(device, 0x400720, 0x00000001, 0x00000000); |
| 102 | 102 | ||
| 103 | if (nvkm_rd32(device, 0x40032c) == inst) { | 103 | if (nvkm_rd32(device, 0x40032c) == inst) { |
| 104 | if (suspend) { | 104 | if (suspend != NVKM_POWEROFF) { |
| 105 | nvkm_wr32(device, 0x400720, 0x00000000); | 105 | nvkm_wr32(device, 0x400720, 0x00000000); |
| 106 | nvkm_wr32(device, 0x400784, inst); | 106 | nvkm_wr32(device, 0x400784, inst); |
| 107 | nvkm_mask(device, 0x400310, 0x00000020, 0x00000020); | 107 | nvkm_mask(device, 0x400310, 0x00000020, 0x00000020); |
| @@ -65,7 +65,7 @@ nv44_mpeg_chan_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent, · 64 unmodified lines | |||
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static int | 67 | static int |
| 68 | nv44_mpeg_chan_fini(struct nvkm_object *object, bool suspend) | 68 | nv44_mpeg_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 69 | { | 69 | { |
| 70 | 70 | ||
| 71 | struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object); | 71 | struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object); |
| @@ -37,7 +37,7 @@ nvkm_sec2_finimsg(void *priv, struct nvfw_falcon_msg *hdr) · 36 unmodified lines | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static int | 39 | static int |
| 40 | nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend) | 40 | nvkm_sec2_fini(struct nvkm_engine *engine, enum nvkm_suspend_state suspend) |
| 41 | { | 41 | { |
| 42 | struct nvkm_sec2 *sec2 = nvkm_sec2(engine); | 42 | struct nvkm_sec2 *sec2 = nvkm_sec2(engine); |
| 43 | struct nvkm_subdev *subdev = &sec2->engine.subdev; | 43 | struct nvkm_subdev *subdev = &sec2->engine.subdev; |
| @@ -76,7 +76,7 @@ nvkm_xtensa_intr(struct nvkm_engine *engine) · 75 unmodified lines | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static int | 78 | static int |
| 79 | nvkm_xtensa_fini(struct nvkm_engine *engine, bool suspend) | 79 | nvkm_xtensa_fini(struct nvkm_engine *engine, enum nvkm_suspend_state suspend) |
| 80 | { | 80 | { |
| 81 | struct nvkm_xtensa *xtensa = nvkm_xtensa(engine); | 81 | struct nvkm_xtensa *xtensa = nvkm_xtensa(engine); |
| 82 | struct nvkm_device *device = xtensa->engine.subdev.device; | 82 | struct nvkm_device *device = xtensa->engine.subdev.device; |
| @@ -85,7 +85,7 @@ nvkm_xtensa_fini(struct nvkm_engine *engine, bool suspend) · 2 unmodified lines | |||
| 85 | nvkm_wr32(device, base + 0xd84, 0); /* INTR_EN */ | 85 | nvkm_wr32(device, base + 0xd84, 0); /* INTR_EN */ |
| 86 | nvkm_wr32(device, base + 0xd94, 0); /* FIFO_CTRL */ | 86 | nvkm_wr32(device, base + 0xd94, 0); /* FIFO_CTRL */ |
| 87 | 87 | ||
| 88 | if (!suspend) | 88 | if (suspend == NVKM_POWEROFF) |
| 89 | nvkm_memory_unref(&xtensa->gpu_fw); | 89 | nvkm_memory_unref(&xtensa->gpu_fw); |
| 90 | return 0; | 90 | return 0; |
| 91 | } | 91 | } |
| @@ -182,7 +182,7 @@ nvkm_acr_managed_falcon(struct nvkm_device *device, enum nvkm_acr_lsf_id id) · 181 unmodified lines | |||
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | static int | 184 | static int |
| 185 | nvkm_acr_fini(struct nvkm_subdev *subdev, bool suspend) | 185 | nvkm_acr_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 186 | { | 186 | { |
| 187 | if (!subdev->use.enabled) | 187 | if (!subdev->use.enabled) |
| 188 | return 0; | 188 | return 0; |
| @@ -90,7 +90,7 @@ nvkm_bar_bar2_init(struct nvkm_device *device) · 89 unmodified lines | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static int | 92 | static int |
| 93 | nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend) | 93 | nvkm_bar_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 94 | { | 94 | { |
| 95 | struct nvkm_bar *bar = nvkm_bar(subdev); | 95 | struct nvkm_bar *bar = nvkm_bar(subdev); |
| 96 | 96 | ||
| @@ -577,7 +577,7 @@ nvkm_clk_read(struct nvkm_clk *clk, enum nv_clk_src src) · 576 unmodified lines | |||
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | static int | 579 | static int |
| 580 | nvkm_clk_fini(struct nvkm_subdev *subdev, bool suspend) | 580 | nvkm_clk_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 581 | { | 581 | { |
| 582 | struct nvkm_clk *clk = nvkm_clk(subdev); | 582 | struct nvkm_clk *clk = nvkm_clk(subdev); |
| 583 | flush_work(&clk->work); | 583 | flush_work(&clk->work); |
| @@ -67,11 +67,11 @@ nvkm_devinit_post(struct nvkm_devinit *init) · 66 unmodified lines | |||
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | static int | 69 | static int |
| 70 | nvkm_devinit_fini(struct nvkm_subdev *subdev, bool suspend) | 70 | nvkm_devinit_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 71 | { | 71 | { |
| 72 | struct nvkm_devinit *init = nvkm_devinit(subdev); | 72 | struct nvkm_devinit *init = nvkm_devinit(subdev); |
| 73 | /* force full reinit on resume */ | 73 | /* force full reinit on resume */ |
| 74 | if (suspend) | 74 | if (suspend != NVKM_POWEROFF) |
| 75 | init->post = true; | 75 | init->post = true; |
| 76 | return 0; | 76 | return 0; |
| 77 | } | 77 | } |
| @@ -51,7 +51,7 @@ nvkm_fault_intr(struct nvkm_subdev *subdev) · 50 unmodified lines | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | static int | 53 | static int |
| 54 | nvkm_fault_fini(struct nvkm_subdev *subdev, bool suspend) | 54 | nvkm_fault_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 55 | { | 55 | { |
| 56 | struct nvkm_fault *fault = nvkm_fault(subdev); | 56 | struct nvkm_fault *fault = nvkm_fault(subdev); |
| 57 | if (fault->func->fini) | 57 | if (fault->func->fini) |
| @@ -56,7 +56,7 @@ nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc, · 55 unmodified lines | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static int | 58 | static int |
| 59 | nvkm_ufault_fini(struct nvkm_object *object, bool suspend) | 59 | nvkm_ufault_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend) |
| 60 | { | 60 | { |
| 61 | struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); | 61 | struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); |
| 62 | buffer->fault->func->buffer.fini(buffer); | 62 | buffer->fault->func->buffer.fini(buffer); |
| @@ -144,7 +144,7 @@ nvkm_gpio_intr(struct nvkm_subdev *subdev) · 143 unmodified lines | |||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static int | 146 | static int |
| 147 | nvkm_gpio_fini(struct nvkm_subdev *subdev, bool suspend) | 147 | nvkm_gpio_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 148 | { | 148 | { |
| 149 | struct nvkm_gpio *gpio = nvkm_gpio(subdev); | 149 | struct nvkm_gpio *gpio = nvkm_gpio(subdev); |
| 150 | u32 mask = (1ULL << gpio->func->lines) - 1; | 150 | u32 mask = (1ULL << gpio->func->lines) - 1; |
| @@ -48,7 +48,7 @@ nvkm_gsp_intr_stall(struct nvkm_gsp *gsp, enum nvkm_subdev_type type, int inst) · 47 unmodified lines | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static int | 50 | static int |
| 51 | nvkm_gsp_fini(struct nvkm_subdev *subdev, bool suspend) | 51 | nvkm_gsp_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 52 | { | 52 | { |
| 53 | struct nvkm_gsp *gsp = nvkm_gsp(subdev); | 53 | struct nvkm_gsp *gsp = nvkm_gsp(subdev); |
| 54 | 54 | ||
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <nvhw/ref/gh100/dev_riscv_pri.h> | 17 | #include <nvhw/ref/gh100/dev_riscv_pri.h> |
| 18 | 18 | ||
| 19 | int | 19 | int |
| 20 | gh100_gsp_fini(struct nvkm_gsp *gsp, bool suspend) | 20 | gh100_gsp_fini(struct nvkm_gsp *gsp, enum nvkm_suspend_state suspend) |
| 21 | { | 21 | { |
| 22 | struct nvkm_falcon *falcon = &gsp->falcon; | 22 | struct nvkm_falcon *falcon = &gsp->falcon; |
| 23 | int ret, time = 4000; | 23 | int ret, time = 4000; |
| @@ -59,7 +59,7 @@ struct nvkm_gsp_func { · 58 unmodified lines | |||
| 59 | void (*dtor)(struct nvkm_gsp *); | 59 | void (*dtor)(struct nvkm_gsp *); |
| 60 | int (*oneinit)(struct nvkm_gsp *); | 60 | int (*oneinit)(struct nvkm_gsp *); |
| 61 | int (*init)(struct nvkm_gsp *); | 61 | int (*init)(struct nvkm_gsp *); |
| 62 | int (*fini)(struct nvkm_gsp *, bool suspend); | 62 | int (*fini)(struct nvkm_gsp *, enum nvkm_suspend_state suspend); |
| 63 | int (*reset)(struct nvkm_gsp *); | 63 | int (*reset)(struct nvkm_gsp *); |
| 64 | 64 | ||
| 65 | struct { | 65 | struct { |
| @@ -75,7 +75,7 @@ int tu102_gsp_fwsec_sb_ctor(struct nvkm_gsp *); · 9 unmodified lines | |||
| 75 | void tu102_gsp_fwsec_sb_dtor(struct nvkm_gsp *); | 75 | void tu102_gsp_fwsec_sb_dtor(struct nvkm_gsp *); |
| 76 | int tu102_gsp_oneinit(struct nvkm_gsp *); | 76 | int tu102_gsp_oneinit(struct nvkm_gsp *); |
| 77 | int tu102_gsp_init(struct nvkm_gsp *); | 77 | int tu102_gsp_init(struct nvkm_gsp *); |
| 78 | int tu102_gsp_fini(struct nvkm_gsp *, bool suspend); | 78 | int tu102_gsp_fini(struct nvkm_gsp *, enum nvkm_suspend_state suspend); |
| 79 | int tu102_gsp_reset(struct nvkm_gsp *); | 79 | int tu102_gsp_reset(struct nvkm_gsp *); |
| 80 | u64 tu102_gsp_wpr_heap_size(struct nvkm_gsp *); | 80 | u64 tu102_gsp_wpr_heap_size(struct nvkm_gsp *); |
| 81 | 81 | ||
| @@ -87,12 +87,12 @@ int ga102_gsp_reset(struct nvkm_gsp *); · 5 unmodified lines | |||
| 87 | 87 | ||
| 88 | int gh100_gsp_oneinit(struct nvkm_gsp *); | 88 | int gh100_gsp_oneinit(struct nvkm_gsp *); |
| 89 | int gh100_gsp_init(struct nvkm_gsp *); | 89 | int gh100_gsp_init(struct nvkm_gsp *); |
| 90 | int gh100_gsp_fini(struct nvkm_gsp *, bool suspend); | 90 | int gh100_gsp_fini(struct nvkm_gsp *, enum nvkm_suspend_state suspend); |
| 91 | 91 | ||
| 92 | void r535_gsp_dtor(struct nvkm_gsp *); | 92 | void r535_gsp_dtor(struct nvkm_gsp *); |
| 93 | int r535_gsp_oneinit(struct nvkm_gsp *); | 93 | int r535_gsp_oneinit(struct nvkm_gsp *); |
| 94 | int r535_gsp_init(struct nvkm_gsp *); | 94 | int r535_gsp_init(struct nvkm_gsp *); |
| 95 | int r535_gsp_fini(struct nvkm_gsp *, bool suspend); | 95 | int r535_gsp_fini(struct nvkm_gsp *, enum nvkm_suspend_state suspend); |
| 96 | 96 | ||
| 97 | int nvkm_gsp_new_(const struct nvkm_gsp_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, | 97 | int nvkm_gsp_new_(const struct nvkm_gsp_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, |
| 98 | struct nvkm_gsp **); | 98 | struct nvkm_gsp **); |
| @@ -208,7 +208,7 @@ r535_fbsr_resume(struct nvkm_gsp *gsp) · 207 unmodified lines | |||
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static int | 210 | static int |
| 211 | r535_fbsr_suspend(struct nvkm_gsp *gsp) | 211 | r535_fbsr_suspend(struct nvkm_gsp *gsp, bool runtime) |
| 212 | { | 212 | { |
| 213 | struct nvkm_subdev *subdev = &gsp->subdev; | 213 | struct nvkm_subdev *subdev = &gsp->subdev; |
| 214 | struct nvkm_device *device = subdev->device; | 214 | struct nvkm_device *device = subdev->device; |
| @@ -704,7 +704,7 @@ r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp) · 703 unmodified lines | |||
| 704 | 704 | ||
| 705 | build_registry(gsp, rpc); | 705 | build_registry(gsp, rpc); |
| 706 | 706 | ||
| 707 | return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_NOWAIT); | 707 | return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_NOSEQ); |
| 708 | 708 | ||
| 709 | fail: | 709 | fail: |
| 710 | clean_registry(gsp); | 710 | clean_registry(gsp); |
| @@ -921,7 +921,7 @@ r535_gsp_set_system_info(struct nvkm_gsp *gsp) · 210 unmodified lines | |||
| 921 | info->pciConfigMirrorSize = device->pci->func->cfg.size; | 921 | info->pciConfigMirrorSize = device->pci->func->cfg.size; |
| 922 | r535_gsp_acpi_info(gsp, &info->acpiMethodData); | 922 | r535_gsp_acpi_info(gsp, &info->acpiMethodData); |
| 923 | 923 | ||
| 924 | return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOWAIT); | 924 | return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOSEQ); |
| 925 | } | 925 | } |
| 926 | 926 | ||
| 927 | static int | 927 | static int |
| @@ -1721,7 +1721,7 @@ r535_gsp_sr_data_size(struct nvkm_gsp *gsp) · 793 unmodified lines | |||
| 1721 | } | 1721 | } |
| 1722 | 1722 | ||
| 1723 | int | 1723 | int |
| 1724 | r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) | 1724 | r535_gsp_fini(struct nvkm_gsp *gsp, enum nvkm_suspend_state suspend) |
| 1725 | { | 1725 | { |
| 1726 | struct nvkm_rm *rm = gsp->rm; | 1726 | struct nvkm_rm *rm = gsp->rm; |
| 1727 | int ret; | 1727 | int ret; |
| @@ -1748,7 +1748,7 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) · 20 unmodified lines | |||
| 1748 | sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr; | 1748 | sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr; |
| 1749 | sr->sizeOfSuspendResumeData = len; | 1749 | sr->sizeOfSuspendResumeData = len; |
| 1750 | 1750 | ||
| 1751 | ret = rm->api->fbsr->suspend(gsp); | 1751 | ret = rm->api->fbsr->suspend(gsp, suspend == NVKM_RUNTIME_SUSPEND); |
| 1752 | if (ret) { | 1752 | if (ret) { |
| 1753 | nvkm_gsp_mem_dtor(&gsp->sr.meta); | 1753 | nvkm_gsp_mem_dtor(&gsp->sr.meta); |
| 1754 | nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3); | 1754 | nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3); |
| @@ -557,6 +557,7 @@ r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn, · 556 unmodified lines | |||
| 557 | 557 | ||
| 558 | switch (policy) { | 558 | switch (policy) { |
| 559 | case NVKM_GSP_RPC_REPLY_NOWAIT: | 559 | case NVKM_GSP_RPC_REPLY_NOWAIT: |
| 560 | case NVKM_GSP_RPC_REPLY_NOSEQ: | ||
| 560 | break; | 561 | break; |
| 561 | case NVKM_GSP_RPC_REPLY_RECV: | 562 | case NVKM_GSP_RPC_REPLY_RECV: |
| 562 | reply = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); | 563 | reply = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); |
| @@ -588,6 +589,11 @@ r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload, · 25 unmodified lines | |||
| 588 | rpc->data, rpc->length - sizeof(*rpc), true); | 589 | rpc->data, rpc->length - sizeof(*rpc), true); |
| 589 | } | 590 | } |
| 590 | 591 | ||
| 592 | if (policy == NVKM_GSP_RPC_REPLY_NOSEQ) | ||
| 593 | rpc->sequence = 0; | ||
| 594 | else | ||
| 595 | rpc->sequence = gsp->rpc_seq++; | ||
| 596 | |||
| 591 | ret = r535_gsp_cmdq_push(gsp, rpc); | 597 | ret = r535_gsp_cmdq_push(gsp, rpc); |
| 592 | if (ret) | 598 | if (ret) |
| 593 | return ERR_PTR(ret); | 599 | return ERR_PTR(ret); |
| @@ -62,7 +62,7 @@ r570_fbsr_resume(struct nvkm_gsp *gsp) · 61 unmodified lines | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static int | 64 | static int |
| 65 | r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size) | 65 | r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, bool runtime) |
| 66 | { | 66 | { |
| 67 | NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS *ctrl; | 67 | NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS *ctrl; |
| 68 | struct nvkm_gsp_object memlist; | 68 | struct nvkm_gsp_object memlist; |
| @@ -81,7 +81,7 @@ r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size) · 12 unmodified lines | |||
| 81 | ctrl->hClient = gsp->internal.client.object.handle; | 81 | ctrl->hClient = gsp->internal.client.object.handle; |
| 82 | ctrl->hSysMem = memlist.handle; | 82 | ctrl->hSysMem = memlist.handle; |
| 83 | ctrl->sysmemAddrOfSuspendResumeData = gsp->sr.meta.addr; | 83 | ctrl->sysmemAddrOfSuspendResumeData = gsp->sr.meta.addr; |
| 84 | ctrl->bEnteringGcoffState = 1; | 84 | ctrl->bEnteringGcoffState = runtime ? 1 : 0; |
| 85 | 85 | ||
| 86 | ret = nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); | 86 | ret = nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); |
| 87 | if (ret) | 87 | if (ret) |
| @@ -92,7 +92,7 @@ r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size) · 4 unmodified lines | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static int | 94 | static int |
| 95 | r570_fbsr_suspend(struct nvkm_gsp *gsp) | 95 | r570_fbsr_suspend(struct nvkm_gsp *gsp, bool runtime) |
| 96 | { | 96 | { |
| 97 | struct nvkm_subdev *subdev = &gsp->subdev; | 97 | struct nvkm_subdev *subdev = &gsp->subdev; |
| 98 | struct nvkm_device *device = subdev->device; | 98 | struct nvkm_device *device = subdev->device; |
| @@ -133,7 +133,7 @@ r570_fbsr_suspend(struct nvkm_gsp *gsp) · 34 unmodified lines | |||
| 133 | return ret; | 133 | return ret; |
| 134 | 134 | ||
| 135 | /* Initialise FBSR on RM. */ | 135 | /* Initialise FBSR on RM. */ |
| 136 | ret = r570_fbsr_init(gsp, &gsp->sr.fbsr, size); | 136 | ret = r570_fbsr_init(gsp, &gsp->sr.fbsr, size, runtime); |
| 137 | if (ret) { | 137 | if (ret) { |
| 138 | nvkm_gsp_sg_free(device, &gsp->sr.fbsr); | 138 | nvkm_gsp_sg_free(device, &gsp->sr.fbsr); |
| 139 | return ret; | 139 | return ret; |
| @@ -176,7 +176,7 @@ r570_gsp_set_system_info(struct nvkm_gsp *gsp) · 175 unmodified lines | |||
| 176 | info->bIsPrimary = video_is_primary_device(device->dev); | 176 | info->bIsPrimary = video_is_primary_device(device->dev); |
| 177 | info->bPreserveVideoMemoryAllocations = false; | 177 | info->bPreserveVideoMemoryAllocations = false; |
| 178 | 178 | ||
| 179 | return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOWAIT); | 179 | return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOSEQ); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | static void | 182 | static void |
| @@ -78,7 +78,7 @@ struct nvkm_rm_api { · 77 unmodified lines | |||
| 78 | } *device; | 78 | } *device; |
| 79 | 79 | ||
| 80 | const struct nvkm_rm_api_fbsr { | 80 | const struct nvkm_rm_api_fbsr { |
| 81 | int (*suspend)(struct nvkm_gsp *); | 81 | int (*suspend)(struct nvkm_gsp *, bool runtime); |
| 82 | void (*resume)(struct nvkm_gsp *); | 82 | void (*resume)(struct nvkm_gsp *); |
| 83 | } *fbsr; | 83 | } *fbsr; |
| 84 | 84 | ||
| @@ -161,7 +161,7 @@ tu102_gsp_reset(struct nvkm_gsp *gsp) · 160 unmodified lines | |||
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | int | 163 | int |
| 164 | tu102_gsp_fini(struct nvkm_gsp *gsp, bool suspend) | 164 | tu102_gsp_fini(struct nvkm_gsp *gsp, enum nvkm_suspend_state suspend) |
| 165 | { | 165 | { |
| 166 | u32 mbox0 = 0xff, mbox1 = 0xff; | 166 | u32 mbox0 = 0xff, mbox1 = 0xff; |
| 167 | int ret; | 167 | int ret; |
| @@ -135,7 +135,7 @@ nvkm_i2c_intr(struct nvkm_subdev *subdev) · 134 unmodified lines | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static int | 137 | static int |
| 138 | nvkm_i2c_fini(struct nvkm_subdev *subdev, bool suspend) | 138 | nvkm_i2c_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 139 | { | 139 | { |
| 140 | struct nvkm_i2c *i2c = nvkm_i2c(subdev); | 140 | struct nvkm_i2c *i2c = nvkm_i2c(subdev); |
| 141 | struct nvkm_i2c_pad *pad; | 141 | struct nvkm_i2c_pad *pad; |
| @@ -176,7 +176,7 @@ nvkm_instmem_boot(struct nvkm_instmem *imem) · 175 unmodified lines | |||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static int | 178 | static int |
| 179 | nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) | 179 | nvkm_instmem_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 180 | { | 180 | { |
| 181 | struct nvkm_instmem *imem = nvkm_instmem(subdev); | 181 | struct nvkm_instmem *imem = nvkm_instmem(subdev); |
| 182 | int ret; | 182 | int ret; |
| @@ -74,7 +74,7 @@ nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow) · 73 unmodified lines | |||
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static int | 76 | static int |
| 77 | nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend) | 77 | nvkm_pci_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 78 | { | 78 | { |
| 79 | struct nvkm_pci *pci = nvkm_pci(subdev); | 79 | struct nvkm_pci *pci = nvkm_pci(subdev); |
| 80 | 80 | ||
| @@ -77,7 +77,7 @@ nvkm_pmu_intr(struct nvkm_subdev *subdev) · 76 unmodified lines | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static int | 79 | static int |
| 80 | nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend) | 80 | nvkm_pmu_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 81 | { | 81 | { |
| 82 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); | 82 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); |
| 83 | 83 | ||
| @@ -341,15 +341,15 @@ nvkm_therm_intr(struct nvkm_subdev *subdev) · 340 unmodified lines | |||
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | static int | 343 | static int |
| 344 | nvkm_therm_fini(struct nvkm_subdev *subdev, bool suspend) | 344 | nvkm_therm_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 345 | { | 345 | { |
| 346 | struct nvkm_therm *therm = nvkm_therm(subdev); | 346 | struct nvkm_therm *therm = nvkm_therm(subdev); |
| 347 | 347 | ||
| 348 | if (therm->func->fini) | 348 | if (therm->func->fini) |
| 349 | therm->func->fini(therm); | 349 | therm->func->fini(therm); |
| 350 | 350 | ||
| 351 | nvkm_therm_fan_fini(therm, suspend); | 351 | nvkm_therm_fan_fini(therm, suspend != NVKM_POWEROFF); |
| 352 | nvkm_therm_sensor_fini(therm, suspend); | 352 | nvkm_therm_sensor_fini(therm, suspend != NVKM_POWEROFF); |
| 353 | 353 | ||
| 354 | if (suspend) { | 354 | if (suspend) { |
| 355 | therm->suspend = therm->mode; | 355 | therm->suspend = therm->mode; |
| @@ -149,7 +149,7 @@ nvkm_timer_intr(struct nvkm_subdev *subdev) · 148 unmodified lines | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | static int | 151 | static int |
| 152 | nvkm_timer_fini(struct nvkm_subdev *subdev, bool suspend) | 152 | nvkm_timer_fini(struct nvkm_subdev *subdev, enum nvkm_suspend_state suspend) |
| 153 | { | 153 | { |
| 154 | struct nvkm_timer *tmr = nvkm_timer(subdev); | 154 | struct nvkm_timer *tmr = nvkm_timer(subdev); |
| 155 | tmr->func->alarm_fini(tmr); | 155 | tmr->func->alarm_fini(tmr); |