mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 12:53:14 +01:00
Merge tag 'drm-fixes-2026-10-03' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie: "Live from Brisbane airport, it's Saturday Night drm fixes. The misc fixes tree didn't get a PR this week, so I'll probably have that to you when I see it, there were a few patches in there. Otherwise amdgpu is the main act, mediatek has a guest spot, and xe/i915 bring in a fix each. xe: - keep VF LMEM bar size low if no VFs enabled i915: - Disable VRR DC balance by default to fix timing issues mediatek: - Add missing IS_ERR check for ovl_adaptor platform device - Fix VID_DOWNSAMPLE_CONFIG register offset - Fix pdev reference leak in mtk_drm_bind() - Fix runtime PM leak in mtk_hdmi_ddc_v2_probe() - Fix ovl adaptor platform device leak amdgpu: - dc_state_create_copy() fix - HDMI RGB limited range fix - eDP ASSR fix - DCE 6 fixes - DCE 8.1 fix - SI DPM fixes - Reset fixes - Workaround for multiple SDMA entities with DCC - PWM backlight fix - GPUVM fixes - Switcheroo fix - Error handling leak fixes - GC 6 unload FW leak fix - SDMA 7.1 fix - DML frame size limit fix - RGB vs YCbCr 4:4:4 fix - DP MST fix - DC Power module fixes - MacBookPro14,3 fix amdkfd: - SVM fix radeon: - sparc64 fix" * tag 'drm-fixes-2026-10-03' of https://gitlab.freedesktop.org/drm/kernel: (36 commits) drm/mediatek: Fix ovl adaptor platform device leak drm/mediatek: Fix runtime PM leak in mtk_hdmi_ddc_v2_probe() drm/mediatek: Fix pdev reference leak in mtk_drm_bind() drm/amdgpu: reset VI ASIC on MacBookPro14,3 drm/amd/pm/si: Fix updating clock limits on AC/DC drm/amd/display: Fix stale replay_events after mod_power stream removal drm/radeon: Read the VRAM VBIOS signature with readb() drm/amd/display: guard dc_sink dereferences in MST mode validation drm/amd/display: Try RGB before YCbCr 4:4:4 in stream validation drm/amd/display: Fix sanitizer check for the DML frame size limit drm/amdgpu/gmc12.1: properly pass flush_type to gmc_v12_1_flush_vm_hub() drm/amdgpu: drop userq callback assignment for sdma 7.1 drm/amdgpu/gfx6: fix firmware leak on teardown drm/amdgpu: fix ACP MFD device leak on init failure drm/amdgpu: fix IP instance memory leak on kobject add failure drm/amdgpu: skip the noirq suspend reset for a switcheroo-parked GPU drm/amdgpu/gmc12: properly pass flush_type to gmc_v12_0_flush_vm_hub() drm/amd/display: map PWM brightness through custom backlight curve drm/amdgpu: implement workaround for sdma dcc corruption drm/amdkfd: Fix always mapped range mapping to all ACCESS GPUs ...
This commit is contained in:
commit
f7c918b8d9
34 files changed
+399
-87
No files matched your search
@@ -318,7 +318,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
|
||||
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
|
||||
acp_genpd_add_device);
|
||||
if (r)
|
||||
goto failure;
|
||||
goto failure_remove_mfd;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -443,7 +443,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
|
||||
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
|
||||
acp_genpd_add_device);
|
||||
if (r)
|
||||
goto failure;
|
||||
goto failure_remove_mfd;
|
||||
}
|
||||
|
||||
/* Assert Soft reset of ACP */
|
||||
@@ -461,7 +461,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
|
||||
if (--count == 0) {
|
||||
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
|
||||
r = -ETIMEDOUT;
|
||||
goto failure;
|
||||
goto failure_remove_mfd;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
@@ -479,7 +479,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
|
||||
if (--count == 0) {
|
||||
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
|
||||
r = -ETIMEDOUT;
|
||||
goto failure;
|
||||
goto failure_remove_mfd;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
@@ -489,6 +489,11 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
|
||||
cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
|
||||
return 0;
|
||||
|
||||
failure_remove_mfd:
|
||||
device_for_each_child(adev->acp.parent, NULL,
|
||||
acp_genpd_remove_device);
|
||||
mfd_remove_devices(adev->acp.parent);
|
||||
|
||||
failure:
|
||||
kfree(adev->acp.i2s_pdata);
|
||||
kfree(adev->acp.acp_res);
|
||||
|
||||
@@ -1325,6 +1325,8 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,
|
||||
ip_hw_instance->kobj.kset = &ip_hw_id->hw_id_kset;
|
||||
res = kobject_add(&ip_hw_instance->kobj, NULL,
|
||||
"%d", ip_hw_instance->num_instance);
|
||||
if (res)
|
||||
kobject_put(&ip_hw_instance->kobj);
|
||||
next_ip:
|
||||
if (reg_base_64)
|
||||
ip_offset += struct_size(ip, base_address_64,
|
||||
|
||||
@@ -2664,6 +2664,14 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev)
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
/*
|
||||
* A GPU parked by vga_switcheroo has no power and no PCIe link, so the
|
||||
* ASIC reset below would fail and abort the whole noirq suspend phase.
|
||||
* Bail out like amdgpu_device_prepare/suspend/resume() already do.
|
||||
*/
|
||||
if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
|
||||
return 0;
|
||||
|
||||
if (amdgpu_acpi_should_gpu_reset(adev)) {
|
||||
amdgpu_device_lock_reset_domain(adev->reset_domain);
|
||||
r = amdgpu_asic_reset(adev);
|
||||
|
||||
@@ -724,8 +724,14 @@ void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
|
||||
bool is_guilty_fence;
|
||||
bool is_guilty_context;
|
||||
|
||||
last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
|
||||
seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
|
||||
last_seq = amdgpu_fence_read(ring);
|
||||
seq = ring->fence_drv.sync_seq;
|
||||
|
||||
/* Hardware completion can precede the interrupt which signals fences. */
|
||||
if (last_seq == seq) {
|
||||
amdgpu_fence_process(ring);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there is nothing to reemit, return early and set an error on the fence
|
||||
* if applicable. If all of the fences are siganlled, this will be a nop.
|
||||
@@ -733,7 +739,9 @@ void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
|
||||
* we are skipping it on purpose.
|
||||
*/
|
||||
if (!ring->ring_backup_entries_to_copy) {
|
||||
amdgpu_fence_driver_force_completion(ring, &guilty_fence->base);
|
||||
if (guilty_fence)
|
||||
amdgpu_fence_driver_force_completion(ring,
|
||||
&guilty_fence->base);
|
||||
return;
|
||||
}
|
||||
ring->reemit = true;
|
||||
@@ -741,9 +749,8 @@ void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
|
||||
spin_lock_irqsave(&ring->fence_drv.lock, flags);
|
||||
do {
|
||||
last_seq++;
|
||||
last_seq &= ring->fence_drv.num_fences_mask;
|
||||
|
||||
ptr = &ring->fence_drv.fences[last_seq];
|
||||
ptr = &ring->fence_drv.fences[last_seq & ring->fence_drv.num_fences_mask];
|
||||
rcu_read_lock();
|
||||
unprocessed = rcu_dereference(*ptr);
|
||||
|
||||
@@ -800,26 +807,24 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
|
||||
struct amdgpu_fence *fence;
|
||||
u32 seq, last_seq;
|
||||
|
||||
last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
|
||||
seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
|
||||
last_seq = amdgpu_fence_read(ring);
|
||||
seq = ring->fence_drv.sync_seq;
|
||||
ring->ring_backup_entries_to_copy = 0;
|
||||
|
||||
/* if we've already seen this fence, return early.
|
||||
* ring->ring_backup_entries_to_copy is set to 0 so
|
||||
* the reemit helper will return early as well to
|
||||
* avoid getting stuck in a reemit loop.
|
||||
/*
|
||||
* Avoid replay loops for a repeated guilty fence. NULL identifies a
|
||||
* collateral ring, whose pending commands still need backup.
|
||||
*/
|
||||
if (ring->guilty_fence == guilty_fence) {
|
||||
if (guilty_fence && ring->guilty_fence == guilty_fence) {
|
||||
ring->guilty_fence = NULL;
|
||||
return;
|
||||
}
|
||||
ring->guilty_fence = guilty_fence;
|
||||
|
||||
do {
|
||||
while (last_seq != seq) {
|
||||
last_seq++;
|
||||
last_seq &= ring->fence_drv.num_fences_mask;
|
||||
|
||||
ptr = &ring->fence_drv.fences[last_seq];
|
||||
ptr = &ring->fence_drv.fences[last_seq & ring->fence_drv.num_fences_mask];
|
||||
rcu_read_lock();
|
||||
unprocessed = rcu_dereference(*ptr);
|
||||
|
||||
@@ -829,7 +834,7 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
|
||||
amdgpu_ring_backup_unprocessed_command(ring, fence);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
} while (last_seq != seq);
|
||||
}
|
||||
}
|
||||
|
||||
struct amdgpu_fence *
|
||||
|
||||
@@ -2342,7 +2342,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
|
||||
void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
|
||||
u32 num_clear_entities, num_move_entities;
|
||||
u32 num_clear_entities, num_move_entities, sdma_ip_version;
|
||||
int r, i, j;
|
||||
|
||||
if (!adev->mman.initialized || amdgpu_in_reset(adev) ||
|
||||
@@ -2367,6 +2367,12 @@ void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
|
||||
|
||||
num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
|
||||
num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
|
||||
/* TODO: workaround for DCC corruption when moving BOs from multiple queues at
|
||||
* the same time: use a single queue until the root cause is identified and fixed.
|
||||
*/
|
||||
sdma_ip_version = amdgpu_ip_version(adev, SDMA0_HWIP, 0);
|
||||
if (sdma_ip_version == IP_VERSION(7, 0, 0) || sdma_ip_version == IP_VERSION(7, 0, 1))
|
||||
num_move_entities = 1;
|
||||
|
||||
adev->mman.clear_entities = kzalloc_objs(struct amdgpu_ttm_buffer_entity,
|
||||
num_clear_entities);
|
||||
|
||||
@@ -3808,6 +3808,7 @@ static int gfx_v11_0_cp_gfx_resume(struct amdgpu_device *adev)
|
||||
rb_bufsz = order_base_2(ring->ring_size / 8);
|
||||
tmp = REG_SET_FIELD(0, CP_RB0_CNTL, RB_BUFSZ, rb_bufsz);
|
||||
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, RB_BLKSZ, rb_bufsz - 2);
|
||||
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, KMD_QUEUE, 1);
|
||||
WREG32_SOC15(GC, 0, regCP_RB0_CNTL, tmp);
|
||||
|
||||
/* Initialize the ring buffer's write pointers */
|
||||
@@ -4216,6 +4217,7 @@ static int gfx_v11_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
|
||||
tmp = regCP_GFX_HQD_CNTL_DEFAULT;
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BUFSZ, rb_bufsz);
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BLKSZ, rb_bufsz - 2);
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, KMD_QUEUE, prop->kernel_queue);
|
||||
#ifdef __BIG_ENDIAN
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, BUF_SWAP, 1);
|
||||
#endif
|
||||
|
||||
@@ -2767,6 +2767,7 @@ static int gfx_v12_0_cp_gfx_resume(struct amdgpu_device *adev)
|
||||
rb_bufsz = order_base_2(ring->ring_size / 8);
|
||||
tmp = REG_SET_FIELD(0, CP_RB0_CNTL, RB_BUFSZ, rb_bufsz);
|
||||
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, RB_BLKSZ, rb_bufsz - 2);
|
||||
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, KMD_QUEUE, 1);
|
||||
WREG32_SOC15(GC, 0, regCP_RB0_CNTL, tmp);
|
||||
|
||||
/* Initialize the ring buffer's write pointers */
|
||||
@@ -3059,6 +3060,7 @@ static int gfx_v12_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
|
||||
tmp = regCP_GFX_HQD_CNTL_DEFAULT;
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BUFSZ, rb_bufsz);
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BLKSZ, rb_bufsz - 2);
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, KMD_QUEUE, prop->kernel_queue);
|
||||
#ifdef __BIG_ENDIAN
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, BUF_SWAP, 1);
|
||||
#endif
|
||||
|
||||
@@ -322,6 +322,14 @@ static const u32 verde_rlc_save_restore_register_list[] =
|
||||
0x00000000
|
||||
};
|
||||
|
||||
static void gfx_v6_0_free_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
amdgpu_ucode_release(&adev->gfx.pfp_fw);
|
||||
amdgpu_ucode_release(&adev->gfx.me_fw);
|
||||
amdgpu_ucode_release(&adev->gfx.ce_fw);
|
||||
amdgpu_ucode_release(&adev->gfx.rlc_fw);
|
||||
}
|
||||
|
||||
static int gfx_v6_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const char *chip_name;
|
||||
@@ -3249,6 +3257,7 @@ static int gfx_v6_0_sw_fini(struct amdgpu_ip_block *ip_block)
|
||||
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
|
||||
|
||||
amdgpu_gfx_rlc_fini(adev);
|
||||
gfx_v6_0_free_microcode(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ static void gmc_v12_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
return;
|
||||
}
|
||||
|
||||
gmc_v12_0_flush_vm_hub(adev, vmid, vmhub, 0);
|
||||
gmc_v12_0_flush_vm_hub(adev, vmid, vmhub, flush_type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -389,7 +389,7 @@ static void gmc_v12_1_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
return;
|
||||
}
|
||||
|
||||
gmc_v12_1_flush_vm_hub(adev, vmid, vmhub, 0);
|
||||
gmc_v12_1_flush_vm_hub(adev, vmid, vmhub, flush_type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1339,10 +1339,6 @@ static int sdma_v7_1_sw_init(struct amdgpu_ip_block *ip_block)
|
||||
else
|
||||
DRM_ERROR("Failed to allocated memory for SDMA IP Dump\n");
|
||||
|
||||
#ifdef CONFIG_DRM_AMDGPU_NAVI3X_USERQ
|
||||
adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -1397,6 +1397,7 @@ struct vi_reset_quirk {
|
||||
static const struct vi_reset_quirk vi_reset_quirks[] = {
|
||||
{ 0x67ef, PCI_VENDOR_ID_APPLE, 0x0190, 0xe3 }, /* Radeon Pro 555X */
|
||||
{ 0x67ef, PCI_VENDOR_ID_APPLE, 0x018f, 0xc2 }, /* Radeon Pro 560X */
|
||||
{ 0x67ef, PCI_VENDOR_ID_APPLE, 0x017a, 0xc7 }, /* Radeon Pro 555 */
|
||||
};
|
||||
|
||||
static bool vi_need_reset_on_init(struct amdgpu_device *adev)
|
||||
|
||||
@@ -1752,12 +1752,15 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
|
||||
}
|
||||
|
||||
/*
|
||||
* If prange with always mapped flag, update mapping on GPUs with
|
||||
* ACCESS attribute
|
||||
* If prange with always mapped flag is not mapped or migrated
|
||||
* yet, update mapping on GPUs with ACCESS attribute. Don't add
|
||||
* them otherwise, ACCESS GPUs may be on different XGMI hives,
|
||||
* that would force hmm_range_fault to migrate VRAM back to ram.
|
||||
*/
|
||||
if (prange->flags & KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED)
|
||||
bitmap_or(ctx->bitmap, ctx->bitmap, prange->bitmap_access,
|
||||
MAX_GPU_INSTANCE);
|
||||
if (bitmap_empty(ctx->bitmap, MAX_GPU_INSTANCE) &&
|
||||
prange->flags & KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED)
|
||||
bitmap_copy(ctx->bitmap, prange->bitmap_access,
|
||||
MAX_GPU_INSTANCE);
|
||||
} else {
|
||||
bitmap_or(ctx->bitmap, prange->bitmap_access,
|
||||
prange->bitmap_aip, MAX_GPU_INSTANCE);
|
||||
|
||||
@@ -426,6 +426,8 @@ static int amdgpu_dm_init_power_module(struct amdgpu_display_manager *dm)
|
||||
init_data[i].use_custom_backlight_caps = false;
|
||||
init_data[i].custom_backlight_caps_config_no = 0;
|
||||
init_data[i].use_linear_backlight_curve = false;
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)
|
||||
init_data[i].use_linear_backlight_curve = true;
|
||||
init_data[i].def_varibright_enable = 0;
|
||||
init_data[i].varibright_level = 0;
|
||||
/*
|
||||
@@ -1582,9 +1584,14 @@ static int dm_suspend(struct amdgpu_ip_block *ip_block)
|
||||
dc_allow_idle_optimizations(adev->dm.dc, false);
|
||||
|
||||
dm->cached_dc_state = dc_state_create_copy(dm->dc->current_state);
|
||||
if (!dm->cached_dc_state) {
|
||||
drm_err(adev_to_drm(adev),
|
||||
"Failed to allocate cached DC state during suspend\n");
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (dm->cached_dc_state)
|
||||
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
|
||||
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
|
||||
|
||||
res = amdgpu_dm_commit_zero_streams(dm->dc);
|
||||
if (res != DC_OK) {
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "modules/inc/mod_power.h"
|
||||
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_utils.h>
|
||||
@@ -118,6 +119,68 @@ static inline u32 scale_fw_to_input(int min, int max, u64 input)
|
||||
return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), AMDGPU_MAX_BL_LEVEL);
|
||||
}
|
||||
|
||||
static u32 backlight_signal_to_luminance(const struct amdgpu_dm_backlight_caps *caps,
|
||||
u32 signal)
|
||||
{
|
||||
u32 lower_signal, upper_signal;
|
||||
u32 lower_lum, upper_lum;
|
||||
int i;
|
||||
|
||||
if (!caps->data_points)
|
||||
return DIV_ROUND_CLOSEST(signal * 100, AMDGPU_MAX_BL_LEVEL);
|
||||
|
||||
if (signal < caps->luminance_data[0].input_signal) {
|
||||
lower_signal = 0;
|
||||
lower_lum = 0;
|
||||
upper_signal = caps->luminance_data[0].input_signal;
|
||||
upper_lum = caps->luminance_data[0].luminance;
|
||||
} else if (signal >=
|
||||
caps->luminance_data[caps->data_points - 1].input_signal) {
|
||||
lower_signal = caps->luminance_data[caps->data_points - 1].input_signal;
|
||||
lower_lum = caps->luminance_data[caps->data_points - 1].luminance;
|
||||
upper_signal = caps->max_input_signal;
|
||||
upper_lum = 100;
|
||||
} else {
|
||||
for (i = 1;
|
||||
i < caps->data_points &&
|
||||
signal > caps->luminance_data[i].input_signal;
|
||||
i++)
|
||||
;
|
||||
|
||||
lower_signal = caps->luminance_data[i - 1].input_signal;
|
||||
upper_signal = caps->luminance_data[i].input_signal;
|
||||
lower_lum = caps->luminance_data[i - 1].luminance;
|
||||
upper_lum = caps->luminance_data[i].luminance;
|
||||
}
|
||||
|
||||
if (upper_signal == lower_signal)
|
||||
return upper_lum;
|
||||
|
||||
return lower_lum + DIV_ROUND_CLOSEST((upper_lum - lower_lum) *
|
||||
(signal - lower_signal),
|
||||
upper_signal - lower_signal);
|
||||
}
|
||||
|
||||
static u32 convert_brightness_to_millipercent(const struct amdgpu_dm_backlight_caps *caps,
|
||||
u32 user_brightness)
|
||||
{
|
||||
unsigned int min, max;
|
||||
u32 signal, luminance;
|
||||
|
||||
if (!get_brightness_range(caps, &min, &max))
|
||||
return DIV_ROUND_CLOSEST_ULL((u64)user_brightness * 100000,
|
||||
MAX_BACKLIGHT_LEVEL);
|
||||
|
||||
user_brightness = clamp(user_brightness, min, max);
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)
|
||||
return DIV_ROUND_CLOSEST_ULL((u64)user_brightness * 100000, max);
|
||||
|
||||
signal = scale_input_to_fw(max, user_brightness);
|
||||
luminance = backlight_signal_to_luminance(caps, signal);
|
||||
|
||||
return min_t(u32, luminance * 1000, 100000);
|
||||
}
|
||||
|
||||
STATIC_IFN_KUNIT
|
||||
void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
|
||||
unsigned int min, unsigned int max,
|
||||
@@ -260,10 +323,10 @@ void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
struct amdgpu_dm_backlight_caps *caps;
|
||||
struct dc_link *link;
|
||||
u32 brightness = 0;
|
||||
u32 millipercent = 0;
|
||||
bool rc = false, reallow_idle = false;
|
||||
struct drm_connector *connector;
|
||||
struct dc_stream_state *stream;
|
||||
unsigned int min, max;
|
||||
|
||||
list_for_each_entry(connector, &dm->ddev->mode_config.connector_list, head) {
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
@@ -286,12 +349,21 @@ void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
/* update scratch register */
|
||||
if (bl_idx == 0)
|
||||
amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]);
|
||||
brightness = convert_brightness_from_user(caps, dm->brightness[bl_idx]);
|
||||
link = (struct dc_link *)dm->backlight_link[bl_idx];
|
||||
|
||||
/* Apply brightness quirk */
|
||||
if (caps->brightness_mask)
|
||||
brightness |= caps->brightness_mask;
|
||||
link = (struct dc_link *)dm->backlight_link[bl_idx];
|
||||
stream = dm_find_stream_with_link(dm, link);
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
if (caps->aux_support) {
|
||||
brightness = convert_brightness_from_user(caps, dm->brightness[bl_idx]);
|
||||
/* Apply brightness quirk */
|
||||
if (caps->brightness_mask)
|
||||
brightness |= caps->brightness_mask;
|
||||
} else {
|
||||
millipercent = convert_brightness_to_millipercent(caps,
|
||||
user_brightness);
|
||||
}
|
||||
|
||||
if (trace_amdgpu_dm_brightness_enabled()) {
|
||||
trace_amdgpu_dm_brightness(__builtin_return_address(0),
|
||||
@@ -301,10 +373,6 @@ void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
power_supply_is_system_supplied() > 0);
|
||||
}
|
||||
|
||||
stream = dm_find_stream_with_link(dm, link);
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
mutex_lock(&dm->dc_lock);
|
||||
if (dm->dc->caps.ips_support && dm->dc->ctx->dmub_srv->idle_allowed) {
|
||||
dc_allow_idle_optimizations(dm->dc, false);
|
||||
@@ -316,10 +384,8 @@ void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
AUX_BL_DEFAULT_TRANSITION_TIME_MS, false, true);
|
||||
} else {
|
||||
/* power module uses millipercent */
|
||||
get_brightness_range(caps, &min, &max);
|
||||
brightness = DIV_ROUND_CLOSEST(brightness * 100, (max - min)) * 1000;
|
||||
rc = mod_power_set_backlight_percent(dm->power_module, stream,
|
||||
brightness, 0, false);
|
||||
millipercent, 0, false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -732,6 +732,24 @@ get_aspect_ratio(const struct drm_display_mode *mode_in)
|
||||
}
|
||||
EXPORT_IF_KUNIT(get_aspect_ratio);
|
||||
|
||||
/*
|
||||
* CTA-861 5.1: RGB video formats default to limited range except 640x480 (VIC 1).
|
||||
* With Broadcast RGB left at Automatic follow that default, as i915 does.
|
||||
*/
|
||||
static bool rgb_output_is_limited_range(const struct dc_crtc_timing *dc_crtc_timing,
|
||||
const struct drm_connector_state *connector_state)
|
||||
{
|
||||
switch (connector_state->hdmi.broadcast_rgb) {
|
||||
case DRM_HDMI_BROADCAST_RGB_FULL:
|
||||
return false;
|
||||
case DRM_HDMI_BROADCAST_RGB_LIMITED:
|
||||
return true;
|
||||
default:
|
||||
return connector_state->connector->display_info.is_hdmi &&
|
||||
dc_crtc_timing->vic > 1;
|
||||
}
|
||||
}
|
||||
|
||||
enum dc_color_space
|
||||
amdgpu_dm_get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing,
|
||||
const struct drm_connector_state *connector_state)
|
||||
@@ -757,7 +775,7 @@ amdgpu_dm_get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing,
|
||||
case DRM_MODE_COLORIMETRY_BT2020_RGB:
|
||||
case DRM_MODE_COLORIMETRY_BT2020_YCC:
|
||||
if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) {
|
||||
if (connector_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
|
||||
if (rgb_output_is_limited_range(dc_crtc_timing, connector_state))
|
||||
color_space = COLOR_SPACE_2020_RGB_LIMITEDRANGE;
|
||||
else
|
||||
color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
|
||||
@@ -769,7 +787,7 @@ amdgpu_dm_get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing,
|
||||
default:
|
||||
if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) {
|
||||
color_space = COLOR_SPACE_SRGB;
|
||||
if (connector_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
|
||||
if (rgb_output_is_limited_range(dc_crtc_timing, connector_state))
|
||||
color_space = COLOR_SPACE_SRGB_LIMITED;
|
||||
/*
|
||||
* 27030khz is the separation point between HDTV and SDTV
|
||||
@@ -2256,8 +2274,8 @@ amdgpu_dm_create_validate_stream_for_sink(struct drm_connector *connector,
|
||||
* below gate which of these entries are actually attempted.
|
||||
*/
|
||||
static const enum dc_pixel_encoding encoding_order[] = {
|
||||
PIXEL_ENCODING_YCBCR444,
|
||||
PIXEL_ENCODING_RGB,
|
||||
PIXEL_ENCODING_YCBCR444,
|
||||
PIXEL_ENCODING_YCBCR422,
|
||||
PIXEL_ENCODING_YCBCR420,
|
||||
};
|
||||
|
||||
@@ -1231,7 +1231,8 @@ static bool get_conv_frl_bw(struct amdgpu_dm_connector *aconnector,
|
||||
unsigned int max_sink_bw_in_kbps = 0;
|
||||
unsigned int dsc_max_sink_bw_in_kbps = 0;
|
||||
|
||||
if (aconnector->dc_link->dc->caps.dp_hdmi21_pcon_support &&
|
||||
if (aconnector->dc_sink &&
|
||||
aconnector->dc_link->dc->caps.dp_hdmi21_pcon_support &&
|
||||
aconnector->mst_downstream_port_caps.bytes.byte0.bits.DWN_STRM_PORTX_TYPE == DOWN_STREAM_DETAILED_HDMI) {
|
||||
max_conv_bw_in_kbps = dc_link_bw_kbps_from_raw_frl_link_rate_data(
|
||||
aconnector->dc_link->dc,
|
||||
@@ -1996,6 +1997,9 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
struct dc_dsc_config_options dsc_options = {0};
|
||||
uint32_t stream_kbps;
|
||||
|
||||
if (!aconnector->dc_sink)
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
|
||||
/* DSC unnecessary case
|
||||
* Check if timing could be supported within end-to-end BW
|
||||
*/
|
||||
|
||||
@@ -409,7 +409,9 @@ static void dm_test_output_color_space_default_rgb_full(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
state.connector = connector;
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
|
||||
@@ -559,7 +561,9 @@ static void dm_test_output_color_space_bt2020_rgb(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
state.connector = connector;
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
|
||||
|
||||
@@ -584,6 +588,110 @@ static void dm_test_output_color_space_bt2020_rgb_limited(struct kunit *test)
|
||||
(int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_default_rgb_auto_hdmi_cta - Automatic follows the CTA-861 default
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_output_color_space_default_rgb_auto_hdmi_cta(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
connector->display_info.is_hdmi = true;
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
timing.vic = 32;
|
||||
state.connector = connector;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
|
||||
(int)COLOR_SPACE_SRGB_LIMITED);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_default_rgb_auto_hdmi_vga - 640x480 (VIC 1) stays full range
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_output_color_space_default_rgb_auto_hdmi_vga(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
connector->display_info.is_hdmi = true;
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
timing.vic = 1;
|
||||
state.connector = connector;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
|
||||
(int)COLOR_SPACE_SRGB);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_default_rgb_auto_dp_cta - Automatic on a non-HDMI sink is full range
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_output_color_space_default_rgb_auto_dp_cta(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
timing.vic = 32;
|
||||
state.connector = connector;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
|
||||
(int)COLOR_SPACE_SRGB);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_default_rgb_full_hdmi_cta - Full overrides the CTA-861 default
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_output_color_space_default_rgb_full_hdmi_cta(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
connector->display_info.is_hdmi = true;
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
timing.vic = 32;
|
||||
state.connector = connector;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
|
||||
(int)COLOR_SPACE_SRGB);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_bt2020_rgb_auto_hdmi_cta - BT.2020 RGB follows the same default
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_output_color_space_bt2020_rgb_auto_hdmi_cta(struct kunit *test)
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
connector->display_info.is_hdmi = true;
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
timing.vic = 32;
|
||||
state.connector = connector;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
|
||||
state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
|
||||
(int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_output_color_space_bt2020_ycc - Test Output color space bt2020 ycc
|
||||
* @test: The KUnit test context
|
||||
@@ -647,7 +755,9 @@ static void dm_test_output_color_space_bt2020_ycc_rgb_encoding(struct kunit *tes
|
||||
{
|
||||
struct dc_crtc_timing timing = {};
|
||||
struct drm_connector_state state = {};
|
||||
struct drm_connector *connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
|
||||
|
||||
state.connector = connector;
|
||||
timing.pixel_encoding = PIXEL_ENCODING_RGB;
|
||||
state.colorspace = DRM_MODE_COLORIMETRY_BT2020_YCC;
|
||||
|
||||
@@ -3425,6 +3535,7 @@ static struct dm_test_fill_ctx *dm_test_fill_ctx_alloc(struct kunit *test)
|
||||
|
||||
ctx->conn_state = drmm_kzalloc(ctx->drm, sizeof(*ctx->conn_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, ctx->conn_state);
|
||||
ctx->conn_state->connector = &ctx->aconnector->base;
|
||||
ctx->stream = kunit_kzalloc(test, sizeof(*ctx->stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, ctx->stream);
|
||||
ctx->mode = kunit_kzalloc(test, sizeof(*ctx->mode), GFP_KERNEL);
|
||||
@@ -3818,6 +3929,7 @@ static struct dm_test_stream_ctx *dm_test_stream_ctx_alloc(struct kunit *test)
|
||||
|
||||
ctx->dm_state = kunit_kzalloc(test, sizeof(*ctx->dm_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, ctx->dm_state);
|
||||
ctx->dm_state->base.connector = &ctx->aconnector->base;
|
||||
ctx->dm_state->scaling = RMX_OFF;
|
||||
|
||||
ctx->mode = kunit_kzalloc(test, sizeof(*ctx->mode), GFP_KERNEL);
|
||||
@@ -5458,6 +5570,11 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
|
||||
KUNIT_CASE(dm_test_output_color_space_oprgb),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_limited),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_rgb_auto_hdmi_cta),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_rgb_auto_hdmi_vga),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_rgb_auto_dp_cta),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_rgb_full_hdmi_cta),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_auto_hdmi_cta),
|
||||
KUNIT_CASE(dm_test_output_color_space_bt2020_ycc),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_ycbcr709_y_only),
|
||||
KUNIT_CASE(dm_test_output_color_space_default_ycbcr601),
|
||||
|
||||
@@ -1905,6 +1905,7 @@ struct dc_scratch_space {
|
||||
struct ddc_service *ddc;
|
||||
|
||||
enum dp_panel_mode panel_mode;
|
||||
bool panel_mode_initialized;
|
||||
bool aux_mode;
|
||||
|
||||
/* Private to DC core */
|
||||
|
||||
@@ -29,7 +29,7 @@ dml_ccflags := $(CC_FLAGS_FPU)
|
||||
dml_rcflags := $(CC_FLAGS_NO_FPU)
|
||||
|
||||
ifneq ($(CONFIG_FRAME_WARN),0)
|
||||
ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)$(CONFIG_UBSAN)),y)
|
||||
ifneq ($(filter y,$(CONFIG_KASAN) $(CONFIG_KCSAN) $(CONFIG_UBSAN)),)
|
||||
ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_COMPILE_TEST),yy)
|
||||
frame_warn_limit := 4096
|
||||
else
|
||||
|
||||
@@ -28,7 +28,7 @@ dml2_ccflags := $(CC_FLAGS_FPU)
|
||||
dml2_rcflags := $(CC_FLAGS_NO_FPU)
|
||||
|
||||
ifneq ($(CONFIG_FRAME_WARN),0)
|
||||
ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)$(CONFIG_UBSAN)),y)
|
||||
ifneq ($(filter y,$(CONFIG_KASAN) $(CONFIG_KCSAN) $(CONFIG_UBSAN)),)
|
||||
ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_COMPILE_TEST),yy)
|
||||
frame_warn_limit := 4096
|
||||
else
|
||||
|
||||
@@ -93,6 +93,7 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
|
||||
}
|
||||
|
||||
link->panel_mode = panel_mode;
|
||||
link->panel_mode_initialized = true;
|
||||
DC_LOG_DETECTION_DP_CAPS("%d eDP panel mode supported: %d, enabled: %d\n",
|
||||
link->link_index,
|
||||
link->dpcd_caps.panel_mode_edp,
|
||||
@@ -1297,7 +1298,8 @@ void edp_set_panel_assr(struct dc_link *link, struct pipe_ctx *pipe_ctx,
|
||||
|
||||
result = cp_psp->funcs.enable_assr(cp_psp->handle, link);
|
||||
|
||||
if (!result && link->panel_mode != DP_PANEL_MODE_EDP)
|
||||
if (!result && link->panel_mode_initialized &&
|
||||
link->panel_mode != DP_PANEL_MODE_EDP)
|
||||
*panel_mode = DP_PANEL_MODE_DEFAULT;
|
||||
}
|
||||
}
|
||||
@@ -448,6 +448,12 @@ static const struct dce_abm_mask abm_mask = {
|
||||
ABM_MASK_SH_LIST_DCE110(_MASK)
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults = { 0 };
|
||||
|
||||
static const struct dc_check_config config_defaults = {
|
||||
.enable_legacy_fast_update = true,
|
||||
};
|
||||
|
||||
#define CTX ctx
|
||||
#define REG(reg) mm ## reg
|
||||
|
||||
@@ -937,6 +943,8 @@ static bool dce60_construct(
|
||||
dc->caps.max_cursor_size = 64;
|
||||
dc->caps.dual_link_dvi = true;
|
||||
dc->caps.extended_aux_timeout_support = false;
|
||||
dc->debug = debug_defaults;
|
||||
dc->check_config = config_defaults;
|
||||
|
||||
/*************************************************
|
||||
* Create resources *
|
||||
@@ -1134,6 +1142,8 @@ static bool dce61_construct(
|
||||
dc->caps.i2c_speed_in_khz = 40;
|
||||
dc->caps.max_cursor_size = 64;
|
||||
dc->caps.is_apu = true;
|
||||
dc->debug = debug_defaults;
|
||||
dc->check_config = config_defaults;
|
||||
|
||||
/*************************************************
|
||||
* Create resources *
|
||||
@@ -1331,7 +1341,8 @@ static bool dce64_construct(
|
||||
dc->caps.max_downscale_ratio = 200;
|
||||
dc->caps.i2c_speed_in_khz = 40;
|
||||
dc->caps.max_cursor_size = 64;
|
||||
dc->caps.is_apu = true;
|
||||
dc->debug = debug_defaults;
|
||||
dc->check_config = config_defaults;
|
||||
|
||||
/*************************************************
|
||||
* Create resources *
|
||||
|
||||
@@ -1148,6 +1148,8 @@ static bool dce81_construct(
|
||||
dc->caps.max_cursor_size = 128;
|
||||
dc->caps.min_horizontal_blanking_period = 80;
|
||||
dc->caps.is_apu = true;
|
||||
dc->debug = debug_defaults;
|
||||
dc->check_config = config_defaults;
|
||||
|
||||
/*************************************************
|
||||
* Create resources *
|
||||
|
||||
@@ -328,6 +328,7 @@ bool mod_power_add_stream(struct mod_power *mod_power,
|
||||
core_power->map[core_power->num_entities].psr_enabled = 0;
|
||||
core_power->map[core_power->num_entities].psr_events = psr_event_vsync;
|
||||
core_power->map[core_power->num_entities].psr_power_opt = 0;
|
||||
core_power->map[core_power->num_entities].replay_events = replay_event_vsync;
|
||||
core_power->num_entities++;
|
||||
return true;
|
||||
}
|
||||
@@ -387,6 +388,7 @@ bool mod_power_remove_stream(struct mod_power *mod_power,
|
||||
core_power->map[i].psr_enabled = core_power->map[i + 1].psr_enabled;
|
||||
core_power->map[i].psr_events = core_power->map[i + 1].psr_events;
|
||||
core_power->map[i].psr_power_opt = core_power->map[i + 1].psr_power_opt;
|
||||
core_power->map[i].replay_events = core_power->map[i + 1].replay_events;
|
||||
|
||||
memcpy(core_power->map[i].psr_context, core_power->map[i + 1].psr_context, sizeof(struct mod_power_psr_context));
|
||||
memset(core_power->map[i + 1].psr_context, 0, sizeof(struct mod_power_psr_context));
|
||||
|
||||
@@ -5263,7 +5263,8 @@ static int si_init_smc_table(struct amdgpu_device *adev)
|
||||
break;
|
||||
}
|
||||
|
||||
if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
|
||||
if ((adev->flags & AMD_IS_MOBILITY) &&
|
||||
(adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC))
|
||||
table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
|
||||
|
||||
if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) {
|
||||
@@ -7237,6 +7238,19 @@ static void si_parse_pplib_non_clock_info(struct amdgpu_device *adev,
|
||||
adev->pm.dpm.uvd_ps = rps;
|
||||
}
|
||||
|
||||
static void si_update_limits(struct amdgpu_clock_and_voltage_limits *limits,
|
||||
struct rv7xx_pl *pl)
|
||||
{
|
||||
if (pl->sclk > limits->sclk)
|
||||
limits->sclk = pl->sclk;
|
||||
if (pl->mclk > limits->mclk)
|
||||
limits->mclk = pl->mclk;
|
||||
if (pl->vddc > limits->vddc)
|
||||
limits->vddc = pl->vddc;
|
||||
if (pl->vddci > limits->vddci)
|
||||
limits->vddci = pl->vddci;
|
||||
}
|
||||
|
||||
static void si_parse_pplib_clock_info(struct amdgpu_device *adev,
|
||||
struct amdgpu_ps *rps, int index,
|
||||
union pplib_clock_info *clock_info)
|
||||
@@ -7245,7 +7259,6 @@ static void si_parse_pplib_clock_info(struct amdgpu_device *adev,
|
||||
struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
|
||||
struct si_power_info *si_pi = si_get_pi(adev);
|
||||
struct si_ps *ps = si_get_ps(rps);
|
||||
struct amdgpu_clock_and_voltage_limits *limits;
|
||||
u16 leakage_voltage;
|
||||
struct rv7xx_pl *pl = &ps->performance_levels[index];
|
||||
int ret;
|
||||
@@ -7310,26 +7323,14 @@ static void si_parse_pplib_clock_info(struct amdgpu_device *adev,
|
||||
* VBIOS can contain conflicting values between:
|
||||
* - the maximum allowed clocks and voltages on AC or DC
|
||||
* - the clocks and voltages in power states on AC or DC
|
||||
*
|
||||
* Assume that the AC limits are the maximum of all power states,
|
||||
* and the DC limits are the maximum of battery power states.
|
||||
*/
|
||||
si_update_limits(&adev->pm.dpm.dyn_state.max_clock_voltage_on_ac, pl);
|
||||
if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
|
||||
ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE)
|
||||
limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
|
||||
else if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
|
||||
ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)
|
||||
limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
|
||||
else
|
||||
limits = NULL;
|
||||
|
||||
if (limits) {
|
||||
if (pl->sclk > limits->sclk)
|
||||
limits->sclk = pl->sclk;
|
||||
if (pl->mclk > limits->mclk)
|
||||
limits->mclk = pl->mclk;
|
||||
if (pl->vddc > limits->vddc)
|
||||
limits->vddc = pl->vddc;
|
||||
if (pl->vddci > limits->vddci)
|
||||
limits->vddci = pl->vddci;
|
||||
}
|
||||
si_update_limits(&adev->pm.dpm.dyn_state.max_clock_voltage_on_dc, pl);
|
||||
}
|
||||
|
||||
union pplib_power_state {
|
||||
|
||||
@@ -120,6 +120,10 @@ intel_display_param_named_unsafe(enable_psr, int, 0400,
|
||||
"(0=disabled, 1=enable up to PSR1, 2=enable up to PSR2) "
|
||||
"Default: -1 (use per-chip default)");
|
||||
|
||||
intel_display_param_named_unsafe(enable_dc_balance, bool, 0400,
|
||||
"Enable VRR DC balance (0=disabled, 1=enabled). "
|
||||
"Default: 0 (disabled)");
|
||||
|
||||
intel_display_param_named_unsafe(enable_panel_replay, int, 0400,
|
||||
"Enable Panel Replay (0=disabled, 1=enabled). Default: -1 (use per-chip default)");
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ struct drm_printer;
|
||||
param(bool, enable_dp_mst, true, 0600) \
|
||||
param(int, enable_fbc, -1, 0600) \
|
||||
param(int, enable_psr, -1, 0600) \
|
||||
param(bool, enable_dc_balance, false, 0600) \
|
||||
param(int, enable_panel_replay, -1, 0600) \
|
||||
param(bool, psr_safest_params, false, 0400) \
|
||||
param(bool, enable_psr2_sel_fetch, true, 0400) \
|
||||
|
||||
@@ -386,10 +386,12 @@ static bool intel_vrr_dc_balance_possible(const struct intel_crtc_state *crtc_st
|
||||
static void
|
||||
intel_vrr_dc_balance_compute_config(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
int guardband_usec, adjustment_usec;
|
||||
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
||||
|
||||
if (!intel_vrr_dc_balance_possible(crtc_state) || !crtc_state->vrr.enable)
|
||||
if (!intel_vrr_dc_balance_possible(crtc_state) ||
|
||||
!crtc_state->vrr.enable || !display->params.enable_dc_balance)
|
||||
return;
|
||||
|
||||
crtc_state->vrr.dc_balance.vmax = crtc_state->vrr.vmax;
|
||||
|
||||
@@ -638,8 +638,10 @@ static int mtk_drm_bind(struct device *dev)
|
||||
private->mtk_drm_bound = true;
|
||||
private->dev = dev;
|
||||
|
||||
if (!mtk_drm_get_all_drm_priv(dev))
|
||||
if (!mtk_drm_get_all_drm_priv(dev)) {
|
||||
put_device(private->mutex_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm = drm_dev_alloc(&mtk_drm_driver, dev);
|
||||
if (IS_ERR(drm)) {
|
||||
@@ -1060,7 +1062,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
||||
struct mtk_mmsys_driver_data *mtk_drm_data;
|
||||
struct device_node *node;
|
||||
struct component_match *match = NULL;
|
||||
struct platform_device *ovl_adaptor;
|
||||
struct platform_device *ovl_adaptor = NULL;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@@ -1112,6 +1114,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
||||
PLATFORM_DEVID_AUTO,
|
||||
(void *)private->mmsys_dev,
|
||||
sizeof(*private->mmsys_dev));
|
||||
if (IS_ERR(ovl_adaptor))
|
||||
return PTR_ERR(ovl_adaptor);
|
||||
|
||||
private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev = &ovl_adaptor->dev;
|
||||
mtk_ddp_comp_init(dev, NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR],
|
||||
DDP_COMPONENT_DRM_OVL_ADAPTOR);
|
||||
@@ -1205,6 +1210,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
||||
err_pm:
|
||||
pm_runtime_disable(dev);
|
||||
err_node:
|
||||
if (ovl_adaptor)
|
||||
platform_device_unregister(ovl_adaptor);
|
||||
of_node_put(private->mutex_node);
|
||||
for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
|
||||
of_node_put(private->comp_node[i]);
|
||||
@@ -1214,9 +1221,15 @@ err_node:
|
||||
static void mtk_drm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mtk_drm_private *private = platform_get_drvdata(pdev);
|
||||
struct device *ovl_adaptor_dev;
|
||||
int i;
|
||||
|
||||
ovl_adaptor_dev =
|
||||
private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev;
|
||||
|
||||
component_master_del(&pdev->dev, &mtk_drm_ops);
|
||||
if (ovl_adaptor_dev)
|
||||
platform_device_unregister(to_platform_device(ovl_adaptor_dev));
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
of_node_put(private->mutex_node);
|
||||
for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
|
||||
|
||||
@@ -376,8 +376,10 @@ static int mtk_hdmi_ddc_v2_probe(struct platform_device *pdev)
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
ret = devm_i2c_add_adapter(dev, &ddc->adap);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
return dev_err_probe(dev, ret, "Cannot add DDC I2C adapter\n");
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, ddc);
|
||||
return 0;
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
#define TPI_AUDIO_LOOKUP_EN BIT(2)
|
||||
|
||||
/* Video downsampling configuration */
|
||||
#define VID_DOWNSAMPLE_CONFIG 0x8d0
|
||||
#define VID_DOWNSAMPLE_CONFIG 0x8f0
|
||||
#define C444_C422_CONFIG_ENABLE BIT(0)
|
||||
#define C422_C420_CONFIG_ENABLE BIT(4)
|
||||
#define C422_C420_CONFIG_BYPASS BIT(5)
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
static bool igp_read_bios_from_vram(struct radeon_device *rdev)
|
||||
{
|
||||
uint8_t __iomem *bios;
|
||||
uint8_t val1, val2;
|
||||
resource_size_t vram_base;
|
||||
resource_size_t size = 256 * 1024; /* ??? */
|
||||
|
||||
@@ -63,7 +64,10 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
|
||||
val1 = readb(&bios[0]);
|
||||
val2 = readb(&bios[1]);
|
||||
|
||||
if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
|
||||
iounmap(bios);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -82,16 +82,33 @@ static void pf_engine_activity_stats(struct xe_device *xe, unsigned int num_vfs,
|
||||
}
|
||||
}
|
||||
|
||||
static int resize_vf_vram_bar(struct xe_device *xe, int num_vfs)
|
||||
static int pf_resize_vf_vram_bar(struct xe_device *xe, int num_vfs)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||
char buf[10];
|
||||
u32 sizes;
|
||||
int size;
|
||||
int err;
|
||||
|
||||
if (!IS_DGFX(xe))
|
||||
return 0;
|
||||
|
||||
sizes = pci_iov_vf_bar_get_sizes(pdev, VF_LMEM_BAR, num_vfs);
|
||||
if (!sizes)
|
||||
return 0;
|
||||
|
||||
return pci_iov_vf_bar_set_size(pdev, VF_LMEM_BAR, __fls(sizes));
|
||||
size = __fls(sizes);
|
||||
string_get_size(pci_rebar_size_to_bytes(size), 1, STRING_UNITS_2, buf, sizeof(buf));
|
||||
|
||||
err = pci_iov_vf_bar_set_size(pdev, VF_LMEM_BAR, size);
|
||||
if (err) {
|
||||
xe_sriov_notice(xe, "Failed to resize VF BAR %u to %s (%pe)\n",
|
||||
VF_LMEM_BAR, buf, ERR_PTR(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
xe_sriov_dbg(xe, "VF LMEM BAR resized to %s\n", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pf_prepare_vfs_enabling(struct xe_device *xe)
|
||||
@@ -142,11 +159,7 @@ static int pf_enable_vfs(struct xe_device *xe, int num_vfs)
|
||||
if (err < 0)
|
||||
goto failed;
|
||||
|
||||
if (IS_DGFX(xe)) {
|
||||
err = resize_vf_vram_bar(xe, num_vfs);
|
||||
if (err)
|
||||
xe_sriov_info(xe, "Failed to set VF LMEM BAR size: %d\n", err);
|
||||
}
|
||||
pf_resize_vf_vram_bar(xe, num_vfs);
|
||||
|
||||
err = pci_enable_sriov(pdev, num_vfs);
|
||||
if (err < 0)
|
||||
@@ -164,6 +177,7 @@ static int pf_enable_vfs(struct xe_device *xe, int num_vfs)
|
||||
return num_vfs;
|
||||
|
||||
failed:
|
||||
pf_resize_vf_vram_bar(xe, xe->sriov.pf.device_total_vfs);
|
||||
xe_sriov_pf_unprovision_vfs(xe, num_vfs);
|
||||
xe_pm_runtime_put(xe);
|
||||
pf_finish_vfs_enabling(xe);
|
||||
@@ -191,6 +205,8 @@ static int pf_disable_vfs(struct xe_device *xe)
|
||||
|
||||
pci_disable_sriov(pdev);
|
||||
|
||||
pf_resize_vf_vram_bar(xe, xe->sriov.pf.device_total_vfs);
|
||||
|
||||
xe_sriov_pf_reprovision_default(xe);
|
||||
|
||||
pf_reset_vfs(xe, num_vfs);
|
||||
|
||||
Reference in new issue
Block a user