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

Alex Deucher alexdeucher at gmail.com
Thu Aug 4 18:17:05 UTC 2016


On Wed, Aug 3, 2016 at 11:42 PM, 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>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h          |  2 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 27 +++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h |  2 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h     |  5 +-
>  drivers/gpu/drm/amd/amdgpu/dce_v10_0.c       | 75 ++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/dce_v10_0.h       |  2 +
>  drivers/gpu/drm/amd/amdgpu/dce_v11_0.c       | 83 +++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/dce_v11_0.h       |  2 +
>  drivers/gpu/drm/amd/amdgpu/dce_v8_0.c        | 82 +++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/dce_v8_0.h        |  2 +
>  drivers/gpu/drm/amd/amdgpu/dce_virtual.c     | 85 ++++++++++++++++++++++++++--
>  11 files changed, 359 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 3cafcfd..7a9e6b8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -2304,6 +2304,8 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
>  #define amdgpu_display_add_connector(adev, ci, sd, ct, ib, coi, h, r) (adev)->mode_info.funcs->add_connector((adev), (ci), (sd), (ct), (ib), (coi), (h), (r))
>  #define amdgpu_display_stop_mc_access(adev, s) (adev)->mode_info.funcs->stop_mc_access((adev), (s))
>  #define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s))
> +#define amdgpu_display_disable_vga_and_crtc(adev) (adev)->mode_info.funcs->disable_vga_and_crtc((adev))
> +#define amdgpu_display_resume_vga_and_crtc(adev) (adev)->mode_info.funcs->resume_vga_and_crtc((adev))
>  #define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib),  (s), (d), (b))
>  #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
>  #define amdgpu_dpm_pre_set_power_state(adev) (adev)->pm.funcs->pre_set_power_state((adev))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> index 9831753..f9ea890 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> @@ -259,6 +259,33 @@ static const int object_connector_convert[] = {
>         DRM_MODE_CONNECTOR_Unknown
>  };
>
> +bool amdgpu_atombios_has_DCE_engine_info(struct amdgpu_device *adev)

No need to capitalize the DCE in this function name.
amdgpu_atombios_has_dce_engine_info() is fine.  It would also be nice
to add this function in a separate commit.

> +{
> +       struct amdgpu_mode_info *mode_info = &adev->mode_info;
> +       struct atom_context *ctx = mode_info->atom_context;
> +       int index = GetIndexIntoMasterTable(DATA, Object_Header);
> +       u16 size, data_offset;
> +       u8 frev, crev;
> +       ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
> +       ATOM_OBJECT_HEADER *obj_header;
> +
> +       if (!amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
> +               return false;
> +
> +       if (crev < 2)
> +               return false;
> +
> +       obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
> +       path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
> +           (ctx->bios + data_offset +
> +            le16_to_cpu(obj_header->usDisplayPathTableOffset));
> +
> +       if (path_obj->ucNumOfDispPath)
> +               return true;
> +       else
> +               return false;
> +}
> +
>  bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev)
>  {
>         struct amdgpu_mode_info *mode_info = &adev->mode_info;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
> index 8c2e696..8a0f770 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
> @@ -140,6 +140,8 @@ struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *
>                                                           uint8_t id);
>  void amdgpu_atombios_i2c_init(struct amdgpu_device *adev);
>
> +bool amdgpu_atombios_has_DCE_engine_info(struct amdgpu_device *adev);
> +
>  bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev);
>
>  int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index a2f12b0..d7cf37c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -313,8 +313,8 @@ struct amdgpu_display_funcs {
>         int (*set_freesync_property)(struct drm_connector *connector,
>                                      struct drm_property *property,
>                                      uint64_t val);
> -
> -
> +       void (*disable_vga_and_crtc)(struct amdgpu_device *adev);
> +       void (*resume_vga_and_crtc)(struct amdgpu_device *adev);

I think we can drop these.

>  };
>
>  struct amdgpu_framebuffer {
> @@ -367,6 +367,7 @@ struct amdgpu_mode_info {
>         int                     num_dig; /* number of dig blocks */
>         int                     disp_priority;
>         const struct amdgpu_display_funcs *funcs;
> +       struct amdgpu_mode_mc_save save;
>  };
>
>  #define AMDGPU_MAX_BL_LEVEL 0xFF
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> index e49e151..efa5605 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> @@ -690,6 +690,81 @@ void dce_v10_0_resume_mc_access(struct amdgpu_device *adev,
>         WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
>  }
>
> +static int dce_virtual_v10_0_original_crtc_num(struct amdgpu_device *adev)
> +{
> +       int original_num_crtc = 0;
> +
> +       switch (adev->asic_type) {
> +       case CHIP_FIJI:
> +       case CHIP_TONGA:
> +               original_num_crtc = 6;
> +               break;
> +       default:
> +               original_num_crtc = 0;
> +       }
> +       return original_num_crtc;
> +}

Can you make dce_v10_0_early_init() use this function too?  that way
we don't duplicate the same information.  Call it
dce_v10_get_num_crtc() or something like that.

> +
> +void dce_virtual_v10_0_disable_vga_and_crtc(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;
> +               int original_num_crtc = dce_virtual_v10_0_original_crtc_num(adev);
> +
> +               adev->mode_info.save.vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
> +               adev->mode_info.save.vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
> +
> +               /* Disable VGA render */
> +               tmp = RREG32(mmVGA_RENDER_CONTROL);
> +               tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
> +               WREG32(mmVGA_RENDER_CONTROL, tmp);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < original_num_crtc; 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);
> +                               adev->mode_info.save.crtc_enabled[i] = true;
> +                       } else {
> +                               adev->mode_info.save.crtc_enabled[i] = false;
> +                       }
> +               }
> +       }
> +}

Rename this function disable_dce() Just go ahead and disable vga and
the crtcs.  This function would basically turn into:
void dce_v10_0_disable_dce(adev)
{
    unsigned i;

    dce_v10_0_set_vga_render_state(adev, false);

    for (i = 0; i < dce_v10_0_get_num_crtc(adev); i++) {
                                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);
    }
}

> +
> +void dce_virtual_v10_0_resume_vga_and_crtc(struct amdgpu_device *adev)
> +{
> +       /*Restore VGA render and enabled crtc, if has DCE engine*/
> +       if (amdgpu_atombios_has_DCE_engine_info(adev)) {
> +               u32 tmp;
> +               int i;
> +               int original_num_crtc = dce_virtual_v10_0_original_crtc_num(adev);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < original_num_crtc; i++) {
> +                       if (adev->mode_info.save.crtc_enabled[i]) {
> +                               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, 1);
> +                               WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
> +                       }
> +               }
> +
> +               /* Unlock vga access */
> +               WREG32(mmVGA_HDP_CONTROL, adev->mode_info.save.vga_hdp_control);
> +               mdelay(1);
> +               WREG32(mmVGA_RENDER_CONTROL, adev->mode_info.save.vga_render_control);
> +       }
> +}
> +

No need to restore the old state.  WIth virtual dce, we generally want
the display hw turned off.  We can drop this function.

>  void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev,
>                                     bool render)
>  {
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
> index 77a732c..48f56f3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
> @@ -32,5 +32,7 @@ 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_virtual_v10_0_disable_vga_and_crtc(struct amdgpu_device *adev);
> +void dce_virtual_v10_0_resume_vga_and_crtc(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..cf552ae 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> @@ -651,6 +651,89 @@ void dce_v11_0_resume_mc_access(struct amdgpu_device *adev,
>         WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
>  }
>
> +static int dce_virtual_v11_0_original_crtc_num(struct amdgpu_device *adev)
> +{
> +       int original_num_crtc = 0;
> +
> +       switch (adev->asic_type) {
> +       case CHIP_CARRIZO:
> +               original_num_crtc = 3;
> +               break;
> +       case CHIP_STONEY:
> +               original_num_crtc = 2;
> +               break;
> +       case CHIP_POLARIS10:
> +               original_num_crtc = 6;
> +               break;
> +       case CHIP_POLARIS11:
> +               original_num_crtc = 5;
> +               break;
> +       default:
> +               original_num_crtc = 0;
> +       }
> +       return original_num_crtc;
> +}
> +
> +void dce_virtual_v11_0_disable_vga_and_crtc(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;
> +               int original_num_crtc = dce_virtual_v11_0_original_crtc_num(adev);
> +
> +               adev->mode_info.save.vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
> +               adev->mode_info.save.vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
> +
> +               /* Disable VGA render */
> +               tmp = RREG32(mmVGA_RENDER_CONTROL);
> +               tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
> +               WREG32(mmVGA_RENDER_CONTROL, tmp);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < original_num_crtc; 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);
> +                               adev->mode_info.save.crtc_enabled[i] = true;
> +                       } else {
> +                               adev->mode_info.save.crtc_enabled[i] = false;
> +                       }
> +               }
> +       }
> +}
> +
> +void dce_virtual_v11_0_resume_vga_and_crtc(struct amdgpu_device *adev)
> +{
> +       /*Restore VGA render and enabled crtc, if has DCE engine*/
> +       if (amdgpu_atombios_has_DCE_engine_info(adev)) {
> +               u32 tmp;
> +               int i;
> +               int original_num_crtc = dce_virtual_v11_0_original_crtc_num(adev);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < original_num_crtc; i++) {
> +                       if (adev->mode_info.save.crtc_enabled[i]) {
> +                               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, 1);
> +                               WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
> +                       }
> +               }
> +
> +               /* Unlock vga access */
> +               WREG32(mmVGA_HDP_CONTROL, adev->mode_info.save.vga_hdp_control);
> +               mdelay(1);
> +               WREG32(mmVGA_RENDER_CONTROL, adev->mode_info.save.vga_render_control);
> +       }
> +}
> +
>  void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev,
>                                     bool render)
>  {
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
> index fa1884c..6a5e134 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
> @@ -32,5 +32,7 @@ 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_virtual_v11_0_disable_vga_and_crtc(struct amdgpu_device *adev);
> +void dce_virtual_v11_0_resume_vga_and_crtc(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..da4307c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> @@ -582,6 +582,88 @@ void dce_v8_0_resume_mc_access(struct amdgpu_device *adev,
>         WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
>  }
>
> +static int dce_virtual_v8_0_original_crtc_num(struct amdgpu_device *adev)
> +{
> +       int original_num_crtc = 0;
> +
> +       switch (adev->asic_type) {
> +       case CHIP_BONAIRE:
> +       case CHIP_HAWAII:
> +               original_num_crtc = 6;
> +               break;
> +       case CHIP_KAVERI:
> +               original_num_crtc = 4;
> +               break;
> +       case CHIP_KABINI:
> +       case CHIP_MULLINS:
> +               original_num_crtc = 2;
> +               break;
> +       default:
> +               original_num_crtc = 0;
> +       }
> +       return original_num_crtc;
> +}
> +
> +void dce_virtual_v8_0_disable_vga_and_crtc(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;
> +               int original_num_crtc = dce_virtual_v8_0_original_crtc_num(adev);
> +
> +               adev->mode_info.save.vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
> +               adev->mode_info.save.vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
> +
> +               /* Disable VGA render */
> +               tmp = RREG32(mmVGA_RENDER_CONTROL);
> +               tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
> +               WREG32(mmVGA_RENDER_CONTROL, tmp);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < original_num_crtc; 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);
> +                               adev->mode_info.save.crtc_enabled[i] = true;
> +                       } else {
> +                               adev->mode_info.save.crtc_enabled[i] = false;
> +                       }
> +               }
> +       }
> +}
> +
> +void dce_virtual_v8_0_resume_vga_and_crtc(struct amdgpu_device *adev)
> +{
> +       /*Restore VGA render and enabled crtc, if has DCE engine*/
> +       if (amdgpu_atombios_has_DCE_engine_info(adev)) {
> +               u32 tmp;
> +               int i;
> +               int original_num_crtc = dce_virtual_v8_0_original_crtc_num(adev);
> +
> +               /*Disable crtc*/
> +               for (i = 0; i < original_num_crtc; i++) {
> +                       if (adev->mode_info.save.crtc_enabled[i]) {
> +                               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, 1);
> +                               WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
> +                               WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
> +                       }
> +               }
> +
> +               /* Unlock vga access */
> +               WREG32(mmVGA_HDP_CONTROL, adev->mode_info.save.vga_hdp_control);
> +               mdelay(1);
> +               WREG32(mmVGA_RENDER_CONTROL, adev->mode_info.save.vga_render_control);
> +       }
> +}
> +
>  void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
>                                    bool render)
>  {
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
> index 53f643c..464b564 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
> @@ -32,5 +32,7 @@ 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_virtual_v8_0_disable_vga_and_crtc(struct amdgpu_device *adev);
> +void dce_virtual_v8_0_resume_vga_and_crtc(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..21a2e41 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);
> @@ -414,6 +416,7 @@ static int dce_virtual_sw_fini(void *handle)
>
>         drm_mode_config_cleanup(adev->ddev);
>         adev->mode_info.mode_config_initialized = false;
> +       amdgpu_display_resume_vga_and_crtc(adev);
>         return 0;
>  }
>
> @@ -589,7 +592,8 @@ static void dce_virtual_encoder_add(struct amdgpu_device *adev,
>         DRM_INFO("[FM]encoder: %d is VIRTUAL\n", amdgpu_encoder->encoder_id);
>  }
>
> -static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> +static const struct amdgpu_display_funcs dce_virtual_v8_0_display_funcs = {
>         .set_vga_render_state = &dce_virtual_set_vga_render_state,
>         .bandwidth_update = &dce_virtual_bandwidth_update,
>         .vblank_get_counter = &dce_virtual_vblank_get_counter,
> @@ -606,12 +610,81 @@ static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
>         .add_connector = &amdgpu_connector_add,
>         .stop_mc_access = &dce_virtual_stop_mc_access,
>         .resume_mc_access = &dce_virtual_resume_mc_access,
> +       .disable_vga_and_crtc = &dce_virtual_v8_0_disable_vga_and_crtc,
> +       .resume_vga_and_crtc = &dce_virtual_v8_0_resume_vga_and_crtc,
> +};
> +#endif
> +
> +static const struct amdgpu_display_funcs dce_virtual_v10_0_display_funcs = {
> +       .set_vga_render_state = &dce_virtual_set_vga_render_state,
> +       .bandwidth_update = &dce_virtual_bandwidth_update,
> +       .vblank_get_counter = &dce_virtual_vblank_get_counter,
> +       .vblank_wait = &dce_virtual_vblank_wait,
> +       .is_display_hung = &dce_virtual_is_display_hung,
> +       .backlight_set_level = NULL,
> +       .backlight_get_level = NULL,
> +       .hpd_sense = &dce_virtual_hpd_sense,
> +       .hpd_set_polarity = &dce_virtual_hpd_set_polarity,
> +       .hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg,
> +       .page_flip = &dce_virtual_page_flip,
> +       .page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
> +       .add_encoder = &dce_virtual_encoder_add,
> +       .add_connector = &amdgpu_connector_add,
> +       .stop_mc_access = &dce_virtual_stop_mc_access,
> +       .resume_mc_access = &dce_virtual_resume_mc_access,
> +       .disable_vga_and_crtc = &dce_virtual_v10_0_disable_vga_and_crtc,
> +       .resume_vga_and_crtc = &dce_virtual_v10_0_resume_vga_and_crtc,
> +};
> +
> +static const struct amdgpu_display_funcs dce_virtual_v11_0_display_funcs = {
> +       .set_vga_render_state = &dce_virtual_set_vga_render_state,
> +       .bandwidth_update = &dce_virtual_bandwidth_update,
> +       .vblank_get_counter = &dce_virtual_vblank_get_counter,
> +       .vblank_wait = &dce_virtual_vblank_wait,
> +       .is_display_hung = &dce_virtual_is_display_hung,
> +       .backlight_set_level = NULL,
> +       .backlight_get_level = NULL,
> +       .hpd_sense = &dce_virtual_hpd_sense,
> +       .hpd_set_polarity = &dce_virtual_hpd_set_polarity,
> +       .hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg,
> +       .page_flip = &dce_virtual_page_flip,
> +       .page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
> +       .add_encoder = &dce_virtual_encoder_add,
> +       .add_connector = &amdgpu_connector_add,
> +       .stop_mc_access = &dce_virtual_stop_mc_access,
> +       .resume_mc_access = &dce_virtual_resume_mc_access,
> +       .disable_vga_and_crtc = &dce_virtual_v11_0_disable_vga_and_crtc,
> +       .resume_vga_and_crtc = &dce_virtual_v11_0_resume_vga_and_crtc,
>  };
>
>  static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
>  {
> -       if (adev->mode_info.funcs == NULL)
> -               adev->mode_info.funcs = &dce_virtual_display_funcs;
> +       switch (adev->asic_type) {
> +       case CHIP_BONAIRE:
> +       case CHIP_HAWAII:
> +       case CHIP_KAVERI:
> +       case CHIP_KABINI:
> +       case CHIP_MULLINS:
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> +               if (adev->mode_info.funcs == NULL)
> +                       adev->mode_info.funcs = &dce_virtual_v8_0_display_funcs;
> +#endif
> +               break;
> +       case CHIP_FIJI:
> +       case CHIP_TONGA:
> +               if (adev->mode_info.funcs == NULL)
> +                       adev->mode_info.funcs = &dce_virtual_v10_0_display_funcs;
> +               break;
> +       case CHIP_CARRIZO:
> +       case CHIP_STONEY:
> +       case CHIP_POLARIS11:
> +       case CHIP_POLARIS10:
> +               if (adev->mode_info.funcs == NULL)
> +                       adev->mode_info.funcs = &dce_virtual_v11_0_display_funcs;
> +               break;
> +       default:
> +               DRM_ERROR("Usupported ASIC type: 0x%X\n", adev->asic_type);
> +       }
>  }

Rather than adding all of these callbacks, just add a big asic_type
switch statement to the virtual mc_stop function can just call the
dce8, 10, and 11 disable_dce() functions directly.

Alex

>
>  static void dce_virtual_set_crtc_vblank_interrupt_state(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