diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-02 15:04:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-02 15:04:15 -0700 |
commit | faa392181a0bd42c5478175cef601adeecdc91b6 (patch) | |
tree | e020e1142e34786676d0cd40f539bccdbb66099e /drivers/gpu/drm/amd/display/amdgpu_dm | |
parent | cfa3b8068b09f25037146bfd5eed041b78878bee (diff) | |
parent | 9ca1f474cea0edc14a1d7ec933e5472c0ff115d3 (diff) |
Merge tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"Highlights:
- Core DRM had a lot of refactoring around managed drm resources to
make drivers simpler.
- Intel Tigerlake support is on by default
- amdgpu now support p2p PCI buffer sharing and encrypted GPU memory
Details:
core:
- uapi: error out EBUSY when existing master
- uapi: rework SET/DROP MASTER permission handling
- remove drm_pci.h
- drm_pci* are now legacy
- introduced managed DRM resources
- subclassing support for drm_framebuffer
- simple encoder helper
- edid improvements
- vblank + writeback documentation improved
- drm/mm - optimise tree searches
- port drivers to use devm_drm_dev_alloc
dma-buf:
- add flag for p2p buffer support
mst:
- ACT timeout improvements
- remove drm_dp_mst_has_audio
- don't use 2nd TX slot - spec recommends against it
bridge:
- dw-hdmi various improvements
- chrontel ch7033 support
- fix stack issues with old gcc
hdmi:
- add unpack function for drm infoframe
fbdev:
- misc fbdev driver fixes
i915:
- uapi: global sseu pinning
- uapi: OA buffer polling
- uapi: remove generated perf code
- uapi: per-engine default property values in sysfs
- Tigerlake GEN12 enabled.
- Lots of gem refactoring
- Tigerlake enablement patches
- move to drm_device logging
- Icelake gamma HW readout
- push MST link retrain to hotplug work
- bandwidth atomic helpers
- ICL fixes
- RPS/GT refactoring
- Cherryview full-ppgtt support
- i915 locking guidelines documented
- require linear fb stride to be 512 multiple on gen9
- Tigerlake SAGV support
amdgpu:
- uapi: encrypted GPU memory handling
- uapi: add MEM_SYNC IB flag
- p2p dma-buf support
- export VRAM dma-bufs
- FRU chip access support
- RAS/SR-IOV updates
- Powerplay locking fixes
- VCN DPG (powergating) enablement
- GFX10 clockgating fixes
- DC fixes
- GPU reset fixes
- navi SDMA fix
- expose FP16 for modesetting
- DP 1.4 compliance fixes
- gfx10 soft recovery
- Improved Critical Thermal Faults handling
- resizable BAR on gmc10
amdkfd:
- uapi: GWS resource management
- track GPU memory per process
- report PCI domain in topology
radeon:
- safe reg list generator fixes
nouveau:
- HD audio fixes on recent systems
- vGPU detection (fail probe if we're on one, for now)
- Interlaced mode fixes (mostly avoidance on Turing, which doesn't support it)
- SVM improvements/fixes
- NVIDIA format modifier support
- Misc other fixes.
adv7511:
- HDMI SPDIF support
ast:
- allocate crtc state size
- fix double assignment
- fix suspend
bochs:
- drop connector register
cirrus:
- move to tiny drivers.
exynos:
- fix imported dma-buf mapping
- enable runtime PM
- fixes and cleanups
mediatek:
- DPI pin mode swap
- config mipi_tx current/impedance
lima:
- devfreq + cooling device support
- task handling improvements
- runtime PM support
pl111:
- vexpress init improvements
- fix module auto-load
rcar-du:
- DT bindings conversion to YAML
- Planes zpos sanity check and fix
- MAINTAINERS entry for LVDS panel driver
mcde:
- fix return value
mgag200:
- use managed config init
stm:
- read endpoints from DT
vboxvideo:
- use PCI managed functions
- drop WC mtrr
vkms:
- enable cursor by default
rockchip:
- afbc support
virtio:
- various cleanups
qxl:
- fix cursor notify port
hisilicon:
- 128-byte stride alignment fix
sun4i:
- improved format handling"
* tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm: (1401 commits)
drm/amd/display: Fix potential integer wraparound resulting in a hang
drm/amd/display: drop cursor position check in atomic test
drm/amdgpu: fix device attribute node create failed with multi gpu
drm/nouveau: use correct conflicting framebuffer API
drm/vblank: Fix -Wformat compile warnings on some arches
drm/amdgpu: Sync with VM root BO when switching VM to CPU update mode
drm/amd/display: Handle GPU reset for DC block
drm/amdgpu: add apu flags (v2)
drm/amd/powerpay: Disable gfxoff when setting manual mode on picasso and raven
drm/amdgpu: fix pm sysfs node handling (v2)
drm/amdgpu: move gpu_info parsing after common early init
drm/amdgpu: move discovery gfx config fetching
drm/nouveau/dispnv50: fix runtime pm imbalance on error
drm/nouveau: fix runtime pm imbalance on error
drm/nouveau: fix runtime pm imbalance on error
drm/nouveau/debugfs: fix runtime pm imbalance on error
drm/nouveau/nouveau/hmm: fix migrate zero page to GPU
drm/nouveau/nouveau/hmm: fix nouveau_dmem_chunk allocations
drm/nouveau/kms/nv50-: Share DP SST mode_valid() handling with MST
drm/nouveau/kms/nv50-: Move 8BPC limit for MST into nv50_mstc_get_modes()
...
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm')
6 files changed, 453 insertions, 184 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 7fc15b82fe48..bdba0bfd6df1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -30,7 +30,7 @@ #include "dc.h" #include "dc/inc/core_types.h" #include "dal_asic_id.h" -#include "dmub/inc/dmub_srv.h" +#include "dmub/dmub_srv.h" #include "dc/inc/hw/dmcu.h" #include "dc/inc/hw/abm.h" #include "dc/dc_dmub_srv.h" @@ -774,8 +774,9 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) fw_inst_const_size); } - memcpy(fb_info->fb[DMUB_WINDOW_2_BSS_DATA].cpu_addr, fw_bss_data, - fw_bss_data_size); + if (fw_bss_data_size) + memcpy(fb_info->fb[DMUB_WINDOW_2_BSS_DATA].cpu_addr, + fw_bss_data, fw_bss_data_size); /* Copy firmware bios info into FB memory. */ memcpy(fb_info->fb[DMUB_WINDOW_3_VBIOS].cpu_addr, adev->bios, @@ -917,6 +918,23 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) goto error; } + if (amdgpu_dc_debug_mask & DC_DISABLE_PIPE_SPLIT) { + adev->dm.dc->debug.force_single_disp_pipe_split = false; + adev->dm.dc->debug.pipe_split_policy = MPC_SPLIT_AVOID; + } + + if (adev->asic_type != CHIP_CARRIZO && adev->asic_type != CHIP_STONEY) + adev->dm.dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true; + + if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER) + adev->dm.dc->debug.disable_stutter = true; + + if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) + adev->dm.dc->debug.disable_dsc = true; + + if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING) + adev->dm.dc->debug.disable_clock_gate = true; + r = dm_dmub_hw_init(adev); if (r) { DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); @@ -1214,6 +1232,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) adev->dm.dmub_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes) + le32_to_cpu(hdr->inst_const_bytes); + region_params.fw_inst_const = + adev->dm.dmub_fw->data + + le32_to_cpu(hdr->header.ucode_array_offset_bytes) + + PSP_HEADER_BYTES; status = dmub_srv_calc_region_info(dmub_srv, ®ion_params, ®ion_info); @@ -1333,9 +1355,14 @@ static int dm_late_init(void *handle) struct dmcu_iram_parameters params; unsigned int linear_lut[16]; int i; - struct dmcu *dmcu = adev->dm.dc->res_pool->dmcu; + struct dmcu *dmcu = NULL; bool ret = false; + if (!adev->dm.fw_dmcu) + return detect_mst_link_for_all_connectors(adev->ddev); + + dmcu = adev->dm.dc->res_pool->dmcu; + for (i = 0; i < 16; i++) linear_lut[i] = 0xFFFF * i / 15; @@ -1511,12 +1538,115 @@ static int dm_hw_fini(void *handle) return 0; } + +static int dm_enable_vblank(struct drm_crtc *crtc); +static void dm_disable_vblank(struct drm_crtc *crtc); + +static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, + struct dc_state *state, bool enable) +{ + enum dc_irq_source irq_source; + struct amdgpu_crtc *acrtc; + int rc = -EBUSY; + int i = 0; + + for (i = 0; i < state->stream_count; i++) { + acrtc = get_crtc_by_otg_inst( + adev, state->stream_status[i].primary_otg_inst); + + if (acrtc && state->stream_status[i].plane_count != 0) { + irq_source = IRQ_TYPE_PFLIP + acrtc->otg_inst; + rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; + DRM_DEBUG("crtc %d - vupdate irq %sabling: r=%d\n", + acrtc->crtc_id, enable ? "en" : "dis", rc); + if (rc) + DRM_WARN("Failed to %s pflip interrupts\n", + enable ? "enable" : "disable"); + + if (enable) { + rc = dm_enable_vblank(&acrtc->base); + if (rc) + DRM_WARN("Failed to enable vblank interrupts\n"); + } else { + dm_disable_vblank(&acrtc->base); + } + + } + } + +} + +enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) +{ + struct dc_state *context = NULL; + enum dc_status res = DC_ERROR_UNEXPECTED; + int i; + struct dc_stream_state *del_streams[MAX_PIPES]; + int del_streams_count = 0; + + memset(del_streams, 0, sizeof(del_streams)); + + context = dc_create_state(dc); + if (context == NULL) + goto context_alloc_fail; + + dc_resource_state_copy_construct_current(dc, context); + + /* First remove from context all streams */ + for (i = 0; i < context->stream_count; i++) { + struct dc_stream_state *stream = context->streams[i]; + + del_streams[del_streams_count++] = stream; + } + + /* Remove all planes for removed streams and then remove the streams */ + for (i = 0; i < del_streams_count; i++) { + if (!dc_rem_all_planes_for_stream(dc, del_streams[i], context)) { + res = DC_FAIL_DETACH_SURFACES; + goto fail; + } + + res = dc_remove_stream_from_ctx(dc, context, del_streams[i]); + if (res != DC_OK) + goto fail; + } + + + res = dc_validate_global_state(dc, context, false); + + if (res != DC_OK) { + DRM_ERROR("%s:resource validation failed, dc_status:%d\n", __func__, res); + goto fail; + } + + res = dc_commit_state(dc, context); + +fail: + dc_release_state(context); + +context_alloc_fail: + return res; +} + static int dm_suspend(void *handle) { struct amdgpu_device *adev = handle; struct amdgpu_display_manager *dm = &adev->dm; int ret = 0; + if (adev->in_gpu_reset) { + mutex_lock(&dm->dc_lock); + dm->cached_dc_state = dc_copy_state(dm->dc->current_state); + + dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); + + amdgpu_dm_commit_zero_streams(dm->dc); + + amdgpu_dm_irq_suspend(adev); + + return ret; + } + WARN_ON(adev->dm.cached_state); adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev); @@ -1527,7 +1657,7 @@ static int dm_suspend(void *handle) dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); - return ret; + return 0; } static struct amdgpu_dm_connector * @@ -1631,6 +1761,46 @@ static void emulated_link_detect(struct dc_link *link) } +static void dm_gpureset_commit_state(struct dc_state *dc_state, + struct amdgpu_display_manager *dm) +{ + struct { + struct dc_surface_update surface_updates[MAX_SURFACES]; + struct dc_plane_info plane_infos[MAX_SURFACES]; + struct dc_scaling_info scaling_infos[MAX_SURFACES]; + struct dc_flip_addrs flip_addrs[MAX_SURFACES]; + struct dc_stream_update stream_update; + } * bundle; + int k, m; + + bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); + + if (!bundle) { + dm_error("Failed to allocate update bundle\n"); + goto cleanup; + } + + for (k = 0; k < dc_state->stream_count; k++) { + bundle->stream_update.stream = dc_state->streams[k]; + + for (m = 0; m < dc_state->stream_status->plane_count; m++) { + bundle->surface_updates[m].surface = + dc_state->stream_status->plane_states[m]; + bundle->surface_updates[m].surface->force_full_update = + true; + } + dc_commit_updates_for_stream( + dm->dc, bundle->surface_updates, + dc_state->stream_status->plane_count, + dc_state->streams[k], &bundle->stream_update, dc_state); + } + +cleanup: + kfree(bundle); + + return; +} + static int dm_resume(void *handle) { struct amdgpu_device *adev = handle; @@ -1647,8 +1817,44 @@ static int dm_resume(void *handle) struct dm_plane_state *dm_new_plane_state; struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state); enum dc_connection_type new_connection_type = dc_connection_none; - int i, r; + struct dc_state *dc_state; + int i, r, j; + + if (adev->in_gpu_reset) { + dc_state = dm->cached_dc_state; + + r = dm_dmub_hw_init(adev); + if (r) + DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); + + dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0); + dc_resume(dm->dc); + + amdgpu_dm_irq_resume_early(adev); + + for (i = 0; i < dc_state->stream_count; i++) { + dc_state->streams[i]->mode_changed = true; + for (j = 0; j < dc_state->stream_status->plane_count; j++) { + dc_state->stream_status->plane_states[j]->update_flags.raw + = 0xffffffff; + } + } + + WARN_ON(!dc_commit_state(dm->dc, dc_state)); + dm_gpureset_commit_state(dm->cached_dc_state, dm); + + dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, true); + + dc_release_state(dm->cached_dc_state); + dm->cached_dc_state = NULL; + + amdgpu_dm_irq_resume_late(adev); + + mutex_unlock(&dm->dc_lock); + + return 0; + } /* Recreate dc_state - DC invalidates it when setting power state to S3. */ dc_release_state(dm_state->context); dm_state->context = dc_create_state(dm->dc); @@ -3013,9 +3219,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) goto fail; } - if (adev->asic_type != CHIP_CARRIZO && adev->asic_type != CHIP_STONEY) - dm->dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true; - /* No userspace support. */ dm->dc->debug.disable_tri_buf = true; @@ -3286,7 +3489,7 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, } static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, - uint64_t *tiling_flags) + uint64_t *tiling_flags, bool *tmz_surface) { struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]); int r = amdgpu_bo_reserve(rbo, false); @@ -3301,6 +3504,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, if (tiling_flags) amdgpu_bo_get_tiling_flags(rbo, tiling_flags); + if (tmz_surface) + *tmz_surface = amdgpu_bo_encrypted(rbo); + amdgpu_bo_unreserve(rbo); return r; @@ -3388,6 +3594,7 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, struct plane_size *plane_size, struct dc_plane_dcc_param *dcc, struct dc_plane_address *address, + bool tmz_surface, bool force_disable_dcc) { const struct drm_framebuffer *fb = &afb->base; @@ -3398,6 +3605,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, memset(dcc, 0, sizeof(*dcc)); memset(address, 0, sizeof(*address)); + address->tmz_surface = tmz_surface; + if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { plane_size->surface_size.x = 0; plane_size->surface_size.y = 0; @@ -3588,6 +3797,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, const uint64_t tiling_flags, struct dc_plane_info *plane_info, struct dc_plane_address *address, + bool tmz_surface, bool force_disable_dcc) { const struct drm_framebuffer *fb = plane_state->fb; @@ -3631,6 +3841,14 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, case DRM_FORMAT_P010: plane_info->format = SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb; break; + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F; + break; + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: + plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F; + break; default: DRM_ERROR( "Unsupported screen format %s\n", @@ -3670,7 +3888,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, plane_info->rotation, tiling_flags, &plane_info->tiling_info, &plane_info->plane_size, - &plane_info->dcc, address, + &plane_info->dcc, address, tmz_surface, force_disable_dcc); if (ret) return ret; @@ -3694,6 +3912,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, struct dc_plane_info plane_info; uint64_t tiling_flags; int ret; + bool tmz_surface = false; bool force_disable_dcc = false; ret = fill_dc_scaling_info(plane_state, &scaling_info); @@ -3705,7 +3924,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, dc_plane_state->clip_rect = scaling_info.clip_rect; dc_plane_state->scaling_quality = scaling_info.scaling_quality; - ret = get_fb_info(amdgpu_fb, &tiling_flags); + ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface); if (ret) return ret; @@ -3713,6 +3932,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, &plane_info, &dc_plane_state->address, + tmz_surface, force_disable_dcc); if (ret) return ret; @@ -3800,8 +4020,7 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode, static enum dc_color_depth convert_color_depth_from_display_info(const struct drm_connector *connector, - const struct drm_connector_state *state, - bool is_y420) + bool is_y420, int requested_bpc) { uint8_t bpc; @@ -3821,10 +4040,7 @@ convert_color_depth_from_display_info(const struct drm_connector *connector, bpc = bpc ? bpc : 8; } - if (!state) - state = connector->state; - - if (state) { + if (requested_bpc > 0) { /* * Cap display bpc based on the user requested value. * @@ -3833,7 +4049,7 @@ convert_color_depth_from_display_info(const struct drm_connector *connector, * or if this was called outside of atomic check, so it * can't be used directly. */ - bpc = min(bpc, state->max_requested_bpc); + bpc = min_t(u8, bpc, requested_bpc); /* Round down to the nearest even number. */ bpc = bpc - (bpc & 1); @@ -3955,7 +4171,8 @@ static void fill_stream_properties_from_drm_display_mode( const struct drm_display_mode *mode_in, const struct drm_connector *connector, const struct drm_connector_state *connector_state, - const struct dc_stream_state *old_stream) + const struct dc_stream_state *old_stream, + int requested_bpc) { struct dc_crtc_timing *timing_out = &stream->timing; const struct drm_display_info *info = &connector->display_info; @@ -3985,8 +4202,9 @@ static void fill_stream_properties_from_drm_display_mode( timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE; timing_out->display_color_depth = convert_color_depth_from_display_info( - connector, connector_state, - (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420)); + connector, + (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420), + requested_bpc); timing_out->scan_type = SCANNING_TYPE_NODATA; timing_out->hdmi_vic = 0; @@ -4192,7 +4410,8 @@ static struct dc_stream_state * create_stream_for_sink(struct amdgpu_dm_connector *aconnector, const struct drm_display_mode *drm_mode, const struct dm_connector_state *dm_state, - const struct dc_stream_state *old_stream) + const struct dc_stream_state *old_stream, + int requested_bpc) { struct drm_display_mode *preferred_mode = NULL; struct drm_connector *drm_connector; @@ -4277,10 +4496,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, */ if (!scale || mode_refresh != preferred_refresh) fill_stream_properties_from_drm_display_mode(stream, - &mode, &aconnector->base, con_state, NULL); + &mode, &aconnector->base, con_state, NULL, requested_bpc); else fill_stream_properties_from_drm_display_mode(stream, - &mode, &aconnector->base, con_state, old_stream); + &mode, &aconnector->base, con_state, old_stream, requested_bpc); stream->timing.flags.DSC = 0; @@ -4317,14 +4536,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false); - if (stream->link->psr_feature_enabled) { + if (stream->link->psr_settings.psr_feature_enabled) { struct dc *core_dc = stream->link->ctx->dc; if (dc_is_dmcu_initialized(core_dc)) { - struct dmcu *dmcu = core_dc->res_pool->dmcu; - - stream->psr_version = dmcu->dmcu_version.psr_version; - // // should decide stream support vsc sdp colorimetry capability // before building vsc info packet @@ -4803,16 +5018,54 @@ static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector) create_eml_sink(aconnector); } +static struct dc_stream_state * +create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector, + const struct drm_display_mode *drm_mode, + const struct dm_connector_state *dm_state, + const struct dc_stream_state *old_stream) +{ + struct drm_connector *connector = &aconnector->base; + struct amdgpu_device *adev = connector->dev->dev_private; + struct dc_stream_state *stream; + int requested_bpc = connector->state ? connector->state->max_requested_bpc : 8; + enum dc_status dc_result = DC_OK; + + do { + stream = create_stream_for_sink(aconnector, drm_mode, + dm_state, old_stream, + requested_bpc); + if (stream == NULL) { + DRM_ERROR("Failed to create stream for sink!\n"); + break; + } + + dc_result = dc_validate_stream(adev->dm.dc, stream); + + if (dc_result != DC_OK) { + DRM_DEBUG_KMS("Mode %dx%d (clk %d) failed DC validation with error %d\n", + drm_mode->hdisplay, + drm_mode->vdisplay, + drm_mode->clock, + dc_result); + + dc_stream_release(stream); + stream = NULL; + requested_bpc -= 2; /* lower bpc to retry validation */ + } + + } while (stream == NULL && requested_bpc >= 6); + + return stream; +} + enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { int result = MODE_ERROR; struct dc_sink *dc_sink; - struct amdgpu_device *adev = connector->dev->dev_private; /* TODO: Unhardcode stream count */ struct dc_stream_state *stream; struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); - enum dc_status dc_result = DC_OK; if ((mode->flags & DRM_MODE_FLAG_INTERLACE) || (mode->flags & DRM_MODE_FLAG_DBLSCAN)) @@ -4833,24 +5086,11 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec goto fail; } - stream = create_stream_for_sink(aconnector, mode, NULL, NULL); - if (stream == NULL) { - DRM_ERROR("Failed to create stream for sink!\n"); - goto fail; - } - - dc_result = dc_validate_stream(adev->dm.dc, stream); - - if (dc_result == DC_OK) + stream = create_validate_stream_for_sink(aconnector, mode, NULL, NULL); + if (stream) { + dc_stream_release(stream); result = MODE_OK; - else - DRM_DEBUG_KMS("Mode %dx%d (clk %d) failed DC validation with error %d\n", - mode->hdisplay, - mode->vdisplay, - mode->clock, - dc_result); - - dc_stream_release(stream); + } fail: /* TODO: error handling*/ @@ -5173,10 +5413,12 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, return 0; if (!state->duplicated) { + int max_bpc = conn_state->max_requested_bpc; is_y420 = drm_mode_is_420_also(&connector->display_info, adjusted_mode) && aconnector->force_yuv420_output; - color_depth = convert_color_depth_from_display_info(connector, conn_state, - is_y420); + color_depth = convert_color_depth_from_display_info(connector, + is_y420, + max_bpc); bpp = convert_dc_color_depth_into_bpc(color_depth) * 3; clock = adjusted_mode->clock; dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false); @@ -5331,6 +5573,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, uint64_t tiling_flags; uint32_t domain; int r; + bool tmz_surface = false; bool force_disable_dcc = false; dm_plane_state_old = to_dm_plane_state(plane->state); @@ -5380,6 +5623,8 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); + tmz_surface = amdgpu_bo_encrypted(rbo); + ttm_eu_backoff_reservation(&ticket, &list); afb->address = amdgpu_bo_gpu_offset(rbo); @@ -5395,7 +5640,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, adev, afb, plane_state->format, plane_state->rotation, tiling_flags, &plane_state->tiling_info, &plane_state->plane_size, &plane_state->dcc, - &plane_state->address, + &plane_state->address, tmz_surface, force_disable_dcc); } @@ -5542,6 +5787,12 @@ static int get_plane_formats(const struct drm_plane *plane, formats[num_formats++] = DRM_FORMAT_NV12; if (plane_cap && plane_cap->pixel_format_support.p010) formats[num_formats++] = DRM_FORMAT_P010; + if (plane_cap && plane_cap->pixel_format_support.fp16) { + formats[num_formats++] = DRM_FORMAT_XRGB16161616F; + formats[num_formats++] = DRM_FORMAT_ARGB16161616F; + formats[num_formats++] = DRM_FORMAT_XBGR16161616F; + formats[num_formats++] = DRM_FORMAT_ABGR16161616F; + } break; case DRM_PLANE_TYPE_OVERLAY: @@ -6569,6 +6820,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, unsigned long flags; struct amdgpu_bo *abo; uint64_t tiling_flags; + bool tmz_surface = false; uint32_t target_vblank, last_flip_vblank; bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); bool pflip_present = false; @@ -6621,6 +6873,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, if (new_pcrtc_state->color_mgmt_changed) { bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction; bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func; + bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix; } fill_dc_scaling_info(new_plane_state, @@ -6663,12 +6916,15 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, amdgpu_bo_get_tiling_flags(abo, &tiling_flags); + tmz_surface = amdgpu_bo_encrypted(abo); + amdgpu_bo_unreserve(abo); fill_dc_plane_info_and_addr( dm->adev, new_plane_state, tiling_flags, &bundle->plane_infos[planes_count], &bundle->flip_addrs[planes_count].address, + tmz_surface, false); DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", @@ -6814,7 +7070,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, } mutex_lock(&dm->dc_lock); if ((acrtc_state->update_type > UPDATE_TYPE_FAST) && - acrtc_state->stream->link->psr_allow_active) + acrtc_state->stream->link->psr_settings.psr_allow_active) amdgpu_dm_psr_disable(acrtc_state->stream); dc_commit_updates_for_stream(dm->dc, @@ -6825,12 +7081,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, dc_state); if ((acrtc_state->update_type > UPDATE_TYPE_FAST) && - acrtc_state->stream->psr_version && - !acrtc_state->stream->link->psr_feature_enabled) + acrtc_state->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED && + !acrtc_state->stream->link->psr_settings.psr_feature_enabled) amdgpu_dm_link_setup_psr(acrtc_state->stream); else if ((acrtc_state->update_type == UPDATE_TYPE_FAST) && - acrtc_state->stream->link->psr_feature_enabled && - !acrtc_state->stream->link->psr_allow_active) { + acrtc_state->stream->link->psr_settings.psr_feature_enabled && + !acrtc_state->stream->link->psr_settings.psr_allow_active) { amdgpu_dm_psr_enable(acrtc_state->stream); } @@ -7144,7 +7400,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) DRM_DEBUG_DRIVER("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc); /* i.e. reset mode */ if (dm_old_crtc_state->stream) { - if (dm_old_crtc_state->stream->link->psr_allow_active) + if (dm_old_crtc_state->stream->link->psr_settings.psr_allow_active) amdgpu_dm_psr_disable(dm_old_crtc_state->stream); remove_stream(adev, acrtc, dm_old_crtc_state->stream); @@ -7592,10 +7848,10 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) goto skip_modeset; - new_stream = create_stream_for_sink(aconnector, - &new_crtc_state->mode, - dm_new_conn_state, - dm_old_crtc_state->stream); + new_stream = create_validate_stream_for_sink(aconnector, + &new_crtc_state->mode, + dm_new_conn_state, + dm_old_crtc_state->stream); /* * we can have no stream on ACTION_SET if a display @@ -8056,6 +8312,7 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, struct dc_flip_addrs *flip_addr = &bundle->flip_addrs[num_plane]; struct dc_scaling_info *scaling_info = &bundle->scaling_infos[num_plane]; uint64_t tiling_flags; + bool tmz_surface = false; new_plane_crtc = new_plane_state->crtc; new_dm_plane_state = to_dm_plane_state(new_plane_state); @@ -8085,6 +8342,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, new_dm_plane_state->dc_state->gamma_correction; bundle->surface_updates[num_plane].in_transfer_func = new_dm_plane_state->dc_state->in_transfer_func; + bundle->surface_updates[num_plane].gamut_remap_matrix = + &new_dm_plane_state->dc_state->gamut_remap_matrix; bundle->stream_update.gamut_remap = &new_dm_crtc_state->stream->gamut_remap_matrix; bundle->stream_update.output_csc_transform = @@ -8101,14 +8360,14 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, bundle->surface_updates[num_plane].scaling_info = scaling_info; if (amdgpu_fb) { - ret = get_fb_info(amdgpu_fb, &tiling_flags); + ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface); if (ret) goto cleanup; ret = fill_dc_plane_info_and_addr( dm->adev, new_plane_state, tiling_flags, plane_info, - &flip_addr->address, + &flip_addr->address, tmz_surface, false); if (ret) goto cleanup; @@ -8609,8 +8868,17 @@ static void amdgpu_dm_set_psr_caps(struct dc_link *link) return; if (dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT, dpcd_data, sizeof(dpcd_data))) { - link->psr_feature_enabled = dpcd_data[0] ? true:false; - DRM_INFO("PSR support:%d\n", link->psr_feature_enabled); + link->dpcd_caps.psr_caps.psr_version = dpcd_data[0]; + + if (dpcd_data[0] == 0) { + link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; + link->psr_settings.psr_feature_enabled = false; + } else { + link->psr_settings.psr_version = DC_PSR_VERSION_1; + link->psr_settings.psr_feature_enabled = true; + } + + DRM_INFO("PSR support:%d\n", link->psr_settings.psr_feature_enabled); } } @@ -8625,16 +8893,14 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream) struct dc_link *link = NULL; struct psr_config psr_config = {0}; struct psr_context psr_context = {0}; - struct dc *dc = NULL; bool ret = false; if (stream == NULL) return false; link = stream->link; - dc = link->ctx->dc; - psr_config.psr_version = dc->res_pool->dmcu->dmcu_version.psr_version; + psr_config.psr_version = link->dpcd_caps.psr_caps.psr_version; if (psr_config.psr_version > 0) { psr_config.psr_exit_link_training_required = 0x1; @@ -8646,7 +8912,7 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream) ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context); } - DRM_DEBUG_DRIVER("PSR link: %d\n", link->psr_feature_enabled); + DRM_DEBUG_DRIVER("PSR link: %d\n", link->psr_settings.psr_feature_enabled); return ret; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 5cab3e65d992..d61186ff411d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -315,6 +315,7 @@ struct amdgpu_display_manager { #endif struct drm_atomic_state *cached_state; + struct dc_state *cached_dc_state; struct dm_comressor_info compressor; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index 2233d293a707..4dfb6b55bb2e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -239,7 +239,8 @@ static int __set_output_tf(struct dc_transfer_func *func, * instead to simulate this. */ gamma->type = GAMMA_CUSTOM; - res = mod_color_calculate_degamma_params(func, gamma, true); + res = mod_color_calculate_degamma_params(NULL, func, + gamma, true); } else { /* * Assume sRGB. The actual mapping will depend on whether the @@ -271,7 +272,7 @@ static int __set_input_tf(struct dc_transfer_func *func, __drm_lut_to_dc_gamma(lut, gamma, false); - res = mod_color_calculate_degamma_params(func, gamma, true); + res = mod_color_calculate_degamma_params(NULL, func, gamma, true); dc_gamma_release(&gamma); return res ? 0 : -ENOMEM; @@ -419,9 +420,21 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, struct dc_plane_state *dc_plane_state) { const struct drm_color_lut *degamma_lut; + enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; uint32_t degamma_size; int r; + /* Get the correct base transfer function for implicit degamma. */ + switch (dc_plane_state->format) { + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: + /* DC doesn't have a transfer function for BT601 specifically. */ + tf = TRANSFER_FUNCTION_BT709; + break; + default: + break; + } + if (crtc->cm_has_degamma) { degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, °amma_size); @@ -455,8 +468,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, * map these to the atomic one instead. */ if (crtc->cm_is_degamma_srgb) - dc_plane_state->in_transfer_func->tf = - TRANSFER_FUNCTION_SRGB; + dc_plane_state->in_transfer_func->tf = tf; else dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; @@ -471,7 +483,12 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, * in linear space. Assume that the input is sRGB. */ dc_plane_state->in_transfer_func->type = TF_TYPE_PREDEFINED; - dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_SRGB; + dc_plane_state->in_transfer_func->tf = tf; + + if (tf != TRANSFER_FUNCTION_SRGB && + !mod_color_calculate_degamma_params(NULL, + dc_plane_state->in_transfer_func, NULL, false)) + return -ENOMEM; } else { /* ...Otherwise we can just bypass the DGM block. */ dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 0461fecd68db..076af267b488 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -32,7 +32,7 @@ #include "amdgpu_dm.h" #include "amdgpu_dm_debugfs.h" #include "dm_helpers.h" -#include "dmub/inc/dmub_srv.h" +#include "dmub/dmub_srv.h" struct dmub_debugfs_trace_header { uint32_t entry_count; @@ -838,6 +838,44 @@ static int vrr_range_show(struct seq_file *m, void *data) return 0; } +#ifdef CONFIG_DRM_AMD_DC_HDCP +/* + * Returns the HDCP capability of the Display (1.4 for now). + * + * NOTE* Not all HDMI displays report their HDCP caps even when they are capable. + * Since its rare for a display to not be HDCP 1.4 capable, we set HDMI as always capable. + * + * Example usage: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability + * or cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability + */ +static int hdcp_sink_capability_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + bool hdcp_cap, hdcp2_cap; + + if (connector->status != connector_status_connected) + return -ENODEV; + + seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id); + + hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link); + hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link); + + + if (hdcp_cap) + seq_printf(m, "%s ", "HDCP1.4"); + if (hdcp2_cap) + seq_printf(m, "%s ", "HDCP2.2"); + + if (!hdcp_cap && !hdcp2_cap) + seq_printf(m, "%s ", "None"); + + seq_puts(m, "\n"); + + return 0; +} +#endif /* function description * * generic SDP message access for testing @@ -964,6 +1002,9 @@ DEFINE_SHOW_ATTRIBUTE(dmub_fw_state); DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer); DEFINE_SHOW_ATTRIBUTE(output_bpc); DEFINE_SHOW_ATTRIBUTE(vrr_range); +#ifdef CONFIG_DRM_AMD_DC_HDCP +DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability); +#endif static const struct file_operations dp_link_settings_debugfs_fops = { .owner = THIS_MODULE, @@ -1019,12 +1060,23 @@ static const struct { {"test_pattern", &dp_phy_test_pattern_fops}, {"output_bpc", &output_bpc_fops}, {"vrr_range", &vrr_range_fops}, +#ifdef CONFIG_DRM_AMD_DC_HDCP + {"hdcp_sink_capability", &hdcp_sink_capability_fops}, +#endif {"sdp_message", &sdp_message_fops}, {"aux_dpcd_address", &dp_dpcd_address_debugfs_fops}, {"aux_dpcd_size", &dp_dpcd_size_debugfs_fops}, {"aux_dpcd_data", &dp_dpcd_data_debugfs_fops} }; +#ifdef CONFIG_DRM_AMD_DC_HDCP +static const struct { + char *name; + const struct file_operations *fops; +} hdmi_debugfs_entries[] = { + {"hdcp_sink_capability", &hdcp_sink_capability_fops} +}; +#endif /* * Force YUV420 output if available from the given mode */ @@ -1093,6 +1145,15 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) connector->debugfs_dpcd_address = 0; connector->debugfs_dpcd_size = 0; +#ifdef CONFIG_DRM_AMD_DC_HDCP + if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) { + for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) { + debugfs_create_file(hdmi_debugfs_entries[i].name, + 0644, dir, connector, + hdmi_debugfs_entries[i].fops); + } + } +#endif } /* @@ -1167,8 +1228,9 @@ static int current_backlight_read(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; struct amdgpu_device *adev = dev->dev_private; - struct dc *dc = adev->dm.dc; - unsigned int backlight = dc_get_current_backlight_pwm(dc); + struct amdgpu_display_manager *dm = &adev->dm; + + unsigned int backlight = dc_link_get_backlight_level(dm->backlight_link); seq_printf(m, "0x%x\n", backlight); return 0; @@ -1184,8 +1246,9 @@ static int target_backlight_read(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; struct amdgpu_device *adev = dev->dev_private; - struct dc *dc = adev->dm.dc; - unsigned int backlight = dc_get_target_backlight_pwm(dc); + struct amdgpu_display_manager *dm = &adev->dm; + + unsigned int backlight = dc_link_get_target_backlight_pwm(dm->backlight_link); seq_printf(m, "0x%x\n", backlight); return 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index c20fb08c450b..b086d5c906e0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -445,7 +445,7 @@ bool dm_helpers_dp_read_dpcd( struct amdgpu_dm_connector *aconnector = link->priv; if (!aconnector) { - DRM_ERROR("Failed to find connector for link!"); + DC_LOG_DC("Failed to find connector for link!\n"); return false; } @@ -554,6 +554,7 @@ enum dc_edid_status dm_helpers_read_local_edid( struct dc_sink *sink) { struct amdgpu_dm_connector *aconnector = link->priv; + struct drm_connector *connector = &aconnector->base; struct i2c_adapter *ddc; int retry = 3; enum dc_edid_status edid_status; @@ -571,6 +572,15 @@ enum dc_edid_status dm_helpers_read_local_edid( edid = drm_get_edid(&aconnector->base, ddc); + /* DP Compliance Test 4.2.2.6 */ + if (link->aux_mode && connector->edid_corrupt) + drm_dp_send_real_edid_checksum(&aconnector->dm_dp_aux.aux, connector->real_edid_checksum); + + if (!edid && connector->edid_corrupt) { + connector->edid_corrupt = false; + return EDID_BAD_CHECKSUM; + } + if (!edid) return EDID_NO_RESPONSE; @@ -605,34 +615,10 @@ enum dc_edid_status dm_helpers_read_local_edid( DRM_ERROR("EDID err: %d, on connector: %s", edid_status, aconnector->base.name); - if (link->aux_mode) { - union test_request test_request = { {0} }; - union test_response test_response = { {0} }; - - dm_helpers_dp_read_dpcd(ctx, - link, - DP_TEST_REQUEST, - &test_request.raw, - sizeof(union test_request)); - - if (!test_request.bits.EDID_READ) - return edid_status; - test_response.bits.EDID_CHECKSUM_WRITE = 1; - - dm_helpers_dp_write_dpcd(ctx, - link, - DP_TEST_EDID_CHECKSUM, - &sink->dc_edid.raw_edid[sink->dc_edid.length-1], - 1); - - dm_helpers_dp_write_dpcd(ctx, - link, - DP_TEST_RESPONSE, - &test_response.raw, - sizeof(test_response)); - - } + /* DP Compliance Test 4.2.2.3 */ + if (link->aux_mode) + drm_dp_send_real_edid_checksum(&aconnector->dm_dp_aux.aux, sink->dc_edid.raw_edid[sink->dc_edid.length-1]); return edid_status; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index d2917759b7ab..ae0a7ef1d595 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -41,53 +41,10 @@ #include "amdgpu_dm_debugfs.h" #endif - #if defined(CONFIG_DRM_AMD_DC_DCN) #include "dc/dcn20/dcn20_resource.h" #endif -/* #define TRACE_DPCD */ - -#ifdef TRACE_DPCD -#define SIDE_BAND_MSG(address) (address >= DP_SIDEBAND_MSG_DOWN_REQ_BASE && address < DP_SINK_COUNT_ESI) - -static inline char *side_band_msg_type_to_str(uint32_t address) -{ - static char str[10] = {0}; - - if (address < DP_SIDEBAND_MSG_UP_REP_BASE) - strcpy(str, "DOWN_REQ"); - else if (address < DP_SIDEBAND_MSG_DOWN_REP_BASE) - strcpy(str, "UP_REP"); - else if (address < DP_SIDEBAND_MSG_UP_REQ_BASE) - strcpy(str, "DOWN_REP"); - else - strcpy(str, "UP_REQ"); - - return str; -} - -static void log_dpcd(uint8_t type, - uint32_t address, - uint8_t *data, - uint32_t size, - bool res) -{ - DRM_DEBUG_KMS("Op: %s, addr: %04x, SideBand Msg: %s, Op res: %s\n", - (type == DP_AUX_NATIVE_READ) || - (type == DP_AUX_I2C_READ) ? - "Read" : "Write", - address, - SIDE_BAND_MSG(address) ? - side_band_msg_type_to_str(address) : "Nop", - res ? "OK" : "Fail"); - - if (res) { - print_hex_dump(KERN_INFO, "Body: ", DUMP_PREFIX_NONE, 16, 1, data, size, false); - } -} -#endif - static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { @@ -136,17 +93,23 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, static void dm_dp_mst_connector_destroy(struct drm_connector *connector) { - struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); - struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder; + struct amdgpu_dm_connector *aconnector = + to_amdgpu_dm_connector(connector); + struct amdgpu_encoder *amdgpu_encoder = aconnector->mst_encoder; - kfree(amdgpu_dm_connector->edid); - amdgpu_dm_connector->edid = NULL; + if (aconnector->dc_sink) { + dc_link_remove_remote_sink(aconnector->dc_link, + aconnector->dc_sink); + dc_sink_release(aconnector->dc_sink); + } + + kfree(aconnector->edid); drm_encoder_cleanup(&amdgpu_encoder->base); kfree(amdgpu_encoder); drm_connector_cleanup(connector); - drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port); - kfree(amdgpu_dm_connector); + drm_dp_mst_put_port_malloc(aconnector->port); + kfree(aconnector); } static int @@ -435,40 +398,13 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, */ amdgpu_dm_connector_funcs_reset(connector); - DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", - aconnector, connector->base.id, aconnector->mst_port); - drm_dp_mst_get_port_malloc(port); - DRM_DEBUG_KMS(":%d\n", connector->base.id); - return connector; } -static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, - struct drm_connector *connector) -{ - struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); - - DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", - aconnector, connector->base.id, aconnector->mst_port); - - if (aconnector->dc_sink) { - amdgpu_dm_update_freesync_caps(connector, NULL); - dc_link_remove_remote_sink(aconnector->dc_link, - aconnector->dc_sink); - dc_sink_release(aconnector->dc_sink); - aconnector->dc_sink = NULL; - aconnector->dc_link->cur_link_settings.lane_count = 0; - } - - drm_connector_unregister(connector); - drm_connector_put(connector); -} - static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { .add_connector = dm_dp_add_mst_connector, - .destroy_connector = dm_dp_destroy_mst_connector, }; void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, |