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 <[email protected]>
---
 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)
+{
+       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);
 };
 
 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;
+}
+
+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;
+                       }
+               }
+       }
+}
+
+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);
+       }
+}
+
 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);
+       }
 }
 
 static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device 
*adev,
-- 
1.9.1

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to