lkml.org 
[lkml]   [2022]   [Jan]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.16 017/217] drm/nouveau/pmu/gm200-: avoid touching PMU outside of DEVINIT/PREOS/ACR
    Date
    From: Ben Skeggs <bskeggs@redhat.com>

    [ Upstream commit 1d2271d2fb85e54bfc9630a6c30ac0feb9ffb983 ]

    There have been reports of the WFI timing out on some boards, and a
    patch was proposed to just remove it. This stuff is rather fragile,
    and I believe the WFI might be needed with our FW prior to GM200.

    However, we probably should not be touching PMU during init on GPUs
    where we depend on NVIDIA FW, outside of limited circumstances, so
    this should be a somewhat safer change that achieves the desired
    result.

    Reported-by: Diego Viola <diego.viola@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
    Reviewed-by: Karol Herbst <kherbst@redhat.com>
    Signed-off-by: Karol Herbst <kherbst@redhat.com>
    Link: https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests/10
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    .../gpu/drm/nouveau/nvkm/subdev/pmu/base.c | 37 +++++++++++--------
    1 file changed, 21 insertions(+), 16 deletions(-)

    diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
    index 24382875fb4f3..455e95a89259f 100644
    --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
    +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
    @@ -94,20 +94,13 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
    return 0;
    }

    -static int
    +static void
    nvkm_pmu_reset(struct nvkm_pmu *pmu)
    {
    struct nvkm_device *device = pmu->subdev.device;

    if (!pmu->func->enabled(pmu))
    - return 0;
    -
    - /* Inhibit interrupts, and wait for idle. */
    - nvkm_wr32(device, 0x10a014, 0x0000ffff);
    - nvkm_msec(device, 2000,
    - if (!nvkm_rd32(device, 0x10a04c))
    - break;
    - );
    + return;

    /* Reset. */
    if (pmu->func->reset)
    @@ -118,25 +111,37 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu)
    if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006))
    break;
    );
    -
    - return 0;
    }

    static int
    nvkm_pmu_preinit(struct nvkm_subdev *subdev)
    {
    struct nvkm_pmu *pmu = nvkm_pmu(subdev);
    - return nvkm_pmu_reset(pmu);
    + nvkm_pmu_reset(pmu);
    + return 0;
    }

    static int
    nvkm_pmu_init(struct nvkm_subdev *subdev)
    {
    struct nvkm_pmu *pmu = nvkm_pmu(subdev);
    - int ret = nvkm_pmu_reset(pmu);
    - if (ret == 0 && pmu->func->init)
    - ret = pmu->func->init(pmu);
    - return ret;
    + struct nvkm_device *device = pmu->subdev.device;
    +
    + if (!pmu->func->init)
    + return 0;
    +
    + if (pmu->func->enabled(pmu)) {
    + /* Inhibit interrupts, and wait for idle. */
    + nvkm_wr32(device, 0x10a014, 0x0000ffff);
    + nvkm_msec(device, 2000,
    + if (!nvkm_rd32(device, 0x10a04c))
    + break;
    + );
    +
    + nvkm_pmu_reset(pmu);
    + }
    +
    + return pmu->func->init(pmu);
    }

    static void *
    --
    2.34.1
    \
     
     \ /
      Last update: 2022-01-18 03:21    [W:4.093 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site