OSDN Git Service

drm/amdgpu: Disable VGA render and crtc when init GMC.
authorEmily Deng <Emily.Deng@amd.com>
Mon, 8 Aug 2016 03:33:11 +0000 (11:33 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Aug 2016 18:04:37 +0000 (14:04 -0400)
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@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
drivers/gpu/drm/amd/amdgpu/dce_virtual.c

index 7f642b5..b888d72 100644 (file)
@@ -712,6 +712,45 @@ static 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;
@@ -2962,10 +3001,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;
index 1bfa48d..e3dc04d 100644 (file)
@@ -26,4 +26,6 @@
 
 extern const struct amd_ip_funcs dce_v10_0_ip_funcs;
 
+void dce_v10_0_disable_dce(struct amdgpu_device *adev);
+
 #endif
index d4bf133..cfadd79 100644 (file)
@@ -673,6 +673,53 @@ static 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;
@@ -2999,24 +3046,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;
index 84e4618..1f58a65 100644 (file)
@@ -26,4 +26,6 @@
 
 extern const struct amd_ip_funcs dce_v11_0_ip_funcs;
 
+void dce_v11_0_disable_dce(struct amdgpu_device *adev);
+
 #endif
index 4fdfab1..e4467b8 100644 (file)
@@ -604,6 +604,52 @@ static 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;
@@ -2803,21 +2849,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;
index 7701685..7d0770c 100644 (file)
@@ -26,4 +26,6 @@
 
 extern const struct amd_ip_funcs dce_v8_0_ip_funcs;
 
+void dce_v8_0_disable_dce(struct amdgpu_device *adev);
+
 #endif
index d6802be..c7da45c 100644 (file)
 #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,