[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