mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
synced 2026-04-18 06:33:43 -04:00
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()
...
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user