mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
drm fixes for 7.3-rc3
drm_exec: - fix 0 object handling sched: - null ptr deref fix in kunit tests amdgpu: - Freesync fix - GPUVM fix - Debugfs fixes - HDMI fixes - IPS fix - GPU reset fix - RGB quantization fixes - SMU 13.0.x fixes xe: - runtime PM guard fix - cache flushing fix i915: - Fix a memleak on perf config query error path - Fix UHBR SST SDP splitting when sink doesn't support it bridge: - fix ti-sn65dsi83 error handling - tc358768: Enforce input bus flags via atomic_check ast: - fix blend mode property on cursor plane qxl: - fix blend mode property on primary/cursor planes virtio: - fix blend mode property on cursor plane vboxvideo: - fix blend mode property on planes rockchip: - fix endpoint name length - fix Kconfig issues ivpu: - limit firmware log prints to field size - validate buffer range in ivpu address translation - validate fw log buffers ethosu: - ensure SRAM sizing - ensure cmd stream formatting - drop IRQF_SHARED - fix open return value adp: - fix Kconfig logicvc: - fix Kconfig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmqkZ3gACgkQDHTzWXnE hr73LQ//YciKV7q62r31apitbxB/pffXWbQsKZU3FtBBUwyPvuO0R1iyQiaxN71O DqVqSBpnRf2SjAyyF0YAon1hmOcbkiDli1oZ3X8I20C1llGcTCzT8mYjnFejFBoX ScqBO3iwdKEI6vrSBy9SJjnL6h2OBhPaE8EH3tZVko5OalpLwnUyLP4UffX25sIF 2kN904rA5yaBSdnMGry2I819m85K9I+kx321u08LaUlXUzJa28uPWm2rPsSSWRj5 HB83FIIYe5z2DH2GyBQJa6XP/oP3ysbra68wfB34mHrfjgGxQVgoe1oY1ERcqlo1 V4a/N0lJCvjEPAfTQ+jO28wj1H4my7YPDekv+iA9mBETM0sUKTb63KTt95L44Ap+ I6OyommsHZAcMDWvvRW5Q1DlQ5DRCYUSUhvSan6WzxtFueobwhl+SpJ3EHLevDIy xmlnoG6qV5YHYiw9CG+95+Y69N8kj9FffNvAdE/Db/5JyMTlhC2sagLAAJC4z54X BlGS96yRzJm9spmGctzCTMFCfgDDR7TqSSi6pPMazFB4vLpmkfr7xZ7C54Gerrjp Q4lWW/MoS+wSpzZuGa7EZq8e65dTRdDo5TgpOMI6qS8uYfaidNsU9lG6x8/xRDKD elniWmhe2b49RwoAUXQz7IIDFR3gzbo8MxI1ikCtyOfE7fIKCBI= =WQ9l -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2026-09-12' of https://gitlab.freedesktop.org/drm/kernel Pull drm fixes from Dave Airlie: "Weekly fixes pull, this seems relatively quiet for the new world, scattered fixes, mostly amdgpu leading the way, but lots of minor fixes in other drivers. drm_exec: - fix 0 object handling sched: - null ptr deref fix in kunit tests amdgpu: - Freesync fix - GPUVM fix - Debugfs fixes - HDMI fixes - IPS fix - GPU reset fix - RGB quantization fixes - SMU 13.0.x fixes xe: - runtime PM guard fix - cache flushing fix i915: - Fix a memleak on perf config query error path - Fix UHBR SST SDP splitting when sink doesn't support it bridge: - fix ti-sn65dsi83 error handling - tc358768: Enforce input bus flags via atomic_check ast: - fix blend mode property on cursor plane qxl: - fix blend mode property on primary/cursor planes virtio: - fix blend mode property on cursor plane vboxvideo: - fix blend mode property on planes rockchip: - fix endpoint name length - fix Kconfig issues ivpu: - limit firmware log prints to field size - validate buffer range in ivpu address translation - validate fw log buffers ethosu: - ensure SRAM sizing - ensure cmd stream formatting - drop IRQF_SHARED - fix open return value adp: - fix Kconfig logicvc: - fix Kconfig" * tag 'drm-fixes-2026-09-12' of https://gitlab.freedesktop.org/drm/kernel: (38 commits) drm/amd/pm: report energy accumulator for smu 13.0.0 drm/amd/pm: fix gpu metrics energy accumulator for smu 13.0.0/13.0.7 drm/amd/display: Rebuild InfoFrames on output color space changes drm/amd/display: Honor Broadcast RGB for BT.2020 RGB output drm/amd/display: Propagate HDMI RGB quantization selectability Revert "drm/amdgpu: debugfs: avoid extra EOLs in amdgpu_gem_info" drm/amdgpu: skip gfx switch_power_profile during GPU reset drm/amd/display: Fix HF-VSDB DSC bpc detection to be cumulative drm/amd/display: Exit IPS before connector detection on resume drm/amd/display: Shorten hdmi_frl_status_polling_workqueue dm/amdgpu: fix malformed link_settings debugfs output drm/amdgpu: skip the VMID 0 flush for VRAM drm/amd/display: Consult MCCS FreeSync cap only if requested & supported drm/i915: Fix memory leak in query_perf_config_list() drm/i915/dp: Gate UHBR SST SDP splitting on sink capability drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches drm/xe: Guard page-fault worker with runtime PM check drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() drm/bridge: tc358768: Enforce input bus flags via atomic_check drm/drm_exec: fix up contended obj when num_objects is 0 ...
This commit is contained in:
commit
525f0f99a4
|
|
@ -87,6 +87,7 @@ struct gen_pool;
|
|||
#define PMU_EV_TYPE_IDLE 0x20
|
||||
|
||||
enum ethosu_cmds {
|
||||
NPU_OP_STOP = 0x0,
|
||||
NPU_OP_CONV = 0x2,
|
||||
NPU_OP_DEPTHWISE = 0x3,
|
||||
NPU_OP_POOL = 0x5,
|
||||
|
|
|
|||
|
|
@ -281,8 +281,6 @@ static int ethosu_device_suspend(struct device *dev)
|
|||
|
||||
static int ethosu_sram_init(struct ethosu_device *ethosudev)
|
||||
{
|
||||
ethosudev->npu_info.sram_size = 0;
|
||||
|
||||
ethosudev->srampool = of_gen_pool_get(ethosudev->base.dev->of_node, "sram", 0);
|
||||
if (!ethosudev->srampool)
|
||||
return 0;
|
||||
|
|
@ -293,6 +291,7 @@ static int ethosu_sram_init(struct ethosu_device *ethosudev)
|
|||
ethosudev->npu_info.sram_size,
|
||||
ðosudev->sramphys);
|
||||
if (!ethosudev->sram) {
|
||||
ethosudev->npu_info.sram_size = 0;
|
||||
dev_err(ethosudev->base.dev, "failed to allocate from SRAM pool\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -390,6 +390,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
struct ethosu_validated_cmdstream_info __free(kfree) *info = kzalloc_obj(*info);
|
||||
struct ethosu_device *edev = to_ethosu_device(ddev);
|
||||
u32 *bocmds = bo->base.vaddr;
|
||||
bool ends_with_stop = false;
|
||||
struct cmd_state st;
|
||||
int i, ret;
|
||||
|
||||
|
|
@ -426,6 +427,11 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
}
|
||||
|
||||
switch (cmd) {
|
||||
case NPU_OP_STOP:
|
||||
if (i != size / 4 - 1)
|
||||
return -EINVAL;
|
||||
ends_with_stop = true;
|
||||
break;
|
||||
case NPU_OP_DMA_START:
|
||||
srclen = dma_length(info, &st.dma, &st.dma.src);
|
||||
dstlen = dma_length(info, &st.dma, &st.dma.dst);
|
||||
|
|
@ -688,6 +694,9 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
}
|
||||
}
|
||||
|
||||
if (!ends_with_stop)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < NPU_BASEP_REGION_MAX; i++) {
|
||||
if (!info->region_size[i])
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ int ethosu_job_init(struct ethosu_device *edev)
|
|||
ret = devm_request_threaded_irq(dev, edev->irq,
|
||||
ethosu_job_irq_handler,
|
||||
ethosu_job_irq_handler_thread,
|
||||
IRQF_SHARED, KBUILD_MODNAME,
|
||||
0, KBUILD_MODNAME,
|
||||
edev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to request irq\n");
|
||||
|
|
@ -374,12 +374,10 @@ int ethosu_job_open(struct ethosu_file_priv *ethosu_priv)
|
|||
{
|
||||
struct ethosu_device *dev = ethosu_priv->edev;
|
||||
struct drm_gpu_scheduler *sched = &dev->sched;
|
||||
int ret;
|
||||
|
||||
ret = drm_sched_entity_init(ðosu_priv->sched_entity,
|
||||
DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
return WARN_ON(ret);
|
||||
return drm_sched_entity_init(ðosu_priv->sched_entity,
|
||||
DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
}
|
||||
|
||||
void ethosu_job_close(struct ethosu_file_priv *ethosu_priv)
|
||||
|
|
@ -449,13 +447,13 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file
|
|||
if (!cmd_info->region_size[i])
|
||||
continue;
|
||||
if (i == ETHOSU_SRAM_REGION) {
|
||||
if (cmd_info->region_size[i] <= edev->npu_info.sram_size)
|
||||
if (cmd_info->region_size[i] <= ejob->sram_size)
|
||||
continue;
|
||||
|
||||
dev_err(dev->dev,
|
||||
"cmd stream region %d size greater than SRAM size (%llu > %u)\n",
|
||||
"cmd stream region %d size greater than job SRAM size (%llu > %u)\n",
|
||||
i, cmd_info->region_size[i],
|
||||
edev->npu_info.sram_size);
|
||||
ejob->sram_size);
|
||||
ret = -EINVAL;
|
||||
goto out_cleanup_job;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,17 @@ MODULE_PARM_DESC(fw_log_level,
|
|||
" error=" __stringify(IVPU_FW_LOG_ERROR)
|
||||
" fatal=" __stringify(IVPU_FW_LOG_FATAL));
|
||||
|
||||
struct ivpu_fw_log_desc {
|
||||
struct vpu_tracing_buffer_header *log;
|
||||
u32 header_size;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset,
|
||||
struct vpu_tracing_buffer_header **out_log)
|
||||
struct ivpu_fw_log_desc *desc)
|
||||
{
|
||||
struct vpu_tracing_buffer_header *log;
|
||||
u32 header_size, size;
|
||||
|
||||
if ((*offset + sizeof(*log)) > ivpu_bo_size(bo))
|
||||
return -EINVAL;
|
||||
|
|
@ -39,26 +46,32 @@ static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *off
|
|||
if (log->vpu_canary_start != VPU_TRACING_BUFFER_CANARY)
|
||||
return -EINVAL;
|
||||
|
||||
if (log->header_size < sizeof(*log) || log->header_size > 1024) {
|
||||
ivpu_dbg(vdev, FW_BOOT, "Invalid header size 0x%x\n", log->header_size);
|
||||
header_size = READ_ONCE(log->header_size);
|
||||
size = READ_ONCE(log->size);
|
||||
|
||||
if (header_size < sizeof(*log) || header_size > 1024) {
|
||||
ivpu_dbg(vdev, FW_BOOT, "Invalid header size 0x%x\n", header_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (log->size < log->header_size) {
|
||||
ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size);
|
||||
if ((char *)log + size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) {
|
||||
ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", size);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((char *)log + log->size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) {
|
||||
ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size);
|
||||
if (size < header_size) {
|
||||
ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x < header size 0x%x\n",
|
||||
size, header_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*out_log = log;
|
||||
*offset += log->size;
|
||||
desc->log = log;
|
||||
desc->header_size = header_size;
|
||||
desc->size = size;
|
||||
*offset += size;
|
||||
|
||||
ivpu_dbg(vdev, FW_BOOT,
|
||||
"FW log name \"%s\", write offset 0x%x size 0x%x, wrap count %d, hdr version %d size %d format %d, alignment %d",
|
||||
log->name, log->write_index, log->size, log->wrap_count, log->header_version,
|
||||
log->header_size, log->format, log->alignment);
|
||||
"FW log name \"%.*s\", write offset 0x%x size 0x%x, wrap count %d, hdr version %d size %d format %d, alignment %d",
|
||||
(int)ARRAY_SIZE(log->name), log->name, log->write_index, size, log->wrap_count,
|
||||
log->header_version, header_size, log->format, log->alignment);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -94,11 +107,12 @@ static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p)
|
|||
drm_printf(p, "%s", line);
|
||||
}
|
||||
|
||||
static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix,
|
||||
static void fw_log_print_buffer(struct ivpu_fw_log_desc *desc, const char *prefix,
|
||||
bool only_new_msgs, struct drm_printer *p)
|
||||
{
|
||||
char *log_data = (void *)log + log->header_size;
|
||||
u32 data_size = log->size - log->header_size;
|
||||
struct vpu_tracing_buffer_header *log = desc->log;
|
||||
char *log_data = (void *)log + desc->header_size;
|
||||
u32 data_size = desc->size - desc->header_size;
|
||||
u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0;
|
||||
u32 log_end = READ_ONCE(log->write_index);
|
||||
|
||||
|
|
@ -109,7 +123,8 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha
|
|||
|
||||
if (log->wrap_count == log->read_wrap_count) {
|
||||
if (log_end <= log_start) {
|
||||
drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name);
|
||||
drm_printf(p, "==== %s \"%.*s\" log empty ====\n", prefix,
|
||||
(int)ARRAY_SIZE(log->name), log->name);
|
||||
return;
|
||||
}
|
||||
} else if (log->wrap_count == log->read_wrap_count + 1) {
|
||||
|
|
@ -119,7 +134,8 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha
|
|||
log_start = log_end;
|
||||
}
|
||||
|
||||
drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name);
|
||||
drm_printf(p, "==== %s \"%.*s\" log start ====\n", prefix, (int)ARRAY_SIZE(log->name),
|
||||
log->name);
|
||||
if (log_end > log_start) {
|
||||
fw_log_print_lines(log_data + log_start, log_end - log_start, p);
|
||||
} else {
|
||||
|
|
@ -127,18 +143,19 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha
|
|||
fw_log_print_lines(log_data, log_end, p);
|
||||
}
|
||||
drm_printf(p, "\n\x1b[0m"); /* add new line and clear formatting */
|
||||
drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name);
|
||||
drm_printf(p, "==== %s \"%.*s\" log end ====\n", prefix, (int)ARRAY_SIZE(log->name),
|
||||
log->name);
|
||||
}
|
||||
|
||||
static void
|
||||
fw_log_print_all_in_bo(struct ivpu_device *vdev, const char *name,
|
||||
struct ivpu_bo *bo, bool only_new_msgs, struct drm_printer *p)
|
||||
{
|
||||
struct vpu_tracing_buffer_header *log;
|
||||
struct ivpu_fw_log_desc desc;
|
||||
u32 next = 0;
|
||||
|
||||
while (fw_log_from_bo(vdev, bo, &next, &log) == 0)
|
||||
fw_log_print_buffer(log, name, only_new_msgs, p);
|
||||
while (fw_log_from_bo(vdev, bo, &next, &desc) == 0)
|
||||
fw_log_print_buffer(&desc, name, only_new_msgs, p);
|
||||
}
|
||||
|
||||
void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p)
|
||||
|
|
@ -149,36 +166,36 @@ void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_
|
|||
|
||||
void ivpu_fw_log_mark_read(struct ivpu_device *vdev)
|
||||
{
|
||||
struct vpu_tracing_buffer_header *log;
|
||||
struct ivpu_fw_log_desc desc;
|
||||
u32 next;
|
||||
|
||||
next = 0;
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) {
|
||||
log->read_index = READ_ONCE(log->write_index);
|
||||
log->read_wrap_count = READ_ONCE(log->wrap_count);
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &desc) == 0) {
|
||||
desc.log->read_index = READ_ONCE(desc.log->write_index);
|
||||
desc.log->read_wrap_count = READ_ONCE(desc.log->wrap_count);
|
||||
}
|
||||
|
||||
next = 0;
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) {
|
||||
log->read_index = READ_ONCE(log->write_index);
|
||||
log->read_wrap_count = READ_ONCE(log->wrap_count);
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &desc) == 0) {
|
||||
desc.log->read_index = READ_ONCE(desc.log->write_index);
|
||||
desc.log->read_wrap_count = READ_ONCE(desc.log->wrap_count);
|
||||
}
|
||||
}
|
||||
|
||||
void ivpu_fw_log_reset(struct ivpu_device *vdev)
|
||||
{
|
||||
struct vpu_tracing_buffer_header *log;
|
||||
struct ivpu_fw_log_desc desc;
|
||||
u32 next;
|
||||
|
||||
next = 0;
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) {
|
||||
log->read_index = 0;
|
||||
log->read_wrap_count = 0;
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &desc) == 0) {
|
||||
desc.log->read_index = 0;
|
||||
desc.log->read_wrap_count = 0;
|
||||
}
|
||||
|
||||
next = 0;
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) {
|
||||
log->read_index = 0;
|
||||
log->read_wrap_count = 0;
|
||||
while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &desc) == 0) {
|
||||
desc.log->read_index = 0;
|
||||
desc.log->read_wrap_count = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,15 +87,23 @@ static inline bool ivpu_bo_is_resident(struct ivpu_bo *bo)
|
|||
return !!bo->base.pages;
|
||||
}
|
||||
|
||||
static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
|
||||
static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u64 vpu_addr, u64 size)
|
||||
{
|
||||
u64 bo_size = ivpu_bo_size(bo);
|
||||
u64 offset;
|
||||
|
||||
if (vpu_addr < bo->vpu_addr)
|
||||
return NULL;
|
||||
|
||||
if (vpu_addr >= (bo->vpu_addr + ivpu_bo_size(bo)))
|
||||
if (size > bo_size)
|
||||
return NULL;
|
||||
|
||||
return ivpu_bo_vaddr(bo) + (vpu_addr - bo->vpu_addr);
|
||||
offset = vpu_addr - bo->vpu_addr;
|
||||
|
||||
if (offset > bo_size - size)
|
||||
return NULL;
|
||||
|
||||
return ivpu_bo_vaddr(bo) + offset;
|
||||
}
|
||||
|
||||
static inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ ivpu_ipc_tx_prepare(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tx_buf = ivpu_to_cpu_addr(ipc->mem_tx, tx_buf_vpu_addr);
|
||||
tx_buf = ivpu_to_cpu_addr(ipc->mem_tx, tx_buf_vpu_addr, sizeof(*tx_buf));
|
||||
if (drm_WARN_ON(&vdev->drm, !tx_buf)) {
|
||||
gen_pool_free(ipc->mm_tx, tx_buf_vpu_addr, sizeof(*tx_buf));
|
||||
return -EIO;
|
||||
|
|
@ -420,7 +420,7 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev)
|
|||
return;
|
||||
}
|
||||
|
||||
ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr);
|
||||
ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr, sizeof(*ipc_hdr));
|
||||
if (!ipc_hdr) {
|
||||
ivpu_warn_ratelimited(vdev, "IPC msg 0x%x out of range\n", vpu_addr);
|
||||
continue;
|
||||
|
|
@ -429,7 +429,8 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev)
|
|||
|
||||
jsm_msg = NULL;
|
||||
if (ipc_hdr->channel != IVPU_IPC_CHAN_BOOT_MSG) {
|
||||
jsm_msg = ivpu_to_cpu_addr(ipc->mem_rx, ipc_hdr->data_addr);
|
||||
jsm_msg = ivpu_to_cpu_addr(ipc->mem_rx, ipc_hdr->data_addr,
|
||||
sizeof(*jsm_msg));
|
||||
if (!jsm_msg) {
|
||||
ivpu_warn_ratelimited(vdev, "JSM msg 0x%x out of range\n",
|
||||
ipc_hdr->data_addr);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ config DRM_ADP
|
|||
select DRM_KMS_HELPER
|
||||
select DRM_BRIDGE_CONNECTOR
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_KMS_DMA_HELPER
|
||||
select DRM_GEM_DMA_HELPER
|
||||
select DRM_PANEL_BRIDGE
|
||||
select VIDEOMODE_HELPERS
|
||||
|
|
|
|||
|
|
@ -1701,9 +1701,8 @@ u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
|
|||
if (dma_resv_trylock(bo->tbo.base.resv)) {
|
||||
dma_resv_describe(bo->tbo.base.resv, m);
|
||||
dma_resv_unlock(bo->tbo.base.resv);
|
||||
} else {
|
||||
seq_puts(m, "\n");
|
||||
}
|
||||
seq_puts(m, "\n");
|
||||
|
||||
return size;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,6 +191,8 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entit
|
|||
* @tmz: if we should setup a TMZ enabled mapping
|
||||
* @size: in number of bytes to map, out number of bytes mapped
|
||||
* @addr: resulting address inside the MC address space
|
||||
* @vm_needs_flush: out, set true if a GART window was programmed (VMID 0 flush
|
||||
* needed) or false for a direct address
|
||||
*
|
||||
* Setup one of the GART windows to access a specific piece of memory or return
|
||||
* the physical address for local memory.
|
||||
|
|
@ -200,7 +202,8 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,
|
|||
struct ttm_resource *mem,
|
||||
struct amdgpu_res_cursor *mm_cur,
|
||||
unsigned int window,
|
||||
bool tmz, uint64_t *size, uint64_t *addr)
|
||||
bool tmz, uint64_t *size, uint64_t *addr,
|
||||
bool *vm_needs_flush)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
|
||||
unsigned int offset, num_pages, num_dw, num_bytes;
|
||||
|
|
@ -221,9 +224,12 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,
|
|||
if (!tmz && mem->start != AMDGPU_BO_INVALID_OFFSET) {
|
||||
*addr = amdgpu_ttm_domain_start(adev, mem->mem_type) +
|
||||
mm_cur->start;
|
||||
*vm_needs_flush = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* A GART window is programmed below, so its VMID 0 TLB needs a flush */
|
||||
*vm_needs_flush = true;
|
||||
|
||||
/*
|
||||
* If start begins at an offset inside the page, then adjust the size
|
||||
|
|
@ -324,6 +330,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
|||
while (src_mm.remaining) {
|
||||
uint64_t from, to, cur_size, tiling_flags;
|
||||
uint32_t num_type, data_format, max_com, write_compress_disable;
|
||||
bool src_vm_flush, dst_vm_flush;
|
||||
struct dma_fence *next;
|
||||
|
||||
/* Never copy more than 256MiB at once to avoid a timeout */
|
||||
|
|
@ -331,12 +338,12 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
|||
|
||||
/* Map src to window 0 and dst to window 1. */
|
||||
r = amdgpu_ttm_map_buffer(entity, src->bo, src->mem, &src_mm,
|
||||
0, tmz, &cur_size, &from);
|
||||
0, tmz, &cur_size, &from, &src_vm_flush);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
r = amdgpu_ttm_map_buffer(entity, dst->bo, dst->mem, &dst_mm,
|
||||
1, tmz, &cur_size, &to);
|
||||
1, tmz, &cur_size, &to, &dst_vm_flush);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
|
|
@ -364,7 +371,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
r = amdgpu_copy_buffer(adev, entity, from, to, cur_size, resv,
|
||||
&next, true, copy_flags);
|
||||
&next, src_vm_flush || dst_vm_flush, copy_flags);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
|
|
@ -2624,6 +2631,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
|
|||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
struct dma_fence *fence = NULL;
|
||||
struct amdgpu_res_cursor dst;
|
||||
bool vm_needs_flush = false;
|
||||
int r;
|
||||
|
||||
if (!entity)
|
||||
|
|
@ -2645,13 +2653,13 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
|
|||
cur_size = min(dst.size, 256ULL << 20);
|
||||
|
||||
r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst,
|
||||
0, false, &cur_size, &to);
|
||||
0, false, &cur_size, &to, &vm_needs_flush);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
r = amdgpu_ttm_fill_mem(adev, entity,
|
||||
0, to, cur_size, resv,
|
||||
&next, true, k_job_id);
|
||||
&next, vm_needs_flush, k_job_id);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
|
|
|
|||
|
|
@ -747,9 +747,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
}
|
||||
if (adev->dm.dc->caps.max_links > 0) {
|
||||
adev->dm.hdmi_frl_status_polling_wq =
|
||||
create_singlethread_workqueue("hdmi_frl_status_polling_workqueue");
|
||||
create_singlethread_workqueue("hdmi_frl_status_polling_wq");
|
||||
if (!adev->dm.hdmi_frl_status_polling_wq)
|
||||
drm_err(adev_to_drm(adev), "failed to initialize hdmi_frl_status_polling_workqueue\n");
|
||||
drm_err(adev_to_drm(adev), "failed to initialize hdmi_frl_status_polling_wq\n");
|
||||
}
|
||||
if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
|
||||
init_completion(&adev->dm.dmub_aux_transfer_done);
|
||||
|
|
@ -1972,6 +1972,10 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
|
|||
/* On resume we need to rewrite the MSTM control bits to enable MST*/
|
||||
s3_handle_mst(ddev, false);
|
||||
|
||||
/* Exit IPS before the detection loop's first AUX/DDC access. */
|
||||
scoped_guard(mutex, &dm->dc_lock)
|
||||
dc_exit_ips_for_hw_access(dm->dc);
|
||||
|
||||
/* Do detection*/
|
||||
drm_connector_list_iter_begin(ddev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter) {
|
||||
|
|
|
|||
|
|
@ -756,10 +756,14 @@ amdgpu_dm_get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing,
|
|||
break;
|
||||
case DRM_MODE_COLORIMETRY_BT2020_RGB:
|
||||
case DRM_MODE_COLORIMETRY_BT2020_YCC:
|
||||
if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
|
||||
color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
|
||||
else
|
||||
if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) {
|
||||
if (connector_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
|
||||
color_space = COLOR_SPACE_2020_RGB_LIMITEDRANGE;
|
||||
else
|
||||
color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
|
||||
} else {
|
||||
color_space = COLOR_SPACE_2020_YCBCR_LIMITED;
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_COLORIMETRY_DEFAULT: /* ITU601 */
|
||||
default:
|
||||
|
|
@ -3937,17 +3941,15 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
|
|||
}
|
||||
|
||||
/* Handle MCCS */
|
||||
if (do_mccs)
|
||||
if (do_mccs) {
|
||||
dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
|
||||
|
||||
if ((sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
|
||||
as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) &&
|
||||
(!sink->edid_caps.freesync_vcp_code ||
|
||||
(sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)))
|
||||
freesync_capable = false;
|
||||
if (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)
|
||||
freesync_capable = false;
|
||||
|
||||
if (do_mccs && sink->mccs_caps.freesync_supported && freesync_capable)
|
||||
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
|
||||
if (sink->mccs_caps.freesync_supported && freesync_capable)
|
||||
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
|
||||
}
|
||||
|
||||
update:
|
||||
if (dm_con_state)
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
|
|||
char *rd_buf_ptr = NULL;
|
||||
const uint32_t rd_buf_size = 100;
|
||||
uint32_t result = 0;
|
||||
uint8_t str_len = 0;
|
||||
int r;
|
||||
|
||||
if (*pos & 3 || size & 3)
|
||||
|
|
@ -208,29 +207,26 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
|
|||
|
||||
rd_buf_ptr = rd_buf;
|
||||
|
||||
str_len = strlen("Current: %d 0x%x %d ");
|
||||
snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ",
|
||||
rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
|
||||
"Current: %d 0x%x %d ",
|
||||
link->cur_link_settings.lane_count,
|
||||
link->cur_link_settings.link_rate,
|
||||
link->cur_link_settings.link_spread);
|
||||
rd_buf_ptr += str_len;
|
||||
|
||||
str_len = strlen("Verified: %d 0x%x %d ");
|
||||
snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ",
|
||||
rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
|
||||
"Verified: %d 0x%x %d ",
|
||||
link->verified_link_cap.lane_count,
|
||||
link->verified_link_cap.link_rate,
|
||||
link->verified_link_cap.link_spread);
|
||||
rd_buf_ptr += str_len;
|
||||
|
||||
str_len = strlen("Reported: %d 0x%x %d ");
|
||||
snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ",
|
||||
rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
|
||||
"Reported: %d 0x%x %d ",
|
||||
link->reported_link_cap.lane_count,
|
||||
link->reported_link_cap.link_rate,
|
||||
link->reported_link_cap.link_spread);
|
||||
rd_buf_ptr += str_len;
|
||||
|
||||
str_len = strlen("Preferred: %d 0x%x %d ");
|
||||
snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n",
|
||||
rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
|
||||
"Preferred: %d 0x%x %d\n",
|
||||
link->preferred_link_setting.lane_count,
|
||||
link->preferred_link_setting.link_rate,
|
||||
link->preferred_link_setting.link_spread);
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
|
|||
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
|
||||
|
||||
if (edid_caps->edid_hdmi) {
|
||||
edid_caps->qs_bit = connector->display_info.rgb_quant_range_selectable;
|
||||
populate_hdmi_info_from_connector(link->dc->config.enable_frl, &connector->display_info.hdmi, edid_caps);
|
||||
drm_dbg_driver(connector->dev, "%s: HDMI_FRL [%s] max_frl_rate %d\n", __func__, connector->name, edid_caps->max_frl_rate);
|
||||
if (edid_caps->frl_dsc_support)
|
||||
|
|
@ -1202,9 +1203,10 @@ void populate_hdmi_info_from_connector(bool enable_frl, struct drm_hdmi_info *hd
|
|||
edid_caps->max_frl_rate = get_max_frl_rate(hdmi->max_lanes, hdmi->max_frl_rate_per_lane);
|
||||
edid_caps->frl_dsc_support = hdmi->dsc_cap.v_1p2;
|
||||
if (edid_caps->frl_dsc_support) {
|
||||
if (hdmi->dsc_cap.bpc_supported == 10)
|
||||
/* HF-VSDB DSC max bpc is cumulative: >=12 implies 10 and 8. */
|
||||
if (hdmi->dsc_cap.bpc_supported >= 10)
|
||||
edid_caps->frl_dsc_10bpc = true;
|
||||
else if (hdmi->dsc_cap.bpc_supported == 12)
|
||||
if (hdmi->dsc_cap.bpc_supported >= 12)
|
||||
edid_caps->frl_dsc_12bpc = true;
|
||||
edid_caps->frl_dsc_all_bpp = hdmi->dsc_cap.all_bpp;
|
||||
edid_caps->frl_dsc_native_420 = hdmi->dsc_cap.native_420;
|
||||
|
|
|
|||
|
|
@ -567,6 +567,23 @@ static void dm_test_output_color_space_bt2020_rgb(struct kunit *test)
|
|||
(int)COLOR_SPACE_2020_RGB_FULLRANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_bt2020_rgb_limited - Test limited BT.2020 RGB
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_output_color_space_bt2020_rgb_limited(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
|
||||
(int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_bt2020_ycc - Test Output color space bt2020 ycc
|
||||
* @test: The KUnit test context
|
||||
|
|
@ -638,6 +655,24 @@ static void dm_test_output_color_space_bt2020_ycc_rgb_encoding(struct kunit *tes
|
|||
(int)COLOR_SPACE_2020_RGB_FULLRANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited - Test limited
|
||||
* BT.2020 RGB output selected through the BT.2020 YCC connector colorspace
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_BT2020_YCC;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
|
||||
(int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_bt2020_rgb_ycc_encoding - Test Output color space
|
||||
* bt2020 rgb with non-rgb pixel encoding falls back to limited ycbcr
|
||||
|
|
@ -5422,10 +5457,12 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
|
|||
KUNIT_CASE(dm_test_output_color_space_bt709_y_only),
|
||||
KUNIT_CASE(dm_test_output_color_space_oprgb),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_limited),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_ycc),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_ycbcr709_y_only),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_ycbcr601),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_ycc_rgb_encoding),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_ycc_encoding),
|
||||
/* Tests for amdgpu_dm_convert_dc_color_depth_into_bpc */
|
||||
KUNIT_CASE(dm_test_convert_color_depth_bpc_mappings),
|
||||
|
|
|
|||
|
|
@ -358,12 +358,14 @@ static void dm_test_parse_edid_caps_hdmi_frl(struct kunit *test)
|
|||
|
||||
/* Drive the HDMI/FRL branch */
|
||||
connector->display_info.is_hdmi = true;
|
||||
connector->display_info.rgb_quant_range_selectable = true;
|
||||
connector->display_info.hdmi.scdc.supported = true;
|
||||
connector->display_info.hdmi.max_lanes = 4;
|
||||
connector->display_info.hdmi.max_frl_rate_per_lane = 12;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, dm_helpers_parse_edid_caps(link, dc_edid, edid_caps), EDID_OK);
|
||||
KUNIT_EXPECT_TRUE(test, edid_caps->edid_hdmi);
|
||||
KUNIT_EXPECT_EQ(test, edid_caps->qs_bit, 1);
|
||||
KUNIT_EXPECT_TRUE(test, edid_caps->scdc_present);
|
||||
/* max_lanes 4 + max_frl_rate_per_lane 12 -> rate index 6 */
|
||||
KUNIT_EXPECT_EQ(test, edid_caps->max_frl_rate, 6);
|
||||
|
|
@ -909,7 +911,7 @@ static void dm_test_populate_hdmi_frl_dsc_12bpc(struct kunit *test)
|
|||
|
||||
KUNIT_EXPECT_EQ(test, caps->max_frl_rate, 2);
|
||||
KUNIT_EXPECT_TRUE(test, caps->frl_dsc_support);
|
||||
KUNIT_EXPECT_FALSE(test, caps->frl_dsc_10bpc);
|
||||
KUNIT_EXPECT_TRUE(test, caps->frl_dsc_10bpc);
|
||||
KUNIT_EXPECT_TRUE(test, caps->frl_dsc_12bpc);
|
||||
KUNIT_EXPECT_EQ(test, caps->frl_dsc_max_slices, 7);
|
||||
KUNIT_EXPECT_EQ(test, caps->frl_dsc_max_frl_rate, 1);
|
||||
|
|
|
|||
|
|
@ -3198,6 +3198,7 @@ static struct dc_update_descriptor check_update_surfaces_for_stream(
|
|||
}
|
||||
|
||||
if ((stream_update->hdr_static_metadata && !stream_update->stream->use_dynamic_meta) ||
|
||||
stream_update->output_color_space ||
|
||||
stream_update->vrr_infopacket ||
|
||||
stream_update->vsc_infopacket ||
|
||||
stream_update->vsp_infopacket ||
|
||||
|
|
@ -4188,6 +4189,7 @@ static void commit_planes_do_stream_update_sequence(struct dc *dc,
|
|||
hwss_add_setup_periodic_interrupt(&seq_state, dc, pipe_ctx);
|
||||
|
||||
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
|
||||
stream_update->output_color_space ||
|
||||
stream_update->vrr_infopacket ||
|
||||
stream_update->vsc_infopacket ||
|
||||
stream_update->vsp_infopacket ||
|
||||
|
|
@ -4370,6 +4372,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
|||
dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
|
||||
|
||||
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
|
||||
stream_update->output_color_space ||
|
||||
stream_update->vrr_infopacket ||
|
||||
stream_update->vsc_infopacket ||
|
||||
stream_update->vsp_infopacket ||
|
||||
|
|
|
|||
|
|
@ -348,7 +348,8 @@ int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
|
|||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
int ret = 0;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_sriov_vf(adev) ||
|
||||
amdgpu_in_reset(adev))
|
||||
return 0;
|
||||
|
||||
if (pp_funcs && pp_funcs->switch_power_profile) {
|
||||
|
|
@ -367,7 +368,8 @@ int amdgpu_dpm_pause_power_profile(struct amdgpu_device *adev,
|
|||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
int ret = 0;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_sriov_vf(adev) ||
|
||||
amdgpu_in_reset(adev))
|
||||
return 0;
|
||||
|
||||
if (pp_funcs && pp_funcs->pause_power_profile) {
|
||||
|
|
|
|||
|
|
@ -2092,11 +2092,11 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu,
|
|||
|
||||
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
|
||||
|
||||
if ((mp1_ver == IP_VERSION(13, 0, 0) && smu->smc_fw_version <= 0x004e1e00) ||
|
||||
(mp1_ver == IP_VERSION(13, 0, 10) && smu->smc_fw_version <= 0x00500800))
|
||||
if ((mp1_ver == IP_VERSION(13, 0, 0) &&
|
||||
(smu->smc_fw_version <= 0x004e1e00 || smu->smc_fw_version >= 0x004e8600)) ||
|
||||
(mp1_ver == IP_VERSION(13, 0, 10) &&
|
||||
smu->smc_fw_version <= 0x00500800))
|
||||
gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
|
||||
else
|
||||
gpu_metrics->energy_accumulator = UINT_MAX;
|
||||
|
||||
if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD)
|
||||
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
|
||||
|
|
|
|||
|
|
@ -2097,8 +2097,8 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu,
|
|||
metrics->Vcn1ActivityPercentage);
|
||||
|
||||
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
|
||||
gpu_metrics->energy_accumulator = smu->smc_fw_version <= 0x00521400 ?
|
||||
metrics->EnergyAccumulator : UINT_MAX;
|
||||
if (smu->smc_fw_version <= 0x00521400)
|
||||
gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
|
||||
|
||||
if (metrics->AverageGfxActivity <= SMU_13_0_7_BUSY_THRESHOLD)
|
||||
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/sizes.h>
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_damage_helper.h>
|
||||
#include <drm/drm_format_helper.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
|
|
@ -355,6 +356,8 @@ int ast_cursor_plane_init(struct ast_device *ast)
|
|||
}
|
||||
drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
|
||||
drm_plane_enable_fb_damage_clips(cursor_plane);
|
||||
drm_plane_create_blend_mode_property(cursor_plane,
|
||||
BIT(DRM_MODE_BLEND_COVERAGE));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1263,10 +1263,13 @@ tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
|||
return input_fmts;
|
||||
}
|
||||
|
||||
static bool tc358768_mode_fixup(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
static int tc358768_bridge_atomic_check(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
|
||||
|
||||
/* Default to positive sync */
|
||||
|
||||
if (!(adjusted_mode->flags &
|
||||
|
|
@ -1277,13 +1280,15 @@ static bool tc358768_mode_fixup(struct drm_bridge *bridge,
|
|||
(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
|
||||
adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
|
||||
|
||||
return true;
|
||||
bridge_state->input_bus_cfg.flags = bridge->timings->input_bus_flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs tc358768_bridge_funcs = {
|
||||
.attach = tc358768_bridge_attach,
|
||||
.mode_valid = tc358768_bridge_mode_valid,
|
||||
.mode_fixup = tc358768_mode_fixup,
|
||||
.atomic_check = tc358768_bridge_atomic_check,
|
||||
.atomic_pre_enable = tc358768_bridge_atomic_pre_enable,
|
||||
.atomic_enable = tc358768_bridge_atomic_enable,
|
||||
.atomic_disable = tc358768_bridge_atomic_disable,
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ static int sn65dsi83_reset_pipe(struct sn65dsi83 *sn65dsi83)
|
|||
drm_modeset_drop_locks(&ctx);
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void sn65dsi83_reset_work(struct work_struct *ws)
|
||||
|
|
@ -419,11 +419,13 @@ static void sn65dsi83_reset_work(struct work_struct *ws)
|
|||
ret = sn65dsi83_reset_pipe(ctx);
|
||||
if (ret) {
|
||||
dev_err(ctx->dev, "reset pipe failed %pe\n", ERR_PTR(ret));
|
||||
return;
|
||||
goto bridge_exit;
|
||||
}
|
||||
|
||||
if (ctx->irq)
|
||||
enable_irq(ctx->irq);
|
||||
|
||||
bridge_exit:
|
||||
drm_bridge_exit(idx);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,19 @@ int drm_exec_prepare_array(struct drm_exec *exec,
|
|||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Make sure to lock a contended object even when no objects are
|
||||
* given, otherwise drm_exec_retry_on_contention() would loop
|
||||
* forever on patterns like:
|
||||
*
|
||||
* ret = drm_exec_prepare_array(exec, objs, num_objects, ...);
|
||||
* drm_exec_retry_on_contention(exec);
|
||||
*
|
||||
* with num_objects == 0.
|
||||
*/
|
||||
if (!num_objects)
|
||||
return drm_exec_lock_contended(exec);
|
||||
|
||||
for (unsigned int i = 0; i < num_objects; ++i) {
|
||||
ret = drm_exec_prepare_obj(exec, objects[i], num_fences);
|
||||
if (unlikely(ret))
|
||||
|
|
|
|||
|
|
@ -1946,6 +1946,8 @@ struct intel_dp {
|
|||
|
||||
bool colorimetry_support;
|
||||
|
||||
bool sst_split_sdp_support;
|
||||
|
||||
struct {
|
||||
enum transcoder transcoder;
|
||||
struct mutex lock;
|
||||
|
|
|
|||
|
|
@ -3409,12 +3409,22 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder,
|
|||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
pipe_config->has_audio =
|
||||
intel_dp_has_audio(encoder, conn_state) &&
|
||||
intel_audio_compute_config(encoder, pipe_config, conn_state);
|
||||
|
||||
pipe_config->sdp_split_enable = pipe_config->has_audio &&
|
||||
intel_dp_is_uhbr(pipe_config);
|
||||
|
||||
/*
|
||||
* SDP splitting for UHBR audio requires explicit sink capability in
|
||||
* SST mode, whereas in MST mode it is inherently supported.
|
||||
*/
|
||||
if (pipe_config->sdp_split_enable &&
|
||||
!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST))
|
||||
pipe_config->sdp_split_enable = intel_dp->sst_split_sdp_support;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4462,16 +4472,25 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
|
|||
str_enable_disable(tmp));
|
||||
}
|
||||
|
||||
static bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
|
||||
static u8 intel_dp_read_dprx_feature_enum(struct intel_dp *intel_dp)
|
||||
{
|
||||
u8 dprx = 0;
|
||||
|
||||
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
|
||||
&dprx) != 1)
|
||||
return false;
|
||||
drm_dp_dpcd_read_data(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
|
||||
&dprx, sizeof(dprx));
|
||||
return dprx;
|
||||
}
|
||||
|
||||
static bool intel_dp_get_colorimetry_status(u8 dprx)
|
||||
{
|
||||
return dprx & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED;
|
||||
}
|
||||
|
||||
static bool intel_dp_get_sst_split_sdp_status(u8 dprx)
|
||||
{
|
||||
return dprx & DP_SST_SPLIT_SDP_CAP;
|
||||
}
|
||||
|
||||
static int intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
|
||||
u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
|
||||
{
|
||||
|
|
@ -4771,6 +4790,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
|
|||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
u8 dprx;
|
||||
|
||||
/* this function is meant to be called only once */
|
||||
drm_WARN_ON(display->drm, intel_dp->dpcd[DP_DPCD_REV] != 0);
|
||||
|
|
@ -4782,8 +4802,13 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
|
|||
drm_dp_is_branch(intel_dp->dpcd));
|
||||
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
|
||||
|
||||
dprx = intel_dp_read_dprx_feature_enum(intel_dp);
|
||||
|
||||
intel_dp->colorimetry_support =
|
||||
intel_dp_get_colorimetry_status(intel_dp);
|
||||
intel_dp_get_colorimetry_status(dprx);
|
||||
|
||||
intel_dp->sst_split_sdp_support =
|
||||
intel_dp_get_sst_split_sdp_status(dprx);
|
||||
|
||||
/*
|
||||
* Read the eDP display control registers.
|
||||
|
|
@ -4874,13 +4899,20 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
|
|||
* the OUI/ID since we know it won't change.
|
||||
*/
|
||||
if (!intel_dp_is_edp(intel_dp)) {
|
||||
u8 dprx;
|
||||
|
||||
drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
|
||||
drm_dp_is_branch(intel_dp->dpcd));
|
||||
|
||||
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
|
||||
|
||||
dprx = intel_dp_read_dprx_feature_enum(intel_dp);
|
||||
|
||||
intel_dp->colorimetry_support =
|
||||
intel_dp_get_colorimetry_status(intel_dp);
|
||||
intel_dp_get_colorimetry_status(dprx);
|
||||
|
||||
intel_dp->sst_split_sdp_support =
|
||||
intel_dp_get_sst_split_sdp_status(dprx);
|
||||
|
||||
intel_dp_update_sink_caps(intel_dp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -403,8 +403,10 @@ static int query_perf_config_list(struct drm_i915_private *i915,
|
|||
ids = krealloc(oa_config_ids,
|
||||
n_configs * sizeof(*oa_config_ids),
|
||||
GFP_KERNEL);
|
||||
if (!ids)
|
||||
if (!ids) {
|
||||
kfree(oa_config_ids);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
alloc = fetch_and_zero(&n_configs);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ config DRM_LOGICVC
|
|||
depends on OF || COMPILE_TEST
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_KMS_DMA_HELPER
|
||||
select DRM_GEM_DMA_HELPER
|
||||
select REGMAP
|
||||
select REGMAP_MMIO
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_encoder.h>
|
||||
#include <drm/drm_framebuffer.h>
|
||||
|
|
@ -993,6 +994,9 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev,
|
|||
|
||||
drm_plane_helper_add(plane, helper_funcs);
|
||||
|
||||
drm_plane_create_blend_mode_property(plane,
|
||||
BIT(DRM_MODE_BLEND_PREMULTI));
|
||||
|
||||
return plane;
|
||||
|
||||
free_plane:
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ config ROCKCHIP_CDN_DP
|
|||
|
||||
config ROCKCHIP_DW_DP
|
||||
bool "Rockchip specific extensions for Synopsys DW DP"
|
||||
select DRM_BRIDGE_CONNECTOR
|
||||
help
|
||||
This selects support for Rockchip SoC specific extensions
|
||||
to enable Synopsys DesignWare Cores based DisplayPort transmit
|
||||
|
|
@ -145,6 +146,8 @@ config ROCKCHIP_RGB
|
|||
config ROCKCHIP_RK3066_HDMI
|
||||
bool "Rockchip specific extensions for RK3066 HDMI"
|
||||
depends on DRM_ROCKCHIP
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_BRIDGE_CONNECTOR
|
||||
help
|
||||
This selects support for Rockchip SoC specific extensions
|
||||
for the RK3066 HDMI driver. If you want to enable
|
||||
|
|
|
|||
|
|
@ -241,10 +241,11 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
|
|||
of_graph_get_remote_port(endpoint.local_node);
|
||||
|
||||
of_property_read_u32(remote_port, "reg", &port_id);
|
||||
sprintf(name, "%s vp%d", remote_port_parent->full_name, port_id);
|
||||
snprintf(name, sizeof(name), "%s vp%d",
|
||||
remote_port_parent->full_name, port_id);
|
||||
} else {
|
||||
sprintf(name, "%s %s",
|
||||
remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
|
||||
snprintf(name, sizeof(name), "%s %s",
|
||||
remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
|
||||
}
|
||||
|
||||
DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2025 Valve Corporation */
|
||||
|
||||
#include <kunit/device.h>
|
||||
|
||||
#include "sched_tests.h"
|
||||
|
||||
/*
|
||||
|
|
@ -288,6 +290,7 @@ static const struct drm_sched_backend_ops drm_mock_scheduler_ops = {
|
|||
*/
|
||||
struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test, long timeout)
|
||||
{
|
||||
static unsigned int instance;
|
||||
struct drm_sched_init_args args = {
|
||||
.ops = &drm_mock_scheduler_ops,
|
||||
.num_rqs = DRM_SCHED_PRIORITY_COUNT,
|
||||
|
|
@ -297,11 +300,19 @@ struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test, long timeout)
|
|||
.name = "drm-mock-scheduler",
|
||||
};
|
||||
struct drm_mock_scheduler *sched;
|
||||
struct device *dev;
|
||||
char name[64];
|
||||
int ret;
|
||||
|
||||
sched = kunit_kzalloc(test, sizeof(*sched), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, sched);
|
||||
|
||||
snprintf(name, sizeof(name), "%s-%u", args.name, instance++);
|
||||
dev = kunit_device_register(test, name);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
args.dev = dev;
|
||||
|
||||
ret = drm_sched_init(&sched->base, &args);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
|
@ -540,6 +541,9 @@ static struct drm_plane *vbox_create_plane(struct vbox_private *vbox,
|
|||
|
||||
drm_plane_helper_add(plane, helper_funcs);
|
||||
|
||||
drm_plane_create_blend_mode_property(plane,
|
||||
BIT(DRM_MODE_BLEND_COVERAGE));
|
||||
|
||||
return plane;
|
||||
|
||||
free_plane:
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_damage_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
|
|
@ -609,6 +610,9 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
|
|||
|
||||
if (type == DRM_PLANE_TYPE_PRIMARY)
|
||||
drm_plane_enable_fb_damage_clips(plane);
|
||||
else if (type == DRM_PLANE_TYPE_CURSOR)
|
||||
drm_plane_create_blend_mode_property(plane,
|
||||
BIT(DRM_MODE_BLEND_PREMULTI));
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
|
||||
|
||||
#define PIPE_CONTROL0_QUEUE_DRAIN_MODE BIT(12)
|
||||
#define PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH BIT(11) /* gen12 */
|
||||
#define PIPE_CONTROL0_L3_READ_ONLY_CACHE_INVALIDATE BIT(10) /* gen12 */
|
||||
#define PIPE_CONTROL0_HDC_PIPELINE_FLUSH BIT(9) /* gen12 */
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "xe_hw_engine.h"
|
||||
#include "xe_pagefault.h"
|
||||
#include "xe_pagefault_types.h"
|
||||
#include "xe_pm.h"
|
||||
#include "xe_svm.h"
|
||||
#include "xe_trace_bo.h"
|
||||
#include "xe_vm.h"
|
||||
|
|
@ -292,9 +293,17 @@ static void xe_pagefault_queue_work(struct work_struct *w)
|
|||
{
|
||||
struct xe_pagefault_queue *pf_queue =
|
||||
container_of(w, typeof(*pf_queue), worker);
|
||||
struct xe_device *xe = pf_queue->xe;
|
||||
struct xe_pagefault pf;
|
||||
unsigned long threshold;
|
||||
|
||||
/*
|
||||
* A live VM holds a PM reference, but a torn-down VM does not.
|
||||
* Guard the entire worker loop to safely drain stale faults and
|
||||
* prevent autosuspends from desyncing batched CT flushes.
|
||||
*/
|
||||
guard(xe_pm_runtime)(xe);
|
||||
|
||||
#define USM_QUEUE_MAX_RUNTIME_MS 20
|
||||
threshold = jiffies + msecs_to_jiffies(USM_QUEUE_MAX_RUNTIME_MS);
|
||||
|
||||
|
|
@ -365,6 +374,7 @@ static int xe_pagefault_queue_init(struct xe_device *xe,
|
|||
drm_dbg(&xe->drm, "xe_pagefault_entry_size=%d, total_num_eus=%d, pf_queue->size=%u",
|
||||
xe_pagefault_entry_size(), total_num_eus, pf_queue->size);
|
||||
|
||||
pf_queue->xe = xe;
|
||||
spin_lock_init(&pf_queue->lock);
|
||||
INIT_WORK(&pf_queue->worker, xe_pagefault_queue_work);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
struct xe_device;
|
||||
struct xe_gt;
|
||||
struct xe_pagefault;
|
||||
|
||||
|
|
@ -118,6 +119,8 @@ struct xe_pagefault {
|
|||
* queue to absorb the device’s worst-case number of outstanding faults.
|
||||
*/
|
||||
struct xe_pagefault_queue {
|
||||
/** @xe: Back-pointer to the Xe device */
|
||||
struct xe_device *xe;
|
||||
/**
|
||||
* @data: Data in queue containing struct xe_pagefault, protected by
|
||||
* @lock
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ static int emit_render_cache_flush(struct xe_sched_job *job, u32 *dw, int i)
|
|||
{
|
||||
struct xe_exec_queue *q = job->q;
|
||||
struct xe_gt *gt = q->gt;
|
||||
struct xe_device *xe = gt_to_xe(gt);
|
||||
bool lacks_render = !(gt->info.engine_mask & XE_HW_ENGINE_RCS_MASK);
|
||||
u32 flags0, flags1;
|
||||
|
||||
|
|
@ -220,6 +221,16 @@ static int emit_render_cache_flush(struct xe_sched_job *job, u32 *dw, int i)
|
|||
LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR, 0);
|
||||
|
||||
flags0 = PIPE_CONTROL0_HDC_PIPELINE_FLUSH;
|
||||
/*
|
||||
* Prior to MTL, HDC Pipeline Flush reliably also flushes the LSC
|
||||
* untyped L1 dataport cache, provided HDC_CHICKEN0 is programmed
|
||||
* correctly. Starting with MTL that coupling no longer holds
|
||||
* regardless of how HDC_CHICKEN0 is programmed, but explicitly
|
||||
* requesting the flush via PIPE_CONTROL is itself only reliable
|
||||
* from Xe2 onward, so only gate it in on Xe2+.
|
||||
*/
|
||||
if (GRAPHICS_VERx100(xe) >= 2000)
|
||||
flags0 |= PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH;
|
||||
flags1 = (PIPE_CONTROL_TILE_CACHE_FLUSH |
|
||||
PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
|
||||
PIPE_CONTROL_DEPTH_CACHE_FLUSH |
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user