summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
commit8f9aa2c90530ab92301a82231ae44f3722becd93 (patch)
treefb282e955b0a880b07131a135257fe3ec764e928 /drivers/gpu/drm/amd
parent93467b31bec6da512b51544e5e4584f2745e995e (diff)
parent155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_v12_1.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c20
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c5
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c6
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.c1
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c10
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c81
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h58
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h24
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c201
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h23
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c78
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c389
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c499
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h35
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h79
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c177
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c388
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h49
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c2
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_pm.c26
35 files changed, 1533 insertions, 736 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 72a5a29e63f6..abc319488969 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1914,13 +1914,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
mutex_lock(&mem->lock);
- /* Unpin MMIO/DOORBELL BO's that were pinned during allocation */
- if (mem->alloc_flags &
- (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
- KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
- amdgpu_amdkfd_gpuvm_unpin_bo(mem->bo);
- }
-
mapped_to_gpu_memory = mem->mapped_to_gpu_memory;
is_imported = mem->is_imported;
mutex_unlock(&mem->lock);
@@ -1934,6 +1927,15 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
return -EBUSY;
}
+ /* At this point the BO is guaranteed to be freed, so unpin the
+ * MMIO/DOORBELL BOs that were pinned during allocation.
+ */
+ if (mem->alloc_flags &
+ (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
+ KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
+ amdgpu_amdkfd_gpuvm_unpin_bo(mem->bo);
+ }
+
/* Make sure restore workers don't access the BO any more */
mutex_lock(&process_info->lock);
if (!list_empty(&mem->validate_list))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
index d386bc775d03..f89f3a37a45b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
@@ -229,6 +229,7 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
sizing_pass = buffer == NULL;
iter.data = buffer;
+ iter.start = 0;
iter.offset = 0;
iter.remain = count;
@@ -553,7 +554,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
coredump->rings_dw = kzalloc(total_ring_size, GFP_NOWAIT);
coredump->rings = kcalloc(ring_count, sizeof(struct amdgpu_coredump_ring), GFP_NOWAIT);
if (coredump->rings && coredump->rings_dw) {
- for (i = 0, off = 0, idx = 0; i < adev->num_rings; i++) {
+ for (i = 0, off = 0, idx = 0; i < adev->num_rings && idx < ring_count; i++) {
ring = adev->rings[i];
if (atomic_read(&ring->fence_drv.last_seq) == ring->fence_drv.sync_seq &&
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index feab90e3efd1..4f8489626624 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3747,6 +3747,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
mutex_init(&adev->gfx.workload_profile_mutex);
mutex_init(&adev->vcn.workload_profile_mutex);
+ spin_lock_init(&adev->irq.lock);
+
amdgpu_device_init_apu_flags(adev);
r = amdgpu_device_check_arguments(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index fe6d988e7f24..1120f8225ac0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -27,6 +27,7 @@
*/
#include <linux/ktime.h>
#include <linux/module.h>
+#include <linux/overflow.h>
#include <linux/pagemap.h>
#include <linux/pci.h>
#include <linux/dma-buf.h>
@@ -1228,13 +1229,14 @@ int amdgpu_gem_list_handles_ioctl(struct drm_device *dev, void *data,
return ret;
}
-static int amdgpu_gem_align_pitch(struct amdgpu_device *adev,
- int width,
- int cpp,
- bool tiled)
+static unsigned int amdgpu_gem_align_pitch(struct amdgpu_device *adev,
+ unsigned int width,
+ unsigned int cpp,
+ bool tiled)
{
- int aligned = width;
- int pitch_mask = 0;
+ unsigned int aligned = width;
+ unsigned int pitch_mask = 0;
+ unsigned int pitch;
switch (cpp) {
case 1:
@@ -1249,9 +1251,12 @@ static int amdgpu_gem_align_pitch(struct amdgpu_device *adev,
break;
}
- aligned += pitch_mask;
+ if (check_add_overflow(aligned, pitch_mask, &aligned))
+ return 0;
aligned &= ~pitch_mask;
- return aligned * cpp;
+ if (check_mul_overflow(aligned, cpp, &pitch))
+ return 0;
+ return pitch;
}
int amdgpu_mode_dumb_create(struct drm_file *file_priv,
@@ -1278,8 +1283,12 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
args->pitch = amdgpu_gem_align_pitch(adev, args->width,
DIV_ROUND_UP(args->bpp, 8), 0);
+ if (!args->pitch)
+ return -EINVAL;
args->size = (u64)args->pitch * args->height;
args->size = ALIGN(args->size, PAGE_SIZE);
+ if (!args->size)
+ return -EINVAL;
domain = amdgpu_bo_get_preferred_domain(adev,
amdgpu_display_supported_domains(adev, flags));
r = amdgpu_gem_object_create(adev, args->size, 0, domain, flags,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 254a4e983f40..40b8506ac66f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -309,8 +309,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
unsigned int irq, flags;
int r;
- spin_lock_init(&adev->irq.lock);
-
/* Enable MSI if not disabled by module parameter */
adev->irq.msi_enabled = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c
index 823ba17e32af..cc6d1a4e4c3a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c
@@ -99,6 +99,7 @@ int amdgpu_mca_mp0_ras_sw_init(struct amdgpu_device *adev)
strcpy(ras->ras_block.ras_comm.name, "mca.mp0");
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA;
+ ras->ras_block.ras_comm.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP0;
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
adev->mca.mp0.ras_if = &ras->ras_block.ras_comm;
@@ -123,6 +124,7 @@ int amdgpu_mca_mp1_ras_sw_init(struct amdgpu_device *adev)
strcpy(ras->ras_block.ras_comm.name, "mca.mp1");
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA;
+ ras->ras_block.ras_comm.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP1;
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
adev->mca.mp1.ras_if = &ras->ras_block.ras_comm;
@@ -147,6 +149,7 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev)
strcpy(ras->ras_block.ras_comm.name, "mca.mpio");
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA;
+ ras->ras_block.ras_comm.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MPIO;
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
adev->mca.mpio.ras_if = &ras->ras_block.ras_comm;
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
index cec801278126..be86802fef33 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
@@ -2016,7 +2016,7 @@ static int mes_v12_1_map_test_bo(struct amdgpu_device *adev,
error:
amdgpu_sync_free(&sync);
- return 0;
+ return r;
}
static int mes_v12_1_test_ring(struct amdgpu_device *adev, int xcc_id,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 8785f7810157..78068b2c9685 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -2362,6 +2362,9 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
const bool criu_resume = true;
u64 offset;
+ if (bo_priv->idr_handle > INT_MAX)
+ return -EINVAL;
+
if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) {
if (bo_bucket->size !=
kfd_doorbell_process_slice(pdd->dev->kfd))
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 31187ddbb79e..ee413117b0ff 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -3095,32 +3095,24 @@ int kfd_dqm_suspend_bad_queue_mes(struct kfd_node *knode, u32 pasid, u32 doorbel
list_for_each_entry(q, &qpd->queues_list, list) {
if (q->doorbell_id == doorbell_id && q->properties.is_active) {
- ret = suspend_all_queues_mes(dqm);
- if (ret) {
- dev_err(dev, "Suspending all queues failed");
- goto out;
- }
+ /* suspend all queues will save any good queues and mark the rest as bad */
+ suspend_all_queues_mes(dqm);
q->properties.is_evicted = true;
q->properties.is_active = false;
decrement_queue_count(dqm, qpd, q);
+ /* this will remove the bad queue and sched a GPU reset if needed */
ret = remove_queue_mes(dqm, q, qpd);
- if (ret) {
- dev_err(dev, "Removing bad queue failed");
- goto out;
- }
-
- ret = resume_all_queues_mes(dqm);
if (ret)
- dev_err(dev, "Resuming all queues failed");
-
+ dev_err(dev, "Removing bad queue failed");
+ /* resume the good queues */
+ resume_all_queues_mes(dqm);
break;
}
}
}
-out:
dqm_unlock(dqm);
kfd_unref_process(p);
return ret;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index e65b323aafbf..81900b49d9d5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -483,6 +483,11 @@ int kfd_criu_restore_event(struct file *devkfd,
}
*priv_data_offset += sizeof(*ev_priv);
+ if (ev_priv->event_id > INT_MAX) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
if (ev_priv->user_handle) {
ret = kfd_kmap_event_page(p, ev_priv->user_handle);
if (ret)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
index c90c0d99b1e3..475589b924e9 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
@@ -32,6 +32,10 @@
#include "amdgpu_amdkfd.h"
#include "kfd_device_queue_manager.h"
+static void update_mqd(struct mqd_manager *mm, void *mqd,
+ struct queue_properties *q,
+ struct mqd_update_info *minfo);
+
static inline struct v12_1_compute_mqd *get_mqd(void *mqd)
{
return (struct v12_1_compute_mqd *)mqd;
@@ -215,7 +219,7 @@ static void init_mqd(struct mqd_manager *mm, void **mqd,
*mqd = m;
if (gart_addr)
*gart_addr = addr;
- mm->update_mqd(mm, m, q, NULL);
+ update_mqd(mm, m, q, NULL);
}
static int load_mqd(struct mqd_manager *mm, void *mqd,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index d28ca581cad0..888fbaf069be 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -910,7 +910,7 @@ static void kfd_process_free_id(struct kfd_process *process)
{
struct kfd_process *primary_process;
- if (process->context_id != KFD_CONTEXT_ID_PRIMARY)
+ if (process->context_id == KFD_CONTEXT_ID_PRIMARY)
return;
primary_process = kfd_lookup_process_by_mm(process->lead_thread->mm);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 3841943da5ec..0b54ad8036b6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -4115,6 +4115,7 @@ exit:
list_for_each_entry_safe(criu_svm_md, next, &svms->criu_svm_metadata_list, list) {
pr_debug("freeing criu_svm_md[]\n\tstart: 0x%llx\n",
criu_svm_md->data.start_addr);
+ list_del(&criu_svm_md->list);
kfree(criu_svm_md);
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f8c13bad4ac2..1ecd7bef9ed8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -12553,13 +12553,11 @@ static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev,
struct drm_plane_state *new_plane_state, *old_plane_state;
drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
- new_plane_state = drm_atomic_get_plane_state(state, plane);
- old_plane_state = drm_atomic_get_plane_state(state, plane);
+ new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+ old_plane_state = drm_atomic_get_old_plane_state(state, plane);
- if (IS_ERR(new_plane_state) || IS_ERR(old_plane_state)) {
- drm_err(dev, "Failed to get plane state for plane %s\n", plane->name);
- return false;
- }
+ if (!old_plane_state || !new_plane_state)
+ continue;
if (old_plane_state->fb && new_plane_state->fb &&
get_mem_type(old_plane_state->fb) != get_mem_type(new_plane_state->fb))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index a3cb05490dc9..ee214f7592e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -95,8 +95,11 @@ static u32 edid_extract_panel_id(struct edid *edid)
(u32)EDID_PRODUCT_ID(edid);
}
-static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct dc_edid_caps *edid_caps)
+static void apply_edid_quirks(struct dc_link *link, struct edid *edid,
+ struct dc_edid_caps *edid_caps)
{
+ struct amdgpu_dm_connector *aconnector = link->priv;
+ struct drm_device *dev = aconnector->base.dev;
uint32_t panel_id = edid_extract_panel_id(edid);
switch (panel_id) {
@@ -126,6 +129,11 @@ static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct
drm_dbg_driver(dev, "Disabling VSC on monitor with panel id %X\n", panel_id);
edid_caps->panel_patch.disable_colorimetry = true;
break;
+ /* Workaround for monitors that get corrupted by the PHY SSC reduction */
+ case drm_edid_encode_panel_id('D', 'E', 'L', 0x4147):
+ drm_dbg_driver(dev, "Skip PHY SSC reduction on panel id %X\n", panel_id);
+ link->wa_flags.skip_phy_ssc_reduction = true;
+ break;
default:
return;
}
@@ -147,7 +155,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
{
struct amdgpu_dm_connector *aconnector = link->priv;
struct drm_connector *connector = &aconnector->base;
- struct drm_device *dev = connector->dev;
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
struct cea_sad *sads;
int sad_count = -1;
@@ -181,7 +188,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
if (edid_caps->edid_hdmi)
populate_hdmi_info_from_connector(&connector->display_info.hdmi, edid_caps);
- apply_edid_quirks(dev, edid_buf, edid_caps);
+ apply_edid_quirks(link, edid_buf, edid_caps);
sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
if (sad_count <= 0)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index b3530fbf32f7..5f2c62fcba9b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2956,27 +2956,16 @@ static struct surface_update_descriptor det_surface_update(
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
- if (u->cm || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
+ if (u->blend_tf || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
update_flags->bits.gamma_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
- if (u->cm && (u->cm->flags.bits.lut3d_enable || u->surface->cm.flags.bits.lut3d_enable)) {
+ if (u->lut3d_func || u->func_shaper) {
update_flags->bits.lut_3d = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
- if (u->cm && u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable &&
- u->cm->flags.bits.lut3d_enable && u->surface->cm.flags.bits.lut3d_enable) {
- /* Toggling 3DLUT loading between DMA and Host is illegal */
- BREAK_TO_DEBUGGER();
- }
-
- if (u->cm && u->cm->flags.bits.lut3d_enable && !u->cm->flags.bits.lut3d_dma_enable) {
- /* Host loading 3DLUT requires full update but only stream lock */
- elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_STREAM);
- }
-
if (u->hdr_mult.value)
if (u->hdr_mult.value != u->surface->hdr_mult.value) {
// TODO: Should be fast?
@@ -2995,6 +2984,20 @@ static struct surface_update_descriptor det_surface_update(
update_flags->bits.cm_hist_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
+ if (u->cm2_params) {
+ if (u->cm2_params->component_settings.shaper_3dlut_setting != u->surface->mcm_shaper_3dlut_setting
+ || u->cm2_params->component_settings.lut1d_enable != u->surface->mcm_lut1d_enable
+ || u->cm2_params->cm2_luts.lut3d_data.lut3d_src != u->surface->mcm_luts.lut3d_data.lut3d_src) {
+ update_flags->bits.mcm_transfer_function_enable_change = 1;
+ elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
+ }
+ }
+
+ if (update_flags->bits.lut_3d &&
+ u->surface->mcm_luts.lut3d_data.lut3d_src != DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
+ elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
+ }
+
if (check_config->enable_legacy_fast_update &&
(update_flags->bits.gamma_change ||
update_flags->bits.gamut_remap_change ||
@@ -3250,12 +3253,24 @@ static void copy_surface_update_to_plane(
sizeof(struct dc_transfer_func_distributed_points));
}
- /* Shaper, 3DLUT, 1DLUT */
- if (srf_update->cm) {
- memcpy(&surface->cm, srf_update->cm,
- sizeof(surface->cm));
+ if (srf_update->cm2_params) {
+ surface->mcm_shaper_3dlut_setting = srf_update->cm2_params->component_settings.shaper_3dlut_setting;
+ surface->mcm_lut1d_enable = srf_update->cm2_params->component_settings.lut1d_enable;
+ surface->mcm_luts = srf_update->cm2_params->cm2_luts;
}
+ if (srf_update->func_shaper) {
+ memcpy(&surface->in_shaper_func, srf_update->func_shaper,
+ sizeof(surface->in_shaper_func));
+
+ if (surface->mcm_shaper_3dlut_setting >= DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER)
+ surface->mcm_luts.shaper = &surface->in_shaper_func;
+ }
+
+ if (srf_update->lut3d_func)
+ memcpy(&surface->lut3d_func, srf_update->lut3d_func,
+ sizeof(surface->lut3d_func));
+
if (srf_update->hdr_mult.value)
surface->hdr_mult =
srf_update->hdr_mult;
@@ -3264,6 +3279,17 @@ static void copy_surface_update_to_plane(
surface->sdr_white_level_nits =
srf_update->sdr_white_level_nits;
+ if (srf_update->blend_tf) {
+ memcpy(&surface->blend_tf, srf_update->blend_tf,
+ sizeof(surface->blend_tf));
+
+ if (surface->mcm_lut1d_enable)
+ surface->mcm_luts.lut1d_func = &surface->blend_tf;
+ }
+
+ if (srf_update->cm2_params || srf_update->blend_tf)
+ surface->lut_bank_a = !surface->lut_bank_a;
+
if (srf_update->input_csc_color_matrix)
surface->input_csc_color_matrix =
*srf_update->input_csc_color_matrix;
@@ -4550,9 +4576,11 @@ static void commit_planes_for_stream(struct dc *dc,
if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
continue;
- if (srf_updates[i].cm &&
- srf_updates[i].cm->flags.bits.lut3d_enable &&
- srf_updates[i].cm->flags.bits.lut3d_dma_enable &&
+ if (srf_updates[i].cm2_params &&
+ srf_updates[i].cm2_params->cm2_luts.lut3d_data.lut3d_src ==
+ DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM &&
+ srf_updates[i].cm2_params->component_settings.shaper_3dlut_setting ==
+ DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT &&
dc->hwss.trigger_3dlut_dma_load)
dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx);
@@ -5209,12 +5237,6 @@ static bool full_update_required(
const struct dc_stream_update *stream_update,
const struct dc_stream_state *stream)
{
- const union dc_plane_cm_flags blend_only_flags = {
- .bits = {
- .blend_enable = 1,
- }
- };
-
if (full_update_required_weak(dc, srf_updates, surface_count, stream_update, stream))
return true;
@@ -5229,10 +5251,7 @@ static bool full_update_required(
srf_updates[i].in_transfer_func ||
srf_updates[i].surface->force_full_update ||
(srf_updates[i].flip_addr &&
- srf_updates[i].flip_addr->address.tmz_surface != srf_updates[i].surface->address.tmz_surface) ||
- (srf_updates[i].cm &&
- ((srf_updates[i].cm->flags.all != blend_only_flags.all && srf_updates[i].cm->flags.all != 0) ||
- (srf_updates[i].surface->cm.flags.all != blend_only_flags.all && srf_updates[i].surface->cm.flags.all != 0)))))
+ srf_updates[i].flip_addr->address.tmz_surface != srf_updates[i].surface->address.tmz_surface)))
return true;
}
@@ -6966,7 +6985,7 @@ bool dc_capture_register_software_state(struct dc *dc, struct dc_register_softwa
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
/* MPCC blending tree and mode control - capture actual blend configuration */
- state->mpc.mpcc_mode[i] = (plane_state->cm.blend_func.type != TF_TYPE_BYPASS) ? 1 : 0;
+ state->mpc.mpcc_mode[i] = (plane_state->blend_tf.type != TF_TYPE_BYPASS) ? 1 : 0;
state->mpc.mpcc_alpha_blend_mode[i] = plane_state->per_pixel_alpha ? 1 : 0;
state->mpc.mpcc_alpha_multiplied_mode[i] = plane_state->pre_multiplied_alpha ? 1 : 0;
state->mpc.mpcc_blnd_active_overlap_only[i] = 0; /* Default - no overlap restriction */
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index e16de323f39c..717451828361 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -996,6 +996,7 @@ void dc_stream_release_3dlut_for_stream(
if (rmcm_3dlut) {
rmcm_3dlut->isInUse = false;
rmcm_3dlut->stream = NULL;
+ rmcm_3dlut->protection_bits = 0;
}
}
@@ -1007,6 +1008,7 @@ void dc_stream_init_rmcm_3dlut(struct dc *dc)
for (int i = 0; i < num_rmcm; i++) {
dc->res_pool->rmcm_3dlut[i].isInUse = false;
dc->res_pool->rmcm_3dlut[i].stream = NULL;
+ dc->res_pool->rmcm_3dlut[i].protection_bits = 0;
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 37714d4371fb..55152f12af48 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1407,50 +1407,15 @@ struct lut_mem_mapping {
struct dc_rmcm_3dlut {
bool isInUse;
const struct dc_stream_state *stream;
+ uint8_t protection_bits;
};
struct dc_3dlut {
struct kref refcount;
struct tetrahedral_params lut_3d;
+ struct fixed31_32 hdr_multiplier;
union dc_3dlut_state state;
};
-
-/* 3DLUT DMA (Fast Load) params */
-struct dc_3dlut_dma {
- struct dc_plane_address addr;
- enum dc_cm_lut_swizzle swizzle;
- enum dc_cm_lut_pixel_format format;
- uint16_t bias; /* FP1.5.10 */
- uint16_t scale; /* FP1.5.10 */
- enum dc_cm_lut_size size;
-};
-
-/* color manager */
-union dc_plane_cm_flags {
- unsigned int all;
- struct {
- unsigned int shaper_enable : 1;
- unsigned int lut3d_enable : 1;
- unsigned int blend_enable : 1;
- /* whether legacy (lut3d_func) or DMA is valid */
- unsigned int lut3d_dma_enable : 1;
- /* RMCM lut to be used instead of MCM */
- unsigned int rmcm_enable : 1;
- unsigned int reserved: 27;
- } bits;
-};
-
-struct dc_plane_cm {
- struct kref refcount;
- struct dc_transfer_func shaper_func;
- union {
- struct dc_3dlut lut3d_func;
- struct dc_3dlut_dma lut3d_dma;
- };
- struct dc_transfer_func blend_func;
- union dc_plane_cm_flags flags;
-};
-
/*
* This structure is filled in by dc_surface_get_status and contains
* the last requested address and the currently active address so the called
@@ -1528,18 +1493,14 @@ struct dc_plane_state {
struct fixed31_32 hdr_mult;
struct colorspace_transform gamut_remap_matrix;
+ // TODO: No longer used, remove
+ struct dc_hdr_static_metadata hdr_static_ctx;
+
enum dc_color_space color_space;
- bool lut_bank_a;
- struct dc_hdr_static_metadata hdr_static_ctx;
struct dc_3dlut lut3d_func;
struct dc_transfer_func in_shaper_func;
struct dc_transfer_func blend_tf;
- enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
- bool mcm_lut1d_enable;
- struct dc_cm2_func_luts mcm_luts;
- enum mpcc_movable_cm_location mcm_location;
- struct dc_plane_cm cm;
struct dc_transfer_func *gamcor_tf;
enum surface_pixel_format format;
@@ -1576,6 +1537,11 @@ struct dc_plane_state {
bool is_statically_allocated;
enum chroma_cositing cositing;
+ enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
+ bool mcm_lut1d_enable;
+ struct dc_cm2_func_luts mcm_luts;
+ bool lut_bank_a;
+ enum mpcc_movable_cm_location mcm_location;
struct dc_csc_transform cursor_csc_color_matrix;
bool adaptive_sharpness_en;
int adaptive_sharpness_policy;
@@ -1968,10 +1934,6 @@ struct dc_3dlut *dc_create_3dlut_func(void);
void dc_3dlut_func_release(struct dc_3dlut *lut);
void dc_3dlut_func_retain(struct dc_3dlut *lut);
-struct dc_plane_cm *dc_plane_cm_create(void);
-void dc_plane_cm_release(struct dc_plane_cm *cm);
-void dc_plane_cm_retain(struct dc_plane_cm *cm);
-
void dc_post_update_surfaces_to_stream(
struct dc *dc);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index c08d5c005df6..62e35dcb585c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -1493,28 +1493,4 @@ struct dc_validation_dpia_set {
uint32_t required_bw;
};
-enum dc_cm_lut_swizzle {
- CM_LUT_3D_SWIZZLE_LINEAR_RGB,
- CM_LUT_3D_SWIZZLE_LINEAR_BGR,
- CM_LUT_1D_PACKED_LINEAR
-};
-
-enum dc_cm_lut_pixel_format {
- CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB,
- CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB,
- CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB,
- CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB,
- CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10,
- CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10
-};
-
-enum dc_cm_lut_size {
- CM_LUT_SIZE_NONE,
- CM_LUT_SIZE_999,
- CM_LUT_SIZE_171717,
- CM_LUT_SIZE_333333,
- CM_LUT_SIZE_454545,
- CM_LUT_SIZE_656565,
-};
-
#endif /* DC_TYPES_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index 5a816442deee..3c7a6569b692 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -41,12 +41,12 @@
hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
void hubp401_program_3dlut_fl_addr(struct hubp *hubp,
- const struct dc_plane_address *address)
+ const struct dc_plane_address address)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address->lut3d.addr.high_part);
- REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address->lut3d.addr.low_part);
+ REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address.lut3d.addr.high_part);
+ REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address.lut3d.addr.low_part);
}
void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group)
@@ -72,169 +72,96 @@ int hubp401_get_3dlut_fl_done(struct hubp *hubp)
return ret;
}
-static void hubp401_get_3dlut_fl_xbar_map(
- const enum dc_cm_lut_pixel_format format,
- enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
- enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
- enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
+void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode)
{
- switch (format) {
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
- /* BGRA */
- *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
- *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
- default:
- /* RGBA */
- *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
- *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
- break;
- }
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+ REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode);
}
-void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
- const enum dc_cm_lut_pixel_format format)
+void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g = 0;
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b = 0;
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r = 0;
+ REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, width);
+}
- hubp401_get_3dlut_fl_xbar_map(format,
- &bit_slice_y_g,
- &bit_slice_cb_b,
- &bit_slice_cr_r);
+void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits)
+{
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- REG_UPDATE_3(HUBP_3DLUT_CONTROL,
- HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
- HUBP_3DLUT_CROSSBAR_SELECT_CB_B, bit_slice_cb_b,
- HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
+ REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits);
}
-static enum hubp_3dlut_fl_width hubp401_get_3dlut_fl_width(
- const enum dc_cm_lut_size size,
- const enum dc_cm_lut_swizzle swizzle)
+void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r)
{
- enum hubp_3dlut_fl_width width = 0;
-
- switch (size) {
- case CM_LUT_SIZE_333333:
- ASSERT(swizzle != CM_LUT_1D_PACKED_LINEAR);
- width = hubp_3dlut_fl_width_33;
- break;
- case CM_LUT_SIZE_171717:
- if (swizzle != CM_LUT_1D_PACKED_LINEAR) {
- width = hubp_3dlut_fl_width_17;
- } else {
- width = hubp_3dlut_fl_width_17_transformed;
- }
- break;
- default:
- width = 0;
- break;
- }
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- return width;
+ REG_UPDATE_3(HUBP_3DLUT_CONTROL,
+ HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
+ HUBP_3DLUT_CROSSBAR_SELECT_CB_B, bit_slice_cb_b,
+ HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
}
-static enum hubp_3dlut_fl_format hubp401_get_3dlut_fl_format(
- const enum dc_cm_lut_pixel_format dc_format)
+void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale)
{
- enum hubp_3dlut_fl_format hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
-
- switch (dc_format) {
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
- hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
- hubp_format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
- hubp_format = hubp_3dlut_fl_format_float_fp1_5_10;
- break;
- default:
- BREAK_TO_DEBUGGER();
- break;
- }
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- return hubp_format;
+ REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, HUBP0_3DLUT_FL_SCALE, scale);
}
-static enum hubp_3dlut_fl_addressing_mode hubp401_get_3dlut_fl_addr_mode(
- const enum dc_cm_lut_swizzle swizzle)
+void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode)
{
- enum hubp_3dlut_fl_addressing_mode addr_mode;
-
- switch (swizzle) {
- case CM_LUT_1D_PACKED_LINEAR:
- addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
- break;
- case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
- case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
- default:
- addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- }
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- return addr_mode;
+ REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode);
}
-static enum hubp_3dlut_fl_mode hubp401_get_3dlut_fl_mode(
- const enum dc_cm_lut_swizzle swizzle)
+void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format)
{
- enum hubp_3dlut_fl_mode mode;
-
- switch (swizzle) {
- case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
- mode = hubp_3dlut_fl_mode_native_1;
- break;
- case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
- mode = hubp_3dlut_fl_mode_native_2;
- break;
- case CM_LUT_1D_PACKED_LINEAR:
- mode = hubp_3dlut_fl_mode_transform;
- break;
- default:
- mode = hubp_3dlut_fl_mode_disable;
- break;
- }
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- return mode;
+ REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format);
}
-void hubp401_program_3dlut_fl_config(struct hubp *hubp,
- const struct dc_3dlut_dma *config)
+void hubp401_program_3dlut_fl_config(
+ struct hubp *hubp,
+ struct hubp_fl_3dlut_config *cfg)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- enum hubp_3dlut_fl_width width = hubp401_get_3dlut_fl_width(config->size, config->swizzle);
- enum hubp_3dlut_fl_format format = hubp401_get_3dlut_fl_format(config->format);
- enum hubp_3dlut_fl_addressing_mode addr_mode = hubp401_get_3dlut_fl_addr_mode(config->swizzle);
- enum hubp_3dlut_fl_mode mode = hubp401_get_3dlut_fl_mode(config->swizzle);
+ uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1};
+ uint32_t width = {cfg->width};
+
+ if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR)
+ width = (cfg->width == 17) ? 4916 : 35940;
REG_UPDATE_2(_3DLUT_FL_CONFIG,
- HUBP0_3DLUT_FL_MODE, mode,
- HUBP0_3DLUT_FL_FORMAT, format);
+ HUBP0_3DLUT_FL_MODE, cfg->mode,
+ HUBP0_3DLUT_FL_FORMAT, cfg->format);
REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE,
- HUBP0_3DLUT_FL_BIAS, config->bias,
- HUBP0_3DLUT_FL_SCALE, config->scale);
-
- REG_UPDATE_3(HUBP_3DLUT_CONTROL,
- HUBP_3DLUT_WIDTH, width,
- HUBP_3DLUT_ADDRESSING_MODE, addr_mode,
- HUBP_3DLUT_TMZ, config->addr.tmz_surface);
+ HUBP0_3DLUT_FL_BIAS, cfg->bias,
+ HUBP0_3DLUT_FL_SCALE, cfg->scale);
+
+ REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH,
+ HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part);
+ REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW,
+ HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part);
+
+ //cross bar
+ REG_UPDATE_8(HUBP_3DLUT_CONTROL,
+ HUBP_3DLUT_MPC_WIDTH, mpc_width,
+ HUBP_3DLUT_WIDTH, width,
+ HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r,
+ HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g,
+ HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b,
+ HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode,
+ HUBP_3DLUT_TMZ, cfg->protection_bits,
+ HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0);
}
void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor)
@@ -1135,13 +1062,19 @@ static struct hubp_funcs dcn401_hubp_funcs = {
.hubp_update_mall_sel = hubp401_update_mall_sel,
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
.hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate,
+ .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
+ .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
+ .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
- .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
+ .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
+ .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
+ .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
.hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp401_clear_tiling,
+ .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
.hubp_read_reg_state = hubp3_read_reg_state
};
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
index 043948f64b86..4570b8016de5 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
@@ -328,17 +328,32 @@ int hubp401_get_3dlut_fl_done(struct hubp *hubp);
void hubp401_set_unbounded_requesting(struct hubp *hubp, bool enable);
+void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale);
+
void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
- const enum dc_cm_lut_pixel_format format);
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
+
+void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits);
+
+void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width);
+
+void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode);
void hubp401_enable_3dlut_fl(struct hubp *hubp, bool enable);
void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group);
-void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address *address);
+void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address address);
-void hubp401_program_3dlut_fl_config(struct hubp *hubp,
- const struct dc_3dlut_dma *config);
+void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format);
+
+void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode);
+
+void hubp401_program_3dlut_fl_config(
+ struct hubp *hubp,
+ struct hubp_fl_3dlut_config *cfg);
void hubp401_clear_tiling(struct hubp *hubp);
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
index ad6badcceb12..e4602c3ddc66 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
@@ -311,84 +311,19 @@ static void hubp42_program_surface_config(
hubp42_program_pixel_format(hubp, format);
}
-static void hubp42_get_3dlut_fl_xbar_map(
- const enum dc_cm_lut_pixel_format format,
- enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
- enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
- enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
-{
- switch (format) {
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
- case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
- /* BGRA */
- *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
- *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
- default:
- /* RGBA */
- *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
- *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
- break;
- }
-}
-
void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
- const enum dc_cm_lut_pixel_format format)
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g = 0;
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b = 0;
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r = 0;
-
- hubp42_get_3dlut_fl_xbar_map(format,
- &bit_slice_g,
- &bit_slice_b,
- &bit_slice_r);
-
REG_UPDATE_3(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_CROSSBAR_SEL_R, bit_slice_r,
HUBP_3DLUT_CROSSBAR_SEL_G, bit_slice_g,
HUBP_3DLUT_CROSSBAR_SEL_B, bit_slice_b);
}
-static uint32_t hubp42_get_3dlut_fl_mpc_width(
- const enum dc_cm_lut_size size)
-{
- uint32_t width = 0;
-
- switch (size) {
- case CM_LUT_SIZE_333333:
- width = 1;
- break;
- case CM_LUT_SIZE_171717:
- default:
- width = 0;
- break;
- }
-
- return width;
-}
-
-void hubp42_program_3dlut_fl_config(struct hubp *hubp,
- const struct dc_3dlut_dma *config)
-{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
-
- uint32_t mpc_width = hubp42_get_3dlut_fl_mpc_width(config->size);
-
- REG_UPDATE(HUBP_3DLUT_CONTROL,
- HUBP_3DLUT_MPC_WIDTH, mpc_width);
-
- hubp401_program_3dlut_fl_config(hubp, config);
-}
-
static bool hubp42_program_surface_flip_and_addr(
struct hubp *hubp,
const struct dc_plane_address *address,
@@ -670,10 +605,15 @@ struct hubp_funcs dcn42_hubp_funcs = {
.hubp_set_flip_int = hubp1_set_flip_int,
.hubp_in_blank = hubp1_in_blank,
.program_extended_blank = hubp31_program_extended_blank_value,
+ .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
+ .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
+ .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
- .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
+ .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
+ .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
+ .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
.hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp3_clear_tiling,
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
index 88bb1337ab9d..f0e614136228 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
@@ -58,11 +58,11 @@ bool hubp42_construct(
const struct dcn_hubp2_shift *hubp_shift,
const struct dcn_hubp2_mask *hubp_mask);
-void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
- const enum dc_cm_lut_pixel_format format);
-
-void hubp42_program_3dlut_fl_config(struct hubp *hubp,
- const struct dc_3dlut_dma *config);
+void hubp42_program_3dlut_fl_crossbar(
+ struct hubp *hubp,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b);
void hubp42_read_state(struct hubp *hubp);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 9768b8f6b6fb..98e78aa2259c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -95,6 +95,10 @@ void dcn401_program_gamut_remap(struct pipe_ctx *pipe_ctx)
unsigned int mpcc_id = pipe_ctx->plane_res.mpcc_inst;
struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+ //For now assert if location is not pre-blend
+ if (pipe_ctx->plane_state)
+ ASSERT(pipe_ctx->plane_state->mcm_location == MPCC_MOVABLE_CM_LOCATION_BEFORE);
+
// program MPCC_MCM_FIRST_GAMUT_REMAP
memset(&mpc_adjust, 0, sizeof(mpc_adjust));
mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@@ -374,180 +378,300 @@ void dcn401_init_hw(struct dc *dc)
}
}
-void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
+static void dcn401_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct pipe_ctx *pipe_ctx,
+ enum MCM_LUT_XABLE *shaper_xable,
+ enum MCM_LUT_XABLE *lut3d_xable,
+ enum MCM_LUT_XABLE *lut1d_xable)
{
- (void)dc;
- struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
+ bool lut1d_enable = false;
+ struct mpc *mpc = dc->res_pool->mpc;
+ int mpcc_id = pipe_ctx->plane_res.hubp->inst;
- if (hubp->funcs->hubp_enable_3dlut_fl) {
- hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+ if (!pipe_ctx->plane_state)
+ return;
+ shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting;
+ lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable;
+ mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
+ pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
+
+ *lut1d_xable = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE;
+
+ switch (shaper_3dlut_setting) {
+ case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL:
+ *lut3d_xable = *shaper_xable = MCM_LUT_DISABLE;
+ break;
+ case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER:
+ *lut3d_xable = MCM_LUT_DISABLE;
+ *shaper_xable = MCM_LUT_ENABLE;
+ break;
+ case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT:
+ *lut3d_xable = *shaper_xable = MCM_LUT_ENABLE;
+ break;
}
}
-bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
- const struct dc_plane_state *plane_state)
+void dcn401_populate_mcm_luts(struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ struct dc_cm2_func_luts mcm_luts,
+ bool lut_bank_a)
{
- struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
- const struct dc_plane_cm *cm = &plane_state->cm;
int mpcc_id = hubp->inst;
struct mpc *mpc = dc->res_pool->mpc;
union mcm_lut_params m_lut_params;
- struct dc_3dlut_dma lut3d_dma;
- bool lut_enable;
- bool lut_bank_a;
+ enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src;
+ enum hubp_3dlut_fl_format format = 0;
+ enum hubp_3dlut_fl_mode mode;
+ enum hubp_3dlut_fl_width width = 0;
+ enum hubp_3dlut_fl_addressing_mode addr_mode;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0;
+ enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
+ enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
+ enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
bool rval;
- bool result = true;
- /* decide LUT bank based on current in use */
- mpc->funcs->get_lut_mode(mpc, MCM_LUT_1DLUT, mpcc_id, &lut_enable, &lut_bank_a);
- if (!lut_enable) {
- mpc->funcs->get_lut_mode(mpc, MCM_LUT_SHAPER, mpcc_id, &lut_enable, &lut_bank_a);
- }
- if (!lut_enable) {
- mpc->funcs->get_lut_mode(mpc, MCM_LUT_3DLUT, mpcc_id, &lut_enable, &lut_bank_a);
- }
-
- /* switch to the next bank */
- if (lut_enable) {
- lut_bank_a = !lut_bank_a;
- }
-
- /* MCM location fixed to pre-blend */
- mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
+ dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
/* 1D LUT */
- lut_enable = cm->flags.bits.blend_enable;
- memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (lut_enable) {
- if (cm->blend_func.type == TF_TYPE_HWPWL)
- m_lut_params.pwl = &cm->blend_func.pwl;
- else if (cm->blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
- &cm->blend_func,
- &dpp_base->regamma_params,
- false);
+ if (mcm_luts.lut1d_func) {
+ memset(&m_lut_params, 0, sizeof(m_lut_params));
+ if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
+ m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
+ else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+ rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+ mcm_luts.lut1d_func,
+ &dpp_base->regamma_params, false);
m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
-
- if (!m_lut_params.pwl) {
- lut_enable = false;
+ if (m_lut_params.pwl) {
+ if (mpc->funcs->populate_lut)
+ mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id);
}
- } else {
- lut_enable = false;
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
}
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut_enable, lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id);
- if (lut_enable && mpc->funcs->populate_lut)
- mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, &m_lut_params, lut_bank_a, mpcc_id);
-
/* Shaper */
- lut_enable = cm->flags.bits.shaper_enable;
- if (lut_enable) {
+ if (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_enable) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (cm->shaper_func.type == TF_TYPE_HWPWL)
- m_lut_params.pwl = &cm->shaper_func.pwl;
- else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ if (mcm_luts.shaper->type == TF_TYPE_HWPWL)
+ m_lut_params.pwl = &mcm_luts.shaper->pwl;
+ else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
ASSERT(false);
- rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
- &cm->shaper_func,
- &dpp_base->shaper_params,
- true);
- m_lut_params.pwl = rval ? &dpp_base->shaper_params : NULL;
+ rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+ mcm_luts.shaper,
+ &dpp_base->regamma_params, true);
+ m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
- if (!m_lut_params.pwl) {
- lut_enable = false;
+ if (m_lut_params.pwl) {
+ if (mpc->funcs->mcm.populate_lut)
+ mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id);
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
}
- } else {
- lut_enable = false;
}
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, lut_enable, lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id);
- if (lut_enable && mpc->funcs->populate_lut)
- mpc->funcs->populate_lut(mpc, MCM_LUT_SHAPER, &m_lut_params, lut_bank_a, mpcc_id);
+ /* 3DLUT */
+ switch (lut3d_src) {
+ case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
+ memset(&m_lut_params, 0, sizeof(m_lut_params));
+ if (hubp->funcs->hubp_enable_3dlut_fl)
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
- /* NOTE: Toggling from DMA->Host is not supported atomically as hardware
- * blocks writes until 3DLUT FL mode is cleared from HUBP on VUpdate.
- * Expectation is either option is used consistently.
- */
+ if (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) {
+ m_lut_params.lut3d = &mcm_luts.lut3d_data.lut3d_func->lut_3d;
+ if (mpc->funcs->populate_lut)
+ mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id);
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
+ mpcc_id);
+ }
+ break;
+ case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
+ switch (mcm_luts.lut3d_data.gpu_mem_params.size) {
+#if defined(CONFIG_DRM_AMD_DC_DCN4_2)
+ case DC_CM2_GPU_MEM_SIZE_333333:
+ if (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33)
+ width = hubp_3dlut_fl_width_33;
+ break;
+#endif
+ case DC_CM2_GPU_MEM_SIZE_171717:
+ width = hubp_3dlut_fl_width_17;
+ break;
+ case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
+ width = hubp_3dlut_fl_width_transformed;
+ break;
+ default:
+ //TODO: handle default case
+ break;
+ }
- /* 3DLUT */
- lut_enable = cm->flags.bits.lut3d_enable;
- if (lut_enable && cm->flags.bits.lut3d_dma_enable) {
- /* Fast (DMA) Load Mode */
- /* MPC */
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut_enable, lut_bank_a, cm->lut3d_dma.size, mpcc_id);
+ //check for support
+ if (mpc->funcs->mcm.is_config_supported &&
+ !mpc->funcs->mcm.is_config_supported(width))
+ break;
- /* only supports 12 bit */
if (mpc->funcs->program_lut_read_write_control)
- mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, 12, mpcc_id);
+ mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id);
- if (mpc->funcs->update_3dlut_fast_load_select)
- mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
+ if (hubp->funcs->hubp_program_3dlut_fl_addr)
+ hubp->funcs->hubp_program_3dlut_fl_addr(hubp, mcm_luts.lut3d_data.gpu_mem_params.addr);
- /* HUBP */
- if (hubp->funcs->hubp_program_3dlut_fl_config)
- hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma);
+ if (mpc->funcs->mcm.program_bit_depth)
+ mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id);
- if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
- hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format);
+ switch (mcm_luts.lut3d_data.gpu_mem_params.layout) {
+ case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
+ mode = hubp_3dlut_fl_mode_native_1;
+ addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
+ mode = hubp_3dlut_fl_mode_native_2;
+ addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
+ mode = hubp_3dlut_fl_mode_transform;
+ addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
+ break;
+ default:
+ mode = hubp_3dlut_fl_mode_disable;
+ addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ }
+ if (hubp->funcs->hubp_program_3dlut_fl_mode)
+ hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
- if (hubp->funcs->hubp_program_3dlut_fl_addr)
- hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr);
+ if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
+ hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
- if (hubp->funcs->hubp_enable_3dlut_fl) {
- hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
- } else {
- /* GPU memory only supports fast load path */
- BREAK_TO_DEBUGGER();
- lut_enable = false;
- result = false;
+ switch (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) {
+ case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
+ format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+ break;
+ case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
+ format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+ break;
+ case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
+ format = hubp_3dlut_fl_format_float_fp1_5_10;
+ break;
+ }
+ if (hubp->funcs->hubp_program_3dlut_fl_format)
+ hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
+ if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
+ mpc->funcs->mcm.program_bias_scale) {
+ mpc->funcs->mcm.program_bias_scale(mpc,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale,
+ mpcc_id);
+ hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale);
}
- } else {
- /* Legacy (Host) Load Mode */
- memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (cm->flags.bits.lut3d_enable && cm->lut3d_func.state.bits.initialized) {
- m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
- } else {
- lut_enable = false;
+ //navi 4x has a bug and r and blue are swapped and need to be worked around here in
+ //TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x
+ switch (mcm_luts.lut3d_data.gpu_mem_params.component_order) {
+ case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA:
+ default:
+ crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ break;
}
- /* MPC */
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc,
- MCM_LUT_3DLUT,
- lut_enable,
- lut_bank_a,
- cm->lut3d_func.lut_3d.use_tetrahedral_9 ? CM_LUT_SIZE_999 : CM_LUT_SIZE_171717,
- mpcc_id);
-
- if (lut_enable) {
- if (mpc->funcs->program_lut_read_write_control)
- mpc->funcs->program_lut_read_write_control(mpc,
- MCM_LUT_3DLUT,
- lut_bank_a,
- cm->lut3d_func.lut_3d.use_12bits ? 12 : 10,
- mpcc_id);
+ if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
+ hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
+ crossbar_bit_slice_cr_r,
+ crossbar_bit_slice_y_g,
+ crossbar_bit_slice_cb_b);
- if (mpc->funcs->update_3dlut_fast_load_select)
- mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 0xf);
+ if (mpc->funcs->mcm.program_lut_read_write_control)
+ mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
- if (mpc->funcs->populate_lut)
- mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, &m_lut_params, lut_bank_a, mpcc_id);
- }
+ if (mpc->funcs->mcm.program_3dlut_size)
+ mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
- /* HUBP */
- memset(&lut3d_dma, 0, sizeof(lut3d_dma));
- if (hubp->funcs->hubp_program_3dlut_fl_config)
- hubp->funcs->hubp_program_3dlut_fl_config(hubp, &lut3d_dma);
+ if (mpc->funcs->update_3dlut_fast_load_select)
+ mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
if (hubp->funcs->hubp_enable_3dlut_fl)
- hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+ else {
+ if (mpc->funcs->program_lut_mode) {
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
+ }
+ }
+ break;
+
+ }
+}
+
+void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+ (void)dc;
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+
+ if (hubp->funcs->hubp_enable_3dlut_fl) {
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+ }
+}
+
+bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
+ const struct dc_plane_state *plane_state)
+{
+ struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+ int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+ struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc;
+ struct mpc *mpc = dc->res_pool->mpc;
+ bool result;
+ const struct pwl_params *lut_params = NULL;
+ bool rval;
+
+ if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
+ dcn401_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, plane_state->lut_bank_a);
+ return true;
+ }
+
+ mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
+ pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
+ // 1D LUT
+ if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->blend_tf.pwl;
+ else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+ &plane_state->blend_tf,
+ &dpp_base->regamma_params, false);
+ lut_params = rval ? &dpp_base->regamma_params : NULL;
+ }
+ result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
+ lut_params = NULL;
+
+ // Shaper
+ if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->in_shaper_func.pwl;
+ else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ // TODO: dpp_base replace
+ rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+ &plane_state->in_shaper_func,
+ &dpp_base->shaper_params, true);
+ lut_params = rval ? &dpp_base->shaper_params : NULL;
+ }
+ result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
+
+ // 3D
+ if (mpc->funcs->program_3dlut) {
+ if (plane_state->lut3d_func.state.bits.initialized == 1)
+ result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
+ else
+ result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
}
return result;
@@ -1824,9 +1948,10 @@ void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx)
for (odm_pipe = pipe_ctx; odm_pipe != NULL; odm_pipe = odm_pipe->next_odm_pipe) {
for (mpc_pipe = odm_pipe; mpc_pipe != NULL; mpc_pipe = mpc_pipe->bottom_pipe) {
- if (mpc_pipe->plane_state &&
- mpc_pipe->plane_state->cm.flags.bits.lut3d_enable &&
- mpc_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) {
+ if (mpc_pipe->plane_state && mpc_pipe->plane_state->mcm_luts.lut3d_data.lut3d_src
+ == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM
+ && mpc_pipe->plane_state->mcm_shaper_3dlut_setting
+ == DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT) {
wa_pipes[wa_pipe_ct++] = mpc_pipe;
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
index 46f2f9833d9e..53ff5a02af02 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
@@ -394,6 +394,68 @@ void dcn42_program_cm_hist(
plane_state->cm_hist_control, plane_state->color_space);
}
+static void dc_get_lut_xbar(
+ enum dc_cm2_gpu_mem_pixel_component_order order,
+ enum hubp_3dlut_fl_crossbar_bit_slice *cr_r,
+ enum hubp_3dlut_fl_crossbar_bit_slice *y_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice *cb_b)
+{
+ switch (order) {
+ case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA:
+ *cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ *y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ *cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ break;
+ case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_BGRA:
+ *cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ *y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ *cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ break;
+ }
+}
+
+static void dc_get_lut_mode(
+ enum dc_cm2_gpu_mem_layout layout,
+ enum hubp_3dlut_fl_mode *mode,
+ enum hubp_3dlut_fl_addressing_mode *addr_mode)
+{
+ switch (layout) {
+ case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
+ *mode = hubp_3dlut_fl_mode_native_1;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
+ *mode = hubp_3dlut_fl_mode_native_2;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
+ *mode = hubp_3dlut_fl_mode_transform;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
+ break;
+ default:
+ *mode = hubp_3dlut_fl_mode_disable;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ }
+}
+
+static void dc_get_lut_format(
+ enum dc_cm2_gpu_mem_format dc_format,
+ enum hubp_3dlut_fl_format *format)
+{
+ switch (dc_format) {
+ case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
+ *format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+ break;
+ case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
+ *format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+ break;
+ case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
+ *format = hubp_3dlut_fl_format_float_fp1_5_10;
+ break;
+ }
+}
+
static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
{
if (mpc->funcs->rmcm.power_on_shaper_3dlut &&
@@ -404,17 +466,119 @@ static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
return false;
}
+static bool is_rmcm_3dlut_fl_supported(struct dc *dc, enum dc_cm2_gpu_mem_size size)
+{
+ if (!dc->caps.color.mpc.rmcm_3d_lut_caps.dma_3d_lut)
+ return false;
+ if (size == DC_CM2_GPU_MEM_SIZE_171717)
+ return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_17);
+ else if (size == DC_CM2_GPU_MEM_SIZE_333333)
+ return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33);
+ return false;
+}
+
+static void dcn42_set_mcm_location_post_blend(struct dc *dc, struct pipe_ctx *pipe_ctx, bool bPostBlend)
+{
+ struct mpc *mpc = dc->res_pool->mpc;
+ int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+
+ if (!pipe_ctx->plane_state)
+ return;
+
+ mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
+ pipe_ctx->plane_state->mcm_location = (bPostBlend) ?
+ MPCC_MOVABLE_CM_LOCATION_AFTER :
+ MPCC_MOVABLE_CM_LOCATION_BEFORE;
+}
+
+static void dcn42_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct pipe_ctx *pipe_ctx,
+ enum MCM_LUT_XABLE *shaper_xable,
+ enum MCM_LUT_XABLE *lut3d_xable,
+ enum MCM_LUT_XABLE *lut1d_xable)
+{
+ enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
+ bool lut1d_enable = false;
+ struct mpc *mpc = dc->res_pool->mpc;
+ int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+
+ if (!pipe_ctx->plane_state)
+ return;
+ shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting;
+ lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable;
+ mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
+ pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
+
+ *lut1d_xable = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE;
+
+ switch (shaper_3dlut_setting) {
+ case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL:
+ *lut3d_xable = *shaper_xable = MCM_LUT_DISABLE;
+ break;
+ case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER:
+ *lut3d_xable = MCM_LUT_DISABLE;
+ *shaper_xable = MCM_LUT_ENABLE;
+ break;
+ case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT:
+ *lut3d_xable = *shaper_xable = MCM_LUT_ENABLE;
+ break;
+ }
+}
+
+static void fl_get_lut_mode(
+ enum dc_cm2_gpu_mem_layout layout,
+ enum dc_cm2_gpu_mem_size size,
+ enum hubp_3dlut_fl_mode *mode,
+ enum hubp_3dlut_fl_addressing_mode *addr_mode,
+ enum hubp_3dlut_fl_width *width)
+{
+ *width = hubp_3dlut_fl_width_17;
+
+ if (size == DC_CM2_GPU_MEM_SIZE_333333)
+ *width = hubp_3dlut_fl_width_33;
+
+ switch (layout) {
+ case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
+ *mode = hubp_3dlut_fl_mode_native_1;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
+ *mode = hubp_3dlut_fl_mode_native_2;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
+ *mode = hubp_3dlut_fl_mode_transform;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
+ break;
+ default:
+ *mode = hubp_3dlut_fl_mode_disable;
+ *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ }
+}
+
bool dcn42_program_rmcm_luts(
struct hubp *hubp,
struct pipe_ctx *pipe_ctx,
- const struct dc_plane_cm *cm,
+ enum dc_cm2_transfer_func_source lut3d_src,
+ struct dc_cm2_func_luts *mcm_luts,
struct mpc *mpc,
+ bool lut_bank_a,
int mpcc_id)
{
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
union mcm_lut_params m_lut_params = {0};
+ enum MCM_LUT_XABLE shaper_xable, lut3d_xable = MCM_LUT_DISABLE, lut1d_xable;
+ enum hubp_3dlut_fl_mode mode;
+ enum hubp_3dlut_fl_addressing_mode addr_mode;
+ enum hubp_3dlut_fl_format format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_17;
+
struct dc *dc = hubp->ctx->dc;
+ struct hubp_fl_3dlut_config fl_config;
struct mpc_fl_3dlut_config mpc_fl_config;
struct dc_stream_state *stream = pipe_ctx->stream;
@@ -422,23 +586,25 @@ bool dcn42_program_rmcm_luts(
// true->false when it can be allocated at DI time
struct dc_rmcm_3dlut *rmcm_3dlut = dc_stream_get_3dlut_for_stream(dc, stream, false);
- bool lut_bank_a = true; // TODO get from HW
-
//check to see current pipe is part of a stream with allocated rmcm 3dlut
if (!rmcm_3dlut)
return false;
+ rmcm_3dlut->protection_bits = mcm_luts->lut3d_data.rmcm_tmz;
+
+ dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
+
/* Shaper */
- if (cm->flags.bits.shaper_enable) {
+ if (mcm_luts->shaper) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (cm->shaper_func.type == TF_TYPE_HWPWL) {
- m_lut_params.pwl = &cm->shaper_func.pwl;
- } else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ if (mcm_luts->shaper->type == TF_TYPE_HWPWL) {
+ m_lut_params.pwl = &mcm_luts->shaper->pwl;
+ } else if (mcm_luts->shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
ASSERT(false);
cm_helper_translate_curve_to_hw_format(
dc->ctx,
- &cm->shaper_func,
+ mcm_luts->shaper,
&dpp_base->shaper_params, true);
m_lut_params.pwl = &dpp_base->shaper_params;
}
@@ -454,21 +620,58 @@ bool dcn42_program_rmcm_luts(
}
/* 3DLUT */
- if (!cm->flags.bits.lut3d_dma_enable) {
+ switch (lut3d_src) {
+ case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
memset(&m_lut_params, 0, sizeof(m_lut_params));
// Don't know what to do in this case.
- } else {
- if (!dc_is_rmcm_3dlut_supported(hubp, mpc))
+ //case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
+ break;
+ case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
+ fl_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout,
+ mcm_luts->lut3d_data.gpu_mem_params.size,
+ &mode,
+ &addr_mode,
+ &width);
+
+ if (!dc_is_rmcm_3dlut_supported(hubp, mpc) ||
+ !mpc->funcs->rmcm.is_config_supported(
+ (width == hubp_3dlut_fl_width_17 ||
+ width == hubp_3dlut_fl_width_transformed) ? 17 : 33))
return false;
+ // setting native or transformed mode,
+ dc_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout, &mode, &addr_mode);
+
//seems to be only for the MCM
- mpc_fl_config.enabled = cm->flags.bits.lut3d_enable;
- mpc_fl_config.size = cm->lut3d_dma.size;
+ dc_get_lut_format(mcm_luts->lut3d_data.gpu_mem_params.format_params.format, &format);
+
+ dc_get_lut_xbar(
+ mcm_luts->lut3d_data.gpu_mem_params.component_order,
+ &crossbar_bit_slice_cr_r,
+ &crossbar_bit_slice_y_g,
+ &crossbar_bit_slice_cb_b);
+
+ fl_config.mode = mode;
+ fl_config.enabled = lut3d_xable != MCM_LUT_DISABLE;
+ fl_config.address = mcm_luts->lut3d_data.gpu_mem_params.addr;
+ fl_config.format = format;
+ fl_config.crossbar_bit_slice_y_g = crossbar_bit_slice_y_g;
+ fl_config.crossbar_bit_slice_cb_b = crossbar_bit_slice_cb_b;
+ fl_config.crossbar_bit_slice_cr_r = crossbar_bit_slice_cr_r;
+ fl_config.width = width;
+ fl_config.protection_bits = rmcm_3dlut->protection_bits;
+ fl_config.addr_mode = addr_mode;
+ fl_config.layout = mcm_luts->lut3d_data.gpu_mem_params.layout;
+ fl_config.bias = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias;
+ fl_config.scale = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale;
+
+ mpc_fl_config.enabled = fl_config.enabled;
+ mpc_fl_config.width = width;
mpc_fl_config.select_lut_bank_a = lut_bank_a;
- mpc_fl_config.bit_depth = 0;
+ mpc_fl_config.bit_depth = mcm_luts->lut3d_data.gpu_mem_params.bit_depth;
mpc_fl_config.hubp_index = hubp->inst;
- mpc_fl_config.bias = cm->lut3d_dma.bias;
- mpc_fl_config.scale = cm->lut3d_dma.scale;
+ mpc_fl_config.bias = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias;
+ mpc_fl_config.scale = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale;
//1. power down the block
mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, false);
@@ -476,44 +679,268 @@ bool dcn42_program_rmcm_luts(
//2. program RMCM - 3dlut reg programming
mpc->funcs->rmcm.fl_3dlut_configure(mpc, &mpc_fl_config, mpcc_id);
- /* HUBP */
- if (hubp->funcs->hubp_program_3dlut_fl_config)
- hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma);
-
- if (hubp->funcs->hubp_program_3dlut_fl_addr)
- hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr);
+ hubp->funcs->hubp_program_3dlut_fl_config(hubp, &fl_config);
//3. power on the block
mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, true);
+
+ break;
+ default:
+ return false;
}
return true;
}
-bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
- const struct dc_plane_state *plane_state)
+void dcn42_populate_mcm_luts(struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ struct dc_cm2_func_luts mcm_luts,
+ bool lut_bank_a)
{
- struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
+ struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
- const struct dc_plane_cm *cm = &plane_state->cm;
- struct mpc *mpc = dc->res_pool->mpc;
int mpcc_id = hubp->inst;
- bool result;
-
- /* MCM */
- result = dcn401_set_mcm_luts(pipe_ctx, plane_state);
-
- /* RMCM */
- if (cm->flags.bits.rmcm_enable && cm->flags.bits.lut3d_dma_enable) {
- /* TODO - move RMCM to its own block */
+ struct mpc *mpc = dc->res_pool->mpc;
+ union mcm_lut_params m_lut_params;
+ enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src;
+ enum hubp_3dlut_fl_format format = 0;
+ enum hubp_3dlut_fl_mode mode;
+ enum hubp_3dlut_fl_width width = 0;
+ enum hubp_3dlut_fl_addressing_mode addr_mode;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0;
+ enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
+ enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
+ enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
+ bool rval;
+
+ dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
+
+ //MCM - setting its location (Before/After) blender
+ //set to post blend (true)
+ dcn42_set_mcm_location_post_blend(
+ dc,
+ pipe_ctx,
+ mcm_luts.lut3d_data.mpc_mcm_post_blend);
+
+ //RMCM - 3dLUT+Shaper
+ if (mcm_luts.lut3d_data.rmcm_3dlut_enable &&
+ is_rmcm_3dlut_fl_supported(dc, mcm_luts.lut3d_data.gpu_mem_params.size)) {
dcn42_program_rmcm_luts(
hubp,
pipe_ctx,
- cm,
+ lut3d_src,
+ &mcm_luts,
mpc,
+ lut_bank_a,
mpcc_id);
}
+ /* 1D LUT */
+ if (mcm_luts.lut1d_func) {
+ memset(&m_lut_params, 0, sizeof(m_lut_params));
+ if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
+ m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
+ else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+ rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+ mcm_luts.lut1d_func,
+ &dpp_base->regamma_params, false);
+ m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
+ }
+ if (m_lut_params.pwl) {
+ if (mpc->funcs->populate_lut)
+ mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id);
+ }
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
+ }
+
+ /* Shaper */
+ if (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_enable) {
+ memset(&m_lut_params, 0, sizeof(m_lut_params));
+ if (mcm_luts.shaper->type == TF_TYPE_HWPWL)
+ m_lut_params.pwl = &mcm_luts.shaper->pwl;
+ else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
+ ASSERT(false);
+ rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+ mcm_luts.shaper,
+ &dpp_base->regamma_params, true);
+ m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
+ }
+ if (m_lut_params.pwl) {
+ if (mpc->funcs->mcm.populate_lut)
+ mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id);
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
+ }
+ }
+
+ /* 3DLUT */
+ switch (lut3d_src) {
+ case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
+ memset(&m_lut_params, 0, sizeof(m_lut_params));
+ if (hubp->funcs->hubp_enable_3dlut_fl)
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
+
+ if (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) {
+ m_lut_params.lut3d = &mcm_luts.lut3d_data.lut3d_func->lut_3d;
+ if (mpc->funcs->populate_lut)
+ mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id);
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
+ mpcc_id);
+ }
+ break;
+ case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
+ switch (mcm_luts.lut3d_data.gpu_mem_params.size) {
+ case DC_CM2_GPU_MEM_SIZE_333333:
+ width = hubp_3dlut_fl_width_33;
+ break;
+ case DC_CM2_GPU_MEM_SIZE_171717:
+ width = hubp_3dlut_fl_width_17;
+ break;
+ case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
+ width = hubp_3dlut_fl_width_transformed;
+ break;
+ default:
+ //TODO: Handle default case
+ break;
+ }
+
+ //check for support
+ if (mpc->funcs->mcm.is_config_supported &&
+ !mpc->funcs->mcm.is_config_supported(width))
+ break;
+
+ if (mpc->funcs->program_lut_read_write_control)
+ mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id);
+
+ if (hubp->funcs->hubp_program_3dlut_fl_addr)
+ hubp->funcs->hubp_program_3dlut_fl_addr(hubp, mcm_luts.lut3d_data.gpu_mem_params.addr);
+
+ if (mpc->funcs->mcm.program_bit_depth)
+ mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id);
+
+ dc_get_lut_mode(mcm_luts.lut3d_data.gpu_mem_params.layout, &mode, &addr_mode);
+ if (hubp->funcs->hubp_program_3dlut_fl_mode)
+ hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
+
+ if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
+ hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
+
+ switch (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) {
+ case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
+ format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+ break;
+ case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
+ format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+ break;
+ case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
+ format = hubp_3dlut_fl_format_float_fp1_5_10;
+ break;
+ }
+ if (hubp->funcs->hubp_program_3dlut_fl_format)
+ hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
+ if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
+ mpc->funcs->mcm.program_bias_scale) {
+ mpc->funcs->mcm.program_bias_scale(mpc,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale,
+ mpcc_id);
+ hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+ mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale);
+ }
+
+ //navi 4x has a bug and r and blue are swapped and need to be worked around here in
+ //TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x
+ dc_get_lut_xbar(
+ mcm_luts.lut3d_data.gpu_mem_params.component_order,
+ &crossbar_bit_slice_cr_r,
+ &crossbar_bit_slice_y_g,
+ &crossbar_bit_slice_cb_b);
+
+ if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
+ hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
+ crossbar_bit_slice_cr_r,
+ crossbar_bit_slice_y_g,
+ crossbar_bit_slice_cb_b);
+
+ if (mpc->funcs->mcm.program_lut_read_write_control)
+ mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
+
+ if (mpc->funcs->mcm.program_3dlut_size)
+ mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
+
+ if (mpc->funcs->update_3dlut_fast_load_select)
+ mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
+
+ if (hubp->funcs->hubp_enable_3dlut_fl)
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+ else {
+ if (mpc->funcs->program_lut_mode) {
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
+ }
+ }
+ break;
+ }
+}
+
+bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
+ const struct dc_plane_state *plane_state)
+{
+ struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+ int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+ struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc;
+ struct mpc *mpc = dc->res_pool->mpc;
+ bool result;
+ const struct pwl_params *lut_params = NULL;
+ bool rval;
+
+ if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
+ dcn42_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, plane_state->lut_bank_a);
+ return true;
+ }
+
+ mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
+ pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
+ // 1D LUT
+ if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->blend_tf.pwl;
+ else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+ &plane_state->blend_tf,
+ &dpp_base->regamma_params, false);
+ lut_params = rval ? &dpp_base->regamma_params : NULL;
+ }
+ result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
+ lut_params = NULL;
+
+ // Shaper
+ if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->in_shaper_func.pwl;
+ else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ // TODO: dpp_base replace
+ rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+ &plane_state->in_shaper_func,
+ &dpp_base->shaper_params, true);
+ lut_params = rval ? &dpp_base->shaper_params : NULL;
+ }
+ result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
+
+ // 3D
+ if (mpc->funcs->program_3dlut) {
+ if (plane_state->lut3d_func.state.bits.initialized == 1)
+ result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
+ else
+ result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+ }
+
return result;
}
void dcn42_hardware_release(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
index c4cfeed45b19..0539ee0ffaee 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
@@ -18,11 +18,18 @@ void dcn42_program_cm_hist(
bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state);
+void dcn42_populate_mcm_luts(struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ struct dc_cm2_func_luts mcm_luts,
+ bool lut_bank_a);
+
bool dcn42_program_rmcm_luts(
struct hubp *hubp,
struct pipe_ctx *pipe_ctx,
- const struct dc_plane_cm *cm,
+ enum dc_cm2_transfer_func_source lut3d_src,
+ struct dc_cm2_func_luts *mcm_luts,
struct mpc *mpc,
+ bool lut_bank_a,
int mpcc_id);
void dcn42_hardware_release(struct dc *dc);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index 2a5a81d15950..fc005aadfd55 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -89,7 +89,7 @@ enum hubp_3dlut_fl_addressing_mode {
enum hubp_3dlut_fl_width {
hubp_3dlut_fl_width_17 = 17,
hubp_3dlut_fl_width_33 = 33,
- hubp_3dlut_fl_width_17_transformed = 4916, //mpc default
+ hubp_3dlut_fl_width_transformed = 4916, //mpc default
};
enum hubp_3dlut_fl_crossbar_bit_slice {
@@ -99,6 +99,22 @@ enum hubp_3dlut_fl_crossbar_bit_slice {
hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3
};
+struct hubp_fl_3dlut_config {
+ bool enabled;
+ enum hubp_3dlut_fl_width width;
+ enum hubp_3dlut_fl_mode mode;
+ enum hubp_3dlut_fl_format format;
+ uint16_t bias;
+ uint16_t scale;
+ struct dc_plane_address address;
+ enum hubp_3dlut_fl_addressing_mode addr_mode;
+ enum dc_cm2_gpu_mem_layout layout;
+ uint8_t protection_bits;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
+ enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
+};
+
struct hubp {
const struct hubp_funcs *funcs;
struct dc_context *ctx;
@@ -273,15 +289,24 @@ struct hubp_funcs {
void (*hubp_wait_pipe_read_start)(struct hubp *hubp);
void (*hubp_program_mcache_id_and_split_coordinate)(struct hubp *hubp, struct dml2_hubp_pipe_mcache_regs *mcache_regs);
+ void (*hubp_update_3dlut_fl_bias_scale)(struct hubp *hubp, uint16_t bias, uint16_t scale);
+ void (*hubp_program_3dlut_fl_mode)(struct hubp *hubp,
+ enum hubp_3dlut_fl_mode mode);
+ void (*hubp_program_3dlut_fl_format)(struct hubp *hubp,
+ enum hubp_3dlut_fl_format format);
void (*hubp_program_3dlut_fl_addr)(struct hubp *hubp,
- const struct dc_plane_address *address);
- void (*hubp_program_3dlut_fl_config)(struct hubp *hubp,
- const struct dc_3dlut_dma *config);
+ const struct dc_plane_address address);
void (*hubp_program_3dlut_fl_dlg_param)(struct hubp *hubp, int refcyc_per_3dlut_group);
void (*hubp_enable_3dlut_fl)(struct hubp *hubp, bool enable);
+ void (*hubp_program_3dlut_fl_addressing_mode)(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode);
+ void (*hubp_program_3dlut_fl_width)(struct hubp *hubp, enum hubp_3dlut_fl_width width);
+ void (*hubp_program_3dlut_fl_tmz_protected)(struct hubp *hubp, uint8_t protection_bits);
void (*hubp_program_3dlut_fl_crossbar)(struct hubp *hubp,
- enum dc_cm_lut_pixel_format format);
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
int (*hubp_get_3dlut_fl_done)(struct hubp *hubp);
+ void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg);
void (*hubp_clear_tiling)(struct hubp *hubp);
uint32_t (*hubp_get_current_read_line)(struct hubp *hubp);
uint32_t (*hubp_get_det_config_error)(struct hubp *hubp);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index f5617674bea8..54eb2eba68bf 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -54,7 +54,6 @@
#include "dc_hw_types.h"
#include "hw_shared.h"
#include "transform.h"
-#include "dc_types.h"
#define MAX_MPCC 6
#define MAX_OPP 6
@@ -102,6 +101,13 @@ enum mpcc_movable_cm_location {
MPCC_MOVABLE_CM_LOCATION_AFTER,
};
+enum MCM_LUT_XABLE {
+ MCM_LUT_DISABLE,
+ MCM_LUT_DISABLED = MCM_LUT_DISABLE,
+ MCM_LUT_ENABLE,
+ MCM_LUT_ENABLED = MCM_LUT_ENABLE,
+};
+
enum MCM_LUT_ID {
MCM_LUT_3DLUT,
MCM_LUT_1DLUT,
@@ -110,7 +116,7 @@ enum MCM_LUT_ID {
struct mpc_fl_3dlut_config {
bool enabled;
- enum dc_cm_lut_size size;
+ uint16_t width;
bool select_lut_bank_a;
uint16_t bit_depth;
int hubp_index;
@@ -1069,11 +1075,8 @@ struct mpc_funcs {
*
* void
*/
- void (*populate_lut)(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const union mcm_lut_params *params,
- const bool lut_bank_a,
- const int mpcc_id);
+ void (*populate_lut)(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params,
+ bool lut_bank_a, int mpcc_id);
/**
* @program_lut_read_write_control:
@@ -1084,18 +1087,13 @@ struct mpc_funcs {
* - [in/out] mpc - MPC context.
* - [in] id
* - [in] lut_bank_a
- * - [in] bit_depth
* - [in] mpcc_id
*
* Return:
*
* void
*/
- void (*program_lut_read_write_control)(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const bool lut_bank_a,
- const unsigned int bit_depth,
- const int mpcc_id);
+ void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id);
/**
* @program_lut_mode:
@@ -1105,44 +1103,33 @@ struct mpc_funcs {
* Parameters:
* - [in/out] mpc - MPC context.
* - [in] id
- * - [in] enable
+ * - [in] xable
* - [in] lut_bank_a
- * - [in] size
* - [in] mpcc_id
*
* Return:
*
* void
*/
- void (*program_lut_mode)(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const bool enable,
- const bool lut_bank_a,
- const enum dc_cm_lut_size size,
- const int mpcc_id);
-
+ void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, const enum MCM_LUT_XABLE xable,
+ bool lut_bank_a, int mpcc_id);
/**
- * @get_lut_mode:
- *
- * Obtains enablement and ram bank status.
- *
- * Parameters:
- * - [in/out] mpc - MPC context.
- * - [in] id
- * - [in] mpcc_id
- * - [out] enable
- * - [out] lut_bank_a
- *
- * Return:
- *
- * void
- */
- void (*get_lut_mode)(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const int mpcc_id,
- bool *enable,
- bool *lut_bank_a);
+ * @mcm:
+ *
+ * MPC MCM new HW sequential programming functions
+ */
+ struct {
+ void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id);
+ void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id);
+ void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id);
+ bool (*is_config_supported)(uint32_t width);
+ void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,
+ bool lut_bank_a, bool enabled, int mpcc_id);
+
+ void (*populate_lut)(struct mpc *mpc, const union mcm_lut_params params,
+ bool lut_bank_a, int mpcc_id);
+ } mcm;
/**
* @rmcm:
@@ -1155,11 +1142,9 @@ struct mpc_funcs {
void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx);
void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,
bool lut_bank_a, bool enabled, int mpcc_id);
- void (*program_lut_mode)(struct mpc *mpc,
- bool enable,
- bool lut_bank_a,
- int mpcc_id);
- void (*program_3dlut_size)(struct mpc *mpc, const enum dc_cm_lut_size size, int mpcc_id);
+ void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
+ bool lut_bank_a, int mpcc_id);
+ void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id);
void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id);
void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id);
bool (*is_config_supported)(uint32_t width);
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
index e0617db2d0c1..ce1ee2062e41 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
@@ -73,15 +73,56 @@ void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_locati
}
}
-void mpc401_populate_lut(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const union mcm_lut_params *params,
- const bool lut_bank_a,
- const int mpcc_id)
+static enum dc_lut_mode get3dlut_config(
+ struct mpc *mpc,
+ bool *is_17x17x17,
+ bool *is_12bits_color_channel,
+ int mpcc_id)
+{
+ uint32_t i_mode, i_enable_10bits, lut_size;
+ enum dc_lut_mode mode;
+ struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
+
+ REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
+ MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode);
+
+ REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
+ MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
+
+ switch (i_mode) {
+ case 0:
+ mode = LUT_BYPASS;
+ break;
+ case 1:
+ mode = LUT_RAM_A;
+ break;
+ case 2:
+ mode = LUT_RAM_B;
+ break;
+ default:
+ mode = LUT_BYPASS;
+ break;
+ }
+ if (i_enable_10bits > 0)
+ *is_12bits_color_channel = false;
+ else
+ *is_12bits_color_channel = true;
+
+ REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
+
+ if (lut_size == 0)
+ *is_17x17x17 = true;
+ else
+ *is_17x17x17 = false;
+
+ return mode;
+}
+
+void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, bool lut_bank_a, int mpcc_id)
{
const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
- const struct pwl_params *lut1d = params->pwl;
- const struct pwl_params *lut_shaper = params->pwl;
+ const struct pwl_params *lut1d = params.pwl;
+ const struct pwl_params *lut_shaper = params.pwl;
bool is_17x17x17;
bool is_12bits_color_channel;
const struct dc_rgb *lut0;
@@ -90,7 +131,7 @@ void mpc401_populate_lut(struct mpc *mpc,
const struct dc_rgb *lut3;
int lut_size0;
int lut_size;
- const struct tetrahedral_params *lut3d = params->lut3d;
+ const struct tetrahedral_params *lut3d = params.lut3d;
switch (id) {
case MCM_LUT_1DLUT:
@@ -133,6 +174,8 @@ void mpc401_populate_lut(struct mpc *mpc,
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
+ get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id);
+
is_17x17x17 = !lut3d->use_tetrahedral_9;
is_12bits_color_channel = lut3d->use_12bits;
if (is_17x17x17) {
@@ -155,6 +198,8 @@ void mpc401_populate_lut(struct mpc *mpc,
sizeof(lut3d->tetrahedral_9.lut1[0]);
}
+ mpc32_select_3dlut_ram(mpc, next_mode,
+ is_12bits_color_channel, mpcc_id);
mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
if (is_12bits_color_channel)
mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
@@ -187,69 +232,46 @@ void mpc401_populate_lut(struct mpc *mpc,
}
-static uint32_t mpc401_cm_lut_size_to_3dlut_size(const enum dc_cm_lut_size cm_size)
-{
- uint32_t size = 0;
-
- switch (cm_size) {
- case CM_LUT_SIZE_999:
- size = 1;
- break;
- case CM_LUT_SIZE_171717:
- size = 0;
- break;
- default:
- /* invalid LUT size */
- ASSERT(false);
- size = 0;
- break;
- }
-
- return size;
-}
-
void mpc401_program_lut_mode(
struct mpc *mpc,
const enum MCM_LUT_ID id,
- const bool enable,
- const bool lut_bank_a,
- const enum dc_cm_lut_size size,
- const int mpcc_id)
+ const enum MCM_LUT_XABLE xable,
+ bool lut_bank_a,
+ int mpcc_id)
{
- uint32_t lut_size;
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
- if (enable) {
- lut_size = mpc401_cm_lut_size_to_3dlut_size(size);
- REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
- MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2,
- MPCC_MCM_3DLUT_SIZE, lut_size);
- } else {
- if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
- mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
+ switch (xable) {
+ case MCM_LUT_DISABLE:
REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 0);
+ break;
+ case MCM_LUT_ENABLE:
+ REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2);
+ break;
}
break;
case MCM_LUT_SHAPER:
- if (enable) {
- REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
- } else {
- if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
- mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
+ switch (xable) {
+ case MCM_LUT_DISABLE:
REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0);
+ break;
+ case MCM_LUT_ENABLE:
+ REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+ break;
}
break;
case MCM_LUT_1DLUT:
- if (enable) {
- REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
- MPCC_MCM_1DLUT_MODE, 2);
- } else {
- if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
- mpc32_power_on_blnd_lut(mpc, mpcc_id, false);
+ switch (xable) {
+ case MCM_LUT_DISABLE:
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_MODE, 0);
+ break;
+ case MCM_LUT_ENABLE:
+ REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+ MPCC_MCM_1DLUT_MODE, 2);
+ break;
}
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
@@ -257,20 +279,14 @@ void mpc401_program_lut_mode(
}
}
-void mpc401_program_lut_read_write_control(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const bool lut_bank_a,
- const unsigned int bit_depth,
- const int mpcc_id)
+void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id)
{
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
- REG_UPDATE_2(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
- MPCC_MCM_3DLUT_30BIT_EN, (bit_depth == 10) ? 1 : 0,
- MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
+ REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
break;
case MCM_LUT_SHAPER:
mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
@@ -562,44 +578,6 @@ void mpc401_get_gamut_remap(struct mpc *mpc,
arr_reg_val, ARRAY_SIZE(arr_reg_val));
}
-void mpc401_get_lut_mode(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const int mpcc_id,
- bool *enable,
- bool *lut_bank_a)
-{
- struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
-
- uint32_t lut_mode = 0;
- uint32_t lut_select = 0;
-
- *enable = false;
- *lut_bank_a = true;
-
- switch (id) {
- case MCM_LUT_SHAPER:
- REG_GET(MPCC_MCM_SHAPER_CONTROL[mpcc_id],
- MPCC_MCM_SHAPER_MODE_CURRENT, &lut_mode);
- *enable = lut_mode != 0;
- *lut_bank_a = lut_mode != 2;
- break;
- case MCM_LUT_1DLUT:
- REG_GET_2(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
- MPCC_MCM_1DLUT_MODE_CURRENT, &lut_mode,
- MPCC_MCM_1DLUT_SELECT_CURRENT, &lut_select);
- *enable = lut_mode != 0;
- *lut_bank_a = lut_mode == 0 || lut_select == 0;
- break;
- case MCM_LUT_3DLUT:
- default:
- REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
- MPCC_MCM_3DLUT_MODE_CURRENT, &lut_mode);
- *enable = lut_mode != 0;
- *lut_bank_a = lut_mode != 2;
- break;
- }
-}
-
static const struct mpc_funcs dcn401_mpc_funcs = {
.read_mpcc_state = mpc1_read_mpcc_state,
.insert_plane = mpc1_insert_plane,
@@ -638,7 +616,6 @@ static const struct mpc_funcs dcn401_mpc_funcs = {
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc401_program_lut_read_write_control,
.program_lut_mode = mpc401_program_lut_mode,
- .get_lut_mode = mpc401_get_lut_mode,
};
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
index c16560c84453..6d842d7b95c7 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
@@ -206,32 +206,21 @@ void dcn401_mpc_construct(struct dcn401_mpc *mpc401,
int num_rmu);
void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_location location, int mpcc_id);
-void mpc401_populate_lut(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const union mcm_lut_params *params,
- bool lut_bank_a,
- int mpcc_id);
+void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params,
+ bool lut_bank_a, int mpcc_id);
void mpc401_program_lut_mode(
struct mpc *mpc,
const enum MCM_LUT_ID id,
- const bool enable,
- const bool lut_bank_a,
- const enum dc_cm_lut_size size,
- const int mpcc_id);
-
-void mpc401_get_lut_mode(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- const int mpcc_id,
- bool *enable,
- bool *lut_bank_a);
+ const enum MCM_LUT_XABLE xable,
+ bool lut_bank_a,
+ int mpcc_id);
void mpc401_program_lut_read_write_control(
struct mpc *mpc,
const enum MCM_LUT_ID id,
- const bool lut_bank_a,
- const unsigned int bit_depth,
- const int mpcc_id);
+ bool lut_bank_a,
+ int mpcc_id);
void mpc401_set_gamut_remap(
struct mpc *mpc,
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
index 507dbdbea600..38c0e8f96d40 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
@@ -63,6 +63,154 @@ void mpc42_update_blending(
mpcc->blnd_cfg = *blnd_cfg;
}
+/* Shaper functions */
+void mpc42_power_on_shaper_3dlut(
+ struct mpc *mpc,
+ uint32_t mpcc_id,
+ bool power_on)
+{
+ uint32_t power_status_shaper = 2;
+ uint32_t power_status_3dlut = 2;
+ struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+ int max_retries = 10;
+
+ REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
+ MPCC_MCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1:0);
+ REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
+ MPCC_MCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1:0);
+ /* wait for memory to fully power up */
+ if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
+ REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
+ REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
+ }
+
+ /*read status is not mandatory, it is just for debugging*/
+ REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, &power_status_shaper);
+ REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
+
+ if (power_status_shaper != 0 && power_on == true)
+ BREAK_TO_DEBUGGER();
+
+ if (power_status_3dlut != 0 && power_on == true)
+ BREAK_TO_DEBUGGER();
+}
+
+void mpc42_configure_shaper_lut(
+ struct mpc *mpc,
+ bool is_ram_a,
+ uint32_t mpcc_id)
+{
+ struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+
+ REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
+ MPCC_MCM_SHAPER_SCALE_B, 0x7000);
+ REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
+ MPCC_MCM_SHAPER_SCALE_G, 0x7000);
+ REG_UPDATE(MPCC_MCM_SHAPER_SCALE_R[mpcc_id],
+ MPCC_MCM_SHAPER_SCALE_R, 0x7000);
+ REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
+ MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, 7);
+ REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
+ MPCC_MCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
+ REG_SET(MPCC_MCM_SHAPER_LUT_INDEX[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_INDEX, 0);
+}
+
+
+void mpc42_program_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
+{
+ struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+ uint32_t size = 0xff;
+
+ REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
+
+ REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE,
+ (width == 33) ? 2 :
+ (width == 17) ? 0 : 2);
+
+ REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
+}
+
+void mpc42_program_3dlut_fl_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id)
+{
+ struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+
+ REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_R[mpcc_id],
+ MPCC_MCM_3DLUT_OUT_OFFSET_R, bias,
+ MPCC_MCM_3DLUT_OUT_SCALE_R, scale);
+
+ REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_G[mpcc_id],
+ MPCC_MCM_3DLUT_OUT_OFFSET_G, bias,
+ MPCC_MCM_3DLUT_OUT_SCALE_G, scale);
+
+ REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_B[mpcc_id],
+ MPCC_MCM_3DLUT_OUT_OFFSET_B, bias,
+ MPCC_MCM_3DLUT_OUT_SCALE_B, scale);
+}
+
+void mpc42_program_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_id)
+{
+ struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+
+ REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_WRITE_EN_MASK, 0xF);
+
+ //program bit_depth
+ REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
+ MPCC_MCM_3DLUT_30BIT_EN,
+ (bit_depth == 10) ? 1 : 0);
+}
+
+bool mpc42_is_config_supported(uint32_t width)
+{
+ if (width == 17)
+ return true;
+
+ return false;
+}
+
+void mpc42_populate_lut(struct mpc *mpc, const union mcm_lut_params params,
+ bool lut_bank_a, int mpcc_id)
+{
+ const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
+ const struct pwl_params *lut_shaper = params.pwl;
+
+ if (lut_shaper == NULL)
+ return;
+ if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+ mpc42_power_on_shaper_3dlut(mpc, mpcc_id, true);
+
+ mpc42_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id);
+
+ if (next_mode == LUT_RAM_A)
+ mpc32_program_shaper_luta_settings(mpc, lut_shaper, mpcc_id);
+ else
+ mpc32_program_shaper_lutb_settings(mpc, lut_shaper, mpcc_id);
+
+ mpc32_program_shaper_lut(
+ mpc, lut_shaper->rgb_resulted, lut_shaper->hw_points_num, mpcc_id);
+
+ mpc42_power_on_shaper_3dlut(mpc, mpcc_id, false);
+}
+
+void mpc42_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id,
+ bool lut_bank_a, bool enabled, int mpcc_id)
+{
+ struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+
+ switch (id) {
+ case MCM_LUT_3DLUT:
+ REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE,
+ (!enabled) ? 0 :
+ (lut_bank_a) ? 1 : 2);
+ REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
+ break;
+ case MCM_LUT_SHAPER:
+ mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
+ break;
+ default:
+ break;
+ }
+}
+
/* RMCM Shaper functions */
void mpc42_power_on_rmcm_shaper_3dlut(
struct mpc *mpc,
@@ -526,47 +674,32 @@ void mpc42_program_rmcm_lut_read_write_control(struct mpc *mpc, const enum MCM_L
}
}
-void mpc42_program_lut_mode(struct mpc *mpc,
- bool enable,
- bool lut_bank_a,
- int mpcc_id)
+void mpc42_program_lut_mode(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
+ bool lut_bank_a, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
- if (enable) {
- REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
- } else {
+ switch (xable) {
+ case MCM_LUT_DISABLE:
REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, 0);
- }
-}
-
-static uint32_t mpc42_get_rmcm_3dlut_width(
- const enum dc_cm_lut_size size)
-{
- uint32_t width = 0;
-
- switch (size) {
- case CM_LUT_SIZE_333333:
- width = 2;
break;
- case CM_LUT_SIZE_171717:
- default:
- width = 0;
+ case MCM_LUT_ENABLE:
+ REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
break;
}
-
- return width;
}
-void mpc42_program_rmcm_3dlut_size(struct mpc *mpc,
- const enum dc_cm_lut_size size,
- int mpcc_id)
+void mpc42_program_rmcm_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
- uint32_t width = mpc42_get_rmcm_3dlut_width(size);
+ uint32_t size = 0xff;
+
+ REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
- REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id],
- MPC_RMCM_3DLUT_SIZE, width);
+ REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE,
+ (width == 33) ? 2 : 0);
+
+ REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
}
void mpc42_program_rmcm_3dlut_fast_load_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id)
@@ -598,6 +731,14 @@ void mpc42_program_rmcm_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_
(bit_depth == 10) ? 1 : 0);
}
+bool mpc42_is_rmcm_config_supported(uint32_t width)
+{
+ if (width == 17 || width == 33)
+ return true;
+
+ return false;
+}
+
void mpc42_set_fl_config(
struct mpc *mpc,
struct mpc_fl_3dlut_config *cfg,
@@ -605,7 +746,6 @@ void mpc42_set_fl_config(
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
- uint32_t width = mpc42_get_rmcm_3dlut_width(cfg->size);
/*
From: Jie Zhou
@@ -646,7 +786,7 @@ void mpc42_set_fl_config(
//width
REG_UPDATE_2(MPC_RMCM_3DLUT_MODE[mpcc_id],
- MPC_RMCM_3DLUT_SIZE, width,
+ MPC_RMCM_3DLUT_SIZE, (cfg->width == 33) ? 2 : 0,
MPC_RMCM_3DLUT_MODE, (!cfg->enabled) ? 0 : (cfg->select_lut_bank_a) ? 1 : 2);
//connect to hubp
@@ -659,6 +799,182 @@ void mpc42_set_fl_config(
REG_UPDATE(MPC_RMCM_CNTL[mpcc_id], MPC_RMCM_CNTL, cfg->enabled ? 0 : 0xF);
}
+//static void rmcm_program_gamut_remap(
+// struct mpc *mpc,
+// unsigned int mpcc_id,
+// const uint16_t *regval,
+// enum mpcc_gamut_remap_id gamut_remap_block_id,
+// enum mpcc_gamut_remap_mode_select mode_select)
+//{
+// struct color_matrices_reg gamut_regs;
+// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+//
+// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
+// gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
+// gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
+// mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
+// return;
+// }
+// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP) {
+//
+// if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
+// REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0,
+// MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
+// return;
+// }
+//
+// gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
+// gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
+// gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
+// gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
+//
+// switch (mode_select) {
+// case MPCC_GAMUT_REMAP_MODE_SELECT_1:
+// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
+// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
+// break;
+// case MPCC_GAMUT_REMAP_MODE_SELECT_2:
+// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
+// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
+// break;
+// default:
+// break;
+// }
+//
+// cm_helper_program_color_matrices(
+// mpc->ctx,
+// regval,
+// &gamut_regs);
+//
+// //select coefficient set to use, set A (MODE_1) or set B (MODE_2)
+// REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0, MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
+// }
+//}
+
+//static bool is_mpc_legacy_gamut_id(enum mpcc_gamut_remap_id gamut_remap_block_id)
+//{
+// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
+// gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
+// gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
+// return true;
+// }
+// return false;
+//}
+//static void program_gamut_remap(
+// struct mpc *mpc,
+// unsigned int mpcc_id,
+// const uint16_t *regval,
+// enum mpcc_gamut_remap_id gamut_remap_block_id,
+// enum mpcc_gamut_remap_mode_select mode_select)
+//{
+// if (is_mpc_legacy_gamut_id(gamut_remap_block_id))
+// mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
+// else
+// rmcm_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
+//}
+
+//void mpc42_set_gamut_remap(
+// struct mpc *mpc,
+// int mpcc_id,
+// const struct mpc_grph_gamut_adjustment *adjust)
+//{
+// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+// unsigned int i = 0;
+// uint32_t mode_select = 0;
+//
+// if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) {
+// /* Bypass / Disable if type is bypass or hw */
+// program_gamut_remap(mpc, mpcc_id, NULL,
+// adjust->mpcc_gamut_remap_block_id, MPCC_GAMUT_REMAP_MODE_SELECT_0);
+// } else {
+// struct fixed31_32 arr_matrix[12];
+// uint16_t arr_reg_val[12];
+//
+// for (i = 0; i < 12; i++)
+// arr_matrix[i] = adjust->temperature_matrix[i];
+//
+// convert_float_matrix(arr_reg_val, arr_matrix, 12);
+//
+// if (is_mpc_legacy_gamut_id(adjust->mpcc_gamut_remap_block_id))
+// REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id],
+// MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select);
+// else
+// REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id],
+// MPC_RMCM_GAMUT_REMAP_MODE_CURRENT, &mode_select);
+//
+// //If current set in use not set A (MODE_1), then use set A, otherwise use set B
+// if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1)
+// mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1;
+// else
+// mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2;
+//
+// program_gamut_remap(mpc, mpcc_id, arr_reg_val,
+// adjust->mpcc_gamut_remap_block_id, mode_select);
+// }
+//}
+
+//static void read_gamut_remap(struct mpc *mpc,
+// int mpcc_id,
+// uint16_t *regval,
+// enum mpcc_gamut_remap_id gamut_remap_block_id,
+// uint32_t *mode_select)
+//{
+// struct color_matrices_reg gamut_regs = {0};
+// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+//
+// if (is_mpc_legacy_gamut_id(gamut_remap_block_id)) {
+// mpc_read_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
+// }
+// if (gamut_remap_block_id == MPCC_RMCM_GAMUT_REMAP) {
+// //current coefficient set in use
+// REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
+//
+// gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
+// gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
+// gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
+// gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
+//
+// switch (*mode_select) {
+// case MPCC_GAMUT_REMAP_MODE_SELECT_1:
+// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
+// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
+// break;
+// case MPCC_GAMUT_REMAP_MODE_SELECT_2:
+// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
+// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
+// break;
+// default:
+// break;
+// }
+// }
+//
+// if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) {
+// cm_helper_read_color_matrices(
+// mpc42->base.ctx,
+// regval,
+// &gamut_regs);
+// }
+//}
+
+//void mpc42_get_gamut_remap(struct mpc *mpc,
+// int mpcc_id,
+// struct mpc_grph_gamut_adjustment *adjust)
+//{
+// uint16_t arr_reg_val[12] = {0};
+// uint32_t mode_select;
+//
+// read_gamut_remap(mpc, mpcc_id, arr_reg_val, adjust->mpcc_gamut_remap_block_id, &mode_select);
+//
+// if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
+// adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+// return;
+// }
+//
+// adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+// convert_hw_matrix(adjust->temperature_matrix,
+// arr_reg_val, ARRAY_SIZE(arr_reg_val));
+//}
+
void mpc42_read_mpcc_state(
struct mpc *mpc,
int mpcc_inst,
@@ -755,7 +1071,14 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc401_program_lut_read_write_control,
.program_lut_mode = mpc401_program_lut_mode,
- .get_lut_mode = mpc401_get_lut_mode,
+ .mcm = {
+ .program_lut_read_write_control = mpc42_program_lut_read_write_control,
+ .program_3dlut_size = mpc42_program_3dlut_size,
+ .program_bias_scale = mpc42_program_3dlut_fl_bias_scale,
+ .program_bit_depth = mpc42_program_bit_depth,
+ .is_config_supported = mpc42_is_config_supported,
+ .populate_lut = mpc42_populate_lut,
+ },
.rmcm = {
.enable_3dlut_fl = mpc42_enable_3dlut_fl,
.update_3dlut_fast_load_select = mpc42_update_3dlut_fast_load_select,
@@ -764,6 +1087,7 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
.program_3dlut_size = mpc42_program_rmcm_3dlut_size,
.program_bias_scale = mpc42_program_rmcm_3dlut_fast_load_bias_scale,
.program_bit_depth = mpc42_program_rmcm_bit_depth,
+ .is_config_supported = mpc42_is_rmcm_config_supported,
.power_on_shaper_3dlut = mpc42_power_on_rmcm_shaper_3dlut,
.populate_lut = mpc42_populate_rmcm_lut,
.fl_3dlut_configure = mpc42_set_fl_config,
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
index a5f7f4f2bb3b..12a12c28e553 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
@@ -884,6 +884,49 @@ void dcn42_mpc_construct(struct dcn42_mpc *mpc401,
void mpc42_init_mpcc(struct mpcc *mpcc, int mpcc_inst);
+void mpc42_program_shaper_lutb_settings(
+ struct mpc *mpc,
+ const struct pwl_params *params,
+ uint32_t mpcc_id);
+void mpc42_program_shaper_luta_settings(
+ struct mpc *mpc,
+ const struct pwl_params *params,
+ uint32_t mpcc_id);
+void mpc42_configure_shaper_lut(
+ struct mpc *mpc,
+ bool is_ram_a,
+ uint32_t mpcc_id);
+void mpc42_power_on_shaper_3dlut(
+ struct mpc *mpc,
+ uint32_t mpcc_id,
+ bool power_on);
+void mpc42_program_3dlut_size(
+ struct mpc *mpc,
+ uint32_t width,
+ int mpcc_id);
+void mpc42_program_3dlut_fl_bias_scale(
+ struct mpc *mpc,
+ uint16_t bias,
+ uint16_t scale,
+ int mpcc_id);
+void mpc42_program_bit_depth(
+ struct mpc *mpc,
+ uint16_t bit_depth,
+ int mpcc_id);
+void mpc42_populate_lut(
+ struct mpc *mpc,
+ const union mcm_lut_params params,
+ bool lut_bank_a,
+ int mpcc_id);
+void mpc42_program_lut_read_write_control(
+ struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ bool lut_bank_a,
+ bool enabled,
+ int mpcc_id);
+
+bool mpc42_is_config_supported(uint32_t width);
+
/* RMCM */
void mpc42_program_rmcm_shaper_lut(
struct mpc *mpc,
@@ -927,12 +970,12 @@ void mpc42_program_rmcm_lut_read_write_control(
int mpcc_id);
void mpc42_program_lut_mode(
struct mpc *mpc,
- bool enable,
+ const enum MCM_LUT_XABLE xable,
bool lut_bank_a,
int mpcc_id);
void mpc42_program_rmcm_3dlut_size(
struct mpc *mpc,
- const enum dc_cm_lut_size size,
+ uint32_t width,
int mpcc_id);
void mpc42_program_rmcm_3dlut_fast_load_bias_scale(
struct mpc *mpc,
@@ -944,6 +987,8 @@ void mpc42_program_rmcm_bit_depth(
uint16_t bit_depth,
int mpcc_id);
+bool mpc42_is_rmcm_config_supported(uint32_t width);
+
void mpc42_set_fl_config(
struct mpc *mpc,
struct mpc_fl_3dlut_config *cfg,
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
index c0d37f00fed9..2c1f72cf1a63 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
@@ -666,7 +666,6 @@ static const struct resource_caps res_cap_dcn42 = {
.num_vmid = 16,
.num_mpc_3dlut = 2,
.num_dsc = 4,
- .num_rmcm = 2,
};
static const struct dc_plane_cap plane_cap = {
diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
index 00473c6284d5..614db22d62f3 100644
--- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
+++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
@@ -502,6 +502,8 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
*
* @stream: contains data we may need to construct VSIF (i.e. timing_3d_format, etc.)
* @info_packet: output structure where to store VSIF
+ * @ALLMEnabled: indicates whether ALLM HF-VSIF should be generated
+ * @ALLMValue: ALLM bit value to advertise in HF-VSIF
*/
void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
struct dc_info_packet *info_packet)
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 736304e73ca4..952391aecf2d 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -244,6 +244,10 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev,
enum amd_pm_state_type state;
int ret;
+ /* Reject empty/whitespace strings - fuzzing found this is not validated */
+ if (count == 0 || sysfs_streq(buf, ""))
+ return -EINVAL;
+
if (sysfs_streq(buf, "battery"))
state = POWER_STATE_TYPE_BATTERY;
else if (sysfs_streq(buf, "balanced"))
@@ -364,6 +368,10 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev,
enum amd_dpm_forced_level level;
int ret = 0;
+ /* Reject empty/whitespace strings - fuzzing found this is not validated */
+ if (count == 0 || sysfs_streq(buf, ""))
+ return -EINVAL;
+
if (sysfs_streq(buf, "low"))
level = AMD_DPM_FORCED_LEVEL_LOW;
else if (sysfs_streq(buf, "high"))
@@ -902,6 +910,10 @@ static ssize_t amdgpu_set_pp_features(struct device *dev,
uint64_t featuremask;
int ret;
+ /* Reject empty/whitespace strings - fuzzing found kstrtou64 accepts "" as 0 */
+ if (count == 0 || sysfs_streq(buf, ""))
+ return -EINVAL;
+
ret = kstrtou64(buf, 0, &featuremask);
if (ret)
return -EINVAL;
@@ -1027,6 +1039,10 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask)
*mask = 0;
+ /* Reject empty/whitespace strings - fuzzing found this is not validated */
+ if (count == 0 || sysfs_streq(buf, ""))
+ return -EINVAL;
+
bytes = min(count, sizeof(buf_cpy) - 1);
memcpy(buf_cpy, buf, bytes);
buf_cpy[bytes] = '\0';
@@ -1378,6 +1394,10 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
long int profile_mode = 0;
const char delimiter[3] = {' ', '\n', '\0'};
+ /* Reject empty/whitespace strings - fuzzing found this is not validated */
+ if (count == 0 || sysfs_streq(buf, ""))
+ return -EINVAL;
+
tmp[0] = *(buf);
tmp[1] = '\0';
ret = kstrtol(tmp, 0, &profile_mode);
@@ -2505,12 +2525,12 @@ static ssize_t amdgpu_set_pm_policy_attr(struct device *dev,
.dev_attr = __ATTR(_name, 0644, amdgpu_get_pm_policy_attr, \
amdgpu_set_pm_policy_attr), \
.id = PP_PM_POLICY_##_id, \
- };
+ }
#define AMDGPU_PM_POLICY_ATTR_VAR(_name) pm_policy_attr_##_name.dev_attr.attr
-AMDGPU_PM_POLICY_ATTR(soc_pstate, SOC_PSTATE)
-AMDGPU_PM_POLICY_ATTR(xgmi_plpd, XGMI_PLPD)
+AMDGPU_PM_POLICY_ATTR(soc_pstate, SOC_PSTATE);
+AMDGPU_PM_POLICY_ATTR(xgmi_plpd, XGMI_PLPD);
static struct attribute *pm_policy_attrs[] = {
&AMDGPU_PM_POLICY_ATTR_VAR(soc_pstate),