[PATCH 2/2] drm/amdgpu: make VCN DPG pause mode detached from general VCN

Alex Deucher alexdeucher at gmail.com
Mon May 13 17:24:33 UTC 2019


On Mon, May 13, 2019 at 1:19 PM Liu, Leo <Leo.Liu at amd.com> wrote:
>
> It should be attached to VCN 1.0
>
> Signed-off-by: Leo Liu <leo.liu at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 130 +----------------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h |   2 +
>  drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c   | 132 +++++++++++++++++++++++-
>  3 files changed, 135 insertions(+), 129 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> index ecf6f96df2ad..01545ff87424 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> @@ -212,132 +212,6 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
>         return 0;
>  }
>
> -static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev,
> -                                    struct dpg_pause_state *new_state)
> -{
> -       int ret_code;
> -       uint32_t reg_data = 0;
> -       uint32_t reg_data2 = 0;
> -       struct amdgpu_ring *ring;
> -
> -       /* pause/unpause if state is changed */
> -       if (adev->vcn.pause_state.fw_based != new_state->fw_based) {
> -               DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
> -                       adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
> -                       new_state->fw_based, new_state->jpeg);
> -
> -               reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
> -                       (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
> -
> -               if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
> -                       ret_code = 0;
> -
> -                       if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK))
> -                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> -                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
> -                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> -
> -                       if (!ret_code) {
> -                               /* pause DPG non-jpeg */
> -                               reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
> -                               WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> -                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
> -                                                  UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
> -                                                  UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code);
> -
> -                               /* Restore */
> -                               ring = &adev->vcn.ring_enc[0];
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
> -
> -                               ring = &adev->vcn.ring_enc[1];
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
> -                               WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
> -
> -                               ring = &adev->vcn.ring_dec;
> -                               WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
> -                                                  RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);
> -                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> -                                                  UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
> -                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> -                       }
> -               } else {
> -                       /* unpause dpg non-jpeg, no need to wait */
> -                       reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
> -                       WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> -               }
> -               adev->vcn.pause_state.fw_based = new_state->fw_based;
> -       }
> -
> -       /* pause/unpause if state is changed */
> -       if (adev->vcn.pause_state.jpeg != new_state->jpeg) {
> -               DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
> -                       adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
> -                       new_state->fw_based, new_state->jpeg);
> -
> -               reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
> -                       (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);
> -
> -               if (new_state->jpeg == VCN_DPG_STATE__PAUSE) {
> -                       ret_code = 0;
> -
> -                       if (!(reg_data & UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK))
> -                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> -                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
> -                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> -
> -                       if (!ret_code) {
> -                               /* Make sure JPRG Snoop is disabled before sending the pause */
> -                               reg_data2 = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
> -                               reg_data2 |= UVD_POWER_STATUS__JRBC_SNOOP_DIS_MASK;
> -                               WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data2);
> -
> -                               /* pause DPG jpeg */
> -                               reg_data |= UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
> -                               WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> -                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
> -                                                       UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK,
> -                                                       UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK, ret_code);
> -
> -                               /* Restore */
> -                               ring = &adev->vcn.ring_jpeg;
> -                               WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
> -                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
> -                                                       UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
> -                                                       UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
> -                               WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
> -                                                       lower_32_bits(ring->gpu_addr));
> -                               WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
> -                                                       upper_32_bits(ring->gpu_addr));
> -                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, ring->wptr);
> -                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, ring->wptr);
> -                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
> -                                                       UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
> -
> -                               ring = &adev->vcn.ring_dec;
> -                               WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
> -                                                  RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);
> -                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> -                                                  UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
> -                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> -                       }
> -               } else {
> -                       /* unpause dpg jpeg, no need to wait */
> -                       reg_data &= ~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
> -                       WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> -               }
> -               adev->vcn.pause_state.jpeg = new_state->jpeg;
> -       }
> -
> -       return 0;
> -}
> -
>  static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
>  {
>         struct amdgpu_device *adev =
> @@ -362,7 +236,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
>                 else
>                         new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
>
> -               amdgpu_vcn_pause_dpg_mode(adev, &new_state);
> +               adev->vcn.vcn_pause_dpg_mode(adev, &new_state);
>         }
>
>         fences += amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg);
> @@ -417,7 +291,7 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
>                 else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
>                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
>
> -               amdgpu_vcn_pause_dpg_mode(adev, &new_state);
> +               adev->vcn.vcn_pause_dpg_mode(adev, &new_state);
>         }
>  }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> index d29a5c9545bd..cee0f263d159 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> @@ -101,6 +101,8 @@ struct amdgpu_vcn {
>         unsigned                num_enc_rings;
>         enum amd_powergating_state cur_state;
>         struct dpg_pause_state pause_state;
> +       int (*vcn_pause_dpg_mode)(struct amdgpu_device *adev,
> +               struct dpg_pause_state *new_state);

Can probably drop the vcn in the function pointer name since it's
already part of the vcn struct.  E.g.,
int (*pause_dpg_mode)(struct amdgpu_device *adev, struct
dpg_pause_state *new_state);


Either way, series is:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

>  };
>
>  int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> index ac2e5a1eb576..a5ab676cb4ac 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> @@ -49,6 +49,8 @@ static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev);
>  static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);
>  static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr);
>  static int vcn_v1_0_set_powergating_state(void *handle, enum amd_powergating_state state);
> +static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
> +                               struct dpg_pause_state *new_state);
>
>  /**
>   * vcn_v1_0_early_init - set function pointers
> @@ -140,7 +142,9 @@ static int vcn_v1_0_sw_init(void *handle)
>         if (r)
>                 return r;
>
> -       return r;
> +       adev->vcn.vcn_pause_dpg_mode = vcn_v1_0_pause_dpg_mode;
> +
> +       return 0;
>  }
>
>  /**
> @@ -1204,6 +1208,132 @@ static int vcn_v1_0_stop(struct amdgpu_device *adev)
>         return r;
>  }
>
> +static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
> +                               struct dpg_pause_state *new_state)
> +{
> +       int ret_code;
> +       uint32_t reg_data = 0;
> +       uint32_t reg_data2 = 0;
> +       struct amdgpu_ring *ring;
> +
> +       /* pause/unpause if state is changed */
> +       if (adev->vcn.pause_state.fw_based != new_state->fw_based) {
> +               DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
> +                       adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
> +                       new_state->fw_based, new_state->jpeg);
> +
> +               reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
> +                       (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
> +
> +               if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
> +                       ret_code = 0;
> +
> +                       if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK))
> +                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> +                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
> +                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> +
> +                       if (!ret_code) {
> +                               /* pause DPG non-jpeg */
> +                               reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
> +                               WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> +                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
> +                                                  UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
> +                                                  UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code);
> +
> +                               /* Restore */
> +                               ring = &adev->vcn.ring_enc[0];
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
> +
> +                               ring = &adev->vcn.ring_enc[1];
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
> +                               WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
> +
> +                               ring = &adev->vcn.ring_dec;
> +                               WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
> +                                                  RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);
> +                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> +                                                  UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
> +                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> +                       }
> +               } else {
> +                       /* unpause dpg non-jpeg, no need to wait */
> +                       reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
> +                       WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> +               }
> +               adev->vcn.pause_state.fw_based = new_state->fw_based;
> +       }
> +
> +       /* pause/unpause if state is changed */
> +       if (adev->vcn.pause_state.jpeg != new_state->jpeg) {
> +               DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
> +                       adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
> +                       new_state->fw_based, new_state->jpeg);
> +
> +               reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
> +                       (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);
> +
> +               if (new_state->jpeg == VCN_DPG_STATE__PAUSE) {
> +                       ret_code = 0;
> +
> +                       if (!(reg_data & UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK))
> +                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> +                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
> +                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> +
> +                       if (!ret_code) {
> +                               /* Make sure JPRG Snoop is disabled before sending the pause */
> +                               reg_data2 = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
> +                               reg_data2 |= UVD_POWER_STATUS__JRBC_SNOOP_DIS_MASK;
> +                               WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data2);
> +
> +                               /* pause DPG jpeg */
> +                               reg_data |= UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
> +                               WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> +                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
> +                                                       UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK,
> +                                                       UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK, ret_code);
> +
> +                               /* Restore */
> +                               ring = &adev->vcn.ring_jpeg;
> +                               WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
> +                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
> +                                                       UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
> +                                                       UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
> +                               WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
> +                                                       lower_32_bits(ring->gpu_addr));
> +                               WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
> +                                                       upper_32_bits(ring->gpu_addr));
> +                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, ring->wptr);
> +                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, ring->wptr);
> +                               WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
> +                                                       UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
> +
> +                               ring = &adev->vcn.ring_dec;
> +                               WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
> +                                                  RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);
> +                               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
> +                                                  UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
> +                                                  UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
> +                       }
> +               } else {
> +                       /* unpause dpg jpeg, no need to wait */
> +                       reg_data &= ~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
> +                       WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
> +               }
> +               adev->vcn.pause_state.jpeg = new_state->jpeg;
> +       }
> +
> +       return 0;
> +}
> +
>  static bool vcn_v1_0_is_idle(void *handle)
>  {
>         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list