mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:44:45 +01:00
drm fixes for 7.0-rc2
i915/display: - Fix Panel Replay stuck with X during mode transitions on Panther Lake xe: - W/a fix for multi-cast registers - Fix xe_sync initialization issues amdgpu: - UserQ fixes - DC fix - RAS fixes - VCN 5 fix - Slot reset fix - Remove MES workaround that's no longer needed amdxdna: - deadlock fix - NULL ptr deref fix - suspend failure fix - OOB access fix - buffer overflow fix - input sanitiation fix - firmware loading fix dw-dp: - An error handling fix ethosu: - A binary shift overflow fix imx: - An error handling fix logicvc: - A dt node reference leak fix nouveau: - A WARN_ON removal samsung-dsim: - A memory leak fix tiny: - sharp-memory: NULL pointer deref fix vmwgfx: - A reference count and error handling fix -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmmhNZoACgkQDHTzWXnE hr4F0hAAoc+Lbq0tePa+I6Pf6Yjq/ufzqBSWvEjN+5mXjBuY2oUytpGrGzqASczr 03Q6zGVFzdXA5mJtRPxlhUVUn/SVbTGauTHs5wzZejiylw2+xngGAt81kIFab4km y2BLkOOCn96JhE/VqjrisydfwwXQD4TAbzpF12EZ4t+zyqmuEnuJ9TDTLcFDrOxn WfOY5neXtmntHavZ14IqghQNPUcj0x8KLC65BldNUfLdhnk5JwdsqdLwrID80fYW OBPGW1g1/4Ee4AKv+aKUB+1dm3fQGWh1K9C4Xh6g+OWIhn30Oo7BnTbu6N15GPN6 rle+t5jnxkxhNcxEQNA8l1WJgexBJz4wKixwf7XwrF21OMom+QhS9hboCwhunQt6 BTtw5HJubFXHRgEnTXiMeTLgW80TppDUjt5nEsy5CzP+5G8gqi1Xh3qMF0SjJHki Spxvt7Fh0qxHctzecOJi5aqVq2PiTeKNihI7OfZ5604OLlhbZE2WL556upJRLMz+ u5CrdB3gCJ5aSNQyi3bP0Rg25jE8/mobdWJSgn3n2Z8v/XKdFX+s7cxyZiyTBEYu aQuQAfVOh5l1VT1ydQ0tki/sHyZ2cWDTukKHR7li8rJPC0kkZc28IE8T2YML8+A8 1zgKhVHnTKoa/ngmTvmhBAfKaoLr+wgf646JGTllDw1z8hk5+3k= =/AzA -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2026-02-27' of https://gitlab.freedesktop.org/drm/kernel Pull drm fixes from Dave Airlie: "Regular fixes pull, amdxdna and amdgpu are the main ones, with a couple of intel fixes, then a scattering of fixes across drivers, nothing too major. i915/display: - Fix Panel Replay stuck with X during mode transitions on Panther Lake xe: - W/a fix for multi-cast registers - Fix xe_sync initialization issues amdgpu: - UserQ fixes - DC fix - RAS fixes - VCN 5 fix - Slot reset fix - Remove MES workaround that's no longer needed amdxdna: - deadlock fix - NULL ptr deref fix - suspend failure fix - OOB access fix - buffer overflow fix - input sanitiation fix - firmware loading fix dw-dp: - An error handling fix ethosu: - A binary shift overflow fix imx: - An error handling fix logicvc: - A dt node reference leak fix nouveau: - A WARN_ON removal samsung-dsim: - A memory leak fix tiny: - sharp-memory: NULL pointer deref fix vmwgfx: - A reference count and error handling fix" * tag 'drm-fixes-2026-02-27' of https://gitlab.freedesktop.org/drm/kernel: (39 commits) drm/amd: Disable MES LR compute W/A drm/amdgpu: Fix error handling in slot reset drm/amdgpu/vcn5: Add SMU dpm interface type drm/amdgpu: Fix locking bugs in error paths drm/amdgpu: Unlock a mutex before destroying it drm/amd/display: Use GFP_ATOMIC in dc_create_stream_for_sink drm/amdgpu: add upper bound check on user inputs in wait ioctl drm/amdgpu: add upper bound check on user inputs in signal ioctl drm/amdgpu/userq: Do not allow userspace to trivially triger kernel warnings drm/amdgpu/userq: Fix reference leak in amdgpu_userq_wait_ioctl accel/amdxdna: Use a different name for latest firmware drm/client: Do not destroy NULL modes drm/gpusvm: Fix drm_gpusvm_pages_valid_unlocked() kernel-doc drm/xe/sync: Fix user fence leak on alloc failure drm/xe/sync: Cleanup partially initialized sync on parse failure drm/xe/wa: Steer RMW of MCR registers while building default LRC accel/amdxdna: Validate command buffer payload count accel/amdxdna: Prevent ubuf size overflow accel/amdxdna: Fix out-of-bounds memset in command slot handling accel/amdxdna: Fix command hang on suspended hardware context ...
This commit is contained in:
commit
466d6175e3
40 changed files with 300 additions and 161 deletions
|
|
@ -23,9 +23,9 @@
|
|||
#include "amdxdna_pci_drv.h"
|
||||
#include "amdxdna_pm.h"
|
||||
|
||||
static bool force_cmdlist;
|
||||
static bool force_cmdlist = true;
|
||||
module_param(force_cmdlist, bool, 0600);
|
||||
MODULE_PARM_DESC(force_cmdlist, "Force use command list (Default false)");
|
||||
MODULE_PARM_DESC(force_cmdlist, "Force use command list (Default true)");
|
||||
|
||||
#define HWCTX_MAX_TIMEOUT 60000 /* milliseconds */
|
||||
|
||||
|
|
@ -53,6 +53,7 @@ static void aie2_hwctx_stop(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwct
|
|||
{
|
||||
drm_sched_stop(&hwctx->priv->sched, bad_job);
|
||||
aie2_destroy_context(xdna->dev_handle, hwctx);
|
||||
drm_sched_start(&hwctx->priv->sched, 0);
|
||||
}
|
||||
|
||||
static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwctx)
|
||||
|
|
@ -80,7 +81,6 @@ static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hw
|
|||
}
|
||||
|
||||
out:
|
||||
drm_sched_start(&hwctx->priv->sched, 0);
|
||||
XDNA_DBG(xdna, "%s restarted, ret %d", hwctx->name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -297,19 +297,23 @@ aie2_sched_job_run(struct drm_sched_job *sched_job)
|
|||
struct dma_fence *fence;
|
||||
int ret;
|
||||
|
||||
if (!hwctx->priv->mbox_chann)
|
||||
ret = amdxdna_pm_resume_get(hwctx->client->xdna);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
if (!mmget_not_zero(job->mm))
|
||||
if (!hwctx->priv->mbox_chann) {
|
||||
amdxdna_pm_suspend_put(hwctx->client->xdna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mmget_not_zero(job->mm)) {
|
||||
amdxdna_pm_suspend_put(hwctx->client->xdna);
|
||||
return ERR_PTR(-ESRCH);
|
||||
}
|
||||
|
||||
kref_get(&job->refcnt);
|
||||
fence = dma_fence_get(job->fence);
|
||||
|
||||
ret = amdxdna_pm_resume_get(hwctx->client->xdna);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (job->drv_cmd) {
|
||||
switch (job->drv_cmd->opcode) {
|
||||
case SYNC_DEBUG_BO:
|
||||
|
|
@ -497,7 +501,7 @@ static void aie2_release_resource(struct amdxdna_hwctx *hwctx)
|
|||
|
||||
if (AIE2_FEATURE_ON(xdna->dev_handle, AIE2_TEMPORAL_ONLY)) {
|
||||
ret = aie2_destroy_context(xdna->dev_handle, hwctx);
|
||||
if (ret)
|
||||
if (ret && ret != -ENODEV)
|
||||
XDNA_ERR(xdna, "Destroy temporal only context failed, ret %d", ret);
|
||||
} else {
|
||||
ret = xrs_release_resource(xdna->xrs_hdl, (uintptr_t)hwctx);
|
||||
|
|
@ -629,7 +633,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
|
|||
goto free_entity;
|
||||
}
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto free_col_list;
|
||||
|
||||
|
|
@ -760,7 +764,7 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size
|
|||
if (!hwctx->cus)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto free_cus;
|
||||
|
||||
|
|
@ -1070,6 +1074,8 @@ void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo,
|
|||
|
||||
ret = dma_resv_wait_timeout(gobj->resv, DMA_RESV_USAGE_BOOKKEEP,
|
||||
true, MAX_SCHEDULE_TIMEOUT);
|
||||
if (!ret || ret == -ERESTARTSYS)
|
||||
if (!ret)
|
||||
XDNA_ERR(xdna, "Failed to wait for bo, ret %ld", ret);
|
||||
else if (ret == -ERESTARTSYS)
|
||||
XDNA_DBG(xdna, "Wait for bo interrupted by signal");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,8 +216,10 @@ static int aie2_destroy_context_req(struct amdxdna_dev_hdl *ndev, u32 id)
|
|||
|
||||
req.context_id = id;
|
||||
ret = aie2_send_mgmt_msg_wait(ndev, &msg);
|
||||
if (ret)
|
||||
if (ret && ret != -ENODEV)
|
||||
XDNA_WARN(xdna, "Destroy context failed, ret %d", ret);
|
||||
else if (ret == -ENODEV)
|
||||
XDNA_DBG(xdna, "Destroy context: device already stopped");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -318,6 +320,9 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc
|
|||
struct amdxdna_dev *xdna = ndev->xdna;
|
||||
int ret;
|
||||
|
||||
if (!hwctx->priv->mbox_chann)
|
||||
return 0;
|
||||
|
||||
xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);
|
||||
ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
|
||||
xdna_mailbox_destroy_channel(hwctx->priv->mbox_chann);
|
||||
|
|
@ -694,11 +699,11 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz
|
|||
u32 cmd_len;
|
||||
void *cmd;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
if (*size < sizeof(*npu_slot) + cmd_len)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
|
@ -719,7 +724,6 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*sn);
|
||||
if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
|
|
@ -728,6 +732,7 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
if (*size < sizeof(*npu_slot) + arg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
|
@ -751,7 +756,6 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
|
|||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*pd);
|
||||
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
|
|
@ -760,6 +764,7 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
|
|||
if (*size < sizeof(*npu_slot) + arg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
|
@ -787,7 +792,6 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*pd);
|
||||
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
|
|
@ -796,6 +800,7 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
if (*size < sizeof(*npu_slot) + arg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->type = EXEC_NPU_TYPE_ELF;
|
||||
npu_slot->inst_buf_addr = pd->inst_buf;
|
||||
npu_slot->save_buf_addr = pd->save_buf;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ static int aie2_max_col = XRS_MAX_COL;
|
|||
module_param(aie2_max_col, uint, 0600);
|
||||
MODULE_PARM_DESC(aie2_max_col, "Maximum column could be used");
|
||||
|
||||
static char *npu_fw[] = {
|
||||
"npu_7.sbin",
|
||||
"npu.sbin"
|
||||
};
|
||||
|
||||
/*
|
||||
* The management mailbox channel is allocated by firmware.
|
||||
* The related register and ring buffer information is on SRAM BAR.
|
||||
|
|
@ -323,6 +328,7 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna)
|
|||
return;
|
||||
}
|
||||
|
||||
aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, NULL);
|
||||
aie2_mgmt_fw_fini(ndev);
|
||||
xdna_mailbox_stop_channel(ndev->mgmt_chann);
|
||||
xdna_mailbox_destroy_channel(ndev->mgmt_chann);
|
||||
|
|
@ -406,18 +412,18 @@ static int aie2_hw_start(struct amdxdna_dev *xdna)
|
|||
goto stop_psp;
|
||||
}
|
||||
|
||||
ret = aie2_pm_init(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to init pm, ret %d", ret);
|
||||
goto destroy_mgmt_chann;
|
||||
}
|
||||
|
||||
ret = aie2_mgmt_fw_init(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret);
|
||||
goto destroy_mgmt_chann;
|
||||
}
|
||||
|
||||
ret = aie2_pm_init(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to init pm, ret %d", ret);
|
||||
goto destroy_mgmt_chann;
|
||||
}
|
||||
|
||||
ret = aie2_mgmt_fw_query(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to query fw, ret %d", ret);
|
||||
|
|
@ -451,7 +457,6 @@ static int aie2_hw_suspend(struct amdxdna_dev *xdna)
|
|||
{
|
||||
struct amdxdna_client *client;
|
||||
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
list_for_each_entry(client, &xdna->client_list, node)
|
||||
aie2_hwctx_suspend(client);
|
||||
|
||||
|
|
@ -489,6 +494,7 @@ static int aie2_init(struct amdxdna_dev *xdna)
|
|||
struct psp_config psp_conf;
|
||||
const struct firmware *fw;
|
||||
unsigned long bars = 0;
|
||||
char *fw_full_path;
|
||||
int i, nvec, ret;
|
||||
|
||||
if (!hypervisor_is_type(X86_HYPER_NATIVE)) {
|
||||
|
|
@ -503,7 +509,19 @@ static int aie2_init(struct amdxdna_dev *xdna)
|
|||
ndev->priv = xdna->dev_info->dev_priv;
|
||||
ndev->xdna = xdna;
|
||||
|
||||
ret = request_firmware(&fw, ndev->priv->fw_path, &pdev->dev);
|
||||
for (i = 0; i < ARRAY_SIZE(npu_fw); i++) {
|
||||
fw_full_path = kasprintf(GFP_KERNEL, "%s%s", ndev->priv->fw_path, npu_fw[i]);
|
||||
if (!fw_full_path)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = firmware_request_nowarn(&fw, fw_full_path, &pdev->dev);
|
||||
kfree(fw_full_path);
|
||||
if (!ret) {
|
||||
XDNA_INFO(xdna, "Load firmware %s%s", ndev->priv->fw_path, npu_fw[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to request_firmware %s, ret %d",
|
||||
ndev->priv->fw_path, ret);
|
||||
|
|
@ -951,7 +969,7 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i
|
|||
if (!drm_dev_enter(&xdna->ddev, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto dev_exit;
|
||||
|
||||
|
|
@ -1044,7 +1062,7 @@ static int aie2_get_array(struct amdxdna_client *client,
|
|||
if (!drm_dev_enter(&xdna->ddev, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto dev_exit;
|
||||
|
||||
|
|
@ -1134,7 +1152,7 @@ static int aie2_set_state(struct amdxdna_client *client,
|
|||
if (!drm_dev_enter(&xdna->ddev, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto dev_exit;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = amdxdna_pm_resume_get(ndev->xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(ndev->xdna);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,10 @@ void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size)
|
|||
|
||||
if (size) {
|
||||
count = FIELD_GET(AMDXDNA_CMD_COUNT, cmd->header);
|
||||
if (unlikely(count <= num_masks)) {
|
||||
if (unlikely(count <= num_masks ||
|
||||
count * sizeof(u32) +
|
||||
offsetof(struct amdxdna_cmd, data[0]) >
|
||||
abo->mem.size)) {
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -266,9 +269,9 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr
|
|||
struct amdxdna_drm_config_hwctx *args = data;
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(dev);
|
||||
struct amdxdna_hwctx *hwctx;
|
||||
int ret, idx;
|
||||
u32 buf_size;
|
||||
void *buf;
|
||||
int ret;
|
||||
u64 val;
|
||||
|
||||
if (XDNA_MBZ_DBG(xdna, &args->pad, sizeof(args->pad)))
|
||||
|
|
@ -310,20 +313,17 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&xdna->dev_lock);
|
||||
idx = srcu_read_lock(&client->hwctx_srcu);
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
hwctx = xa_load(&client->hwctx_xa, args->handle);
|
||||
if (!hwctx) {
|
||||
XDNA_DBG(xdna, "PID %d failed to get hwctx %d", client->pid, args->handle);
|
||||
ret = -EINVAL;
|
||||
goto unlock_srcu;
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
ret = xdna->dev_info->ops->hwctx_config(hwctx, args->param_type, val, buf, buf_size);
|
||||
|
||||
unlock_srcu:
|
||||
srcu_read_unlock(&client->hwctx_srcu, idx);
|
||||
mutex_unlock(&xdna->dev_lock);
|
||||
free_buf:
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -334,7 +334,7 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl)
|
|||
struct amdxdna_hwctx *hwctx;
|
||||
struct amdxdna_gem_obj *abo;
|
||||
struct drm_gem_object *gobj;
|
||||
int ret, idx;
|
||||
int ret;
|
||||
|
||||
if (!xdna->dev_info->ops->hwctx_sync_debug_bo)
|
||||
return -EOPNOTSUPP;
|
||||
|
|
@ -345,17 +345,15 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl)
|
|||
|
||||
abo = to_xdna_obj(gobj);
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
idx = srcu_read_lock(&client->hwctx_srcu);
|
||||
hwctx = xa_load(&client->hwctx_xa, abo->assigned_hwctx);
|
||||
if (!hwctx) {
|
||||
ret = -EINVAL;
|
||||
goto unlock_srcu;
|
||||
goto put_obj;
|
||||
}
|
||||
|
||||
ret = xdna->dev_info->ops->hwctx_sync_debug_bo(hwctx, debug_bo_hdl);
|
||||
|
||||
unlock_srcu:
|
||||
srcu_read_unlock(&client->hwctx_srcu, idx);
|
||||
put_obj:
|
||||
drm_gem_object_put(gobj);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
#include "amdxdna_pci_drv.h"
|
||||
#include "amdxdna_ubuf.h"
|
||||
|
||||
#define XDNA_MAX_CMD_BO_SIZE SZ_32K
|
||||
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
|
||||
static int
|
||||
|
|
@ -745,12 +743,6 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev,
|
|||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(dev);
|
||||
struct amdxdna_gem_obj *abo;
|
||||
int ret;
|
||||
|
||||
if (args->size > XDNA_MAX_CMD_BO_SIZE) {
|
||||
XDNA_ERR(xdna, "Command bo size 0x%llx too large", args->size);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (args->size < sizeof(struct amdxdna_cmd)) {
|
||||
XDNA_DBG(xdna, "Command BO size 0x%llx too small", args->size);
|
||||
|
|
@ -764,17 +756,7 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev,
|
|||
abo->type = AMDXDNA_BO_CMD;
|
||||
abo->client = filp->driver_priv;
|
||||
|
||||
ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret);
|
||||
goto release_obj;
|
||||
}
|
||||
|
||||
return abo;
|
||||
|
||||
release_obj:
|
||||
drm_gem_object_put(to_gobj(abo));
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
int amdxdna_drm_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
|
|
@ -871,6 +853,7 @@ struct amdxdna_gem_obj *amdxdna_gem_get_obj(struct amdxdna_client *client,
|
|||
struct amdxdna_dev *xdna = client->xdna;
|
||||
struct amdxdna_gem_obj *abo;
|
||||
struct drm_gem_object *gobj;
|
||||
int ret;
|
||||
|
||||
gobj = drm_gem_object_lookup(client->filp, bo_hdl);
|
||||
if (!gobj) {
|
||||
|
|
@ -879,9 +862,26 @@ struct amdxdna_gem_obj *amdxdna_gem_get_obj(struct amdxdna_client *client,
|
|||
}
|
||||
|
||||
abo = to_xdna_obj(gobj);
|
||||
if (bo_type == AMDXDNA_BO_INVALID || abo->type == bo_type)
|
||||
if (bo_type != AMDXDNA_BO_INVALID && abo->type != bo_type)
|
||||
goto put_obj;
|
||||
|
||||
if (bo_type != AMDXDNA_BO_CMD || abo->mem.kva)
|
||||
return abo;
|
||||
|
||||
if (abo->mem.size > SZ_32K) {
|
||||
XDNA_ERR(xdna, "Cmd bo is too big %ld", abo->mem.size);
|
||||
goto put_obj;
|
||||
}
|
||||
|
||||
ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret);
|
||||
goto put_obj;
|
||||
}
|
||||
|
||||
return abo;
|
||||
|
||||
put_obj:
|
||||
drm_gem_object_put(gobj);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ MODULE_FIRMWARE("amdnpu/1502_00/npu.sbin");
|
|||
MODULE_FIRMWARE("amdnpu/17f0_10/npu.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_11/npu.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/1502_00/npu_7.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_10/npu_7.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_11/npu_7.sbin");
|
||||
|
||||
/*
|
||||
* 0.0: Initial version
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ int amdxdna_pm_suspend(struct device *dev)
|
|||
struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
if (xdna->dev_info->ops->suspend)
|
||||
ret = xdna->dev_info->ops->suspend(xdna);
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ int amdxdna_pm_resume(struct device *dev)
|
|||
struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
if (xdna->dev_info->ops->resume)
|
||||
ret = xdna->dev_info->ops->resume(xdna);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,4 +15,15 @@ void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna);
|
|||
void amdxdna_pm_init(struct amdxdna_dev *xdna);
|
||||
void amdxdna_pm_fini(struct amdxdna_dev *xdna);
|
||||
|
||||
static inline int amdxdna_pm_resume_get_locked(struct amdxdna_dev *xdna)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_unlock(&xdna->dev_lock);
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
mutex_lock(&xdna->dev_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _AMDXDNA_PM_H_ */
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_print.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
|
|
@ -176,7 +177,10 @@ struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev,
|
|||
goto free_ent;
|
||||
}
|
||||
|
||||
exp_info.size += va_ent[i].len;
|
||||
if (check_add_overflow(exp_info.size, va_ent[i].len, &exp_info.size)) {
|
||||
ret = -EINVAL;
|
||||
goto free_ent;
|
||||
}
|
||||
}
|
||||
|
||||
ubuf->nr_pages = exp_info.size >> PAGE_SHIFT;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = {
|
|||
};
|
||||
|
||||
static const struct amdxdna_dev_priv npu1_dev_priv = {
|
||||
.fw_path = "amdnpu/1502_00/npu.sbin",
|
||||
.fw_path = "amdnpu/1502_00/",
|
||||
.rt_config = npu1_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu1_dpm_clk_table,
|
||||
.fw_feature_tbl = npu1_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ const struct aie2_fw_feature_tbl npu4_fw_feature_table[] = {
|
|||
};
|
||||
|
||||
static const struct amdxdna_dev_priv npu4_dev_priv = {
|
||||
.fw_path = "amdnpu/17f0_10/npu.sbin",
|
||||
.fw_path = "amdnpu/17f0_10/",
|
||||
.rt_config = npu4_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu4_dpm_clk_table,
|
||||
.fw_feature_tbl = npu4_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
#define NPU5_SRAM_BAR_BASE MMNPU_APERTURE1_BASE
|
||||
|
||||
static const struct amdxdna_dev_priv npu5_dev_priv = {
|
||||
.fw_path = "amdnpu/17f0_11/npu.sbin",
|
||||
.fw_path = "amdnpu/17f0_11/",
|
||||
.rt_config = npu4_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu4_dpm_clk_table,
|
||||
.fw_feature_tbl = npu4_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
#define NPU6_SRAM_BAR_BASE MMNPU_APERTURE1_BASE
|
||||
|
||||
static const struct amdxdna_dev_priv npu6_dev_priv = {
|
||||
.fw_path = "amdnpu/17f0_10/npu.sbin",
|
||||
.fw_path = "amdnpu/17f0_10/",
|
||||
.rt_config = npu4_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu4_dpm_clk_table,
|
||||
.fw_feature_tbl = npu4_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ static void cmd_state_init(struct cmd_state *st)
|
|||
|
||||
static u64 cmd_to_addr(u32 *cmd)
|
||||
{
|
||||
return ((u64)((cmd[0] & 0xff0000) << 16)) | cmd[1];
|
||||
return (((u64)cmd[0] & 0xff0000) << 16) | cmd[1];
|
||||
}
|
||||
|
||||
static u64 dma_length(struct ethosu_validated_cmdstream_info *info,
|
||||
|
|
|
|||
|
|
@ -641,6 +641,7 @@ static void aca_error_fini(struct aca_error *aerr)
|
|||
aca_bank_error_remove(aerr, bank_error);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&aerr->lock);
|
||||
mutex_destroy(&aerr->lock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7059,6 +7059,15 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
|||
dev_info(adev->dev, "PCI error: slot reset callback!!\n");
|
||||
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive) {
|
||||
mutex_lock(&hive->hive_lock);
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
} else {
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
}
|
||||
|
||||
if (adev->pcie_reset_ctx.swus)
|
||||
link_dev = adev->pcie_reset_ctx.swus;
|
||||
|
|
@ -7099,19 +7108,13 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
|||
reset_context.reset_req_dev = adev;
|
||||
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive) {
|
||||
mutex_lock(&hive->hive_lock);
|
||||
reset_context.hive = hive;
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
|
||||
tmp_adev->pcie_reset_ctx.in_link_reset = true;
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
}
|
||||
} else {
|
||||
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
}
|
||||
|
||||
r = amdgpu_device_asic_reset(adev, &device_list, &reset_context);
|
||||
|
|
|
|||
|
|
@ -332,13 +332,13 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
|||
if (!context || !context->initialized) {
|
||||
dev_err(adev->dev, "TA is not initialized\n");
|
||||
ret = -EINVAL;
|
||||
goto err_free_shared_buf;
|
||||
goto free_shared_buf;
|
||||
}
|
||||
|
||||
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_invoke) {
|
||||
dev_err(adev->dev, "Unsupported function to invoke TA\n");
|
||||
ret = -EOPNOTSUPP;
|
||||
goto err_free_shared_buf;
|
||||
goto free_shared_buf;
|
||||
}
|
||||
|
||||
context->session_id = ta_id;
|
||||
|
|
@ -346,7 +346,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
|||
mutex_lock(&psp->ras_context.mutex);
|
||||
ret = prep_ta_mem_context(&context->mem_context, shared_buf, shared_buf_len);
|
||||
if (ret)
|
||||
goto err_free_shared_buf;
|
||||
goto unlock;
|
||||
|
||||
ret = psp_fn_ta_invoke(psp, cmd_id);
|
||||
if (ret || context->resp_status) {
|
||||
|
|
@ -354,15 +354,17 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
|||
ret, context->resp_status);
|
||||
if (!ret) {
|
||||
ret = -EINVAL;
|
||||
goto err_free_shared_buf;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user((char *)&buf[copy_pos], context->mem_context.shared_buf, shared_buf_len))
|
||||
ret = -EFAULT;
|
||||
|
||||
err_free_shared_buf:
|
||||
unlock:
|
||||
mutex_unlock(&psp->ras_context.mutex);
|
||||
|
||||
free_shared_buf:
|
||||
kfree(shared_buf);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
static const struct dma_fence_ops amdgpu_userq_fence_ops;
|
||||
static struct kmem_cache *amdgpu_userq_fence_slab;
|
||||
|
||||
#define AMDGPU_USERQ_MAX_HANDLES (1U << 16)
|
||||
|
||||
int amdgpu_userq_fence_slab_init(void)
|
||||
{
|
||||
amdgpu_userq_fence_slab = kmem_cache_create("amdgpu_userq_fence",
|
||||
|
|
@ -478,6 +480,11 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
|
|||
if (!amdgpu_userq_enabled(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (args->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
args->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
args->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
|
||||
return -EINVAL;
|
||||
|
||||
num_syncobj_handles = args->num_syncobj_handles;
|
||||
syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles),
|
||||
size_mul(sizeof(u32), num_syncobj_handles));
|
||||
|
|
@ -664,6 +671,11 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
if (!amdgpu_userq_enabled(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (wait_info->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
wait_info->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
wait_info->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
|
||||
return -EINVAL;
|
||||
|
||||
num_read_bo_handles = wait_info->num_bo_read_handles;
|
||||
bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles),
|
||||
size_mul(sizeof(u32), num_read_bo_handles));
|
||||
|
|
@ -833,7 +845,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
dma_resv_for_each_fence(&resv_cursor, gobj_read[i]->resv,
|
||||
DMA_RESV_USAGE_READ, fence) {
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
goto free_fences;
|
||||
}
|
||||
|
|
@ -850,7 +862,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
dma_resv_for_each_fence(&resv_cursor, gobj_write[i]->resv,
|
||||
DMA_RESV_USAGE_WRITE, fence) {
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
goto free_fences;
|
||||
}
|
||||
|
|
@ -874,8 +886,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
goto free_fences;
|
||||
|
||||
dma_fence_unwrap_for_each(f, &iter, fence) {
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
dma_fence_put(fence);
|
||||
goto free_fences;
|
||||
}
|
||||
|
||||
|
|
@ -898,8 +911,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
if (r)
|
||||
goto free_fences;
|
||||
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
dma_fence_put(fence);
|
||||
goto free_fences;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -720,11 +720,6 @@ static int mes_v11_0_set_hw_resources(struct amdgpu_mes *mes)
|
|||
mes_set_hw_res_pkt.enable_reg_active_poll = 1;
|
||||
mes_set_hw_res_pkt.enable_level_process_quantum_check = 1;
|
||||
mes_set_hw_res_pkt.oversubscription_timer = 50;
|
||||
if ((mes->adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x7f)
|
||||
mes_set_hw_res_pkt.enable_lr_compute_wa = 1;
|
||||
else
|
||||
dev_info_once(mes->adev->dev,
|
||||
"MES FW version must be >= 0x7f to enable LR compute workaround.\n");
|
||||
|
||||
if (amdgpu_mes_log_enable) {
|
||||
mes_set_hw_res_pkt.enable_mes_event_int_logging = 1;
|
||||
|
|
|
|||
|
|
@ -779,11 +779,6 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe)
|
|||
mes_set_hw_res_pkt.use_different_vmid_compute = 1;
|
||||
mes_set_hw_res_pkt.enable_reg_active_poll = 1;
|
||||
mes_set_hw_res_pkt.enable_level_process_quantum_check = 1;
|
||||
if ((mes->adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x82)
|
||||
mes_set_hw_res_pkt.enable_lr_compute_wa = 1;
|
||||
else
|
||||
dev_info_once(adev->dev,
|
||||
"MES FW version must be >= 0x82 to enable LR compute workaround.\n");
|
||||
|
||||
/*
|
||||
* Keep oversubscribe timer for sdma . When we have unmapped doorbell
|
||||
|
|
|
|||
|
|
@ -174,6 +174,10 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
|
||||
fw_shared->sq.is_enabled = 1;
|
||||
|
||||
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);
|
||||
fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
|
||||
AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;
|
||||
|
||||
if (amdgpu_vcnfw_log)
|
||||
amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
|
||||
|
||||
|
|
|
|||
|
|
@ -170,11 +170,11 @@ struct dc_stream_state *dc_create_stream_for_sink(
|
|||
if (sink == NULL)
|
||||
goto fail;
|
||||
|
||||
stream = kzalloc_obj(struct dc_stream_state);
|
||||
stream = kzalloc_obj(struct dc_stream_state, GFP_ATOMIC);
|
||||
if (stream == NULL)
|
||||
goto fail;
|
||||
|
||||
stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_KERNEL);
|
||||
stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_ATOMIC);
|
||||
if (stream->update_scratch == NULL)
|
||||
goto fail;
|
||||
|
||||
|
|
|
|||
|
|
@ -1881,6 +1881,14 @@ static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)
|
||||
{
|
||||
if (dsi->te_gpio) {
|
||||
free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
|
||||
gpiod_put(dsi->te_gpio);
|
||||
}
|
||||
}
|
||||
|
||||
static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
|
||||
struct mipi_dsi_device *device)
|
||||
{
|
||||
|
|
@ -1961,7 +1969,7 @@ of_find_panel_or_bridge:
|
|||
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
|
||||
ret = samsung_dsim_register_te_irq(dsi, &device->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_bridge;
|
||||
}
|
||||
|
||||
// The next bridge can be used by host_ops->attach
|
||||
|
|
@ -1982,15 +1990,12 @@ of_find_panel_or_bridge:
|
|||
err_release_next_bridge:
|
||||
drm_bridge_put(dsi->bridge.next_bridge);
|
||||
dsi->bridge.next_bridge = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)
|
||||
{
|
||||
if (dsi->te_gpio) {
|
||||
free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
|
||||
gpiod_put(dsi->te_gpio);
|
||||
}
|
||||
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO))
|
||||
samsung_dsim_unregister_te_irq(dsi);
|
||||
err_remove_bridge:
|
||||
drm_bridge_remove(&dsi->bridge);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
|
||||
|
|
|
|||
|
|
@ -2049,7 +2049,9 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
|
|||
bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
|
||||
bridge->ycbcr_420_allowed = true;
|
||||
|
||||
devm_drm_bridge_add(dev, bridge);
|
||||
ret = devm_drm_bridge_add(dev, bridge);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
dp->aux.dev = dev;
|
||||
dp->aux.drm_dev = encoder->dev;
|
||||
|
|
|
|||
|
|
@ -1415,6 +1415,7 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
|
|||
{
|
||||
struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);
|
||||
struct device_node *np = pdata->dev->of_node;
|
||||
const struct i2c_client *client = to_i2c_client(pdata->dev);
|
||||
int ret;
|
||||
|
||||
pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0);
|
||||
|
|
@ -1433,8 +1434,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
|
|||
? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;
|
||||
|
||||
if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) {
|
||||
pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT |
|
||||
DRM_BRIDGE_OP_HPD;
|
||||
pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
|
||||
if (client->irq)
|
||||
pdata->bridge.ops |= DRM_BRIDGE_OP_HPD;
|
||||
/*
|
||||
* If comms were already enabled they would have been enabled
|
||||
* with the wrong value of HPD_DISABLE. Update it now. Comms
|
||||
|
|
|
|||
|
|
@ -930,7 +930,8 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
|
|||
mutex_unlock(&client->modeset_mutex);
|
||||
out:
|
||||
kfree(crtcs);
|
||||
modes_destroy(dev, modes, connector_count);
|
||||
if (modes)
|
||||
modes_destroy(dev, modes, connector_count);
|
||||
kfree(modes);
|
||||
kfree(offsets);
|
||||
kfree(enabled);
|
||||
|
|
|
|||
|
|
@ -1338,14 +1338,14 @@ bool drm_gpusvm_range_pages_valid(struct drm_gpusvm *gpusvm,
|
|||
EXPORT_SYMBOL_GPL(drm_gpusvm_range_pages_valid);
|
||||
|
||||
/**
|
||||
* drm_gpusvm_range_pages_valid_unlocked() - GPU SVM range pages valid unlocked
|
||||
* drm_gpusvm_pages_valid_unlocked() - GPU SVM pages valid unlocked
|
||||
* @gpusvm: Pointer to the GPU SVM structure
|
||||
* @range: Pointer to the GPU SVM range structure
|
||||
* @svm_pages: Pointer to the GPU SVM pages structure
|
||||
*
|
||||
* This function determines if a GPU SVM range pages are valid. Expected be
|
||||
* called without holding gpusvm->notifier_lock.
|
||||
* This function determines if a GPU SVM pages are valid. Expected be called
|
||||
* without holding gpusvm->notifier_lock.
|
||||
*
|
||||
* Return: True if GPU SVM range has valid pages, False otherwise
|
||||
* Return: True if GPU SVM pages are valid, False otherwise
|
||||
*/
|
||||
static bool drm_gpusvm_pages_valid_unlocked(struct drm_gpusvm *gpusvm,
|
||||
struct drm_gpusvm_pages *svm_pages)
|
||||
|
|
|
|||
|
|
@ -562,12 +562,7 @@ void intel_alpm_disable(struct intel_dp *intel_dp)
|
|||
mutex_lock(&intel_dp->alpm.lock);
|
||||
|
||||
intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder),
|
||||
ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE |
|
||||
ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
|
||||
|
||||
intel_de_rmw(display,
|
||||
PORT_ALPM_CTL(cpu_transcoder),
|
||||
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
|
||||
ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE, 0);
|
||||
|
||||
drm_dbg_kms(display->drm, "Disabling ALPM\n");
|
||||
mutex_unlock(&intel_dp->alpm.lock);
|
||||
|
|
|
|||
|
|
@ -256,7 +256,9 @@ static int imx_pd_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, imxpd);
|
||||
|
||||
devm_drm_bridge_add(dev, &imxpd->bridge);
|
||||
ret = devm_drm_bridge_add(dev, &imxpd->bridge);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return component_add(dev, &imx_pd_ops);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ static int logicvc_drm_config_parse(struct logicvc_drm *logicvc)
|
|||
struct device *dev = drm_dev->dev;
|
||||
struct device_node *of_node = dev->of_node;
|
||||
struct logicvc_drm_config *config = &logicvc->config;
|
||||
struct device_node *layers_node;
|
||||
int ret;
|
||||
|
||||
logicvc_of_property_parse_bool(of_node, LOGICVC_OF_PROPERTY_DITHERING,
|
||||
|
|
@ -128,7 +127,8 @@ static int logicvc_drm_config_parse(struct logicvc_drm *logicvc)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
layers_node = of_get_child_by_name(of_node, "layers");
|
||||
struct device_node *layers_node __free(device_node) =
|
||||
of_get_child_by_name(of_node, "layers");
|
||||
if (!layers_node) {
|
||||
drm_err(drm_dev, "Missing non-optional layers node\n");
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -737,8 +737,8 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
|
|||
if (!obj)
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
if (obj->type != ACPI_TYPE_BUFFER ||
|
||||
obj->buffer.length != 4)
|
||||
goto done;
|
||||
|
||||
caps->status = 0;
|
||||
|
|
@ -773,8 +773,8 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt)
|
|||
if (!obj)
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
if (obj->type != ACPI_TYPE_BUFFER ||
|
||||
obj->buffer.length != 4)
|
||||
goto done;
|
||||
|
||||
jt->status = 0;
|
||||
|
|
@ -861,8 +861,8 @@ r535_gsp_acpi_dod(acpi_handle handle, DOD_METHOD_DATA *dod)
|
|||
|
||||
_DOD = output.pointer;
|
||||
|
||||
if (WARN_ON(_DOD->type != ACPI_TYPE_PACKAGE) ||
|
||||
WARN_ON(_DOD->package.count > ARRAY_SIZE(dod->acpiIdList)))
|
||||
if (_DOD->type != ACPI_TYPE_PACKAGE ||
|
||||
_DOD->package.count > ARRAY_SIZE(dod->acpiIdList))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _DOD->package.count; i++) {
|
||||
|
|
|
|||
|
|
@ -541,8 +541,8 @@ static int sharp_memory_probe(struct spi_device *spi)
|
|||
|
||||
smd = devm_drm_dev_alloc(dev, &sharp_memory_drm_driver,
|
||||
struct sharp_memory_device, drm);
|
||||
if (!smd)
|
||||
return -ENOMEM;
|
||||
if (IS_ERR(smd))
|
||||
return PTR_ERR(smd);
|
||||
|
||||
spi_set_drvdata(spi, smd);
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ struct vmw_cmdbuf_context {
|
|||
* @handle: DMA address handle for the command buffer space if @using_mob is
|
||||
* false. Immutable.
|
||||
* @size: The size of the command buffer space. Immutable.
|
||||
* @id: Monotonically increasing ID of the last cmdbuf submitted.
|
||||
* @num_contexts: Number of contexts actually enabled.
|
||||
*/
|
||||
struct vmw_cmdbuf_man {
|
||||
|
|
@ -132,6 +133,7 @@ struct vmw_cmdbuf_man {
|
|||
bool has_pool;
|
||||
dma_addr_t handle;
|
||||
size_t size;
|
||||
u64 id;
|
||||
u32 num_contexts;
|
||||
};
|
||||
|
||||
|
|
@ -303,6 +305,8 @@ static int vmw_cmdbuf_header_submit(struct vmw_cmdbuf_header *header)
|
|||
struct vmw_cmdbuf_man *man = header->man;
|
||||
u32 val;
|
||||
|
||||
header->cb_header->id = man->id++;
|
||||
|
||||
val = upper_32_bits(header->handle);
|
||||
vmw_write(man->dev_priv, SVGA_REG_COMMAND_HIGH, val);
|
||||
|
||||
|
|
|
|||
|
|
@ -1143,7 +1143,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
|
|||
ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo);
|
||||
if (ret != 0) {
|
||||
drm_dbg(&dev_priv->drm, "Could not find or use MOB buffer.\n");
|
||||
return PTR_ERR(vmw_bo);
|
||||
return ret;
|
||||
}
|
||||
vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB);
|
||||
ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
|
||||
|
|
@ -1199,7 +1199,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
|
|||
ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo);
|
||||
if (ret != 0) {
|
||||
drm_dbg(&dev_priv->drm, "Could not find or use GMR region.\n");
|
||||
return PTR_ERR(vmw_bo);
|
||||
return ret;
|
||||
}
|
||||
vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
|
||||
VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
|
||||
|
|
|
|||
|
|
@ -260,6 +260,13 @@ out_no_dirty:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void vmw_bo_dirty_free(struct kref *kref)
|
||||
{
|
||||
struct vmw_bo_dirty *dirty = container_of(kref, struct vmw_bo_dirty, ref_count);
|
||||
|
||||
kvfree(dirty);
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_bo_dirty_release - Release a dirty-tracking user from a buffer object
|
||||
* @vbo: The buffer object
|
||||
|
|
@ -274,7 +281,7 @@ void vmw_bo_dirty_release(struct vmw_bo *vbo)
|
|||
{
|
||||
struct vmw_bo_dirty *dirty = vbo->dirty;
|
||||
|
||||
if (dirty && kref_put(&dirty->ref_count, (void *)kvfree))
|
||||
if (dirty && kref_put(&dirty->ref_count, vmw_bo_dirty_free))
|
||||
vbo->dirty = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,12 @@
|
|||
#define ENABLE_SEMAPHORE_POLL_BIT REG_BIT(13)
|
||||
|
||||
#define RING_CMD_CCTL(base) XE_REG((base) + 0xc4, XE_REG_OPTION_MASKED)
|
||||
|
||||
#define CS_MMIO_GROUP_INSTANCE_SELECT(base) XE_REG((base) + 0xcc)
|
||||
#define SELECTIVE_READ_ADDRESSING REG_BIT(30)
|
||||
#define SELECTIVE_READ_GROUP REG_GENMASK(29, 23)
|
||||
#define SELECTIVE_READ_INSTANCE REG_GENMASK(22, 16)
|
||||
|
||||
/*
|
||||
* CMD_CCTL read/write fields take a MOCS value and _not_ a table index.
|
||||
* The lsb of each can be considered a separate enabling bit for encryption.
|
||||
|
|
|
|||
|
|
@ -210,11 +210,15 @@ static int emit_nop_job(struct xe_gt *gt, struct xe_exec_queue *q)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Dwords required to emit a RMW of a register */
|
||||
#define EMIT_RMW_DW 20
|
||||
|
||||
static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
|
||||
{
|
||||
struct xe_reg_sr *sr = &q->hwe->reg_lrc;
|
||||
struct xe_hw_engine *hwe = q->hwe;
|
||||
struct xe_reg_sr *sr = &hwe->reg_lrc;
|
||||
struct xe_reg_sr_entry *entry;
|
||||
int count_rmw = 0, count = 0, ret;
|
||||
int count_rmw = 0, count_rmw_mcr = 0, count = 0, ret;
|
||||
unsigned long idx;
|
||||
struct xe_bb *bb;
|
||||
size_t bb_len = 0;
|
||||
|
|
@ -224,6 +228,8 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
|
|||
xa_for_each(&sr->xa, idx, entry) {
|
||||
if (entry->reg.masked || entry->clr_bits == ~0)
|
||||
++count;
|
||||
else if (entry->reg.mcr)
|
||||
++count_rmw_mcr;
|
||||
else
|
||||
++count_rmw;
|
||||
}
|
||||
|
|
@ -231,17 +237,35 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
|
|||
if (count)
|
||||
bb_len += count * 2 + 1;
|
||||
|
||||
if (count_rmw)
|
||||
bb_len += count_rmw * 20 + 7;
|
||||
/*
|
||||
* RMW of MCR registers is the same as a normal RMW, except an
|
||||
* additional LRI (3 dwords) is required per register to steer the read
|
||||
* to a nom-terminated instance.
|
||||
*
|
||||
* We could probably shorten the batch slightly by eliding the
|
||||
* steering for consecutive MCR registers that have the same
|
||||
* group/instance target, but it's not worth the extra complexity to do
|
||||
* so.
|
||||
*/
|
||||
bb_len += count_rmw * EMIT_RMW_DW;
|
||||
bb_len += count_rmw_mcr * (EMIT_RMW_DW + 3);
|
||||
|
||||
if (q->hwe->class == XE_ENGINE_CLASS_RENDER)
|
||||
/*
|
||||
* After doing all RMW, we need 7 trailing dwords to clean up,
|
||||
* plus an additional 3 dwords to reset steering if any of the
|
||||
* registers were MCR.
|
||||
*/
|
||||
if (count_rmw || count_rmw_mcr)
|
||||
bb_len += 7 + (count_rmw_mcr ? 3 : 0);
|
||||
|
||||
if (hwe->class == XE_ENGINE_CLASS_RENDER)
|
||||
/*
|
||||
* Big enough to emit all of the context's 3DSTATE via
|
||||
* xe_lrc_emit_hwe_state_instructions()
|
||||
*/
|
||||
bb_len += xe_gt_lrc_size(gt, q->hwe->class) / sizeof(u32);
|
||||
bb_len += xe_gt_lrc_size(gt, hwe->class) / sizeof(u32);
|
||||
|
||||
xe_gt_dbg(gt, "LRC %s WA job: %zu dwords\n", q->hwe->name, bb_len);
|
||||
xe_gt_dbg(gt, "LRC %s WA job: %zu dwords\n", hwe->name, bb_len);
|
||||
|
||||
bb = xe_bb_new(gt, bb_len, false);
|
||||
if (IS_ERR(bb))
|
||||
|
|
@ -276,13 +300,23 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
|
|||
}
|
||||
}
|
||||
|
||||
if (count_rmw) {
|
||||
/* Emit MI_MATH for each RMW reg: 20dw per reg + 7 trailing dw */
|
||||
|
||||
if (count_rmw || count_rmw_mcr) {
|
||||
xa_for_each(&sr->xa, idx, entry) {
|
||||
if (entry->reg.masked || entry->clr_bits == ~0)
|
||||
continue;
|
||||
|
||||
if (entry->reg.mcr) {
|
||||
struct xe_reg_mcr reg = { .__reg.raw = entry->reg.raw };
|
||||
u8 group, instance;
|
||||
|
||||
xe_gt_mcr_get_nonterminated_steering(gt, reg, &group, &instance);
|
||||
*cs++ = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1);
|
||||
*cs++ = CS_MMIO_GROUP_INSTANCE_SELECT(hwe->mmio_base).addr;
|
||||
*cs++ = SELECTIVE_READ_ADDRESSING |
|
||||
REG_FIELD_PREP(SELECTIVE_READ_GROUP, group) |
|
||||
REG_FIELD_PREP(SELECTIVE_READ_INSTANCE, instance);
|
||||
}
|
||||
|
||||
*cs++ = MI_LOAD_REGISTER_REG | MI_LRR_DST_CS_MMIO;
|
||||
*cs++ = entry->reg.addr;
|
||||
*cs++ = CS_GPR_REG(0, 0).addr;
|
||||
|
|
@ -308,8 +342,9 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
|
|||
*cs++ = CS_GPR_REG(0, 0).addr;
|
||||
*cs++ = entry->reg.addr;
|
||||
|
||||
xe_gt_dbg(gt, "REG[%#x] = ~%#x|%#x\n",
|
||||
entry->reg.addr, entry->clr_bits, entry->set_bits);
|
||||
xe_gt_dbg(gt, "REG[%#x] = ~%#x|%#x%s\n",
|
||||
entry->reg.addr, entry->clr_bits, entry->set_bits,
|
||||
entry->reg.mcr ? " (MCR)" : "");
|
||||
}
|
||||
|
||||
/* reset used GPR */
|
||||
|
|
@ -321,6 +356,13 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
|
|||
*cs++ = 0;
|
||||
*cs++ = CS_GPR_REG(0, 2).addr;
|
||||
*cs++ = 0;
|
||||
|
||||
/* reset steering */
|
||||
if (count_rmw_mcr) {
|
||||
*cs++ = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1);
|
||||
*cs++ = CS_MMIO_GROUP_INSTANCE_SELECT(q->hwe->mmio_base).addr;
|
||||
*cs++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cs = xe_lrc_emit_hwe_state_instructions(q, cs);
|
||||
|
|
|
|||
|
|
@ -146,8 +146,10 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
|
|||
|
||||
if (!signal) {
|
||||
sync->fence = drm_syncobj_fence_get(sync->syncobj);
|
||||
if (XE_IOCTL_DBG(xe, !sync->fence))
|
||||
return -EINVAL;
|
||||
if (XE_IOCTL_DBG(xe, !sync->fence)) {
|
||||
err = -EINVAL;
|
||||
goto free_sync;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -167,17 +169,21 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
|
|||
|
||||
if (signal) {
|
||||
sync->chain_fence = dma_fence_chain_alloc();
|
||||
if (!sync->chain_fence)
|
||||
return -ENOMEM;
|
||||
if (!sync->chain_fence) {
|
||||
err = -ENOMEM;
|
||||
goto free_sync;
|
||||
}
|
||||
} else {
|
||||
sync->fence = drm_syncobj_fence_get(sync->syncobj);
|
||||
if (XE_IOCTL_DBG(xe, !sync->fence))
|
||||
return -EINVAL;
|
||||
if (XE_IOCTL_DBG(xe, !sync->fence)) {
|
||||
err = -EINVAL;
|
||||
goto free_sync;
|
||||
}
|
||||
|
||||
err = dma_fence_chain_find_seqno(&sync->fence,
|
||||
sync_in.timeline_value);
|
||||
if (err)
|
||||
return err;
|
||||
goto free_sync;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -200,8 +206,10 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
|
|||
if (XE_IOCTL_DBG(xe, IS_ERR(sync->ufence)))
|
||||
return PTR_ERR(sync->ufence);
|
||||
sync->ufence_chain_fence = dma_fence_chain_alloc();
|
||||
if (!sync->ufence_chain_fence)
|
||||
return -ENOMEM;
|
||||
if (!sync->ufence_chain_fence) {
|
||||
err = -ENOMEM;
|
||||
goto free_sync;
|
||||
}
|
||||
sync->ufence_syncobj = ufence_syncobj;
|
||||
}
|
||||
|
||||
|
|
@ -216,6 +224,10 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
|
|||
sync->timeline_value = sync_in.timeline_value;
|
||||
|
||||
return 0;
|
||||
|
||||
free_sync:
|
||||
xe_sync_entry_cleanup(sync);
|
||||
return err;
|
||||
}
|
||||
ALLOW_ERROR_INJECTION(xe_sync_entry_parse, ERRNO);
|
||||
|
||||
|
|
|
|||
|
|
@ -401,8 +401,8 @@ extern "C" {
|
|||
* implementation can multiply the values by 2^6=64. For that reason the padding
|
||||
* must only contain zeros.
|
||||
* index 0 = Y plane, [15:0] z:Y [6:10] little endian
|
||||
* index 1 = Cr plane, [15:0] z:Cr [6:10] little endian
|
||||
* index 2 = Cb plane, [15:0] z:Cb [6:10] little endian
|
||||
* index 1 = Cb plane, [15:0] z:Cb [6:10] little endian
|
||||
* index 2 = Cr plane, [15:0] z:Cr [6:10] little endian
|
||||
*/
|
||||
#define DRM_FORMAT_S010 fourcc_code('S', '0', '1', '0') /* 2x2 subsampled Cb (1) and Cr (2) planes 10 bits per channel */
|
||||
#define DRM_FORMAT_S210 fourcc_code('S', '2', '1', '0') /* 2x1 subsampled Cb (1) and Cr (2) planes 10 bits per channel */
|
||||
|
|
@ -414,8 +414,8 @@ extern "C" {
|
|||
* implementation can multiply the values by 2^4=16. For that reason the padding
|
||||
* must only contain zeros.
|
||||
* index 0 = Y plane, [15:0] z:Y [4:12] little endian
|
||||
* index 1 = Cr plane, [15:0] z:Cr [4:12] little endian
|
||||
* index 2 = Cb plane, [15:0] z:Cb [4:12] little endian
|
||||
* index 1 = Cb plane, [15:0] z:Cb [4:12] little endian
|
||||
* index 2 = Cr plane, [15:0] z:Cr [4:12] little endian
|
||||
*/
|
||||
#define DRM_FORMAT_S012 fourcc_code('S', '0', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes 12 bits per channel */
|
||||
#define DRM_FORMAT_S212 fourcc_code('S', '2', '1', '2') /* 2x1 subsampled Cb (1) and Cr (2) planes 12 bits per channel */
|
||||
|
|
@ -424,8 +424,8 @@ extern "C" {
|
|||
/*
|
||||
* 3 plane YCbCr
|
||||
* index 0 = Y plane, [15:0] Y little endian
|
||||
* index 1 = Cr plane, [15:0] Cr little endian
|
||||
* index 2 = Cb plane, [15:0] Cb little endian
|
||||
* index 1 = Cb plane, [15:0] Cb little endian
|
||||
* index 2 = Cr plane, [15:0] Cr little endian
|
||||
*/
|
||||
#define DRM_FORMAT_S016 fourcc_code('S', '0', '1', '6') /* 2x2 subsampled Cb (1) and Cr (2) planes 16 bits per channel */
|
||||
#define DRM_FORMAT_S216 fourcc_code('S', '2', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes 16 bits per channel */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue