Pull drm fixes from Dave Airlie:
 "Hopefully no Easter eggs in this bunch of fixes. Usual stuff across
  the amd/intel with some misc bits. Thanks to Thorsten and Alex for
  making sure a regression fix that was hanging around in process land
  finally made it in, that is probably the biggest change in here.

  core:
   - revert unplug/framebuffer fix as it caused problems
   - compat ioctl speculation fix

  bridge:
   - refcounting fix

  sysfb:
   - error handling fix

  amdgpu:
   - fix renoir audio regression
   - UserQ fixes
   - PASID handling fix
   - S4 fix for smu11 chips
   - Misc small fixes

  amdkfd:
   - Non-4K page fixes

  i915:
   - Fix for #12045: Huawei Matebook E (DRR-WXX): Persistent Black
     Screen on Boot with i915 and Gen11: Modesetting and Backlight
     Control Malfunction
   - Fix for #15826: i915: Raptor Lake-P [UHD Graphics] display
     flicker/corruption on eDP panel
   - Use crtc_state->enhanced_framing properly on ivb/hsw CPU eDP

  xe:
   - uapi: Accept canonical GPU addresses in xe_vm_madvise_ioctl
   - Disallow writes to read-only VMAs
   - PXP fixes
   - Disable garbage collector work item on SVM close
   - void memory allocations in xe_device_declare_wedged

  qaic:
   - hang fix

  ast:
   - initialisation fix"

* tag 'drm-fixes-2026-04-03' of https://gitlab.freedesktop.org/drm/kernel: (28 commits)
  drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
  drm/ioc32: stop speculation on the drm_compat_ioctl path
  drm/sysfb: Fix efidrm error handling and memory type mismatch
  drm/i915/dp: Use crtc_state->enhanced_framing properly on ivb/hsw CPU eDP
  drm/i915/cdclk: Do the full CDCLK dance for min_voltage_level changes
  drm/amdkfd: Fix queue preemption/eviction failures by aligning control stack size to GPU page size
  drm/amdgpu: Fix wait after reset sequence in S4
  drm/amd/display: Fix NULL pointer dereference in dcn401_init_hw()
  drm/amdgpu: Change AMDGPU_VA_RESERVED_TRAP_SIZE to 64KB
  drm/amdgpu/userq: fix memory leak in MQD creation error paths
  drm/amd: Fix MQD and control stack alignment for non-4K
  drm/amdkfd: Align expected_queue_size to PAGE_SIZE
  drm/amdgpu: fix the idr allocation flags
  drm/amdgpu: validate doorbell_offset in user queue creation
  drm/amdgpu/pm: drop SMU driver if version not matched messages
  drm/xe: Avoid memory allocations in xe_device_declare_wedged()
  drm/xe: Disable garbage collector work item on SVM close
  drm/xe/pxp: Don't allow PXP on older PTL GSC FWs
  drm/xe/pxp: Clear restart flag in pxp_start after jumping back
  drm/xe/pxp: Remove incorrect handling of impossible state during suspend
  ...
This commit is contained in:
Linus Torvalds committed 2026-04-03 08:23:51 -07:00
commit 60d9212c69
48 files changed
+1013 -108

No files matched your search

+45 -2
View File
@@ -914,7 +914,7 @@ static int decode_deactivate(struct qaic_device *qdev, void *trans, u32 *msg_len
*/
return -ENODEV;
if (status) {
if (usr && status) {
/*
* Releasing resources failed on the device side, which puts
* us in a bind since they may still be in use, so enable the
@@ -1109,6 +1109,9 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u
mutex_lock(&qdev->cntl_mutex);
if (!list_empty(&elem.list))
list_del(&elem.list);
/* resp_worker() processed the response but the wait was interrupted */
else if (ret == -ERESTARTSYS)
ret = 0;
if (!ret && !elem.buf)
ret = -ETIMEDOUT;
else if (ret > 0 && !elem.buf)
@@ -1419,9 +1422,49 @@ static void resp_worker(struct work_struct *work)
}
mutex_unlock(&qdev->cntl_mutex);
if (!found)
if (!found) {
/*
* The user might have gone away at this point without waiting
* for QAIC_TRANS_DEACTIVATE_FROM_DEV transaction coming from
* the device. If this is not handled correctly, the host will
* not know that the DBC[n] has been freed on the device.
* Due to this failure in synchronization between the device and
* the host, if another user requests to activate a network, and
* the device assigns DBC[n] again, save_dbc_buf() will hang,
* waiting for dbc[n]->in_use to be set to false, which will not
* happen unless the qaic_dev_reset_clean_local_state() gets
* called by resetting the device (or re-inserting the module).
*
* As a solution, we look for QAIC_TRANS_DEACTIVATE_FROM_DEV
* transactions in the message before disposing of it, then
* handle releasing the DBC resources.
*
* Since the user has gone away, if the device could not
* deactivate the network (status != 0), there is no way to
* enable and reassign the DBC to the user. We can put trust in
* the device that it will release all the active DBCs in
* response to the QAIC_TRANS_TERMINATE_TO_DEV transaction,
* otherwise, the user can issue an soc_reset to the device.
*/
u32 msg_count = le32_to_cpu(msg->hdr.count);
u32 msg_len = le32_to_cpu(msg->hdr.len);
u32 len = 0;
int j;
for (j = 0; j < msg_count && len < msg_len; ++j) {
struct wire_trans_hdr *trans_hdr;
trans_hdr = (struct wire_trans_hdr *)(msg->data + len);
if (le32_to_cpu(trans_hdr->type) == QAIC_TRANS_DEACTIVATE_FROM_DEV) {
if (decode_deactivate(qdev, trans_hdr, &len, NULL))
len += le32_to_cpu(trans_hdr->len);
} else {
len += le32_to_cpu(trans_hdr->len);
}
}
/* request must have timed out, drop packet */
kfree(msg);
}
kfree(resp);
}
+6 -2
View File
@@ -2703,8 +2703,12 @@ static int amdgpu_pmops_freeze(struct device *dev)
if (r)
return r;
if (amdgpu_acpi_should_gpu_reset(adev))
return amdgpu_asic_reset(adev);
if (amdgpu_acpi_should_gpu_reset(adev)) {
amdgpu_device_lock_reset_domain(adev->reset_domain);
r = amdgpu_asic_reset(adev);
amdgpu_device_unlock_reset_domain(adev->reset_domain);
return r;
}
return 0;
}
+44
View File
@@ -403,6 +403,50 @@ void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa,
drm_dev_exit(idx);
}
/**
* amdgpu_gart_map_gfx9_mqd - map mqd and ctrl_stack dma_addresses into GART entries
*
* @adev: amdgpu_device pointer
* @offset: offset into the GPU's gart aperture
* @pages: number of pages to bind
* @dma_addr: DMA addresses of pages
* @flags: page table entry flags
*
* Map the MQD and control stack addresses into GART entries with the correct
* memory types on gfxv9. The MQD occupies the first 4KB and is followed by
* the control stack. The MQD uses UC (uncached) memory, while the control stack
* uses NC (non-coherent) memory.
*/
void amdgpu_gart_map_gfx9_mqd(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags)
{
uint64_t page_base;
unsigned int i, j, t;
int idx;
uint64_t ctrl_flags = AMDGPU_PTE_MTYPE_VG10(flags, AMDGPU_MTYPE_NC);
void *dst;
if (!adev->gart.ptr)
return;
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return;
t = offset / AMDGPU_GPU_PAGE_SIZE;
dst = adev->gart.ptr;
for (i = 0; i < pages; i++) {
page_base = dma_addr[i];
for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) {
if ((i == 0) && (j == 0))
amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, flags);
else
amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, ctrl_flags);
page_base += AMDGPU_GPU_PAGE_SIZE;
}
}
drm_dev_exit(idx);
}
/**
* amdgpu_gart_bind - bind pages into the gart page table
*
+2
View File
@@ -62,6 +62,8 @@ void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags,
void *dst);
void amdgpu_gart_map_gfx9_mqd(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags);
void amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags);
void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa,
+4 -1
View File
@@ -68,8 +68,11 @@ int amdgpu_pasid_alloc(unsigned int bits)
return -EINVAL;
spin_lock(&amdgpu_pasid_idr_lock);
/* TODO: Need to replace the idr with an xarry, and then
* handle the internal locking with ATOMIC safe paths.
*/
pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1,
1U << bits, GFP_KERNEL);
1U << bits, GFP_ATOMIC);
spin_unlock(&amdgpu_pasid_idr_lock);
if (pasid >= 0)
+3 -13
View File
@@ -853,25 +853,15 @@ static void amdgpu_ttm_gart_bind_gfx9_mqd(struct amdgpu_device *adev,
int num_xcc = max(1U, adev->gfx.num_xcc_per_xcp);
uint64_t page_idx, pages_per_xcc;
int i;
uint64_t ctrl_flags = AMDGPU_PTE_MTYPE_VG10(flags, AMDGPU_MTYPE_NC);
pages_per_xcc = total_pages;
do_div(pages_per_xcc, num_xcc);
for (i = 0, page_idx = 0; i < num_xcc; i++, page_idx += pages_per_xcc) {
/* MQD page: use default flags */
amdgpu_gart_bind(adev,
amdgpu_gart_map_gfx9_mqd(adev,
gtt->offset + (page_idx << PAGE_SHIFT),
1, &gtt->ttm.dma_address[page_idx], flags);
/*
* Ctrl pages - modify the memory type to NC (ctrl_flags) from
* the second page of the BO onward.
*/
amdgpu_gart_bind(adev,
gtt->offset + ((page_idx + 1) << PAGE_SHIFT),
pages_per_xcc - 1,
&gtt->ttm.dma_address[page_idx + 1],
ctrl_flags);
pages_per_xcc, &gtt->ttm.dma_address[page_idx],
flags);
}
}
@@ -600,6 +600,13 @@ amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr,
goto unpin_bo;
}
/* Validate doorbell_offset is within the doorbell BO */
if ((u64)db_info->doorbell_offset * db_size + db_size >
amdgpu_bo_size(db_obj->obj)) {
r = -EINVAL;
goto unpin_bo;
}
index = amdgpu_doorbell_index_on_bar(uq_mgr->adev, db_obj->obj,
db_info->doorbell_offset, db_size);
drm_dbg_driver(adev_to_drm(uq_mgr->adev),
+1 -1
View File
@@ -173,7 +173,7 @@ struct amdgpu_bo_vm;
#define AMDGPU_VA_RESERVED_SEQ64_SIZE (2ULL << 20)
#define AMDGPU_VA_RESERVED_SEQ64_START(adev) (AMDGPU_VA_RESERVED_CSA_START(adev) \
- AMDGPU_VA_RESERVED_SEQ64_SIZE)
#define AMDGPU_VA_RESERVED_TRAP_SIZE (2ULL << 12)
#define AMDGPU_VA_RESERVED_TRAP_SIZE (1ULL << 16)
#define AMDGPU_VA_RESERVED_TRAP_START(adev) (AMDGPU_VA_RESERVED_SEQ64_START(adev) \
- AMDGPU_VA_RESERVED_TRAP_SIZE)
#define AMDGPU_VA_RESERVED_BOTTOM (1ULL << 16)
+12 -4
View File
@@ -324,8 +324,10 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
r = amdgpu_userq_input_va_validate(adev, queue, compute_mqd->eop_va,
2048);
if (r)
if (r) {
kfree(compute_mqd);
goto free_mqd;
}
userq_props->eop_gpu_addr = compute_mqd->eop_va;
userq_props->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_NORMAL;
@@ -365,12 +367,16 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->shadow_va,
shadow_info.shadow_size);
if (r)
if (r) {
kfree(mqd_gfx_v11);
goto free_mqd;
}
r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->csa_va,
shadow_info.csa_size);
if (r)
if (r) {
kfree(mqd_gfx_v11);
goto free_mqd;
}
kfree(mqd_gfx_v11);
} else if (queue->queue_type == AMDGPU_HW_IP_DMA) {
@@ -390,8 +396,10 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
}
r = amdgpu_userq_input_va_validate(adev, queue, mqd_sdma_v11->csa_va,
32);
if (r)
if (r) {
kfree(mqd_sdma_v11);
goto free_mqd;
}
userq_props->csa_addr = mqd_sdma_v11->csa_va;
kfree(mqd_sdma_v11);
+2 -1
View File
@@ -170,7 +170,8 @@ static int psp_v11_0_wait_for_bootloader(struct psp_context *psp)
int retry_loop;
/* For a reset done at the end of S3, only wait for TOS to be unloaded */
if (adev->in_s3 && !(adev->flags & AMD_IS_APU) && amdgpu_in_reset(adev))
if ((adev->in_s4 || adev->in_s3) && !(adev->flags & AMD_IS_APU) &&
amdgpu_in_reset(adev))
return psp_v11_wait_for_tos_unload(psp);
for (retry_loop = 0; retry_loop < 20; retry_loop++) {
@@ -42,9 +42,16 @@ static uint64_t mqd_stride_v9(struct mqd_manager *mm,
struct queue_properties *q)
{
if (mm->dev->kfd->cwsr_enabled &&
q->type == KFD_QUEUE_TYPE_COMPUTE)
return ALIGN(q->ctl_stack_size, PAGE_SIZE) +
ALIGN(sizeof(struct v9_mqd), PAGE_SIZE);
q->type == KFD_QUEUE_TYPE_COMPUTE) {
/* On gfxv9, the MQD resides in the first 4K page,
* followed by the control stack. Align both to
* AMDGPU_GPU_PAGE_SIZE to maintain the required 4K boundary.
*/
return ALIGN(ALIGN(q->ctl_stack_size, AMDGPU_GPU_PAGE_SIZE) +
ALIGN(sizeof(struct v9_mqd), AMDGPU_GPU_PAGE_SIZE), PAGE_SIZE);
}
return mm->mqd_size;
}
@@ -151,8 +158,8 @@ static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
if (!mqd_mem_obj)
return NULL;
retval = amdgpu_amdkfd_alloc_kernel_mem(node->adev,
(ALIGN(q->ctl_stack_size, PAGE_SIZE) +
ALIGN(sizeof(struct v9_mqd), PAGE_SIZE)) *
(ALIGN(ALIGN(q->ctl_stack_size, AMDGPU_GPU_PAGE_SIZE) +
ALIGN(sizeof(struct v9_mqd), AMDGPU_GPU_PAGE_SIZE), PAGE_SIZE)) *
NUM_XCC(node->xcc_mask),
mqd_on_vram(node->adev) ? AMDGPU_GEM_DOMAIN_VRAM :
AMDGPU_GEM_DOMAIN_GTT,
@@ -360,7 +367,7 @@ static int get_wave_state(struct mqd_manager *mm, void *mqd,
struct kfd_context_save_area_header header;
/* Control stack is located one page after MQD. */
void *mqd_ctl_stack = (void *)((uintptr_t)mqd + PAGE_SIZE);
void *mqd_ctl_stack = (void *)((uintptr_t)mqd + AMDGPU_GPU_PAGE_SIZE);
m = get_mqd(mqd);
@@ -397,7 +404,7 @@ static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, voi
{
struct v9_mqd *m;
/* Control stack is located one page after MQD. */
void *ctl_stack = (void *)((uintptr_t)mqd + PAGE_SIZE);
void *ctl_stack = (void *)((uintptr_t)mqd + AMDGPU_GPU_PAGE_SIZE);
m = get_mqd(mqd);
@@ -443,7 +450,7 @@ static void restore_mqd(struct mqd_manager *mm, void **mqd,
*gart_addr = addr;
/* Control stack is located one page after MQD. */
ctl_stack = (void *)((uintptr_t)*mqd + PAGE_SIZE);
ctl_stack = (void *)((uintptr_t)*mqd + AMDGPU_GPU_PAGE_SIZE);
memcpy(ctl_stack, ctl_stack_src, ctl_stack_size);
m->cp_hqd_pq_doorbell_control =
+2 -2
View File
@@ -102,8 +102,8 @@
* The first chunk is the TBA used for the CWSR ISA code. The second
* chunk is used as TMA for user-mode trap handler setup in daisy-chain mode.
*/
#define KFD_CWSR_TBA_TMA_SIZE (PAGE_SIZE * 2)
#define KFD_CWSR_TMA_OFFSET (PAGE_SIZE + 2048)
#define KFD_CWSR_TBA_TMA_SIZE (AMDGPU_GPU_PAGE_SIZE * 2)
#define KFD_CWSR_TMA_OFFSET (AMDGPU_GPU_PAGE_SIZE + 2048)
#define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \
(KFD_MAX_NUM_OF_PROCESSES * \
+6 -5
View File
@@ -249,10 +249,10 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
topo_dev->node_props.gfx_target_version < 90000)
/* metadata_queue_size not supported on GFX7/GFX8 */
expected_queue_size =
properties->queue_size / 2;
PAGE_ALIGN(properties->queue_size / 2);
else
expected_queue_size =
properties->queue_size + properties->metadata_queue_size;
PAGE_ALIGN(properties->queue_size + properties->metadata_queue_size);
vm = drm_priv_to_vm(pdd->drm_priv);
err = amdgpu_bo_reserve(vm->root.bo, false);
@@ -492,10 +492,11 @@ void kfd_queue_ctx_save_restore_size(struct kfd_topology_device *dev)
cu_num = props->simd_count / props->simd_per_cu / NUM_XCC(dev->gpu->xcc_mask);
wave_num = get_num_waves(props, gfxv, cu_num);
wg_data_size = ALIGN(cu_num * WG_CONTEXT_DATA_SIZE_PER_CU(gfxv, props), PAGE_SIZE);
wg_data_size = ALIGN(cu_num * WG_CONTEXT_DATA_SIZE_PER_CU(gfxv, props),
AMDGPU_GPU_PAGE_SIZE);
ctl_stack_size = wave_num * CNTL_STACK_BYTES_PER_WAVE(gfxv) + 8;
ctl_stack_size = ALIGN(SIZEOF_HSA_USER_CONTEXT_SAVE_AREA_HEADER + ctl_stack_size,
PAGE_SIZE);
AMDGPU_GPU_PAGE_SIZE);
if ((gfxv / 10000 * 10000) == 100000) {
/* HW design limits control stack size to 0x7000.
@@ -507,7 +508,7 @@ void kfd_queue_ctx_save_restore_size(struct kfd_topology_device *dev)
props->ctl_stack_size = ctl_stack_size;
props->debug_memory_size = ALIGN(wave_num * DEBUGGER_BYTES_PER_WAVE, DEBUGGER_BYTES_ALIGN);
props->cwsr_size = ctl_stack_size + wg_data_size;
props->cwsr_size = ALIGN(ctl_stack_size + wg_data_size, PAGE_SIZE);
if (gfxv == 80002) /* GFX_VERSION_TONGA */
props->eop_buffer_size = 0x8000;
@@ -147,6 +147,7 @@ void dcn401_init_hw(struct dc *dc)
int edp_num;
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
bool dchub_ref_freq_changed;
int current_dchub_ref_freq = 0;
if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) {
@@ -360,14 +361,18 @@ void dcn401_init_hw(struct dc *dc)
dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver > 0;
dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver;
/* sw and fw FAMS versions must match for support */
dc->debug.fams2_config.bits.enable &=
dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver; // sw & fw fams versions must match for support
if ((!dc->debug.fams2_config.bits.enable && dc->res_pool->funcs->update_bw_bounding_box)
|| res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq) {
dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver;
dchub_ref_freq_changed =
res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq;
if ((!dc->debug.fams2_config.bits.enable || dchub_ref_freq_changed) &&
dc->res_pool->funcs->update_bw_bounding_box &&
dc->clk_mgr && dc->clk_mgr->bw_params) {
/* update bounding box if FAMS2 disabled, or if dchub clk has changed */
if (dc->clk_mgr)
dc->res_pool->funcs->update_bw_bounding_box(dc,
dc->clk_mgr->bw_params);
dc->res_pool->funcs->update_bw_bounding_box(dc,
dc->clk_mgr->bw_params);
}
}
}
@@ -71,6 +71,7 @@
#include "dce/dce_dmcu.h"
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
#include "dio/dcn10/dcn10_dio.h"
#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
@@ -444,6 +445,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
HUBBUB_MASK_SH_LIST_DCN10(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static struct dio *dcn10_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
@@ -917,6 +945,11 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.opps[i] != NULL)
pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
@@ -1653,6 +1686,14 @@ static bool dcn10_resource_construct(
goto fail;
}
/* DIO */
pool->base.dio = dcn10_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto fail;
}
if (!resource_construct(num_virtual_links, dc, &pool->base,
&res_create_funcs))
goto fail;
@@ -82,6 +82,7 @@
#include "dce/dce_dmcu.h"
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
#include "dio/dcn10/dcn10_dio.h"
#include "vm_helper.h"
#include "link_enc_cfg.h"
@@ -550,6 +551,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
HUBBUB_MASK_SH_LIST_DCN20(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static struct dio *dcn20_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
#define vmid_regs(id)\
[id] = {\
DCN20_VMID_REG_LIST(id)\
@@ -1104,6 +1132,12 @@ static void dcn20_resource_destruct(struct dcn20_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn20_dpp_destroy(&pool->base.dpps[i]);
@@ -2692,6 +2726,14 @@ static bool dcn20_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn20_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
pool->base.dscs[i] = dcn20_dsc_create(ctx, i);
if (pool->base.dscs[i] == NULL) {
@@ -56,6 +56,7 @@
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
#include "dcn10/dcn10_resource.h"
#include "dio/dcn10/dcn10_dio.h"
#include "cyan_skillfish_ip_offset.h"
@@ -755,6 +756,33 @@ static struct hubbub *dcn201_hubbub_create(struct dc_context *ctx)
return &hubbub->base;
}
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static struct dio *dcn201_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct timing_generator *dcn201_timing_generator_create(
struct dc_context *ctx,
uint32_t instance)
@@ -930,6 +958,11 @@ static void dcn201_resource_destruct(struct dcn201_resource_pool *pool)
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn201_dpp_destroy(&pool->base.dpps[i]);
@@ -1276,6 +1309,14 @@ static bool dcn201_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn201_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
if (!resource_construct(num_virtual_links, dc, &pool->base,
&res_create_funcs))
goto create_fail;
@@ -84,6 +84,7 @@
#include "dce/dce_dmcu.h"
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dcn21_resource.h"
#include "vm_helper.h"
#include "dcn20/dcn20_vmid.h"
@@ -329,6 +330,25 @@ static const struct dcn_hubbub_mask hubbub_mask = {
HUBBUB_MASK_SH_LIST_DCN21(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
static const struct dcn_dio_shift dio_shift = { 0 };
static const struct dcn_dio_mask dio_mask = { 0 };
static struct dio *dcn21_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
#define vmid_regs(id)\
[id] = {\
@@ -677,6 +697,12 @@ static void dcn21_resource_destruct(struct dcn21_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn20_dpp_destroy(&pool->base.dpps[i]);
@@ -1654,6 +1680,14 @@ static bool dcn21_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn21_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
pool->base.dscs[i] = dcn21_dsc_create(ctx, i);
if (pool->base.dscs[i] == NULL) {
@@ -60,6 +60,7 @@
#include "dml/display_mode_vba.h"
#include "dcn30/dcn30_dccg.h"
#include "dcn10/dcn10_resource.h"
#include "dio/dcn10/dcn10_dio.h"
#include "link_service.h"
#include "dce/dce_panel_cntl.h"
@@ -886,6 +887,33 @@ static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx)
return &hubbub3->base;
}
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static struct dio *dcn30_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct timing_generator *dcn30_timing_generator_create(
struct dc_context *ctx,
uint32_t instance)
@@ -1095,6 +1123,12 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn30_dpp_destroy(&pool->base.dpps[i]);
@@ -2464,6 +2498,14 @@ static bool dcn30_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn30_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn30_hubp_create(ctx, i);
@@ -59,6 +59,7 @@
#include "dml/display_mode_vba.h"
#include "dcn301/dcn301_dccg.h"
#include "dcn10/dcn10_resource.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn301/dcn301_dio_link_encoder.h"
#include "dcn301/dcn301_panel_cntl.h"
@@ -843,6 +844,33 @@ static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx)
return &hubbub3->base;
}
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static struct dio *dcn301_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct timing_generator *dcn301_timing_generator_create(
struct dc_context *ctx, uint32_t instance)
{
@@ -1066,6 +1094,12 @@ static void dcn301_destruct(struct dcn301_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn301_dpp_destroy(&pool->base.dpps[i]);
@@ -1582,6 +1616,14 @@ static bool dcn301_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn301_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
j = 0;
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
@@ -46,6 +46,7 @@
#include "dml/dcn30/dcn30_fpu.h"
#include "dcn10/dcn10_resource.h"
#include "dio/dcn10/dcn10_dio.h"
#include "link_service.h"
@@ -253,6 +254,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static struct dio *dcn302_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn302_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1022,6 +1050,11 @@ static void dcn302_resource_destruct(struct resource_pool *pool)
pool->hubbub = NULL;
}
if (pool->dio != NULL) {
kfree(TO_DCN10_DIO(pool->dio));
pool->dio = NULL;
}
for (i = 0; i < pool->pipe_count; i++) {
if (pool->dpps[i] != NULL) {
kfree(TO_DCN20_DPP(pool->dpps[i]));
@@ -1372,6 +1405,14 @@ static bool dcn302_resource_construct(
goto create_fail;
}
/* DIO */
pool->dio = dcn302_dio_create(ctx);
if (pool->dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->pipe_count; i++) {
pool->hubps[i] = dcn302_hubp_create(ctx, i);
@@ -46,6 +46,7 @@
#include "dml/dcn30/dcn30_fpu.h"
#include "dcn10/dcn10_resource.h"
#include "dio/dcn10/dcn10_dio.h"
#include "link_service.h"
@@ -249,6 +250,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static struct dio *dcn303_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn303_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -966,6 +994,11 @@ static void dcn303_resource_destruct(struct resource_pool *pool)
pool->hubbub = NULL;
}
if (pool->dio != NULL) {
kfree(TO_DCN10_DIO(pool->dio));
pool->dio = NULL;
}
for (i = 0; i < pool->pipe_count; i++) {
if (pool->dpps[i] != NULL) {
kfree(TO_DCN20_DPP(pool->dpps[i]));
@@ -1304,6 +1337,14 @@ static bool dcn303_resource_construct(
goto create_fail;
}
/* DIO */
pool->dio = dcn303_dio_create(ctx);
if (pool->dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->pipe_count; i++) {
pool->hubps[i] = dcn303_hubp_create(ctx, i);
@@ -64,6 +64,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -810,6 +811,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn31 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1021,6 +1037,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
static struct dio *dcn31_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1396,6 +1424,10 @@ static void dcn31_resource_destruct(struct dcn31_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -2063,6 +2095,14 @@ static bool dcn31_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn31_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
@@ -66,6 +66,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -822,6 +823,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn314 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1079,6 +1095,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
static struct dio *dcn314_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1455,6 +1483,10 @@ static void dcn314_resource_destruct(struct dcn314_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -1987,6 +2019,14 @@ static bool dcn314_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn314_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
@@ -63,6 +63,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -809,6 +810,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn31 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1020,6 +1036,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
static struct dio *dcn315_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1397,6 +1425,10 @@ static void dcn315_resource_destruct(struct dcn315_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -2012,6 +2044,14 @@ static bool dcn315_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn315_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
@@ -63,6 +63,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -804,6 +805,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static const struct dcn_dio_registers dio_regs = {
DIO_REG_LIST_DCN10()
};
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn31 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1013,6 +1029,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
static struct dio *dcn316_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1392,6 +1420,10 @@ static void dcn316_resource_destruct(struct dcn316_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -1887,6 +1919,14 @@ static bool dcn316_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn316_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
@@ -66,6 +66,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dml/display_mode_vba.h"
#include "dcn32/dcn32_dccg.h"
#include "dcn10/dcn10_resource.h"
@@ -643,6 +644,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static struct dcn_dio_registers dio_regs;
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn32 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -833,6 +847,22 @@ static struct clock_source *dcn32_clock_source_create(
return NULL;
}
static struct dio *dcn32_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
#undef REG_STRUCT
#define REG_STRUCT dio_regs
DIO_REG_LIST_DCN10();
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1494,6 +1524,11 @@ static void dcn32_resource_destruct(struct dcn32_resource_pool *pool)
if (pool->base.dccg != NULL)
dcn_dccg_destroy(&pool->base.dccg);
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
if (pool->base.oem_device != NULL) {
struct dc *dc = pool->base.oem_device->ctx->dc;
@@ -2373,6 +2408,14 @@ static bool dcn32_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn32_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs, TGs, ABMs */
for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) {
@@ -69,6 +69,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dml/display_mode_vba.h"
#include "dcn32/dcn32_dccg.h"
#include "dcn10/dcn10_resource.h"
@@ -639,6 +640,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static struct dcn_dio_registers dio_regs;
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn321 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -827,6 +841,22 @@ static struct clock_source *dcn321_clock_source_create(
return NULL;
}
static struct dio *dcn321_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
#undef REG_STRUCT
#define REG_STRUCT dio_regs
DIO_REG_LIST_DCN10();
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn321_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1474,6 +1504,11 @@ static void dcn321_resource_destruct(struct dcn321_resource_pool *pool)
if (pool->base.dccg != NULL)
dcn_dccg_destroy(&pool->base.dccg);
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
if (pool->base.oem_device != NULL) {
struct dc *dc = pool->base.oem_device->ctx->dc;
@@ -1872,6 +1907,14 @@ static bool dcn321_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn321_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs, TGs, ABMs */
for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) {
@@ -71,6 +71,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
#include "dcn35/dcn35_dccg.h"
@@ -664,6 +665,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static struct dcn_dio_registers dio_regs;
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn35 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -973,6 +987,22 @@ static struct mpc *dcn35_mpc_create(
return &mpc30->base;
}
static struct dio *dcn35_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
#undef REG_STRUCT
#define REG_STRUCT dio_regs
DIO_REG_LIST_DCN10();
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1563,6 +1593,11 @@ static void dcn35_resource_destruct(struct dcn35_resource_pool *pool)
if (pool->base.dccg != NULL)
dcn_dccg_destroy(&pool->base.dccg);
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
}
static struct hubp *dcn35_hubp_create(
@@ -2033,6 +2068,14 @@ static bool dcn35_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn35_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
@@ -50,6 +50,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
#include "dcn35/dcn35_dccg.h"
@@ -644,6 +645,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static struct dcn_dio_registers dio_regs;
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn351 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -953,6 +967,22 @@ static struct mpc *dcn35_mpc_create(
return &mpc30->base;
}
static struct dio *dcn351_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
#undef REG_STRUCT
#define REG_STRUCT dio_regs
DIO_REG_LIST_DCN10();
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1543,6 +1573,11 @@ static void dcn351_resource_destruct(struct dcn351_resource_pool *pool)
if (pool->base.dccg != NULL)
dcn_dccg_destroy(&pool->base.dccg);
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
}
static struct hubp *dcn35_hubp_create(
@@ -2005,6 +2040,14 @@ static bool dcn351_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn351_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
@@ -50,6 +50,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dio/dcn10/dcn10_dio.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
#include "dcn35/dcn35_dccg.h"
@@ -651,6 +652,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
static struct dcn_dio_registers dio_regs;
#define DIO_MASK_SH_LIST(mask_sh)\
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
static const struct dcn_dio_shift dio_shift = {
DIO_MASK_SH_LIST(__SHIFT)
};
static const struct dcn_dio_mask dio_mask = {
DIO_MASK_SH_LIST(_MASK)
};
static const struct resource_caps res_cap_dcn36 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -960,6 +974,22 @@ static struct mpc *dcn35_mpc_create(
return &mpc30->base;
}
static struct dio *dcn36_dio_create(struct dc_context *ctx)
{
struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
if (!dio10)
return NULL;
#undef REG_STRUCT
#define REG_STRUCT dio_regs
DIO_REG_LIST_DCN10();
dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
return &dio10->base;
}
static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1550,6 +1580,11 @@ static void dcn36_resource_destruct(struct dcn36_resource_pool *pool)
if (pool->base.dccg != NULL)
dcn_dccg_destroy(&pool->base.dccg);
if (pool->base.dio != NULL) {
kfree(TO_DCN10_DIO(pool->base.dio));
pool->base.dio = NULL;
}
}
static struct hubp *dcn35_hubp_create(
@@ -2012,6 +2047,14 @@ static bool dcn36_resource_construct(
goto create_fail;
}
/* DIO */
pool->base.dio = dcn36_dio_create(ctx);
if (pool->base.dio == NULL) {
BREAK_TO_DEBUGGER();
dm_error("DC: failed to create dio!\n");
goto create_fail;
}
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
@@ -262,7 +262,6 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
"smu fw program = %d, version = 0x%08x (%d.%d.%d)\n",
smu->smc_driver_if_version, if_version,
smu_program, smu_version, smu_major, smu_minor, smu_debug);
dev_info(smu->adev->dev, "SMU driver if version not matched\n");
}
return ret;
@@ -101,7 +101,6 @@ int smu_v12_0_check_fw_version(struct smu_context *smu)
"smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n",
smu->smc_driver_if_version, if_version,
smu_program, smu_version, smu_major, smu_minor, smu_debug);
dev_info(smu->adev->dev, "SMU driver if version not matched\n");
}
return ret;
@@ -284,7 +284,6 @@ int smu_v14_0_check_fw_version(struct smu_context *smu)
"smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n",
smu->smc_driver_if_version, if_version,
smu_program, smu_version, smu_major, smu_minor, smu_debug);
dev_info(adev->dev, "SMU driver if version not matched\n");
}
return ret;
+1 -1
View File
@@ -436,7 +436,7 @@ static void ast_init_analog(struct ast_device *ast)
/* Finally, clear bits [17:16] of SCU2c */
data = ast_read32(ast, 0x1202c);
data &= 0xfffcffff;
ast_write32(ast, 0, data);
ast_write32(ast, 0x1202c, data);
/* Disable DVO */
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00);
+11 -5
View File
@@ -1569,11 +1569,17 @@ EXPORT_SYMBOL(devm_drm_put_bridge);
static void drm_bridge_debugfs_show_bridge(struct drm_printer *p,
struct drm_bridge *bridge,
unsigned int idx,
bool lingering)
bool lingering,
bool scoped)
{
unsigned int refcount = kref_read(&bridge->refcount);
if (scoped)
refcount--;
drm_printf(p, "bridge[%u]: %ps\n", idx, bridge->funcs);
drm_printf(p, "\trefcount: %u%s\n", kref_read(&bridge->refcount),
drm_printf(p, "\trefcount: %u%s\n", refcount,
lingering ? " [lingering]" : "");
drm_printf(p, "\ttype: [%d] %s\n",
@@ -1607,10 +1613,10 @@ static int allbridges_show(struct seq_file *m, void *data)
mutex_lock(&bridge_lock);
list_for_each_entry(bridge, &bridge_list, list)
drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false);
drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false, false);
list_for_each_entry(bridge, &bridge_lingering_list, list)
drm_bridge_debugfs_show_bridge(&p, bridge, idx++, true);
drm_bridge_debugfs_show_bridge(&p, bridge, idx++, true, false);
mutex_unlock(&bridge_lock);
@@ -1625,7 +1631,7 @@ static int encoder_bridges_show(struct seq_file *m, void *data)
unsigned int idx = 0;
drm_for_each_bridge_in_chain_scoped(encoder, bridge)
drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false);
drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false, true);
return 0;
}
+1 -4
View File
@@ -233,7 +233,6 @@ static void drm_events_release(struct drm_file *file_priv)
void drm_file_free(struct drm_file *file)
{
struct drm_device *dev;
int idx;
if (!file)
return;
@@ -250,11 +249,9 @@ void drm_file_free(struct drm_file *file)
drm_events_release(file);
if (drm_core_check_feature(dev, DRIVER_MODESET) &&
drm_dev_enter(dev, &idx)) {
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
drm_fb_release(file);
drm_property_destroy_user_blobs(dev, file);
drm_dev_exit(idx);
}
if (drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+2
View File
@@ -28,6 +28,7 @@
* IN THE SOFTWARE.
*/
#include <linux/compat.h>
#include <linux/nospec.h>
#include <linux/ratelimit.h>
#include <linux/export.h>
@@ -374,6 +375,7 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (nr >= ARRAY_SIZE(drm_compat_ioctls))
return drm_ioctl(filp, cmd, arg);
nr = array_index_nospec(nr, ARRAY_SIZE(drm_compat_ioctls));
fn = drm_compat_ioctls[nr].fn;
if (!fn)
return drm_ioctl(filp, cmd, arg);
+3 -6
View File
@@ -577,13 +577,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
*/
WARN_ON(!list_empty(&dev->mode_config.fb_list));
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
if (list_empty(&fb->filp_head) || drm_framebuffer_read_refcount(fb) > 1) {
struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]");
struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]");
drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
drm_framebuffer_print_info(&p, 1, fb);
}
list_del_init(&fb->filp_head);
drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
drm_framebuffer_print_info(&p, 1, fb);
drm_framebuffer_free(&fb->base.refcount);
}
+1 -1
View File
@@ -137,7 +137,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
intel_dp->DP |= DP_SYNC_VS_HIGH;
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
if (pipe_config->enhanced_framing)
intel_dp->DP |= DP_ENHANCED_FRAMING;
intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe);
+2 -2
View File
@@ -889,7 +889,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
* non-compressed link speeds, and simplifies down to the ratio between
* compressed and non-compressed bpp.
*/
if (crtc_state->dsc.compression_enable) {
if (is_vid_mode(intel_dsi) && crtc_state->dsc.compression_enable) {
mul = fxp_q4_to_int(crtc_state->dsc.compressed_bpp_x16);
div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
}
@@ -1503,7 +1503,7 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
if (pipe_config->dsc.compressed_bpp_x16) {
if (is_vid_mode(intel_dsi) && pipe_config->dsc.compressed_bpp_x16) {
int div = fxp_q4_to_int(pipe_config->dsc.compressed_bpp_x16);
int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
@@ -2971,6 +2971,53 @@ static int intel_cdclk_update_crtc_min_cdclk(struct intel_atomic_state *state,
return 0;
}
static int intel_cdclk_update_crtc_min_voltage_level(struct intel_atomic_state *state,
struct intel_crtc *crtc,
u8 old_min_voltage_level,
u8 new_min_voltage_level,
bool *need_cdclk_calc)
{
struct intel_display *display = to_intel_display(state);
struct intel_cdclk_state *cdclk_state;
bool allow_voltage_level_decrease = intel_any_crtc_needs_modeset(state);
int ret;
if (new_min_voltage_level == old_min_voltage_level)
return 0;
if (!allow_voltage_level_decrease &&
new_min_voltage_level < old_min_voltage_level)
return 0;
cdclk_state = intel_atomic_get_cdclk_state(state);
if (IS_ERR(cdclk_state))
return PTR_ERR(cdclk_state);
old_min_voltage_level = cdclk_state->min_voltage_level[crtc->pipe];
if (new_min_voltage_level == old_min_voltage_level)
return 0;
if (!allow_voltage_level_decrease &&
new_min_voltage_level < old_min_voltage_level)
return 0;
cdclk_state->min_voltage_level[crtc->pipe] = new_min_voltage_level;
ret = intel_atomic_lock_global_state(&cdclk_state->base);
if (ret)
return ret;
*need_cdclk_calc = true;
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] min voltage level: %d -> %d\n",
crtc->base.base.id, crtc->base.name,
old_min_voltage_level, new_min_voltage_level);
return 0;
}
int intel_cdclk_update_dbuf_bw_min_cdclk(struct intel_atomic_state *state,
int old_min_cdclk, int new_min_cdclk,
bool *need_cdclk_calc)
@@ -3386,6 +3433,13 @@ static int intel_crtcs_calc_min_cdclk(struct intel_atomic_state *state,
need_cdclk_calc);
if (ret)
return ret;
ret = intel_cdclk_update_crtc_min_voltage_level(state, crtc,
old_crtc_state->min_voltage_level,
new_crtc_state->min_voltage_level,
need_cdclk_calc);
if (ret)
return ret;
}
return 0;
+31 -15
View File
@@ -151,7 +151,6 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
struct drm_sysfb_device *sysfb;
struct drm_device *dev;
struct resource *mem = NULL;
void __iomem *screen_base = NULL;
struct drm_plane *primary_plane;
struct drm_crtc *crtc;
struct drm_encoder *encoder;
@@ -238,21 +237,38 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
mem_flags = efidrm_get_mem_flags(dev, res->start, vsize);
if (mem_flags & EFI_MEMORY_WC)
screen_base = devm_ioremap_wc(&pdev->dev, mem->start, resource_size(mem));
else if (mem_flags & EFI_MEMORY_UC)
screen_base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
else if (mem_flags & EFI_MEMORY_WT)
screen_base = devm_memremap(&pdev->dev, mem->start, resource_size(mem),
MEMREMAP_WT);
else if (mem_flags & EFI_MEMORY_WB)
screen_base = devm_memremap(&pdev->dev, mem->start, resource_size(mem),
MEMREMAP_WB);
else
if (mem_flags & EFI_MEMORY_WC) {
void __iomem *screen_base = devm_ioremap_wc(&pdev->dev, mem->start,
resource_size(mem));
if (!screen_base)
return ERR_PTR(-ENXIO);
iosys_map_set_vaddr_iomem(&sysfb->fb_addr, screen_base);
} else if (mem_flags & EFI_MEMORY_UC) {
void __iomem *screen_base = devm_ioremap(&pdev->dev, mem->start,
resource_size(mem));
if (!screen_base)
return ERR_PTR(-ENXIO);
iosys_map_set_vaddr_iomem(&sysfb->fb_addr, screen_base);
} else if (mem_flags & EFI_MEMORY_WT) {
void *screen_base = devm_memremap(&pdev->dev, mem->start,
resource_size(mem), MEMREMAP_WT);
if (IS_ERR(screen_base))
return ERR_CAST(screen_base);
iosys_map_set_vaddr(&sysfb->fb_addr, screen_base);
} else if (mem_flags & EFI_MEMORY_WB) {
void *screen_base = devm_memremap(&pdev->dev, mem->start,
resource_size(mem), MEMREMAP_WB);
if (IS_ERR(screen_base))
return ERR_CAST(screen_base);
iosys_map_set_vaddr(&sysfb->fb_addr, screen_base);
} else {
drm_err(dev, "invalid mem_flags: 0x%llx\n", mem_flags);
if (!screen_base)
return ERR_PTR(-ENOMEM);
iosys_map_set_vaddr_iomem(&sysfb->fb_addr, screen_base);
return ERR_PTR(-EINVAL);
}
/*
* Modesetting
+13 -14
View File
@@ -837,6 +837,14 @@ static void detect_preproduction_hw(struct xe_device *xe)
}
}
static void xe_device_wedged_fini(struct drm_device *drm, void *arg)
{
struct xe_device *xe = arg;
if (atomic_read(&xe->wedged.flag))
xe_pm_runtime_put(xe);
}
int xe_device_probe(struct xe_device *xe)
{
struct xe_tile *tile;
@@ -1013,6 +1021,10 @@ int xe_device_probe(struct xe_device *xe)
detect_preproduction_hw(xe);
err = drmm_add_action_or_reset(&xe->drm, xe_device_wedged_fini, xe);
if (err)
goto err_unregister_display;
return devm_add_action_or_reset(xe->drm.dev, xe_device_sanitize, xe);
err_unregister_display:
@@ -1216,13 +1228,6 @@ u64 xe_device_uncanonicalize_addr(struct xe_device *xe, u64 address)
return address & GENMASK_ULL(xe->info.va_bits - 1, 0);
}
static void xe_device_wedged_fini(struct drm_device *drm, void *arg)
{
struct xe_device *xe = arg;
xe_pm_runtime_put(xe);
}
/**
* DOC: Xe Device Wedging
*
@@ -1300,15 +1305,9 @@ void xe_device_declare_wedged(struct xe_device *xe)
return;
}
xe_pm_runtime_get_noresume(xe);
if (drmm_add_action_or_reset(&xe->drm, xe_device_wedged_fini, xe)) {
drm_err(&xe->drm, "Failed to register xe_device_wedged_fini clean-up. Although device is wedged.\n");
return;
}
if (!atomic_xchg(&xe->wedged.flag, 1)) {
xe->needs_flr_on_fini = true;
xe_pm_runtime_get_noresume(xe);
drm_err(&xe->drm,
"CRITICAL: Xe has declared device %s as wedged.\n"
"IOCTLs and executions are blocked. Only a rebind may clear the failure\n"
+6
View File
@@ -187,6 +187,12 @@ static int xe_pagefault_service(struct xe_pagefault *pf)
goto unlock_vm;
}
if (xe_vma_read_only(vma) &&
pf->consumer.access_type != XE_PAGEFAULT_ACCESS_TYPE_READ) {
err = -EPERM;
goto unlock_vm;
}
atomic = xe_pagefault_access_is_atomic(pf->consumer.access_type);
if (xe_vma_is_cpu_addr_mirror(vma))
+16 -7
View File
@@ -380,6 +380,18 @@ int xe_pxp_init(struct xe_device *xe)
return 0;
}
/*
* On PTL, older GSC FWs have a bug that can cause them to crash during
* PXP invalidation events, which leads to a complete loss of power
* management on the media GT. Therefore, we can't use PXP on FWs that
* have this bug, which was fixed in PTL GSC build 1396.
*/
if (xe->info.platform == XE_PANTHERLAKE &&
gt->uc.gsc.fw.versions.found[XE_UC_FW_VER_RELEASE].build < 1396) {
drm_info(&xe->drm, "PXP requires PTL GSC build 1396 or newer\n");
return 0;
}
pxp = drmm_kzalloc(&xe->drm, sizeof(struct xe_pxp), GFP_KERNEL);
if (!pxp) {
err = -ENOMEM;
@@ -512,7 +524,7 @@ static int __exec_queue_add(struct xe_pxp *pxp, struct xe_exec_queue *q)
static int pxp_start(struct xe_pxp *pxp, u8 type)
{
int ret = 0;
bool restart = false;
bool restart;
if (!xe_pxp_is_enabled(pxp))
return -ENODEV;
@@ -541,6 +553,8 @@ wait_for_idle:
msecs_to_jiffies(PXP_ACTIVATION_TIMEOUT_MS)))
return -ETIMEDOUT;
restart = false;
mutex_lock(&pxp->mutex);
/* If PXP is not already active, turn it on */
@@ -583,6 +597,7 @@ wait_for_idle:
drm_err(&pxp->xe->drm, "PXP termination failed before start\n");
mutex_lock(&pxp->mutex);
pxp->status = XE_PXP_ERROR;
complete_all(&pxp->termination);
goto out_unlock;
}
@@ -870,11 +885,6 @@ wait_for_activation:
pxp->key_instance++;
needs_queue_inval = true;
break;
default:
drm_err(&pxp->xe->drm, "unexpected state during PXP suspend: %u",
pxp->status);
ret = -EIO;
goto out;
}
/*
@@ -899,7 +909,6 @@ wait_for_activation:
pxp->last_suspend_key_instance = pxp->key_instance;
out:
return ret;
}
+1 -1
View File
@@ -903,7 +903,7 @@ int xe_svm_init(struct xe_vm *vm)
void xe_svm_close(struct xe_vm *vm)
{
xe_assert(vm->xe, xe_vm_is_closed(vm));
flush_work(&vm->svm.garbage_collector.work);
disable_work_sync(&vm->svm.garbage_collector.work);
xe_svm_put_pagemaps(vm);
drm_pagemap_release_owner(&vm->svm.peer);
}
+12 -4
View File
@@ -408,8 +408,15 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
struct xe_device *xe = to_xe_device(dev);
struct xe_file *xef = to_xe_file(file);
struct drm_xe_madvise *args = data;
struct xe_vmas_in_madvise_range madvise_range = {.addr = args->start,
.range = args->range, };
struct xe_vmas_in_madvise_range madvise_range = {
/*
* Userspace may pass canonical (sign-extended) addresses.
* Strip the sign extension to get the internal non-canonical
* form used by the GPUVM, matching xe_vm_bind_ioctl() behavior.
*/
.addr = xe_device_uncanonicalize_addr(xe, args->start),
.range = args->range,
};
struct xe_madvise_details details;
struct xe_vm *vm;
struct drm_exec exec;
@@ -439,7 +446,7 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
if (err)
goto unlock_vm;
err = xe_vm_alloc_madvise_vma(vm, args->start, args->range);
err = xe_vm_alloc_madvise_vma(vm, madvise_range.addr, args->range);
if (err)
goto madv_fini;
@@ -482,7 +489,8 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
madvise_funcs[attr_type](xe, vm, madvise_range.vmas, madvise_range.num_vmas, args,
&details);
err = xe_vm_invalidate_madvise_range(vm, args->start, args->start + args->range);
err = xe_vm_invalidate_madvise_range(vm, madvise_range.addr,
madvise_range.addr + args->range);
if (madvise_range.has_svm_userptr_vmas)
xe_svm_notifier_unlock(vm);