[PATCH 08/14] drm/amdgpu: Disable VGA render and crtc when init GMC.

Alex Deucher alexdeucher at gmail.com
Fri Aug 5 18:35:01 UTC 2016


On Fri, Aug 5, 2016 at 2:08 AM, Emily Deng <Emily.Deng at amd.com> wrote:
> For virtual display feature, when the GPU has DCE engine, need to disable
> the VGA render and CRTC, or it will hang when initialize GMC.
>
> Signed-off-by: Emily Deng <Emily.Deng at amd.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/dce_v10_0.c   | 42 ++++++++++++++++++++++++-
>  drivers/gpu/drm/amd/amdgpu/dce_v10_0.h   |  1 +
>  drivers/gpu/drm/amd/amdgpu/dce_v11_0.c   | 53 +++++++++++++++++++++++++++++---
>  drivers/gpu/drm/amd/amdgpu/dce_v11_0.h   |  1 +
>  drivers/gpu/drm/amd/amdgpu/dce_v8_0.c    | 51 ++++++++++++++++++++++++++++--
>  drivers/gpu/drm/amd/amdgpu/dce_v8_0.h    |  1 +
>  drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 32 +++++++++++++++++--
>  7 files changed, 170 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> index e49e151..9bb97a3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> @@ -712,6 +712,45 @@ void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev,
>         WREG32(mmVGA_RENDER_CONTROL, tmp);
>  }
>
> +static int dce_v10_0_get_num_crtc(struct amdgpu_device *adev)
> +{
> +       int num_crtc = 0;
> +
> +       switch (adev->asic_type) {
> +       case CHIP_FIJI:
> +       case CHIP_TONGA:
> +               num_crtc = 6;
> +               break;
> +       default:
> +               num_crtc = 0;
> +       }
> +       return num_crtc;
> +}
> +
> +void dce_v10_0_disable_dce(struct amdgpu_device *adev)
> +{
> +       /*Disable VGA render and enabled crtc, if has DCE engine*/
> +       if (amdgpu_atombios_has_dce_engine_info(adev)) {
> +               u32 tmp;
> +               int crtc_enabled, i;
> +
> +               dce_v10_0_set_vga_render_state(adev, false);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < dce_v10_0_get_num_crtc(adev); i++) {
> +                       crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
> +                                                                        CRTC_CONTROL, CRTC_MASTER_EN);
> +                       if (crtc_enabled) {
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
> +                               tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
> +                               tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
> +                               WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
> +                       }
> +               }
> +       }
> +}
> +
>  static void dce_v10_0_program_fmt(struct drm_encoder *encoder)
>  {
>         struct drm_device *dev = encoder->dev;
> @@ -2960,10 +2999,11 @@ static int dce_v10_0_early_init(void *handle)
>         dce_v10_0_set_display_funcs(adev);
>         dce_v10_0_set_irq_funcs(adev);
>
> +       adev->mode_info.num_crtc = dce_v10_0_get_num_crtc(adev);
> +
>         switch (adev->asic_type) {
>         case CHIP_FIJI:
>         case CHIP_TONGA:
> -               adev->mode_info.num_crtc = 6; /* XXX 7??? */
>                 adev->mode_info.num_hpd = 6;
>                 adev->mode_info.num_dig = 7;
>                 break;
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
> index 77a732c..3c9d9e0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
> @@ -32,5 +32,6 @@ void dce_v10_0_stop_mc_access(struct amdgpu_device *adev,
>                               struct amdgpu_mode_mc_save *save);
>  void dce_v10_0_resume_mc_access(struct amdgpu_device *adev,
>                                 struct amdgpu_mode_mc_save *save);
> +void dce_v10_0_disable_dce(struct amdgpu_device *adev);
>  bool dce_v10_0_is_display_hung(struct amdgpu_device *adev);
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> index 2f08c8b..674dfc7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> @@ -673,6 +673,53 @@ void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev,
>         WREG32(mmVGA_RENDER_CONTROL, tmp);
>  }
>
> +static int dce_v11_0_get_num_crtc (struct amdgpu_device *adev)
> +{
> +       int num_crtc = 0;
> +
> +       switch (adev->asic_type) {
> +       case CHIP_CARRIZO:
> +               num_crtc = 3;
> +               break;
> +       case CHIP_STONEY:
> +               num_crtc = 2;
> +               break;
> +       case CHIP_POLARIS10:
> +               num_crtc = 6;
> +               break;
> +       case CHIP_POLARIS11:
> +               num_crtc = 5;
> +               break;
> +       default:
> +               num_crtc = 0;
> +       }
> +       return num_crtc;
> +}
> +
> +void dce_v11_0_disable_dce(struct amdgpu_device *adev)
> +{
> +       /*Disable VGA render and enabled crtc, if has DCE engine*/
> +       if (amdgpu_atombios_has_dce_engine_info(adev)) {
> +               u32 tmp;
> +               int crtc_enabled, i;
> +
> +               dce_v11_0_set_vga_render_state(adev, false);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < dce_v11_0_get_num_crtc(adev); i++) {
> +                       crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
> +                                                                        CRTC_CONTROL, CRTC_MASTER_EN);
> +                       if (crtc_enabled) {
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
> +                               tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
> +                               tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
> +                               WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
> +                       }
> +               }
> +       }
> +}
> +
>  static void dce_v11_0_program_fmt(struct drm_encoder *encoder)
>  {
>         struct drm_device *dev = encoder->dev;
> @@ -2997,24 +3044,22 @@ static int dce_v11_0_early_init(void *handle)
>         dce_v11_0_set_display_funcs(adev);
>         dce_v11_0_set_irq_funcs(adev);
>
> +       adev->mode_info.num_crtc = dce_v11_0_get_num_crtc(adev);
> +
>         switch (adev->asic_type) {
>         case CHIP_CARRIZO:
> -               adev->mode_info.num_crtc = 3;
>                 adev->mode_info.num_hpd = 6;
>                 adev->mode_info.num_dig = 9;
>                 break;
>         case CHIP_STONEY:
> -               adev->mode_info.num_crtc = 2;
>                 adev->mode_info.num_hpd = 6;
>                 adev->mode_info.num_dig = 9;
>                 break;
>         case CHIP_POLARIS10:
> -               adev->mode_info.num_crtc = 6;
>                 adev->mode_info.num_hpd = 6;
>                 adev->mode_info.num_dig = 6;
>                 break;
>         case CHIP_POLARIS11:
> -               adev->mode_info.num_crtc = 5;
>                 adev->mode_info.num_hpd = 5;
>                 adev->mode_info.num_dig = 5;
>                 break;
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
> index fa1884c..cbe338c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
> @@ -32,5 +32,6 @@ void dce_v11_0_stop_mc_access(struct amdgpu_device *adev,
>                               struct amdgpu_mode_mc_save *save);
>  void dce_v11_0_resume_mc_access(struct amdgpu_device *adev,
>                                 struct amdgpu_mode_mc_save *save);
> +void dce_v11_0_disable_dce(struct amdgpu_device *adev);
>  bool dce_v11_0_is_display_hung(struct amdgpu_device *adev);
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> index ca5fc06..28e1682 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> @@ -604,6 +604,52 @@ void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
>         WREG32(mmVGA_RENDER_CONTROL, tmp);
>  }
>
> +static int dce_v8_0_get_num_crtc(struct amdgpu_device *adev)
> +{
> +       int num_crtc = 0;
> +
> +       switch (adev->asic_type) {
> +       case CHIP_BONAIRE:
> +       case CHIP_HAWAII:
> +               num_crtc = 6;
> +               break;
> +       case CHIP_KAVERI:
> +               num_crtc = 4;
> +               break;
> +       case CHIP_KABINI:
> +       case CHIP_MULLINS:
> +               num_crtc = 2;
> +               break;
> +       default:
> +               num_crtc = 0;
> +       }
> +       return num_crtc;
> +}
> +
> +void dce_v8_0_disable_dce(struct amdgpu_device *adev)
> +{
> +       /*Disable VGA render and enabled crtc, if has DCE engine*/
> +       if (amdgpu_atombios_has_dce_engine_info(adev)) {
> +               u32 tmp;
> +               int crtc_enabled, i;
> +
> +               dce_v8_0_set_vga_render_state(adev, false);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < dce_v8_0_get_num_crtc(adev); i++) {
> +                       crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
> +                                                                        CRTC_CONTROL, CRTC_MASTER_EN);
> +                       if (crtc_enabled) {
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
> +                               tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
> +                               tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
> +                               WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
> +                       }
> +               }
> +       }
> +}
> +
>  static void dce_v8_0_program_fmt(struct drm_encoder *encoder)
>  {
>         struct drm_device *dev = encoder->dev;
> @@ -2801,21 +2847,20 @@ static int dce_v8_0_early_init(void *handle)
>         dce_v8_0_set_display_funcs(adev);
>         dce_v8_0_set_irq_funcs(adev);
>
> +       adev->mode_info.num_crtc = dce_v8_0_get_num_crtc(adev);
> +
>         switch (adev->asic_type) {
>         case CHIP_BONAIRE:
>         case CHIP_HAWAII:
> -               adev->mode_info.num_crtc = 6;
>                 adev->mode_info.num_hpd = 6;
>                 adev->mode_info.num_dig = 6;
>                 break;
>         case CHIP_KAVERI:
> -               adev->mode_info.num_crtc = 4;
>                 adev->mode_info.num_hpd = 6;
>                 adev->mode_info.num_dig = 7;
>                 break;
>         case CHIP_KABINI:
>         case CHIP_MULLINS:
> -               adev->mode_info.num_crtc = 2;
>                 adev->mode_info.num_hpd = 6;
>                 adev->mode_info.num_dig = 6; /* ? */
>                 break;
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
> index 53f643c..8cadb4b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
> @@ -32,5 +32,6 @@ void dce_v8_0_stop_mc_access(struct amdgpu_device *adev,
>                              struct amdgpu_mode_mc_save *save);
>  void dce_v8_0_resume_mc_access(struct amdgpu_device *adev,
>                                struct amdgpu_mode_mc_save *save);
> +void dce_v8_0_disable_dce(struct amdgpu_device *adev);
>  bool dce_v8_0_is_display_hung(struct amdgpu_device *adev);
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> index b77c85e..cb240451 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> @@ -25,11 +25,13 @@
>  #include "amdgpu_pm.h"
>  #include "amdgpu_i2c.h"
>  #include "atom.h"
> -#include "amdgpu_atombios.h"
> -#include "atombios_crtc.h"
> -#include "atombios_encoders.h"
>  #include "amdgpu_pll.h"
>  #include "amdgpu_connectors.h"
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> +#include "dce_v8_0.h"
> +#endif
> +#include "dce_v10_0.h"
> +#include "dce_v11_0.h"
>
>  static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
>  static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
> @@ -98,6 +100,30 @@ static bool dce_virtual_is_display_hung(struct amdgpu_device *adev)
>  void dce_virtual_stop_mc_access(struct amdgpu_device *adev,
>                               struct amdgpu_mode_mc_save *save)
>  {
> +       switch (adev->asic_type) {
> +       case CHIP_BONAIRE:
> +       case CHIP_HAWAII:
> +       case CHIP_KAVERI:
> +       case CHIP_KABINI:
> +       case CHIP_MULLINS:
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> +               dce_v8_0_disable_dce(adev);
> +#endif
> +               break;
> +       case CHIP_FIJI:
> +       case CHIP_TONGA:
> +               dce_v10_0_disable_dce(adev);
> +               break;
> +       case CHIP_CARRIZO:
> +       case CHIP_STONEY:
> +       case CHIP_POLARIS11:
> +       case CHIP_POLARIS10:
> +               dce_v11_0_disable_dce(adev);
> +               break;
> +       default:
> +               DRM_ERROR("Usupported ASIC type: 0x%X\n", adev->asic_type);
> +       }
> +
>         return;
>  }
>  void dce_virtual_resume_mc_access(struct amdgpu_device *adev,
> --
> 1.9.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