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