[PATCH 1/2] drm/amd/pm: Fix warn: missing error code in smu_v13_0_0_check_ecc_table_support()

2023-09-25 Thread Cong Liu
This patch fixes a smatch warning:

drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu13/smu_v13_0_0_ppt.c:2868
smu_v13_0_0_check_ecc_table_support() warn: missing error code? 'ret'

This warning is caused by the fact that this function returns the value of
the variable ret. However, the value of ret is not explicitly set in the
function. This patch fixes the warning by explicitly setting the value of
ret to 0 if the device is supported

Signed-off-by: Cong Liu 
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 9ac2be5627d9..cf832cef2b0a 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2863,11 +2863,11 @@ static int smu_v13_0_0_check_ecc_table_support(struct 
smu_context *smu)
if (ret)
return -EOPNOTSUPP;
 
-   if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)) &&
-   (smu_version >= SUPPORT_ECCTABLE_SMU_13_0_10_VERSION))
-   return ret;
-   else
+   if ((adev->ip_versions[MP1_HWIP][0] != IP_VERSION(13, 0, 10)) &&
+   (smu_version < SUPPORT_ECCTABLE_SMU_13_0_10_VERSION))
return -EOPNOTSUPP;
+
+   return 0;
 }
 
 static ssize_t smu_v13_0_0_get_ecc_info(struct smu_context *smu,
-- 
2.34.1



[PATCH 2/2] drm/amd/display: Fix null pointer dereference in error message

2023-09-25 Thread Cong Liu
This patch fixes a null pointer dereference in the error message that is
printed when the Display Core (DC) fails to initialize. The original
message includes the DC version number, which is undefined if the DC is
not initialized.

Fixes: 9788d087caff ("drm/amd/display: improve the message printed when loading 
DC")
Signed-off-by: Cong Liu 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

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 8e98dda1e084..bf52a909f558 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1703,8 +1703,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
DRM_INFO("Display Core v%s initialized on %s\n", DC_VER,
 dce_version_to_string(adev->dm.dc->ctx->dce_version));
} else {
-   DRM_INFO("Display Core v%s failed to initialize on %s\n", 
DC_VER,
-dce_version_to_string(adev->dm.dc->ctx->dce_version));
+   DRM_INFO("Display Core failed to initialize with v%s!\n", 
DC_VER);
goto error;
}
 
-- 
2.34.1



[PATCH 3/2] accel/ivpu: Use local variable for debugfs root

2023-09-25 Thread Stanislaw Gruszka
Use local variable for debugfs root, just to make further changes
easier.

Signed-off-by: Stanislaw Gruszka 
---

I'll squash that patch into patch 1

 drivers/accel/ivpu/ivpu_debugfs.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/accel/ivpu/ivpu_debugfs.c 
b/drivers/accel/ivpu/ivpu_debugfs.c
index 9163bc6bd3ef..ea453b985b49 100644
--- a/drivers/accel/ivpu/ivpu_debugfs.c
+++ b/drivers/accel/ivpu/ivpu_debugfs.c
@@ -273,20 +273,22 @@ static const struct file_operations 
ivpu_reset_engine_fops = {
 
 void ivpu_debugfs_init(struct ivpu_device *vdev)
 {
+   struct dentry *debugfs_root = vdev->drm.debugfs_root;
+
drm_debugfs_add_files(>drm, vdev_debugfs_list, 
ARRAY_SIZE(vdev_debugfs_list));
 
-   debugfs_create_file("force_recovery", 0200, vdev->drm.debugfs_root, 
vdev,
+   debugfs_create_file("force_recovery", 0200, debugfs_root, vdev,
_force_recovery_fops);
 
-   debugfs_create_file("fw_log", 0644, vdev->drm.debugfs_root, vdev,
+   debugfs_create_file("fw_log", 0644, debugfs_root, vdev,
_log_fops);
-   debugfs_create_file("fw_trace_destination_mask", 0200, 
vdev->drm.debugfs_root, vdev,
+   debugfs_create_file("fw_trace_destination_mask", 0200, debugfs_root, 
vdev,
_trace_destination_mask_fops);
-   debugfs_create_file("fw_trace_hw_comp_mask", 0200, 
vdev->drm.debugfs_root, vdev,
+   debugfs_create_file("fw_trace_hw_comp_mask", 0200, debugfs_root, vdev,
_trace_hw_comp_mask_fops);
-   debugfs_create_file("fw_trace_level", 0200, vdev->drm.debugfs_root, 
vdev,
+   debugfs_create_file("fw_trace_level", 0200, debugfs_root, vdev,
_trace_level_fops);
 
-   debugfs_create_file("reset_engine", 0200, vdev->drm.debugfs_root, vdev,
+   debugfs_create_file("reset_engine", 0200, debugfs_root, vdev,
_reset_engine_fops);
 }
-- 
2.25.1



linux-next: build warning after merge of the drm-misc tree

2023-09-25 Thread Stephen Rothwell
Hi all,

After merging the drm-misc tree, today's linux-next build (htmldocs)
produced this warning:

Error: Cannot open file /home/sfr/next/next/drivers/gpu/drm/drm_gpuva_mgr.c
Error: Cannot open file /home/sfr/next/next/include/drm/drm_gpuva_mgr.h

Introduced by commit

  f72c2db47080 ("drm/gpuvm: rename struct drm_gpuva_manager to struct 
drm_gpuvm")

-- 
Cheers,
Stephen Rothwell


pgpwjFOflpFGs.pgp
Description: OpenPGP digital signature


Re: [PATCH v17 10/18] drm/shmem-helper: Use refcount_t for vmap_use_count

2023-09-25 Thread kernel test robot



Hello,

kernel test robot noticed 
"WARNING:at_drivers/gpu/drm/drm_fbdev_generic.c:#drm_fbdev_generic_helper_fb_dirty"
 on:

commit: e5f31d1a2da5d43187a0e1fc4d1882982ab0d9b8 ("[PATCH v17 10/18] 
drm/shmem-helper: Use refcount_t for vmap_use_count")
url: 
https://github.com/intel-lab-lkp/linux/commits/Dmitry-Osipenko/drm-gem-Change-locked-unlocked-postfix-of-drm_gem_v-unmap-function-names/20230915-073105
base: git://anongit.freedesktop.org/drm/drm drm-next
patch link: 
https://lore.kernel.org/all/20230914232721.408581-11-dmitry.osipe...@collabora.com/
patch subject: [PATCH v17 10/18] drm/shmem-helper: Use refcount_t for 
vmap_use_count

in testcase: rcuscale
version: 
with following parameters:

runtime: 300s
scale_type: tasks



compiler: gcc-11
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)



If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-lkp/202309261238.bce3ce91-oliver.s...@intel.com


[   23.102568][T8] [ cut here ]
[   23.102576][T8] platform vkms: Damage blitter failed: ret=-12
[ 23.102605][ T8] WARNING: CPU: 0 PID: 8 at 
drivers/gpu/drm/drm_fbdev_generic.c:226 drm_fbdev_generic_helper_fb_dirty 
(drivers/gpu/drm/drm_fbdev_generic.c:226) 
[   23.102614][T8] Modules linked in:
[   23.102619][T8] CPU: 0 PID: 8 Comm: kworker/0:0 Tainted: G   
  N 6.6.0-rc1-00010-ge5f31d1a2da5 #1 debbcfa26ac7594ab4e1fde44696b4efa3ea485a
[   23.102624][T8] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), 
BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   23.102627][T8] Workqueue: events drm_fb_helper_damage_work
[ 23.102631][ T8] EIP: drm_fbdev_generic_helper_fb_dirty 
(drivers/gpu/drm/drm_fbdev_generic.c:226) 
[ 23.102633][ T8] Code: 05 a8 49 81 c2 01 8b 40 08 8b 58 2c 85 db 75 02 8b 18 
89 55 e0 e8 90 7a 04 00 8b 55 e0 52 53 50 68 d4 41 28 c2 e8 74 68 a5 ff <0f> 0b 
8b 55 e0 83 c4 10 e9 7b ff ff ff 8d 76 00 8b 45 e4 8b 55 e8
All code

   0:   05 a8 49 81 c2  add$0xc28149a8,%eax
   5:   01 8b 40 08 8b 58   add%ecx,0x588b0840(%rbx)
   b:   2c 85   sub$0x85,%al
   d:   db 75 02(bad)  0x2(%rbp)
  10:   8b 18   mov(%rax),%ebx
  12:   89 55 e0mov%edx,-0x20(%rbp)
  15:   e8 90 7a 04 00  call   0x47aaa
  1a:   8b 55 e0mov-0x20(%rbp),%edx
  1d:   52  push   %rdx
  1e:   53  push   %rbx
  1f:   50  push   %rax
  20:   68 d4 41 28 c2  push   $0xc22841d4
  25:   e8 74 68 a5 ff  call   0xffa5689e
  2a:*  0f 0b   ud2 <-- trapping instruction
  2c:   8b 55 e0mov-0x20(%rbp),%edx
  2f:   83 c4 10add$0x10,%esp
  32:   e9 7b ff ff ff  jmp0xffb2
  37:   8d 76 00lea0x0(%rsi),%esi
  3a:   8b 45 e4mov-0x1c(%rbp),%eax
  3d:   8b 55 e8mov-0x18(%rbp),%edx

Code starting with the faulting instruction
===
   0:   0f 0b   ud2
   2:   8b 55 e0mov-0x20(%rbp),%edx
   5:   83 c4 10add$0x10,%esp
   8:   e9 7b ff ff ff  jmp0xff88
   d:   8d 76 00lea0x0(%rsi),%esi
  10:   8b 45 e4mov-0x1c(%rbp),%eax
  13:   8b 55 e8mov-0x18(%rbp),%edx
[   23.102636][T8] EAX:  EBX: ee027ab0 ECX:  EDX: 
[   23.102638][T8] ESI: c624b600 EDI: c624b738 EBP: c3585ef8 ESP: c3585ec4
[   23.102640][T8] DS: 007b ES: 007b FS: 00d8 GS:  SS: 0068 EFLAGS: 
00010246
[   23.102647][T8] CR0: 80050033 CR2: ffd3a000 CR3: 0295e000 CR4: 00040690
[   23.102649][T8] DR0:  DR1:  DR2:  DR3: 
[   23.102651][T8] DR6: fffe0ff0 DR7: 0400
[   23.102653][T8] Call Trace:
[ 23.102656][ T8] ? show_regs (arch/x86/kernel/dumpstack.c:479 
arch/x86/kernel/dumpstack.c:465) 
[ 23.102661][ T8] ? drm_fbdev_generic_helper_fb_dirty 
(drivers/gpu/drm/drm_fbdev_generic.c:226) 
[ 23.102664][ T8] ? __warn (kernel/panic.c:673) 
[ 23.102668][ T8] ? drm_fbdev_generic_helper_fb_dirty 
(drivers/gpu/drm/drm_fbdev_generic.c:226) 
[ 23.102670][ T8] ? report_bug (lib/bug.c:201 lib/bug.c:219) 
[ 23.102677][ T8] ? exc_overflow (arch/x86/kernel/traps.c:250) 
[ 23.102681][ T8] ? handle_bug (arch/x86/kernel/traps.c:216) 
[ 23.102685][ T8] ? exc_invalid_op (arch/x86/kernel/traps.c:258 (discriminator 
1)) 
[ 23.102689][ T8] ? handle_exception (arch/x86/entry/entry_32.S:1056) 
[ 23.102701][ T8] ? exc_overflow (arch/x86/kernel/traps.c:250) 
[ 23.102704][ T8] ? 

[PATCH] drm/ttm: Make sure the mapped tt pages are decrypted when needed

2023-09-25 Thread Zack Rusin
From: Zack Rusin 

Some drivers require the mapped tt pages to be decrypted. In an ideal
world this would have been handled by the dma layer, but the TTM page
fault handling would have to be rewritten to able to do that.

A side-effect of the TTM page fault handling is using a dma allocation
per order (via ttm_pool_alloc_page) which makes it impossible to just
trivially use dma_mmap_attrs. As a result ttm has to be very careful
about trying to make its pgprot for the mapped tt pages match what
the dma layer thinks it is. At the ttm layer it's possible to
deduce the requirement to have tt pages decrypted by checking
whether coherent dma allocations have been requested and the system
is running with confidential computing technologies.

This approach isn't ideal but keeping TTM matching DMAs expectations
for the page properties is in general fragile, unfortunately proper
fix would require a rewrite of TTM's page fault handling.

Fixes vmwgfx with SEV enabled.

Signed-off-by: Zack Rusin 
Fixes: 3bf3710e3718 ("drm/ttm: Add a generic TTM memcpy move for page-based 
iomem")
Cc: Christian König 
Cc: Thomas Hellström 
Cc: Huang Rui 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Cc:  # v5.14+
---
 drivers/gpu/drm/ttm/ttm_bo_util.c | 13 +++--
 drivers/gpu/drm/ttm/ttm_tt.c  |  7 +++
 include/drm/ttm/ttm_tt.h  |  9 -
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c 
b/drivers/gpu/drm/ttm/ttm_bo_util.c
index fd9fd3d15101..0b3f4267130c 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -294,7 +294,13 @@ pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct 
ttm_resource *res,
enum ttm_caching caching;
 
man = ttm_manager_type(bo->bdev, res->mem_type);
-   caching = man->use_tt ? bo->ttm->caching : res->bus.caching;
+   if (man->use_tt) {
+   caching = bo->ttm->caching;
+   if (bo->ttm->page_flags & TTM_TT_FLAG_DECRYPTED)
+   tmp = pgprot_decrypted(tmp);
+   } else  {
+   caching = res->bus.caching;
+   }
 
return ttm_prot_from_caching(caching, tmp);
 }
@@ -337,6 +343,8 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
.no_wait_gpu = false
};
struct ttm_tt *ttm = bo->ttm;
+   struct ttm_resource_manager *man =
+   ttm_manager_type(bo->bdev, bo->resource->mem_type);
pgprot_t prot;
int ret;
 
@@ -346,7 +354,8 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
if (ret)
return ret;
 
-   if (num_pages == 1 && ttm->caching == ttm_cached) {
+   if (num_pages == 1 && ttm->caching == ttm_cached &&
+   !(man->use_tt && (ttm->page_flags & TTM_TT_FLAG_DECRYPTED))) {
/*
 * We're mapping a single page, and the desired
 * page protection is consistent with the bo.
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index e0a77671edd6..02dcb728e29c 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -81,6 +81,13 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool 
zero_alloc)
pr_err("Illegal buffer object type\n");
return -EINVAL;
}
+   /*
+* When using dma_alloc_coherent with memory encryption the
+* mapped TT pages need to be decrypted or otherwise the drivers
+* will end up sending encrypted mem to the gpu.
+*/
+   if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+   page_flags |= TTM_TT_FLAG_DECRYPTED;
 
bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags);
if (unlikely(bo->ttm == NULL))
diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h
index a4eff85b1f44..2b9d856ff388 100644
--- a/include/drm/ttm/ttm_tt.h
+++ b/include/drm/ttm/ttm_tt.h
@@ -79,6 +79,12 @@ struct ttm_tt {
 *   page_flags = TTM_TT_FLAG_EXTERNAL |
 *TTM_TT_FLAG_EXTERNAL_MAPPABLE;
 *
+* TTM_TT_FLAG_DECRYPTED: The mapped ttm pages should be marked as
+* not encrypted. The framework will try to match what the dma layer
+* is doing, but note that it is a little fragile because ttm page
+* fault handling abuses the DMA api a bit and dma_map_attrs can't be
+* used to assure pgprot always matches.
+*
 * TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. This is
 * set by TTM after ttm_tt_populate() has successfully returned, and is
 * then unset when TTM calls ttm_tt_unpopulate().
@@ -87,8 +93,9 @@ struct ttm_tt {
 #define TTM_TT_FLAG_ZERO_ALLOC BIT(1)
 #define TTM_TT_FLAG_EXTERNAL   BIT(2)
 #define TTM_TT_FLAG_EXTERNAL_MAPPABLE  BIT(3)
+#define TTM_TT_FLAG_DECRYPTED  BIT(4)
 
-#define TTM_TT_FLAG_PRIV_POPULATED BIT(4)

RE: [PATCH v14 RESEND 5/6] drm/imx: Introduce i.MX8qm/qxp DPU DRM

2023-09-25 Thread Ying Liu
On Tuesday, September 5, 2023 4:37 PM, Maxime Ripard  wrote:
> On Tue, Sep 05, 2023 at 03:32:47AM +, Ying Liu wrote:
> > > On Tue, Aug 22, 2023 at 04:59:48PM +0800, Liu Ying wrote:
> > > > +int dpu_cf_init(struct dpu_soc *dpu, unsigned int index,
> > > > +   unsigned int id, enum dpu_unit_type type,
> > > > +   unsigned long pec_base, unsigned long base)
> > > > +{
> > > > +   struct dpu_constframe *cf;
> > > > +
> > > > +   cf = devm_kzalloc(dpu->dev, sizeof(*cf), GFP_KERNEL);
> > > > +   if (!cf)
> > > > +   return -ENOMEM;
> > > > +
> > > > +   dpu->cf_priv[index] = cf;
> > >
> > > You can't store structures related to KMS in a device managed structure.
> > > The DRM KMS device will stick around (and be accessible from userspace)
> > > after the device has been removed until the last application closed its
> > > file descriptor to the device.
> >
> > The DRM device is registered after component_bind_all() is called in
> > dpu_drm_bind().  The CRTC components' platform devices are created
> > in the dpu_core_probe() where the device managed resources are
> > created.   So, it looks those resources are safe because the DRM device
> > will be unregistered before those resources are freed.
> 
> Not, it's not, because the KMS device isn't freed when devices will be
> unbound/removed, but when the last application closes its fd to it, and
> so you'll get dangling pointers.
> 
> The general rule to get it right is to use drmm for anything but device
> resources (like clocks, regulators, memory mapping, etc.). You can
> deviate from the rule, of course, but you'll need a long and clear
> explanation on why it doesn't work, and why your new approach works.
> Your current approach doesn't though.

I'll try to follow the rule in next version. Will call drmm_kzalloc() instead of
devm_kzalloc() here.

> 
> > > This can be checked by enabling KASAN and manually unbinding the
> driver
> > > through sysfs.
> >
> > I enabled KASAN and manually unbound the dpu-core driver with
> command:
> >
> > echo 5618.dpu > /sys/bus/platform/drivers/dpu-
> core/5618.dpu/driver/unbind
> >
> > KASAN didin't report memory issue regarding those device managed
> > resources.  However, it did report another issue in dpu_drm_unbind(),
> > where drm_device should be got from drv_data->drm_dev instead of
> > dev_get_drvdata(dev).  I'll fix that in next version.
> >
> > BTW, the dpu-core driver was successfully bound again after unbinding
> with
> > command:
> >
> > echo  5618.dpu > /sys/bus/platform/drivers/dpu-core/bind
> 
> Guess you're lucky. That doesn't make it safe or right.
> 
> > > > +   cf->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_16);
> > > > +   if (!cf->pec_base)
> > > > +   return -ENOMEM;
> > > > +
> > > > +   cf->base = devm_ioremap(dpu->dev, base, SZ_32);
> > > > +   if (!cf->base)
> > > > +   return -ENOMEM;
> > >
> > > For the same reason, you need to protect any access to a device managed
> > > resource (so clocks, registers, regulators, etc.) by a call to
> > > drm_dev_enter/drm_dev_exit and you need to call drm_dev_unplug
> instead
> > > of drm_dev_unregister.
> >
> > That's a good point. I've tried to do that, but it turns out that the
> > display controller cannot be enabled again after binding the dpu-core
> > driver manually again. It seems that the display controller requires a
> > proper disablement procedure, but the "driver instance overview " kdoc
> > mentions the shortcoming of no proper disablement if drm_dev_unplug()
> > is used:
> >
> > """
> > * Drivers that want to support device unplugging (USB, DT overlay unload)
> should
> >  * use drm_dev_unplug() instead of drm_dev_unregister(). The driver must
> protect
> >  * regions that is accessing device resources to prevent use after they're
> >  * released. This is done using drm_dev_enter() and drm_dev_exit(). There
> is one
> >  * shortcoming however, drm_dev_unplug() marks the drm_device as
> unplugged before
> >  * drm_atomic_helper_shutdown() is called. This means that if the disable
> code
> >  * paths are protected, they will not run on regular driver module unload,
> >  * possibly leaving the hardware enabled.
> > """
> >
> > A DPU reset in dpu_core() might be helpful, but I'm not sure if there is any
> > reset line provided by the embodying system.
> 
> Generally speaking, you shouldn't rely on the device being in any
> particuliar state before your driver loads. So a reset at probe/bind
> time is a good idea.

Yes. I'll drop the platform device creations for CRTCs from dpu-core.c 
and drop the aggregation of CRTC components from different DPU
instances into one DRM device.  This way, there will be only two CRTCs
of one DPU in one DRM device. Then, the driver will be simpler and
users cannot unbind the driver of one of the two DPU instances, which
means drm_dev_unplug() won't be needed any more(?) and the reset
issue will be gone.  The 

Re: [PATCH v3] drm/i915/gem: Make i915_gem_shrinker multi-gt aware

2023-09-25 Thread kernel test robot
Hi Nirmoy,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on drm-intel/for-linux-next-fixes drm-tip/drm-tip 
drm/drm-next drm-exynos/exynos-drm-next drm-misc/drm-misc-next linus/master 
v6.6-rc3 next-20230925]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Nirmoy-Das/drm-i915-gem-Make-i915_gem_shrinker-multi-gt-aware/20230926-020533
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
patch link:
https://lore.kernel.org/r/20230925171048.19245-1-nirmoy.das%40intel.com
patch subject: [PATCH v3] drm/i915/gem: Make i915_gem_shrinker multi-gt aware
config: i386-randconfig-016-20230926 
(https://download.01.org/0day-ci/archive/20230926/202309261109.t06eiy08-...@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20230926/202309261109.t06eiy08-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202309261109.t06eiy08-...@intel.com/

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/gem/i915_gem_shrinker.c: In function 'i915_gem_shrink':
>> drivers/gpu/drm/i915/gem/i915_gem_shrinker.c:152:12: error: suggest explicit 
>> braces to avoid ambiguous 'else' [-Werror=dangling-else]
 152 | if (shrink & I915_SHRINK_ACTIVE)
 |^
   cc1: all warnings being treated as errors


vim +/else +152 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c

2d6692e642e7ca drivers/gpu/drm/i915/i915_gem_shrinker.c Chris Wilson
   2019-04-20   75  
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   76  /**
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   77   * i915_gem_shrink - Shrink buffer object caches
772f7bb75dffd4 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c Maarten Lankhorst   
   2021-04-21   78   * @ww: i915 gem ww acquire ctx, or NULL
56fa4bf2b2f084 drivers/gpu/drm/i915/i915_gem_shrinker.c Chris Wilson
   2017-11-23   79   * @i915: i915 device
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   80   * @target: amount of memory to make available, in pages
912d572d63b8cd drivers/gpu/drm/i915/i915_gem_shrinker.c Chris Wilson
   2017-09-06   81   * @nr_scanned: optional output for number of pages scanned 
(incremental)
70972f51819a22 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c Chris Wilson
   2019-06-12   82   * @shrink: control flags for selecting cache types
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   83   *
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   84   * This function is the main interface to the shrinker. It 
will try to release
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   85   * up to @target pages of main memory backing storage from 
buffer objects.
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   86   * Selection of the specific caches can be done with 
@flags. This is e.g. useful
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   87   * when purgeable objects should be removed from caches 
preferentially.
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   88   *
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   89   * Note that it's not guaranteed that released amount is 
actually available as
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   90   * free system memory - the pages might still be in-used to 
due to other reasons
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   91   * (like cpu mmaps) or the mm core has reused them before 
we could grab them.
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   92   * Therefore code that needs to explicitly shrink buffer 
objects caches (e.g. to
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   93   * avoid deadlocks in memory reclaim) must fall back to 
i915_gem_shrink_all().
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrinker.c Daniel Vetter   
   2015-03-18   94   *
eb0b44adc08c0b drivers/gpu/drm/i915/i915_gem_shrink

Re: [PATCH 07/15] mailbox: mediatek: Add loop pkt flag and irq handling for loop command

2023-09-25 Thread 林睿祥


Re: [PATCH] drm/i915/gem: Allow users to disable waitboost

2023-09-25 Thread kernel test robot



Hello,

kernel test robot noticed a -3.2% regression of 
phoronix-test-suite.paraview.WaveletContour.1024x768.mipolys___sec on:


commit: 54fef7ea35dadd66193b98805b0bc42ef2b279db ("[PATCH] drm/i915/gem: Allow 
users to disable waitboost")
url: 
https://github.com/intel-lab-lkp/linux/commits/Vinay-Belgaumkar/drm-i915-gem-Allow-users-to-disable-waitboost/20230921-060357
base: git://anongit.freedesktop.org/drm-intel for-linux-next
patch link: 
https://lore.kernel.org/all/20230920215624.3482244-1-vinay.belgaum...@intel.com/
patch subject: [PATCH] drm/i915/gem: Allow users to disable waitboost

testcase: phoronix-test-suite
test machine: 12 threads 1 sockets Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz 
(Coffee Lake) with 32G memory
parameters:

need_x: true
test: paraview-1.0.2
option_a: Wavelet Contour
option_b: 1024 x 768
cpufreq_governor: performance


In addition to that, the commit also has significant impact on the following 
tests:

+--++
| testcase: change | phoronix-test-suite: 
phoronix-test-suite.x11perf.PutImageXY500x500Square.operations___second 12.8% 
improvement |
| test machine | 12 threads 1 sockets Intel(R) Core(TM) i7-8700 CPU @ 
3.20GHz (Coffee Lake) with 32G memory |
| test parameters  | cpufreq_governor=performance   
|
|  | need_x=true
|
|  | option_a=PutImage XY 500x500 Square
|
|  | test=x11perf-1.1.1 
|
+--++
| testcase: change | phoronix-test-suite: 
phoronix-test-suite.openarena.2560x1440.milliseconds -12.2% regression  
  |
| test machine | 12 threads 1 sockets Intel(R) Core(TM) i7-8700 CPU @ 
3.20GHz (Coffee Lake) with 32G memory |
| test parameters  | cpufreq_governor=performance   
|
|  | need_x=true
|
|  | option_a=2560 x 1440   
|
|  | test=openarena-1.5.5   
|
+--++


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-lkp/202309261055.b74df987-oliver.s...@intel.com


Details are as below:
-->


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20230926/202309261055.b74df987-oliver.s...@intel.com

=
compiler/cpufreq_governor/kconfig/need_x/option_a/option_b/rootfs/tbox_group/test/testcase:
  gcc-12/performance/x86_64-rhel-8.3/true/Wavelet Contour/1024 x 
768/debian-x86_64-phoronix/lkp-cfl-d2/paraview-1.0.2/phoronix-test-suite

commit: 
  16a9359401 ("drm/i915: Implement transcoder LRR for TGL+")
  54fef7ea35 ("drm/i915/gem: Allow users to disable waitboost")

16a9359401edcbc0 54fef7ea35dadd66193b98805b0 
 --- 
 %stddev %change %stddev
 \  |\  
  0.05 ±  4%  +0.00.06 ±  2%  mpstat.cpu.all.soft%
 66.17 ± 60%+145.6% 162.50 ± 33%  turbostat.C10
 28.61-3.3%  27.68
phoronix-test-suite.paraview.WaveletContour.1024x768.frames___sec
298.15-3.2% 288.49
phoronix-test-suite.paraview.WaveletContour.1024x768.mipolys___sec
535005+8.6% 580810
phoronix-test-suite.time.minor_page_faults
  6278+8.3%   6797
phoronix-test-suite.time.voluntary_context_switches
801166+5.6% 845675proc-vmstat.numa_hit
799382+5.1% 840353proc-vmstat.numa_local
 59648+2.6%  61211proc-vmstat.pgactivate
   1539307+2.7%1580759

Re: [PATCH 02/15] dt-bindings: gce: mt8195: Add CMDQ_SYNC_TOKEN_SECURE_THR_EOF event id

2023-09-25 Thread 林睿祥


[PATCH] MAINTAINERS: update nouveau maintainers

2023-09-25 Thread Danilo Krummrich
Since I will continue to work on Nouveau consistently, also beyond my
former and still ongoing VM_BIND/EXEC work, add myself to the list of
Nouveau maintainers.

Signed-off-by: Danilo Krummrich 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b19995690904..67ce91c8778a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6647,6 +6647,7 @@ F:drivers/gpu/drm/panel/panel-novatek-nt36672a.c
 DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
 M: Karol Herbst 
 M: Lyude Paul 
+M: Danilo Krummrich 
 L: dri-devel@lists.freedesktop.org
 L: nouv...@lists.freedesktop.org
 S: Supported
-- 
2.41.0



Re: [PATCH 3/6] dt-bindings: display: msm: Add SDM670 MDSS

2023-09-25 Thread Rob Herring


On Mon, 25 Sep 2023 19:26:30 -0400, Richard Acayan wrote:
> Add documentation for the SDM670 display subsystem, adapted from the
> SDM845 and SM6125 documentation.
> 
> Signed-off-by: Richard Acayan 
> ---
>  .../display/msm/qcom,sdm670-mdss.yaml | 280 ++
>  1 file changed, 280 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.example.dts:198.43-200.27:
 Warning (graph_endpoint): 
/example-0/display-subsystem@ae0/dsi@ae96000/ports/port@0/endpoint: graph 
connection to node 
'/example-0/display-subsystem@ae0/display-controller@ae01000/ports/port@1/endpoint'
 is not bidirectional

doc reference errors (make refcheckdocs):

See 
https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230925232625.84-12-mailingrad...@gmail.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



Re: [PATCH v17 13/18] drm/shmem-helper: Add memory shrinker

2023-09-25 Thread Dmitry Osipenko
On 9/15/23 11:46, Boris Brezillon wrote:
>> -static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object 
>> *shmem)
>> +static int
>> +drm_gem_shmem_acquire_pages(struct drm_gem_shmem_object *shmem, bool init)
>>  {
>>  struct drm_gem_object *obj = >base;
>>  struct page **pages;
>>  
>>  dma_resv_assert_held(shmem->base.resv);
>>  
>> -if (refcount_inc_not_zero(>pages_use_count))
>> +if (shmem->madv < 0) {
>> +drm_WARN_ON(obj->dev, shmem->pages);
>> +return -ENOMEM;
>> +}
>> +
>> +if (shmem->pages) {
>> +drm_WARN_ON(obj->dev, !shmem->evicted);
>>  return 0;
>> +}
>> +
>> +if (drm_WARN_ON(obj->dev, !(init ^ 
>> refcount_read(>pages_use_count
>> +return -EINVAL;
> OOC, why do we care? Is there any difference between initial and re-pin
> that make the page allocation impossible? Feels like, if there's a
> check to do, it should be done in the caller instead, and you can drop
> the init param here.

This is a sanity check that addresses additional refcnt tracking
complexity imposed by shrinker.

This function is used by both init and re-pin that is invoked from
several places in the code. It's not trivial to move that check to the
callers.

-- 
Best regards,
Dmitry



Re: [PATCH v17 13/18] drm/shmem-helper: Add memory shrinker

2023-09-25 Thread Dmitry Osipenko
On 9/15/23 11:46, Boris Brezillon wrote:
> The naming becomes quite confusing, with drm_gem_shmem_unpin_locked()
> and drm_gem_shmem_unpin_pages_locked(). By the look of it, it seems to
> do exactly the opposite of drm_gem_shmem_swapin_locked(), except for
> the missing ->evicted = true, which we can move here anyway, given
> drm_gem_shmem_purge_locked() explicitly set it to false anyway. The
> other thing that's missing is the
> drm_gem_shmem_update_pages_state_locked(), but it can also be moved
> there I think, if the the ->madv update happens before the
> drm_gem_shmem_unpin_pages_locked() call in
> drm_gem_shmem_purge_locked().
> 
> So, how about renaming this function drm_gem_shmem_swapout_locked()?

The swapout name would be misleading to me because pages aren't moved to
swap, but allowed to be moved. I'll rename it to
drm_gem_shmem_shrinker_unpin_locked().

>>  {
>>  struct drm_gem_object *obj = >base;
>>  struct drm_device *dev = obj->dev;
>>  
>>  dma_resv_assert_held(shmem->base.resv);
>>  
>> -drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem));
>> +if (shmem->evicted)
>> +return;
>>  
>>  dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
> Are we sure we'll always have sgt != NULL? IIRC, if the GEM is only
> mmap-ed in userspace, get_sgt() is not necessarily called by the driver
> (needed to map in GPU space), and we have a potential NULL deref here.
> Maybe that changed at some point in the series, and sgt is
> unconditionally populated when get_pages() is called now.

The sgt is always set in this function because it's part of shrinker and
shrinker doesn't touch GEMs without sgt.

>> +__drm_gem_shmem_release_pages(shmem);
> Make sure you drop the implicit pages_use_count ref the sgt had, this
> way you can still tie the necessity to drop the pages to sgt != NULL in
> drm_gem_shmem_free().

This will require further refcnt re-initialization when pages are
restored if it's dropped to zero. I don't see how this will improve
anything.

-- 
Best regards,
Dmitry



[PATCH 4/6] drm/msm: mdss: add support for SDM670

2023-09-25 Thread Richard Acayan
Add support for the MDSS block on the SDM670 platform.

Signed-off-by: Richard Acayan 
---
 drivers/gpu/drm/msm/msm_mdss.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index 2e87dd6cb17b..2afb843271aa 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -551,6 +551,12 @@ static const struct msm_mdss_data sc8280xp_data = {
.macrotile_mode = 1,
 };
 
+static const struct msm_mdss_data sdm670_data = {
+   .ubwc_enc_version = UBWC_2_0,
+   .ubwc_dec_version = UBWC_2_0,
+   .highest_bank_bit = 1,
+};
+
 static const struct msm_mdss_data sdm845_data = {
.ubwc_enc_version = UBWC_2_0,
.ubwc_dec_version = UBWC_2_0,
@@ -609,6 +615,7 @@ static const struct of_device_id mdss_dt_match[] = {
{ .compatible = "qcom,mdss" },
{ .compatible = "qcom,msm8998-mdss", .data = _data },
{ .compatible = "qcom,qcm2290-mdss", .data = _data },
+   { .compatible = "qcom,sdm670-mdss", .data = _data },
{ .compatible = "qcom,sdm845-mdss", .data = _data },
{ .compatible = "qcom,sc7180-mdss", .data = _data },
{ .compatible = "qcom,sc7280-mdss", .data = _data },
-- 
2.42.0



[PATCH 5/6] drm/msm/dpu: Add hw revision 4.1 (SDM670)

2023-09-25 Thread Richard Acayan
The Snapdragon 670 uses similar clocks (with one frequency added) to the
Snapdragon 845 but reports DPU revision 4.1. Add support for this DPU
with configuration from the Pixel 3a downstream kernel.

Since revision 4.0 is SDM845, reuse some configuration from its catalog
entry.

Link: 
https://android.googlesource.com/kernel/msm/+/368478b0ae76566927a2769a2bf24dfe7f38bb78/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
Signed-off-by: Richard Acayan 
---
 .../msm/disp/dpu1/catalog/dpu_4_1_sdm670.h| 105 ++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|   6 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   1 +
 4 files changed, 113 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h
new file mode 100644
index ..eaccb16b5db9
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023, Richard Acayan. All rights reserved.
+ */
+
+#ifndef _DPU_4_1_SDM670_H
+#define _DPU_4_1_SDM670_H
+
+static const struct dpu_mdp_cfg sdm670_mdp = {
+   .name = "top_0",
+   .base = 0x0, .len = 0x45c,
+   .features = BIT(DPU_MDP_AUDIO_SELECT),
+   .clk_ctrls = {
+   [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0},
+   [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0},
+   [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8},
+   [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8},
+   [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8},
+   },
+};
+
+static const struct dpu_sspp_cfg sdm670_sspp[] = {
+   {
+   .name = "sspp_0", .id = SSPP_VIG0,
+   .base = 0x4000, .len = 0x1c8,
+   .features = VIG_SDM845_MASK_SDMA,
+   .sblk = _vig_sblk_0,
+   .xin_id = 0,
+   .type = SSPP_TYPE_VIG,
+   .clk_ctrl = DPU_CLK_CTRL_VIG0,
+   }, {
+   .name = "sspp_1", .id = SSPP_VIG1,
+   .base = 0x6000, .len = 0x1c8,
+   .features = VIG_SDM845_MASK_SDMA,
+   .sblk = _vig_sblk_1,
+   .xin_id = 4,
+   .type = SSPP_TYPE_VIG,
+   .clk_ctrl = DPU_CLK_CTRL_VIG0,
+   }, {
+   .name = "sspp_8", .id = SSPP_DMA0,
+   .base = 0x24000, .len = 0x1c8,
+   .features = DMA_SDM845_MASK_SDMA,
+   .sblk = _dma_sblk_0,
+   .xin_id = 1,
+   .type = SSPP_TYPE_DMA,
+   .clk_ctrl = DPU_CLK_CTRL_DMA0,
+   }, {
+   .name = "sspp_9", .id = SSPP_DMA1,
+   .base = 0x26000, .len = 0x1c8,
+   .features = DMA_CURSOR_SDM845_MASK_SDMA,
+   .sblk = _dma_sblk_1,
+   .xin_id = 5,
+   .type = SSPP_TYPE_DMA,
+   .clk_ctrl = DPU_CLK_CTRL_DMA1,
+   }, {
+   .name = "sspp_10", .id = SSPP_DMA2,
+   .base = 0x28000, .len = 0x1c8,
+   .features = DMA_CURSOR_SDM845_MASK_SDMA,
+   .sblk = _dma_sblk_2,
+   .xin_id = 9,
+   .type = SSPP_TYPE_DMA,
+   .clk_ctrl = DPU_CLK_CTRL_DMA2,
+   },
+};
+
+static struct dpu_dsc_cfg sdm670_dsc[] = {
+   {
+   .name = "dsc_0", .id = DSC_0,
+   .base = 0x8, .len = 0x140,
+   },
+   {
+   .name = "dsc_1", .id = DSC_1,
+   .base = 0x80400, .len = 0x140,
+   },
+};
+
+static struct dpu_mdss_version sdm670_mdss_ver = {
+   .core_major_ver = 4,
+   .core_minor_ver = 1,
+};
+
+const struct dpu_mdss_cfg dpu_sdm670_cfg = {
+   .mdss_ver = _mdss_ver,
+   .caps = _dpu_caps,
+   .mdp = _mdp,
+   .ctl_count = ARRAY_SIZE(sdm845_ctl),
+   .ctl = sdm845_ctl,
+   .sspp_count = ARRAY_SIZE(sdm670_sspp),
+   .sspp = sdm670_sspp,
+   .mixer_count = ARRAY_SIZE(sdm845_lm),
+   .mixer = sdm845_lm,
+   .pingpong_count = ARRAY_SIZE(sdm845_pp),
+   .pingpong = sdm845_pp,
+   .dsc_count = ARRAY_SIZE(sdm670_dsc),
+   .dsc = sdm670_dsc,
+   .intf_count = ARRAY_SIZE(sdm845_intf),
+   .intf = sdm845_intf,
+   .vbif_count = ARRAY_SIZE(sdm845_vbif),
+   .vbif = sdm845_vbif,
+   .perf = _perf_data,
+};
+
+#endif
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 713dfc079718..63b274ae032a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -313,6 +313,11 @@ static const struct 

[PATCH 6/6] arm64: dts: qcom: sdm670: add display subsystem

2023-09-25 Thread Richard Acayan
The Snapdragon 670 has a display subsystem for controlling and
outputting to the display. Add support for it in the device tree.

Signed-off-by: Richard Acayan 
---
 arch/arm64/boot/dts/qcom/sdm670.dtsi | 294 +++
 1 file changed, 294 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi 
b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 84cd2e39266f..427415ed4e4a 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -6,6 +6,7 @@
  * Copyright (c) 2022, Richard Acayan. All rights reserved.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -400,6 +401,30 @@ cpu6_opp10: opp-199680 {
};
};
 
+   dsi_opp_table: opp-table-dsi {
+   compatible = "operating-points-v2";
+
+   opp-1920 {
+   opp-hz = /bits/ 64 <1920>;
+   required-opps = <_opp_min_svs>;
+   };
+
+   opp-18000 {
+   opp-hz = /bits/ 64 <18000>;
+   required-opps = <_opp_low_svs>;
+   };
+
+   opp-27500 {
+   opp-hz = /bits/ 64 <27500>;
+   required-opps = <_opp_svs>;
+   };
+
+   opp-35800 {
+   opp-hz = /bits/ 64 <35800>;
+   required-opps = <_opp_svs_l1>;
+   };
+   };
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
@@ -1352,6 +1377,275 @@ spmi_bus: spmi@c44 {
#interrupt-cells = <4>;
};
 
+   mdss: display-subsystem@ae0 {
+   compatible = "qcom,sdm670-mdss";
+   reg = <0 0x0ae0 0 0x1000>;
+   reg-names = "mdss";
+
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < DISP_CC_MDSS_AHB_CLK>,
+< DISP_CC_MDSS_MDP_CLK>;
+   clock-names = "iface", "core";
+
+   interrupts = ;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   interconnects = <_noc MASTER_MDP_PORT0 0 _noc 
SLAVE_EBI_CH0 0>,
+   <_noc MASTER_MDP_PORT1 0 _noc 
SLAVE_EBI_CH0 0>;
+   interconnect-names = "mdp0-mem", "mdp1-mem";
+
+   iommus = <_smmu 0x880 0x8>,
+<_smmu 0xc80 0x8>;
+
+   status = "disabled";
+
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+
+   mdss_mdp: display-controller@ae01000 {
+   compatible = "qcom,sdm670-dpu";
+   reg = <0 0x0ae01000 0 0x8f000>,
+ <0 0x0aeb 0 0x2008>;
+   reg-names = "mdp", "vbif";
+
+   clocks = < GCC_DISP_AXI_CLK>,
+< DISP_CC_MDSS_AHB_CLK>,
+< DISP_CC_MDSS_AXI_CLK>,
+< DISP_CC_MDSS_MDP_CLK>,
+< DISP_CC_MDSS_VSYNC_CLK>;
+   clock-names = "gcc-bus", "iface", "bus", 
"core", "vsync";
+
+   assigned-clocks = < 
DISP_CC_MDSS_VSYNC_CLK>;
+   assigned-clock-rates = <1920>;
+   operating-points-v2 = <_opp_table>;
+   power-domains = < SDM670_CX>;
+
+   interrupt-parent = <>;
+   interrupts = <0>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   dpu_intf0_out: endpoint {
+   remote-endpoint = 
<_dsi0_in>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   dpu_intf1_out: endpoint {
+   remote-endpoint = 
<_dsi1_in>;
+   };
+   };
+   };
+
+   mdp_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   

[PATCH 2/6] dt-bindings: display/msm: sdm845-dpu: Describe SDM670

2023-09-25 Thread Richard Acayan
The SDM670 display controller has the same requirements as the SDM845
display controller, despite having distinct properties as described in
the catalog. Add the compatible for SDM670 to the SDM845 controller.

Signed-off-by: Richard Acayan 
---
 .../devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml
index b917064bdf33..dc11fd421a27 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml
@@ -13,7 +13,9 @@ $ref: /schemas/display/msm/dpu-common.yaml#
 
 properties:
   compatible:
-const: qcom,sdm845-dpu
+enum:
+  - qcom,sdm670-dpu
+  - qcom,sdm845-dpu
 
   reg:
 items:
-- 
2.42.0



[PATCH 3/6] dt-bindings: display: msm: Add SDM670 MDSS

2023-09-25 Thread Richard Acayan
Add documentation for the SDM670 display subsystem, adapted from the
SDM845 and SM6125 documentation.

Signed-off-by: Richard Acayan 
---
 .../display/msm/qcom,sdm670-mdss.yaml | 280 ++
 1 file changed, 280 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml

diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml
new file mode 100644
index ..839b372759ed
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml
@@ -0,0 +1,280 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/qcom,sdm670-mdss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SDM670 Display MDSS
+
+maintainers:
+  - Richard Acayan 
+
+description:
+  SDM670 MSM Mobile Display Subsystem (MDSS), which encapsulates sub-blocks
+  like DPU display controller, DSI and DP interfaces etc.
+
+$ref: /schemas/display/msm/mdss-common.yaml#
+
+properties:
+  compatible:
+const: qcom,sdm670-mdss
+
+  clocks:
+items:
+  - description: Display AHB clock from gcc
+  - description: Display core clock
+
+  clock-names:
+items:
+  - const: iface
+  - const: core
+
+  iommus:
+maxItems: 2
+
+  interconnects:
+maxItems: 2
+
+  interconnect-names:
+maxItems: 2
+
+patternProperties:
+  "^display-controller@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+const: qcom,sdm670-dpu
+
+  "^displayport-controller@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+const: qcom,sdm670-dp
+
+  "^dsi@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+items:
+  - const: qcom,sdm670-dsi-ctrl
+  - const: qcom,mdss-dsi-ctrl
+
+  "^phy@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+const: qcom,dsi-phy-10nm
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+#include 
+#include 
+
+display-subsystem@ae0 {
+compatible = "qcom,sdm670-mdss";
+reg = <0x0ae0 0x1000>;
+reg-names = "mdss";
+power-domains = < MDSS_GDSC>;
+
+clocks = < GCC_DISP_AHB_CLK>,
+ < DISP_CC_MDSS_MDP_CLK>;
+clock-names = "iface", "core";
+
+interrupts = ;
+interrupt-controller;
+#interrupt-cells = <1>;
+
+iommus = <_smmu 0x880 0x8>,
+ <_smmu 0xc80 0x8>;
+
+#address-cells = <1>;
+#size-cells = <1>;
+ranges;
+
+display-controller@ae01000 {
+compatible = "qcom,sdm670-dpu";
+reg = <0x0ae01000 0x8f000>,
+  <0x0aeb 0x2008>;
+reg-names = "mdp", "vbif";
+
+clocks = < GCC_DISP_AXI_CLK>,
+ < DISP_CC_MDSS_AHB_CLK>,
+ < DISP_CC_MDSS_AXI_CLK>,
+ < DISP_CC_MDSS_MDP_CLK>,
+ < DISP_CC_MDSS_VSYNC_CLK>;
+clock-names = "gcc-bus", "iface", "bus", "core", "vsync";
+
+interrupt-parent = <>;
+interrupts = <0>;
+power-domains = < SDM670_CX>;
+operating-points-v2 = <_opp_table>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+dpu_intf1_out: endpoint {
+remote-endpoint = <_dsi0_in>;
+};
+};
+
+port@1 {
+reg = <1>;
+dpu_intf2_out: endpoint {
+remote-endpoint = <_dsi1_in>;
+};
+};
+};
+};
+
+dsi@ae94000 {
+compatible = "qcom,sdm670-dsi-ctrl", "qcom,mdss-dsi-ctrl";
+reg = <0x0ae94000 0x400>;
+reg-names = "dsi_ctrl";
+
+interrupt-parent = <>;
+interrupts = <4>;
+
+clocks = < DISP_CC_MDSS_BYTE0_CLK>,
+ < DISP_CC_MDSS_BYTE0_INTF_CLK>,
+ < DISP_CC_MDSS_PCLK0_CLK>,
+ < DISP_CC_MDSS_ESC0_CLK>,
+ < DISP_CC_MDSS_AHB_CLK>,
+ < DISP_CC_MDSS_AXI_CLK>;
+clock-names = "byte",
+  "byte_intf",
+  "pixel",
+  "core",
+  "iface",
+  "bus";
+assigned-clocks = < DISP_CC_MDSS_BYTE0_CLK_SRC>,
+  < DISP_CC_MDSS_PCLK0_CLK_SRC>;
+assigned-clock-parents = <_dsi0_phy 0>, <_dsi0_phy 1>;
+
+operating-points-v2 = <_opp_table>;
+power-domains = < SDM670_CX>;
+
+ 

[PATCH 1/6] dt-bindings: display/msm: dsi-controller-main: add SDM670 compatible

2023-09-25 Thread Richard Acayan
The SDM670 has DSI ports. Add the compatible for the controller.

Signed-off-by: Richard Acayan 
---
 .../devicetree/bindings/display/msm/dsi-controller-main.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index c6dbab65d5f7..887c7dcaf438 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -25,6 +25,7 @@ properties:
   - qcom,sc7180-dsi-ctrl
   - qcom,sc7280-dsi-ctrl
   - qcom,sdm660-dsi-ctrl
+  - qcom,sdm670-dsi-ctrl
   - qcom,sdm845-dsi-ctrl
   - qcom,sm6115-dsi-ctrl
   - qcom,sm6125-dsi-ctrl
-- 
2.42.0



[PATCH 0/6] SDM670 display subsystem support

2023-09-25 Thread Richard Acayan
This series adds support for the display subsystem on the Snapdragon
670. It is based on an earlier patch a few versions back, which had
missing device tree bindings and device tree changes.

There is a separate IOMMU patch which adds the MDSS compatible to a
workaround.

Richard Acayan (6):
  dt-bindings: display/msm: dsi-controller-main: add SDM670 compatible
  dt-bindings: display/msm: sdm845-dpu: Describe SDM670
  dt-bindings: display: msm: Add SDM670 MDSS
  drm/msm: mdss: add support for SDM670
  drm/msm/dpu: Add hw revision 4.1 (SDM670)
  arm64: dts: qcom: sdm670: add display subsystem

 .../display/msm/dsi-controller-main.yaml  |   1 +
 .../display/msm/qcom,sdm670-mdss.yaml | 280 +
 .../bindings/display/msm/qcom,sdm845-dpu.yaml |   4 +-
 arch/arm64/boot/dts/qcom/sdm670.dtsi  | 294 ++
 .../msm/disp/dpu1/catalog/dpu_4_1_sdm670.h| 105 +++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|   6 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   1 +
 drivers/gpu/drm/msm/msm_mdss.c|   7 +
 9 files changed, 698 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h

-- 
2.42.0



Re: [RFT PATCH v2 01/12] drm/imx/dcss: Call drm_atomic_helper_shutdown() at shutdown time

2023-09-25 Thread Doug Anderson
Hi,

On Sun, Sep 24, 2023 at 10:47 PM Laurentiu Palcu
 wrote:
>
> Hi Doug,
>
> On Fri, Sep 22, 2023 at 08:44:16AM -0700, Doug Anderson wrote:
> > Hi,
> >
> > On Fri, Sep 22, 2023 at 12:56 AM Laurentiu Palcu
> >  wrote:
> > >
> > > Hi,
> > >
> > > On Thu, Sep 21, 2023 at 12:26:44PM -0700, Douglas Anderson wrote:
> > > > Based on grepping through the source code this driver appears to be
> > > > missing a call to drm_atomic_helper_shutdown() at system shutdown
> > > > time. Among other things, this means that if a panel is in use that it
> > > > won't be cleanly powered off at system shutdown time.
> > > >
> > > > The fact that we should call drm_atomic_helper_shutdown() in the case
> > > > of OS shutdown/restart comes straight out of the kernel doc "driver
> > > > instance overview" in drm_drv.c.
> > > >
> > > > Suggested-by: Maxime Ripard 
> > > > Reviewed-by: Maxime Ripard 
> > > > Signed-off-by: Douglas Anderson 
> > >
> > > No issues found on i.MX8MQ.
> > >
> > > Tested-by: Laurentiu Palcu 
> > > Reviewed-by: Laurentiu Palcu 
> >
> > Thanks! Would you expect this patch to land through drm-misc? If so,
> > I'm happy to commit it there with your tags.
>
> Yes, please do. The i.MX8MQ DCSS patches go through drm-misc.

OK, landed in drm-misc-next:

89755ee1d593 drm/imx/dcss: Call drm_atomic_helper_shutdown() at shutdown time


> > If patches to this driver normally flow through drm-misc, I'm also
> > happy to post a patch to MAINTAINERS (or review a patch you post)
> > adding this to the entry for "NXP i.MX 8MQ DCSS DRIVER":
> >
> > T: git git://anongit.freedesktop.org/drm/drm-misc
> >
> > ...which would make it obvious in the future that things should land
> > through drm-misc.
>
> Thanks, that sounds good.

https://lore.kernel.org/r/20230925154929.1.I3287e895ce8e68d41b458494a49a1b5ec5c71013@changeid


[PATCH] MAINTAINERS: Document that the NXP i.MX 8MQ DCSS driver goes thru drm-misc

2023-09-25 Thread Douglas Anderson
As per the discussion on the lists [1], changes to this driver
generally flow through drm-misc. Add a tag in MAINTAINERS to document
this

[1] 
https://lore.kernel.org/r/20230925054710.r3guqn5jzdl4g...@fsr-ub1664-121.ea.freescale.net

Signed-off-by: Douglas Anderson 
---

 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d72d3af551fb..d20a375ecd7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15225,6 +15225,7 @@ M:  Laurentiu Palcu 
 R: Lucas Stach 
 L: dri-devel@lists.freedesktop.org
 S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
 F: Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml
 F: drivers/gpu/drm/imx/dcss/
 
-- 
2.42.0.515.g380fc7ccd1-goog



Re: [Nouveau] [PATCH] drm/nouveau/kms/nv50: hide unused variables

2023-09-25 Thread Danilo Krummrich

On 9/25/23 17:59, Arnd Bergmann wrote:

From: Arnd Bergmann 

After a recent change, two variables are only used in an #ifdef:

drivers/gpu/drm/nouveau/dispnv50/disp.c: In function 'nv50_sor_atomic_disable':
drivers/gpu/drm/nouveau/dispnv50/disp.c:1569:13: error: unused variable 'ret' 
[-Werror=unused-variable]
  1569 | int ret;
   | ^~~
drivers/gpu/drm/nouveau/dispnv50/disp.c:1568:28: error: unused variable 'aux' 
[-Werror=unused-variable]
  1568 | struct drm_dp_aux *aux = _connector->aux;
   |^~~

Move them into the same conditional block, along with the nv_connector variable
that becomes unused during that fix.

Fixes: 757033808c95b ("drm/nouveau/kms/nv50-: fixup sink D3 before tearing down 
link")
Signed-off-by: Arnd Bergmann 


Reviewed-by: Danilo Krummrich 


---
  drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 +---
  1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 52f1569ee37c1..a0ac8c258d9ff 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1560,15 +1560,13 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
  {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_head *head = nv50_head(nv_encoder->crtc);
-   struct nouveau_connector *nv_connector = 
nv50_outp_get_old_connector(state, nv_encoder);
  #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+   struct nouveau_connector *nv_connector = 
nv50_outp_get_old_connector(state, nv_encoder);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_backlight *backlight = nv_connector->backlight;
-#endif
struct drm_dp_aux *aux = _connector->aux;
int ret;
  
-#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT

if (backlight && backlight->uses_dpcd) {
ret = drm_edp_backlight_disable(aux, >edp_info);
if (ret < 0)




[PATCH] drm/panel: Move AUX B116XW03 out of panel-edp back to panel-simple

2023-09-25 Thread Douglas Anderson
In commit 5f04e7ce392d ("drm/panel-edp: Split eDP panels out of
panel-simple") I moved a pile of panels out of panel-simple driver
into the newly created panel-edp driver. One of those panels, however,
shouldn't have been moved.

As is clear from commit e35e305eff0f ("drm/panel: simple: Add AUO
B116XW03 panel support"), AUX B116XW03 is an LVDS panel. It's used in
exynos5250-snow and exynos5420-peach-pit where it's clear that the
panel is hooked up with LVDS. Furthermore, searching for datasheets I
found one that makes it clear that this panel is LVDS.

As far as I can tell, I got confused because in commit 88d3457ceb82
("drm/panel: auo,b116xw03: fix flash backlight when power on") Jitao
Shi added "DRM_MODE_CONNECTOR_eDP". That seems wrong. Looking at the
downstream ChromeOS trees, it seems like some Mediatek boards are
using a panel that they call "auo,b116xw03" that's an eDP panel. The
best I can guess is that they actually have a different panel that has
similar timing. If so then the proper panel should be used or they
should switch to the generic "edp-panel" compatible.

When moving this back to panel-edp, I wasn't sure what to use for
.bus_flags and .bus_format and whether to add the extra "enable" delay
from commit 88d3457ceb82 ("drm/panel: auo,b116xw03: fix flash
backlight when power on"). I've added formats/flags/delays based on my
(inexpert) analysis of the datasheet. These are untested.

NOTE: if/when this is backported to stable, we might run into some
trouble. Specifically, before 474c162878ba ("arm64: dts: mt8183:
jacuzzi: Move panel under aux-bus") this panel was used by
"mt8183-kukui-jacuzzi", which assumed it was an eDP panel. I don't
know what to suggest for that other than someone making up a bogus
panel for jacuzzi that's just for the stable channel.

Fixes: 88d3457ceb82 ("drm/panel: auo,b116xw03: fix flash backlight when power 
on")
Fixes: 5f04e7ce392d ("drm/panel-edp: Split eDP panels out of panel-simple")
Signed-off-by: Douglas Anderson 
---
I haven't had a snow or peach-pit hooked up for debugging / testing
for years. I presume that they must be broken and hope that this fixes
them.

 drivers/gpu/drm/panel/panel-edp.c| 29 ---
 drivers/gpu/drm/panel/panel-simple.c | 35 
 2 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-edp.c 
b/drivers/gpu/drm/panel/panel-edp.c
index feb665df35a1..95c8472d878a 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -976,32 +976,6 @@ static const struct panel_desc auo_b116xak01 = {
},
 };
 
-static const struct drm_display_mode auo_b116xw03_mode = {
-   .clock = 70589,
-   .hdisplay = 1366,
-   .hsync_start = 1366 + 40,
-   .hsync_end = 1366 + 40 + 40,
-   .htotal = 1366 + 40 + 40 + 32,
-   .vdisplay = 768,
-   .vsync_start = 768 + 10,
-   .vsync_end = 768 + 10 + 12,
-   .vtotal = 768 + 10 + 12 + 6,
-   .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
-};
-
-static const struct panel_desc auo_b116xw03 = {
-   .modes = _b116xw03_mode,
-   .num_modes = 1,
-   .bpc = 6,
-   .size = {
-   .width = 256,
-   .height = 144,
-   },
-   .delay = {
-   .enable = 400,
-   },
-};
-
 static const struct drm_display_mode auo_b133han05_mode = {
.clock = 142600,
.hdisplay = 1920,
@@ -1725,9 +1699,6 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "auo,b116xa01",
.data = _b116xak01,
-   }, {
-   .compatible = "auo,b116xw03",
-   .data = _b116xw03,
}, {
.compatible = "auo,b133han05",
.data = _b133han05,
diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index bb89e6d047bc..439d26928938 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -919,6 +919,38 @@ static const struct panel_desc auo_b101xtn01 = {
},
 };
 
+static const struct drm_display_mode auo_b116xw03_mode = {
+   .clock = 70589,
+   .hdisplay = 1366,
+   .hsync_start = 1366 + 40,
+   .hsync_end = 1366 + 40 + 40,
+   .htotal = 1366 + 40 + 40 + 32,
+   .vdisplay = 768,
+   .vsync_start = 768 + 10,
+   .vsync_end = 768 + 10 + 12,
+   .vtotal = 768 + 10 + 12 + 6,
+   .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+};
+
+static const struct panel_desc auo_b116xw03 = {
+   .modes = _b116xw03_mode,
+   .num_modes = 1,
+   .bpc = 6,
+   .size = {
+   .width = 256,
+   .height = 144,
+   },
+   .delay = {
+   .prepare = 1,
+   .enable = 200,
+   .disable = 200,
+   .unprepare = 500,
+   },
+   .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+

Re: [PATCH v4 00/10] DRM scheduler changes for Xe

2023-09-25 Thread Danilo Krummrich

On 9/19/23 13:44, Danilo Krummrich wrote:

Hi Matt,

On 9/19/23 07:01, Matthew Brost wrote:

As a prerequisite to merging the new Intel Xe DRM driver [1] [2], we
have been asked to merge our common DRM scheduler patches first.

This a continuation of a RFC [3] with all comments addressed, ready for
a full review, and hopefully in state which can merged in the near
future. More details of this series can found in the cover letter of the
RFC [3].

These changes have been tested with the Xe driver.

v2:
  - Break run job, free job, and process message in own work items
  - This might break other drivers as run job and free job now can run in
    parallel, can fix up if needed

v3:
  - Include missing patch 'drm/sched: Add drm_sched_submit_* helpers'
  - Fix issue with setting timestamp to early
  - Don't dequeue jobs for single entity after calling entity fini
  - Flush pending jobs on entity fini
  - Add documentation for entity teardown
  - Add Matthew Brost to maintainers of DRM scheduler

v4:
  - Drop message interface
  - Drop 'Flush pending jobs on entity fini'
  - Drop 'Add documentation for entity teardown'
  - Address all feedback


There is some feedback from V3 that doesn't seem to be addressed yet.

(1) Document tear down of struct drm_gpu_scheduler. [1]
(2) Implement helpers to tear down struct drm_gpu_scheduler. [2]
(3) Document implications of using a workqueue in terms of free_job() being
     or not being part of the fence signaling path respectively. [3]

I think at least (1) and (3) should be part of this series. I think (2) could
also happen subsequently. Christian's idea [2] how to address this is quite
interesting, but might exceed the scope of this series.

I will try to rebase my Nouveau changes onto your V4 tomorrow for a quick test.


Tested-by: Danilo Krummrich 



- Danilo

[1] 
https://lore.kernel.org/all/20230912021615.2086698-1-matthew.br...@intel.com/T/#m2e8c1c1e68e8127d5dd62509b5e424a12217300b
[2] 
https://lore.kernel.org/all/20230912021615.2086698-1-matthew.br...@intel.com/T/#m16a0d6fa2e617383776515af45d3c6b9db543d47
[3] 
https://lore.kernel.org/all/20230912021615.2086698-1-matthew.br...@intel.com/T/#m807ff95284089fdb51985f1c187666772314bd8a



Matt

Matthew Brost (10):
   drm/sched: Add drm_sched_submit_* helpers
   drm/sched: Convert drm scheduler to use a work queue rather than
 kthread
   drm/sched: Move schedule policy to scheduler
   drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy
   drm/sched: Split free_job into own work item
   drm/sched: Add drm_sched_start_timeout_unlocked helper
   drm/sched: Start submission before TDR in drm_sched_start
   drm/sched: Submit job before starting TDR
   drm/sched: Add helper to queue TDR immediately for current and future
 jobs
   drm/sched: Update maintainers of GPU scheduler

  MAINTAINERS   |   1 +
  .../drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c   |   2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c   |  15 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |  15 +-
  drivers/gpu/drm/etnaviv/etnaviv_sched.c   |   5 +-
  drivers/gpu/drm/lima/lima_sched.c |   5 +-
  drivers/gpu/drm/msm/adreno/adreno_device.c    |   6 +-
  drivers/gpu/drm/msm/msm_ringbuffer.c  |   5 +-
  drivers/gpu/drm/nouveau/nouveau_sched.c   |   5 +-
  drivers/gpu/drm/panfrost/panfrost_job.c   |   5 +-
  drivers/gpu/drm/scheduler/sched_entity.c  |  85 ++-
  drivers/gpu/drm/scheduler/sched_fence.c   |   2 +-
  drivers/gpu/drm/scheduler/sched_main.c    | 491 --
  drivers/gpu/drm/v3d/v3d_sched.c   |  25 +-
  include/drm/gpu_scheduler.h   |  48 +-
  15 files changed, 495 insertions(+), 220 deletions(-)





Re: [PATCH 08/15] platform/x86/amd/pmf: Add support to update system state

2023-09-25 Thread kernel test robot
Hi Shyam,

kernel test robot noticed the following build warnings:

[auto build test WARNING on hid/for-next]
[also build test WARNING on linus/master v6.6-rc3 next-20230925]
[cannot apply to drm-misc/drm-misc-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Shyam-Sundar-S-K/platform-x86-amd-pmf-Add-PMF-TEE-interface/20230923-015418
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
patch link:
https://lore.kernel.org/r/20230922175056.244940-9-Shyam-sundar.S-k%40amd.com
patch subject: [PATCH 08/15] platform/x86/amd/pmf: Add support to update system 
state
reproduce: 
(https://download.01.org/0day-ci/archive/20230926/202309260515.5xbr6n0g-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202309260515.5xbr6n0g-...@intel.com/

All warnings (new ones prefixed by >>):

>> Documentation/admin-guide/pmf.rst:16: WARNING: Unexpected indentation.
>> Documentation/admin-guide/pmf.rst: WARNING: document isn't included in any 
>> toctree

vim +16 Documentation/admin-guide/pmf.rst

13  
14  Please add the following line(s) to
15  ``/etc/udev/rules.d/99-local.rules``::
  > 16  DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="1", 
RUN+="/usr/bin/systemctl suspend"
17  DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="2", 
RUN+="/usr/bin/systemctl hibernate"
18  DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="3", 
RUN+="/bin/loginctl lock-sessions"
19  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


[PATCH 2/2] dt-bindings: display: msm: Make "additionalProperties: true" explicit

2023-09-25 Thread Rob Herring
Make it explicit that child nodes have additional properties and the
child node schema is not complete. The complete schemas are applied
separately based the compatible strings.

Signed-off-by: Rob Herring 
---
 .../bindings/display/msm/qcom,msm8998-mdss.yaml|  6 ++
 .../bindings/display/msm/qcom,qcm2290-mdss.yaml|  6 ++
 .../bindings/display/msm/qcom,sc7180-mdss.yaml |  8 
 .../bindings/display/msm/qcom,sc7280-mdss.yaml | 10 ++
 .../bindings/display/msm/qcom,sc8280xp-mdss.yaml   |  4 
 .../bindings/display/msm/qcom,sdm845-mdss.yaml |  8 
 .../bindings/display/msm/qcom,sm6115-mdss.yaml |  6 ++
 .../bindings/display/msm/qcom,sm6125-mdss.yaml |  6 ++
 .../bindings/display/msm/qcom,sm6350-mdss.yaml |  6 ++
 .../bindings/display/msm/qcom,sm6375-mdss.yaml |  6 ++
 .../bindings/display/msm/qcom,sm8150-mdss.yaml |  6 ++
 .../bindings/display/msm/qcom,sm8250-mdss.yaml |  6 ++
 .../bindings/display/msm/qcom,sm8350-mdss.yaml |  8 
 .../bindings/display/msm/qcom,sm8450-mdss.yaml |  8 
 .../bindings/display/msm/qcom,sm8550-mdss.yaml |  8 
 15 files changed, 102 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml
index e320ab1de6de..2d9edab5a30d 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml
@@ -38,12 +38,16 @@ properties:
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,msm8998-dpu
 
   "^dsi@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 items:
@@ -52,6 +56,8 @@ patternProperties:
 
   "^phy@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,dsi-phy-10nm-8998
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
index 4184b84d4c21..5ad155612b6c 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
@@ -44,18 +44,24 @@ properties:
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,qcm2290-dpu
 
   "^dsi@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,dsi-ctrl-6g-qcm2290
 
   "^phy@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,dsi-phy-14nm-2290
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml
index 3b9c103e504a..3432a2407caa 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml
@@ -44,18 +44,24 @@ properties:
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,sc7180-dpu
 
   "^displayport-controller@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,sc7180-dp
 
   "^dsi@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 items:
@@ -64,6 +70,8 @@ patternProperties:
 
   "^phy@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,dsi-phy-10nm
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sc7280-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sc7280-mdss.yaml
index 43500dad66e7..bbb727831fca 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,sc7280-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sc7280-mdss.yaml
@@ -44,18 +44,24 @@ properties:
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,sc7280-dpu
 
   "^displayport-controller@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 const: qcom,sc7280-dp
 
   "^dsi@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 properties:
   compatible:
 items:
@@ -64,12 +70,16 @@ patternProperties:
 
   "^edp@[0-9a-f]+$":
 type: object
+additionalProperties: true
+
 

[PATCH 1/2] dt-bindings: display: msm: Add missing unevaluatedProperties on child node schemas

2023-09-25 Thread Rob Herring
Just as unevaluatedProperties or additionalProperties are required at
the top level of schemas, they should (and will) also be required for
child node schemas. That ensures only documented properties are
present for any node.

Signed-off-by: Rob Herring 
---
 Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index f12558960cd8..dbe398f84ffb 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -114,6 +114,7 @@ properties:
 
   port@1:
 $ref: /schemas/graph.yaml#/$defs/port-base
+unevaluatedProperties: false
 description: Output endpoint of the controller
 properties:
   endpoint:
-- 
2.40.1



[RFC PATCH] drm/ci: add helper script update-xfails.py

2023-09-25 Thread Helen Koike
Add helper script that given a gitlab pipeline url, analise which are
the failures and flakes and update the xfails folder accordingly.

Example:
Trigger a pipeline in gitlab infrastructure, than re-try a few jobs more
than once (so we can have data if failues are consistent across jobs
with the same name or if they are flakes) and execute:

update-xfails.py 
https://gitlab.freedesktop.org/helen.fornazier/linux/-/pipelines/970661

git diff should show you that it updated files in xfails folder.

Signed-off-by: Helen Koike 

---

Hello,

This script is being very handy for me, so I suppose it could be handy
to others, since I'm publishing it in the xfails folder.

Let me know your thoughts.

Regards,
Helen
---
 drivers/gpu/drm/ci/xfails/requirements.txt |  16 ++
 drivers/gpu/drm/ci/xfails/update-xfails.py | 161 +
 2 files changed, 177 insertions(+)
 create mode 100644 drivers/gpu/drm/ci/xfails/requirements.txt
 create mode 100755 drivers/gpu/drm/ci/xfails/update-xfails.py

diff --git a/drivers/gpu/drm/ci/xfails/requirements.txt 
b/drivers/gpu/drm/ci/xfails/requirements.txt
new file mode 100644
index ..26255fb6d6b8
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/requirements.txt
@@ -0,0 +1,16 @@
+git+https://gitlab.freedesktop.org/gfx-ci/ci-collate@4a5bb602855f2bd4fc1ecf43db19e84a906f4258
+
+# ci-collate dependencies
+certifi==2023.7.22
+charset-normalizer==3.2.0
+idna==3.4
+pip==23.2.1
+python-gitlab==3.15.0
+requests==2.31.0
+requests-toolbelt==1.0.0
+ruamel.yaml==0.17.32
+ruamel.yaml.clib==0.2.7
+setuptools==68.0.0
+tenacity==8.2.3
+urllib3==2.0.4
+wheel==0.41.1
diff --git a/drivers/gpu/drm/ci/xfails/update-xfails.py 
b/drivers/gpu/drm/ci/xfails/update-xfails.py
new file mode 100755
index ..f14f8ea78de7
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/update-xfails.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import re
+from glcollate import Collate
+from urllib.parse import urlparse
+
+
+def get_canonical_name(job_name):
+return re.split(r" \d+/\d+", job_name)[0]
+
+
+def get_xfails_file_path(canonical_name, suffix):
+name = canonical_name.replace(":", "-")
+script_dir = os.path.dirname(os.path.abspath(__file__))
+return os.path.join(script_dir, f"{name}-{suffix}.txt")
+
+
+def get_unit_test_name_and_results(unit_test):
+if "Artifact results/failures.csv not found" in unit_test:
+return None, None
+unit_test_name, unit_test_result = unit_test.strip().split(",")
+return unit_test_name, unit_test_result
+
+
+def read_file(file_path):
+try:
+with open(file_path, "r") as file:
+f = file.readlines()
+if len(f):
+f[-1] = f[-1].strip() + "\n"
+return f
+except FileNotFoundError:
+return []
+
+
+def save_file(content, file_path):
+# delete file is content is empty
+if not content or not any(content):
+if os.path.exists(file_path):
+os.remove(file_path)
+return
+
+content.sort()
+with open(file_path, "w") as file:
+file.writelines(content)
+
+
+def is_test_present_on_file(file_content, unit_test_name):
+return any(unit_test_name in line for line in file_content)
+
+
+def is_unit_test_present_in_other_jobs(unit_test, job_ids):
+return all(unit_test in job_ids[job_id] for job_id in job_ids)
+
+
+def remove_unit_test_if_present(lines, unit_test_name, file_name):
+if not is_test_present_on_file(lines, unit_test_name):
+return
+lines[:] = [line for line in lines if unit_test_name not in line]
+print(os.path.basename(file_name), ": REMOVED", unit_test_name)
+
+
+def add_unit_test_if_not_present(lines, unit_test_name, file_name):
+if all(unit_test_name not in line for line in lines):
+lines.append(unit_test_name + "\n")
+print(os.path.basename(file_name), ": ADDED", unit_test_name)
+
+
+def update_unit_test_result_in_fails_txt(fails_txt, unit_test, file_name):
+unit_test_name, unit_test_result = 
get_unit_test_name_and_results(unit_test)
+for i, line in enumerate(fails_txt):
+if unit_test_name in line:
+_, current_result = get_unit_test_name_and_results(line)
+fails_txt[i] = unit_test + "\n"
+print(os.path.basename(file_name), ": UPDATED", unit_test,
+  "FROM", current_result, "TO", unit_test_result)
+return
+
+
+def add_unit_test_or_update_result_to_fails_if_present(fails_txt, unit_test, 
fails_txt_path):
+unit_test_name, _ = get_unit_test_name_and_results(unit_test)
+if not is_test_present_on_file(fails_txt, unit_test_name):
+add_unit_test_if_not_present(fails_txt, unit_test, fails_txt_path)
+# if it is present but not with the same result
+elif not is_test_present_on_file(fails_txt, unit_test):
+update_unit_test_result_in_fails_txt(fails_txt, unit_test, 
fails_txt_path)
+
+
+def split_unit_test_from_collate(xfails):
+for 

[PATCH v3 31/32] drm/amd/display: add plane CTM support

2023-09-25 Thread Melissa Wen
Map the plane CTM driver-specific property to DC plane, instead of DC
stream. The remaining steps to program DPP block are already implemented
on DC shared-code.

v3:
- fix comment about plane and CRTC CTMs priorities (Harry)

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 25 +++
 2 files changed, 26 insertions(+)

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 581afa7c5f8c..e4edd97982a6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9714,6 +9714,7 @@ static bool should_reset_plane(struct drm_atomic_state 
*state,
if (dm_old_other_state->degamma_tf != 
dm_new_other_state->degamma_tf ||
dm_old_other_state->degamma_lut != 
dm_new_other_state->degamma_lut ||
dm_old_other_state->hdr_mult != 
dm_new_other_state->hdr_mult ||
+   dm_old_other_state->ctm != dm_new_other_state->ctm ||
dm_old_other_state->shaper_lut != 
dm_new_other_state->shaper_lut ||
dm_old_other_state->shaper_tf != 
dm_new_other_state->shaper_tf ||
dm_old_other_state->lut3d != dm_new_other_state->lut3d ||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 26338f565574..944dccd483de 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -1153,6 +1153,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct 
dm_crtc_state *crtc,
  struct dc_plane_state *dc_plane_state)
 {
struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev);
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   struct drm_color_ctm *ctm = NULL;
struct dc_color_caps *color_caps = NULL;
bool has_crtc_cm_degamma;
int ret;
@@ -1204,5 +1206,28 @@ int amdgpu_dm_update_plane_color_mgmt(struct 
dm_crtc_state *crtc,
return ret;
}
 
+   /* Setup CRTC CTM. */
+   if (dm_plane_state->ctm) {
+   ctm = (struct drm_color_ctm *)dm_plane_state->ctm->data;
+   /* DCN2 and older don't support both pre-blending and
+* post-blending gamut remap. For this HW family, if we have
+* the plane and CRTC CTMs simultaneously, CRTC CTM takes
+* priority, and we discard plane CTM, as implemented in
+* dcn10_program_gamut_remap(). However, DCN3+ has DPP
+* (pre-blending) and MPC (post-blending) `gamut remap` blocks;
+* therefore, we can program plane and CRTC CTMs together by
+* mapping CRTC CTM to MPC and keeping plane CTM setup at DPP,
+* as it's done by dcn30_program_gamut_remap().
+*/
+   __drm_ctm_to_dc_matrix(ctm, 
dc_plane_state->gamut_remap_matrix.matrix);
+
+   dc_plane_state->gamut_remap_matrix.enable_remap = true;
+   dc_plane_state->input_csc_color_matrix.enable_adjustment = 
false;
+   } else {
+   /* Bypass CTM. */
+   dc_plane_state->gamut_remap_matrix.enable_remap = false;
+   dc_plane_state->input_csc_color_matrix.enable_adjustment = 
false;
+   }
+
return amdgpu_dm_plane_set_color_properties(plane_state, 
dc_plane_state);
 }
-- 
2.40.1



[PATCH v3 26/32] drm/amd/display: handle empty LUTs in __set_input_tf

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Unlike degamma, blend gamma doesn't support hardcoded curve
(predefined/ROM), but we can use AMD color module to fill blend gamma
parameters when we have non-linear plane gamma TF without plane gamma
LUT. The regular degamma path doesn't hit this.

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 20 +++
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index dcdf9b580e23..cbebfd24ca78 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -549,17 +549,21 @@ static int __set_input_tf(struct dc_transfer_func *func,
struct dc_gamma *gamma = NULL;
bool res;
 
-   gamma = dc_create_gamma();
-   if (!gamma)
-   return -ENOMEM;
+   if (lut_size) {
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
 
-   gamma->type = GAMMA_CUSTOM;
-   gamma->num_entries = lut_size;
+   gamma->type = GAMMA_CUSTOM;
+   gamma->num_entries = lut_size;
 
-   __drm_lut_to_dc_gamma(lut, gamma, false);
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+   }
 
-   res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-   dc_gamma_release();
+   res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != 
NULL);
+
+   if (gamma)
+   dc_gamma_release();
 
return res ? 0 : -ENOMEM;
 }
-- 
2.40.1



[PATCH v3 24/32] drm/amd/display: add plane shaper TF support

2023-09-25 Thread Melissa Wen
Enable usage of predefined transfer func in addition to shaper 1D LUT.
That means we can save some complexity by just setting a predefined
curve, instead of programming a custom curve when preparing color space
for applying 3D LUT.

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c   | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 8c991b5cf473..a085f98c8e90 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -595,19 +595,22 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf)
 }
 
 static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+  bool has_rom,
+  enum dc_transfer_func_predefined tf,
   uint32_t shaper_size,
   struct dc_transfer_func *func_shaper)
 {
int ret = 0;
 
-   if (shaper_size) {
+   if (shaper_size || tf != TRANSFER_FUNCTION_LINEAR) {
/* If DRM shaper LUT is set, we assume a linear color space
 * (linearized by DRM degamma 1D LUT or not)
 */
func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
-   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+   func_shaper->tf = tf;
+   func_shaper->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE;
 
-   ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, 
false);
+   ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, 
has_rom);
} else {
func_shaper->type = TF_TYPE_BYPASS;
func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
@@ -954,6 +957,7 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state 
*plane_state,
 struct dc_plane_state *dc_plane_state)
 {
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   enum amdgpu_transfer_function shaper_tf = 
AMDGPU_TRANSFER_FUNCTION_DEFAULT;
const struct drm_color_lut *shaper_lut;
uint32_t shaper_size;
int ret;
@@ -966,8 +970,11 @@ amdgpu_dm_plane_set_color_properties(struct 
drm_plane_state *plane_state,
 
shaper_lut = __extract_blob_lut(dm_plane_state->shaper_lut, 
_size);
shaper_size = shaper_lut != NULL ? shaper_size : 0;
+   shaper_tf = dm_plane_state->shaper_tf;
 
-   ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, shaper_size,
+   ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false,
+ amdgpu_tf_to_dc_tf(shaper_tf),
+ shaper_size,
  dc_plane_state->in_shaper_func);
if (ret)
drm_dbg_kms(plane_state->plane->dev,
-- 
2.40.1



[PATCH v3 29/32] drm/amd/display: copy 3D LUT settings from crtc state to stream_update

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

When commiting planes, we copy color mgmt resources to the stream state.
Do the same for shaper and 3D LUTs.

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 
 1 file changed, 4 insertions(+)

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 f4049ec7991d..581afa7c5f8c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8399,6 +8399,10 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
_state->stream->csc_color_matrix;
bundle->stream_update.out_transfer_func =
acrtc_state->stream->out_transfer_func;
+   bundle->stream_update.lut3d_func =
+   (struct dc_3dlut *) 
acrtc_state->stream->lut3d_func;
+   bundle->stream_update.func_shaper =
+   (struct dc_transfer_func *) 
acrtc_state->stream->func_shaper;
}
 
acrtc_state->stream->abm_level = acrtc_state->abm_level;
-- 
2.40.1



[PATCH v3 17/32] drm/amd/display: mark plane as needing reset if color props change

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

We should reset a plane state if at least one of the color management
properties differs from old and new state.

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++
 1 file changed, 15 insertions(+)

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 1ab2e0ecfb1d..f239326d85b9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9660,6 +9660,10 @@ static bool should_reset_plane(struct drm_atomic_state 
*state,
 */
for_each_oldnew_plane_in_state(state, other, old_other_state, 
new_other_state, i) {
struct amdgpu_framebuffer *old_afb, *new_afb;
+   struct dm_plane_state *dm_new_other_state, *dm_old_other_state;
+
+   dm_new_other_state = to_dm_plane_state(new_other_state);
+   dm_old_other_state = to_dm_plane_state(old_other_state);
 
if (other->type == DRM_PLANE_TYPE_CURSOR)
continue;
@@ -9696,6 +9700,17 @@ static bool should_reset_plane(struct drm_atomic_state 
*state,
old_other_state->color_encoding != 
new_other_state->color_encoding)
return true;
 
+   /* HDR/Transfer Function changes. */
+   if (dm_old_other_state->degamma_tf != 
dm_new_other_state->degamma_tf ||
+   dm_old_other_state->degamma_lut != 
dm_new_other_state->degamma_lut ||
+   dm_old_other_state->hdr_mult != 
dm_new_other_state->hdr_mult ||
+   dm_old_other_state->shaper_lut != 
dm_new_other_state->shaper_lut ||
+   dm_old_other_state->shaper_tf != 
dm_new_other_state->shaper_tf ||
+   dm_old_other_state->lut3d != dm_new_other_state->lut3d ||
+   dm_old_other_state->blend_lut != 
dm_new_other_state->blend_lut ||
+   dm_old_other_state->blend_tf != 
dm_new_other_state->blend_tf)
+   return true;
+
/* Framebuffer checks fall at the end. */
if (!old_other_state->fb || !new_other_state->fb)
continue;
-- 
2.40.1



[PATCH v3 21/32] drm/amd/display: add dc_fixpt_from_s3132 helper

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Detach value translation from CTM to reuse it for programming HDR
multiplier property.

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c  |  8 +---
 drivers/gpu/drm/amd/display/include/fixed31_32.h | 12 
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index fe8fca72efc8..c0b3ccd85a9f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -381,7 +381,6 @@ static void __drm_lut_to_dc_gamma(const struct 
drm_color_lut *lut,
 static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
   struct fixed31_32 *matrix)
 {
-   int64_t val;
int i;
 
/*
@@ -400,12 +399,7 @@ static void __drm_ctm_to_dc_matrix(const struct 
drm_color_ctm *ctm,
}
 
/* gamut_remap_matrix[i] = ctm[i - floor(i/4)] */
-   val = ctm->matrix[i - (i / 4)];
-   /* If negative, convert to 2's complement. */
-   if (val & (1ULL << 63))
-   val = -(val & ~(1ULL << 63));
-
-   matrix[i].value = val;
+   matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i - (i / 4)]);
}
 }
 
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h 
b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index d4cf7ead1d87..84da1dd34efd 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -69,6 +69,18 @@ static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
 static const struct fixed31_32 dc_fixpt_half = { 0x8000LL };
 static const struct fixed31_32 dc_fixpt_one = { 0x1LL };
 
+static inline struct fixed31_32 dc_fixpt_from_s3132(__u64 x)
+{
+   struct fixed31_32 val;
+
+   /* If negative, convert to 2's complement. */
+   if (x & (1ULL << 63))
+   x = -(x & ~(1ULL << 63));
+
+   val.value = x;
+   return val;
+}
+
 /*
  * @brief
  * Initialization routines
-- 
2.40.1



[PATCH v3 19/32] drm/amd/display: add plane degamma TF and LUT support

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Set DC plane with user degamma LUT or predefined TF from driver-specific
plane color properties. If plane and CRTC degamma are set in the same
time, plane degamma has priority.  That means, we only set CRTC degamma
if we don't have plane degamma LUT or TF to configure. We return -EINVAL
if we don't have plane degamma settings, so we can continue and check
CRTC degamma.

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 70 +--
 3 files changed, 69 insertions(+), 6 deletions(-)

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 f239326d85b9..341cde61bf0b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5130,7 +5130,9 @@ static int fill_dc_plane_attributes(struct amdgpu_device 
*adev,
 * Always set input transfer function, since plane state is refreshed
 * every time.
 */
-   ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dc_plane_state);
+   ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state,
+   plane_state,
+   dc_plane_state);
if (ret)
return ret;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 0140f4fb903e..b7b1d67f87a0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -907,6 +907,7 @@ int amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+ struct drm_plane_state *plane_state,
  struct dc_plane_state *dc_plane_state);
 
 void amdgpu_dm_update_connector_after_detect(
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index aa34501e2a32..a02c85511a3a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -839,9 +839,58 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
return 0;
 }
 
+static int
+__set_dm_plane_degamma(struct drm_plane_state *plane_state,
+  struct dc_plane_state *dc_plane_state)
+{
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   const struct drm_color_lut *degamma_lut;
+   enum amdgpu_transfer_function tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
+   uint32_t degamma_size;
+   bool has_degamma_lut;
+   int ret;
+
+   degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut,
+_size);
+
+   has_degamma_lut = degamma_lut &&
+ !__is_lut_linear(degamma_lut, degamma_size);
+
+   tf = dm_plane_state->degamma_tf;
+
+   /* If we don't have plane degamma LUT nor TF to set on DC, we have
+* nothing to do here, return.
+*/
+   if (!has_degamma_lut && tf == AMDGPU_TRANSFER_FUNCTION_DEFAULT)
+   return -EINVAL;
+
+   dc_plane_state->in_transfer_func->tf = amdgpu_tf_to_dc_tf(tf);
+
+   if (has_degamma_lut) {
+   ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
+
+   dc_plane_state->in_transfer_func->type =
+   TF_TYPE_DISTRIBUTED_POINTS;
+
+   ret = __set_input_tf(dc_plane_state->in_transfer_func,
+degamma_lut, degamma_size);
+   if (ret)
+   return ret;
+   } else {
+   dc_plane_state->in_transfer_func->type =
+   TF_TYPE_PREDEFINED;
+
+   if (!mod_color_calculate_degamma_params(NULL,
+   dc_plane_state->in_transfer_func, NULL, false))
+   return -ENOMEM;
+   }
+   return 0;
+}
+
 /**
  * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
  * @crtc: amdgpu_dm crtc state
+ * @plane_state: DRM plane state
  * @dc_plane_state: target DC surface
  *
  * Update the underlying dc_stream_state's input transfer function (ITF) in
@@ -852,13 +901,28 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
  * 0 on success. -ENOMEM if mem allocation fails.
  */
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+ struct drm_plane_state *plane_state,
  struct 

[PATCH v3 20/32] drm/amd/display: reject atomic commit if setting both plane and CRTC degamma

2023-09-25 Thread Melissa Wen
DC only has pre-blending degamma caps (plane/DPP) that is currently in
use for CRTC/post-blending degamma, so that we don't have HW caps to
perform plane and CRTC degamma at the same time. Reject atomic updates
when serspace sets both plane and CRTC degamma properties.

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a02c85511a3a..fe8fca72efc8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -915,9 +915,20 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
has_crtc_cm_degamma = (crtc->cm_has_degamma || 
crtc->cm_is_degamma_srgb);
 
ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
-   if (ret != -EINVAL)
+   if (ret == -ENOMEM)
return ret;
 
+   /* We only have one degamma block available (pre-blending) for the
+* whole color correction pipeline, so that we can't actually perform
+* plane and CRTC degamma at the same time. Explicitly reject atomic
+* updates when userspace sets both plane and CRTC degamma properties.
+*/
+   if (has_crtc_cm_degamma && ret != -EINVAL){
+   drm_dbg_kms(crtc->base.crtc->dev,
+   "doesn't support plane and CRTC degamma at the same 
time\n");
+   return -EINVAL;
+   }
+
/* If we are here, it means we don't have plane degamma settings, check
 * if we have CRTC degamma waiting for mapping to pre-blending degamma
 * block
-- 
2.40.1



[PATCH v3 32/32] drm/amd/display: Add 3x4 CTM support for plane CTM

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Create drm_color_ctm_3x4 to support 3x4-dimension plane CTM matrix and
convert DRM CTM to DC CSC float matrix.

v3:
- rename ctm2 to ctm_3x4 (Harry)

Signed-off-by: Joshua Ashton 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 28 +--
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   |  2 +-
 include/uapi/drm/drm_mode.h   |  8 ++
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 944dccd483de..774a83a9dee7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -410,6 +410,28 @@ static void __drm_ctm_to_dc_matrix(const struct 
drm_color_ctm *ctm,
}
 }
 
+/**
+ * __drm_ctm_3x4_to_dc_matrix - converts a DRM CTM 3x4 to a DC CSC float matrix
+ * @ctm: DRM color transformation matrix with 3x4 dimensions
+ * @matrix: DC CSC float matrix
+ *
+ * The matrix needs to be a 3x4 (12 entry) matrix.
+ */
+static void __drm_ctm_3x4_to_dc_matrix(const struct drm_color_ctm_3x4 *ctm,
+  struct fixed31_32 *matrix)
+{
+   int i;
+
+   /* The format provided is S31.32, using signed-magnitude representation.
+* Our fixed31_32 is also S31.32, but is using 2's complement. We have
+* to convert from signed-magnitude to 2's complement.
+*/
+   for (i = 0; i < 12; i++) {
+   /* gamut_remap_matrix[i] = ctm[i - floor(i/4)] */
+   matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i]);
+   }
+}
+
 /**
  * __set_legacy_tf - Calculates the legacy transfer function
  * @func: transfer function
@@ -1154,7 +1176,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct 
dm_crtc_state *crtc,
 {
struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev);
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
-   struct drm_color_ctm *ctm = NULL;
+   struct drm_color_ctm_3x4 *ctm = NULL;
struct dc_color_caps *color_caps = NULL;
bool has_crtc_cm_degamma;
int ret;
@@ -1208,7 +1230,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct 
dm_crtc_state *crtc,
 
/* Setup CRTC CTM. */
if (dm_plane_state->ctm) {
-   ctm = (struct drm_color_ctm *)dm_plane_state->ctm->data;
+   ctm = (struct drm_color_ctm_3x4 *)dm_plane_state->ctm->data;
/* DCN2 and older don't support both pre-blending and
 * post-blending gamut remap. For this HW family, if we have
 * the plane and CRTC CTMs simultaneously, CRTC CTM takes
@@ -1219,7 +1241,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct 
dm_crtc_state *crtc,
 * mapping CRTC CTM to MPC and keeping plane CTM setup at DPP,
 * as it's done by dcn30_program_gamut_remap().
 */
-   __drm_ctm_to_dc_matrix(ctm, 
dc_plane_state->gamut_remap_matrix.matrix);
+   __drm_ctm_3x4_to_dc_matrix(ctm, 
dc_plane_state->gamut_remap_matrix.matrix);
 
dc_plane_state->gamut_remap_matrix.enable_remap = true;
dc_plane_state->input_csc_color_matrix.enable_adjustment = 
false;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 98501f5044c2..a1f087b0f7e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1551,7 +1551,7 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
ret = drm_property_replace_blob_from_id(plane->dev,
_plane_state->ctm,
val,
-   sizeof(struct 
drm_color_ctm), -1,
+   sizeof(struct 
drm_color_ctm_3x4), -1,
);
dm_plane_state->base.color_mgmt_changed |= replaced;
return ret;
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 46becedf5b2f..a811d24e8ed5 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -838,6 +838,14 @@ struct drm_color_ctm {
__u64 matrix[9];
 };
 
+struct drm_color_ctm_3x4 {
+   /*
+* Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude
+* (not two's complement!) format.
+*/
+   __u64 matrix[12];
+};
+
 struct drm_color_lut {
/*
 * Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and
-- 
2.40.1



[PATCH v3 22/32] drm/amd/display: add HDR multiplier support

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

With `dc_fixpt_from_s3132()` translation, we can just use it to set
hdr_mult.

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   | 1 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 3 +++
 2 files changed, 4 insertions(+)

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 341cde61bf0b..455b690d6185 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8184,6 +8184,7 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
bundle->surface_updates[planes_count].gamma = 
dc_plane->gamma_correction;
bundle->surface_updates[planes_count].in_transfer_func 
= dc_plane->in_transfer_func;

bundle->surface_updates[planes_count].gamut_remap_matrix = 
_plane->gamut_remap_matrix;
+   bundle->surface_updates[planes_count].hdr_mult = 
dc_plane->hdr_mult;
}
 
amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index c0b3ccd85a9f..577a9dc669a5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -898,6 +898,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
  struct drm_plane_state *plane_state,
  struct dc_plane_state *dc_plane_state)
 {
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
bool has_crtc_cm_degamma;
int ret;
 
@@ -908,6 +909,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
/* After, we start to update values according to color props */
has_crtc_cm_degamma = (crtc->cm_has_degamma || 
crtc->cm_is_degamma_srgb);
 
+   dc_plane_state->hdr_mult = 
dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+
ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
if (ret == -ENOMEM)
return ret;
-- 
2.40.1



[PATCH v3 27/32] drm/amd/display: add plane blend LUT and TF support

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Map plane blend properties to DPP blend gamma. Plane blend is a
post-3D LUT curve that linearizes color space for blending. It may be
defined by a user-blob LUT and/or predefined transfer function. As
hardcoded curve (ROM) is not supported on blend gamma, we use AMD color
module to fill parameters when setting non-linear TF with empty LUT.

v2:
- rename DRM TFs to AMDGPU TFs

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 55 +--
 2 files changed, 52 insertions(+), 4 deletions(-)

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 0adf6e6c6e04..f4049ec7991d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8187,6 +8187,7 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
bundle->surface_updates[planes_count].hdr_mult = 
dc_plane->hdr_mult;
bundle->surface_updates[planes_count].func_shaper = 
dc_plane->in_shaper_func;
bundle->surface_updates[planes_count].lut3d_func = 
dc_plane->lut3d_func;
+   bundle->surface_updates[planes_count].blend_tf = 
dc_plane->blend_tf;
}
 
amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index cbebfd24ca78..15590677f209 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -702,6 +702,34 @@ static int amdgpu_dm_atomic_shaper_lut(const struct 
drm_color_lut *shaper_lut,
return ret;
 }
 
+static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut,
+  bool has_rom,
+  enum dc_transfer_func_predefined tf,
+  uint32_t blend_size,
+  struct dc_transfer_func *func_blend)
+{
+   int ret = 0;
+
+   if (blend_size || tf != TRANSFER_FUNCTION_LINEAR) {
+   /* DRM plane gamma LUT or TF means we are linearizing color
+* space before blending (similar to degamma programming). As
+* we don't have hardcoded curve support, or we use AMD color
+* module to fill the parameters that will be translated to HW
+* points.
+*/
+   func_blend->type = TF_TYPE_DISTRIBUTED_POINTS;
+   func_blend->tf = tf;
+   func_blend->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE;
+
+   ret = __set_input_tf(func_blend, blend_lut, blend_size);
+   } else {
+   func_blend->type = TF_TYPE_BYPASS;
+   func_blend->tf = TRANSFER_FUNCTION_LINEAR;
+   }
+
+   return ret;
+}
+
 /* amdgpu_dm_lut3d_size - get expected size according to hw color caps
  * @adev: amdgpu device
  * @lut_size: default size
@@ -1049,8 +1077,9 @@ amdgpu_dm_plane_set_color_properties(struct 
drm_plane_state *plane_state,
 {
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
enum amdgpu_transfer_function shaper_tf = 
AMDGPU_TRANSFER_FUNCTION_DEFAULT;
-   const struct drm_color_lut *shaper_lut, *lut3d;
-   uint32_t shaper_size, lut3d_size;
+   enum amdgpu_transfer_function blend_tf = 
AMDGPU_TRANSFER_FUNCTION_DEFAULT;
+   const struct drm_color_lut *shaper_lut, *lut3d, *blend_lut;
+   uint32_t shaper_size, lut3d_size, blend_size;
int ret;
 
/* We have nothing to do here, return */
@@ -1070,12 +1099,30 @@ amdgpu_dm_plane_set_color_properties(struct 
drm_plane_state *plane_state,
  amdgpu_tf_to_dc_tf(shaper_tf),
  shaper_size,
  dc_plane_state->in_shaper_func);
-   if (ret)
+   if (ret) {
drm_dbg_kms(plane_state->plane->dev,
"setting plane %d shaper LUT failed.\n",
plane_state->plane->index);
 
-   return ret;
+   return ret;
+   }
+
+   blend_tf = dm_plane_state->blend_tf;
+   blend_lut = __extract_blob_lut(dm_plane_state->blend_lut, _size);
+   blend_size = blend_lut != NULL ? blend_size : 0;
+
+   ret = amdgpu_dm_atomic_blend_lut(blend_lut, false,
+amdgpu_tf_to_dc_tf(blend_tf),
+blend_size, dc_plane_state->blend_tf);
+   if (ret) {
+   drm_dbg_kms(plane_state->plane->dev,
+   "setting plane %d gamma lut 

[PATCH v3 25/32] drm/amd/display: add plane 3D LUT support

2023-09-25 Thread Melissa Wen
Wire up DC 3D LUT to DM plane color management (pre-blending). On AMD
display HW, 3D LUT comes after a shaper curve and we always have to
program a shaper curve to delinearize or normalize the color space
before applying a 3D LUT (since we have a reduced number of LUT
entries).

In this version, the default values of 3D LUT for size and bit_depth are
17x17x17 and 12-bit, but we already provide here a more generic
mechanisms to program other supported values (9x9x9 size and 10-bit).

v2:
- started with plane 3D LUT instead of CRTC 3D LUT support

Reviewed-by: Harry Wentland  (v1)
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 96 ++-
 2 files changed, 94 insertions(+), 3 deletions(-)

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 af18c523c431..0adf6e6c6e04 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8186,6 +8186,7 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,

bundle->surface_updates[planes_count].gamut_remap_matrix = 
_plane->gamut_remap_matrix;
bundle->surface_updates[planes_count].hdr_mult = 
dc_plane->hdr_mult;
bundle->surface_updates[planes_count].func_shaper = 
dc_plane->in_shaper_func;
+   bundle->surface_updates[planes_count].lut3d_func = 
dc_plane->lut3d_func;
}
 
amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a085f98c8e90..dcdf9b580e23 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -594,6 +594,85 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf)
}
 }
 
+static void __to_dc_lut3d_color(struct dc_rgb *rgb,
+   const struct drm_color_lut lut,
+   int bit_precision)
+{
+   rgb->red = drm_color_lut_extract(lut.red, bit_precision);
+   rgb->green = drm_color_lut_extract(lut.green, bit_precision);
+   rgb->blue  = drm_color_lut_extract(lut.blue, bit_precision);
+}
+
+static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
+   uint32_t lut3d_size,
+   struct tetrahedral_params *params,
+   bool use_tetrahedral_9,
+   int bit_depth)
+{
+   struct dc_rgb *lut0;
+   struct dc_rgb *lut1;
+   struct dc_rgb *lut2;
+   struct dc_rgb *lut3;
+   int lut_i, i;
+
+
+   if (use_tetrahedral_9) {
+   lut0 = params->tetrahedral_9.lut0;
+   lut1 = params->tetrahedral_9.lut1;
+   lut2 = params->tetrahedral_9.lut2;
+   lut3 = params->tetrahedral_9.lut3;
+   } else {
+   lut0 = params->tetrahedral_17.lut0;
+   lut1 = params->tetrahedral_17.lut1;
+   lut2 = params->tetrahedral_17.lut2;
+   lut3 = params->tetrahedral_17.lut3;
+   }
+
+   for (lut_i = 0, i = 0; i < lut3d_size - 4; lut_i++, i += 4) {
+   /* We should consider the 3dlut RGB values are distributed
+* along four arrays lut0-3 where the first sizes 1229 and the
+* other 1228. The bit depth supported for 3dlut channel is
+* 12-bit, but DC also supports 10-bit.
+*
+* TODO: improve color pipeline API to enable the userspace set
+* bit depth and 3D LUT size/stride, as specified by VA-API.
+*/
+   __to_dc_lut3d_color([lut_i], lut[i], bit_depth);
+   __to_dc_lut3d_color([lut_i], lut[i + 1], bit_depth);
+   __to_dc_lut3d_color([lut_i], lut[i + 2], bit_depth);
+   __to_dc_lut3d_color([lut_i], lut[i + 3], bit_depth);
+   }
+   /* lut0 has 1229 points (lut_size/4 + 1) */
+   __to_dc_lut3d_color([lut_i], lut[i], bit_depth);
+}
+
+/* amdgpu_dm_atomic_lut3d - set DRM 3D LUT to DC stream
+ * @drm_lut3d: DRM CRTC (user) 3D LUT
+ * @drm_lut3d_size: size of 3D LUT
+ * @lut3d: DC 3D LUT
+ *
+ * Map DRM CRTC 3D LUT to DC 3D LUT and all necessary bits to program it
+ * on DCN MPC accordingly.
+ */
+static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
+  uint32_t drm_lut3d_size,
+  struct dc_3dlut *lut)
+{
+   if (!drm_lut3d_size) {
+   lut->state.bits.initialized = 0;
+   } else {
+   /* Stride and bit depth are not programmable by API yet.
+* Therefore, only supports 17x17x17 3D LUT (12-bit).

[PATCH v3 15/32] drm/amd/display: add CRTC gamma TF support

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Add predefined transfer function programming. There is no pre-blending
out gamma ROM, but we can use AMD color modules to program LUT
parameters from a pre-defined TF and an empty regamma LUT (or bump up
LUT parameters with pre-defined TF setup).

v2:
- update crtc color mgmt if regamma TF differs between states (Joshua)
- map inverse EOTF to DC transfer function (Melissa)

v3:
- update AMDGPU TF list

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 71 ++-
 2 files changed, 56 insertions(+), 16 deletions(-)

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 1ad16850e8c5..1ab2e0ecfb1d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9592,6 +9592,7 @@ static int dm_update_crtc_state(struct 
amdgpu_display_manager *dm,
 * when a modeset is needed, to ensure it gets reprogrammed.
 */
if (dm_new_crtc_state->base.color_mgmt_changed ||
+   dm_old_crtc_state->regamma_tf != dm_new_crtc_state->regamma_tf ||
drm_atomic_crtc_needs_modeset(new_crtc_state)) {
ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state);
if (ret)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index e82ca33cea1c..0fe2f76193ee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -466,16 +466,18 @@ static int __set_output_tf(struct dc_transfer_func *func,
struct calculate_buffer cal_buffer = {0};
bool res;
 
-   ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
-
cal_buffer.buffer_index = -1;
 
-   gamma = dc_create_gamma();
-   if (!gamma)
-   return -ENOMEM;
+   if (lut_size) {
+   ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
 
-   gamma->num_entries = lut_size;
-   __drm_lut_to_dc_gamma(lut, gamma, false);
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
+
+   gamma->num_entries = lut_size;
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+   }
 
if (func->tf == TRANSFER_FUNCTION_LINEAR) {
/*
@@ -483,32 +485,36 @@ static int __set_output_tf(struct dc_transfer_func *func,
 * on top of a linear input. But degamma params can be used
 * instead to simulate this.
 */
-   gamma->type = GAMMA_CUSTOM;
+   if (gamma)
+   gamma->type = GAMMA_CUSTOM;
res = mod_color_calculate_degamma_params(NULL, func,
-   gamma, true);
+gamma, gamma != NULL);
} else {
/*
 * Assume sRGB. The actual mapping will depend on whether the
 * input was legacy or not.
 */
-   gamma->type = GAMMA_CS_TFM_1D;
-   res = mod_color_calculate_regamma_params(func, gamma, false,
+   if (gamma)
+   gamma->type = GAMMA_CS_TFM_1D;
+   res = mod_color_calculate_regamma_params(func, gamma, gamma != 
NULL,
 has_rom, NULL, 
_buffer);
}
 
-   dc_gamma_release();
+   if (gamma)
+   dc_gamma_release();
 
return res ? 0 : -ENOMEM;
 }
 
 static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
const struct drm_color_lut *regamma_lut,
-   uint32_t regamma_size, bool has_rom)
+   uint32_t regamma_size, bool has_rom,
+   enum dc_transfer_func_predefined tf)
 {
struct dc_transfer_func *out_tf = stream->out_transfer_func;
int ret = 0;
 
-   if (regamma_size) {
+   if (regamma_size || tf != TRANSFER_FUNCTION_LINEAR) {
/* CRTC RGM goes into RGM LUT.
 *
 * Note: there is no implicit sRGB regamma here. We are using
@@ -516,7 +522,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
 * from a linear base.
 */
out_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
-   out_tf->tf = TRANSFER_FUNCTION_LINEAR;
+   out_tf->tf = tf;
 
ret = __set_output_tf(out_tf, regamma_lut, regamma_size, 
has_rom);
} else {
@@ -562,6 +568,36 @@ static int __set_input_tf(struct 

[PATCH v3 30/32] drm/amd/display: add plane CTM driver-specific property

2023-09-25 Thread Melissa Wen
Plane CTM for pre-blending color space conversion. Only enable
driver-specific plane CTM property on drivers that support both pre- and
post-blending gamut remap matrix, i.e., DCN3+ family. Otherwise it
conflits with DRM CRTC CTM property.

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  2 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  7 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   |  7 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 20 +++
 4 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 2587847ae318..15f820926a3f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -363,6 +363,8 @@ struct amdgpu_mode_info {
 * @plane_hdr_mult_property:
 */
struct drm_property *plane_hdr_mult_property;
+
+   struct drm_property *plane_ctm_property;
/**
 * @shaper_lut_property: Plane property to set pre-blending shaper LUT
 * that converts color content before 3D LUT. If
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index ad583cc97f15..e3fbc242d9a4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -773,6 +773,13 @@ struct dm_plane_state {
 * S31.32 sign-magnitude.
 */
__u64 hdr_mult;
+   /**
+* @ctm:
+*
+* Color transformation matrix. The blob (if not NULL) is a 
+* drm_color_ctm_3x4.
+*/
+   struct drm_property_blob *ctm;
/**
 * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an
 * array of  drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 7871256f0e5f..26338f565574 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -216,6 +216,13 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_hdr_mult_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_CTM", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_ctm_property = prop;
+
prop = drm_property_create(adev_to_drm(adev),
   DRM_MODE_PROP_BLOB,
   "AMD_PLANE_SHAPER_LUT", 0);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index c7aeb9f06fa7..98501f5044c2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1363,6 +1363,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 
if (dm_plane_state->degamma_lut)
drm_property_blob_get(dm_plane_state->degamma_lut);
+   if (dm_plane_state->ctm)
+   drm_property_blob_get(dm_plane_state->ctm);
if (dm_plane_state->shaper_lut)
drm_property_blob_get(dm_plane_state->shaper_lut);
if (dm_plane_state->lut3d)
@@ -1444,6 +1446,8 @@ static void dm_drm_plane_destroy_state(struct drm_plane 
*plane,
 
if (dm_plane_state->degamma_lut)
drm_property_blob_put(dm_plane_state->degamma_lut);
+   if (dm_plane_state->ctm)
+   drm_property_blob_put(dm_plane_state->ctm);
if (dm_plane_state->lut3d)
drm_property_blob_put(dm_plane_state->lut3d);
if (dm_plane_state->shaper_lut)
@@ -1481,6 +1485,11 @@ dm_atomic_plane_attach_color_mgmt_properties(struct 
amdgpu_display_manager *dm,
   dm->adev->mode_info.plane_hdr_mult_property,
   AMDGPU_HDR_MULT_DEFAULT);
 
+   /* Only enable plane CTM if both DPP and MPC gamut remap is available. 
*/
+   if (dm->dc->caps.color.mpc.gamut_remap)
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_ctm_property, 0);
+
if (dpp_color_caps.hw_3d_lut) {
drm_object_attach_property(>base,
   mode_info.plane_shaper_lut_property, 
0);
@@ -1538,6 +1547,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
dm_plane_state->hdr_mult = val;
dm_plane_state->base.color_mgmt_changed = 1;
}
+   } else if (property == adev->mode_info.plane_ctm_property) {
+   ret = drm_property_replace_blob_from_id(plane->dev,
+  

[PATCH v3 23/32] drm/amd/display: add plane shaper LUT support

2023-09-25 Thread Melissa Wen
Map DC shaper LUT to DM plane color management. Shaper LUT can be used
to delinearize and/or normalize the color space for computational
efficiency and achiving specific visual styles. If a plane degamma is
apply to linearize the color space, a custom shaper 1D LUT can be used
just before applying 3D LUT.

v2:
- use DPP color caps to verify plane 3D LUT support
- add debug message if shaper LUT programming fails

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   1 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 108 +-
 3 files changed, 107 insertions(+), 4 deletions(-)

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 455b690d6185..af18c523c431 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8185,6 +8185,7 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
bundle->surface_updates[planes_count].in_transfer_func 
= dc_plane->in_transfer_func;

bundle->surface_updates[planes_count].gamut_remap_matrix = 
_plane->gamut_remap_matrix;
bundle->surface_updates[planes_count].hdr_mult = 
dc_plane->hdr_mult;
+   bundle->surface_updates[planes_count].func_shaper = 
dc_plane->in_shaper_func;
}
 
amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b7b1d67f87a0..ad583cc97f15 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -897,6 +897,8 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 /* 3D LUT max size is 17x17x17 */
 #define MAX_COLOR_3DLUT_ENTRIES 4913
 #define MAX_COLOR_3DLUT_BITDEPTH 12
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+   struct drm_plane_state *plane_state);
 /* 1D LUT size */
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 577a9dc669a5..8c991b5cf473 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -594,6 +594,74 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf)
}
 }
 
+static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+  uint32_t shaper_size,
+  struct dc_transfer_func *func_shaper)
+{
+   int ret = 0;
+
+   if (shaper_size) {
+   /* If DRM shaper LUT is set, we assume a linear color space
+* (linearized by DRM degamma 1D LUT or not)
+*/
+   func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
+   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+
+   ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, 
false);
+   } else {
+   func_shaper->type = TF_TYPE_BYPASS;
+   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+   }
+
+   return ret;
+}
+
+/* amdgpu_dm_lut3d_size - get expected size according to hw color caps
+ * @adev: amdgpu device
+ * @lut_size: default size
+ *
+ * Return:
+ * lut_size if DC 3D LUT is supported, zero otherwise.
+ */
+static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev,
+uint32_t lut_size)
+{
+   return adev->dm.dc->caps.color.dpp.hw_3d_lut ? lut_size : 0;
+}
+
+/**
+ * amdgpu_dm_verify_lut3d_size - verifies if 3D LUT is supported and if DRM 3D
+ * LUT matches the hw supported size
+ * @adev: amdgpu device
+ * @crtc_state: the DRM CRTC state
+ *
+ * Verifies if post-blending (MPC) 3D LUT is supported by the HW (DCN 3.0 or
+ * newer) and if the DRM 3D LUT matches the supported size.
+ *
+ * Returns:
+ * 0 on success. -EINVAL if lut size are invalid.
+ */
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+   struct drm_plane_state *plane_state)
+{
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   const struct drm_color_lut *shaper = NULL;
+   uint32_t exp_size, size;
+
+   /* shaper LUT is only available if 3D LUT color caps*/
+   exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_LUT_ENTRIES);
+   shaper = __extract_blob_lut(dm_plane_state->shaper_lut, );
+
+   if (shaper && size != exp_size) {
+   drm_dbg(>ddev,
+   "Invalid Shaper LUT size. Should be %u but got %u.\n",
+   exp_size, size);
+ 

[PATCH v3 28/32] drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Need to funnel the color caps through to these functions so it can check
that the hardware is capable.

v2:
- remove redundant color caps assignment on plane degamma map (Harry)
- pass color caps to degamma params

v3:
- remove unused color_caps parameter from set_color_properties (Harry)

Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 29 ---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 15590677f209..7871256f0e5f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -536,6 +536,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
+ * @caps: dc color capabilities
  * @func: transfer function
  * @lut: lookup table that defines the color space
  * @lut_size: size of respective lut.
@@ -543,7 +544,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
  * Returns:
  * 0 in case of success. -ENOMEM if fails.
  */
-static int __set_input_tf(struct dc_transfer_func *func,
+static int __set_input_tf(struct dc_color_caps *caps, struct dc_transfer_func 
*func,
  const struct drm_color_lut *lut, uint32_t lut_size)
 {
struct dc_gamma *gamma = NULL;
@@ -560,7 +561,7 @@ static int __set_input_tf(struct dc_transfer_func *func,
__drm_lut_to_dc_gamma(lut, gamma, false);
}
 
-   res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != 
NULL);
+   res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != 
NULL);
 
if (gamma)
dc_gamma_release();
@@ -721,7 +722,7 @@ static int amdgpu_dm_atomic_blend_lut(const struct 
drm_color_lut *blend_lut,
func_blend->tf = tf;
func_blend->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE;
 
-   ret = __set_input_tf(func_blend, blend_lut, blend_size);
+   ret = __set_input_tf(NULL, func_blend, blend_lut, blend_size);
} else {
func_blend->type = TF_TYPE_BYPASS;
func_blend->tf = TRANSFER_FUNCTION_LINEAR;
@@ -946,7 +947,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
 
 static int
 map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
-struct dc_plane_state *dc_plane_state)
+struct dc_plane_state *dc_plane_state,
+struct dc_color_caps *caps)
 {
const struct drm_color_lut *degamma_lut;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -1001,7 +1003,7 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
dc_plane_state->in_transfer_func->tf =
TRANSFER_FUNCTION_LINEAR;
 
-   r = __set_input_tf(dc_plane_state->in_transfer_func,
+   r = __set_input_tf(caps, dc_plane_state->in_transfer_func,
   degamma_lut, degamma_size);
if (r)
return r;
@@ -1014,7 +1016,7 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
dc_plane_state->in_transfer_func->tf = tf;
 
if (tf != TRANSFER_FUNCTION_SRGB &&
-   !mod_color_calculate_degamma_params(NULL,
+   !mod_color_calculate_degamma_params(caps,

dc_plane_state->in_transfer_func,
NULL, false))
return -ENOMEM;
@@ -1025,7 +1027,8 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 
 static int
 __set_dm_plane_degamma(struct drm_plane_state *plane_state,
-  struct dc_plane_state *dc_plane_state)
+  struct dc_plane_state *dc_plane_state,
+  struct dc_color_caps *color_caps)
 {
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
const struct drm_color_lut *degamma_lut;
@@ -1056,7 +1059,7 @@ __set_dm_plane_degamma(struct drm_plane_state 
*plane_state,
dc_plane_state->in_transfer_func->type =
TF_TYPE_DISTRIBUTED_POINTS;
 
-   ret = __set_input_tf(dc_plane_state->in_transfer_func,
+   ret = __set_input_tf(color_caps, 
dc_plane_state->in_transfer_func,
 degamma_lut, degamma_size);
if (ret)
return ret;
@@ -1064,7 +1067,7 @@ __set_dm_plane_degamma(struct drm_plane_state 
*plane_state,
dc_plane_state->in_transfer_func->type =

[PATCH v3 18/32] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane

2023-09-25 Thread Melissa Wen
The next patch adds pre-blending degamma to AMD color mgmt pipeline, but
pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC
atomic degamma or implict degamma on legacy gamma. Detach degamma usage
regarging CRTC color properties to manage plane and CRTC color
correction combinations.

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 59 +--
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 9d09a62645b9..aa34501e2a32 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -760,20 +760,9 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
return 0;
 }
 
-/**
- * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
- * @crtc: amdgpu_dm crtc state
- * @dc_plane_state: target DC surface
- *
- * Update the underlying dc_stream_state's input transfer function (ITF) in
- * preparation for hardware commit. The transfer function used depends on
- * the preparation done on the stream for color management.
- *
- * Returns:
- * 0 on success. -ENOMEM if mem allocation fails.
- */
-int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
- struct dc_plane_state *dc_plane_state)
+static int
+map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
+struct dc_plane_state *dc_plane_state)
 {
const struct drm_color_lut *degamma_lut;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -796,8 +785,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
 _size);
ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
 
-   dc_plane_state->in_transfer_func->type =
-   TF_TYPE_DISTRIBUTED_POINTS;
+   dc_plane_state->in_transfer_func->type = 
TF_TYPE_DISTRIBUTED_POINTS;
 
/*
 * This case isn't fully correct, but also fairly
@@ -833,7 +821,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
   degamma_lut, degamma_size);
if (r)
return r;
-   } else if (crtc->cm_is_degamma_srgb) {
+   } else {
/*
 * For legacy gamma support we need the regamma input
 * in linear space. Assume that the input is sRGB.
@@ -843,8 +831,43 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
 
if (tf != TRANSFER_FUNCTION_SRGB &&
!mod_color_calculate_degamma_params(NULL,
-   dc_plane_state->in_transfer_func, NULL, false))
+   
dc_plane_state->in_transfer_func,
+   NULL, false))
return -ENOMEM;
+   }
+
+   return 0;
+}
+
+/**
+ * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
+ * @crtc: amdgpu_dm crtc state
+ * @dc_plane_state: target DC surface
+ *
+ * Update the underlying dc_stream_state's input transfer function (ITF) in
+ * preparation for hardware commit. The transfer function used depends on
+ * the preparation done on the stream for color management.
+ *
+ * Returns:
+ * 0 on success. -ENOMEM if mem allocation fails.
+ */
+int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+ struct dc_plane_state *dc_plane_state)
+{
+   bool has_crtc_cm_degamma;
+   int ret;
+
+   has_crtc_cm_degamma = (crtc->cm_has_degamma || 
crtc->cm_is_degamma_srgb);
+   if (has_crtc_cm_degamma){
+   /* AMD HW doesn't have post-blending degamma caps. When DRM
+* CRTC atomic degamma is set, we maps it to DPP degamma block
+* (pre-blending) or, on legacy gamma, we use DPP degamma to
+* linearize (implicit degamma) from sRGB/BT709 according to
+* the input space.
+*/
+   ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
+   if (ret)
+   return ret;
} else {
/* ...Otherwise we can just bypass the DGM block. */
dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
-- 
2.40.1



[PATCH v3 12/32] drm/amd/display: add CRTC gamma TF driver-specific property

2023-09-25 Thread Melissa Wen
Add AMD pre-defined transfer function property to default DRM CRTC
gamma to convert to wire encoding with or without a user gamma LUT.
There is no post-blending regamma ROM for pre-defined TF. When setting
blend TF (!= Identity) and LUT at the same time, the color module will
combine the pre-defined TF and the custom LUT values into the LUT that's
actually programmed.

v2:
- enable CRTC prop in the end of driver-specific prop sequence
- define inverse EOTFs as supported regamma TFs
- reword driver-specific function doc to remove shaper/3D LUT

v3:
- spell out TF+LUT behavior in the commit and comments (Harry)

Co-developed-by: Joshua Ashton 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  7 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  8 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   |  7 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 72 +++
 4 files changed, 94 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index f333102845b7..2587847ae318 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -423,6 +423,13 @@ struct amdgpu_mode_info {
 * from a combination of pre-defined TF and the custom 1D LUT).
 */
struct drm_property *plane_blend_tf_property;
+   /* @regamma_tf_property: Transfer function for CRTC regamma
+* (post-blending). Possible values are defined by `enum
+* amdgpu_transfer_function`. There is no regamma ROM, but we can use
+* AMD color modules to program LUT parameters from predefined TF (or
+* from a combination of pre-defined TF and the custom 1D LUT).
+*/
+   struct drm_property *regamma_tf_property;
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 0d6f7b0f47bc..0140f4fb903e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -825,6 +825,14 @@ struct dm_crtc_state {
struct dc_info_packet vrr_infopacket;
 
int abm_level;
+
+/**
+* @regamma_tf:
+*
+* Pre-defined transfer function for converting internal FB -> wire
+* encoding.
+*/
+   enum amdgpu_transfer_function regamma_tf;
 };
 
 #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index b76d1eb82267..c9bfb80e9073 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -271,6 +271,13 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_blend_tf_property = prop;
 
+   prop = amdgpu_create_tf_property(adev_to_drm(adev),
+"AMD_CRTC_REGAMMA_TF",
+amdgpu_inv_eotf);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.regamma_tf_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index fb51ec4f8d31..128e37ed5397 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -260,6 +260,7 @@ static struct drm_crtc_state 
*dm_crtc_duplicate_state(struct drm_crtc *crtc)
state->freesync_config = cur->freesync_config;
state->cm_has_degamma = cur->cm_has_degamma;
state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb;
+   state->regamma_tf = cur->regamma_tf;
state->crc_skip_count = cur->crc_skip_count;
state->mpo_requested = cur->mpo_requested;
/* TODO Duplicate dc_stream after objects are stream object is 
flattened */
@@ -296,6 +297,70 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc 
*crtc)
 }
 #endif
 
+#ifdef AMD_PRIVATE_COLOR
+/**
+ * drm_crtc_additional_color_mgmt - enable additional color properties
+ * @crtc: DRM CRTC
+ *
+ * This function lets the driver enable post-blending CRTC regamma transfer
+ * function property in addition to DRM CRTC gamma LUT. Default value means
+ * linear transfer function, which is the default CRTC gamma LUT behaviour
+ * without this property.
+ */
+static void
+dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
+{
+   struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+
+   if(adev->dm.dc->caps.color.mpc.ogam_ram)
+   drm_object_attach_property(>base,
+  adev->mode_info.regamma_tf_property,
+  AMDGPU_TRANSFER_FUNCTION_DEFAULT);
+}
+
+static 

[PATCH v3 14/32] drm/amd/display: encapsulate atomic regamma operation

2023-09-25 Thread Melissa Wen
We will wire up MPC 3D LUT to DM CRTC color pipeline in the next patch,
but so far, only for atomic interface. By checking
set_output_transfer_func in DC drivers with MPC 3D LUT support, we can
verify that regamma is only programmed when 3D LUT programming fails. As
a groundwork to introduce 3D LUT programming and better understand each
step, detach atomic regamma programming from the crtc colocr updating
code.

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 53 ---
 1 file changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a288ba729502..e82ca33cea1c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -501,6 +501,36 @@ static int __set_output_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
+static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
+   const struct drm_color_lut *regamma_lut,
+   uint32_t regamma_size, bool has_rom)
+{
+   struct dc_transfer_func *out_tf = stream->out_transfer_func;
+   int ret = 0;
+
+   if (regamma_size) {
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: there is no implicit sRGB regamma here. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
+   out_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
+   out_tf->tf = TRANSFER_FUNCTION_LINEAR;
+
+   ret = __set_output_tf(out_tf, regamma_lut, regamma_size, 
has_rom);
+   } else {
+   /*
+* No CRTC RGM means we can just put the block into bypass
+* since we don't have any plane level adjustments using it.
+*/
+   out_tf->type = TF_TYPE_BYPASS;
+   out_tf->tf = TRANSFER_FUNCTION_LINEAR;
+   }
+
+   return ret;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -648,27 +678,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
regamma_size, has_rom);
if (r)
return r;
-   } else if (has_regamma) {
-   /* CRTC RGM goes into RGM LUT.
-*
-* Note: there is no implicit sRGB regamma here. We are using
-* degamma calculation from color module to calculate the curve
-* from a linear base.
-*/
-   stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-
-   r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-   regamma_size, has_rom);
+   } else {
+   regamma_size = has_regamma ? regamma_size : 0;
+   r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
+regamma_size, has_rom);
if (r)
return r;
-   } else {
-   /*
-* No CRTC RGM means we can just put the block into bypass
-* since we don't have any plane level adjustments using it.
-*/
-   stream->out_transfer_func->type = TF_TYPE_BYPASS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
}
 
/*
-- 
2.40.1



[PATCH v3 11/32] drm/amd/display: add plane blend LUT and TF driver-specific properties

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Blend 1D LUT or a pre-defined transfer function (TF) can be set to
linearize content before blending, so that it's positioned just before
blending planes in the AMD color mgmt pipeline, and after 3D LUT
(non-linear space). Shaper and Blend LUTs are 1D LUTs that sandwich 3D
LUT. Drivers should advertize blend properties according to HW caps.

There is no blend ROM for pre-defined TF. When setting blend TF (!=
Identity) and LUT at the same time, the color module will combine the
pre-defined TF and the custom LUT values into the LUT that's actually
programmed.

v3:
- spell out TF+LUT behavior in the commit and comments (Harry)

Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 22 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 21 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 36 +++
 4 files changed, 91 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 80ccda0ffc0d..f333102845b7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -401,6 +401,28 @@ struct amdgpu_mode_info {
 * is the max size of one dimension cubed.
 */
struct drm_property *plane_lut3d_size_property;
+   /**
+* @plane_blend_lut_property: Plane property for output gamma before
+* blending. Userspace set a blend LUT to convert colors after 3D LUT
+* conversion. It works as a post-3D LUT 1D LUT, with shaper LUT, they
+* are sandwiching 3D LUT with two 1D LUT. If plane_blend_tf_property
+* != Identity TF, AMD color module will combine the user LUT values
+* with pre-defined TF into the LUT parameters to be programmed.
+*/
+   struct drm_property *plane_blend_lut_property;
+   /**
+* @plane_blend_lut_size_property: Plane property to define the max
+* size of blend LUT as supported by the driver (read-only).
+*/
+   struct drm_property *plane_blend_lut_size_property;
+   /**
+* @plane_blend_tf_property: Plane property to set a predefined
+* transfer function for pre-blending blend/out_gamma (after applying
+* 3D LUT) with or without LUT. There is no blend ROM, but we can use
+* AMD color modules to program LUT parameters from predefined TF (or
+* from a combination of pre-defined TF and the custom 1D LUT).
+*/
+   struct drm_property *plane_blend_tf_property;
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b820bcfedba0..0d6f7b0f47bc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -789,6 +789,18 @@ struct dm_plane_state {
 *  drm_color_lut.
 */
struct drm_property_blob *lut3d;
+   /**
+* @blend_lut: blend lut lookup table blob. The blob (if not NULL) is an
+* array of  drm_color_lut.
+*/
+   struct drm_property_blob *blend_lut;
+   /**
+* @blend_tf:
+*
+* Pre-defined transfer function for converting plane pixel data before
+* applying blend LUT.
+*/
+   enum amdgpu_transfer_function blend_tf;
 };
 
 struct dm_crtc_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index c9e61359a610..b76d1eb82267 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -250,6 +250,27 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_lut3d_size_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_BLEND_LUT", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_blend_lut_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_BLEND_LUT_SIZE", 0, 
UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_blend_lut_size_property = prop;
+
+   prop = amdgpu_create_tf_property(adev_to_drm(adev),
+"AMD_PLANE_BLEND_TF",
+amdgpu_eotf);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_blend_tf_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 

[PATCH v3 08/32] drm/amd/display: add plane HDR multiplier driver-specific property

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
nits for SDR content. So if you want, 203 nits for SDR content, pass in
(203.0 / 80.0).

Signed-off-by: Joshua Ashton 
Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h   |  4 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h  | 14 ++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c|  6 ++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c| 13 +
 4 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 6ef958a14e16..66bae0eed80c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -359,6 +359,10 @@ struct amdgpu_mode_info {
 * to go from scanout/encoded values to linear values.
 */
struct drm_property *plane_degamma_tf_property;
+   /**
+* @plane_hdr_mult_property:
+*/
+   struct drm_property *plane_hdr_mult_property;
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 98f7267d5ee7..7ca594c7dfbe 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -54,6 +54,9 @@
 #define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x1A
 #define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40
 #define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_VERSION_3 0x3
+
+#define AMDGPU_HDR_MULT_DEFAULT (0x1LL)
+
 /*
 #include "include/amdgpu_dal_power_if.h"
 #include "amdgpu_dm_irq.h"
@@ -759,6 +762,17 @@ struct dm_plane_state {
 * linearize.
 */
enum amdgpu_transfer_function degamma_tf;
+   /**
+* @hdr_mult:
+*
+* Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
+* func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
+* AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
+* Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
+* want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
+* S31.32 sign-magnitude.
+*/
+   __u64 hdr_mult;
 };
 
 struct dm_crtc_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 14f9c02539c6..f274909c0c7e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -201,6 +201,12 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_degamma_tf_property = prop;
 
+   prop = drm_property_create_range(adev_to_drm(adev),
+0, "AMD_PLANE_HDR_MULT", 0, U64_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_hdr_mult_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 4f4c59c4f089..b66da6b76f5c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1339,6 +1339,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 
__drm_atomic_helper_plane_reset(plane, _state->base);
amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
+   amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
 }
 
 static struct drm_plane_state *
@@ -1362,6 +1363,7 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
drm_property_blob_get(dm_plane_state->degamma_lut);
 
dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf;
+   dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult;
 
return _plane_state->base;
 }
@@ -1458,6 +1460,10 @@ dm_atomic_plane_attach_color_mgmt_properties(struct 
amdgpu_display_manager *dm,
   
dm->adev->mode_info.plane_degamma_tf_property,
   AMDGPU_TRANSFER_FUNCTION_DEFAULT);
}
+   /* HDR MULT is always available */
+   drm_object_attach_property(>base,
+  dm->adev->mode_info.plane_hdr_mult_property,
+  AMDGPU_HDR_MULT_DEFAULT);
 }
 
 static int
@@ -1484,6 +1490,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
dm_plane_state->degamma_tf = val;
dm_plane_state->base.color_mgmt_changed = 1;
}
+   } else if (property == 

[PATCH v3 13/32] drm/amd/display: add comments to describe DM crtc color mgmt behavior

2023-09-25 Thread Melissa Wen
Describe some expected behavior of the AMD DM color mgmt programming.

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index c9bfb80e9073..a288ba729502 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -638,12 +638,23 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
 
+   /* Note: although we pass has_rom as parameter here, we never
+* actually use ROM because the color module only takes the ROM
+* path if transfer_func->type == PREDEFINED.
+*
+* See more in mod_color_calculate_regamma_params()
+*/
r = __set_legacy_tf(stream->out_transfer_func, regamma_lut,
regamma_size, has_rom);
if (r)
return r;
} else if (has_regamma) {
-   /* If atomic regamma, CRTC RGM goes into RGM LUT. */
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: there is no implicit sRGB regamma here. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
-- 
2.40.1



[PATCH v3 10/32] drm/amd/display: add plane shaper LUT and TF driver-specific properties

2023-09-25 Thread Melissa Wen
On AMD HW, 3D LUT always assumes a preceding shaper 1D LUT used for
delinearizing and/or normalizing the color space before applying a 3D
LUT. Add pre-defined transfer function to enable delinearizing content
with or without shaper LUT, where AMD color module calculates the
resulted shaper curve. We apply an inverse EOTF to go from linear
values to encoded values. If we are already in a non-linear space and/or
don't need to normalize values, we can bypass shaper LUT with a linear
transfer function that is also the default TF value.

There is no shaper ROM. When setting shaper TF (!= Identity) and LUT at
the same time, the color module will combine the pre-defined TF and the
custom LUT values into the LUT that's actually programmed.

v2:
- squash commits for shaper LUT and shaper TF
- define inverse EOTF as supported shaper TFs

v3:
- spell out TF+LUT behavior in the commit and comments (Harry)
- replace BT709 EOTF by inv OETF

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 21 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 11 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 29 +
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 32 +++
 4 files changed, 93 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1b5f25989f7f..80ccda0ffc0d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -363,6 +363,27 @@ struct amdgpu_mode_info {
 * @plane_hdr_mult_property:
 */
struct drm_property *plane_hdr_mult_property;
+   /**
+* @shaper_lut_property: Plane property to set pre-blending shaper LUT
+* that converts color content before 3D LUT. If
+* plane_shaper_tf_property != Identity TF, AMD color module will
+* combine the user LUT values with pre-defined TF into the LUT
+* parameters to be programmed.
+*/
+   struct drm_property *plane_shaper_lut_property;
+   /**
+* @shaper_lut_size_property: Plane property for the size of
+* pre-blending shaper LUT as supported by the driver (read-only).
+*/
+   struct drm_property *plane_shaper_lut_size_property;
+   /**
+* @plane_shaper_tf_property: Plane property to set a predefined
+* transfer function for pre-blending shaper (before applying 3D LUT)
+* with or without LUT. There is no shaper ROM, but we can use AMD
+* color modules to program LUT parameters from predefined TF (or
+* from a combination of pre-defined TF and the custom 1D LUT).
+*/
+   struct drm_property *plane_shaper_tf_property;
/**
 * @plane_lut3d_property: Plane property for color transformation using
 * a 3D LUT (pre-blending), a three-dimensional array where each
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index dbd36fc24eca..b820bcfedba0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -773,6 +773,17 @@ struct dm_plane_state {
 * S31.32 sign-magnitude.
 */
__u64 hdr_mult;
+   /**
+* @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an
+* array of  drm_color_lut.
+*/
+   struct drm_property_blob *shaper_lut;
+   /**
+* @shaper_tf:
+*
+* Predefined transfer function to delinearize color space.
+*/
+   enum amdgpu_transfer_function shaper_tf;
/**
 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
 *  drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index e2f3f2099cac..c9e61359a610 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -150,6 +150,14 @@ static const u32 amdgpu_eotf =
BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF) |
BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF);
 
+static const u32 amdgpu_inv_eotf =
+   BIT(AMDGPU_TRANSFER_FUNCTION_SRGB_INV_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_BT709_OETF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_PQ_INV_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA22_INV_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA24_INV_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA26_INV_EOTF);
+
 static struct drm_property *
 amdgpu_create_tf_property(struct drm_device *dev,
  const char *name,
@@ -207,6 +215,27 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_hdr_mult_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+

[PATCH v3 16/32] drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Otherwise this is just initialized to 0. This needs to actually have a
value so that compute_curve can work for PQ EOTF.

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 0fe2f76193ee..9d09a62645b9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -72,6 +72,7 @@
  */
 
 #define MAX_DRM_LUT_VALUE 0x
+#define SDR_WHITE_LEVEL_INIT_VALUE 80
 
 /**
  * amdgpu_dm_init_color_mod - Initialize the color module.
@@ -523,6 +524,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
 */
out_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
out_tf->tf = tf;
+   out_tf->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE;
 
ret = __set_output_tf(out_tf, regamma_lut, regamma_size, 
has_rom);
} else {
-- 
2.40.1



[PATCH v3 09/32] drm/amd/display: add plane 3D LUT driver-specific properties

2023-09-25 Thread Melissa Wen
Add 3D LUT property for plane color transformations using a 3D lookup
table. 3D LUT allows for highly accurate and complex color
transformations and is suitable to adjust the balance between color
channels. It's also more complex to manage and require more
computational resources. Since a 3D LUT has a limited number of entries
in each dimension we want to use them in an optimal fashion. This means
using the 3D LUT in a colorspace that is optimized for human vision,
such as sRGB, PQ, or another non-linear space. Therefore, userpace may
need one 1D LUT (shaper) before it to delinearize content and another 1D
LUT after 3D LUT (blend) to linearize content again for blending. The
next patches add these 1D LUTs to the plane color mgmt pipeline.

v3:
- improve commit message about 3D LUT
- describe the 3D LUT entries and size (Harry)

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 17 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  9 
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 14 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 23 +++
 4 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 66bae0eed80c..1b5f25989f7f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -363,6 +363,23 @@ struct amdgpu_mode_info {
 * @plane_hdr_mult_property:
 */
struct drm_property *plane_hdr_mult_property;
+   /**
+* @plane_lut3d_property: Plane property for color transformation using
+* a 3D LUT (pre-blending), a three-dimensional array where each
+* element is an RGB triplet. Each dimension has a size of the cubed
+* root of lut3d_size. The array contains samples from the approximated
+* function. On AMD, values between samples are estimated by
+* tetrahedral interpolation. The array is accessed with three indices,
+* one for each input dimension (color channel), blue being the
+* outermost dimension, red the innermost.
+*/
+   struct drm_property *plane_lut3d_property;
+   /**
+* @plane_degamma_lut_size_property: Plane property to define the max
+* size of 3D LUT as supported by the driver (read-only). The max size
+* is the max size of one dimension cubed.
+*/
+   struct drm_property *plane_lut3d_size_property;
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 7ca594c7dfbe..dbd36fc24eca 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -773,6 +773,11 @@ struct dm_plane_state {
 * S31.32 sign-magnitude.
 */
__u64 hdr_mult;
+   /**
+* @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
+*  drm_color_lut.
+*/
+   struct drm_property_blob *lut3d;
 };
 
 struct dm_crtc_state {
@@ -858,6 +863,10 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector 
*connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+/* 3D LUT max size is 17x17x17 */
+#define MAX_COLOR_3DLUT_ENTRIES 4913
+#define MAX_COLOR_3DLUT_BITDEPTH 12
+/* 1D LUT size */
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index f274909c0c7e..e2f3f2099cac 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -207,6 +207,20 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_hdr_mult_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_LUT3D", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_lut3d_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_lut3d_size_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index b66da6b76f5c..56f9109ecf60 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1361,6 +1361,8 @@ dm_drm_plane_duplicate_state(struct drm_plane 

[PATCH v3 03/32] drm/drm_plane: track color mgmt changes per plane

2023-09-25 Thread Melissa Wen
We will add color mgmt properties to DRM planes in the next patches and
we want to track when one of this properties change to define atomic
commit behaviors. Using a similar approach from CRTC color props, we set
a color_mgmt_changed boolean whenever a plane color prop changes.

Reviewed-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/drm_atomic.c  | 1 +
 drivers/gpu/drm/drm_atomic_state_helper.c | 1 +
 include/drm/drm_plane.h   | 7 +++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 2c454568a607..2925371d230d 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -724,6 +724,7 @@ static void drm_atomic_plane_print_state(struct drm_printer 
*p,
   drm_get_color_encoding_name(state->color_encoding));
drm_printf(p, "\tcolor-range=%s\n",
   drm_get_color_range_name(state->color_range));
+   drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
 
if (plane->funcs->atomic_print_state)
plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 784e63d70a42..25bb0859fda7 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -338,6 +338,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct 
drm_plane *plane,
state->fence = NULL;
state->commit = NULL;
state->fb_damage_clips = NULL;
+   state->color_mgmt_changed = false;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
 
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 51291983ea44..52c3287da0da 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -237,6 +237,13 @@ struct drm_plane_state {
 
/** @state: backpointer to global drm_atomic_state */
struct drm_atomic_state *state;
+
+   /**
+* @color_mgmt_changed: Color management properties have changed. Used
+* by the atomic helpers and drivers to steer the atomic commit control
+* flow.
+*/
+   bool color_mgmt_changed : 1;
 };
 
 static inline struct drm_rect
-- 
2.40.1



[PATCH v3 06/32] drm/amd/display: explicitly define EOTF and inverse EOTF

2023-09-25 Thread Melissa Wen
Instead of relying on color block names to get the transfer function
intention regarding encoding pixel's luminance, define supported
Electro-Optical Transfer Functions (EOTFs) and inverse EOTFs, that
includes pure gamma or standardized transfer functions.

v3:
- squash linear and unity TFs to identity (Pekka)
- define the right TFs for BT.709 (Pekka and Harry)
- add comment about AMD TF coefficients

Suggested-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 27 +---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 67 ++-
 2 files changed, 71 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index ab89538d5663..98f7267d5ee7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -716,16 +716,27 @@ static inline void amdgpu_dm_set_mst_status(uint8_t 
*status,
 
 extern const struct amdgpu_ip_block_version dm_ip_block;
 
+/* enum amdgpu_transfer_function: pre-defined transfer function supported by 
AMD.
+ *
+ * It includes standardized transfer functions and pure power functions. The
+ * transfer function coefficients are available at modules/color/color_gamma.c
+ */
 enum amdgpu_transfer_function {
AMDGPU_TRANSFER_FUNCTION_DEFAULT,
-   AMDGPU_TRANSFER_FUNCTION_SRGB,
-   AMDGPU_TRANSFER_FUNCTION_BT709,
-   AMDGPU_TRANSFER_FUNCTION_PQ,
-   AMDGPU_TRANSFER_FUNCTION_LINEAR,
-   AMDGPU_TRANSFER_FUNCTION_UNITY,
-   AMDGPU_TRANSFER_FUNCTION_GAMMA22,
-   AMDGPU_TRANSFER_FUNCTION_GAMMA24,
-   AMDGPU_TRANSFER_FUNCTION_GAMMA26,
+   AMDGPU_TRANSFER_FUNCTION_SRGB_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_BT709_INV_OETF,
+   AMDGPU_TRANSFER_FUNCTION_PQ_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_IDENTITY,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA22_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_SRGB_INV_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_BT709_OETF,
+   AMDGPU_TRANSFER_FUNCTION_PQ_INV_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA22_INV_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA24_INV_EOTF,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA26_INV_EOTF,
+AMDGPU_TRANSFER_FUNCTION_COUNT
 };
 
 struct dm_plane_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 56ce008b9095..d03bdb010e8b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -85,18 +85,57 @@ void amdgpu_dm_init_color_mod(void)
 }
 
 #ifdef AMD_PRIVATE_COLOR
-static const struct drm_prop_enum_list amdgpu_transfer_function_enum_list[] = {
-   { AMDGPU_TRANSFER_FUNCTION_DEFAULT, "Default" },
-   { AMDGPU_TRANSFER_FUNCTION_SRGB, "sRGB" },
-   { AMDGPU_TRANSFER_FUNCTION_BT709, "BT.709" },
-   { AMDGPU_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
-   { AMDGPU_TRANSFER_FUNCTION_LINEAR, "Linear" },
-   { AMDGPU_TRANSFER_FUNCTION_UNITY, "Unity" },
-   { AMDGPU_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
-   { AMDGPU_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
-   { AMDGPU_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+static const char * const
+amdgpu_transfer_function_names[] = {
+   [AMDGPU_TRANSFER_FUNCTION_DEFAULT]  = "Default",
+   [AMDGPU_TRANSFER_FUNCTION_IDENTITY] = "Identity",
+   [AMDGPU_TRANSFER_FUNCTION_SRGB_EOTF]= "sRGB EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_BT709_INV_OETF]   = "BT.709 inv_OETF",
+   [AMDGPU_TRANSFER_FUNCTION_PQ_EOTF]  = "PQ EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_GAMMA22_EOTF] = "Gamma 2.2 EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF] = "Gamma 2.4 EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF] = "Gamma 2.6 EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_SRGB_INV_EOTF]= "sRGB inv_EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_BT709_OETF]   = "BT.709 OETF",
+   [AMDGPU_TRANSFER_FUNCTION_PQ_INV_EOTF]  = "PQ inv_EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_GAMMA22_INV_EOTF] = "Gamma 2.2 inv_EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_GAMMA24_INV_EOTF] = "Gamma 2.4 inv_EOTF",
+   [AMDGPU_TRANSFER_FUNCTION_GAMMA26_INV_EOTF] = "Gamma 2.6 inv_EOTF",
 };
 
+static const u32 amdgpu_eotf =
+   BIT(AMDGPU_TRANSFER_FUNCTION_SRGB_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_BT709_INV_OETF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_PQ_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA22_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF) |
+   BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF);
+
+static struct drm_property *
+amdgpu_create_tf_property(struct drm_device *dev,
+ const char *name,
+ u32 

[PATCH v3 07/32] drm/amd/display: document AMDGPU pre-defined transfer functions

2023-09-25 Thread Melissa Wen
Brief documentation about pre-defined transfer function usage on AMD
display driver and standardized EOTFs and inverse EOTFs.

v3:
- Document BT709 OETF (Pekka)
- Fix description of sRGB and pure power funcs (Pekka)

Co-developed-by: Harry Wentland 
Signed-off-by: Harry Wentland 
Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index d03bdb010e8b..14f9c02539c6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -85,6 +85,45 @@ void amdgpu_dm_init_color_mod(void)
 }
 
 #ifdef AMD_PRIVATE_COLOR
+/* Pre-defined Transfer Functions (TF)
+ *
+ * AMD driver supports pre-defined mathematical functions for transferring
+ * between encoded values and optical/linear space. Depending on HW color caps,
+ * ROMs and curves built by the AMD color module support these transforms.
+ *
+ * The driver-specific color implementation exposes properties for pre-blending
+ * degamma TF, shaper TF (before 3D LUT), and blend(dpp.ogam) TF and
+ * post-blending regamma (mpc.ogam) TF. However, only pre-blending degamma
+ * supports ROM curves. AMD color module uses pre-defined coefficients to build
+ * curves for the other blocks. What can be done by each color block is
+ * described by struct dpp_color_capsand struct mpc_color_caps.
+ *
+ * AMD driver-specific color API exposes the following pre-defined transfer
+ * functions:
+ *
+ * - Linear/Unity: linear/identity relationship between pixel value and
+ *   luminance value;
+ * - Gamma 2.2, Gamma 2.4, Gamma 2.6: pure power functions;
+ * - sRGB: 2.4: The piece-wise transfer function from IEC 61966-2-1:1999;
+ * - BT.709: has a linear segment in the bottom part and then a power function
+ *   with a 0.45 (~1/2.22) gamma for the rest of the range; standardized by
+ *   ITU-R BT.709-6;
+ * - PQ (Perceptual Quantizer): used for HDR display, allows luminance range
+ *   capability of 0 to 10,000 nits; standardized by SMPTE ST 2084.
+ *
+ * In the driver-specific API, color block names attached to TF properties
+ * suggest the intention regarding non-linear encoding pixel's luminance
+ * values. As some newer encodings don't use gamma curve, we make encoding and
+ * decoding explicit by defining an enum list of transfer functions supported
+ * in terms of EOTF and inverse EOTF, where:
+ *
+ * - EOTF (electro-optical transfer function): is the transfer function to go
+ *   from the encoded value to an optical (linear) value. De-gamma functions
+ *   traditionally do this.
+ * - Inverse EOTF (simply the inverse of the EOTF): is usually intended to go
+ *   from an optical/linear space (which might have been used for blending)
+ *   back to the encoded values. Gamma functions traditionally do this.
+ */
 static const char * const
 amdgpu_transfer_function_names[] = {
[AMDGPU_TRANSFER_FUNCTION_DEFAULT]  = "Default",
-- 
2.40.1



[PATCH v3 04/32] drm/amd/display: add driver-specific property for plane degamma LUT

2023-09-25 Thread Melissa Wen
Hook up driver-specific atomic operations for managing AMD color
properties. Create AMD driver-specific color management properties
and attach them according to HW capabilities defined by `struct
dc_color_caps`.

First add plane degamma LUT properties that means user-blob and its
size. We will add more plane color properties in the next patches. In
addition, we define AMD_PRIVATE_COLOR to guard these driver-specific
plane properties.

Plane degamma can be used to linearize input space for arithmetical
operations that are more accurate when applied in linear color.

v2:
- update degamma LUT prop description
- move private color operations from amdgpu_display to amdgpu_dm_color

Reviewed-by: Harry Wentland 
Co-developed-by: Joshua Ashton 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 11 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  5 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 11 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 24 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 81 +++
 5 files changed, 132 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 32fe05c810c6..ec4621deac8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -343,6 +343,17 @@ struct amdgpu_mode_info {
int disp_priority;
const struct amdgpu_display_funcs *funcs;
const enum drm_plane_type *plane_type;
+
+   /* Driver-private color mgmt props */
+
+   /* @plane_degamma_lut_property: Plane property to set a degamma LUT to
+* convert input space before blending.
+*/
+   struct drm_property *plane_degamma_lut_property;
+   /* @plane_degamma_lut_size_property: Plane property to define the max
+* size of degamma LUT as supported by the driver (read-only).
+*/
+   struct drm_property *plane_degamma_lut_size_property;
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
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 373884ca38b9..1ad16850e8c5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4041,6 +4041,11 @@ static int amdgpu_dm_mode_config_init(struct 
amdgpu_device *adev)
return r;
}
 
+#ifdef AMD_PRIVATE_COLOR
+   if (amdgpu_dm_create_color_properties(adev))
+   return -ENOMEM;
+#endif
+
r = amdgpu_dm_audio_init(adev);
if (r) {
dc_release_state(state->context);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 3d480be802cb..0eafbf00505b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -719,6 +719,16 @@ extern const struct amdgpu_ip_block_version dm_ip_block;
 struct dm_plane_state {
struct drm_plane_state base;
struct dc_plane_state *dc_state;
+
+   /* Plane color mgmt */
+   /**
+* @degamma_lut:
+*
+* 1D LUT for mapping framebuffer/plane pixel data before sampling or
+* blending operations. It's usually applied to linearize input space.
+* The blob (if not NULL) is an array of  drm_color_lut.
+*/
+   struct drm_property_blob *degamma_lut;
 };
 
 struct dm_crtc_state {
@@ -809,6 +819,7 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
 
 void amdgpu_dm_init_color_mod(void);
+int amdgpu_dm_create_color_properties(struct amdgpu_device *adev);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a4cb23d059bd..cf175b86ba80 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -84,6 +84,30 @@ void amdgpu_dm_init_color_mod(void)
setup_x_points_distribution();
 }
 
+#ifdef AMD_PRIVATE_COLOR
+int
+amdgpu_dm_create_color_properties(struct amdgpu_device *adev)
+{
+   struct drm_property *prop;
+
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_DEGAMMA_LUT", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_degamma_lut_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_DEGAMMA_LUT_SIZE", 0, 

[PATCH v3 05/32] drm/amd/display: add plane degamma TF driver-specific property

2023-09-25 Thread Melissa Wen
From: Joshua Ashton 

Allow userspace to tell the kernel driver the input space and,
therefore, uses correct predefined transfer function (TF) to delinearize
content with or without LUT.

v2:
- rename TF enum prefix from DRM_ to AMDGPU_ (Harry)
- remove HLG TF

Reviewed-by: Harry Wentland 
Signed-off-by: Joshua Ashton 
Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  5 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 19 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 21 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 19 +++--
 4 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index ec4621deac8c..6ef958a14e16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -354,6 +354,11 @@ struct amdgpu_mode_info {
 * size of degamma LUT as supported by the driver (read-only).
 */
struct drm_property *plane_degamma_lut_size_property;
+   /**
+* @plane_degamma_tf_property: Plane pre-defined transfer function to
+* to go from scanout/encoded values to linear values.
+*/
+   struct drm_property *plane_degamma_tf_property;
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 0eafbf00505b..ab89538d5663 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -716,6 +716,18 @@ static inline void amdgpu_dm_set_mst_status(uint8_t 
*status,
 
 extern const struct amdgpu_ip_block_version dm_ip_block;
 
+enum amdgpu_transfer_function {
+   AMDGPU_TRANSFER_FUNCTION_DEFAULT,
+   AMDGPU_TRANSFER_FUNCTION_SRGB,
+   AMDGPU_TRANSFER_FUNCTION_BT709,
+   AMDGPU_TRANSFER_FUNCTION_PQ,
+   AMDGPU_TRANSFER_FUNCTION_LINEAR,
+   AMDGPU_TRANSFER_FUNCTION_UNITY,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA22,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA24,
+   AMDGPU_TRANSFER_FUNCTION_GAMMA26,
+};
+
 struct dm_plane_state {
struct drm_plane_state base;
struct dc_plane_state *dc_state;
@@ -729,6 +741,13 @@ struct dm_plane_state {
 * The blob (if not NULL) is an array of  drm_color_lut.
 */
struct drm_property_blob *degamma_lut;
+   /**
+* @degamma_tf:
+*
+* Predefined transfer function to tell DC driver the input space to
+* linearize.
+*/
+   enum amdgpu_transfer_function degamma_tf;
 };
 
 struct dm_crtc_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index cf175b86ba80..56ce008b9095 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -85,6 +85,18 @@ void amdgpu_dm_init_color_mod(void)
 }
 
 #ifdef AMD_PRIVATE_COLOR
+static const struct drm_prop_enum_list amdgpu_transfer_function_enum_list[] = {
+   { AMDGPU_TRANSFER_FUNCTION_DEFAULT, "Default" },
+   { AMDGPU_TRANSFER_FUNCTION_SRGB, "sRGB" },
+   { AMDGPU_TRANSFER_FUNCTION_BT709, "BT.709" },
+   { AMDGPU_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
+   { AMDGPU_TRANSFER_FUNCTION_LINEAR, "Linear" },
+   { AMDGPU_TRANSFER_FUNCTION_UNITY, "Unity" },
+   { AMDGPU_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
+   { AMDGPU_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
+   { AMDGPU_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+};
+
 int
 amdgpu_dm_create_color_properties(struct amdgpu_device *adev)
 {
@@ -104,6 +116,15 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_degamma_lut_size_property = prop;
 
+   prop = drm_property_create_enum(adev_to_drm(adev),
+   DRM_MODE_PROP_ENUM,
+   "AMD_PLANE_DEGAMMA_TF",
+   amdgpu_transfer_function_enum_list,
+   
ARRAY_SIZE(amdgpu_transfer_function_enum_list));
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_degamma_tf_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 2f25f02185ff..4f4c59c4f089 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1334,8 +1334,11 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
WARN_ON(amdgpu_state == NULL);
 
-   if (amdgpu_state)
-   

[PATCH v3 02/32] drm/drm_property: make replace_property_blob_from_id a DRM helper

2023-09-25 Thread Melissa Wen
Place it in drm_property where drm_property_replace_blob and
drm_property_lookup_blob live. Then we can use the DRM helper for
driver-specific KMS properties too.

Reviewed-by: Harry Wentland 
Reviewed-by: Liviu Dudau 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/arm/malidp_crtc.c |  2 +-
 drivers/gpu/drm/drm_atomic_uapi.c | 43 ---
 drivers/gpu/drm/drm_property.c| 49 +++
 include/drm/drm_property.h|  6 
 4 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_crtc.c 
b/drivers/gpu/drm/arm/malidp_crtc.c
index dc01c43f6193..d72c22dcf685 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -221,7 +221,7 @@ static int malidp_crtc_atomic_check_ctm(struct drm_crtc 
*crtc,
 
/*
 * The size of the ctm is checked in
-* drm_atomic_replace_property_blob_from_id.
+* drm_property_replace_blob_from_id.
 */
ctm = (struct drm_color_ctm *)state->ctm->data;
for (i = 0; i < ARRAY_SIZE(ctm->matrix); ++i) {
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d867e7f9f2cd..a6a9ee5086dd 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -362,39 +362,6 @@ static s32 __user *get_out_fence_for_connector(struct 
drm_atomic_state *state,
return fence_ptr;
 }
 
-static int
-drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
-struct drm_property_blob **blob,
-uint64_t blob_id,
-ssize_t expected_size,
-ssize_t expected_elem_size,
-bool *replaced)
-{
-   struct drm_property_blob *new_blob = NULL;
-
-   if (blob_id != 0) {
-   new_blob = drm_property_lookup_blob(dev, blob_id);
-   if (new_blob == NULL)
-   return -EINVAL;
-
-   if (expected_size > 0 &&
-   new_blob->length != expected_size) {
-   drm_property_blob_put(new_blob);
-   return -EINVAL;
-   }
-   if (expected_elem_size > 0 &&
-   new_blob->length % expected_elem_size != 0) {
-   drm_property_blob_put(new_blob);
-   return -EINVAL;
-   }
-   }
-
-   *replaced |= drm_property_replace_blob(blob, new_blob);
-   drm_property_blob_put(new_blob);
-
-   return 0;
-}
-
 static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
struct drm_crtc_state *state, struct drm_property *property,
uint64_t val)
@@ -415,7 +382,7 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
} else if (property == config->prop_vrr_enabled) {
state->vrr_enabled = val;
} else if (property == config->degamma_lut_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   ret = drm_property_replace_blob_from_id(dev,
>degamma_lut,
val,
-1, sizeof(struct drm_color_lut),
@@ -423,7 +390,7 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
state->color_mgmt_changed |= replaced;
return ret;
} else if (property == config->ctm_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   ret = drm_property_replace_blob_from_id(dev,
>ctm,
val,
sizeof(struct drm_color_ctm), -1,
@@ -431,7 +398,7 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
state->color_mgmt_changed |= replaced;
return ret;
} else if (property == config->gamma_lut_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   ret = drm_property_replace_blob_from_id(dev,
>gamma_lut,
val,
-1, sizeof(struct drm_color_lut),
@@ -563,7 +530,7 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
} else if (property == plane->color_range_property) {
state->color_range = val;
} else if (property == config->prop_fb_damage_clips) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   ret = drm_property_replace_blob_from_id(dev,
>fb_damage_clips,
val,
-1,
@@ -729,7 +696,7 @@ static int 

[PATCH v3 00/32] drm/amd/display: add AMD driver-specific properties for color mgmt

2023-09-25 Thread Melissa Wen
Hi,

This series extends the current KMS color management API with AMD
driver-specific properties to enhance the color management support on
AMD Steam Deck. The key additions to the color pipeline include:

- plane degamma LUT and pre-defined TF;
- plane HDR multiplier;
- plane CTM 3x4;
- plane shaper LUT and pre-defined TF;
- plane 3D LUT;
- plane blend LUT and pre-defined TF;
- CRTC gamma pre-defined TF;

You can find the AMD HW color capabilities documented here:
https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties

The userspace case is Gamescope[1], the compositor for SteamOS.
Gamescope has already adopted AMD driver-specific properties to
implement comprehensive color management support, including gamut
mapping, HDR rendering, SDR on HDR, HDR on SDR. Using these features in
the SteamOS 3.5[2] users can expect a significantly enhanced visual
experience. 

You can find a brief overview of the Steam Deck color pipeline here:
https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png

Changes from:

[RFC] https://lore.kernel.org/dri-devel/20230423141051.702990-1-m...@igalia.com
- Remove KConfig and guard properties with `AMD_PRIVATE_COLOR`;
- Remove properties for post-blending/CRTC shaper TF+LUT and 3D LUT;
- Use color caps to improve the support of pre-defined curve;

[V1] https://lore.kernel.org/dri-devel/20230523221520.3115570-1-m...@igalia.com
- Replace DRM_ by AMDGPU_ prefix for transfer function (TF) enum; 
- Explicitly define EOTFs and inverse EOTFs and set props accordingly;
- Document pre-defined transfer functions;
- Remove HLG transfer function from supported TFs;
- Remove misleading comments;
- Remove post-blending shaper TF+LUT and 3D LUT support;
- Move driver-specific property operations from amdgpu_display.c to
  amdgpu_dm_color.c;
- Reset planes if any color props change;
- Add plane CTM 3x4 support;
- Removed two DC fixes already applied upstream;

[V2] https://lore.kernel.org/dri-devel/20230810160314.48225-1-m...@igalia.com
- Many documentation fixes: BT.709 OETF, description of sRGB and pure
  power functions, TF+1D LUT behavior;
- Rename CTM2 to CTM 3x4 and fix misleading comment about DC gamut remap;
- Squash `Linear` and `Unity` TF in `Identity`;
- Remove the `MPC gamut remap` patch already applied upstream[3];
- Remove outdated delta segmentation fix;
- Nits/small fixes;

It's worth noting that driver-specific properties are guarded by
`AMD_PRIVATE_COLOR`. So, finally, this is the color management API when
driver-specific properties are enabled:

+--+
|   PLANE  |
|  |
|  ++  |
|  | AMD Degamma|  |
|  ||  |
|  | EOTF | 1D LUT  |  |
|  ++---+  |
|   |  |
|  +v---+  |
|  |AMD HDR |  |
|  |Multiply|  |
|  ++---+  |
|   |  |
|  +v---+  |
|  |  AMD CTM (3x4) |  |
|  ++---+  |
|   |  |
|  +v---+  |
|  | AMD Shaper |  |
|  ||  |
|  | inv_EOTF | |  |
|  | Custom 1D LUT  |  |
|  ++---+  |
|   |  |
|  +v---+  |
|  |   AMD 3D LUT   |  |
|  |   17^3/12-bit  |  |
|  ++---+  |
|   |  |
|  +v---+  |
|  | AMD Blend  |  |
|  ||  |
|  | EOTF | 1D LUT  |  |
|  ++---+  |
|   |  |
++--v-++
||  Blending  ||
++--+-++
|CRTC   |  |
|   |  |
|   +---v---+  |
|   | DRM Degamma   |  |
|   |   |  |
|   | Custom 1D LUT |  |
|   +---+---+  |
|   |  |
|   +---v---+  |
|   | DRM CTM (3x3) |  |
|   +---+---+  |
|   |  |
|   +---v---+  |
|   | DRM Gamma |  |
|   |   |  |
|   | Custom 1D LUT |  |
|   +---+  |
|   | *AMD Gamma|  |
|   |   inv_EOTF|  |
|   +---+  |
|  |
+--+

Please, let us know your thoughts.

Best Regards,

Melissa Wen

[1] https://github.com/ValveSoftware/gamescope
[2] https://store.steampowered.com/news/app/1675200/view/3686804163591367815
[3] https://lore.kernel.org/dri-devel/20230721132431.692158-1-m...@igalia.com


Joshua Ashton (14):
  drm/amd/display: add plane degamma TF driver-specific property
  drm/amd/display: add plane HDR multiplier driver-specific property
  drm/amd/display: add plane blend LUT and TF driver-specific properties
  drm/amd/display: add CRTC gamma TF support
  drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
  drm/amd/display: mark plane as needing reset if color props change
  drm/amd/display: add plane degamma TF and LUT support
  drm/amd/display: add dc_fixpt_from_s3132 helper
  drm/amd/display: add HDR multiplier support
  drm/amd/display: handle 

[PATCH v3 01/32] drm/drm_mode_object: increase max objects to accommodate new color props

2023-09-25 Thread Melissa Wen
DRM_OBJECT_MAX_PROPERTY limits the number of properties to be attached
and we are increasing that value all time we add a new property (generic
or driver-specific).

In this series, we are adding 13 new KMS driver-specific properties for
AMD color manage:
- CRTC Gamma enumerated Transfer Function
- Plane: Degamma LUT+size+TF, HDR multiplier, shaper LUT+size+TF, 3D
  LUT+size, blend LUT+size+TF (12)

Therefore, just increase DRM_OBJECT_MAX_PROPERTY to a number (64) that
accomodates these new properties and gives some room for others,
avoiding change this number everytime we add a new KMS property.

Reviewed-by: Harry Wentland 
Reviewed-by: Simon Ser 
Signed-off-by: Melissa Wen 
---
 include/drm/drm_mode_object.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index 912f1e415685..08d7a7f0188f 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -60,7 +60,7 @@ struct drm_mode_object {
void (*free_cb)(struct kref *kref);
 };
 
-#define DRM_OBJECT_MAX_PROPERTY 24
+#define DRM_OBJECT_MAX_PROPERTY 64
 /**
  * struct drm_object_properties - property tracking for _mode_object
  */
-- 
2.40.1



Re: [PATCH 1/9] drm/amd/pm: Annotate struct smu10_voltage_dependency_table with __counted_by

2023-09-25 Thread Alex Deucher
On Mon, Sep 25, 2023 at 1:52 PM Kees Cook  wrote:
>
> On Mon, Sep 25, 2023 at 08:30:30AM +0200, Christian König wrote:
> > Am 22.09.23 um 19:41 schrieb Alex Deucher:
> > > On Fri, Sep 22, 2023 at 1:32 PM Kees Cook  wrote:
> > > > Prepare for the coming implementation by GCC and Clang of the 
> > > > __counted_by
> > > > attribute. Flexible array members annotated with __counted_by can have
> > > > their accesses bounds-checked at run-time checking via 
> > > > CONFIG_UBSAN_BOUNDS
> > > > (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
> > > > functions).
> > > >
> > > > As found with Coccinelle[1], add __counted_by for struct 
> > > > smu10_voltage_dependency_table.
> > > >
> > > > [1] 
> > > > https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci
> > > >
> > > > Cc: Evan Quan 
> > > > Cc: Alex Deucher 
> > > > Cc: "Christian König" 
> > > > Cc: "Pan, Xinhui" 
> > > > Cc: David Airlie 
> > > > Cc: Daniel Vetter 
> > > > Cc: Xiaojian Du 
> > > > Cc: Huang Rui 
> > > > Cc: Kevin Wang 
> > > > Cc: amd-...@lists.freedesktop.org
> > > > Cc: dri-devel@lists.freedesktop.org
> > > > Signed-off-by: Kees Cook 
> > > Acked-by: Alex Deucher 
> >
> > Mhm, I'm not sure if this is a good idea. That is a structure filled in by
> > the firmware, isn't it?
> >
> > That would imply that we might need to byte swap count before it is
> > checkable.
>
> The script found this instance because of this:
>
> static int smu10_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr,
> struct smu10_voltage_dependency_table **pptable,
> uint32_t num_entry, const DpmClock_t 
> *pclk_dependency_table)
> {
> uint32_t i;
> struct smu10_voltage_dependency_table *ptable;
>
> ptable = kzalloc(struct_size(ptable, entries, num_entry), GFP_KERNEL);
> if (NULL == ptable)
> return -ENOMEM;
>
> ptable->count = num_entry;
>
> So the implication is that it's native byte order... but you tell me! I
> certainly don't want this annotation if it's going to break stuff. :)

In this case, the code is for an integrated GPU in an x86 CPU so the
firmware and driver endianness match.  You wouldn't find a stand alone
dGPU that uses this structure.  In this case it's ok.  False alarm.

Alex


Re: [PATCH drm-misc-next 1/3] drm/sched: implement dynamic job flow control

2023-09-25 Thread Christian König




Am 25.09.23 um 14:55 schrieb Boris Brezillon:

+The imagination team, who's probably interested too.

On Mon, 25 Sep 2023 00:43:06 +0200
Danilo Krummrich  wrote:


Currently, job flow control is implemented simply by limiting the amount
of jobs in flight. Therefore, a scheduler is initialized with a
submission limit that corresponds to a certain amount of jobs.

This implies that for each job drivers need to account for the maximum
job size possible in order to not overflow the ring buffer.

However, there are drivers, such as Nouveau, where the job size has a
rather large range. For such drivers it can easily happen that job
submissions not even filling the ring by 1% can block subsequent
submissions, which, in the worst case, can lead to the ring run dry.

In order to overcome this issue, allow for tracking the actual job size
instead of the amount job jobs. Therefore, add a field to track a job's
submission units, which represents the amount of units a job contributes
to the scheduler's submission limit.

As mentioned earlier, this might allow some simplifications in the
PowerVR driver where we do flow-control using a dma_fence returned
through ->prepare_job(). The only thing that'd be missing is a way to
dynamically query the size of a job (a new hook?), instead of having the
size fixed at creation time, because PVR jobs embed native fence waits,
and the number of native fences will decrease if some of these fences
are signalled before ->run_job() is called, thus reducing the job size.


Exactly that is a little bit questionable since it allows for the device 
to postpone jobs infinitely.


It would be good if the scheduler is able to validate if it's ever able 
to run the job when it is pushed into the entity.


Otherwise you can end up with really hard to debug problems.

Regards,
Christian.




Signed-off-by: Danilo Krummrich 
---
This patch is based on Matt's scheduler work [1].

[1] 
https://lore.kernel.org/dri-devel/20230919050155.2647172-1-matthew.br...@intel.com/
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_job.c   |  2 +-
  drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c  |  2 +-
  drivers/gpu/drm/lima/lima_sched.c |  2 +-
  drivers/gpu/drm/msm/msm_gem_submit.c  |  2 +-
  drivers/gpu/drm/nouveau/nouveau_sched.c   |  2 +-
  drivers/gpu/drm/panfrost/panfrost_drv.c   |  2 +-
  .../gpu/drm/scheduler/gpu_scheduler_trace.h   |  2 +-
  drivers/gpu/drm/scheduler/sched_entity.c  |  5 +-
  drivers/gpu/drm/scheduler/sched_main.c| 81 +--
  drivers/gpu/drm/v3d/v3d_gem.c |  2 +-
  include/drm/gpu_scheduler.h   | 18 +++--
  11 files changed, 78 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 78476bc75b4e..d54daaf64bf1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -115,7 +115,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
if (!entity)
return 0;
  
-	return drm_sched_job_init(&(*job)->base, entity, owner);

+   return drm_sched_job_init(&(*job)->base, entity, 1, owner);
  }
  
  int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 45403ea38906..74a446711207 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -538,7 +538,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void 
*data,
  
  	ret = drm_sched_job_init(>sched_job,

 >sched_entity[args->pipe],
-submit->ctx);
+1, submit->ctx);
if (ret)
goto err_submit_put;
  
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c

index 50c2075228aa..5dc6678e1eb9 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -123,7 +123,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
for (i = 0; i < num_bos; i++)
drm_gem_object_get([i]->base.base);
  
-	err = drm_sched_job_init(>base, >base, vm);

+   err = drm_sched_job_init(>base, >base, 1, vm);
if (err) {
kfree(task->bos);
return err;
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
index 3f1aa4de3b87..6d230c38e4f5 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -48,7 +48,7 @@ static struct msm_gem_submit *submit_create(struct drm_device 
*dev,
return ERR_PTR(ret);
}
  
-	ret = drm_sched_job_init(>base, queue->entity, queue);

+   ret = drm_sched_job_init(>base, queue->entity, 1, queue);
if (ret) {
kfree(submit->hw_fence);
kfree(submit);
diff 

Re: [PATCH] drm/msm/a6xx: don't set IO_PGTABLE_QUIRK_ARM_OUTER_WBWA with coherent SMMU

2023-09-25 Thread Robin Murphy

On 2023-04-10 19:52, Dmitry Baryshkov wrote:

If the Adreno SMMU is dma-coherent, allocation will fail unless we
disable IO_PGTABLE_QUIRK_ARM_OUTER_WBWA. Skip setting this quirk for the
coherent SMMUs (like we have on sm8350 platform).


Hmm, but is it right that it should fail in the first place? The fact is 
that if the SMMU is coherent then walks *will* be outer-WBWA, so I 
honestly can't see why the io-pgtable code is going out of its way to 
explicitly reject a request to give them the same attribute it's already 
giving then anyway :/


Even if the original intent was for the quirk to have an over-specific 
implication of representing inner-NC as well, that hardly seems useful 
if what we've ended up with in practice is a nonsensical-looking check 
in one place and then a weird hacky bodge in another purely to work 
around it.


Does anyone know a good reason why this is the way it is?

[ just came across this code in the tree while trying to figure out what 
to do with iommu_set_pgtable_quirks()... ]


Thanks,
Robin.


Fixes: 54af0ceb7595 ("arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU 
nodes")
Reported-by: David Heidelberg 
Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 2942d2548ce6..f74495dcbd96 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1793,7 +1793,8 @@ a6xx_create_address_space(struct msm_gpu *gpu, struct 
platform_device *pdev)
 * This allows GPU to set the bus attributes required to use system
 * cache on behalf of the iommu page table walker.
 */
-   if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
+   if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice) &&
+   !device_iommu_capable(>dev, IOMMU_CAP_CACHE_COHERENCY))
quirks |= IO_PGTABLE_QUIRK_ARM_OUTER_WBWA;
  
  	return adreno_iommu_create_address_space(gpu, pdev, quirks);


Re: [PATCH 1/9] drm/amd/pm: Annotate struct smu10_voltage_dependency_table with __counted_by

2023-09-25 Thread Kees Cook
On Mon, Sep 25, 2023 at 08:30:30AM +0200, Christian König wrote:
> Am 22.09.23 um 19:41 schrieb Alex Deucher:
> > On Fri, Sep 22, 2023 at 1:32 PM Kees Cook  wrote:
> > > Prepare for the coming implementation by GCC and Clang of the __counted_by
> > > attribute. Flexible array members annotated with __counted_by can have
> > > their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS
> > > (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
> > > functions).
> > > 
> > > As found with Coccinelle[1], add __counted_by for struct 
> > > smu10_voltage_dependency_table.
> > > 
> > > [1] 
> > > https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci
> > > 
> > > Cc: Evan Quan 
> > > Cc: Alex Deucher 
> > > Cc: "Christian König" 
> > > Cc: "Pan, Xinhui" 
> > > Cc: David Airlie 
> > > Cc: Daniel Vetter 
> > > Cc: Xiaojian Du 
> > > Cc: Huang Rui 
> > > Cc: Kevin Wang 
> > > Cc: amd-...@lists.freedesktop.org
> > > Cc: dri-devel@lists.freedesktop.org
> > > Signed-off-by: Kees Cook 
> > Acked-by: Alex Deucher 
> 
> Mhm, I'm not sure if this is a good idea. That is a structure filled in by
> the firmware, isn't it?
> 
> That would imply that we might need to byte swap count before it is
> checkable.

The script found this instance because of this:

static int smu10_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr,
struct smu10_voltage_dependency_table **pptable,
uint32_t num_entry, const DpmClock_t 
*pclk_dependency_table)
{
uint32_t i;
struct smu10_voltage_dependency_table *ptable;

ptable = kzalloc(struct_size(ptable, entries, num_entry), GFP_KERNEL);
if (NULL == ptable)
return -ENOMEM;

ptable->count = num_entry;

So the implication is that it's native byte order... but you tell me! I
certainly don't want this annotation if it's going to break stuff. :)

-- 
Kees Cook


Re: [PATCH 3/9] drm/i915/selftests: Annotate struct perf_series with __counted_by

2023-09-25 Thread Kees Cook
On Mon, Sep 25, 2023 at 12:08:36PM +0200, Andrzej Hajda wrote:
> 
> 
> On 22.09.2023 19:32, Kees Cook wrote:
> > Prepare for the coming implementation by GCC and Clang of the __counted_by
> > attribute. Flexible array members annotated with __counted_by can have
> > their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS
> > (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
> > functions).
> > 
> > As found with Coccinelle[1], add __counted_by for struct perf_series.
> > 
> > [1] 
> > https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci
> > 
> > Cc: Jani Nikula 
> > Cc: Joonas Lahtinen 
> > Cc: Rodrigo Vivi 
> > Cc: Tvrtko Ursulin 
> > Cc: David Airlie 
> > Cc: Daniel Vetter 
> > Cc: Chris Wilson 
> > Cc: John Harrison 
> > Cc: Andi Shyti 
> > Cc: Matthew Brost 
> > Cc: intel-...@lists.freedesktop.org
> > Cc: dri-devel@lists.freedesktop.org
> > Signed-off-by: Kees Cook 
> 
> I am surprised this is the only finding in i915, I would expected more.

I'm sure there are more, but it's likely my Coccinelle pattern didn't
catch it. There are many many flexible arrays in drm. :)

$ grep -nRH '\[\];$' drivers/gpu/drm include/uapi/drm | grep -v :extern | wc -l
122

If anyone has some patterns I can add to the Coccinelle script, I can
take another pass at it.

> Anyway:
> 
> Reviewed-by: Andrzej Hajda 

Thank you!

-Kees

-- 
Kees Cook


RE: [PATCH 4/6] drm/edid: use a temp variable for sads to drop one level of dereferences

2023-09-25 Thread Golani, Mitulkumar Ajitkumar
Hi Jani,

added comments in-line.

> -Original Message-
> From: Nikula, Jani 
> Sent: Thursday, September 7, 2023 2:58 PM
> To: dri-devel@lists.freedesktop.org
> Cc: intel-...@lists.freedesktop.org; Nikula, Jani ;
> Golani, Mitulkumar Ajitkumar 
> Subject: [PATCH 4/6] drm/edid: use a temp variable for sads to drop one level
> of dereferences
> 
> It's arguably easier on the eyes, and drops a set of parenthesis too.

Please consider providing a bit more context in the commit message for better 
clarity.

> 
> Cc: Mitul Golani 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/drm_edid.c | 16 +---
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index
> 2025970816c9..fcdc2c314cde 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -5583,7 +5583,7 @@ static void drm_edid_to_eld(struct drm_connector
> *connector,  }
> 
>  static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
> - struct cea_sad **sads)
> + struct cea_sad **psads)
>  {
>   const struct cea_db *db;
>   struct cea_db_iter iter;
> @@ -5592,19 +5592,21 @@ static int _drm_edid_to_sad(const struct
> drm_edid *drm_edid,
>   cea_db_iter_edid_begin(drm_edid, );
>   cea_db_iter_for_each(db, ) {
>   if (cea_db_tag(db) == CTA_DB_AUDIO) {
> + struct cea_sad *sads;
>   int j;
> 
>   count = cea_db_payload_len(db) / 3; /* SAD is 3B */
> - *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL);
> - if (!*sads)
> + sads = kcalloc(count, sizeof(*sads), GFP_KERNEL);
> + *psads = sads;
> + if (!sads)
>   return -ENOMEM;
>   for (j = 0; j < count; j++) {
>   const u8 *sad = >data[j * 3];
> 
> - (*sads)[j].format = (sad[0] & 0x78) >> 3;
> - (*sads)[j].channels = sad[0] & 0x7;
> - (*sads)[j].freq = sad[1] & 0x7F;
> - (*sads)[j].byte2 = sad[2];
> + sads[j].format = (sad[0] & 0x78) >> 3;
> + sads[j].channels = sad[0] & 0x7;
> + sads[j].freq = sad[1] & 0x7F;
> + sads[j].byte2 = sad[2];

Thanks for the code update. I noticed the use of magic values in this section, 
which can make the code less clear 
and harder to maintain. Would it be possible to define constants or use 
descriptive names instead of these magic 
values?

Regards,
Mitul
>   }
>   break;
>   }
> --
> 2.39.2



Re: [PATCH] accel/ivpu: Annotate struct ivpu_job with __counted_by

2023-09-25 Thread Kees Cook
On Fri, 22 Sep 2023 10:54:17 -0700, Kees Cook wrote:
> Prepare for the coming implementation by GCC and Clang of the __counted_by
> attribute. Flexible array members annotated with __counted_by can have
> their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS
> (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
> functions).
> 
> As found with Coccinelle[1], add __counted_by for struct ivpu_job.
> 
> [...]

Thanks Stanislaw! I'll take it through my for-next/hardening tree then:

[1/1] accel/ivpu: Annotate struct ivpu_job with __counted_by
  https://git.kernel.org/kees/c/2ea8275b

Take care,

-- 
Kees Cook



[PATCH v3] drm/i915/gem: Make i915_gem_shrinker multi-gt aware

2023-09-25 Thread Nirmoy Das
From: Jonathan Cavitt 

Where applicable, use for_each_gt instead of to_gt in the
i915_gem_shrinker functions to make them apply to more than just the
primary GT.  Specifically, this ensure i915_gem_shrink_all retires all
requests across all GTs, and this makes i915_gem_shrinker_vmap unmap
VMAs from all GTs.

v2: Pass correct GT to intel_gt_retire_requests(Andrzej).
v3: Remove unnecessary braces(Andi) 

Signed-off-by: Jonathan Cavitt 
Signed-off-by: Nirmoy Das 
Reviewed-by: Andrzej Hajda 
Reviewed-by: Andi Shyti 
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 41 
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 214763942aa2..e79fcbdfab25 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -14,6 +14,7 @@
 #include 
 
 #include "gt/intel_gt_requests.h"
+#include "gt/intel_gt.h"
 
 #include "i915_trace.h"
 
@@ -119,7 +120,8 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
intel_wakeref_t wakeref = 0;
unsigned long count = 0;
unsigned long scanned = 0;
-   int err = 0;
+   int err = 0, i = 0;
+   struct intel_gt *gt;
 
/* CHV + VTD workaround use stop_machine(); need to trylock vm->mutex */
bool trylock_vm = !ww && intel_vm_no_concurrent_access_wa(i915);
@@ -148,8 +150,9 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 * contexts around longer than is necessary.
 */
if (shrink & I915_SHRINK_ACTIVE)
-   /* Retire requests to unpin all idle contexts */
-   intel_gt_retire_requests(to_gt(i915));
+   for_each_gt(gt, i915, i)
+   /* Retire requests to unpin all idle contexts */
+   intel_gt_retire_requests(gt);
 
/*
 * As we may completely rewrite the (un)bound list whilst unbinding
@@ -389,6 +392,8 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned 
long event, void *ptr
struct i915_vma *vma, *next;
unsigned long freed_pages = 0;
intel_wakeref_t wakeref;
+   struct intel_gt *gt;
+   int i;
 
with_intel_runtime_pm(>runtime_pm, wakeref)
freed_pages += i915_gem_shrink(NULL, i915, -1UL, NULL,
@@ -397,24 +402,26 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, 
unsigned long event, void *ptr
   I915_SHRINK_VMAPS);
 
/* We also want to clear any cached iomaps as they wrap vmap */
-   mutex_lock(_gt(i915)->ggtt->vm.mutex);
-   list_for_each_entry_safe(vma, next,
-_gt(i915)->ggtt->vm.bound_list, vm_link) {
-   unsigned long count = i915_vma_size(vma) >> PAGE_SHIFT;
-   struct drm_i915_gem_object *obj = vma->obj;
-
-   if (!vma->iomap || i915_vma_is_active(vma))
-   continue;
+   for_each_gt(gt, i915, i) {
+   mutex_lock(>ggtt->vm.mutex);
+   list_for_each_entry_safe(vma, next,
+>ggtt->vm.bound_list, vm_link) {
+   unsigned long count = i915_vma_size(vma) >> PAGE_SHIFT;
+   struct drm_i915_gem_object *obj = vma->obj;
+
+   if (!vma->iomap || i915_vma_is_active(vma))
+   continue;
 
-   if (!i915_gem_object_trylock(obj, NULL))
-   continue;
+   if (!i915_gem_object_trylock(obj, NULL))
+   continue;
 
-   if (__i915_vma_unbind(vma) == 0)
-   freed_pages += count;
+   if (__i915_vma_unbind(vma) == 0)
+   freed_pages += count;
 
-   i915_gem_object_unlock(obj);
+   i915_gem_object_unlock(obj);
+   }
+   mutex_unlock(>ggtt->vm.mutex);
}
-   mutex_unlock(_gt(i915)->ggtt->vm.mutex);
 
*(unsigned long *)ptr += freed_pages;
return NOTIFY_DONE;
-- 
2.41.0



Re: [RFT PATCH v2 07/12] drm/amdgpu: Call drm_atomic_helper_shutdown() at shutdown time

2023-09-25 Thread Doug Anderson
Hi,

On Mon, Sep 25, 2023 at 8:57 AM Deucher, Alexander
 wrote:
>
> [Public]
>
> > -Original Message-
> > From: Douglas Anderson 
> > Sent: Thursday, September 21, 2023 3:27 PM
> > To: dri-devel@lists.freedesktop.org; Maxime Ripard 
> > Cc: Douglas Anderson ; Zhang, Bokun
> > ; Zhang, Hawking ;
> > Zhu, James ; Zhao, Victor ;
> > Pan, Xinhui ; airl...@gmail.com; Deucher, Alexander
> > ; amd-...@lists.freedesktop.org; Koenig,
> > Christian ; dan...@ffwll.ch; Kuehling, Felix
> > ; jim.cro...@gmail.com; Ma, Le
> > ; Lazar, Lijo ; linux-
> > ker...@vger.kernel.org; maarten.lankho...@linux.intel.com; Limonciello,
> > Mario ; mdaen...@redhat.com; Zhang,
> > Morris ; SHANMUGAM, SRINIVASAN
> > ; tzimmerm...@suse.de
> > Subject: [RFT PATCH v2 07/12] drm/amdgpu: Call
> > drm_atomic_helper_shutdown() at shutdown time
> >
> > Based on grepping through the source code this driver appears to be missing 
> > a
> > call to drm_atomic_helper_shutdown() at system shutdown time. Among
> > other things, this means that if a panel is in use that it won't be cleanly
> > powered off at system shutdown time.
> >
> > The fact that we should call drm_atomic_helper_shutdown() in the case of OS
> > shutdown/restart comes straight out of the kernel doc "driver instance
> > overview" in drm_drv.c.
> >
> > Suggested-by: Maxime Ripard 
> > Signed-off-by: Douglas Anderson 
> > ---
> > This commit is only compile-time tested.
> >
> > ...and further, I'd say that this patch is more of a plea for help than a 
> > patch I
> > think is actually right. I'm _fairly_ certain that drm/amdgpu needs this 
> > call at
> > shutdown time but the logic is a bit hard for me to follow. I'd appreciate 
> > if
> > anyone who actually knows what this should look like could illuminate me, or
> > perhaps even just post a patch themselves!
> >
> > (no changes since v1)
> >
> >  drivers/gpu/drm/amd/amdgpu/amdgpu.h|  1 +
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 ++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|  2 ++
> >  3 files changed, 13 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > index 8f2255b3a38a..cfcff0b37466 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > @@ -1104,6 +1104,7 @@ static inline struct amdgpu_device
> > *amdgpu_ttm_adev(struct ttm_device *bdev)  int amdgpu_device_init(struct
> > amdgpu_device *adev,
> >  uint32_t flags);
> >  void amdgpu_device_fini_hw(struct amdgpu_device *adev);
> > +void amdgpu_device_shutdown_hw(struct amdgpu_device *adev);
> >  void amdgpu_device_fini_sw(struct amdgpu_device *adev);
> >
> >  int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev); diff --git
> > a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > index a2cdde0ca0a7..fa5925c2092d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > @@ -4247,6 +4247,16 @@ void amdgpu_device_fini_hw(struct
> > amdgpu_device *adev)
> >
> >  }
> >
> > +void amdgpu_device_shutdown_hw(struct amdgpu_device *adev) {
>
> This needs a better name since its only for displays.  Also maybe move it 
> into amdgpu_display.c since it's really about turning off the displays.  That 
> said is this really even needed?  The driver already calls its suspend 
> functionality to turn off all of the hardware and put it into a quiescent 
> state before shutdown.  Basically shares the same code we use for suspend.

As per my comment above, for this driver, my patch was a "plea for
help". I have no idea if it's really needed or if suspend handles it.

My main concerns are:

a) If it's possible that someone out there is using this DRM driver
with a "drm_panel" then we need to make sure the panel gets disabled /
unprepared properly at shutdown time. The goal is to remove the
special logic in some panel drivers that disables the panel at
shutdown time. The guidance I got from Maxime is that we should be
relying on the DRM driver to disable panels at shutdown time and not
have extra per-panel code for it.

b) It is documented that DRM driers call drm_atomic_helper_shutdown()
at shutdown time. Even if things are working today, it's always
possible that something will change later and break for drivers that
aren't doing this.


If you're confident that everything is great for the "amdgpu" driver
then I'm happy to drop this patch and not consider it a blocker for
the eventual removal of the code in the individual panels drivers.

If, after reading this, you conclude that some sort of patch is
needed, I'd love it if you could test/post a patch yourself and then
I'll drop this patch from my series.


-Doug


RE: [PATCH 3/6] drm/edid: include drm_eld.h only where required

2023-09-25 Thread Golani, Mitulkumar Ajitkumar
> -Original Message-
> From: Nikula, Jani 
> Sent: Thursday, September 7, 2023 2:58 PM
> To: dri-devel@lists.freedesktop.org
> Cc: intel-...@lists.freedesktop.org; Nikula, Jani ;
> Golani, Mitulkumar Ajitkumar 
> Subject: [PATCH 3/6] drm/edid: include drm_eld.h only where required
> 
> Reduce the dependencies on drm_eld.h. Some files might be able to drop the
> dependency on drm_edid.h too with the direct inclusion of drm_eld.h.
> 
> Cc: Mitul Golani 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c| 1 +
>  drivers/gpu/drm/drm_edid.c   | 1 +
>  drivers/gpu/drm/i915/display/intel_audio.c   | 1 +
>  drivers/gpu/drm/i915/display/intel_crtc_state_dump.c | 1 +
>  drivers/gpu/drm/i915/display/intel_sdvo.c| 1 +
>  drivers/gpu/drm/nouveau/dispnv50/disp.c  | 1 +
>  drivers/gpu/drm/radeon/radeon_audio.c| 1 +
>  drivers/gpu/drm/tegra/hdmi.c | 1 +
>  drivers/gpu/drm/tegra/sor.c  | 1 +
>  include/drm/drm_edid.h   | 1 -
>  sound/core/pcm_drm_eld.c | 1 +
>  sound/soc/codecs/hdac_hdmi.c | 1 +
>  sound/soc/codecs/hdmi-codec.c| 1 +
>  sound/x86/intel_hdmi_audio.c | 1 +
>  14 files changed, 13 insertions(+), 1 deletion(-)
> 
> 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 268cb99a4c4b..fe7e307ae7f9 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -86,6 +86,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index
> 39dd3f694544..2025970816c9 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -41,6 +41,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_audio.c
> b/drivers/gpu/drm/i915/display/intel_audio.c
> index 19605264a35c..39f5b698e08a 100644
> --- a/drivers/gpu/drm/i915/display/intel_audio.c
> +++ b/drivers/gpu/drm/i915/display/intel_audio.c
> @@ -25,6 +25,7 @@
>  #include 
> 
>  #include 
> +#include 
>  #include 
> 
>  #include "i915_drv.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
> b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
> index 8d4640d0fd34..fcddd6d81768 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
> @@ -4,6 +4,7 @@
>   */
> 
>  #include 
> +#include 
> 
>  #include "i915_drv.h"
>  #include "intel_crtc_state_dump.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c
> b/drivers/gpu/drm/i915/display/intel_sdvo.c
> index 135a2527fd1b..6abae283998e 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -35,6 +35,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
> 
>  #include "i915_drv.h"
>  #include "i915_reg.h"
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index 4e7c9c353c51..9332aa633867 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -38,6 +38,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/drivers/gpu/drm/radeon/radeon_audio.c
> b/drivers/gpu/drm/radeon/radeon_audio.c
> index d6ccaf24ee0c..279bf130a18c 100644
> --- a/drivers/gpu/drm/radeon/radeon_audio.c
> +++ b/drivers/gpu/drm/radeon/radeon_audio.c
> @@ -26,6 +26,7 @@
>  #include 
> 
>  #include 
> +#include 
>  #include "dce6_afmt.h"
>  #include "evergreen_hdmi.h"
>  #include "radeon.h"
> diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
> index 0ba3ca3ac509..a1fcee665023 100644
> --- a/drivers/gpu/drm/tegra/hdmi.c
> +++ b/drivers/gpu/drm/tegra/hdmi.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index
> d5a3d3f4fece..83341576630d 100644
> --- a/drivers/gpu/drm/tegra/sor.c
> +++ b/drivers/gpu/drm/tegra/sor.c
> @@ -20,6 +20,7 @@
>  #include   #include
>   #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index
> 1ff52f57ab9c..e98aa6818700 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -25,7 +25,6 @@
> 
>  #include 
>  #include 
> -#include  /* FIXME: remove this, include directly where
> needed */  #include 
> 
>  struct drm_device;
> diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c index
> 07075071972d..1cdca4d4fc9c 100644
> --- 

Re: [v1 1/2] ASoC: dt-bindings: mediatek,mt8188-mt6359: add RT5682S support

2023-09-25 Thread Rob Herring


On Mon, 25 Sep 2023 16:38:46 +0800, xiazhengqiao wrote:
> Add compatible string "mediatek,mt8188-rt5682" to support new board
> with rt5682s codec.
> ---
>  .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml| 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring 



Re: [PATCH 5/7] drm/sun4i: dw-hdmi: Split driver registration

2023-09-25 Thread kernel test robot
Hi Jernej,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.6-rc3 next-20230925]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Jernej-Skrabec/drm-sun4i-dw-hdmi-Deinit-PHY-in-fail-path/20230925-032818
base:   linus/master
patch link:
https://lore.kernel.org/r/20230924192604.3262187-6-jernej.skrabec%40gmail.com
patch subject: [PATCH 5/7] drm/sun4i: dw-hdmi: Split driver registration
config: s390-allmodconfig 
(https://download.01.org/0day-ci/archive/20230926/202309260027.anijqrbi-...@intel.com/config)
compiler: s390-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20230926/202309260027.anijqrbi-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202309260027.anijqrbi-...@intel.com/

All errors (new ones prefixed by >>):

   s390-linux-ld: drivers/gpu/drm/sun4i/sun8i_hdmi_phy.o: in function 
`sun8i_hdmi_phy_driver_init':
>> sun8i_hdmi_phy.c:(.init.text+0x0): multiple definition of `init_module'; 
>> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.o:sun8i_dw_hdmi.c:(.init.text+0x0): 
>> first defined here
   s390-linux-ld: drivers/gpu/drm/sun4i/sun8i_hdmi_phy.o: in function 
`sun8i_hdmi_phy_driver_exit':
>> sun8i_hdmi_phy.c:(.exit.text+0x0): multiple definition of `cleanup_module'; 
>> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.o:sun8i_dw_hdmi.c:(.exit.text+0x0): 
>> first defined here

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


RE: [PATCH 2/6] drm/eld: replace uint8_t with u8

2023-09-25 Thread Golani, Mitulkumar Ajitkumar



> -Original Message-
> From: Nikula, Jani 
> Sent: Thursday, September 7, 2023 2:58 PM
> To: dri-devel@lists.freedesktop.org
> Cc: intel-...@lists.freedesktop.org; Nikula, Jani ;
> Golani, Mitulkumar Ajitkumar 
> Subject: [PATCH 2/6] drm/eld: replace uint8_t with u8
> 
> Unify on kernel types.
> 
> Cc: Mitul Golani 
> Signed-off-by: Jani Nikula 
> ---
>  include/drm/drm_eld.h | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/include/drm/drm_eld.h b/include/drm/drm_eld.h index
> 9bde89bd96ea..7b674256b9aa 100644
> --- a/include/drm/drm_eld.h
> +++ b/include/drm/drm_eld.h
> @@ -70,7 +70,7 @@
>   * drm_eld_mnl - Get ELD monitor name length in bytes.
>   * @eld: pointer to an eld memory structure with mnl set
>   */
> -static inline int drm_eld_mnl(const uint8_t *eld)
> +static inline int drm_eld_mnl(const u8 *eld)
>  {
>   return (eld[DRM_ELD_CEA_EDID_VER_MNL] &
> DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;  } @@ -79,7 +79,7 @@
> static inline int drm_eld_mnl(const uint8_t *eld)
>   * drm_eld_sad - Get ELD SAD structures.
>   * @eld: pointer to an eld memory structure with sad_count set
>   */
> -static inline const uint8_t *drm_eld_sad(const uint8_t *eld)
> +static inline const u8 *drm_eld_sad(const u8 *eld)
>  {
>   unsigned int ver, mnl;
> 
> @@ -98,7 +98,7 @@ static inline const uint8_t *drm_eld_sad(const uint8_t
> *eld)
>   * drm_eld_sad_count - Get ELD SAD count.
>   * @eld: pointer to an eld memory structure with sad_count set
>   */
> -static inline int drm_eld_sad_count(const uint8_t *eld)
> +static inline int drm_eld_sad_count(const u8 *eld)
>  {
>   return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] &
> DRM_ELD_SAD_COUNT_MASK) >>
>   DRM_ELD_SAD_COUNT_SHIFT;
> @@ -111,7 +111,7 @@ static inline int drm_eld_sad_count(const uint8_t
> *eld)
>   * This is a helper for determining the payload size of the baseline block, 
> in
>   * bytes, for e.g. setting the Baseline_ELD_Len field in the ELD header 
> block.
>   */
> -static inline int drm_eld_calc_baseline_block_size(const uint8_t *eld)
> +static inline int drm_eld_calc_baseline_block_size(const u8 *eld)
>  {
>   return DRM_ELD_MONITOR_NAME_STRING -
> DRM_ELD_HEADER_BLOCK_SIZE +
>   drm_eld_mnl(eld) + drm_eld_sad_count(eld) * 3; @@ -127,7
> +127,7 @@ static inline int drm_eld_calc_baseline_block_size(const uint8_t
> *eld)
>   *
>   * The returned value is guaranteed to be a multiple of 4.
>   */
> -static inline int drm_eld_size(const uint8_t *eld)
> +static inline int drm_eld_size(const u8 *eld)
>  {
>   return DRM_ELD_HEADER_BLOCK_SIZE +
> eld[DRM_ELD_BASELINE_ELD_LEN] * 4;  } @@ -139,7 +139,7 @@ static inline
> int drm_eld_size(const uint8_t *eld)
>   * The returned value is the speakers mask. User has to use
> %DRM_ELD_SPEAKER
>   * field definitions to identify speakers.
>   */
> -static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
> +static inline u8 drm_eld_get_spk_alloc(const u8 *eld)
>  {
>   return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;  } @@ -
> 151,7 +151,7 @@ static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
>   * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or
> %DRM_ELD_CONN_TYPE_DP to
>   * identify the display type connected.
>   */
> -static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
> +static inline u8 drm_eld_get_conn_type(const u8 *eld)

Changes LGTM
Reviewed-by: Mitul Golani 

>  {
>   return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] &
> DRM_ELD_CONN_TYPE_MASK;  }
> --
> 2.39.2



Re: [PATCH 13/15] platform/x86/amd/pmf: Add PMF-AMDGPU set interface

2023-09-25 Thread Mario Limonciello

On 9/25/2023 11:27, Deucher, Alexander wrote:

[Public]


-Original Message-
From: amd-gfx  On Behalf Of
Shyam Sundar S K
Sent: Friday, September 22, 2023 1:51 PM
To: hdego...@redhat.com; markgr...@kernel.org; Natikar, Basavaraj
; ji...@kernel.org;
benjamin.tissoi...@redhat.com; Deucher, Alexander
; Koenig, Christian
; Pan, Xinhui ;
airl...@gmail.com; dan...@ffwll.ch
Cc: S-k, Shyam-sundar ; amd-
g...@lists.freedesktop.org; platform-driver-...@vger.kernel.org; dri-
de...@lists.freedesktop.org; Patil Rajesh ; linux-
in...@vger.kernel.org; Limonciello, Mario 
Subject: [PATCH 13/15] platform/x86/amd/pmf: Add PMF-AMDGPU set
interface

For the Smart PC Solution to fully work, it has to enact to the actions coming
from TA. Add the initial code path for set interface to AMDGPU.


This seems to be limited to backlight at this point.  What does setting or not 
setting the backlight level mean for the system when this framework is in 
place?  What if a user manually changes the backlight level?  Additional 
comments below.



It's also for the display count.



Co-developed-by: Mario Limonciello 
Signed-off-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c | 21
+
  drivers/platform/x86/amd/pmf/pmf.h  |  2 ++
  drivers/platform/x86/amd/pmf/tee-if.c   | 19 +--
  include/linux/amd-pmf-io.h  |  1 +
  4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
index 232d11833ddc..5c567bff0548 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
@@ -68,3 +68,24 @@ int amd_pmf_get_gfx_data(struct amd_gpu_pmf_data
*pmf)
   return 0;
  }
  EXPORT_SYMBOL_GPL(amd_pmf_get_gfx_data);
+
+int amd_pmf_set_gfx_data(struct amd_gpu_pmf_data *pmf) {
+ struct drm_device *drm_dev = pci_get_drvdata(pmf->gpu_dev);
+ struct amdgpu_device *adev = drm_to_adev(drm_dev);
+ struct backlight_device *bd;
+
+ if (!(adev->flags & AMD_IS_APU)) {
+ DRM_ERROR("PMF-AMDGPU interface not supported\n");
+ return -ENODEV;
+ }
+
+ bd = backlight_device_get_by_type(BACKLIGHT_RAW);
+ if (!bd)
+ return -ENODEV;
+
+ backlight_device_set_brightness(bd, pmf->brightness);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(amd_pmf_set_gfx_data);
diff --git a/drivers/platform/x86/amd/pmf/pmf.h
b/drivers/platform/x86/amd/pmf/pmf.h
index 9032df4ba48a..ce89cc0daa5a 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -73,6 +73,7 @@
  #define PMF_POLICY_STT_SKINTEMP_APU  7
  #define PMF_POLICY_STT_SKINTEMP_HS2  8
  #define PMF_POLICY_SYSTEM_STATE  9
+#define PMF_POLICY_DISPLAY_BRIGHTNESS12
  #define PMF_POLICY_P3T   38

  /* TA macros */
@@ -480,6 +481,7 @@ enum ta_pmf_error_type {  };

  struct pmf_action_table {
+ unsigned long display_brightness;
   enum system_state system_state;
   unsigned long spl; /* in mW */
   unsigned long sppt; /* in mW */
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c
b/drivers/platform/x86/amd/pmf/tee-if.c
index 1608996654e8..eef83a4c 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -79,10 +79,10 @@ static int amd_pmf_update_uevents(struct
amd_pmf_dev *dev, u16 event)
   return 0;
  }

-static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct
ta_pmf_enact_result *out)
+static int amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct
+ta_pmf_enact_result *out)
  {
   u32 val, event = 0;
- int idx;
+ int idx, ret;

   for (idx = 0; idx < out->actions_count; idx++) {
   val = out->actions_list[idx].value;
@@ -160,8 +160,23 @@ static void amd_pmf_apply_policies(struct
amd_pmf_dev *dev, struct ta_pmf_enact_
   dev->prev_data->system_state = 0;
   }
   break;
+
+ case PMF_POLICY_DISPLAY_BRIGHTNESS:
+ ret = amd_pmf_get_gfx_data(>gfx_data);
+ if (ret)
+ return ret;
+
+ dev->prev_data->display_brightness = dev-

gfx_data.brightness;


Are we using standardized units for the brightness?  On the GPU side, we align 
with the standard blacklight interface, but internally, the driver has to 
convert units depending on the type of backlight controller used on the 
platform.  Presumably PMF does something similar?

Alex


+ if (dev->prev_data->display_brightness != val) {
+ dev->gfx_data.brightness = val;
+ amd_pmf_set_gfx_data(>gfx_data);
+ dev_dbg(dev->dev, "update

RE: [PATCH 13/15] platform/x86/amd/pmf: Add PMF-AMDGPU set interface

2023-09-25 Thread Deucher, Alexander
[Public]

> -Original Message-
> From: amd-gfx  On Behalf Of
> Shyam Sundar S K
> Sent: Friday, September 22, 2023 1:51 PM
> To: hdego...@redhat.com; markgr...@kernel.org; Natikar, Basavaraj
> ; ji...@kernel.org;
> benjamin.tissoi...@redhat.com; Deucher, Alexander
> ; Koenig, Christian
> ; Pan, Xinhui ;
> airl...@gmail.com; dan...@ffwll.ch
> Cc: S-k, Shyam-sundar ; amd-
> g...@lists.freedesktop.org; platform-driver-...@vger.kernel.org; dri-
> de...@lists.freedesktop.org; Patil Rajesh ; linux-
> in...@vger.kernel.org; Limonciello, Mario 
> Subject: [PATCH 13/15] platform/x86/amd/pmf: Add PMF-AMDGPU set
> interface
>
> For the Smart PC Solution to fully work, it has to enact to the actions coming
> from TA. Add the initial code path for set interface to AMDGPU.

This seems to be limited to backlight at this point.  What does setting or not 
setting the backlight level mean for the system when this framework is in 
place?  What if a user manually changes the backlight level?  Additional 
comments below.

>
> Co-developed-by: Mario Limonciello 
> Signed-off-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c | 21
> +
>  drivers/platform/x86/amd/pmf/pmf.h  |  2 ++
>  drivers/platform/x86/amd/pmf/tee-if.c   | 19 +--
>  include/linux/amd-pmf-io.h  |  1 +
>  4 files changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
> index 232d11833ddc..5c567bff0548 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
> @@ -68,3 +68,24 @@ int amd_pmf_get_gfx_data(struct amd_gpu_pmf_data
> *pmf)
>   return 0;
>  }
>  EXPORT_SYMBOL_GPL(amd_pmf_get_gfx_data);
> +
> +int amd_pmf_set_gfx_data(struct amd_gpu_pmf_data *pmf) {
> + struct drm_device *drm_dev = pci_get_drvdata(pmf->gpu_dev);
> + struct amdgpu_device *adev = drm_to_adev(drm_dev);
> + struct backlight_device *bd;
> +
> + if (!(adev->flags & AMD_IS_APU)) {
> + DRM_ERROR("PMF-AMDGPU interface not supported\n");
> + return -ENODEV;
> + }
> +
> + bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> + if (!bd)
> + return -ENODEV;
> +
> + backlight_device_set_brightness(bd, pmf->brightness);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(amd_pmf_set_gfx_data);
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h
> b/drivers/platform/x86/amd/pmf/pmf.h
> index 9032df4ba48a..ce89cc0daa5a 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -73,6 +73,7 @@
>  #define PMF_POLICY_STT_SKINTEMP_APU  7
>  #define PMF_POLICY_STT_SKINTEMP_HS2  8
>  #define PMF_POLICY_SYSTEM_STATE  9
> +#define PMF_POLICY_DISPLAY_BRIGHTNESS12
>  #define PMF_POLICY_P3T   38
>
>  /* TA macros */
> @@ -480,6 +481,7 @@ enum ta_pmf_error_type {  };
>
>  struct pmf_action_table {
> + unsigned long display_brightness;
>   enum system_state system_state;
>   unsigned long spl; /* in mW */
>   unsigned long sppt; /* in mW */
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 1608996654e8..eef83a4c 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -79,10 +79,10 @@ static int amd_pmf_update_uevents(struct
> amd_pmf_dev *dev, u16 event)
>   return 0;
>  }
>
> -static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct
> ta_pmf_enact_result *out)
> +static int amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct
> +ta_pmf_enact_result *out)
>  {
>   u32 val, event = 0;
> - int idx;
> + int idx, ret;
>
>   for (idx = 0; idx < out->actions_count; idx++) {
>   val = out->actions_list[idx].value;
> @@ -160,8 +160,23 @@ static void amd_pmf_apply_policies(struct
> amd_pmf_dev *dev, struct ta_pmf_enact_
>   dev->prev_data->system_state = 0;
>   }
>   break;
> +
> + case PMF_POLICY_DISPLAY_BRIGHTNESS:
> + ret = amd_pmf_get_gfx_data(>gfx_data);
> + if (ret)
> + return ret;
> +
> + dev->prev_data->display_brightness = dev-
> >gfx_data.brightness;

Are we using standardized units for the brightness?  On the GPU side, we align 
with the standard blacklight interface, but internally, the driver has to 
convert units depending on the type of backlight controller used on the 
platform.  Presumably PMF does something similar?

Alex

> + if (dev->prev_data->display_brightness != val) {
> + dev->gfx_data.brightness = val;
> +  

Re: [RFT PATCH v2 11/12] drm/radeon: Call drm_helper_force_disable_all() at shutdown/remove time

2023-09-25 Thread Doug Anderson
Hi,

On Mon, Sep 25, 2023 at 8:49 AM Deucher, Alexander
 wrote:
>
> [Public]
>
> > -Original Message-
> > From: Douglas Anderson 
> > Sent: Thursday, September 21, 2023 3:27 PM
> > To: dri-devel@lists.freedesktop.org; Maxime Ripard 
> > Cc: Douglas Anderson ; Pan, Xinhui
> > ; airl...@gmail.com; Deucher, Alexander
> > ; amd-...@lists.freedesktop.org; Koenig,
> > Christian ; dan...@ffwll.ch; linux-
> > ker...@vger.kernel.org
> > Subject: [RFT PATCH v2 11/12] drm/radeon: Call
> > drm_helper_force_disable_all() at shutdown/remove time
> >
> > Based on grepping through the source code, this driver appears to be missing
> > a call to drm_atomic_helper_shutdown(), or in this case the non-atomic
> > equivalent drm_helper_force_disable_all(), at system shutdown time and at
> > driver remove time. This is important because
> > drm_helper_force_disable_all() will cause panels to get disabled cleanly 
> > which
> > may be important for their power sequencing. Future changes will remove any
> > custom powering off in individual panel drivers so the DRM drivers need to
> > start getting this right.
> >
> > The fact that we should call drm_atomic_helper_shutdown(), or in this case
> > the non-atomic equivalent drm_helper_force_disable_all(), in the case of OS
> > shutdown/restart comes straight out of the kernel doc "driver instance
> > overview" in drm_drv.c.
> >
> > NOTE: in order to get things inserted in the right place, I had to replace 
> > the
> > old/deprecated drm_put_dev() function with the equivalent new calls.
> >
> > Suggested-by: Maxime Ripard 
> > Reviewed-by: Maxime Ripard 
> > Signed-off-by: Douglas Anderson 
> > ---
> > I honestly have no idea if I got this patch right. The shutdown() function
> > already had some special case logic for PPC, Loongson, and VMs and I don't
> > 100% for sure know how this interacts with those. Everything here is just
> > compile tested.
>
> I think the reason for most of this funniness is to reduce shutdown time.  
> Lots of users complain if driver takes a while to shutdown and there is a 
> point to be made that if the system is going into power down, there is not 
> much reason to spend a lot of time messing with the hardware.

Sure, you don't want to do too much at shutdown time. That's the whole
reason that "shutdown" doesn't do a full remove / uninitialization of
all drivers. ...but drm_atomic_helper_shutdown() is documented to do
the things that are important for shutdown. Specifically, it cleanly
disables all of the displays. Depending on the display, this could
avoid temporary garbage on the display at reboot time or it could even
be important for the long term health of the panel.

-Doug


Re: [PATCH v6 09/16] dt-bindings: media: mediatek: mdp3: add component STITCH for MT8195

2023-09-25 Thread Rob Herring
On Fri, Sep 22, 2023 at 03:21:09PM +0800, Moudy Ho wrote:
> Add the fundamental hardware configuration of component STITCH,

STITCH? You mean TCC?

> which is controlled by MDP3 on MT8195.
> 
> Signed-off-by: Moudy Ho 
> ---
>  .../bindings/media/mediatek,mdp3-tcc.yaml | 60 +++
>  1 file changed, 60 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml 
> b/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
> new file mode 100644
> index ..245e2134c74a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
> @@ -0,0 +1,60 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/mediatek,mdp3-tcc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek Media Data Path 3 TCC
> +
> +maintainers:
> +  - Matthias Brugger 
> +
> +description:
> +  One of Media Data Path 3 (MDP3) components used to support
> +  HDR gamma curve conversion HDR displays.

Please say what the block does.

> +
> +properties:
> +  compatible:
> +enum:
> +  - mediatek,mt8195-mdp3-tcc
> +
> +  reg:
> +maxItems: 1
> +
> +  mediatek,gce-client-reg:
> +description:
> +  The register of display function block to be set by gce. There are 4 
> arguments,
> +  such as gce node, subsys id, offset and register size. The subsys id 
> that is
> +  mapping to the register of display function blocks is defined in the 
> gce header
> +  include/dt-bindings/gce/-gce.h of each chips.
> +$ref: /schemas/types.yaml#/definitions/phandle-array
> +items:
> +  items:
> +- description: phandle of GCE
> +- description: GCE subsys id
> +- description: register offset
> +- description: register size
> +maxItems: 1
> +
> +  clocks:
> +minItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - mediatek,gce-client-reg
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +#include 
> +#include 
> +
> +display@1400b000 {
> +compatible = "mediatek,mt8195-mdp3-tcc";
> +reg = <0x1400b000 0x1000>;
> +mediatek,gce-client-reg = < SUBSYS_1400 0xb000 0x1000>;
> +clocks = < CLK_VPP0_MDP_TCC>;
> +};
> -- 
> 2.18.0
> 


Re: [PATCH v3 6/7] drm/msm/dp: add pm_runtime_force_suspend()/resume()

2023-09-25 Thread Kuogee Hsieh



On 9/22/2023 6:35 PM, Abhinav Kumar wrote:

Hi Stephen

On 9/22/2023 2:54 PM, Stephen Boyd wrote:

Quoting Dmitry Baryshkov (2023-09-19 02:50:12)
On Mon, 18 Sept 2023 at 20:48, Kuogee Hsieh 
 wrote:



On 9/15/2023 6:21 PM, Dmitry Baryshkov wrote:
On Sat, 16 Sept 2023 at 00:38, Kuogee Hsieh 
 wrote:

Add pm_runtime_force_suspend()/resume() to complete incorporating pm
runtime framework into DP driver. Both dp_pm_prepare() and 
dp_pm_complete()
are added to set hpd_state to correct state. After resume, DP 
driver will

re training its main link after .hpd_enable() callback enabled HPD
interrupts and bring up display accordingly.

How will it re-train the main link? What is the code path for that?


1) for edp, dp_bridge_atomic_enable(), called from framework, to start
link training and bring up display.


And this path doesn't use .hpd_enable() which you have mentioned in
the commit message. Please don't try to shorten the commit message.
You see, I have had questions to several of them, which means that
they were not verbose enough.



2) for external DP, HPD_PLUG_INT will be generated to start link
training and bring up display.


This should be hpd_notify, who starts link training, not some event.


I think this driver should train the link during atomic_enable(), not
hpd_notify() (or directly from the irq handler). The drm_bridge_funcs
talk a bit about when the clocks and timing signals are supposed to be
enabled. For example, struct drm_bridge_funcs::atomic_pre_enable() says
the "display pipe (i.e.  clocks and timing signals) feeding this bridge
will not yet be running when this callback is called". And struct
drm_bridge_funcs::atomic_enable() says "this callback must enable the
display link feeding the next bridge in the chain if there is one."

That looks to me like link training, i.e. the display link, should
happen in the enable path and not hpd_notify. It looks like link
training could fail, but when that happens I believe the driver should
call drm_connector_set_link_status_property() with
DRM_MODE_LINK_STATUS_BAD. The two callers of that which exist in the
tree also call drm_kms_helper_hotplug_event() or
drm_kms_helper_connector_hotplug_event() after updating the link so that
userspace knows to try again.

It would be nice if there was some drm_bridge_set_link_status_bad() API
that bridge drivers could use to signal that the link status is bad and
call the hotplug helper. Maybe it could also record some diagnostics
about which bridge failed to setup the link and stop the atomic_enable()
chain for that connector.


Doing link training when we get hpd instead of atomic_enable() is a 
design choice we have been following for a while because for the case 
when link training fails in atomic_enable() and setting the link 
status property as you mentioned, the compositor needs to be able to 
handle that and also needs to try with a different resolution or take 
some other corrective action. We have seen many compositors not able 
to handle this complexity. So the design sends the hotplug to usermode 
only after link training succeeds.


I do not think we should change this design unless prototyped with an 
existing compositor such as chrome or android at this point.


Thanks

Abhinav



We did perform link training at atomic_enable() at eDP case since we can 
assume link training will always success without link rate or link lane 
being reduced.


However for external DP case, link training can not be guarantee always 
success without link rate or lane being reduced as Abhinav mentioned.


In addition,  CTS (compliance test) it required to complete link 
training within 10ms after hpd asserted.


I am not sure do link training at atomic_enable() can meet this timing 
requirement.






Re: [RFC PATCH v2 4/5] drm/amd/display: hook DCN30 color state logging to DTN log

2023-09-25 Thread Harry Wentland



On 2023-09-13 12:43, Melissa Wen wrote:
> Color caps changed between HW versions which caused DCN10 color state
> sections on DTN log no longer fit DCN3.0 versions. Create a
> DCN3.0-specific color state logging and hook it to drivers of DCN3.0
> family.
> 
> rfc-v2:
> - detail RAM mode for gamcor and blnd gamma blocks
> 
> Signed-off-by: Melissa Wen 
> ---
>  .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  5 +-
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 88 +++
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.h|  3 +
>  .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c |  1 +
>  .../drm/amd/display/dc/dcn301/dcn301_init.c   |  1 +
>  .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  2 +
>  6 files changed, 99 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
> b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
> index a0c489ed218c..9255425ef794 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
> @@ -358,7 +358,10 @@ void dcn10_log_hw_state(struct dc *dc,
>  
>   dcn10_log_hubp_states(dc, log_ctx);
>  
> - dcn10_log_color_state(dc, log_ctx);
> + if (dc->hwss.log_color_state)
> + dc->hwss.log_color_state(dc, log_ctx);
> + else
> + dcn10_log_color_state(dc, log_ctx);
>  
>   DTN_INFO("OTG:  v_bs  v_be  v_ss  v_se  vpol  vmax  vmin  vmax_sel  
> vmin_sel  h_bs  h_be  h_ss  h_se  hpol  htot  vtot  underflow blank_en\n");
>  
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
> b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
> index 255713ec29bb..47119ae80e98 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
> @@ -69,6 +69,94 @@
>  #define FN(reg_name, field_name) \
>   hws->shifts->field_name, hws->masks->field_name
>  
> +void
> +dcn30_log_color_state(struct dc *dc,
> +   struct dc_log_buffer_ctx *log_ctx)
> +{
> + struct dc_context *dc_ctx = dc->ctx;
> + struct resource_pool *pool = dc->res_pool;
> + int i;
> +
> + DTN_INFO("DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode"
> +  "  3DLUT mode  3DLUT bit depth  3DLUT size  RGAM mode"
> +  "  GAMUT mode  "
> +  "C11 C12   C13 C14   C21 C22   C23 C24   C31 C32   C33 C34\n");
> +
> + for (i = 0; i < pool->pipe_count; i++) {
> + struct dpp *dpp = pool->dpps[i];
> + struct dcn_dpp_state s = {0};
> +
> + dpp->funcs->dpp_read_state(dpp, );
> +
> + if (!s.is_enabled)
> + continue;
> +
> + DTN_INFO("[%2d]:  %7x  %13s  %8s  %11s  %10s  %15s  %10s  %9s"
> +  "  %10x  %08xh %08xh %08xh %08xh %08xh %08xh",
> + dpp->inst,
> + s.pre_dgam_mode,
> + (s.pre_dgam_select == 0) ? "sRGB" :
> +  ((s.pre_dgam_select == 1) ? "Gamma 2.2" :
> +  ((s.pre_dgam_select == 2) ? "Gamma 2.4" :
> +  ((s.pre_dgam_select == 3) ? "Gamma 2.6" :
> +  ((s.pre_dgam_select == 4) ? "BT.709" :
> +  ((s.pre_dgam_select == 5) ? "PQ" :
> +  ((s.pre_dgam_select == 6) ? "HLG" :
> +  "Unknown")),
> + (s.gamcor_mode == 0) ? "Bypass" :
> +  ((s.gamcor_mode == 1) ? "RAM A" :
> +  "RAM B"),
> + (s.shaper_lut_mode == 1) ? "RAM A" :
> +  ((s.shaper_lut_mode == 2) ? "RAM B" :
> +  "Bypass"),
> + (s.lut3d_mode == 1) ? "RAM A" :
> +  ((s.lut3d_mode == 2) ? "RAM B" :
> + "Bypass"),
> + (s.lut3d_bit_depth <= 0) ? "12-bit" : "10-bit",
> + (s.lut3d_size == 0) ? "17x17x17" : "9x9x9",
> + (s.rgam_lut_mode == 0) ? "Bypass" :
> +  ((s.rgam_lut_mode == 1) ? "RAM A" :
> +"RAM B"),
> + s.gamut_remap_mode,
> + s.gamut_remap_c11_c12, s.gamut_remap_c13_c14,
> + s.gamut_remap_c21_c22, s.gamut_remap_c23_c24,
> + s.gamut_remap_c31_c32, s.gamut_remap_c33_c34);
> + DTN_INFO("\n");
> + }
> + DTN_INFO("\n");
> +
> + DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  
> OVERLAP_ONLY  IDLE"
> +  "  SHAPER mode  3DLUT mode  3DLUT bit-depth  3DLUT size  OGAM 
> mode  OGAM LUT"
> +  "  GAMUT mode  C11 C12   C33 C34\n");
> +
> + for (i = 0; i < pool->pipe_count; i++) {
> + struct mpcc_state s = {0};
> 

Re: [RFC PATCH v2 0/5] drm/amd/display: improve DTN color state log

2023-09-25 Thread Harry Wentland



On 2023-09-13 12:43, Melissa Wen wrote:
> Hi,
> 
> This is an update of previous RFC [0] improving the data collection of
> Gamma Correction and Blend Gamma color blocks.
> 
> As I mentioned in the last version, I'm updating the color state part of
> DTN log to match DCN3.0 HW better. Currently, the DTN log considers the
> DCN10 color pipeline, which is useless for DCN3.0 because of all the
> differences in color caps between DCN versions. In addition to new color
> blocks and caps, some semantic differences made the DCN10 output not fit
> DCN30.
> 
> In this RFC, the first patch adds new color state elements to DPP and
> implements the reading of registers according to HW blocks. Similarly to
> MPC, the second patch also creates a DCN3-specific function to read the
> MPC state and add the MPC color state logging to it. With DPP and MPC
> color-register reading, I detach DCN10 color state logging from the HW
> log and create a `.log_color_state` hook for logging color state
> according to HW color blocks with DCN30 as the first use case. Finally,
> the last patch adds DPP and MPC color caps output to facilitate
> understanding of the color state log.
> 
> This version works well with the driver-specific color properties[1] and
> steamdeck/gamescope[2] together, where we can see color state changing
> from default values.
> 
> Here is a before vs. after example:
> 
> Without this series:
> ===
> DPP:IGAM format  IGAM modeDGAM modeRGAM mode  GAMUT mode  C11 C12 
>   C13 C14   C21 C22   C23 C24   C31 C32   C33 C34
> [ 0]:0h  BypassFixed  Bypass   Bypass0
> h h h h h h
> [ 3]:0h  BypassFixed  Bypass   Bypass0
> h h h h h h
> 
> MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE
> [ 0]:   0h   0h   3h 3   20 0 0
> [ 3]:   0h   3h   fh 2   20 0 0
> 
> With this series (Steamdeck/Gamescope):
> ==
> 
> DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode  3DLUT mode  3DLUT bit 
> depth  3DLUT size  RGAM mode  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 
> C24   C31 C32   C33 C34
> [ 0]:1   sRGBBypassRAM A   RAM B   
> 12-bit17x17x17  RAM A   0  h h h 
> h h h
> [ 1]:1   sRGBBypassRAM B   RAM A   
> 12-bit17x17x17  RAM A   0  h h h 
> h h h
> [ 2]:1   sRGBBypassRAM B   RAM A   
> 12-bit17x17x17  RAM A   0  h h h 
> h h h
> [ 3]:1   sRGBBypassRAM A   RAM B   
> 12-bit17x17x17  RAM A   0  h h h 
> h h h
> 
> DPP Color Caps: input_lut_shared:0  icsc:1  dgam_ram:0  dgam_rom: 
> srgb:1,bt2020:1,gamma2_2:1,pq:1,hlg:1  post_csc:1  gamcor:1  
> dgam_rom_for_yuv:0  3d_lut:1  blnd_lut:1  oscs:0
> 
> MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE  
> SHAPER mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM mode  OGAM LUT  
> GAMUT mode  C11 C12   C33 C34
> [ 0]:   0h   0h   2h 3   01 0 0   
> Bypass  Bypass   12-bit17x17x17RAM A  
>  0 h h
> [ 1]:   0h   1h   fh 2   20 0 0   
> Bypass  Bypass   12-bit17x17x17 Bypass A  
>  0 h h
> [ 2]:   0h   2h   3h 3   01 0 0   
> Bypass  Bypass   12-bit17x17x17 Bypass A  
>  0 h h
> [ 3]:   0h   3h   1h 3   20 0 0   
> Bypass  Bypass   12-bit17x17x17 Bypass A  
>  0 h h
> 
> MPC Color Caps: gamut_remap:1, 3dlut:2, ogam_ram:1, ocsc:1
> 
> With this series (Steamdeck/KDE):
> 
> 
> DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode  3DLUT mode  3DLUT bit 
> depth  3DLUT size  RGAM mode  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 
> C24   C31 C32   C33 C34
> [ 0]:0   sRGBBypass   Bypass  Bypass   
> 12-bit   9x9x9 Bypass   0  h h h 
> h h h
> [ 3]:0   sRGBBypass   Bypass  Bypass   
> 12-bit   9x9x9 Bypass   0  h h h 
> h h h
> 
> DPP Color Caps: input_lut_shared:0  icsc:1  dgam_ram:0  dgam_rom: 
> 

Re: [RFC PATCH v2 3/5] drm/amd/display: create DCN3-specific log for MPC state

2023-09-25 Thread Harry Wentland



On 2023-09-13 12:43, Melissa Wen wrote:
> Logging DCN3 MPC state was following DCN1 implementation that doesn't
> consider new DCN3 MPC color blocks. Create new elements according to
> DCN3 MPC color caps and a new DCN3-specific function for reading MPC
> data.
> 
> Signed-off-by: Melissa Wen 
> ---
>  .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c  | 55 ++-
>  drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   | 13 +
>  2 files changed, 67 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c 
> b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
> index d1500b223858..d164fbf89212 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
> @@ -1382,8 +1382,61 @@ static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc)
>   }
>  }
>  
> +static void mpc3_read_mpcc_state(
> + struct mpc *mpc,
> + int mpcc_inst,
> + struct mpcc_state *s)
> +{
> + struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
> + uint32_t rmu_status = 0xf;
> +
> + REG_GET(MPCC_OPP_ID[mpcc_inst], MPCC_OPP_ID, >opp_id);
> + REG_GET(MPCC_TOP_SEL[mpcc_inst], MPCC_TOP_SEL, >dpp_id);
> + REG_GET(MPCC_BOT_SEL[mpcc_inst], MPCC_BOT_SEL, >bot_mpcc_id);
> + REG_GET_4(MPCC_CONTROL[mpcc_inst], MPCC_MODE, >mode,
> + MPCC_ALPHA_BLND_MODE, >alpha_mode,
> + MPCC_ALPHA_MULTIPLIED_MODE, >pre_multiplied_alpha,
> + MPCC_BLND_ACTIVE_OVERLAP_ONLY, >overlap_only);
> + REG_GET_2(MPCC_STATUS[mpcc_inst], MPCC_IDLE, >idle,
> + MPCC_BUSY, >busy);
> +
> + /* Color blocks state */
> + REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, _status);
> + if (rmu_status == mpcc_inst) {
> + REG_GET(SHAPER_CONTROL[0],
> + MPC_RMU_SHAPER_LUT_MODE_CURRENT, >shaper_lut_mode);
> + REG_GET(RMU_3DLUT_MODE[0],
> + MPC_RMU_3DLUT_MODE_CURRENT,  >lut3d_mode);
> + REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[0],
> + MPC_RMU_3DLUT_30BIT_EN, >lut3d_bit_depth);
> + REG_GET(RMU_3DLUT_MODE[0],
> + MPC_RMU_3DLUT_SIZE, >lut3d_size);
> + } else {
> + REG_GET(SHAPER_CONTROL[1],
> + MPC_RMU_SHAPER_LUT_MODE_CURRENT, >shaper_lut_mode);
> + REG_GET(RMU_3DLUT_MODE[1],
> + MPC_RMU_3DLUT_MODE_CURRENT,  >lut3d_mode);
> + REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[1],
> + MPC_RMU_3DLUT_30BIT_EN, >lut3d_bit_depth);
> + REG_GET(RMU_3DLUT_MODE[1],
> + MPC_RMU_3DLUT_SIZE, >lut3d_size);
> + }
> + REG_GET_2(MPCC_OGAM_CONTROL[mpcc_inst],
> +MPCC_OGAM_MODE_CURRENT, >rgam_mode,
> +MPCC_OGAM_SELECT_CURRENT, >rgam_lut);
> + REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_inst],
> + MPCC_GAMUT_REMAP_MODE_CURRENT, >gamut_remap_mode);
> + if (s->gamut_remap_mode == 1) {
> + s->gamut_remap_c11_c12 = 
> REG_READ(MPC_GAMUT_REMAP_C11_C12_A[mpcc_inst]);
> + s->gamut_remap_c33_c34 = 
> REG_READ(MPC_GAMUT_REMAP_C33_C34_A[mpcc_inst]);
> + } else if (s->gamut_remap_mode == 2) {
> + s->gamut_remap_c11_c12 = 
> REG_READ(MPC_GAMUT_REMAP_C11_C12_B[mpcc_inst]);
> + s->gamut_remap_c33_c34 = 
> REG_READ(MPC_GAMUT_REMAP_C33_C34_B[mpcc_inst]);

Any reason we're getting (and printing) only the first and last
coefficients? Is it to avoid printing lines that are too wide?

Harry

> + }
> +}
> +
>  static const struct mpc_funcs dcn30_mpc_funcs = {
> - .read_mpcc_state = mpc1_read_mpcc_state,
> + .read_mpcc_state = mpc3_read_mpcc_state,
>   .insert_plane = mpc1_insert_plane,
>   .remove_mpcc = mpc1_remove_mpcc,
>   .mpc_init = mpc1_mpc_init,
> 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 8d86159d9de0..e60b3503605b 100644
> --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> @@ -193,6 +193,19 @@ struct mpcc_state {
>   uint32_t overlap_only;
>   uint32_t idle;
>   uint32_t busy;
> + uint32_t shaper_lut_mode;
> + uint32_t lut3d_mode;
> + uint32_t lut3d_bit_depth;
> + uint32_t lut3d_size;
> + uint32_t rgam_mode;
> + uint32_t rgam_lut;
> + uint32_t gamut_remap_mode;
> + uint32_t gamut_remap_c11_c12;
> + uint32_t gamut_remap_c13_c14;
> + uint32_t gamut_remap_c21_c22;
> + uint32_t gamut_remap_c23_c24;
> + uint32_t gamut_remap_c31_c32;
> + uint32_t gamut_remap_c33_c34;
>  };
>  
>  /**



[PATCH] drm/nouveau/kms/nv50: hide unused variables

2023-09-25 Thread Arnd Bergmann
From: Arnd Bergmann 

After a recent change, two variables are only used in an #ifdef:

drivers/gpu/drm/nouveau/dispnv50/disp.c: In function 'nv50_sor_atomic_disable':
drivers/gpu/drm/nouveau/dispnv50/disp.c:1569:13: error: unused variable 'ret' 
[-Werror=unused-variable]
 1569 | int ret;
  | ^~~
drivers/gpu/drm/nouveau/dispnv50/disp.c:1568:28: error: unused variable 'aux' 
[-Werror=unused-variable]
 1568 | struct drm_dp_aux *aux = _connector->aux;
  |^~~

Move them into the same conditional block, along with the nv_connector variable
that becomes unused during that fix.

Fixes: 757033808c95b ("drm/nouveau/kms/nv50-: fixup sink D3 before tearing down 
link")
Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 52f1569ee37c1..a0ac8c258d9ff 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1560,15 +1560,13 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
 {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_head *head = nv50_head(nv_encoder->crtc);
-   struct nouveau_connector *nv_connector = 
nv50_outp_get_old_connector(state, nv_encoder);
 #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+   struct nouveau_connector *nv_connector = 
nv50_outp_get_old_connector(state, nv_encoder);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_backlight *backlight = nv_connector->backlight;
-#endif
struct drm_dp_aux *aux = _connector->aux;
int ret;
 
-#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
if (backlight && backlight->uses_dpcd) {
ret = drm_edp_backlight_disable(aux, >edp_info);
if (ret < 0)
-- 
2.39.2



RE: [RFT PATCH v2 07/12] drm/amdgpu: Call drm_atomic_helper_shutdown() at shutdown time

2023-09-25 Thread Deucher, Alexander
[Public]

> -Original Message-
> From: Douglas Anderson 
> Sent: Thursday, September 21, 2023 3:27 PM
> To: dri-devel@lists.freedesktop.org; Maxime Ripard 
> Cc: Douglas Anderson ; Zhang, Bokun
> ; Zhang, Hawking ;
> Zhu, James ; Zhao, Victor ;
> Pan, Xinhui ; airl...@gmail.com; Deucher, Alexander
> ; amd-...@lists.freedesktop.org; Koenig,
> Christian ; dan...@ffwll.ch; Kuehling, Felix
> ; jim.cro...@gmail.com; Ma, Le
> ; Lazar, Lijo ; linux-
> ker...@vger.kernel.org; maarten.lankho...@linux.intel.com; Limonciello,
> Mario ; mdaen...@redhat.com; Zhang,
> Morris ; SHANMUGAM, SRINIVASAN
> ; tzimmerm...@suse.de
> Subject: [RFT PATCH v2 07/12] drm/amdgpu: Call
> drm_atomic_helper_shutdown() at shutdown time
>
> Based on grepping through the source code this driver appears to be missing a
> call to drm_atomic_helper_shutdown() at system shutdown time. Among
> other things, this means that if a panel is in use that it won't be cleanly
> powered off at system shutdown time.
>
> The fact that we should call drm_atomic_helper_shutdown() in the case of OS
> shutdown/restart comes straight out of the kernel doc "driver instance
> overview" in drm_drv.c.
>
> Suggested-by: Maxime Ripard 
> Signed-off-by: Douglas Anderson 
> ---
> This commit is only compile-time tested.
>
> ...and further, I'd say that this patch is more of a plea for help than a 
> patch I
> think is actually right. I'm _fairly_ certain that drm/amdgpu needs this call 
> at
> shutdown time but the logic is a bit hard for me to follow. I'd appreciate if
> anyone who actually knows what this should look like could illuminate me, or
> perhaps even just post a patch themselves!
>
> (no changes since v1)
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h|  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 ++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|  2 ++
>  3 files changed, 13 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 8f2255b3a38a..cfcff0b37466 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1104,6 +1104,7 @@ static inline struct amdgpu_device
> *amdgpu_ttm_adev(struct ttm_device *bdev)  int amdgpu_device_init(struct
> amdgpu_device *adev,
>  uint32_t flags);
>  void amdgpu_device_fini_hw(struct amdgpu_device *adev);
> +void amdgpu_device_shutdown_hw(struct amdgpu_device *adev);
>  void amdgpu_device_fini_sw(struct amdgpu_device *adev);
>
>  int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev); diff --git
> a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index a2cdde0ca0a7..fa5925c2092d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -4247,6 +4247,16 @@ void amdgpu_device_fini_hw(struct
> amdgpu_device *adev)
>
>  }
>
> +void amdgpu_device_shutdown_hw(struct amdgpu_device *adev) {

This needs a better name since its only for displays.  Also maybe move it into 
amdgpu_display.c since it's really about turning off the displays.  That said 
is this really even needed?  The driver already calls its suspend functionality 
to turn off all of the hardware and put it into a quiescent state before 
shutdown.  Basically shares the same code we use for suspend.


> + if (adev->mode_info.mode_config_initialized) {
> + if (!drm_drv_uses_atomic_modeset(adev_to_drm(adev)))
> + drm_helper_force_disable_all(adev_to_drm(adev));
> + else
> + drm_atomic_helper_shutdown(adev_to_drm(adev));
> + }
> +}
> +
>  void amdgpu_device_fini_sw(struct amdgpu_device *adev)  {
>   int idx;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index e90f730eb715..3a7cbff111d1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -2333,6 +2333,8 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
>   struct drm_device *dev = pci_get_drvdata(pdev);
>   struct amdgpu_device *adev = drm_to_adev(dev);
>
> + amdgpu_device_shutdown_hw(adev);

I would move this after the ras_intr check below.

Alex

> +
>   if (amdgpu_ras_intr_triggered())
>   return;
>
> --
> 2.42.0.515.g380fc7ccd1-goog



RE: [PATCH 1/6] drm/edid: split out drm_eld.h from drm_edid.h

2023-09-25 Thread Golani, Mitulkumar Ajitkumar
> -Original Message-
> From: Nikula, Jani 
> Sent: Thursday, September 7, 2023 2:58 PM
> To: dri-devel@lists.freedesktop.org
> Cc: intel-...@lists.freedesktop.org; Nikula, Jani ;
> Golani, Mitulkumar Ajitkumar 
> Subject: [PATCH 1/6] drm/edid: split out drm_eld.h from drm_edid.h
> 
> The drm_edid.[ch] files are starting to be a bit crowded, and with plans to
> add more ELD related functionality, it's perhaps cleanest to split the ELD 
> code
> out to a header of its own.
> 
> Include drm_eld.h from drm_edid.h for starters, and leave it to follow-up
> work to only include drm_eld.h where needed.
> 
> Cc: Mitul Golani 
> Signed-off-by: Jani Nikula 
> ---
>  Documentation/gpu/drm-kms-helpers.rst |   3 +
>  include/drm/drm_edid.h| 149 +---
>  include/drm/drm_eld.h | 159 ++
>  3 files changed, 163 insertions(+), 148 deletions(-)  create mode 100644
> include/drm/drm_eld.h
> 
> diff --git a/Documentation/gpu/drm-kms-helpers.rst
> b/Documentation/gpu/drm-kms-helpers.rst
> index b8ab05e42dbb..f0f93aa62545 100644
> --- a/Documentation/gpu/drm-kms-helpers.rst
> +++ b/Documentation/gpu/drm-kms-helpers.rst
> @@ -363,6 +363,9 @@ EDID Helper Functions Reference  .. kernel-doc::
> drivers/gpu/drm/drm_edid.c
> :export:
> 
> +.. kernel-doc:: include/drm/drm_eld.h
> +   :internal:
> +
>  SCDC Helper Functions Reference
>  ===
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index
> 882d2638708e..1ff52f57ab9c 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -25,6 +25,7 @@
> 
>  #include 
>  #include 
> +#include  /* FIXME: remove this, include directly where
> +needed */
>  #include 
> 
>  struct drm_device;
> @@ -269,64 +270,6 @@ struct detailed_timing {
>  #define DRM_EDID_DSC_MAX_SLICES  0xf
>  #define DRM_EDID_DSC_TOTAL_CHUNK_KBYTES  0x3f
> 
> -/* ELD Header Block */
> -#define DRM_ELD_HEADER_BLOCK_SIZE4
> -
> -#define DRM_ELD_VER  0
> -# define DRM_ELD_VER_SHIFT   3
> -# define DRM_ELD_VER_MASK(0x1f << 3)
> -# define DRM_ELD_VER_CEA861D (2 << 3) /* supports 861D or
> below */
> -# define DRM_ELD_VER_CANNED  (0x1f << 3)
> -
> -#define DRM_ELD_BASELINE_ELD_LEN 2   /* in dwords! */
> -
> -/* ELD Baseline Block for ELD_Ver == 2 */
> -#define DRM_ELD_CEA_EDID_VER_MNL 4
> -# define DRM_ELD_CEA_EDID_VER_SHIFT  5
> -# define DRM_ELD_CEA_EDID_VER_MASK   (7 << 5)
> -# define DRM_ELD_CEA_EDID_VER_NONE   (0 << 5)
> -# define DRM_ELD_CEA_EDID_VER_CEA861 (1 << 5)
> -# define DRM_ELD_CEA_EDID_VER_CEA861A(2 << 5)
> -# define DRM_ELD_CEA_EDID_VER_CEA861BCD  (3 << 5)
> -# define DRM_ELD_MNL_SHIFT   0
> -# define DRM_ELD_MNL_MASK(0x1f << 0)
> -
> -#define DRM_ELD_SAD_COUNT_CONN_TYPE  5
> -# define DRM_ELD_SAD_COUNT_SHIFT 4
> -# define DRM_ELD_SAD_COUNT_MASK  (0xf << 4)
> -# define DRM_ELD_CONN_TYPE_SHIFT 2
> -# define DRM_ELD_CONN_TYPE_MASK  (3 << 2)
> -# define DRM_ELD_CONN_TYPE_HDMI  (0 << 2)
> -# define DRM_ELD_CONN_TYPE_DP(1 << 2)
> -# define DRM_ELD_SUPPORTS_AI (1 << 1)
> -# define DRM_ELD_SUPPORTS_HDCP   (1 << 0)
> -
> -#define DRM_ELD_AUD_SYNCH_DELAY  6   /* in units of
> 2 ms */
> -# define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa/* 500 ms */
> -
> -#define DRM_ELD_SPEAKER  7
> -# define DRM_ELD_SPEAKER_MASK0x7f
> -# define DRM_ELD_SPEAKER_RLRC(1 << 6)
> -# define DRM_ELD_SPEAKER_FLRC(1 << 5)
> -# define DRM_ELD_SPEAKER_RC  (1 << 4)
> -# define DRM_ELD_SPEAKER_RLR (1 << 3)
> -# define DRM_ELD_SPEAKER_FC  (1 << 2)
> -# define DRM_ELD_SPEAKER_LFE (1 << 1)
> -# define DRM_ELD_SPEAKER_FLR (1 << 0)
> -
> -#define DRM_ELD_PORT_ID  8   /* offsets 8..15
> inclusive */
> -# define DRM_ELD_PORT_ID_LEN 8
> -
> -#define DRM_ELD_MANUFACTURER_NAME0   16
> -#define DRM_ELD_MANUFACTURER_NAME1   17
> -
> -#define DRM_ELD_PRODUCT_CODE018
> -#define DRM_ELD_PRODUCT_CODE119
> -
> -#define DRM_ELD_MONITOR_NAME_STRING  20  /* offsets
> 20..(20+mnl-1) inclusive */
> -
> -#define DRM_ELD_CEA_SAD(mnl, sad)(20 + (mnl) + 3 * (sad))
> -
>  struct edid {
>   u8 header[8];
>   /* Vendor & product info */
> @@ -409,96 +352,6 @@ drm_hdmi_avi_infoframe_quant_range(struct
> hdmi_avi_infoframe *frame,
>  const struct drm_display_mode *mode,
>  enum hdmi_quantization_range
> rgb_quant_range);
> 
> -/**
> - * drm_eld_mnl - Get ELD monitor name length in bytes.
> - * @eld: pointer to an eld memory structure with mnl set
> - */
> -static inline int drm_eld_mnl(const uint8_t *eld) -{
> - return (eld[DRM_ELD_CEA_EDID_VER_MNL] &
> 

RE: [RFT PATCH v2 11/12] drm/radeon: Call drm_helper_force_disable_all() at shutdown/remove time

2023-09-25 Thread Deucher, Alexander
[Public]

> -Original Message-
> From: Douglas Anderson 
> Sent: Thursday, September 21, 2023 3:27 PM
> To: dri-devel@lists.freedesktop.org; Maxime Ripard 
> Cc: Douglas Anderson ; Pan, Xinhui
> ; airl...@gmail.com; Deucher, Alexander
> ; amd-...@lists.freedesktop.org; Koenig,
> Christian ; dan...@ffwll.ch; linux-
> ker...@vger.kernel.org
> Subject: [RFT PATCH v2 11/12] drm/radeon: Call
> drm_helper_force_disable_all() at shutdown/remove time
>
> Based on grepping through the source code, this driver appears to be missing
> a call to drm_atomic_helper_shutdown(), or in this case the non-atomic
> equivalent drm_helper_force_disable_all(), at system shutdown time and at
> driver remove time. This is important because
> drm_helper_force_disable_all() will cause panels to get disabled cleanly which
> may be important for their power sequencing. Future changes will remove any
> custom powering off in individual panel drivers so the DRM drivers need to
> start getting this right.
>
> The fact that we should call drm_atomic_helper_shutdown(), or in this case
> the non-atomic equivalent drm_helper_force_disable_all(), in the case of OS
> shutdown/restart comes straight out of the kernel doc "driver instance
> overview" in drm_drv.c.
>
> NOTE: in order to get things inserted in the right place, I had to replace the
> old/deprecated drm_put_dev() function with the equivalent new calls.
>
> Suggested-by: Maxime Ripard 
> Reviewed-by: Maxime Ripard 
> Signed-off-by: Douglas Anderson 
> ---
> I honestly have no idea if I got this patch right. The shutdown() function
> already had some special case logic for PPC, Loongson, and VMs and I don't
> 100% for sure know how this interacts with those. Everything here is just
> compile tested.

I think the reason for most of this funniness is to reduce shutdown time.  Lots 
of users complain if driver takes a while to shutdown and there is a point to 
be made that if the system is going into power down, there is not much reason 
to spend a lot of time messing with the hardware.

Alex

>
> (no changes since v1)
>
>  drivers/gpu/drm/radeon/radeon_drv.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c
> b/drivers/gpu/drm/radeon/radeon_drv.c
> index 39cdede460b5..67995ea24852 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -38,6 +38,7 @@
>  #include 
>
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -357,7 +358,9 @@ radeon_pci_remove(struct pci_dev *pdev)  {
>   struct drm_device *dev = pci_get_drvdata(pdev);
>
> - drm_put_dev(dev);
> + drm_dev_unregister(dev);
> + drm_helper_force_disable_all(dev);
> + drm_dev_put(dev);
>  }
>
>  static void
> @@ -368,6 +371,8 @@ radeon_pci_shutdown(struct pci_dev *pdev)
>*/
>   if (radeon_device_is_virtual())
>   radeon_pci_remove(pdev);
> + else
> + drm_helper_force_disable_all(pci_get_drvdata(pdev));
>
>  #if defined(CONFIG_PPC64) || defined(CONFIG_MACH_LOONGSON64)
>   /*
> --
> 2.42.0.515.g380fc7ccd1-goog



Re: [PATCH 3/7] drm/sun4i: dw-hdmi: Switch to bridge functions

2023-09-25 Thread Jernej Škrabec
Dne ponedeljek, 25. september 2023 ob 09:57:22 CEST je Maxime Ripard napisal(a):
> Hi,
> 
> On Sun, Sep 24, 2023 at 09:26:00PM +0200, Jernej Skrabec wrote:
> > Since ddc-en property handling was moved from sun8i dw-hdmi driver to
> > display connector driver, probe order of drivers determines if EDID is
> > properly read at boot time or not.
> > 
> > In order to fix this, let's switch to bridge functions which allows us
> > to build proper chain and defer execution until all drivers are probed.
> > 
> > Fixes: 920169041baa ("drm/sun4i: dw-hdmi: Fix ddc-en GPIO consumer 
> > conflict")
> > Signed-off-by: Jernej Skrabec 
> > ---
> >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 114 +-
> >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h |   5 ++
> >  2 files changed, 117 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c 
> > b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> > index 8f8d3bdba5ce..93831cdf1917 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> > @@ -8,14 +8,82 @@
> >  #include 
> >  #include 
> >  
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> >  
> > +#include 
> > +
> >  #include "sun8i_dw_hdmi.h"
> >  #include "sun8i_tcon_top.h"
> >  
> > +#define bridge_to_sun8i_dw_hdmi(x) \
> > +   container_of(x, struct sun8i_dw_hdmi, enc_bridge)
> > +
> > +static int sun8i_hdmi_enc_attach(struct drm_bridge *bridge,
> > +enum drm_bridge_attach_flags flags)
> > +{
> > +   struct sun8i_dw_hdmi *hdmi = bridge_to_sun8i_dw_hdmi(bridge);
> > +
> > +   return drm_bridge_attach(>encoder, hdmi->hdmi_bridge,
> > +>enc_bridge, flags);
> > +}
> > +
> > +static void sun8i_hdmi_enc_detach(struct drm_bridge *bridge)
> > +{
> > +   struct sun8i_dw_hdmi *hdmi = bridge_to_sun8i_dw_hdmi(bridge);
> > +
> > +   cec_notifier_conn_unregister(hdmi->cec_notifier);
> > +   hdmi->cec_notifier = NULL;
> > +}
> > +
> > +static void sun8i_hdmi_enc_hpd_notify(struct drm_bridge *bridge,
> > + enum drm_connector_status status)
> > +{
> > +   struct sun8i_dw_hdmi *hdmi = bridge_to_sun8i_dw_hdmi(bridge);
> > +   struct edid *edid;
> > +
> > +   if (!hdmi->cec_notifier)
> > +   return;
> > +
> > +   if (status == connector_status_connected) {
> > +   edid = drm_bridge_get_edid(hdmi->hdmi_bridge, hdmi->connector);
> > +   if (edid)
> > +   cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier,
> > +edid);
> > +   } else {
> > +   cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
> > +   }
> > +}
> > +
> > +static int sun8i_hdmi_enc_atomic_check(struct drm_bridge *bridge,
> > +  struct drm_bridge_state *bridge_state,
> > +  struct drm_crtc_state *crtc_state,
> > +  struct drm_connector_state *conn_state)
> > +{
> > +   struct drm_connector_state *old_conn_state =
> > +   drm_atomic_get_old_connector_state(conn_state->state,
> > +  conn_state->connector);
> > +
> > +   if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, 
> > conn_state))
> > +   crtc_state->mode_changed = true;
> > +
> > +   return 0;
> > +}
> > +
> > +static const struct drm_bridge_funcs sun8i_hdmi_enc_bridge_funcs = {
> > +   .attach = sun8i_hdmi_enc_attach,
> > +   .detach = sun8i_hdmi_enc_detach,
> > +   .hpd_notify = sun8i_hdmi_enc_hpd_notify,
> > +   .atomic_check = sun8i_hdmi_enc_atomic_check,
> > +   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> > +   .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> > +   .atomic_reset = drm_atomic_helper_bridge_reset,
> > +};
> > +
> >  static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder,
> >struct drm_display_mode *mode,
> >struct drm_display_mode *adj_mode)
> > @@ -99,6 +167,8 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct 
> > device *master,
> >  {
> > struct platform_device *pdev = to_platform_device(dev);
> > struct dw_hdmi_plat_data *plat_data;
> > +   struct cec_connector_info conn_info;
> > +   struct drm_connector *connector;
> > struct drm_device *drm = data;
> > struct device_node *phy_node;
> > struct drm_encoder *encoder;
> > @@ -187,18 +257,57 @@ static int sun8i_dw_hdmi_bind(struct device *dev, 
> > struct device *master,
> >  
> > plat_data->mode_valid = hdmi->quirks->mode_valid;
> > plat_data->use_drm_infoframe = hdmi->quirks->use_drm_infoframe;
> > +   plat_data->output_port = 1;
> > sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data);
> >  
> > platform_set_drvdata(pdev, hdmi);
> >  
> > -   hdmi->hdmi = dw_hdmi_bind(pdev, encoder, 

Re: [PATCH] drm/i915/gem: Make i915_gem_shrinker multi-gt aware

2023-09-25 Thread Andi Shyti
Hi Jani,

> >>struct i915_vma *vma, *next;
> >>unsigned long freed_pages = 0;
> >>intel_wakeref_t wakeref;
> >> +  struct intel_gt *gt;
> >> +  int i;
> >
> > the trend is to use 'unsigned int' here and I've seen it
> > reviewed. Personally, if I really have to express a preference, I
> > prefer 'int' because it's a bit safer, generally I don't really
> > mind :)
> 
> Always use int over unsigned int if you don't have a specific reason not
> to. ("It can't be negative" is not a good reason.)

Finally someone! I totally agree!

Andi


Re: [PATCH] drm/i915/gem: Make i915_gem_shrinker multi-gt aware

2023-09-25 Thread Jani Nikula
On Mon, 25 Sep 2023, Andi Shyti  wrote:
> Hi Nirmoy,
>
> you forgot the v2 here.
>
> On Mon, Sep 25, 2023 at 03:49:38PM +0200, Nirmoy Das wrote:
>> From: Jonathan Cavitt 
>> 
>> Where applicable, use for_each_gt instead of to_gt in the
>> i915_gem_shrinker functions to make them apply to more than just the
>> primary GT.  Specifically, this ensure i915_gem_shrink_all retires all
>> requests across all GTs, and this makes i915_gem_shrinker_vmap unmap
>> VMAs from all GTs.
>> 
>> v2: Pass correct GT to intel_gt_retire_requests(Andrzej).
>> 
>> Signed-off-by: Jonathan Cavitt 
>> Signed-off-by: Nirmoy Das 
>> Reviewed-by: Andrzej Hajda 
>
> [...]
>
>> -if (shrink & I915_SHRINK_ACTIVE)
>> -/* Retire requests to unpin all idle contexts */
>> -intel_gt_retire_requests(to_gt(i915));
>> +if (shrink & I915_SHRINK_ACTIVE) {
>> +for_each_gt(gt, i915, i)
>> +/* Retire requests to unpin all idle contexts */
>> +intel_gt_retire_requests(gt);
>> +}
>
> These two brackets are not needed.
>
>>  
>>  /*
>>   * As we may completely rewrite the (un)bound list whilst unbinding
>> @@ -389,6 +393,8 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, 
>> unsigned long event, void *ptr
>>  struct i915_vma *vma, *next;
>>  unsigned long freed_pages = 0;
>>  intel_wakeref_t wakeref;
>> +struct intel_gt *gt;
>> +int i;
>
> the trend is to use 'unsigned int' here and I've seen it
> reviewed. Personally, if I really have to express a preference, I
> prefer 'int' because it's a bit safer, generally I don't really
> mind :)

Always use int over unsigned int if you don't have a specific reason not
to. ("It can't be negative" is not a good reason.)

BR,
Jani.

>
> The rest looks good.
>
> Reviewed-by: Andi Shyti  
>
> Andi

-- 
Jani Nikula, Intel


Re: [PATCH 5/7] drm/sun4i: dw-hdmi: Split driver registration

2023-09-25 Thread Jernej Škrabec
Dne ponedeljek, 25. september 2023 ob 09:47:15 CEST je Maxime Ripard napisal(a):
> On Sun, Sep 24, 2023 at 09:26:02PM +0200, Jernej Skrabec wrote:
> > There is no reason to register two drivers in same place. Using macro
> > lowers amount of boilerplate code.
> 
> There's one actually: you can't have several module_init functions in
> the some module, and both files are compiled into the same module.

Yeah, I figured as much. However, I think code clean up is good enough reason
to add hidden option in Kconfig and extra entry in Makefile (in v2).

Do you agree?

Best regards,
Jernej 






Re: [Intel-gfx] [PATCH] drm/i915: Zap some empty lines

2023-09-25 Thread Andi Shyti
Hi Tvrtko,

On Mon, Sep 25, 2023 at 03:28:27PM +0100, Tvrtko Ursulin wrote:
> 
> On 25/09/2023 15:14, Andi Shyti wrote:
> > Hi Tvrtko,
> > 
> > On Wed, Sep 20, 2023 at 09:57:15AM +0100, Tvrtko Ursulin wrote:
> > > From: Tvrtko Ursulin 
> > > 
> > > Recent refactoring left an unsightly block of empty lines. Remove them.
> > > 
> > > Signed-off-by: Tvrtko Ursulin 
> > > Cc: Dnyaneshwar Bhadane 
> > > Cc: Anusha Srivatsa 
> > > Cc: Radhakrishna Sripada 
> > 
> > as this isn't merged yet:
> > 
> > Reviewed-by: Andi Shyti 
> 
> Thanks, I am catching up with things and this wasn't so important. If you
> have a spare moment feel free to push it?

All right, pushed to drm-intel-next :)

Thanks,
Andi


Re: [PATCH v1] drm/dp/mst: fix missing modeset unlock for MST port detect

2023-09-25 Thread Alex Deucher
On Fri, Sep 22, 2023 at 3:22 PM Imre Deak  wrote:
>
> On Fri, Sep 22, 2023 at 03:02:23PM -0400, Lyude Paul wrote:
> >
> > Oh! wow thank you for catching this:
> >
> > Reviewed-by: Lyude Paul 
> >
> > I will go and push this to drm-misc-next in just a moment
> >
> > On Fri, 2023-09-15 at 10:24 +0530, Ramya SR wrote:
> > > Modeset mutex unlock is missing in drm_dp_mst_detect_port function.
> > > This will lead to deadlock if calling the function multiple times in
> > > an atomic operation, for example, getting imultiple MST ports status
> > > for a DP MST bonding scenario.
> > >
> > > Signed-off-by: Ramya SR 
> > > ---
> > >  drivers/gpu/drm/display/drm_dp_mst_topology.c | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
> > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > index ed96cfc..d6512c4 100644
> > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > @@ -4154,7 +4154,7 @@ drm_dp_mst_detect_port(struct drm_connector 
> > > *connector,
> > >
> > > ret = drm_modeset_lock(>base.lock, ctx);
> > > if (ret)
> > > -   goto out;
> > > +   goto fail;
> > >
> > > ret = connector_status_disconnected;
> > >
> > > @@ -4181,6 +4181,8 @@ drm_dp_mst_detect_port(struct drm_connector 
> > > *connector,
> > > break;
> > > }
> > >  out:
> > > +   drm_modeset_unlock(>base.lock);
>
> Isn't this supposed to be unlocked only by drm_helper_probe_detect_ctx()
> / drm_helper_probe_detect() ?

Maybe adding a comment to that effect would be helpful for the future.

Alex

>
> > > +fail:
> > > drm_dp_mst_topology_put_port(port);
> > > return ret;
> > >  }
> >
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> >


Re: [PATCH] drm/amd/display: set stream gamut remap matrix to MPC for DCN3+

2023-09-25 Thread Harry Wentland



On 2023-07-21 09:24, Melissa Wen wrote:
> dc->caps.color.mpc.gamut_remap says there is a post-blending color block
> for gamut remap matrix for DCN3 HW family and newer versions. However,
> those drivers still follow DCN10 programming that remap stream
> gamut_remap_matrix to DPP (pre-blending).
> 
> To enable pre-blending and post-blending gamut_remap matrix supports at
> the same time, set stream gamut_remap to MPC and plane gamut_remap to
> DPP for DCN families that support both.
> 
> It was tested using IGT KMS color tests for DRM CRTC CTM property and it
> preserves test results.
> 
> Signed-off-by: Melissa Wen 
> 

Reviewed-by: Harry Wentland 

and merged.

I also took the liberty to expand this to the recently merged dcn35
code.

Harry

> ---
> 
> Hi,
> 
> Two relevant things to consider for this change. One is that mapping DRM
> CRTC CTM to MPC is a more consistent way since CRTC CTM is a
> post-blending transformation. Second, programming stream
> gamut_remap_matrix on MPC enables us to provide support for both plane
> CTM and CRTC CTM color properties. If we don't make this separation, we
> would need to reject an atomic commit that tries to set both properties
> at the same time and userspace may also get unexpected results.
> 
> Thanks in advance for any feeback,
> 
> Melissa
> 
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 37 +++
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.h|  3 ++
>  .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c |  2 +-
>  .../drm/amd/display/dc/dcn301/dcn301_init.c   |  2 +-
>  .../gpu/drm/amd/display/dc/dcn31/dcn31_init.c |  2 +-
>  .../drm/amd/display/dc/dcn314/dcn314_init.c   |  2 +-
>  .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c |  2 +-
>  7 files changed, 45 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
> b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
> index 4cd4ae07d73d..4fb4e9ec03f1 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
> @@ -186,6 +186,43 @@ bool dcn30_set_input_transfer_func(struct dc *dc,
>   return result;
>  }
>  
> +void dcn30_program_gamut_remap(struct pipe_ctx *pipe_ctx)
> +{
> + int i = 0;
> + struct dpp_grph_csc_adjustment dpp_adjust;
> + struct mpc_grph_gamut_adjustment mpc_adjust;
> + int mpcc_id = pipe_ctx->plane_res.hubp->inst;
> + struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
> +
> + memset(_adjust, 0, sizeof(dpp_adjust));
> + dpp_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
> +
> + if (pipe_ctx->plane_state &&
> + pipe_ctx->plane_state->gamut_remap_matrix.enable_remap == true) {
> + dpp_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
> + for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
> + dpp_adjust.temperature_matrix[i] =
> + 
> pipe_ctx->plane_state->gamut_remap_matrix.matrix[i];
> + }
> +
> + 
> pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp,
> + _adjust);
> +
> + memset(_adjust, 0, sizeof(mpc_adjust));
> + mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
> +
> + if (pipe_ctx->top_pipe == NULL) {
> + if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
> + mpc_adjust.gamut_adjust_type = 
> GRAPHICS_GAMUT_ADJUST_TYPE_SW;
> + for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
> + mpc_adjust.temperature_matrix[i] =
> + 
> pipe_ctx->stream->gamut_remap_matrix.matrix[i];
> + }
> + }
> +
> + mpc->funcs->set_gamut_remap(mpc, mpcc_id, _adjust);
> +}
> +
>  bool dcn30_set_output_transfer_func(struct dc *dc,
>   struct pipe_ctx *pipe_ctx,
>   const struct dc_stream_state *stream)
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h 
> b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h
> index a24a8e33a3d2..cb34ca932a5f 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h
> +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h
> @@ -58,6 +58,9 @@ bool dcn30_set_blend_lut(struct pipe_ctx *pipe_ctx,
>  bool dcn30_set_input_transfer_func(struct dc *dc,
>   struct pipe_ctx *pipe_ctx,
>   const struct dc_plane_state *plane_state);
> +
> +void dcn30_program_gamut_remap(struct pipe_ctx *pipe_ctx);
> +
>  bool dcn30_set_output_transfer_func(struct dc *dc,
>   struct pipe_ctx *pipe_ctx,
>   const struct dc_stream_state *stream);
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c 
> b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c
> index 

[PATCH v5 10/10] drm/msm/a6xx: Poll for GBIF unhalt status in hw_init

2023-09-25 Thread Konrad Dybcio
Some GPUs - particularly A7xx ones - are really really stubborn and
sometimes take a longer-than-expected time to finish unhalting GBIF.

Note that this is not caused by the request a few lines above.

Poll for the unhalt ack to make sure we're not trying to write bits to
an essentially dead GPU that can't receive data on its end of the bus.
Failing to do this will result in inexplicable GMU timeouts or worse.

This is a rather ugly hack which introduces a whole lot of latency.

Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Dmitry Baryshkov  # sm8450
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 2313620084b6..11cb410e0ac7 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1629,6 +1629,10 @@ static int hw_init(struct msm_gpu *gpu)
mb();
}
 
+   /* Some GPUs are stubborn and take their sweet time to unhalt GBIF! */
+   if (adreno_is_a7xx(adreno_gpu) && a6xx_has_gbif(adreno_gpu))
+   spin_until(!gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK));
+
gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0);
 
if (adreno_is_a619_holi(adreno_gpu))

-- 
2.42.0



[PATCH v5 07/10] drm/msm/a6xx: Mostly implement A7xx gpu_state

2023-09-25 Thread Konrad Dybcio
Provide the necessary alternations to mostly support state dumping on
A7xx. Newer GPUs will probably require more changes here. Crashdumper
and debugbus remain untested.

Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Dmitry Baryshkov  # sm8450
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 52 +++-
 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 61 -
 2 files changed, 110 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
index 4e5d650578c6..18be2d3bde09 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
@@ -948,6 +948,18 @@ static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu)
return gpu_read(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2) >> 14;
 }
 
+static u32 a7xx_get_cp_roq_size(struct msm_gpu *gpu)
+{
+   /*
+* The value at CP_ROQ_THRESHOLDS_2[20:31] is in 4dword units.
+* That register however is not directly accessible from APSS on A7xx.
+* Program the SQE_UCODE_DBG_ADDR with offset=0x70d3 and read the value.
+*/
+   gpu_write(gpu, REG_A6XX_CP_SQE_UCODE_DBG_ADDR, 0x70d3);
+
+   return 4 * (gpu_read(gpu, REG_A6XX_CP_SQE_UCODE_DBG_DATA) >> 20);
+}
+
 /* Read a block of data from an indexed register pair */
 static void a6xx_get_indexed_regs(struct msm_gpu *gpu,
struct a6xx_gpu_state *a6xx_state,
@@ -1019,8 +1031,40 @@ static void a6xx_get_indexed_registers(struct msm_gpu 
*gpu,
 
/* Restore the size in the hardware */
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, mempool_size);
+}
+
+static void a7xx_get_indexed_registers(struct msm_gpu *gpu,
+   struct a6xx_gpu_state *a6xx_state)
+{
+   int i, indexed_count, mempool_count;
+
+   indexed_count = ARRAY_SIZE(a7xx_indexed_reglist);
+   mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
 
-   a6xx_state->nr_indexed_regs = count;
+   a6xx_state->indexed_regs = state_kcalloc(a6xx_state,
+   indexed_count + mempool_count,
+   sizeof(*a6xx_state->indexed_regs));
+   if (!a6xx_state->indexed_regs)
+   return;
+
+   a6xx_state->nr_indexed_regs = indexed_count + mempool_count;
+
+   /* First read the common regs */
+   for (i = 0; i < indexed_count; i++)
+   a6xx_get_indexed_regs(gpu, a6xx_state, _indexed_reglist[i],
+   _state->indexed_regs[i]);
+
+   gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, 0, BIT(2));
+   gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));
+
+   /* Get the contents of the CP_BV mempool */
+   for (i = 0; i < mempool_count; i++)
+   a6xx_get_indexed_regs(gpu, a6xx_state, 
a7xx_cp_bv_mempool_indexed,
+   _state->indexed_regs[indexed_count - 1 + i]);
+
+   gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(2), 0);
+   gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);
+   return;
 }
 
 struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu)
@@ -1056,6 +1100,12 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu 
*gpu)
return _state->base;
 
/* Get the banks of indexed registers */
+   if (adreno_is_a7xx(adreno_gpu)) {
+   a7xx_get_indexed_registers(gpu, a6xx_state);
+   /* Further codeflow is untested on A7xx. */
+   return _state->base;
+   }
+
a6xx_get_indexed_registers(gpu, a6xx_state);
 
/*
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
index e788ed72eb0d..8d7e6f26480a 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
@@ -338,6 +338,28 @@ static const struct a6xx_registers a6xx_vbif_reglist =
 static const struct a6xx_registers a6xx_gbif_reglist =
REGS(a6xx_gbif_registers, 0, 0);
 
+static const u32 a7xx_ahb_registers[] = {
+   /* RBBM_STATUS */
+   0x210, 0x210,
+   /* RBBM_STATUS2-3 */
+   0x212, 0x213,
+};
+
+static const u32 a7xx_gbif_registers[] = {
+   0x3c00, 0x3c0b,
+   0x3c40, 0x3c42,
+   0x3c45, 0x3c47,
+   0x3c49, 0x3c4a,
+   0x3cc0, 0x3cd1,
+};
+
+static const struct a6xx_registers a7xx_ahb_reglist[] = {
+   REGS(a7xx_ahb_registers, 0, 0),
+};
+
+static const struct a6xx_registers a7xx_gbif_reglist =
+   REGS(a7xx_gbif_registers, 0, 0);
+
 static const u32 a6xx_gmu_gx_registers[] = {
/* GMU GX */
0x, 0x, 0x0010, 0x0013, 0x0016, 0x0016, 0x0018, 0x001b,
@@ -384,14 +406,17 @@ static const struct a6xx_registers a6xx_gmu_reglist[] = {
 };
 
 static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu);
+static u32 a7xx_get_cp_roq_size(struct msm_gpu *gpu);
 
-static struct a6xx_indexed_registers {
+struct a6xx_indexed_registers {

[PATCH v5 09/10] drm/msm/a6xx: Add A740 support

2023-09-25 Thread Konrad Dybcio
A740 builds upon the A730 IP, shuffling some values and registers
around. More differences will appear when things like BCL are
implemented.

adreno_is_a740_family is added in preparation for more A7xx GPUs,
the logic checks will be valid resulting in smaller diffs.

Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Dmitry Baryshkov  # sm8450
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c  | 88 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  | 82 +---
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c  | 27 +
 drivers/gpu/drm/msm/adreno/adreno_device.c | 17 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.c|  6 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.h| 19 ++-
 6 files changed, 201 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index c1934d46c0d7..0555a0134fad 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -519,6 +519,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
struct adreno_gpu *adreno_gpu = _gpu->base;
struct platform_device *pdev = to_platform_device(gmu->dev);
void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
+   u32 seqmem0_drv0_reg = REG_A6XX_RSCC_SEQ_MEM_0_DRV0;
void __iomem *seqptr = NULL;
uint32_t pdc_address_offset;
bool pdc_in_aop = false;
@@ -552,21 +553,26 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
-   gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4, 0x8000);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4,
+  adreno_is_a740_family(adreno_gpu) ? 0x8021 : 
0x8000);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
 
+   /* The second spin of A7xx GPUs messed with some register offsets.. */
+   if (adreno_is_a740_family(adreno_gpu))
+   seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;
+
/* Load RSC sequencer uCode for sleep and wakeup */
if (adreno_is_a650_family(adreno_gpu) ||
adreno_is_a7xx(adreno_gpu)) {
-   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xeaaae5a0);
-   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 
0xe1a1ebab);
-   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 
0xa2e0a581);
-   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 
0xecac82e2);
-   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 
0x0020edad);
+   gmu_write_rscc(gmu, seqmem0_drv0_reg, 0xeaaae5a0);
+   gmu_write_rscc(gmu, seqmem0_drv0_reg + 1, 0xe1a1ebab);
+   gmu_write_rscc(gmu, seqmem0_drv0_reg + 2, 0xa2e0a581);
+   gmu_write_rscc(gmu, seqmem0_drv0_reg + 3, 0xecac82e2);
+   gmu_write_rscc(gmu, seqmem0_drv0_reg + 4, 0x0020edad);
} else {
gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 
0xa1e6a6e7);
@@ -764,8 +770,8 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned 
int state)
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
struct adreno_gpu *adreno_gpu = _gpu->base;
u32 fence_range_lower, fence_range_upper;
+   u32 chipid, chipid_min = 0;
int ret;
-   u32 chipid;
 
/* Vote veto for FAL10 */
if (adreno_is_a650_family(adreno_gpu) || adreno_is_a7xx(adreno_gpu)) {
@@ -824,16 +830,37 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, 
unsigned int state)
 */
gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052);
 
-   /*
-* Note that the GMU has a slightly different layout for
-* chip_id, for whatever reason, so a bit of massaging
-* is needed.  The upper 16b are the same, but minor and
-* patchid are packed in four bits each with the lower
-* 8b unused:
-*/
-   chipid  = adreno_gpu->chip_id & 0x;
-   chipid |= (adreno_gpu->chip_id << 4) & 0xf000; /* minor */
-   chipid |= (adreno_gpu->chip_id << 8) & 0x0f00; /* patchid */
+   /* NOTE: A730 may also fall in this if-condition with a future GMU fw 
update. */
+   if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) {
+   /* A7xx GPUs have obfuscated chip IDs. Use constant maj = 7 */
+   

[PATCH v5 08/10] drm/msm/a6xx: Add A730 support

2023-09-25 Thread Konrad Dybcio
Add support for Adreno 730, also known as GEN7_0_x, found on SM8450.

Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Dmitry Baryshkov  # sm8450
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  | 126 -
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c  |  61 ++
 drivers/gpu/drm/msm/adreno/adreno_device.c |  13 +++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h|   7 +-
 4 files changed, 203 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 61ce8d053355..522043883290 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -837,6 +837,63 @@ const struct adreno_reglist a690_hwcg[] = {
{}
 };
 
+const struct adreno_reglist a730_hwcg[] = {
+   { REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x0222 },
+   { REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x0202 },
+   { REG_A6XX_RBBM_CLOCK_HYST_SP0, 0xf3cf },
+   { REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x0080 },
+   { REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x2220 },
+   { REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x0022 },
+   { REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x0007 },
+   { REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x },
+   { REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x0001 },
+   { REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x },
+   { REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x0004 },
+   { REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x0002 },
+   { REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x },
+   { REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x0100 },
+   { REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x2220 },
+   { REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x44000f00 },
+   { REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022 },
+   { REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x0055 },
+   { REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x0011 },
+   { REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00440044 },
+   { REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x0422 },
+   { REG_A7XX_RBBM_CLOCK_MODE2_GRAS, 0x0222 },
+   { REG_A7XX_RBBM_CLOCK_MODE_BV_GRAS, 0x0022 },
+   { REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x0223 },
+   { REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x },
+   { REG_A7XX_RBBM_CLOCK_MODE_BV_GPC, 0x0022 },
+   { REG_A7XX_RBBM_CLOCK_MODE_BV_VFD, 0x },
+   { REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x },
+   { REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+   { REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x },
+   { REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x4000 },
+   { REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x0200 },
+   { REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x },
+   { REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x },
+   { REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x },
+   { REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x },
+   { REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x0002 },
+   { REG_A7XX_RBBM_CLOCK_MODE_BV_LRZ, 0x5552 },
+   { REG_A7XX_RBBM_CLOCK_MODE_CP, 0x0223 },
+   { REG_A6XX_RBBM_CLOCK_CNTL, 0x8aa8aa82 },
+   { REG_A6XX_RBBM_ISDB_CNT, 0x0182 },
+   { REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x },
+   { REG_A6XX_RBBM_SP_HYST_CNT, 0x },
+   { REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x0222 },
+   { REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x0111 },
+   { REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x0555 },
+   {},
+};
+
 static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -1048,6 +1105,59 @@ static const u32 a690_protect[] = {
A6XX_PROTECT_NORDWR(0x11c00, 0x0), /*note: infiite range */
 };
 
+static const u32 a730_protect[] = {
+   A6XX_PROTECT_RDONLY(0x0, 0x04ff),
+   A6XX_PROTECT_RDONLY(0x0050b, 0x0058),
+   A6XX_PROTECT_NORDWR(0x0050e, 0x),
+   A6XX_PROTECT_NORDWR(0x00510, 0x),
+   A6XX_PROTECT_NORDWR(0x00534, 0x),
+   A6XX_PROTECT_RDONLY(0x005fb, 0x009d),
+   A6XX_PROTECT_NORDWR(0x00699, 0x01e9),
+   A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+   A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+   /* 0x008d0-0x008dd are unprotected on purpose for tools like perfetto */
+   A6XX_PROTECT_RDONLY(0x008de, 0x0154),
+   A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+   A6XX_PROTECT_NORDWR(0x0098d, 0x00b2),
+   A6XX_PROTECT_NORDWR(0x00a41, 0x01be),
+   A6XX_PROTECT_NORDWR(0x00df0, 0x0001),
+   A6XX_PROTECT_NORDWR(0x00e01, 0x),
+   A6XX_PROTECT_NORDWR(0x00e07, 0x0008),
+   A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+   A6XX_PROTECT_RDONLY(0x03cc4, 

  1   2   3   >