Re: [PATCH 07/13] drm/amdgpu: Disable VGA render and crtc when init GMC.
On Wed, Aug 3, 2016 at 11:42 PM, Emily Deng 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 > --- > 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 *connec
[PATCH 07/13] 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: Emily Deng --- 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) +{ + 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); }; struct amdgpu_framebuffer { @@ -367,6 +367,7 @@ struct amdgpu_mode_info { int num_dig; /* number of dig blocks */ int