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