Commit 83c9b025 authored by Emily Deng's avatar Emily Deng Committed by Alex Deucher

drm/amdgpu: Disable VGA render and crtc when init GMC.

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: default avatarEmily Deng <Emily.Deng@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 0bad1619
...@@ -712,6 +712,45 @@ static void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev, ...@@ -712,6 +712,45 @@ static void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev,
WREG32(mmVGA_RENDER_CONTROL, tmp); 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) static void dce_v10_0_program_fmt(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -2962,10 +3001,11 @@ static int dce_v10_0_early_init(void *handle) ...@@ -2962,10 +3001,11 @@ static int dce_v10_0_early_init(void *handle)
dce_v10_0_set_display_funcs(adev); dce_v10_0_set_display_funcs(adev);
dce_v10_0_set_irq_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) { switch (adev->asic_type) {
case CHIP_FIJI: case CHIP_FIJI:
case CHIP_TONGA: case CHIP_TONGA:
adev->mode_info.num_crtc = 6; /* XXX 7??? */
adev->mode_info.num_hpd = 6; adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 7; adev->mode_info.num_dig = 7;
break; break;
......
...@@ -26,4 +26,6 @@ ...@@ -26,4 +26,6 @@
extern const struct amd_ip_funcs dce_v10_0_ip_funcs; extern const struct amd_ip_funcs dce_v10_0_ip_funcs;
void dce_v10_0_disable_dce(struct amdgpu_device *adev);
#endif #endif
...@@ -673,6 +673,53 @@ static void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev, ...@@ -673,6 +673,53 @@ static void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev,
WREG32(mmVGA_RENDER_CONTROL, tmp); 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) static void dce_v11_0_program_fmt(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -2999,24 +3046,22 @@ static int dce_v11_0_early_init(void *handle) ...@@ -2999,24 +3046,22 @@ static int dce_v11_0_early_init(void *handle)
dce_v11_0_set_display_funcs(adev); dce_v11_0_set_display_funcs(adev);
dce_v11_0_set_irq_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) { switch (adev->asic_type) {
case CHIP_CARRIZO: case CHIP_CARRIZO:
adev->mode_info.num_crtc = 3;
adev->mode_info.num_hpd = 6; adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 9; adev->mode_info.num_dig = 9;
break; break;
case CHIP_STONEY: case CHIP_STONEY:
adev->mode_info.num_crtc = 2;
adev->mode_info.num_hpd = 6; adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 9; adev->mode_info.num_dig = 9;
break; break;
case CHIP_POLARIS10: case CHIP_POLARIS10:
adev->mode_info.num_crtc = 6;
adev->mode_info.num_hpd = 6; adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 6; adev->mode_info.num_dig = 6;
break; break;
case CHIP_POLARIS11: case CHIP_POLARIS11:
adev->mode_info.num_crtc = 5;
adev->mode_info.num_hpd = 5; adev->mode_info.num_hpd = 5;
adev->mode_info.num_dig = 5; adev->mode_info.num_dig = 5;
break; break;
......
...@@ -26,4 +26,6 @@ ...@@ -26,4 +26,6 @@
extern const struct amd_ip_funcs dce_v11_0_ip_funcs; extern const struct amd_ip_funcs dce_v11_0_ip_funcs;
void dce_v11_0_disable_dce(struct amdgpu_device *adev);
#endif #endif
...@@ -604,6 +604,52 @@ static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev, ...@@ -604,6 +604,52 @@ static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
WREG32(mmVGA_RENDER_CONTROL, tmp); 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) static void dce_v8_0_program_fmt(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -2803,21 +2849,20 @@ static int dce_v8_0_early_init(void *handle) ...@@ -2803,21 +2849,20 @@ static int dce_v8_0_early_init(void *handle)
dce_v8_0_set_display_funcs(adev); dce_v8_0_set_display_funcs(adev);
dce_v8_0_set_irq_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) { switch (adev->asic_type) {
case CHIP_BONAIRE: case CHIP_BONAIRE:
case CHIP_HAWAII: case CHIP_HAWAII:
adev->mode_info.num_crtc = 6;
adev->mode_info.num_hpd = 6; adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 6; adev->mode_info.num_dig = 6;
break; break;
case CHIP_KAVERI: case CHIP_KAVERI:
adev->mode_info.num_crtc = 4;
adev->mode_info.num_hpd = 6; adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 7; adev->mode_info.num_dig = 7;
break; break;
case CHIP_KABINI: case CHIP_KABINI:
case CHIP_MULLINS: case CHIP_MULLINS:
adev->mode_info.num_crtc = 2;
adev->mode_info.num_hpd = 6; adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 6; /* ? */ adev->mode_info.num_dig = 6; /* ? */
break; break;
......
...@@ -26,4 +26,6 @@ ...@@ -26,4 +26,6 @@
extern const struct amd_ip_funcs dce_v8_0_ip_funcs; extern const struct amd_ip_funcs dce_v8_0_ip_funcs;
void dce_v8_0_disable_dce(struct amdgpu_device *adev);
#endif #endif
...@@ -25,11 +25,13 @@ ...@@ -25,11 +25,13 @@
#include "amdgpu_pm.h" #include "amdgpu_pm.h"
#include "amdgpu_i2c.h" #include "amdgpu_i2c.h"
#include "atom.h" #include "atom.h"
#include "amdgpu_atombios.h"
#include "atombios_crtc.h"
#include "atombios_encoders.h"
#include "amdgpu_pll.h" #include "amdgpu_pll.h"
#include "amdgpu_connectors.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_display_funcs(struct amdgpu_device *adev);
static void dce_virtual_set_irq_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) ...@@ -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, void dce_virtual_stop_mc_access(struct amdgpu_device *adev,
struct amdgpu_mode_mc_save *save) 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; return;
} }
void dce_virtual_resume_mc_access(struct amdgpu_device *adev, void dce_virtual_resume_mc_access(struct amdgpu_device *adev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment