Pull drm fixes from Dave Airlie:
 "Weekly pulls request. As expected there is more AMD this week since
  Alex was off last week, vmwgfx looks to have been hit with the AI
  stick a bit and mediatek as well. Otherwise some minor fixes across
  the board, the new normal definitely seems to be a thing.

  dp:
   - Restrict some DP bandwidth calculations to HDMI DFP

  bridge:
   - Fix small leak in bridge/display-connector

  mediatek:
   - Check CRTC state before freeing
   - mtk_hdmi: Fix DDC adapter double put in v2
   - mtk_hdmi_common: take i2c adapter module reference
   - mtk_dsi: Enable HS clock only at pre-enable
   - ovl_adaptor: balance component registrations

  amdgpu:
   - VCN 5.3 fix
   - UserQ fixes
   - GEM close optimization
   - HDMI AV mute fix
   - UML build fixes
   - GFXOFF residency metrics fixes
   - SMU 15 fixes
   - debug_vm fix
   - PSP 15 fixes
   - NBIO 7.11.5 fix
   - pptable use after free fix
   - gpu metrics fetch fix
   - DC viewport fix
   - DML2.1 fix
   - i2c retimer spam fix
   - UMD profile pstate fix
   - Power metrics format cleanup
   - GTT size fix on APUs
   - DC context logging fix
   - PM sysfs fix for APUs
   - Follow on pageflip timeout fix

  amdkfd:
   - Various bounds checking fixes
   - Mutex locking fix

  i915/xe:
   - Check no-DMA huge-pte cases before DMA segment test
   - sink FRL rate fix
   - 200ms fix for TMDS scrambler status

  vmwgfx:
   - Improve various size checks and limit checks
   - Fix oops when submitting  invalid execbuf ioctl
   - Correctly lock in vmfwgx fence signaling path
   - More validation of execbuf ioctl
   - Fix oops in vmwgfx vkms init failure path
   - Overflow handling in shader path

  panthor:
   - Improve firmware validation

  imagination:
   - Improve imagination trace points.

  qaic:
   - Fix QAIC transaction length check"

* tag 'drm-fixes-2026-08-01' of https://gitlab.freedesktop.org/drm/kernel: (59 commits)
  drm/i915/hdmi: Poll for 200 msec for TMDS_Scrambler_Status
  drm/amd/display: Exit idle optimizations before programming
  drm/amd/pm: hide pp_table sysfs on APUs
  accel/qaic: use sizeof(*trans_hdr) for transaction length check
  drm/panthor: validate firmware interface structure sizes
  drm/xe/pt: check no-DMA huge-pte cases before DMA segment test
  drm/imagination: Update the trace point pvr_job_submit_fw()
  drm/i915/dp: Ignore the sink's DSC max FRL rate without a PCON DSC encoder
  drm/mediatek: ovl_adaptor: balance component registrations
  drm/mediatek: mtk_dsi: Enable HS clock only at pre-enable
  drm/dp: Read the PCON max FRL bandwidth only for HDMI DFPs
  drm/amd/display: use proper context for logging
  drm/amdgpu: cap GTT size to physical RAM on APUs
  drm/amd/pm: use milliwatts for GPU power sensors
  drm/amdgpu: restore UMD profile pstate after runtime resume
  drm/amd/display: Silence link_dpms I2C retimer failures
  drm/amdkfd: hold event_mutex while checkpointing CRIU events
  drm/amd/display: check if dml21_add_phantom_plane() is successful
  drm/amd/display: Fix divide-by-zero in calculate_mcache_setting on zero viewport
  drm/amd/display: Add AV mute wait frames to dce110_set_avmute
  ...
This commit is contained in:
Linus Torvalds
2026-07-31 15:47:45 -07:00
92 changed files with 1172 additions and 375 deletions

View File

@@ -786,7 +786,7 @@ static int encode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
break;
}
trans_hdr = (struct qaic_manage_trans_hdr *)(user_msg->data + user_len);
if (trans_hdr->len < sizeof(trans_hdr) ||
if (trans_hdr->len < sizeof(*trans_hdr) ||
size_add(user_len, trans_hdr->len) > user_msg->len) {
ret = -EINVAL;
break;

View File

@@ -92,7 +92,7 @@ struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f)
return NULL;
fence = container_of(f, struct amdgpu_amdkfd_fence, base);
if (f->ops == &amdkfd_fence_ops)
if (rcu_access_pointer(f->ops) == &amdkfd_fence_ops)
return fence;
return NULL;

View File

@@ -3096,7 +3096,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu *
process_info->eviction_fence = new_fence;
replace_eviction_fence(ef, dma_fence_get(&new_fence->base));
} else {
WARN_ONCE(*ef != &process_info->eviction_fence->base,
WARN_ONCE(rcu_access_pointer(*ef) != &process_info->eviction_fence->base,
"KFD eviction fence doesn't match KGD process_info");
}

View File

@@ -1177,19 +1177,6 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
job->vm_pd_addr = amdgpu_gmc_pd_addr(vm->root.bo);
}
if (adev->debug_vm) {
/* Invalidate all BOs to test for userspace bugs */
amdgpu_bo_list_for_each_entry(e, p->bo_list) {
struct amdgpu_bo *bo = e->bo;
/* ignore duplicates */
if (!bo)
continue;
amdgpu_vm_bo_invalidate(bo, false);
}
}
return 0;
}
@@ -1378,6 +1365,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
/* Cleanup the parser structure */
static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser)
{
struct amdgpu_device *adev = parser->adev;
struct amdgpu_bo_list_entry *e;
unsigned int i;
amdgpu_sync_free(&parser->sync);
@@ -1393,8 +1382,21 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser)
if (parser->ctx)
amdgpu_ctx_put(parser->ctx);
if (parser->bo_list)
if (parser->bo_list) {
if (adev->debug_vm) {
/* Invalidate all BOs to test for userspace bugs */
amdgpu_bo_list_for_each_entry(e, parser->bo_list) {
struct amdgpu_bo *bo = e->bo;
/* ignore duplicates */
if (!bo)
continue;
amdgpu_vm_bo_invalidate(bo, false);
}
}
amdgpu_bo_list_put(parser->bo_list);
}
for (i = 0; i < parser->nchunks; i++)
kvfree(parser->chunks[i].kdata);

View File

@@ -43,6 +43,11 @@
#if defined(CONFIG_DEBUG_FS)
/* Encode milliwatts in the raw Q24.8 sensor report format used by UMR. */
#define AMDGPU_DEBUGFS_PWR_MW_TO_Q24_8(power_mw) \
DIV_ROUND_CLOSEST_ULL((u64)(power_mw) * BIT(8), \
MILLIWATT_PER_WATT)
/**
* amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes
*
@@ -1104,6 +1109,10 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
return r;
}
if (idx == AMDGPU_PP_SENSOR_GPU_AVG_POWER ||
idx == AMDGPU_PP_SENSOR_GPU_INPUT_POWER)
values[0] = AMDGPU_DEBUGFS_PWR_MW_TO_Q24_8(values[0]);
if (size > valuesize) {
amdgpu_virt_disable_access_debugfs(adev);
return -EINVAL;
@@ -1319,8 +1328,8 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
* @size: Number of bytes to read
* @pos: Offset to seek to
*
* Read the last residency value logged. It doesn't auto update, one needs to
* stop logging before getting the current value.
* Read a live GFXOFF residency sample from firmware. One needs to start logging
* before getting the current value.
*/
static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)

View File

@@ -2304,6 +2304,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &psp_v14_0_ip_block);
break;
case IP_VERSION(15, 0, 0):
case IP_VERSION(15, 0, 5):
case IP_VERSION(15, 0, 9):
amdgpu_device_ip_block_add(adev, &psp_v15_0_ip_block);
break;

View File

@@ -2908,6 +2908,19 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
return 0;
}
static void amdgpu_restore_umd_profile_pstate_after_runpm(struct amdgpu_device *adev)
{
enum amd_dpm_forced_level level;
uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
level = amdgpu_dpm_get_performance_level(adev);
if (level & profile_mode_mask)
amdgpu_asic_update_umd_stable_pstate(adev, true);
}
static int amdgpu_pmops_runtime_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -2952,6 +2965,8 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
if (adev->pm.rpm_mode == AMDGPU_RUNPM_PX)
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
amdgpu_restore_umd_profile_pstate_after_runpm(adev);
adev->in_runpm = false;
return 0;
}

View File

@@ -1210,7 +1210,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
return -EINVAL;
}
}
ui32 >>= 8;
ui32 /= MILLIWATT_PER_WATT;
break;
case AMDGPU_INFO_SENSOR_GPU_INPUT_POWER:
/* get input GPU power */
@@ -1219,7 +1219,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
(void *)&ui32, &ui32_size)) {
return -EINVAL;
}
ui32 >>= 8;
ui32 /= MILLIWATT_PER_WATT;
break;
case AMDGPU_INFO_SENSOR_VDDNB:
/* get VDDNB in millivolts */

View File

@@ -275,6 +275,7 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block)
psp->boot_time_tmr = false;
break;
case IP_VERSION(15, 0, 0):
case IP_VERSION(15, 0, 5):
case IP_VERSION(15, 0, 9):
psp_v15_0_0_set_psp_funcs(psp);
psp->boot_time_tmr = false;
@@ -1222,6 +1223,33 @@ int psp_memory_partition(struct psp_context *psp, int mode)
return ret;
}
int psp_set_mmhub_eco_sec_level(struct amdgpu_device *adev)
{
int ret;
struct psp_context *psp = &adev->psp;
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
cmd->cmd_id = GFX_CMD_ID_SET_MMHUB_ECO_SEC_LEVEL;
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
if (ret) {
dev_err(psp->adev->dev,
"PSP request failed to set mmuhub eco sec level with ret=%d\n", ret);
release_psp_cmd_buf(psp);
return ret;
}
if (cmd->resp.status) {
dev_err(psp->adev->dev,
"MMHUB ECO SEC LEVEL command 0x%x failed, PSP response status: 0x%X\n",
cmd->cmd_id, cmd->resp.status);
ret = -EIO;
}
release_psp_cmd_buf(psp);
return ret;
}
static int psp_ptl_fmt_verify(struct psp_context *psp, enum amdgpu_ptl_fmt fmt,
uint32_t *ptl_fmt)
{
@@ -3476,8 +3504,10 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 0) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 8) ||
IP_VERSION(15, 0, 5) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 8) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 9)) &&
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 ||
ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 ||

View File

@@ -656,5 +656,6 @@ int amdgpu_psp_reg_program_no_ring(struct psp_context *psp, uint32_t val,
void amdgpu_psp_debugfs_init(struct amdgpu_device *adev);
int amdgpu_psp_get_fw_type(struct amdgpu_firmware_info *ucode,
enum psp_gfx_fw_type *type);
int psp_set_mmhub_eco_sec_level(struct amdgpu_device *adev);
#endif

View File

@@ -2173,6 +2173,18 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
gtt_size = configured_size;
}
/* Cap GTT so that it does not exceed total physical RAM. */
if (adev->flags & AMD_IS_APU) {
u64 phys_ram = (u64)totalram_pages() << PAGE_SHIFT;
if (gtt_size > phys_ram) {
gtt_size = phys_ram;
dev_info(adev->dev,
"Capping GTT to %uM to not exceed available system memory\n",
(unsigned int)(gtt_size / (1024 * 1024)));
}
}
/* Initialize GTT memory pool */
r = amdgpu_gtt_mgr_init(adev, gtt_size);
if (r) {

View File

@@ -965,6 +965,7 @@ amdgpu_userq_vm_validate(struct amdgpu_userq_mgr *uq_mgr)
struct amdgpu_vm *vm = &fpriv->vm;
unsigned long key, tmp_key;
struct amdgpu_bo_va *bo_va;
struct amdgpu_usermode_queue *queue;
struct amdgpu_bo *bo;
struct drm_exec exec;
struct xarray xa;
@@ -1080,6 +1081,24 @@ amdgpu_userq_vm_validate(struct amdgpu_userq_mgr *uq_mgr)
dma_fence_wait(bo_va->last_pt_update, false);
dma_fence_wait(vm->last_update, false);
xa_for_each(&uq_mgr->userq_xa, tmp_key, queue) {
bo = queue->wptr_obj.obj;
if (!bo) {
ret = -EINVAL;
goto unlock_all;
}
ret = amdgpu_ttm_alloc_gart(&bo->tbo);
if (unlikely(ret)) {
drm_file_err(uq_mgr->file,
"failed to bind wptr bo to gart on resume, qid=%lu ret=%d\n",
tmp_key, ret);
goto unlock_all;
}
queue->wptr_obj.gpu_addr = amdgpu_bo_gpu_offset(bo);
}
ret = amdgpu_evf_mgr_rearm(&fpriv->evf_mgr, &exec);
if (ret)
drm_file_err(uq_mgr->file, "Failed to replace eviction fence\n");

View File

@@ -1553,6 +1553,8 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_sync sync;
int r;
if (list_empty(&vm->freed))
return 0;
/*
* Implicitly sync to command submissions in the same VM before

View File

@@ -379,7 +379,7 @@ struct amd_sriov_msg_vf2pf_info {
struct {
uint8_t id;
uint32_t version;
} ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
} __packed ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
uint64_t dummy_page_addr;
/* FB allocated for guest MES to record UQ info */
uint64_t mes_info_addr;

View File

@@ -398,6 +398,25 @@ static void jpeg_v5_3_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
}
/**
* jpeg_v5_3_0_set_mmhub_eco_sec_level - set jpeg sec lvl reg
*
* @adev: amdgpu_device pointer
*
* request psp to set secure lvl
*/
static int jpeg_v5_3_0_set_mmhub_eco_sec_level(struct amdgpu_device *adev)
{
int r = 0;
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
/* Request to PSP to program JPEG secure lvl */
r = psp_set_mmhub_eco_sec_level(adev);
}
return r;
}
/**
* jpeg_v5_3_0_start - start JPEG block
*
@@ -423,6 +442,11 @@ static int jpeg_v5_3_0_start(struct amdgpu_device *adev)
if (r)
return r;
/* program JPEG secure lvl register */
r = jpeg_v5_3_0_set_mmhub_eco_sec_level(adev);
if (r)
return r;
/* JPEG disable CGC */
jpeg_v5_3_0_disable_clock_gating(adev);

View File

@@ -70,27 +70,23 @@ mes_userq_create_wptr_mapping(struct amdgpu_device *adev,
ret = -EINVAL;
goto fail_map;
}
/* TODO use eviction fence instead of pinning. */
ret = amdgpu_bo_pin(wptr_obj->obj, AMDGPU_GEM_DOMAIN_GTT);
/* Keep WPTR BO under eviction-fence control instead of pinning. */
ret = amdgpu_evf_mgr_attach_fence(&uq_mgr_to_fpriv(uq_mgr)->evf_mgr, wptr_obj->obj);
if (ret) {
DRM_ERROR("Failed to pin wptr bo. ret %d\n", ret);
DRM_ERROR("Failed to attach eviction fence to wptr bo. ret %d\n", ret);
goto fail_map;
}
ret = amdgpu_ttm_alloc_gart(&wptr_obj->obj->tbo);
if (ret) {
DRM_ERROR("Failed to bind bo to GART. ret %d\n", ret);
goto fail_alloc_gart;
DRM_ERROR("Failed to bind wptr bo to GART. ret %d\n", ret);
goto fail_map;
}
queue->wptr_obj.gpu_addr = amdgpu_bo_gpu_offset(wptr_obj->obj);
drm_exec_fini(&exec);
return 0;
fail_alloc_gart:
amdgpu_bo_unpin(wptr_obj->obj);
fail_map:
amdgpu_bo_unref(&wptr_obj->obj);
fail_lock:
@@ -468,9 +464,6 @@ static void mes_userq_mqd_destroy(struct amdgpu_usermode_queue *queue)
amdgpu_bo_free_kernel(&queue->mqd.obj, &queue->mqd.gpu_addr,
&queue->mqd.cpu_ptr);
amdgpu_bo_reserve(queue->wptr_obj.obj, true);
amdgpu_bo_unpin(queue->wptr_obj.obj);
amdgpu_bo_unreserve(queue->wptr_obj.obj);
amdgpu_bo_unref(&queue->wptr_obj.obj);
}

View File

@@ -30,70 +30,76 @@
#include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
#include <uapi/linux/kfd_ioctl.h>
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10 0x4f0aeb
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10 0x4f0aec
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10 0x4f0aed
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10 0x4f0aee
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10 0x4f0aef
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10 0x4f0af0
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10 0x4f0af1
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10 0x4f0af2
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10 0x4f0af3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10 0x4f0af4
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10 0x4f0af5
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10 0x4f0af6
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10_BASE_IDX 3
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10 0x0021
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10_BASE_IDX 2
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10 0x4f0aeb
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10 0x4f0aec
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10 0x4f0aed
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10 0x4f0aee
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10 0x4f0aef
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10 0x4f0af0
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10 0x4f0af1
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10 0x4f0af2
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10 0x4f0af3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10 0x4f0af4
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10 0x4f0af5
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10 0x4f0af6
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10_BASE_IDX 3
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10 0x0021
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10_BASE_IDX 2
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5 0x8e13
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5 0x8e14
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5 0x8e15
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5 0x8e13
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5 0x8e14
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5 0x8e15
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5 0x8e4d
#define regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5 0x8e4e
#define regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX1_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5 0x012d
#define regBIF_BX1_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX1_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5 0x012e
#define regBIF_BX1_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 2
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5 0xd000
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5_BASE_IDX 5
#define regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5 0x0021
#define regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX0_BIF_FB_EN_nbio_7_11_5 0x8e20
#define regBIF_BX0_BIF_FB_EN_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX1_BIF_FB_EN_nbio_7_11_5 0x0100
#define regBIF_BX1_BIF_FB_EN_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5 0x8e11
#define regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX0_INTERRUPT_CNTL2_nbio_7_11_5 0x8e12
#define regBIF_BX0_INTERRUPT_CNTL2_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5 0x00f1
#define regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX1_INTERRUPT_CNTL2_nbio_7_11_5 0x00f2
#define regBIF_BX1_INTERRUPT_CNTL2_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX_PF0_GPU_HDP_FLUSH_REQ_nbio_7_11_5 0x8e26
#define regBIF_BX_PF0_GPU_HDP_FLUSH_REQ_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_GPU_HDP_FLUSH_DONE_nbio_7_11_5 0x8e27
#define regBIF_BX_PF0_GPU_HDP_FLUSH_DONE_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF1_GPU_HDP_FLUSH_REQ_nbio_7_11_5 0x0106
#define regBIF_BX_PF1_GPU_HDP_FLUSH_REQ_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX_PF1_GPU_HDP_FLUSH_DONE_nbio_7_11_5 0x0107
#define regBIF_BX_PF1_GPU_HDP_FLUSH_DONE_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5 0x8e17
#define regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF1_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5 0x00f7
#define regBIF_BX_PF1_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 2
//BIF_BX1_BIF_FB_EN
#define BIF_BX1_BIF_FB_EN__FB_READ_EN__SHIFT_nbio_7_11_5 0x0
#define BIF_BX1_BIF_FB_EN__FB_WRITE_EN__SHIFT_nbio_7_11_5 0x1
#define BIF_BX1_BIF_FB_EN__FB_READ_EN_MASK_nbio_7_11_5 0x00000001L
#define BIF_BX1_BIF_FB_EN__FB_WRITE_EN_MASK_nbio_7_11_5 0x00000002L
static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev)
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5)) {
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5,
WREG32_SOC15(NBIO, 0, regBIF_BX1_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5,
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL);
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5,
WREG32_SOC15(NBIO, 0, regBIF_BX1_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5,
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL);
} else {
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL,
@@ -110,7 +116,7 @@ static u32 nbif_v6_3_1_get_rev_id(struct amdgpu_device *adev)
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 4))
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10);
else if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5);
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5);
else
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
@@ -124,11 +130,11 @@ static void nbif_v6_3_1_mc_access_enable(struct amdgpu_device *adev, bool enable
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5)) {
if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_nbio_7_11_5,
BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK |
BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK);
WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN_nbio_7_11_5,
BIF_BX1_BIF_FB_EN__FB_READ_EN_MASK_nbio_7_11_5 |
BIF_BX1_BIF_FB_EN__FB_WRITE_EN_MASK_nbio_7_11_5);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_nbio_7_11_5, 0);
WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN_nbio_7_11_5, 0);
} else {
if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN,
@@ -383,12 +389,12 @@ static void nbif_v6_3_1_ih_control(struct amdgpu_device *adev)
/* setup interrupt control */
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2_nbio_7_11_5,
WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL2_nbio_7_11_5,
adev->dummy_page_addr >> 8);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2, adev->dummy_page_addr >> 8);
interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5);
interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5);
/*
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
@@ -401,7 +407,7 @@ static void nbif_v6_3_1_ih_control(struct amdgpu_device *adev)
IH_REQ_NONSNOOP_EN, 0);
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5, interrupt_cntl);
WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5, interrupt_cntl);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL, interrupt_cntl);
}
@@ -427,7 +433,7 @@ nbif_v6_3_1_get_clockgating_state(struct amdgpu_device *adev,
static u32 nbif_v6_3_1_get_hdp_flush_req_offset(struct amdgpu_device *adev)
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ_nbio_7_11_5);
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_GPU_HDP_FLUSH_REQ_nbio_7_11_5);
else
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ);
}
@@ -435,7 +441,7 @@ static u32 nbif_v6_3_1_get_hdp_flush_req_offset(struct amdgpu_device *adev)
static u32 nbif_v6_3_1_get_hdp_flush_done_offset(struct amdgpu_device *adev)
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE_nbio_7_11_5);
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_GPU_HDP_FLUSH_DONE_nbio_7_11_5);
else
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE);
}
@@ -622,7 +628,7 @@ static void nbif_v6_3_1_set_reg_remap(struct amdgpu_device *adev)
} else {
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5) << 2;
regBIF_BX_PF1_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5) << 2;
else
adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;

View File

@@ -110,6 +110,7 @@ enum psp_gfx_cmd_id
GFX_CMD_ID_PERF_HW = 0x0000004C, /* performance monitor */
GFX_CMD_ID_FB_FW_RESERV_ADDR = 0x00000050, /* Query FW reservation addr */
GFX_CMD_ID_FB_FW_RESERV_EXT_ADDR = 0x00000051, /* Query FW reservation extended addr */
GFX_CMD_ID_SET_MMHUB_ECO_SEC_LEVEL = 0x0000005D, /* Set MMHUB ECO sec lvls on VCN block */
};
/* PSP boot config sub-commands */

View File

@@ -33,9 +33,22 @@
MODULE_FIRMWARE("amdgpu/psp_15_0_0_toc.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_0_ta.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_5_toc.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_5_ta.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_9_toc.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_9_ta.bin");
#define regMPASP_PCRU0_MPASP_C2PMSG_64 0x4280
#define regMPASP_PCRU0_MPASP_C2PMSG_64_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_67 0x4283
#define regMPASP_PCRU0_MPASP_C2PMSG_67_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_69 0x4285
#define regMPASP_PCRU0_MPASP_C2PMSG_69_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_70 0x4286
#define regMPASP_PCRU0_MPASP_C2PMSG_70_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_71 0x4287
#define regMPASP_PCRU0_MPASP_C2PMSG_71_BASE_IDX 2
static int psp_v15_0_0_init_microcode(struct psp_context *psp)
{
struct amdgpu_device *adev = psp->adev;
@@ -71,14 +84,25 @@ static int psp_v15_0_0_ring_stop(struct psp_context *psp,
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_101),
0x80000000, 0x80000000, false);
} else {
/* Write the ring destroy command*/
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64,
GFX_CTRL_CMD_ID_DESTROY_RINGS);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5)) {
/* Write the ring destroy command*/
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64,
GFX_CTRL_CMD_ID_DESTROY_RINGS);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
} else {
/* Write the ring destroy command*/
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64,
GFX_CTRL_CMD_ID_DESTROY_RINGS);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
}
}
return ret;
@@ -118,14 +142,44 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp,
0x80000000, 0x8000FFFF, false);
} else {
/* Wait for sOS ready for ring creation */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5)) {
/* Wait for sOS ready for ring creation */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (ret) {
DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");
return ret;
}
/* Write low address of the ring to C2PMSG_69 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_69, psp_ring_reg);
/* Write high address of the ring to C2PMSG_70 */
psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_70, psp_ring_reg);
/* Write size of ring to C2PMSG_71 */
psp_ring_reg = ring->ring_size;
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_71, psp_ring_reg);
/* Write the ring initialization command to C2PMSG_64 */
psp_ring_reg = ring_type;
psp_ring_reg = psp_ring_reg << 16;
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64, psp_ring_reg);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) in C2PMSG_64 */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64),
0x80000000, 0x8000FFFF, false);
} else {
/* Wait for sOS ready for ring creation */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (ret) {
DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");
return ret;
}
/* Write low address of the ring to C2PMSG_69 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_69, psp_ring_reg);
@@ -146,6 +200,7 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp,
/* Wait for response flag (bit 31) in C2PMSG_64 */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x8000FFFF, false);
}
}
return ret;
@@ -176,8 +231,12 @@ static uint32_t psp_v15_0_0_ring_get_wptr(struct psp_context *psp)
if (amdgpu_sriov_vf(adev))
data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102);
else
data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67);
else {
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5))
data = RREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_67);
else
data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67);
}
return data;
}
@@ -190,8 +249,12 @@ static void psp_v15_0_0_ring_set_wptr(struct psp_context *psp, uint32_t value)
WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102, value);
WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,
GFX_CTRL_CMD_ID_CONSUME_CMD);
} else
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value);
} else {
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5))
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_67, value);
else
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value);
}
}
static const struct psp_funcs psp_v15_0_0_funcs = {

View File

@@ -406,6 +406,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev)
case IP_VERSION(14, 0, 4):
case IP_VERSION(14, 0, 5):
case IP_VERSION(15, 0, 0):
case IP_VERSION(15, 0, 5):
case IP_VERSION(15, 0, 9):
return AMD_RESET_METHOD_MODE2;
default:

View File

@@ -795,6 +795,27 @@ static int vcn_v5_0_0_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
return 0;
}
/**
* vcn_v5_0_0_set_mmhub_eco_sec_level - set vcn sec lvl reg
*
* @adev: amdgpu_device pointer
*
* request psp to set sec lvl
*/
static int vcn_v5_0_0_set_mmhub_eco_sec_level(struct amdgpu_device *adev)
{
int r = 0;
if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(5, 3, 0)) {
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
/* Request to PSP to program VCN secure lvl */
r = psp_set_mmhub_eco_sec_level(adev);
}
}
return r;
}
/**
* vcn_v5_0_0_start - VCN start
*
@@ -819,6 +840,11 @@ static int vcn_v5_0_0_start(struct amdgpu_vcn_inst *vinst)
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
/* program VCN secure lvl register */
r = vcn_v5_0_0_set_mmhub_eco_sec_level(adev);
if (r)
return r;
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
return vcn_v5_0_0_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram);

View File

@@ -3109,10 +3109,14 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v
goto out;
}
/* Check if target is still PTRACED. */
/*
* Verify debugger has permission to debug target process.
* For cross-process debugging, require active ptrace relationship.
* This applies to ALL operations to prevent unauthorized interference.
*/
rcu_read_lock();
if (target != p && args->op != KFD_IOC_DBG_TRAP_DISABLE
&& ptrace_parent(target->lead_thread) != current) {
if (target != p && ptrace_parent(target->lead_thread) != current
&& target->debugger_process != p) {
pr_err("PID %i is not PTRACED and cannot be debugged\n", args->pid);
r = -EPERM;
}

View File

@@ -1412,6 +1412,15 @@ int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
break;
}
/* Validate subtype fits within remaining image */
if ((char *)sub_type_hdr + sub_type_hdr->length >
(char *)crat_image + image_len) {
pr_warn("CRAT subtype length %u exceeds image bounds\n",
sub_type_hdr->length);
ret = -EINVAL;
break;
}
if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) {
ret = kfd_parse_subtype(sub_type_hdr, device_list);
if (ret)

View File

@@ -524,6 +524,9 @@ int kfd_criu_restore_event(struct file *devkfd,
ret = create_other_event(p, ev, &ev_priv->event_id);
break;
default:
ret = -EINVAL;
break;
}
mutex_unlock(&p->event_mutex);
@@ -545,15 +548,27 @@ int kfd_criu_checkpoint_events(struct kfd_process *p,
int ret = 0;
struct kfd_event *ev;
uint32_t ev_id;
uint32_t num_events;
uint32_t num_events = kfd_get_num_events(p);
/* Serialize the count and the walk below against concurrent event
* create/destroy. Those paths take only p->event_mutex, not the
* p->mutex held by the CRIU checkpoint caller, so without this the
* event_idr can grow between kfd_get_num_events() and the loop and the
* walk writes past the ev_privs allocation.
*/
mutex_lock(&p->event_mutex);
if (!num_events)
num_events = kfd_get_num_events(p);
if (!num_events) {
mutex_unlock(&p->event_mutex);
return 0;
}
ev_privs = kvzalloc(num_events * sizeof(*ev_privs), GFP_KERNEL);
if (!ev_privs)
if (!ev_privs) {
mutex_unlock(&p->event_mutex);
return -ENOMEM;
}
idr_for_each_entry(&p->event_idr, ev, ev_id) {
@@ -594,6 +609,8 @@ int kfd_criu_checkpoint_events(struct kfd_process *p,
i++;
}
mutex_unlock(&p->event_mutex);
ret = copy_to_user(user_priv_data + *priv_data_offset,
ev_privs, num_events * sizeof(*ev_privs));
if (ret) {

View File

@@ -383,7 +383,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
false);
if (retval) {
dev_err(dev->adev->dev, "failed to allocate process context bo\n");
return retval;
goto err_allocate_pqn;
}
memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
}

View File

@@ -288,7 +288,7 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
}
err = kfd_queue_buffer_get(vm, (void *)properties->eop_ring_buffer_address,
&properties->eop_buf_bo,
ALIGN(properties->eop_ring_buffer_size, PAGE_SIZE));
ALIGN((u64)properties->eop_ring_buffer_size, PAGE_SIZE));
if (err)
goto out_err_unreserve;
}

View File

@@ -9903,25 +9903,6 @@ static void remove_stream(struct amdgpu_device *adev,
acrtc->enabled = false;
}
static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
{
assert_spin_locked(&acrtc->base.dev->event_lock);
WARN_ON(acrtc->event);
acrtc->event = acrtc->base.state->event;
/* Set the flip status */
acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
/* Mark this event as consumed */
acrtc->base.state->event = NULL;
drm_dbg_state(acrtc->base.dev,
"crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n",
acrtc->crtc_id);
}
static void update_freesync_state_on_stream(
struct amdgpu_display_manager *dm,
struct dm_crtc_state *new_crtc_state,
@@ -10274,17 +10255,47 @@ static void dm_arm_vblank_event(struct amdgpu_crtc *acrtc,
return;
if (pflip_update) {
drm_crtc_vblank_get(&acrtc->base);
WARN_ON(acrtc->pflip_status != AMDGPU_FLIP_NONE);
/* Arm flip completion handling and event delivery after programming. */
prepare_flip_isr(acrtc);
WARN_ON(acrtc->event);
acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
acrtc->event = acrtc->base.state->event;
acrtc->base.state->event = NULL;
drm_dbg_state(acrtc->base.dev,
"crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n",
acrtc->crtc_id);
} else if (cursor_update) {
drm_crtc_vblank_get(&acrtc->base);
acrtc->event = acrtc->base.state->event;
acrtc->base.state->event = NULL;
}
}
/**
* dm_arm_vblank_event_pre_programming - Prepare for programming
* @acrtc: The amdgpu CRTC to prepare
* @acrtc_state: The new CRTC state
* @pflip_update: Whether a page flip is being programmed
* @cursor_update: Whether a cursor update is being programmed
*
* Grab a reference on the vblank counter if a page flip or cursor update is to
* be programmed. Do this before programming so the HW is not in any
* idle-optimized state (such as PSR).
*/
static void dm_arm_vblank_event_pre_programming(struct amdgpu_crtc *acrtc,
struct dm_crtc_state *acrtc_state,
bool pflip_update,
bool cursor_update)
{
assert_spin_locked(&acrtc->base.dev->event_lock);
if (!acrtc->base.state->event || acrtc_state->active_planes == 0)
return;
if (pflip_update || cursor_update)
drm_crtc_vblank_get(&acrtc->base);
}
static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
struct drm_device *dev,
struct amdgpu_display_manager *dm,
@@ -10550,16 +10561,19 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
}
}
/*
* DCE depends on a combination of GRPH_FLIP, VLINE0, and VUPDATE for
* event delivery. Only GRPH_FLIP handler can send pflip events, and it
* only fires if HW latched to the flip. Maintain legacy behavior by
* arming event before programming.
*/
if (amdgpu_ip_version(dm->adev, DCE_HWIP, 0) == 0) {
scoped_guard(spinlock_irqsave, &pcrtc->dev->event_lock) {
scoped_guard(spinlock_irqsave, &pcrtc->dev->event_lock) {
dm_arm_vblank_event_pre_programming(acrtc_attach, acrtc_state,
pflip_present,
cursor_update);
/*
* DCE depends on a combination of GRPH_FLIP, VLINE0, and
* VUPDATE for event delivery. Only GRPH_FLIP handler can send
* pflip events, and it only fires if HW latched to the flip.
* Maintain legacy behavior by arming event before programming.
*/
if (amdgpu_ip_version(dm->adev, DCE_HWIP, 0) == 0) {
dm_arm_vblank_event(acrtc_attach, acrtc_state,
pflip_present, cursor_update);
pflip_present, cursor_update);
}
}

View File

@@ -45,9 +45,7 @@
clk_src->base.ctx
#define DC_LOGGER \
calc_pll_cs->ctx->logger
#define DC_LOGGER_INIT() \
struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll
CTX->logger
#undef FN
#define FN(reg_name, field_name) \
@@ -287,6 +285,7 @@ static bool calc_pll_dividers_in_range(
}
static uint32_t calculate_pixel_clock_pll_dividers(
struct dce110_clk_src *clk_src,
struct calc_pll_clock_source *calc_pll_cs,
struct pll_settings *pll_settings)
{
@@ -474,7 +473,7 @@ static uint32_t dce110_get_pix_clk_dividers_helper (
{
uint32_t field = 0;
uint32_t pll_calc_error = MAX_PLL_CALC_ERROR;
DC_LOGGER_INIT();
/* Check if reference clock is external (not pcie/xtalin)
* HW Dce80 spec:
* 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB
@@ -517,12 +516,14 @@ static uint32_t dce110_get_pix_clk_dividers_helper (
/*Calculate Dividers by HDMI object, no SS case or SS case */
pll_calc_error =
calculate_pixel_clock_pll_dividers(
clk_src,
&clk_src->calc_pll_hdmi,
pll_settings);
else
/*Calculate Dividers by default object, no SS case or SS case */
pll_calc_error =
calculate_pixel_clock_pll_dividers(
clk_src,
&clk_src->calc_pll,
pll_settings);
@@ -568,7 +569,6 @@ static uint32_t dce110_get_pix_clk_dividers(
{
struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs);
uint32_t pll_calc_error = MAX_PLL_CALC_ERROR;
DC_LOGGER_INIT();
if (pix_clk_params == NULL || pll_settings == NULL
|| pix_clk_params->requested_pix_clk_100hz == 0) {
@@ -600,7 +600,6 @@ static uint32_t dce112_get_pix_clk_dividers(
struct pll_settings *pll_settings)
{
struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs);
DC_LOGGER_INIT();
if (pix_clk_params == NULL || pll_settings == NULL
|| pix_clk_params->requested_pix_clk_100hz == 0) {
@@ -1442,8 +1441,6 @@ static uint32_t dcn3_get_pix_clk_dividers(
unsigned long long actual_pix_clk_100Hz = pix_clk_params ? pix_clk_params->requested_pix_clk_100hz : 0;
struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs);
DC_LOGGER_INIT();
if (pix_clk_params == NULL || pll_settings == NULL
|| pix_clk_params->requested_pix_clk_100hz == 0) {
DC_LOG_ERROR(
@@ -1513,7 +1510,6 @@ static const struct clock_source_funcs dce110_clk_src_funcs = {
.get_dp_dto_frequency_100hz = get_dp_dto_frequency_100hz
};
static void get_ss_info_from_atombios(
struct dce110_clk_src *clk_src,
enum as_signal_type as_signal,
@@ -1526,7 +1522,7 @@ static void get_ss_info_from_atombios(
struct spread_spectrum_info *ss_info_cur;
struct spread_spectrum_data *ss_data_cur;
uint32_t i;
DC_LOGGER_INIT();
if (ss_entries_num == NULL) {
DC_LOG_SYNC(
"Invalid entry !!!\n");
@@ -1657,6 +1653,7 @@ static void ss_info_from_atombios_create(
}
static bool calc_pll_max_vco_construct(
struct dce110_clk_src *clk_src,
struct calc_pll_clock_source *calc_pll_cs,
struct calc_pll_clock_source_init_data *init_data)
{
@@ -1808,6 +1805,7 @@ bool dce110_clk_src_construct(
ss_info_from_atombios_create(clk_src);
if (!calc_pll_max_vco_construct(
clk_src,
&clk_src->calc_pll,
&calc_pll_cs_init_data)) {
ASSERT_CRITICAL(false);
@@ -1822,7 +1820,7 @@ bool dce110_clk_src_construct(
if (!calc_pll_max_vco_construct(
&clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) {
clk_src, &clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) {
ASSERT_CRITICAL(false);
goto unexpected_failure;
}

View File

@@ -359,14 +359,13 @@ void dml21_handle_phantom_streams_planes(const struct dc *dc, struct dc_state *c
main_plane = main_stream_status->plane_states[dc_plane_index];
/* create phantom planes for subvp enabled plane */
dml21_add_phantom_plane(dml_ctx,
dc,
context,
phantom_stream,
main_plane,
&dml_ctx->v21.mode_programming.programming->plane_programming[dml_plane_index]);
phantoms_added = true;
if (dml21_add_phantom_plane(dml_ctx,
dc,
context,
phantom_stream,
main_plane,
&dml_ctx->v21.mode_programming.programming->plane_programming[dml_plane_index]))
phantoms_added = true;
}
}
}

View File

@@ -2452,7 +2452,7 @@ static void calculate_mcache_row_bytes(
DML_ASSERT(*p->num_mcaches > 0);
}
static void calculate_mcache_setting(
static bool calculate_mcache_setting(
struct dml2_core_internal_scratch *scratch,
struct dml2_core_calcs_calculate_mcache_setting_params *p)
{
@@ -2478,7 +2478,7 @@ static void calculate_mcache_setting(
*p->lc_comb_mcache = 0;
if (!p->dcc_enable)
return;
return true;
l->is_dual_plane = dml_is_420(p->source_format) || p->source_format == dml2_rgbe_alpha;
@@ -2515,7 +2515,14 @@ static void calculate_mcache_setting(
l->l_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_l;
calculate_mcache_row_bytes(scratch, &l->l_p);
DML_ASSERT(*p->num_mcaches_l > 0);
if (*p->num_mcaches_l == 0 ||
(p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l) == 0) {
DML_LOG_VERBOSE("DML::%s: degenerate luma viewport (num_mcaches_l=%u mvmpg_%s_l=%u) — mode not supported\n",
__func__, *p->num_mcaches_l,
p->surf_vert ? "height" : "width",
p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l);
return false;
}
if (l->is_dual_plane) {
l->c_p.num_chans = p->num_chans;
@@ -2551,7 +2558,14 @@ static void calculate_mcache_setting(
l->c_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_c;
calculate_mcache_row_bytes(scratch, &l->c_p);
DML_ASSERT(*p->num_mcaches_c > 0);
if (*p->num_mcaches_c == 0 ||
(p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c) == 0) {
DML_LOG_VERBOSE("DML::%s: degenerate chroma viewport (num_mcaches_c=%u mvmpg_%s_c=%u) — mode not supported\n",
__func__, *p->num_mcaches_c,
p->surf_vert ? "height" : "width",
p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c);
return false;
}
}
// Sharing for iMALL access
@@ -2661,6 +2675,7 @@ static void calculate_mcache_setting(
*p->mcache_shift_granularity_l = l->mvmpg_access_width_l;
*p->mcache_shift_granularity_c = l->mvmpg_access_width_c;
return true;
}
static void calculate_mall_bw_overhead_factor(
@@ -9457,7 +9472,10 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
calculate_mcache_setting_params->mall_comb_mcache_c = &mode_lib->ms.mall_comb_mcache_c[k];
calculate_mcache_setting_params->lc_comb_mcache = &mode_lib->ms.lc_comb_mcache[k];
calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params);
if (!calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params)) {
mode_lib->ms.support.ModeSupport = false;
return false;
}
}
calculate_mall_bw_overhead_factor(
@@ -10933,7 +10951,8 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
calculate_mcache_setting_params->mall_comb_mcache_l = &mode_lib->mp.mall_comb_mcache_l[k];
calculate_mcache_setting_params->mall_comb_mcache_c = &mode_lib->mp.mall_comb_mcache_c[k];
calculate_mcache_setting_params->lc_comb_mcache = &mode_lib->mp.lc_comb_mcache[k];
calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params);
if (!calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params))
return false;
}
calculate_mall_bw_overhead_factor(

View File

@@ -1337,8 +1337,27 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
{
if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL)
if (pipe_ctx == NULL || pipe_ctx->stream_res.stream_enc == NULL)
return;
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable);
/* Wait for three frames to make sure AV mute is sent out.
* Some HDMI sinks need additional GCP packets to properly
* process the mute state, especially after link re-establishment
* with HDMI 2.0 scrambling enabled.
*/
if (enable && pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg)) {
int i;
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
for (i = 0; i < 3; i++) {
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
}
}
}
}
enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)

View File

@@ -847,13 +847,19 @@ void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
pipe_ctx->stream_res.stream_enc,
enable);
/* Wait for two frame to make sure AV mute is sent out */
/* Wait for three frames to make sure AV mute is sent out.
* Some HDMI sinks need additional GCP packets to properly
* process the mute state, especially after link re-establishment
* with HDMI 2.0 scrambling enabled.
*/
if (enable && pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg)) {
int i;
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
for (i = 0; i < 3; i++) {
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
}
}
}
}

View File

@@ -384,7 +384,7 @@ static bool write_i2c_retimer_vga(
for (size_t i = 0; i < ARRAY_SIZE(vga_data); i++) {
if (!write_i2c_retimer_offset_value(link, address, vga_data[i][0], vga_data[i][1])) {
DC_LOG_ERROR("Set retimer failed, vga index: %zu\n", i);
DC_LOG_DEBUG("Set retimer failed, vga index: %zu\n", i);
return false;
}
}
@@ -405,7 +405,7 @@ static bool write_i2c_retimer_byte(
return true;
if (!write_i2c_retimer_offset_value(link, address, index, value)) {
DC_LOG_ERROR("Set retimer failed, 3g index: 0x%x, value: 0x%x\n", index, value);
DC_LOG_DEBUG("Set retimer failed, 3g index: 0x%x, value: 0x%x\n", index, value);
return false;
}
@@ -421,14 +421,14 @@ static bool write_i2c_retimer_byte(
if (!link_query_ddc_data(
link->ddc, address, &offset, 1, &value, 1
)) {
DC_LOG_ERROR("Set retimer failed, link_query_ddc_data\n");
DC_LOG_DEBUG("Set retimer failed, link_query_ddc_data\n");
return false;
}
}
value |= apply_rx_tx_change;
if (!write_i2c_retimer_offset_value(link, address, offset, value)) {
DC_LOG_ERROR("Set retimer failed, 3g offset: 0x%x, value: 0x%x\n", offset, value);
DC_LOG_DEBUG("Set retimer failed, 3g offset: 0x%x, value: 0x%x\n", offset, value);
return false;
}
}
@@ -449,7 +449,7 @@ static bool write_i2c_retimer_setting(
uint8_t value = settings->reg_settings[i].i2c_reg_val;
if (!write_i2c_retimer_byte(link, address, index, value)) {
DC_LOG_ERROR("Set retimer failed, index: %zu\n", i);
DC_LOG_DEBUG("Set retimer failed, index: %zu\n", i);
return false;
}
}
@@ -460,7 +460,7 @@ static bool write_i2c_retimer_setting(
uint8_t value = settings->reg_settings_6g[i].i2c_reg_val;
if (!write_i2c_retimer_byte(link, address, index, value)) {
DC_LOG_ERROR("Set retimer failed, 6g index: %zu\n", i);
DC_LOG_DEBUG("Set retimer failed, 6g index: %zu\n", i);
return false;
}
}
@@ -492,7 +492,7 @@ static bool write_i2c_default_retimer_setting(
for (size_t i = 0; i < ARRAY_SIZE(data); i++) {
if (!write_i2c_retimer_offset_value(link, address, data[i][0], data[i][1])) {
DC_LOG_ERROR("Set default retimer failed, index: %zu\n", i);
DC_LOG_DEBUG("Set default retimer failed, index: %zu\n", i);
return false;
}
}
@@ -524,7 +524,7 @@ static bool write_i2c_redriver_setting(
);
if (!success)
DC_LOG_ERROR("Set redriver failed");
DC_LOG_DEBUG("Set redriver failed");
return success;
}

View File

@@ -24,6 +24,8 @@
#ifndef __KGD_PP_INTERFACE_H__
#define __KGD_PP_INTERFACE_H__
#include <linux/units.h>
extern const struct amdgpu_ip_block_version pp_smu_ip_block;
extern const struct amdgpu_ip_block_version smu_v11_0_ip_block;
extern const struct amdgpu_ip_block_version smu_v12_0_ip_block;
@@ -150,8 +152,8 @@ enum amd_pp_sensors {
AMDGPU_PP_SENSOR_MEM_TEMP,
AMDGPU_PP_SENSOR_VCE_POWER,
AMDGPU_PP_SENSOR_UVD_POWER,
AMDGPU_PP_SENSOR_GPU_AVG_POWER,
AMDGPU_PP_SENSOR_GPU_INPUT_POWER,
AMDGPU_PP_SENSOR_GPU_AVG_POWER, /* milliwatts */
AMDGPU_PP_SENSOR_GPU_INPUT_POWER, /* milliwatts */
AMDGPU_PP_SENSOR_SS_APU_SHARE,
AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK,

View File

@@ -1183,20 +1183,36 @@ int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
return ret;
}
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
static bool amdgpu_dpm_is_pp_table_allowed(struct amdgpu_device *adev)
{
return !amdgpu_sriov_vf(adev) &&
!(adev->flags & AMD_IS_APU) &&
!adev->scpm_enabled;
}
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char *table,
size_t size)
{
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
char *pptable = NULL;
int ret = 0;
if (!table)
if ((!table && size) || (table && !size))
return -EINVAL;
if (amdgpu_sriov_vf(adev) || !pp_funcs->get_pp_table || adev->scpm_enabled)
if (!amdgpu_dpm_is_pp_table_allowed(adev) ||
!pp_funcs->get_pp_table)
return -EOPNOTSUPP;
mutex_lock(&adev->pm.mutex);
ret = pp_funcs->get_pp_table(adev->powerplay.pp_handle,
table);
&pptable);
if (ret > 0 && !pptable) {
ret = -EINVAL;
} else if (ret > 0 && table) {
ret = min_t(size_t, ret, size);
memcpy(table, pptable, ret);
}
mutex_unlock(&adev->pm.mutex);
return ret;
@@ -1426,17 +1442,23 @@ int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
return ret;
}
int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
ssize_t amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void *buf,
size_t size)
{
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret = 0;
void *table;
ssize_t ret;
if (!pp_funcs->get_gpu_metrics)
return 0;
mutex_lock(&adev->pm.mutex);
ret = pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
table);
&table);
if (ret > 0) {
ret = min_t(ssize_t, ret, size);
memcpy(buf, table, ret);
}
mutex_unlock(&adev->pm.mutex);
return ret;
@@ -1703,7 +1725,8 @@ int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
if (!buf || !size)
return -EINVAL;
if (amdgpu_sriov_vf(adev) || !pp_funcs->set_pp_table || adev->scpm_enabled)
if (!amdgpu_dpm_is_pp_table_allowed(adev) ||
!pp_funcs->set_pp_table)
return -EOPNOTSUPP;
mutex_lock(&adev->pm.mutex);

View File

@@ -41,8 +41,6 @@
#define DEVICE_ATTR_IS(_name) (attr_id == device_attr_id__##_name)
#define power_2_mwatt(power) (((power) >> 8) * 1000 + ((power) & 0xff))
struct od_attribute {
struct kobj_attribute attribute;
struct list_head entry;
@@ -564,25 +562,19 @@ static ssize_t amdgpu_get_pp_table(struct device *dev,
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
char *table = NULL;
int size, ret;
ret = amdgpu_pm_get_access_if_active(adev);
if (ret)
return ret;
size = amdgpu_dpm_get_pp_table(adev, &table);
size = amdgpu_dpm_get_pp_table(adev, buf, PAGE_SIZE - 1);
amdgpu_pm_put_access(adev);
if (size <= 0)
return size;
if (size >= PAGE_SIZE)
size = PAGE_SIZE - 1;
memcpy(buf, table, size);
return size;
}
@@ -1780,7 +1772,6 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
void *gpu_metrics;
ssize_t size = 0;
int ret;
@@ -1788,15 +1779,10 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
if (ret)
return ret;
size = amdgpu_dpm_get_gpu_metrics(adev, &gpu_metrics);
size = amdgpu_dpm_get_gpu_metrics(adev, buf, PAGE_SIZE - 1);
if (size <= 0)
goto out;
if (size >= PAGE_SIZE)
size = PAGE_SIZE - 1;
memcpy(buf, gpu_metrics, size);
out:
amdgpu_pm_put_access(adev);
@@ -2726,10 +2712,9 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
*states = ATTR_STATE_UNSUPPORTED;
} else if (DEVICE_ATTR_IS(pp_table)) {
int ret;
char *tmp = NULL;
ret = amdgpu_dpm_get_pp_table(adev, &tmp);
if (ret == -EOPNOTSUPP || !tmp)
ret = amdgpu_dpm_get_pp_table(adev, NULL, 0);
if (ret <= 0)
*states = ATTR_STATE_UNSUPPORTED;
else
*states = ATTR_STATE_SUPPORTED;
@@ -3364,7 +3349,7 @@ static int amdgpu_hwmon_get_power(struct device *dev,
return r;
/* convert to microwatts */
return power_2_mwatt(query) * 1000;
return query * 1000;
}
static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
@@ -4932,7 +4917,7 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
seq_printf(m, "\t%u mV (VDDNB)\n", value);
size = sizeof(uint32_t);
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size)) {
mwatt = power_2_mwatt(query);
mwatt = query;
centiwatt = DIV_ROUND_CLOSEST(mwatt, 10);
if (adev->flags & AMD_IS_APU)
seq_printf(m, "\t%u.%02u W (average SoC including CPU)\n", centiwatt / 100, centiwatt % 100);
@@ -4941,7 +4926,7 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
}
size = sizeof(uint32_t);
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size)) {
mwatt = power_2_mwatt(query);
mwatt = query;
centiwatt = DIV_ROUND_CLOSEST(mwatt, 10);
if (adev->flags & AMD_IS_APU)
seq_printf(m, "\t%u.%02u W (current SoC including CPU)\n", centiwatt / 100, centiwatt % 100);

View File

@@ -487,7 +487,8 @@ int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
enum amd_pp_task task_id,
enum amd_pm_state_type *user_state);
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table);
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char *table,
size_t size);
int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
uint32_t type,
long *input,
@@ -517,7 +518,8 @@ int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
char *buf);
int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
long *input, uint32_t size);
int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table);
ssize_t amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void *buf,
size_t size);
ssize_t amdgpu_dpm_get_xcp_metrics(struct amdgpu_device *adev, int xcp_id,
void *table);
ssize_t amdgpu_dpm_get_temp_metrics(struct amdgpu_device *adev,

View File

@@ -4062,7 +4062,7 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)
(adev->asic_type != CHIP_FIJI) &&
(adev->asic_type != CHIP_TONGA)) {
smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetCurrPkgPwr, 0, &tmp);
*query = tmp;
*query = PP_PWR_Q24_8_TO_MW(tmp);
if (tmp != 0)
return 0;
@@ -4081,7 +4081,7 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)
if (tmp != 0)
break;
}
*query = tmp;
*query = PP_PWR_Q24_8_TO_MW(tmp);
return 0;
}

View File

@@ -3934,8 +3934,8 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
if (ret)
return ret;
/* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */
*query = value << 8;
/* SMC returns whole Watts, while power sensors use milliwatts. */
*query = value * MILLIWATT_PER_WATT;
return 0;
}

View File

@@ -1419,7 +1419,7 @@ static int vega12_get_gpu_power(struct pp_hwmgr *hwmgr, uint32_t *query)
if (ret)
return ret;
*query = metrics_table.CurrSocketPower << 8;
*query = metrics_table.CurrSocketPower * MILLIWATT_PER_WATT;
return ret;
}

View File

@@ -2154,12 +2154,13 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, int idx,
switch (idx) {
case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
if (hwmgr->smu_version == 0x282e00)
*query = metrics_table.AverageSocketPower << 8;
*query = metrics_table.AverageSocketPower *
MILLIWATT_PER_WATT;
else
ret = -EOPNOTSUPP;
break;
case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
*query = metrics_table.CurrSocketPower << 8;
*query = metrics_table.CurrSocketPower * MILLIWATT_PER_WATT;
break;
}

View File

@@ -35,6 +35,11 @@ struct pp_hwmgr;
struct phm_fan_speed_info;
struct pp_atomctrl_voltage_table;
/* Decode legacy unsigned Q24.8 watts to internal milliwatts. */
#define PP_PWR_Q24_8_TO_MW(power) \
DIV_ROUND_CLOSEST_ULL((u64)(power) * MILLIWATT_PER_WATT, \
BIT(8))
#define VOLTAGE_SCALE 4
#define VOLTAGE_VID_OFFSET_SCALE1 625
#define VOLTAGE_VID_OFFSET_SCALE2 100

View File

@@ -1348,7 +1348,7 @@ struct pptable_funcs {
u32 (*set_gfx_off_residency)(struct smu_context *smu, bool start);
/**
* @get_gfx_off_residency: Average GFXOFF residency % during the logging interval
* @get_gfx_off_residency: Live GFXOFF residency percentage
*/
u32 (*get_gfx_off_residency)(struct smu_context *smu, uint32_t *residency);

View File

@@ -144,6 +144,44 @@ typedef struct {
uint32_t MaxGfxClk;
} DpmClocks_t;
//Freq in MHz
//Voltage in milli volts with 2 fractional bits
typedef struct {
uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
uint32_t VPEClocks[NUM_VPE_DPM_LEVELS];
uint32_t FclkClocks_Freq[NUM_FCLK_DPM_LEVELS];
uint32_t FclkClocks_Voltage[NUM_FCLK_DPM_LEVELS];
uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
MemPstateTable_t MemPstateTable[NUM_MEM_PSTATE_LEVELS];
uint8_t NumDcfClkLevelsEnabled;
uint8_t NumDispClkLevelsEnabled; //Applies to both Dispclk and Dppclk
uint8_t NumSocClkLevelsEnabled;
uint8_t VpeClkLevelsEnabled;
uint8_t NumMemPstatesEnabled;
uint8_t NumFclkLevelsEnabled;
uint8_t Spare1;
uint8_t Spare2;
uint8_t Spare3;
uint8_t Spare4;
uint8_t Spare5[2];
uint32_t MinGfxClk;
uint32_t MaxGfxClk;
uint32_t Spare6[8];
uint32_t Spare7[8];
uint32_t Spare8[8];
uint32_t Spare9[8];
} DpmClocks_t_v15_0_5;
typedef struct {
uint16_t CoreFrequency[16]; //Target core frequency [MHz]
uint16_t CorePower[16]; //CAC calculated core power [mW]

View File

@@ -110,8 +110,10 @@
#define PPSMC_MSG_GetSlowPPTLimit 0x4C
#define PPSMC_MSG_GetGfxOffStatus 0x50
#define PPSMC_MSG_GetGfxOffEntryCount 0x51
#define PPSMC_MSG_LogGfxOffResidency 0x52
#define PPSMC_Message_Count 0x53
#define PPSMC_MSG_GfxOffResidencyLogReadSample 0x52
#define PPSMC_MSG_StopGfxOffResidencyLogging 0x53
#define PPSMC_MSG_StartGfxOffResidencyLogging 0x56
#define PPSMC_Message_Count 0x57
//Argument for PPSMC_MSG_GfxDeviceDriverReset
enum {

View File

@@ -252,7 +252,9 @@
__SMU_DUMMY_MAP(DriverMode2Reset), \
__SMU_DUMMY_MAP(GetGfxOffStatus), \
__SMU_DUMMY_MAP(GetGfxOffEntryCount), \
__SMU_DUMMY_MAP(LogGfxOffResidency), \
__SMU_DUMMY_MAP(StartGfxOffResidencyLogging), \
__SMU_DUMMY_MAP(GfxOffResidencyLogReadSample), \
__SMU_DUMMY_MAP(StopGfxOffResidencyLogging), \
__SMU_DUMMY_MAP(SetNumBadMemoryPagesRetired), \
__SMU_DUMMY_MAP(SetBadMemoryPagesRetiredFlagsPerChannel), \
__SMU_DUMMY_MAP(AllowGpo), \

View File

@@ -26,7 +26,7 @@
#include "amdgpu_smu.h"
#define SMU15_DRIVER_IF_VERSION_INV 0xFFFFFFFF
#define SMU15_DRIVER_IF_VERSION_SMU_V15_0 0x7
#define SMU15_DRIVER_IF_VERSION_SMU_V15_0 0x9
#define FEATURE_MASK(feature) (1ULL << feature)

View File

@@ -658,7 +658,7 @@ static int arcturus_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->VcnActivityPercentage;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->TemperatureEdge *

View File

@@ -158,12 +158,10 @@ cyan_skillfish_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->Current.MemclkFrequency;
break;
case METRICS_CURR_SOCKETPOWER:
*value = (metrics->Current.CurrentSocketPower << 8) /
1000;
*value = metrics->Current.CurrentSocketPower;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = (metrics->Average.CurrentSocketPower << 8) /
1000;
*value = metrics->Average.CurrentSocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->Current.GfxTemperature / 100 *

View File

@@ -602,7 +602,7 @@ static int navi10_get_legacy_smu_metrics_data(struct smu_context *smu,
*value = metrics->AverageUclkActivity;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->TemperatureEdge *
@@ -691,7 +691,7 @@ static int navi10_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->AverageUclkActivity;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->TemperatureEdge *
@@ -777,7 +777,7 @@ static int navi12_get_legacy_smu_metrics_data(struct smu_context *smu,
*value = metrics->AverageUclkActivity;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->TemperatureEdge *
@@ -866,7 +866,7 @@ static int navi12_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->AverageUclkActivity;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->TemperatureEdge *

View File

@@ -855,9 +855,10 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu,
metrics->AverageUclkActivity;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = use_metrics_v3 ? metrics_v3->AverageSocketPower << 8 :
use_metrics_v2 ? metrics_v2->AverageSocketPower << 8 :
metrics->AverageSocketPower << 8;
*value = use_metrics_v3 ? metrics_v3->AverageSocketPower :
use_metrics_v2 ? metrics_v2->AverageSocketPower :
metrics->AverageSocketPower;
*value *= MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = (use_metrics_v3 ? metrics_v3->TemperatureEdge :

View File

@@ -72,6 +72,12 @@ static const struct smu_feature_bits vangogh_dpm_features = {
}
};
/*
* SMU support new GFXOFF residency log interface since version 4.63.62.00,
* use this to get live readings of GFXOFF residency
*/
#define SUPPORT_LIVE_RESIDENCY_MSG_VERSION 0x043f3e00
static struct cmn2asic_msg_mapping vangogh_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0),
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 0),
@@ -142,7 +148,9 @@ static struct cmn2asic_msg_mapping vangogh_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(GetSlowPPTLimit, PPSMC_MSG_GetSlowPPTLimit, 0),
MSG_MAP(GetGfxOffStatus, PPSMC_MSG_GetGfxOffStatus, 0),
MSG_MAP(GetGfxOffEntryCount, PPSMC_MSG_GetGfxOffEntryCount, 0),
MSG_MAP(LogGfxOffResidency, PPSMC_MSG_LogGfxOffResidency, 0),
MSG_MAP(StartGfxOffResidencyLogging, PPSMC_MSG_StartGfxOffResidencyLogging, 0),
MSG_MAP(GfxOffResidencyLogReadSample, PPSMC_MSG_GfxOffResidencyLogReadSample, 0),
MSG_MAP(StopGfxOffResidencyLogging, PPSMC_MSG_StopGfxOffResidencyLogging, 0),
};
static struct cmn2asic_mapping vangogh_feature_mask_map[SMU_FEATURE_COUNT] = {
@@ -310,8 +318,7 @@ static int vangogh_get_legacy_smu_metrics_data(struct smu_context *smu,
*value = metrics->UvdActivity / 100;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = (metrics->CurrentSocketPower << 8) /
1000 ;
*value = metrics->CurrentSocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->GfxTemperature / 100 *
@@ -379,12 +386,10 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->Current.UvdActivity;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = (metrics->Average.CurrentSocketPower << 8) /
1000;
*value = metrics->Average.CurrentSocketPower;
break;
case METRICS_CURR_SOCKETPOWER:
*value = (metrics->Current.CurrentSocketPower << 8) /
1000;
*value = metrics->Current.CurrentSocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->Current.GfxTemperature / 100 *
@@ -2449,19 +2454,32 @@ static int vangogh_set_power_limit(struct smu_context *smu,
static u32 vangogh_set_gfxoff_residency(struct smu_context *smu, bool start)
{
int ret = 0;
u32 residency;
struct amdgpu_device *adev = smu->adev;
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
return 0;
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_LogGfxOffResidency,
start, &residency);
if (ret)
return ret;
if (smu->smc_fw_version < SUPPORT_LIVE_RESIDENCY_MSG_VERSION) {
u32 residency;
if (!start)
adev->gfx.gfx_off_residency = residency;
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxOffResidencyLogReadSample,
start, &residency);
if (ret)
return ret;
if (!start)
adev->gfx.gfx_off_residency = residency;
} else {
if (start) {
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_StartGfxOffResidencyLogging, NULL);
if (ret)
return ret;
} else {
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_StopGfxOffResidencyLogging, NULL);
if (ret)
return ret;
}
}
return ret;
}
@@ -2478,11 +2496,20 @@ static u32 vangogh_set_gfxoff_residency(struct smu_context *smu, bool start)
*/
static u32 vangogh_get_gfxoff_residency(struct smu_context *smu, uint32_t *residency)
{
int ret = 0;
struct amdgpu_device *adev = smu->adev;
*residency = adev->gfx.gfx_off_residency;
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
return 0;
return 0;
if (smu->smc_fw_version < SUPPORT_LIVE_RESIDENCY_MSG_VERSION) {
*residency = adev->gfx.gfx_off_residency;
} else {
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GfxOffResidencyLogReadSample,
residency);
}
return ret;
}
/**

View File

@@ -1215,9 +1215,10 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu,
((amdgpu_ip_version(adev, MP1_HWIP, 0) ==
IP_VERSION(12, 0, 0)) &&
(adev->pm.fw_version >= 0x373200)))
*value = metrics->CurrentSocketPower << 8;
*value = metrics->CurrentSocketPower *
MILLIWATT_PER_WATT;
else
*value = (metrics->CurrentSocketPower << 8) / 1000;
*value = metrics->CurrentSocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = (metrics->GfxTemperature / 100) *

View File

@@ -677,7 +677,8 @@ static int aldebaran_get_smu_metrics_data(struct smu_context *smu,
case METRICS_AVERAGE_SOCKETPOWER:
/* Valid power data is available only from primary die */
if (aldebaran_is_primary(smu))
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower *
MILLIWATT_PER_WATT;
else
ret = -EOPNOTSUPP;
break;

View File

@@ -807,7 +807,7 @@ static int smu_v13_0_0_get_smu_metrics_data(struct smu_context *smu,
metrics->Vcn1ActivityPercentage);
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->AvgTemperature[TEMP_EDGE] *

View File

@@ -434,7 +434,8 @@ int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu,
*value = SMUQ10_ROUND(metrics->DramBandwidthUtilization);
break;
case METRICS_CURR_SOCKETPOWER:
*value = SMUQ10_ROUND(metrics->SocketPower) << 8;
*value = SMUQ10_ROUND(metrics->SocketPower) *
MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_HOTSPOT:
*value = SMUQ10_ROUND(metrics->MaxSocketTemperature) *

View File

@@ -338,10 +338,10 @@ static int smu_v13_0_4_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->UvdActivity / 100;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = (metrics->AverageSocketPower << 8) / 1000;
*value = metrics->AverageSocketPower;
break;
case METRICS_CURR_SOCKETPOWER:
*value = (metrics->CurrentSocketPower << 8) / 1000;
*value = metrics->CurrentSocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->GfxTemperature / 100 *

View File

@@ -295,7 +295,7 @@ static int smu_v13_0_5_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->UvdActivity / 100;
break;
case METRICS_CURR_SOCKETPOWER:
*value = (metrics->CurrentSocketPower << 8) / 1000;
*value = metrics->CurrentSocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->GfxTemperature / 100 *

View File

@@ -1321,7 +1321,8 @@ static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu,
*value = SMUQ10_ROUND(GET_METRIC_FIELD(DramBandwidthUtilization, version));
break;
case METRICS_CURR_SOCKETPOWER:
*value = SMUQ10_ROUND(GET_METRIC_FIELD(SocketPower, version)) << 8;
*value = SMUQ10_ROUND(GET_METRIC_FIELD(SocketPower, version)) *
MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_HOTSPOT:
*value = SMUQ10_ROUND(GET_METRIC_FIELD(MaxSocketTemperature, version)) *

View File

@@ -817,7 +817,7 @@ static int smu_v13_0_7_get_smu_metrics_data(struct smu_context *smu,
*value = smu_safe_u16_nn(metrics->AverageUclkActivity);
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->AvgTemperature[TEMP_EDGE] *

View File

@@ -372,7 +372,7 @@ static int yellow_carp_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->UvdActivity / 100;
break;
case METRICS_CURR_SOCKETPOWER:
*value = (metrics->CurrentSocketPower << 8) / 1000;
*value = metrics->CurrentSocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->GfxTemperature / 100 *

View File

@@ -312,8 +312,7 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
break;
case METRICS_AVERAGE_SOCKETPOWER:
case METRICS_CURR_SOCKETPOWER:
*value = (metrics->SocketPower / 1000 << 8) +
(metrics->SocketPower % 1000 / 10);
*value = metrics->SocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->GfxTemperature / 100 *

View File

@@ -695,7 +695,7 @@ static int smu_v14_0_2_get_smu_metrics_data(struct smu_context *smu,
metrics->Vcn1ActivityPercentage);
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->AvgTemperature[TEMP_EDGE] *

View File

@@ -168,7 +168,7 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t_v15_0_5),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
@@ -178,7 +178,7 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
goto err0_out;
smu_table->metrics_time = 0;
smu_table->clocks_table = kzalloc_obj(DpmClocks_t);
smu_table->clocks_table = kzalloc_obj(DpmClocks_t_v15_0_5);
if (!smu_table->clocks_table)
goto err1_out;
@@ -378,8 +378,7 @@ static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu,
break;
case METRICS_AVERAGE_SOCKETPOWER:
case METRICS_CURR_SOCKETPOWER:
*value = (metrics->SocketPower / 1000 << 8) +
(metrics->SocketPower % 1000 / 10);
*value = metrics->SocketPower;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->GfxTemperature / 100 *
@@ -752,11 +751,48 @@ static int smu_v15_0_0_get_dpm_freq_by_index(struct smu_context *smu,
return 0;
}
static int smu_v15_0_5_get_dpm_freq_by_index(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t dpm_level,
uint32_t *freq)
{
DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
if (!clk_table || clk_type >= SMU_CLK_COUNT)
return -EINVAL;
switch (clk_type) {
case SMU_SOCCLK:
if (dpm_level >= clk_table->NumSocClkLevelsEnabled)
return -EINVAL;
*freq = clk_table->SocClocks[dpm_level];
break;
case SMU_UCLK:
case SMU_MCLK:
if (dpm_level >= clk_table->NumMemPstatesEnabled)
return -EINVAL;
*freq = clk_table->MemPstateTable[dpm_level].MemClk;
break;
case SMU_FCLK:
if (dpm_level >= clk_table->NumFclkLevelsEnabled)
return -EINVAL;
*freq = clk_table->FclkClocks_Freq[dpm_level];
break;
default:
return -EINVAL;
}
return 0;
}
static int smu_v15_0_common_get_dpm_freq_by_index(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t dpm_level,
uint32_t *freq)
{
if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
smu_v15_0_5_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq);
else
smu_v15_0_0_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq);
return 0;
@@ -907,12 +943,116 @@ static int smu_v15_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
return ret;
}
static int smu_v15_0_5_get_dpm_ultimate_freq(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t *min,
uint32_t *max)
{
DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
uint32_t clock_limit;
uint32_t max_dpm_level, min_dpm_level;
int ret = 0;
if (!smu_v15_0_0_clk_dpm_is_enabled(smu, clk_type)) {
switch (clk_type) {
case SMU_MCLK:
case SMU_UCLK:
clock_limit = smu->smu_table.boot_values.uclk;
break;
case SMU_FCLK:
clock_limit = smu->smu_table.boot_values.fclk;
break;
case SMU_GFXCLK:
case SMU_SCLK:
clock_limit = smu->smu_table.boot_values.gfxclk;
break;
case SMU_SOCCLK:
clock_limit = smu->smu_table.boot_values.socclk;
break;
default:
clock_limit = 0;
break;
}
/* clock in Mhz unit */
if (min)
*min = clock_limit / 100;
if (max)
*max = clock_limit / 100;
return 0;
}
if (max) {
switch (clk_type) {
case SMU_GFXCLK:
case SMU_SCLK:
*max = clk_table->MaxGfxClk;
break;
case SMU_MCLK:
case SMU_UCLK:
max_dpm_level = 0;
break;
case SMU_FCLK:
max_dpm_level = clk_table->NumFclkLevelsEnabled - 1;
break;
case SMU_SOCCLK:
max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1;
break;
default:
ret = -EINVAL;
goto failed;
}
if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
ret = smu_v15_0_common_get_dpm_freq_by_index(smu, clk_type,
max_dpm_level, max);
if (ret)
goto failed;
}
}
if (min) {
switch (clk_type) {
case SMU_GFXCLK:
case SMU_SCLK:
*min = clk_table->MinGfxClk;
break;
case SMU_MCLK:
case SMU_UCLK:
min_dpm_level = clk_table->NumMemPstatesEnabled - 1;
break;
case SMU_FCLK:
min_dpm_level = 0;
break;
case SMU_SOCCLK:
min_dpm_level = 0;
break;
default:
ret = -EINVAL;
goto failed;
}
if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
ret = smu_v15_0_common_get_dpm_freq_by_index(smu, clk_type,
min_dpm_level, min);
if (ret)
goto failed;
}
}
failed:
return ret;
}
static int smu_v15_0_common_get_dpm_ultimate_freq(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t *min,
uint32_t *max)
{
if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
smu_v15_0_5_get_dpm_ultimate_freq(smu, clk_type, min, max);
else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
smu_v15_0_0_get_dpm_ultimate_freq(smu, clk_type, min, max);
return 0;
@@ -986,11 +1126,36 @@ static int smu_v15_0_0_get_dpm_level_count(struct smu_context *smu,
return 0;
}
static int smu_v15_0_5_get_dpm_level_count(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t *count)
{
DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
switch (clk_type) {
case SMU_SOCCLK:
*count = clk_table->NumSocClkLevelsEnabled;
break;
case SMU_MCLK:
*count = clk_table->NumMemPstatesEnabled;
break;
case SMU_FCLK:
*count = clk_table->NumFclkLevelsEnabled;
break;
default:
break;
}
return 0;
}
static int smu_v15_0_common_get_dpm_level_count(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t *count)
{
if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
smu_v15_0_5_get_dpm_level_count(smu, clk_type, count);
else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
smu_v15_0_0_get_dpm_level_count(smu, clk_type, count);
return 0;
@@ -1363,9 +1528,24 @@ static int smu_v15_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *sm
return 0;
}
static int smu_v15_0_5_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
{
DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
smu->gfx_actual_hard_min_freq = 0;
smu->gfx_actual_soft_max_freq = 0;
return 0;
}
static int smu_v15_0_common_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
{
smu_v15_0_0_set_fine_grain_gfx_freq_parameters(smu);
if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
smu_v15_0_5_set_fine_grain_gfx_freq_parameters(smu);
else
smu_v15_0_0_set_fine_grain_gfx_freq_parameters(smu);
return 0;
}
@@ -1405,9 +1585,36 @@ static int smu_v15_0_0_get_dpm_table(struct smu_context *smu, struct dpm_clocks
return 0;
}
static int smu_v15_0_5_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
{
DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
uint8_t idx;
/*
* Only the Clock information of SOC and
* VPE is copied to provide VPE DPM settings for use.
*/
for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) {
clock_table->SocClocks[idx].Freq =
(idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0;
clock_table->SocClocks[idx].Vol = 0;
}
for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) {
clock_table->VPEClocks[idx].Freq =
(idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0;
clock_table->VPEClocks[idx].Vol = 0;
}
return 0;
}
static int smu_v15_0_common_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
{
smu_v15_0_0_get_dpm_table(smu, clock_table);
if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
smu_v15_0_5_get_dpm_table(smu, clock_table);
else
smu_v15_0_0_get_dpm_table(smu, clock_table);
return 0;
}

View File

@@ -411,7 +411,8 @@ static int smu_v15_0_8_get_smu_metrics_data(struct smu_context *smu,
*value = SMUQ10_ROUND(metrics->DramBandwidthUtilization);
break;
case METRICS_CURR_SOCKETPOWER:
*value = SMUQ10_ROUND(metrics->SocketPower) << 8;
*value = SMUQ10_ROUND(metrics->SocketPower) *
MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_HOTSPOT:
*value = SMUQ10_ROUND(metrics->MaxSocketTemperature) *

View File

@@ -40,6 +40,13 @@ static int display_connector_attach(struct drm_bridge *bridge,
return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
}
static void display_connector_destroy(struct drm_bridge *bridge)
{
struct display_connector *conn = to_display_connector(bridge);
i2c_put_adapter(conn->bridge.ddc);
}
static enum drm_connector_status display_connector_detect(struct drm_bridge *bridge)
{
struct display_connector *conn = to_display_connector(bridge);
@@ -177,6 +184,7 @@ static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge,
static const struct drm_bridge_funcs display_connector_bridge_funcs = {
.attach = display_connector_attach,
.destroy = display_connector_destroy,
.detect = display_connector_bridge_detect,
.edid_read = display_connector_edid_read,
.atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts,
@@ -403,9 +411,6 @@ static void display_connector_remove(struct platform_device *pdev)
regulator_disable(conn->supply);
drm_bridge_remove(&conn->bridge);
if (!IS_ERR(conn->bridge.ddc))
i2c_put_adapter(conn->bridge.ddc);
}
static const struct of_device_id display_connector_match[] = {

View File

@@ -3686,6 +3686,18 @@ int drm_dp_get_pcon_max_frl_bw(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
int bw;
u8 buf;
if (!drm_dp_is_branch(dpcd))
return 0;
if (dpcd[DP_DPCD_REV] < 0x11)
return 0;
if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
return 0;
if ((port_cap[0] & DP_DS_PORT_TYPE_MASK) != DP_DS_PORT_TYPE_HDMI)
return 0;
buf = port_cap[2];
bw = buf & DP_PCON_MAX_FRL_BW;

View File

@@ -3501,6 +3501,8 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state,
}
intel_ddi_buf_enable(encoder, buf_ctl);
intel_hdmi_poll_for_scrambling_enable(crtc_state, connector);
}
static void intel_ddi_enable(struct intel_atomic_state *state,

View File

@@ -4242,7 +4242,14 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
rate_per_lane = info->hdmi.max_frl_rate_per_lane;
max_frl_rate = max_lanes * rate_per_lane;
if (info->hdmi.dsc_cap.v_1p2) {
/*
* The sink's DSC max FRL rate only applies to compressed video
* transport, which requires a DSC 1.2 encoder in the PCON. Without
* one the HDMI link always carries uncompressed video, for which
* the regular max FRL rate is the limit.
*/
if (drm_dp_pcon_enc_is_dsc_1_2(intel_dp->pcon_dsc_dpcd) &&
info->hdmi.dsc_cap.v_1p2) {
max_dsc_lanes = info->hdmi.dsc_cap.max_lanes;
dsc_rate_per_lane = info->hdmi.dsc_cap.max_frl_rate_per_lane;
if (max_dsc_lanes && dsc_rate_per_lane)

View File

@@ -2728,6 +2728,32 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *_
drm_connector_attach_max_bpc_property(&connector->base, 8, 12);
}
/*
* HDMI 2.0 spec, section 6.1.3.1 (Scrambling Control): after
* enabling Scrambling_Enable and starting scrambled video
* transmission, poll Scrambling_Status for up to 200 ms.
*/
void
intel_hdmi_poll_for_scrambling_enable(const struct intel_crtc_state *crtc_state,
struct drm_connector *_connector)
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(crtc_state);
bool scrambling_enabled = false;
int ret;
if (!crtc_state->hdmi_scrambling)
return;
/* Poll for a max of 200 msec as per HDMI spec */
ret = poll_timeout_us(scrambling_enabled = drm_scdc_get_scrambling_status(&connector->base),
scrambling_enabled, 1000, 200 * 1000, false);
if (ret)
drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] Timed out waiting for scrambling enable\n",
connector->base.base.id, connector->base.name);
}
/*
* intel_hdmi_handle_sink_scrambling: handle sink scrambling/clock ratio setup
* @encoder: intel_encoder

View File

@@ -70,5 +70,7 @@ void hsw_read_infoframe(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
unsigned int type,
void *frame, ssize_t len);
void intel_hdmi_poll_for_scrambling_enable(const struct intel_crtc_state *crtc_state,
struct drm_connector *_connector);
#endif /* __INTEL_HDMI_H__ */

View File

@@ -726,8 +726,6 @@ static void pvr_queue_submit_job_to_cccb(struct pvr_job *job)
cmd->partial_render_geom_frag_fence.value = job->done_fence->seqno - 1;
}
trace_pvr_job_submit_fw(job);
/* Submit job to FW */
pvr_cccb_write_command_with_header(cccb, job->fw_ccb_cmd_type, job->cmd_len, job->cmd,
job->id, job->id);
@@ -802,6 +800,9 @@ static struct dma_fence *pvr_queue_run_job(struct drm_sched_job *sched_job)
job->hwrt,
frag_job->fw_ccb_cmd_type ==
ROGUE_FWIF_CCB_CMD_TYPE_FRAG_PR);
trace_pvr_job_submit_fw(geom_job);
trace_pvr_job_submit_fw(frag_job);
} else {
struct pvr_queue *queue = container_of(job->base.sched,
struct pvr_queue, scheduler);
@@ -809,6 +810,8 @@ static struct dma_fence *pvr_queue_run_job(struct drm_sched_job *sched_job)
pvr_cccb_send_kccb_kick(pvr_dev, &queue->cccb,
pvr_context_get_fw_addr(job->ctx) + queue->ctx_offset,
job->hwrt);
trace_pvr_job_submit_fw(job);
}
return dma_fence_get(job->done_fence);

View File

@@ -41,6 +41,17 @@ TRACE_EVENT(pvr_job_submit_ioctl,
__entry->count)
);
#define PVR_JOB_GET_HWRT_FW_ADDR(job) \
({ \
struct pvr_job *_job = (job); \
u32 _hwrt_fw_addr = 0; \
\
if (_job && _job->hwrt) \
pvr_fw_object_get_fw_addr(_job->hwrt->fw_obj, &_hwrt_fw_addr); \
\
_hwrt_fw_addr; \
})
#define PVR_JOB_TYPE_TO_STR(val) \
__print_symbolic(val, \
{ DRM_PVR_JOB_TYPE_GEOMETRY, "geometry" }, \
@@ -64,9 +75,7 @@ TRACE_EVENT(pvr_job_create,
__entry->ctx = job->ctx;
__entry->fw_obj = job->ctx->fw_obj;
pvr_fw_object_get_fw_addr(job->ctx->fw_obj, &__entry->fw_addr);
__entry->hwrt_addr = job->hwrt ?
job->hwrt->fw_obj->fw_addr_offset :
0;
__entry->hwrt_addr = PVR_JOB_GET_HWRT_FW_ADDR(job);
__entry->job = job;
__entry->job_type = job->type;
__entry->sync_op_count = sync_op_count;),
@@ -82,6 +91,7 @@ TRACE_EVENT(pvr_job_create,
);
#undef PVR_JOB_TYPE_TO_STR
#undef PVR_JOB_GET_HWRT_FW_ADDR
TRACE_EVENT(pvr_job_submit_fw,
TP_PROTO(struct pvr_job *job),

View File

@@ -154,10 +154,10 @@ static void mtk_crtc_reset(struct drm_crtc *crtc)
{
struct mtk_crtc_state *state;
if (crtc->state)
if (crtc->state) {
__drm_atomic_helper_crtc_destroy_state(crtc->state);
kfree(to_mtk_crtc_state(crtc->state));
kfree(to_mtk_crtc_state(crtc->state));
}
crtc->state = NULL;
state = kzalloc_obj(*state);

View File

@@ -625,6 +625,7 @@ static void mtk_disp_ovl_adaptor_master_unbind(struct device *dev)
struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
priv->children_bound = false;
component_unbind_all(dev, priv->mmsys_dev);
}
static const struct component_master_ops mtk_disp_ovl_adaptor_master_ops = {
@@ -651,12 +652,15 @@ static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev)
priv->mmsys_dev = pdev->dev.platform_data;
component_master_add_with_match(dev, &mtk_disp_ovl_adaptor_master_ops, match);
ret = component_master_add_with_match(dev, &mtk_disp_ovl_adaptor_master_ops, match);
if (ret)
return dev_err_probe(dev, ret, "Failed to add component master\n");
pm_runtime_enable(dev);
ret = component_add(dev, &mtk_disp_ovl_adaptor_comp_ops);
if (ret != 0) {
component_master_del(dev, &mtk_disp_ovl_adaptor_master_ops);
pm_runtime_disable(dev);
return dev_err_probe(dev, ret, "Failed to add component\n");
}
@@ -666,6 +670,7 @@ static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev)
static void mtk_disp_ovl_adaptor_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &mtk_disp_ovl_adaptor_comp_ops);
component_master_del(&pdev->dev, &mtk_disp_ovl_adaptor_master_ops);
pm_runtime_disable(&pdev->dev);
}

View File

@@ -743,8 +743,6 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
mtk_dsi_set_vm_cmd(dsi);
mtk_dsi_config_vdo_timing(dsi);
mtk_dsi_set_interrupt_enable(dsi);
mtk_dsi_lane_ready(dsi);
mtk_dsi_clk_hs_mode(dsi, 1);
return 0;
err_disable_engine_clk:
@@ -858,6 +856,9 @@ static void mtk_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
ret = mtk_dsi_poweron(dsi);
if (ret < 0)
drm_err(drm, "failed to power on dsi\n");
mtk_dsi_lane_ready(dsi);
mtk_dsi_clk_hs_mode(dsi, 1);
}
static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,

View File

@@ -290,6 +290,13 @@ static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struc
return 0;
}
static void mtk_hdmi_put_adapter(void *_adap)
{
struct i2c_adapter *adap = _adap;
i2c_put_adapter(adap);
}
static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device *pdev,
const char * const *clk_names, size_t num_clocks)
{
@@ -328,12 +335,12 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device
if (!i2c_np)
return dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
hdmi->ddc_adpt = of_get_i2c_adapter_by_node(i2c_np);
of_node_put(i2c_np);
if (!hdmi->ddc_adpt)
return dev_err_probe(dev, -EPROBE_DEFER, "Failed to get ddc i2c adapter by node\n");
ret = devm_add_action_or_reset(dev, mtk_hdmi_put_device, &hdmi->ddc_adpt->dev);
ret = devm_add_action_or_reset(dev, mtk_hdmi_put_adapter, hdmi->ddc_adpt);
if (ret)
return ret;

View File

@@ -1499,13 +1499,6 @@ static int mtk_hdmi_v2_probe(struct platform_device *pdev)
return 0;
}
static void mtk_hdmi_v2_remove(struct platform_device *pdev)
{
struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
i2c_put_adapter(hdmi->ddc_adpt);
}
static const struct of_device_id mtk_drm_hdmi_v2_of_ids[] = {
{ .compatible = "mediatek,mt8188-hdmi-tx", .data = &mtk_hdmi_conf_mt8188 },
{ .compatible = "mediatek,mt8195-hdmi-tx", .data = &mtk_hdmi_conf_mt8195 },
@@ -1515,7 +1508,6 @@ MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_v2_of_ids);
static struct platform_driver mtk_hdmi_v2_driver = {
.probe = mtk_hdmi_v2_probe,
.remove = mtk_hdmi_v2_remove,
.driver = {
.name = "mediatek-drm-hdmi-v2",
.of_match_table = mtk_drm_hdmi_v2_of_ids,

View File

@@ -545,6 +545,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
struct panthor_fw_binary_section_entry_hdr hdr;
struct panthor_fw_section *section;
u32 section_size;
u32 data_size;
u32 name_len;
int ret;
@@ -595,6 +596,13 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
return -EINVAL;
}
section_size = hdr.va.end - hdr.va.start;
data_size = hdr.data.end - hdr.data.start;
if (data_size > section_size) {
drm_err(&ptdev->base, "Firmware corrupted, section data exceeds section size\n");
return -EINVAL;
}
name_len = iter->size - iter->offset;
section = drmm_kzalloc(&ptdev->base, sizeof(*section), GFP_KERNEL);
@@ -603,7 +611,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
list_add_tail(&section->node, &ptdev->fw->sections);
section->flags = hdr.flags;
section->data.size = hdr.data.end - hdr.data.start;
section->data.size = data_size;
if (section->data.size > 0) {
void *data = drmm_kmalloc(&ptdev->base, section->data.size, GFP_KERNEL);
@@ -626,7 +634,6 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
section->name = name;
}
section_size = hdr.va.end - hdr.va.start;
if (section_size) {
u32 cache_mode = hdr.flags & CSF_FW_BINARY_IFACE_ENTRY_CACHE_MODE_MASK;
struct panthor_gem_object *bo;
@@ -857,18 +864,24 @@ static int panthor_fw_load(struct panthor_device *ptdev)
* iface_fw_to_cpu_addr() - Turn an MCU address into a CPU address
* @ptdev: Device.
* @mcu_va: MCU address.
* @size: Size of the object pointed to by @mcu_va.
*
* Return: NULL if the address is not part of the shared section, non-NULL otherwise.
* Return: NULL if the object is not part of the shared section, non-NULL otherwise.
*/
static void *iface_fw_to_cpu_addr(struct panthor_device *ptdev, u32 mcu_va)
static void *iface_fw_to_cpu_addr(struct panthor_device *ptdev, u32 mcu_va, size_t size)
{
u64 shared_mem_start = panthor_kernel_bo_gpuva(ptdev->fw->shared_section->mem);
u64 shared_mem_end = shared_mem_start +
panthor_kernel_bo_size(ptdev->fw->shared_section->mem);
if (mcu_va < shared_mem_start || mcu_va >= shared_mem_end)
size_t shared_mem_size = panthor_kernel_bo_size(ptdev->fw->shared_section->mem);
u64 offset;
if (mcu_va < shared_mem_start)
return NULL;
return ptdev->fw->shared_section->mem->kmap + (mcu_va - shared_mem_start);
offset = mcu_va - shared_mem_start;
if (offset > shared_mem_size || size > shared_mem_size - offset)
return NULL;
return ptdev->fw->shared_section->mem->kmap + offset;
}
static int panthor_init_cs_iface(struct panthor_device *ptdev,
@@ -890,8 +903,10 @@ static int panthor_init_cs_iface(struct panthor_device *ptdev,
spin_lock_init(&cs_iface->lock);
cs_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset;
cs_iface->input = iface_fw_to_cpu_addr(ptdev, cs_iface->control->input_va);
cs_iface->output = iface_fw_to_cpu_addr(ptdev, cs_iface->control->output_va);
cs_iface->input = iface_fw_to_cpu_addr(ptdev, cs_iface->control->input_va,
sizeof(*cs_iface->input));
cs_iface->output = iface_fw_to_cpu_addr(ptdev, cs_iface->control->output_va,
sizeof(*cs_iface->output));
if (!cs_iface->input || !cs_iface->output) {
drm_err(&ptdev->base, "Invalid stream control interface input/output VA");
@@ -941,8 +956,10 @@ static int panthor_init_csg_iface(struct panthor_device *ptdev,
spin_lock_init(&csg_iface->lock);
csg_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset;
csg_iface->input = iface_fw_to_cpu_addr(ptdev, csg_iface->control->input_va);
csg_iface->output = iface_fw_to_cpu_addr(ptdev, csg_iface->control->output_va);
csg_iface->input = iface_fw_to_cpu_addr(ptdev, csg_iface->control->input_va,
sizeof(*csg_iface->input));
csg_iface->output = iface_fw_to_cpu_addr(ptdev, csg_iface->control->output_va,
sizeof(*csg_iface->output));
if (csg_iface->control->stream_num < MIN_CS_PER_CSG ||
csg_iface->control->stream_num > MAX_CS_PER_CSG)
@@ -999,8 +1016,10 @@ static int panthor_fw_init_ifaces(struct panthor_device *ptdev)
return -EINVAL;
}
glb_iface->input = iface_fw_to_cpu_addr(ptdev, glb_iface->control->input_va);
glb_iface->output = iface_fw_to_cpu_addr(ptdev, glb_iface->control->output_va);
glb_iface->input = iface_fw_to_cpu_addr(ptdev, glb_iface->control->input_va,
sizeof(*glb_iface->input));
glb_iface->output = iface_fw_to_cpu_addr(ptdev, glb_iface->control->output_va,
sizeof(*glb_iface->output));
if (!glb_iface->input || !glb_iface->output) {
drm_err(&ptdev->base, "Invalid global control interface input/output VA");
return -EINVAL;

View File

@@ -104,7 +104,7 @@ vc4_overflow_mem_work(struct work_struct *work)
vc4->bin_alloc_overflow = BIT(bin_bo_slot);
V3D_WRITE(V3D_BPOA, bo->base.dma_addr + bin_bo_slot * vc4->bin_alloc_size);
V3D_WRITE(V3D_BPOS, bo->base.base.size);
V3D_WRITE(V3D_BPOS, vc4->bin_alloc_size);
V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM);
V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM);
spin_unlock_irqrestore(&vc4->job_lock, irqflags);

View File

@@ -385,6 +385,23 @@ validate_tile_binning_config(VALIDATE_ARGS)
return -EINVAL;
}
/* The tile state data array is 48 bytes per tile, and we put it at
* the start of a BO containing both it and the tile alloc.
*/
tile_state_size = 48 * tile_count;
/* Since the tile alloc array will follow us, align. */
tile_state_size = roundup(tile_state_size, 4096);
/* Reject configurations whose tile state would leave no room for
* the tile alloc pool that follows it in the slot.
*/
if (tile_state_size >= vc4->bin_alloc_size) {
DRM_DEBUG("Tile binning config of %dx%d too large\n",
exec->bin_tiles_x, exec->bin_tiles_y);
return -EINVAL;
}
bin_slot = vc4_v3d_get_bin_slot(vc4);
if (bin_slot < 0) {
if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) {
@@ -400,13 +417,13 @@ validate_tile_binning_config(VALIDATE_ARGS)
exec->bin_slots |= BIT(bin_slot);
bin_addr = vc4->bin_bo->base.dma_addr + bin_slot * vc4->bin_alloc_size;
/* The tile state data array is 48 bytes per tile, and we put it at
* the start of a BO containing both it and the tile alloc.
*/
tile_state_size = 48 * tile_count;
exec->tile_alloc_offset = bin_addr + tile_state_size;
/* Since the tile alloc array will follow us, align. */
exec->tile_alloc_offset = bin_addr + roundup(tile_state_size, 4096);
/* The TSDA area must be zeroed out before use, otherwise the PTB might
* consume a stale tile state.
*/
memset(vc4->bin_bo->base.vaddr + bin_slot * vc4->bin_alloc_size, 0,
tile_state_size);
*(uint8_t *)(validated + 14) =
((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK |

View File

@@ -547,14 +547,17 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
if (IS_ERR(dma_buf))
return PTR_ERR(dma_buf);
if (dma_buf->ops != &tdev->ops)
return -ENOSYS;
if (dma_buf->ops != &tdev->ops) {
ret = -ENOSYS;
goto out;
}
prime = (struct ttm_prime_object *) dma_buf->priv;
base = &prime->base;
*handle = base->handle;
ret = ttm_ref_object_add(tfile, base, NULL, false);
out:
dma_buf_put(dma_buf);
return ret;

View File

@@ -30,6 +30,7 @@
#include "vmwgfx_bo.h"
#include <linux/highmem.h>
#include <linux/overflow.h>
/*
* Template that implements find_first_diff() for a generic
@@ -463,19 +464,42 @@ static int vmw_external_bo_copy(struct vmw_bo *dst, u32 dst_offset,
container_of(dst->tbo.bdev, struct vmw_private, bdev);
size_t dst_size = dst->tbo.resource->size;
size_t src_size = src->tbo.resource->size;
size_t dst_end, src_end;
struct iosys_map dst_map = {0};
struct iosys_map src_map = {0};
bool dst_mapped = false;
bool src_mapped = false;
int ret, i;
int x_in_bytes;
u8 *vsrc;
u8 *vdst;
if (!height || !width_in_bytes)
return 0;
if (!dst_stride || !src_stride)
return -EINVAL;
if (dst_stride < width_in_bytes || src_stride < width_in_bytes)
return -EINVAL;
if (check_mul_overflow((size_t)dst_stride, (size_t)height - 1, &dst_end) ||
check_add_overflow(dst_end, (size_t)width_in_bytes, &dst_end) ||
check_add_overflow((size_t)dst_offset, dst_end, &dst_end) ||
dst_end > dst_size ||
check_mul_overflow((size_t)src_stride, (size_t)height - 1, &src_end) ||
check_add_overflow(src_end, (size_t)width_in_bytes, &src_end) ||
check_add_overflow((size_t)src_offset, src_end, &src_end) ||
src_end > src_size) {
drm_dbg_driver(&vmw->drm, "Out-of-bounds external BO copy\n");
return -EINVAL;
}
vsrc = map_external(src, &src_map);
if (!vsrc) {
drm_dbg_driver(&vmw->drm, "Wasn't able to map src\n");
ret = -ENOMEM;
goto out;
}
src_mapped = true;
vdst = map_external(dst, &dst_map);
if (!vdst) {
@@ -483,16 +507,13 @@ static int vmw_external_bo_copy(struct vmw_bo *dst, u32 dst_offset,
ret = -ENOMEM;
goto out;
}
dst_mapped = true;
vsrc += src_offset;
vdst += dst_offset;
if (src_stride == dst_stride) {
dst_size -= dst_offset;
src_size -= src_offset;
memcpy(vdst, vsrc,
min(dst_stride * height, min(dst_size, src_size)));
if (src_stride == dst_stride && width_in_bytes == dst_stride) {
memcpy(vdst, vsrc, dst_stride * (size_t)height);
} else {
WARN_ON(dst_stride < width_in_bytes);
for (i = 0; i < height; ++i) {
memcpy(vdst, vsrc, width_in_bytes);
vsrc += src_stride;
@@ -508,8 +529,10 @@ static int vmw_external_bo_copy(struct vmw_bo *dst, u32 dst_offset,
ret = 0;
out:
unmap_external(src, &src_map);
unmap_external(dst, &dst_map);
if (src_mapped)
unmap_external(src, &src_map);
if (dst_mapped)
unmap_external(dst, &dst_map);
return ret;
}

View File

@@ -432,6 +432,7 @@ vmw_cursor_mob_map(struct vmw_plane_state *vps)
u32 size = vmw_cursor_mob_size(vps->cursor.update_type,
vps->base.crtc_w, vps->base.crtc_h);
struct vmw_bo *vbo = vps->cursor.mob;
void *map;
if (!vbo)
return -EINVAL;
@@ -446,11 +447,15 @@ vmw_cursor_mob_map(struct vmw_plane_state *vps)
if (unlikely(ret != 0))
return -ENOMEM;
vmw_bo_map_and_cache(vbo);
map = vmw_bo_map_and_cache(vbo);
if (!map) {
vmw_bo_unmap(vbo);
ret = -ENOMEM;
}
ttm_bo_unreserve(&vbo->tbo);
return 0;
return ret;
}
/**
@@ -663,9 +668,15 @@ int vmw_cursor_plane_prepare_fb(struct drm_plane *plane,
!vmw_cursor_buffer_changed(vps, old_vps)) {
vps->cursor.update_type =
VMW_CURSOR_UPDATE_NONE;
} else {
vmw_cursor_mob_get(vcp, vps);
vmw_cursor_mob_map(vps);
} else if (vps->cursor.update_type ==
VMW_CURSOR_UPDATE_MOB &&
(vmw_cursor_mob_get(vcp, vps) ||
vmw_cursor_mob_map(vps))) {
/*
* Reset the cursor to avoid crashes later.
*/
vps->cursor.update_type =
VMW_CURSOR_UPDATE_NONE;
}
}
}
@@ -732,6 +743,34 @@ int vmw_cursor_plane_atomic_check(struct drm_plane *plane,
"surface not suitable for cursor\n");
return -EINVAL;
}
} else if (update_type == VMW_CURSOR_UPDATE_GB_ONLY ||
update_type == VMW_CURSOR_UPDATE_MOB) {
u32 cursor_max_dim =
vmw_read(vmw, SVGA_REG_CURSOR_MAX_DIMENSION);
if (new_state->crtc_w > cursor_max_dim ||
new_state->crtc_h > cursor_max_dim) {
drm_warn(&vmw->drm,
"Cursor dimensions (%d, %d) exceed device max %u\n",
new_state->crtc_w, new_state->crtc_h,
cursor_max_dim);
return -EINVAL;
}
if (update_type == VMW_CURSOR_UPDATE_MOB) {
u32 mob_max_size =
vmw_read(vmw, SVGA_REG_MOB_MAX_SIZE);
u64 mob_size = (u64)new_state->crtc_w *
new_state->crtc_h * sizeof(u32) +
sizeof(SVGAGBCursorHeader);
if (mob_size > mob_max_size) {
drm_warn(&vmw->drm,
"Cursor MOB size %llu exceeds device max %u\n",
mob_size, mob_max_size);
return -EINVAL;
}
}
}
return 0;

View File

@@ -1272,9 +1272,13 @@ static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv,
SVGA3dCmdHeader *header)
{
VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindQuery);
struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
struct vmw_bo *vmw_bo;
int ret;
if (!ctx_node)
return -EINVAL;
cmd = container_of(header, typeof(*cmd), header);
/*
@@ -1288,7 +1292,7 @@ static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv,
return ret;
sw_context->dx_query_mob = vmw_bo;
sw_context->dx_query_ctx = sw_context->dx_ctx_node->ctx;
sw_context->dx_query_ctx = ctx_node->ctx;
return 0;
}
@@ -1506,6 +1510,12 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv,
bool dirty;
cmd = container_of(header, typeof(*cmd), header);
if (unlikely(header->size < sizeof(cmd->body) + sizeof(*suffix))) {
VMW_DEBUG_USER("Illegal SVGA_3D_CMD_SURFACE_DMA size.\n");
return -EINVAL;
}
suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->body +
header->size - sizeof(*suffix));
@@ -1567,11 +1577,17 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv,
uint32_t maxnum;
int ret;
cmd = container_of(header, typeof(*cmd), header);
if (unlikely(header->size < sizeof(cmd->body))) {
VMW_DEBUG_USER("Illegal DRAW_PRIMITIVES header size.\n");
return -EINVAL;
}
ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
if (unlikely(ret != 0))
return ret;
cmd = container_of(header, typeof(*cmd), header);
maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
if (unlikely(cmd->body.numVertexDecls > maxnum)) {

View File

@@ -367,13 +367,24 @@ void vmw_fence_fifo_down(struct vmw_fence_manager *fman)
ret = vmw_fence_obj_wait(fence, false, false,
VMW_FENCE_WAIT_TIMEOUT);
spin_lock(&fman->lock);
if (unlikely(ret != 0)) {
bool cookie = dma_fence_begin_signalling();
list_del_init(&fence->head);
dma_fence_signal(&fence->base);
if (fence->waiter_added) {
vmw_seqno_waiter_remove(fman->dev_priv);
fence->waiter_added = false;
}
dma_fence_signal_locked(&fence->base);
dma_fence_end_signalling(cookie);
}
BUG_ON(!list_empty(&fence->head));
spin_unlock(&fman->lock);
dma_fence_put(&fence->base);
spin_lock(&fman->lock);
}
spin_unlock(&fman->lock);

View File

@@ -311,7 +311,7 @@ void vmw_bo_dirty_transfer_to_res(struct vmw_resource *res)
return;
cur = max(res_start, dirty->start);
res_end = max(res_end, dirty->end);
res_end = min(res_end, dirty->end);
while (cur < res_end) {
unsigned long num;
@@ -347,7 +347,7 @@ void vmw_bo_dirty_clear(struct vmw_bo *vbo)
return;
cur = max(res_start, dirty->start);
res_end = max(res_end, dirty->end);
res_end = min(res_end, dirty->end);
while (cur < res_end) {
unsigned long num;

View File

@@ -136,7 +136,7 @@ static void vmw_resource_release(struct kref *kref)
val_buf.num_shared = 0;
res->func->unbind(res, false, &val_buf);
}
res->guest_memory_size = false;
res->guest_memory_dirty = false;
vmw_resource_mob_detach(res);
if (res->dirty)
res->func->dirty_free(res);
@@ -773,7 +773,7 @@ void vmw_resource_unbind_list(struct vmw_bo *vbo)
if (!WARN_ON_ONCE(!res->func->unbind))
(void) res->func->unbind(res, res->res_dirty, &val_buf);
res->guest_memory_size = true;
res->guest_memory_dirty = true;
res->res_dirty = false;
vmw_resource_mob_detach(res);
}

View File

@@ -25,6 +25,8 @@
*
**************************************************************************/
#include <linux/overflow.h>
#include <drm/ttm/ttm_placement.h>
#include "vmwgfx_binding.h"
@@ -685,7 +687,7 @@ int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data,
static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
struct vmw_bo *buffer,
size_t shader_size,
size_t offset,
u64 offset,
SVGA3dShaderType shader_type,
uint8_t num_input_sig,
uint8_t num_output_sig,
@@ -739,7 +741,7 @@ static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv,
struct vmw_bo *buffer,
size_t shader_size,
size_t offset,
u64 offset,
SVGA3dShaderType shader_type)
{
struct vmw_shader *shader;
@@ -768,7 +770,7 @@ static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv,
static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
enum drm_vmw_shader_type shader_type_drm,
u32 buffer_handle, size_t size, size_t offset,
u32 buffer_handle, size_t size, u64 offset,
uint8_t num_input_sig, uint8_t num_output_sig,
uint32_t *shader_handle)
{
@@ -779,13 +781,16 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
int ret;
if (buffer_handle != SVGA3D_INVALID_ID) {
u64 end;
ret = vmw_user_bo_lookup(file_priv, buffer_handle, &buffer);
if (unlikely(ret != 0)) {
VMW_DEBUG_USER("Couldn't find buffer for shader creation.\n");
return ret;
}
if ((u64)buffer->tbo.base.size < (u64)size + (u64)offset) {
if (check_add_overflow((u64)size, (u64)offset, &end) ||
end > buffer->tbo.base.size) {
VMW_DEBUG_USER("Illegal buffer- or shader size.\n");
ret = -EINVAL;
goto out_bad_arg;

View File

@@ -309,7 +309,8 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx,
}
node->res = vmw_resource_reference_unless_doomed(res);
if (!node->res) {
hash_del_rcu(&node->hash.head);
if (ctx->sw_context)
hash_del_rcu(&node->hash.head);
return -ESRCH;
}

View File

@@ -206,14 +206,14 @@ vmw_vkms_init(struct vmw_private *vmw)
vmw->vkms_enabled = false;
ret = vmw_host_get_guestinfo(GUESTINFO_VBLANK, buffer, &buf_len);
if (ret || buf_len > max_buf_len)
return;
buffer[buf_len] = '\0';
if (!ret && buf_len <= max_buf_len) {
buffer[buf_len] = '\0';
ret = kstrtobool(buffer, &vmw->vkms_enabled);
if (!ret && vmw->vkms_enabled) {
ret = drm_vblank_init(&vmw->drm, VMWGFX_NUM_DISPLAY_UNITS);
vmw->vkms_enabled = (ret == 0);
ret = kstrtobool(buffer, &vmw->vkms_enabled);
if (!ret && vmw->vkms_enabled) {
ret = drm_vblank_init(&vmw->drm, VMWGFX_NUM_DISPLAY_UNITS);
vmw->vkms_enabled = (ret == 0);
}
}
vmw->crc_workq = alloc_ordered_workqueue("vmwgfx_crc_generator", 0);
@@ -228,7 +228,8 @@ vmw_vkms_init(struct vmw_private *vmw)
void
vmw_vkms_cleanup(struct vmw_private *vmw)
{
destroy_workqueue(vmw->crc_workq);
if (vmw->crc_workq)
destroy_workqueue(vmw->crc_workq);
}
bool

View File

@@ -443,10 +443,6 @@ static bool xe_pt_hugepte_possible(u64 addr, u64 next, unsigned int level,
if (!xe_pt_covers(addr, next, level, &xe_walk->base))
return false;
/* Does the DMA segment cover the whole pte? */
if (next - xe_walk->va_curs_start > xe_walk->curs->size)
return false;
/* null VMA's and purged BO's do not have dma addresses */
if (xe_vma_is_null(xe_walk->vma) || (bo && xe_bo_is_purged(bo)))
return true;
@@ -455,6 +451,10 @@ static bool xe_pt_hugepte_possible(u64 addr, u64 next, unsigned int level,
if (xe_walk->clear_pt)
return true;
/* Does the DMA segment cover the whole pte? */
if (next - xe_walk->va_curs_start > xe_walk->curs->size)
return false;
/* Is the DMA address huge PTE size aligned? */
size = next - addr;
dma = addr - xe_walk->va_curs_start + xe_res_dma(xe_walk->curs);
@@ -775,8 +775,11 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
}
xe_walk.needs_64K = (vm->flags & XE_VM_FLAG_64K);
if (clear_pt)
if (clear_pt) {
xe_assert(xe, !range);
curs.size = xe_vma_size(vma);
goto walk_pt;
}
if (vma->gpuva.flags & XE_VMA_ATOMIC_PTE_BIT) {
xe_walk.default_vram_pte = xe_atomic_for_vram(vm, vma) ? XE_USM_PPGTT_PTE_AE : 0;