[PATCH] drm/nouveau/mmu: fix Use after Free bug in nvkm_vmm_node_split

2022-12-29 Thread Zheng Wang
Here is a function call chain.
nvkm_vmm_pfn_map->nvkm_vmm_pfn_split_merge->nvkm_vmm_node_split
If nvkm_vma_tail return NULL in nvkm_vmm_node_split, it will
finally invoke nvkm_vmm_node_merge->nvkm_vmm_node_delete, which
will free the vma. However, nvkm_vmm_pfn_map didn't notice that.
It goes into next label and UAF happens.

Fix it by returning the return-value of nvkm_vmm_node_merge
instead of NULL.

Signed-off-by: Zheng Wang 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index ae793f400ba1..84d6fc87b2e8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -937,8 +937,8 @@ nvkm_vmm_node_split(struct nvkm_vmm *vmm,
if (vma->size != size) {
struct nvkm_vma *tmp;
if (!(tmp = nvkm_vma_tail(vma, vma->size - size))) {
-   nvkm_vmm_node_merge(vmm, prev, vma, NULL, vma->size);
-   return NULL;
+   tmp = nvkm_vmm_node_merge(vmm, prev, vma, NULL, 
vma->size);
+   return tmp;
}
tmp->part = true;
nvkm_vmm_node_insert(vmm, tmp);
-- 
2.25.1



[PATCH v3 08/11] drm/amd: Request GFX9 microcode during IP discovery

2022-12-29 Thread Mario Limonciello
If GFX9 microcode is required but not available during early init, the
firmware framebuffer will have already been released and the screen will
freeze.

Move the request for GFX9 microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Fix issues found on real hardware where num_gfx_rings not set during
   discovery
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 147 +
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 194 ++
 2 files changed, 161 insertions(+), 180 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index edaeec35c39f..0ff1b3872441 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -158,6 +158,68 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
 
+
+/* gfx9 */
+MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
+MODULE_FIRMWARE("amdgpu/vega10_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vega10_me.bin");
+MODULE_FIRMWARE("amdgpu/vega10_mec.bin");
+MODULE_FIRMWARE("amdgpu/vega10_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vega10_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/vega12_ce.bin");
+MODULE_FIRMWARE("amdgpu/vega12_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vega12_me.bin");
+MODULE_FIRMWARE("amdgpu/vega12_mec.bin");
+MODULE_FIRMWARE("amdgpu/vega12_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vega12_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/vega20_ce.bin");
+MODULE_FIRMWARE("amdgpu/vega20_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vega20_me.bin");
+MODULE_FIRMWARE("amdgpu/vega20_mec.bin");
+MODULE_FIRMWARE("amdgpu/vega20_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vega20_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/raven_ce.bin");
+MODULE_FIRMWARE("amdgpu/raven_pfp.bin");
+MODULE_FIRMWARE("amdgpu/raven_me.bin");
+MODULE_FIRMWARE("amdgpu/raven_mec.bin");
+MODULE_FIRMWARE("amdgpu/raven_mec2.bin");
+MODULE_FIRMWARE("amdgpu/raven_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/picasso_ce.bin");
+MODULE_FIRMWARE("amdgpu/picasso_pfp.bin");
+MODULE_FIRMWARE("amdgpu/picasso_me.bin");
+MODULE_FIRMWARE("amdgpu/picasso_mec.bin");
+MODULE_FIRMWARE("amdgpu/picasso_mec2.bin");
+MODULE_FIRMWARE("amdgpu/picasso_rlc.bin");
+MODULE_FIRMWARE("amdgpu/picasso_rlc_am4.bin");
+
+MODULE_FIRMWARE("amdgpu/raven2_ce.bin");
+MODULE_FIRMWARE("amdgpu/raven2_pfp.bin");
+MODULE_FIRMWARE("amdgpu/raven2_me.bin");
+MODULE_FIRMWARE("amdgpu/raven2_mec.bin");
+MODULE_FIRMWARE("amdgpu/raven2_mec2.bin");
+MODULE_FIRMWARE("amdgpu/raven2_rlc.bin");
+MODULE_FIRMWARE("amdgpu/raven_kicker_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/arcturus_mec.bin");
+MODULE_FIRMWARE("amdgpu/arcturus_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/renoir_ce.bin");
+MODULE_FIRMWARE("amdgpu/renoir_pfp.bin");
+MODULE_FIRMWARE("amdgpu/renoir_me.bin");
+MODULE_FIRMWARE("amdgpu/renoir_mec.bin");
+MODULE_FIRMWARE("amdgpu/renoir_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/green_sardine_ce.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_pfp.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_me.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_mec.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_mec2.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
[MP1_HWID]  = "MP1",
[MP2_HWID]  = "MP2",
@@ -1845,8 +1907,90 @@ static int amdgpu_discovery_set_display_ip_blocks(struct 
amdgpu_device *adev)
return 0;
 }
 
+static int amdgpu_discovery_load_gfx9(struct amdgpu_device *adev, char 
*ucode_prefix)
+{
+   uint32_t smu_version;
+   char fw_name[40];
+   int r;
+
+   switch (adev->ip_versions[GC_HWIP][0]) {
+   /* No CPG in Arcturus */
+   case IP_VERSION(9, 4, 1):
+   case IP_VERSION(9, 4, 2):
+   break;
+   default:
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", 
ucode_prefix);
+   r = request_firmware(>gfx.pfp_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", 
ucode_prefix);
+   r = request_firmware(>gfx.me_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", 
ucode_prefix);
+   r = request_firmware(>gfx.ce_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+   }
+
+   if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec.bin", 
ucode_prefix);
+   else
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", 
ucode_prefix);
+   r = request_firmware(>gfx.mec_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+
+   /*
+* For Picasso && AM4 SOCKET board, we use 

[PATCH v3 11/11] drm/amd: Request PSP microcode during IP discovery

2022-12-29 Thread Mario Limonciello
If PSP microcode is required but not available during early init, the
firmware framebuffer will have already been released and the screen will
freeze.

Move the request for PSP microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Only request_firmware, don't validate during discovery
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 173 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   |  58 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  12 +-
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  99 +++--
 drivers/gpu/drm/amd/amdgpu/psp_v11_0.c| 191 +-
 drivers/gpu/drm/amd/amdgpu/psp_v12_0.c|  98 +++--
 drivers/gpu/drm/amd/amdgpu/psp_v13_0.c|  46 +
 drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c  |  18 +-
 drivers/gpu/drm/amd/amdgpu/psp_v3_1.c |  16 +-
 9 files changed, 297 insertions(+), 414 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index ce1aa7683738..6b7dd0cf56ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -158,6 +158,40 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
 
+MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_ta.bin");
+MODULE_FIRMWARE("amdgpu/raven_asd.bin");
+MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
+MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
+MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
+MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
+MODULE_FIRMWARE("amdgpu/raven_ta.bin");
+MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
+MODULE_FIRMWARE("amdgpu/renoir_ta.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin");
+MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
+MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
+MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
+MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
+MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_4_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_4_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
 
 /* gfx9 */
 MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
@@ -339,6 +373,13 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_4_me.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_4_mec.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_4_rlc.bin");
 
+enum amd_psp_microcode_kind {
+   AMD_PSP_MICROCODE_SOS,
+   AMD_PSP_MICROCODE_ASD,
+   AMD_PSP_MICROCODE_TA,
+   AMD_PSP_MICROCODE_TOC,
+};
+
 static const char *hw_id_names[HW_ID_MAX] = {
[MP1_HWID]  = "MP1",
[MP2_HWID]  = "MP2",
@@ -1856,14 +1897,59 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct 
amdgpu_device *adev)
return 0;
 }
 
+static int amdgpu_discovery_load_psp_fw(struct amdgpu_device *adev,
+   enum amd_psp_microcode_kind kind,
+   const char *chip_name)
+{
+   char fw_name[PSP_FW_NAME_LEN];
+
+   switch (kind) {
+   case AMD_PSP_MICROCODE_SOS:
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sos.bin", 
chip_name);
+   return request_firmware(>psp.sos_fw, fw_name, adev->dev);
+   case AMD_PSP_MICROCODE_ASD:
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", 
chip_name);
+   return request_firmware(>psp.asd_fw, fw_name, adev->dev);
+   case AMD_PSP_MICROCODE_TA:
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", 
chip_name);
+   return request_firmware(>psp.ta_fw, fw_name, adev->dev);
+   case AMD_PSP_MICROCODE_TOC:
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", 
chip_name);
+   return request_firmware(>psp.toc_fw, fw_name, adev->dev);
+   }
+   return -EINVAL;
+}
+
 static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
 {
+   char ucode_prefix[30];
+   int r;
+
+   amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, 
sizeof(ucode_prefix));
+   adev->psp.adev = adev;
+
switch (adev->ip_versions[MP0_HWIP][0]) {
case IP_VERSION(9, 0, 0):
+   

[PATCH v3 09/11] drm/amd: Request GFX10 microcode during IP discovery

2022-12-29 Thread Mario Limonciello
If GFX10 microcode is required but not available during early init, the
firmware framebuffer will have already been released and the screen will
freeze.

Move the request for GFX10 microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Reviewed-by: Alex Deucher 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 137 +
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c| 180 +-
 2 files changed, 144 insertions(+), 173 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 0ff1b3872441..439b10fdff1b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -220,6 +220,102 @@ MODULE_FIRMWARE("amdgpu/green_sardine_mec.bin");
 MODULE_FIRMWARE("amdgpu/green_sardine_mec2.bin");
 MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
 
+/* gfx10 */
+MODULE_FIRMWARE("amdgpu/aldebaran_mec.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_mec2.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec2.bin");
+
+MODULE_FIRMWARE("amdgpu/navi10_ce.bin");
+MODULE_FIRMWARE("amdgpu/navi10_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navi10_me.bin");
+MODULE_FIRMWARE("amdgpu/navi10_mec.bin");
+MODULE_FIRMWARE("amdgpu/navi10_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navi10_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/navi14_ce_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_pfp_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_me_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec2_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_ce.bin");
+MODULE_FIRMWARE("amdgpu/navi14_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navi14_me.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navi14_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/navi12_ce.bin");
+MODULE_FIRMWARE("amdgpu/navi12_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navi12_me.bin");
+MODULE_FIRMWARE("amdgpu/navi12_mec.bin");
+MODULE_FIRMWARE("amdgpu/navi12_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navi12_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_ce.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_pfp.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_me.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mec.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mec2.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/navy_flounder_ce.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_me.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_mec.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/vangogh_ce.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_me.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_mec.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_ce.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_pfp.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_me.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec2.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/beige_goby_ce.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_pfp.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_me.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_mec.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_mec2.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/yellow_carp_ce.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_pfp.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_me.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_mec.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_mec2.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_ce.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_pfp.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_me.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec2.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_ce.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec2.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_ce.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec2.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_rlc.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
[MP1_HWID]  = "MP1",
[MP2_HWID]  = "MP2",
@@ -1984,6 

[PATCH v3 06/11] drm/amd: Request VCN microcode during IP discovery

2022-12-29 Thread Mario Limonciello
If VCN microcode is not available during early init, the firmware
framebuffer will have already been released and the screen will
freeze.

Move the request for VCN microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Reviewed-by: Alex Deucher 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 41 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c   | 85 +--
 2 files changed, 41 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 24d54ab0963a..07c05782a0e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -124,6 +124,27 @@ MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
 MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
 MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
 
+MODULE_FIRMWARE("amdgpu/raven_vcn.bin");
+MODULE_FIRMWARE("amdgpu/picasso_vcn.bin");
+MODULE_FIRMWARE("amdgpu/raven2_vcn.bin");
+MODULE_FIRMWARE("amdgpu/arcturus_vcn.bin");
+MODULE_FIRMWARE("amdgpu/renoir_vcn.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_vcn.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navi10_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navi14_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navi12_vcn.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_vcn.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_vcn.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_vcn.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_vcn.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_vcn.bin");
+MODULE_FIRMWARE("amdgpu/vcn_3_1_2.bin");
+MODULE_FIRMWARE("amdgpu/vcn_4_0_0.bin");
+MODULE_FIRMWARE("amdgpu/vcn_4_0_2.bin");
+MODULE_FIRMWARE("amdgpu/vcn_4_0_4.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
[MP1_HWID]  = "MP1",
[MP2_HWID]  = "MP2",
@@ -1922,8 +1943,23 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct 
amdgpu_device *adev)
return 0;
 }
 
+static int amdgpu_discovery_load_vcn_fw(struct amdgpu_device *adev,
+   char *fname)
+{
+   char fw_name[40];
+
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", fname);
+
+   return request_firmware(>vcn.fw, fw_name, adev->dev);
+}
+
 static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
 {
+   char ucode_prefix[30];
+   int r = 0;
+
+   amdgpu_ucode_ip_version_decode(adev, UVD_HWIP, ucode_prefix, 
sizeof(ucode_prefix));
+
if (adev->ip_versions[VCE_HWIP][0]) {
switch (adev->ip_versions[UVD_HWIP][0]) {
case IP_VERSION(7, 0, 0):
@@ -2001,7 +2037,10 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct 
amdgpu_device *adev)
return -EINVAL;
}
}
-   return 0;
+   if (*ucode_prefix)
+   r = amdgpu_discovery_load_vcn_fw(adev, ucode_prefix);
+   return r;
+}
 }
 
 static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index a23e26b272b4..370c9644a3b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -35,55 +35,11 @@
 #include "amdgpu_vcn.h"
 #include "soc15d.h"
 
-/* Firmware Names */
-#define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin"
-#define FIRMWARE_PICASSO   "amdgpu/picasso_vcn.bin"
-#define FIRMWARE_RAVEN2"amdgpu/raven2_vcn.bin"
-#define FIRMWARE_ARCTURUS  "amdgpu/arcturus_vcn.bin"
-#define FIRMWARE_RENOIR"amdgpu/renoir_vcn.bin"
-#define FIRMWARE_GREEN_SARDINE "amdgpu/green_sardine_vcn.bin"
-#define FIRMWARE_NAVI10"amdgpu/navi10_vcn.bin"
-#define FIRMWARE_NAVI14"amdgpu/navi14_vcn.bin"
-#define FIRMWARE_NAVI12"amdgpu/navi12_vcn.bin"
-#define FIRMWARE_SIENNA_CICHLID"amdgpu/sienna_cichlid_vcn.bin"
-#define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_vcn.bin"
-#define FIRMWARE_VANGOGH   "amdgpu/vangogh_vcn.bin"
-#define FIRMWARE_DIMGREY_CAVEFISH  "amdgpu/dimgrey_cavefish_vcn.bin"
-#define FIRMWARE_ALDEBARAN "amdgpu/aldebaran_vcn.bin"
-#define FIRMWARE_BEIGE_GOBY"amdgpu/beige_goby_vcn.bin"
-#define FIRMWARE_YELLOW_CARP   "amdgpu/yellow_carp_vcn.bin"
-#define FIRMWARE_VCN_3_1_2 "amdgpu/vcn_3_1_2.bin"
-#define FIRMWARE_VCN4_0_0  "amdgpu/vcn_4_0_0.bin"
-#define FIRMWARE_VCN4_0_2  "amdgpu/vcn_4_0_2.bin"
-#define FIRMWARE_VCN4_0_4  "amdgpu/vcn_4_0_4.bin"
-
-MODULE_FIRMWARE(FIRMWARE_RAVEN);
-MODULE_FIRMWARE(FIRMWARE_PICASSO);
-MODULE_FIRMWARE(FIRMWARE_RAVEN2);
-MODULE_FIRMWARE(FIRMWARE_ARCTURUS);
-MODULE_FIRMWARE(FIRMWARE_RENOIR);
-MODULE_FIRMWARE(FIRMWARE_GREEN_SARDINE);
-MODULE_FIRMWARE(FIRMWARE_ALDEBARAN);
-MODULE_FIRMWARE(FIRMWARE_NAVI10);
-MODULE_FIRMWARE(FIRMWARE_NAVI14);

[PATCH v3 10/11] drm/amd: Request GFX11 microcode during IP discovery

2022-12-29 Thread Mario Limonciello
If GFX11 microcode is required but not available during early init, the
firmware framebuffer will have already been released and the screen will
freeze.

Move the request for GFX11 microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Reviewed-by: Alex Deucher 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 52 +++
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c| 64 +--
 2 files changed, 53 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 439b10fdff1b..ce1aa7683738 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -316,6 +316,29 @@ MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec.bin");
 MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec2.bin");
 MODULE_FIRMWARE("amdgpu/gc_10_3_7_rlc.bin");
 
+/* gfx11 */
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_toc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_rlc.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
[MP1_HWID]  = "MP1",
[MP2_HWID]  = "MP2",
@@ -2114,6 +2137,32 @@ static int amdgpu_discovery_load_gfx10(struct 
amdgpu_device *adev, char *ucode_p
r = request_firmware(>gfx.mec2_fw, fw_name, adev->dev);
if (r)
return r;
+   return 0;
+}
+
+static int amdgpu_discovery_load_gfx11(struct amdgpu_device *adev, char 
*ucode_prefix)
+{
+   char fw_name[40];
+   int r;
+
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", ucode_prefix);
+   r = request_firmware(>gfx.pfp_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", ucode_prefix);
+   r = request_firmware(>gfx.me_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", ucode_prefix);
+   r = request_firmware(>gfx.mec_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+   if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) {
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", 
ucode_prefix);
+   r = request_firmware(>psp.toc_fw, fw_name, adev->dev);
+   if (r)
+   return r;
+   }
 
return 0;
 }
@@ -2162,6 +2211,9 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct 
amdgpu_device *adev)
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
case IP_VERSION(11, 0, 4):
+   r = amdgpu_discovery_load_gfx11(adev, ucode_prefix);
+   if (r)
+   return r;
amdgpu_device_ip_block_add(adev, _v11_0_ip_block);
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index a56c6e106d00..576fa591c6da 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -60,27 +60,6 @@
 #define regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1  0x4e7e
 #define regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1_BASE_IDX 1
 
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_toc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_4_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_4_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_4_mec.bin");

[PATCH v3 03/11] drm/amd: Convert SMUv11 microcode init to use `amdgpu_ucode_ip_version_decode`

2022-12-29 Thread Mario Limonciello
Remove the special casing from SMU v11 code. No intended functional
changes.

Signed-off-by: Mario Limonciello 
---
 .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c| 35 ++-
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
index ad66d57aa102..d4756bd30830 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
@@ -93,7 +93,7 @@ static void smu_v11_0_poll_baco_exit(struct smu_context *smu)
 int smu_v11_0_init_microcode(struct smu_context *smu)
 {
struct amdgpu_device *adev = smu->adev;
-   const char *chip_name;
+   char ucode_prefix[30];
char fw_name[SMU_FW_NAME_LEN];
int err = 0;
const struct smc_firmware_header_v1_0 *hdr;
@@ -105,38 +105,9 @@ int smu_v11_0_init_microcode(struct smu_context *smu)
 (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7
return 0;
 
-   switch (adev->ip_versions[MP1_HWIP][0]) {
-   case IP_VERSION(11, 0, 0):
-   chip_name = "navi10";
-   break;
-   case IP_VERSION(11, 0, 5):
-   chip_name = "navi14";
-   break;
-   case IP_VERSION(11, 0, 9):
-   chip_name = "navi12";
-   break;
-   case IP_VERSION(11, 0, 7):
-   chip_name = "sienna_cichlid";
-   break;
-   case IP_VERSION(11, 0, 11):
-   chip_name = "navy_flounder";
-   break;
-   case IP_VERSION(11, 0, 12):
-   chip_name = "dimgrey_cavefish";
-   break;
-   case IP_VERSION(11, 0, 13):
-   chip_name = "beige_goby";
-   break;
-   case IP_VERSION(11, 0, 2):
-   chip_name = "arcturus";
-   break;
-   default:
-   dev_err(adev->dev, "Unsupported IP version 0x%x\n",
-   adev->ip_versions[MP1_HWIP][0]);
-   return -EINVAL;
-   }
+   amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, 
sizeof(ucode_prefix));
 
-   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_smc.bin", chip_name);
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix);
 
err = request_firmware(>pm.fw, fw_name, adev->dev);
if (err)
-- 
2.34.1



[PATCH v3 07/11] drm/amd: Request MES microcode during IP discovery

2022-12-29 Thread Mario Limonciello
If MES microcode is required but not available during early init, the
firmware framebuffer will have already been released and the screen will
freeze.

Move the request for MES microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Reviewed-by: Alex Deucher 
Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Add a missing newline
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 40 +++
 drivers/gpu/drm/amd/amdgpu/mes_v10_1.c| 28 -
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c| 25 +---
 3 files changed, 41 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 07c05782a0e3..edaeec35c39f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -145,6 +145,19 @@ MODULE_FIRMWARE("amdgpu/vcn_4_0_0.bin");
 MODULE_FIRMWARE("amdgpu/vcn_4_0_2.bin");
 MODULE_FIRMWARE("amdgpu/vcn_4_0_4.bin");
 
+MODULE_FIRMWARE("amdgpu/navi10_mes.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes1.bin");
+
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes1.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
[MP1_HWID]  = "MP1",
[MP2_HWID]  = "MP2",
@@ -2041,10 +2054,30 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct 
amdgpu_device *adev)
r = amdgpu_discovery_load_vcn_fw(adev, ucode_prefix);
return r;
 }
+
+static int amdgpu_discovery_load_mes_fw(struct amdgpu_device *adev,
+   enum admgpu_mes_pipe pipe,
+   const char *ucode_prefix)
+{
+   char fw_name[40];
+
+   if (pipe == AMDGPU_MES_SCHED_PIPE)
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
+ucode_prefix);
+   else
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin",
+ucode_prefix);
+
+   return request_firmware(>mes.fw[pipe], fw_name, adev->dev);
 }
 
 static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
 {
+   char ucode_prefix[30];
+   int pipe, r;
+
+   amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, 
sizeof(ucode_prefix));
+
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(10, 1, 10):
case IP_VERSION(10, 1, 1):
@@ -2077,6 +2110,13 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct 
amdgpu_device *adev)
default:
break;
}
+   if (adev->enable_mes) {
+   for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
+   r = amdgpu_discovery_load_mes_fw(adev, pipe, 
ucode_prefix);
+   if (r)
+   return r;
+   }
+   }
return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c 
b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c
index 614394118a53..9faa9867b3c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c
@@ -37,10 +37,6 @@
 #define mmRLC_CP_SCHEDULERS_Sienna_Cichlid 0x4ca1
 #define mmRLC_CP_SCHEDULERS_Sienna_Cichlid_BASE_IDX1
 
-MODULE_FIRMWARE("amdgpu/navi10_mes.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes1.bin");
-
 static int mes_v10_1_hw_fini(void *handle);
 static int mes_v10_1_kiq_hw_init(struct amdgpu_device *adev);
 
@@ -382,34 +378,10 @@ static const struct amdgpu_mes_funcs mes_v10_1_funcs = {
 static int mes_v10_1_init_microcode(struct amdgpu_device *adev,
enum admgpu_mes_pipe pipe)
 {
-   const char *chip_name;
-   char fw_name[30];
int err;
const struct mes_firmware_header_v1_0 *mes_hdr;
struct amdgpu_firmware_info *info;
 
-   switch (adev->ip_versions[GC_HWIP][0]) {
-   case IP_VERSION(10, 1, 10):
-   chip_name = "navi10";
-   break;
-   case IP_VERSION(10, 3, 0):
-   chip_name = "sienna_cichlid";
-   break;
-   default:
-   BUG();
-   }
-
-   if (pipe == AMDGPU_MES_SCHED_PIPE)
-   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
-chip_name);
-   else
-   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin",
-chip_name);
-
-   err = request_firmware(>mes.fw[pipe], fw_name, adev->dev);
-   if (err)
-   return err;
-
err = 

[PATCH v3 05/11] drm/amd: Request SDMA microcode during IP discovery

2022-12-29 Thread Mario Limonciello
If SDMA microcode is not available during early init, the firmware
framebuffer will have already been released and the screen will
freeze.

Move the request from SDMA microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Fix dGPU naming scheme
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 57 
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c  |  9 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h  |  2 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c| 61 +
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c| 42 +---
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c| 65 +--
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c| 30 +
 7 files changed, 66 insertions(+), 200 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index b719852daa07..24d54ab0963a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -90,6 +90,40 @@ MODULE_FIRMWARE(FIRMWARE_IP_DISCOVERY);
 #define mmMM_INDEX_HI  0x6
 #define mmMM_DATA  0x1
 
+MODULE_FIRMWARE("amdgpu/navi10_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navi10_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/navi14_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navi14_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/navi12_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navi12_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/vega10_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/vega12_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/vega20_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vega20_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/raven_sdma.bin");
+MODULE_FIRMWARE("amdgpu/picasso_sdma.bin");
+MODULE_FIRMWARE("amdgpu/raven2_sdma.bin");
+MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin");
+MODULE_FIRMWARE("amdgpu/renoir_sdma.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_sdma.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_sdma.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_sdma.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_sdma.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_sdma.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_sdma.bin");
+MODULE_FIRMWARE("amdgpu/sdma_5_2_6.bin");
+MODULE_FIRMWARE("amdgpu/sdma_5_2_7.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_0.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
[MP1_HWID]  = "MP1",
[MP2_HWID]  = "MP2",
@@ -1821,8 +1855,26 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct 
amdgpu_device *adev)
return 0;
 }
 
+static int amdgpu_discovery_load_sdma_fw(struct amdgpu_device *adev, u32 
instance,
+const char *chip_name)
+{
+   char fw_name[40];
+
+   if (instance == 0)
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name);
+   else
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s1.bin", chip_name);
+
+   return request_firmware(>sdma.instance[instance].fw, fw_name, 
adev->dev);
+}
+
 static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
 {
+   char ucode_prefix[30];
+   int i, r;
+
+   amdgpu_ucode_ip_version_decode(adev, SDMA0_HWIP, ucode_prefix, 
sizeof(ucode_prefix));
+
switch (adev->ip_versions[SDMA0_HWIP][0]) {
case IP_VERSION(4, 0, 0):
case IP_VERSION(4, 0, 1):
@@ -1862,6 +1914,11 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct 
amdgpu_device *adev)
adev->ip_versions[SDMA0_HWIP][0]);
return -EINVAL;
}
+   for (i = 0; i < adev->sdma.num_instances; i++) {
+   r = amdgpu_discovery_load_sdma_fw(adev, i, ucode_prefix);
+   if (r)
+   return r;
+   }
return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index ea5278f094c0..9e46d8034c03 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -205,8 +205,7 @@ void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device 
*adev,
 }
 
 int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
-  char *fw_name, u32 instance,
-  bool duplicate)
+  u32 instance, bool duplicate)
 {
struct amdgpu_firmware_info *info = NULL;
const struct common_firmware_header *header = NULL;
@@ -214,10 +213,6 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
const struct 

[PATCH v3 02/11] drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"

2022-12-29 Thread Mario Limonciello
This will allow other parts of the driver that currently special
case firmware file names to before IP version style naming to just
have a single call to `amdgpu_ucode_ip_version_decode`.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Fixes for GFX9 SDMA
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 221 ++
 1 file changed, 221 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
index 5cb62e6249c2..eafcddce58d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
@@ -1059,12 +1059,233 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
return 0;
 }
 
+static const char *amdgpu_ucode_legacy_naming(struct amdgpu_device *adev, int 
block_type)
+{
+   if (block_type == MP0_HWIP) {
+   switch (adev->ip_versions[MP0_HWIP][0]) {
+   case IP_VERSION(9, 0, 0):
+   switch (adev->asic_type) {
+   case CHIP_VEGA10:
+   return "vega10";
+   case CHIP_VEGA12:
+   return "vega12";
+   default:
+   return NULL;
+   }
+   break;
+   case IP_VERSION(10, 0, 0):
+   case IP_VERSION(10, 0, 1):
+   if (adev->asic_type == CHIP_RAVEN) {
+   if (adev->apu_flags & AMD_APU_IS_RAVEN2)
+   return "raven2";
+   else if (adev->apu_flags & AMD_APU_IS_PICASSO)
+   return "picasso";
+   return "raven";
+   }
+   break;
+   case IP_VERSION(11, 0, 0):
+   return "navi10";
+   case IP_VERSION(11, 0, 2):
+   return "vega20";
+   case IP_VERSION(11, 0, 4):
+   return "arcturus";
+   case IP_VERSION(11, 0, 5):
+   return "navi14";
+   case IP_VERSION(11, 0, 7):
+   return "sienna_cichlid";
+   case IP_VERSION(11, 0, 9):
+   return "navi12";
+   case IP_VERSION(11, 0, 11):
+   return "navy_flounder";
+   case IP_VERSION(11, 0, 12):
+   return "dimgrey_cavefish";
+   case IP_VERSION(11, 0, 13):
+   return "beige_goby";
+   case IP_VERSION(11, 5, 0):
+   return "vangogh";
+   case IP_VERSION(12, 0, 1):
+   if (adev->asic_type == CHIP_RENOIR) {
+   if (adev->apu_flags & AMD_APU_IS_RENOIR)
+   return "renoir";
+   return "green_sardine";
+   }
+   break;
+   case IP_VERSION(13, 0, 2):
+   return "aldebaran";
+   case IP_VERSION(13, 0, 1):
+   case IP_VERSION(13, 0, 3):
+   return "yellow_carp";
+   }
+   } else if (block_type == MP1_HWIP) {
+   switch (adev->ip_versions[MP1_HWIP][0]) {
+   case IP_VERSION(9, 0, 0):
+   case IP_VERSION(10, 0, 0):
+   case IP_VERSION(10, 0, 1):
+   case IP_VERSION(11, 0, 2):
+   if (adev->asic_type == CHIP_ARCTURUS)
+   return "arcturus_smc";
+   return NULL;
+   case IP_VERSION(11, 0, 0):
+   return "navi10_smc";
+   case IP_VERSION(11, 0, 5):
+   return "navi14_smc";
+   case IP_VERSION(11, 0, 9):
+   return "navi12_smc";
+   case IP_VERSION(11, 0, 7):
+   return "sienna_cichlid_smc";
+   case IP_VERSION(11, 0, 11):
+   return "navy_flounder_smc";
+   case IP_VERSION(11, 0, 12):
+   return "dimgrey_cavefish_smc";
+   case IP_VERSION(11, 0, 13):
+   return "beige_goby_smc";
+   case IP_VERSION(13, 0, 2):
+   return "aldebaran_smc";
+   }
+   } else if (block_type == SDMA0_HWIP) {
+   switch (adev->ip_versions[SDMA0_HWIP][0]) {
+   case IP_VERSION(4, 0, 0):
+   return "vega10_sdma";
+   case IP_VERSION(4, 0, 1):
+   return "vega12_sdma";
+   case IP_VERSION(4, 1, 0):
+   case IP_VERSION(4, 1, 1):
+   if (adev->apu_flags & AMD_APU_IS_RAVEN2)
+   return "raven2_sdma";
+   else if 

[PATCH v3 01/11] drm/amd: Delay removal of the firmware framebuffer

2022-12-29 Thread Mario Limonciello
Removing the firmware framebuffer from the driver means that even
if the driver doesn't support the IP blocks in a GPU it will no
longer be functional after the driver fails to initialize.

This change will ensure that unsupported IP blocks at least cause
the driver to work with the EFI framebuffer.

Cc: sta...@vger.kernel.org
Suggested-by: Alex Deucher 
Reviewed-by: Javier Martinez Canillas 
Reviewed-by: Alex Deucher 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 6 --
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 9a1a5c2864a0..84d83be2087c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -37,6 +37,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -89,6 +90,8 @@ MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
 #define AMDGPU_MAX_RETRY_LIMIT 2
 #define AMDGPU_RETRY_SRIOV_RESET(r) ((r) == -EBUSY || (r) == -ETIMEDOUT || (r) 
== -EINVAL)
 
+static const struct drm_driver amdgpu_kms_driver;
+
 const char *amdgpu_asic_name[] = {
"TAHITI",
"PITCAIRN",
@@ -2140,6 +2143,11 @@ static int amdgpu_device_ip_early_init(struct 
amdgpu_device *adev)
break;
}
 
+   /* Get rid of things like offb */
+   r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, 
_kms_driver);
+   if (r)
+   return r;
+
if (amdgpu_has_atpx() &&
(amdgpu_is_atpx_hybrid() ||
 amdgpu_has_atpx_dgpu_power_cntl()) &&
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index db7e34eacc35..b9f14ec9edb2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -23,7 +23,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -2096,11 +2095,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
}
 #endif
 
-   /* Get rid of things like offb */
-   ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, 
_kms_driver);
-   if (ret)
-   return ret;
-
adev = devm_drm_dev_alloc(>dev, _kms_driver, 
typeof(*adev), ddev);
if (IS_ERR(adev))
return PTR_ERR(adev);
-- 
2.34.1



[PATCH v3 04/11] drm/amd: Convert SMUv13 to use `amdgpu_ucode_ip_version_decode`

2022-12-29 Thread Mario Limonciello
The special case for the one dGPU has been moved into
`amdgpu_ucode_ip_version_decode`, so simplify this code.

Reviewed-by: Alex Deucher 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
index 0ac9cac805f9..506a49a4b425 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -88,7 +88,6 @@ static const int link_speed[] = {25, 50, 80, 160};
 int smu_v13_0_init_microcode(struct smu_context *smu)
 {
struct amdgpu_device *adev = smu->adev;
-   const char *chip_name;
char fw_name[30];
char ucode_prefix[30];
int err = 0;
@@ -100,16 +99,9 @@ int smu_v13_0_init_microcode(struct smu_context *smu)
if (amdgpu_sriov_vf(adev))
return 0;
 
-   switch (adev->ip_versions[MP1_HWIP][0]) {
-   case IP_VERSION(13, 0, 2):
-   chip_name = "aldebaran_smc";
-   break;
-   default:
-   amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, 
sizeof(ucode_prefix));
-   chip_name = ucode_prefix;
-   }
+   amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, 
sizeof(ucode_prefix));
 
-   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name);
+   snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix);
 
err = request_firmware(>pm.fw, fw_name, adev->dev);
if (err)
-- 
2.34.1



[PATCH v3 00/11] Recover from failure to probe GPU

2022-12-29 Thread Mario Limonciello
One of the first thing that KMS drivers do during initialization is
destroy the system firmware framebuffer by means of
`drm_aperture_remove_conflicting_pci_framebuffers`

This means that if for any reason the GPU failed to probe the user
will be stuck with at best a screen frozen at the last thing that
was shown before the KMS driver continued it's probe.

The problem is most pronounced when new GPU support is introduced
because users will need to have a recent linux-firmware snapshot
on their system when they boot a kernel with matching support.

However the problem is further exaggerated in the case of amdgpu because
it has migrated to "IP discovery" where amdgpu will attempt to load
on "ALL" AMD GPUs even if the driver is missing support for IP blocks
contained in that GPU.

IP discovery requires some probing and isn't run until after the
framebuffer has been destroyed.

This means a situation can occur where a user purchases a new GPU not
yet supported by a distribution and when booting the installer it will
"freeze" even if the distribution doesn't have the matching kernel support
for those IP blocks.

The perfect example of this is Ubuntu 22.10 and the new dGPUs just
launched by AMD.  The installation media ships with kernel 5.19 (which
has IP discovery) but the amdgpu support for those IP blocks landed in
kernel 6.0. The matching linux-firmware was released after 22.10's launch.
The screen will freeze without nomodeset. Even if a user manages to install
and then upgrades to kernel 6.0 after install they'll still have the
problem of missing firmware, and the same experience.

This is quite jarring for users, particularly if they don't know
that they have to use "nomodeset" to install.

To help the situation make changes to GPU discovery:
1) Delay releasing the firmware framebuffer until after IP discovery has
completed.  This will help the situation of an older kernel that doesn't
yet support the IP blocks probing a new GPU.
2) Request loading all PSP, VCN, SDMA, MES and GC microcode into memory
during IP discovery. This will help the situation of new enough kernel for
the IP discovery phase to otherwise pass but missing microcode from
linux-firmware.git.

Not all requested firmware will be loaded during IP discovery as some of it
will require larger driver architecture changes. For example SMU firmware
isn't loaded on certain products, but that's not known until later on when
the early_init phase of the SMU load occurs.

v2->v3:
 * Rework patch 11 to not validate PSP microcode during discovery
 * Fix bugs with GFX9 due to gfx.num_gfx_rings not being set during discovery
 * Fix naming scheme for SDMA on dGPUs
 * Pick up tags for patches 1-10 for patches that didn't change from other
   comments.
v1->v2:
 * Take the suggestion from v1 thread to delay the framebuffer release until
   ip discovery is done. This patch is CC to stable to that older stable
   kernels with IP discovery won't try to probe unknown IP.
 * Drop changes to drm aperature.
 * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery.

Mario Limonciello (11):
  drm/amd: Delay removal of the firmware framebuffer
  drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
  drm/amd: Convert SMUv11 microcode init to use
`amdgpu_ucode_ip_version_decode`
  drm/amd: Convert SMUv13 to use `amdgpu_ucode_ip_version_decode`
  drm/amd: Request SDMA microcode during IP discovery
  drm/amd: Request VCN microcode during IP discovery
  drm/amd: Request MES microcode during IP discovery
  drm/amd: Request GFX9 microcode during IP discovery
  drm/amd: Request GFX10 microcode during IP discovery
  drm/amd: Request GFX11 microcode during IP discovery
  drm/amd: Request PSP microcode during IP discovery

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c|   8 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 647 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |   6 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   |  58 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  12 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c  |   9 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h  |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 221 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c   |  85 +--
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c| 180 +
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c|  64 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 194 +-
 drivers/gpu/drm/amd/amdgpu/mes_v10_1.c|  28 -
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c|  25 +-
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  99 +--
 drivers/gpu/drm/amd/amdgpu/psp_v11_0.c| 191 ++
 drivers/gpu/drm/amd/amdgpu/psp_v12_0.c|  98 +--
 drivers/gpu/drm/amd/amdgpu/psp_v13_0.c|  46 +-
 drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c  |  18 +-
 drivers/gpu/drm/amd/amdgpu/psp_v3_1.c |  16 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c|  61 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c   

[drm-misc:drm-misc-next 6/7] drivers/gpu/drm/vc4/vc4_dsi.c:1829:20: error: 'struct drm_bridge' has no member named 'of_node'

2022-12-29 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
head:   12cf36c7125e5313249230e6235b4bfb2c4f765f
commit: 78df640394cd0de88b9f84982f90f2079e60a5b7 [6/7] drm/vc4: dsi: Convert to 
using a bridge instead of encoder
config: xtensa-randconfig-r002-20221230
compiler: xtensa-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
git remote add drm-misc git://anongit.freedesktop.org/drm/drm-misc
git fetch --no-tags drm-misc drm-misc-next
git checkout 78df640394cd0de88b9f84982f90f2079e60a5b7
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=xtensa olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=xtensa SHELL=/bin/bash drivers/gpu/drm/vc4/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/vc4/vc4_dsi.c: In function 'vc4_dsi_dev_probe':
>> drivers/gpu/drm/vc4/vc4_dsi.c:1829:20: error: 'struct drm_bridge' has no 
>> member named 'of_node'
1829 | dsi->bridge.of_node = dev->of_node;
 |^


vim +1829 drivers/gpu/drm/vc4/vc4_dsi.c

  1814  
  1815  static int vc4_dsi_dev_probe(struct platform_device *pdev)
  1816  {
  1817  struct device *dev = >dev;
  1818  struct vc4_dsi *dsi;
  1819  
  1820  dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
  1821  if (!dsi)
  1822  return -ENOMEM;
  1823  dev_set_drvdata(dev, dsi);
  1824  
  1825  kref_init(>kref);
  1826  
  1827  dsi->pdev = pdev;
  1828  dsi->bridge.funcs = _dsi_bridge_funcs;
> 1829  dsi->bridge.of_node = dev->of_node;
  1830  dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
  1831  dsi->dsi_host.ops = _dsi_host_ops;
  1832  dsi->dsi_host.dev = dev;
  1833  mipi_dsi_host_register(>dsi_host);
  1834  
  1835  return 0;
  1836  }
  1837  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp
#
# Automatically generated file; DO NOT EDIT.
# Linux/xtensa 6.1.0-rc6 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="xtensa-linux-gcc (GCC) 12.1.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=120100
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23800
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23800
CONFIG_LLD_VERSION=0
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_PAHOLE_VERSION=123
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y

#
# General setup
#
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_COMPILE_TEST=y
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
CONFIG_BUILD_SALT=""
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_WATCH_QUEUE=y
CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_USELIB is not set
CONFIG_AUDIT=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_SIM=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
# CONFIG_GENERIC_IRQ_DEBUGFS is not set
# end of IRQ subsystem

CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_CONTEXT_TRACKING=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_CONTEXT_TRACKING_USER=y
CONFIG_CONTEXT_TRACKING_USER_FORCE=y
CONFIG_NO_HZ=y
# CONFIG_HIGH_RES_TIMERS is not set
# end of Timers subsystem

CONFIG_BPF=y

#
# BPF subsystem
#
CONFIG_BPF_SYSCALL=y
# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set
# end of BPF subsystem

CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_COUNT=y

#
# CPU/Task time and stats accounting
#
CONFIG_VIRT_CPU_ACCOUNTING=y
# CONFIG_TICK_CPU_ACCOUNTING is not set
CONFIG_VIRT_CPU_ACCOUNTING_GEN=y
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_PSI is not set
# end of CPU/Task time and stats accounting

CONFIG_CPU_ISOLATION=y

#
# RCU Subsystem
#
CONFIG_TINY_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
CONFIG_TINY_SRCU=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_TASKS_RUDE_RCU=y
CONFIG_TASKS_TRACE_RCU=y
CONFIG_RCU_NEED_SEGCBLIST=y
# end of RCU Subsystem

CONFIG_IKCONFIG=m
# CONFIG_IKCONFIG_PROC is not set
# CONFIG_IKHEADERS is not set
CONFIG_GENERIC_SCHED_CLOCK=y

#
# Scheduler features
#
# end of Scheduler features

CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC12_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y
# CONFIG_CGROUPS is not set
# CONFIG_NAMESPACES is not set
CONFIG_CHECKPOINT_RESTORE=y
# CONFIG_SCHED_AUTOGROUP is not set
CONFIG_SYSFS_DEPRECATED=y

[Bug 216840] AMDGPU trace message at boot

2022-12-29 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=216840

--- Comment #4 from Alex Deucher (alexdeuc...@gmail.com) ---
(In reply to Salvador Pérez from comment #3)
> Hi, Alex, 
> 
> I am afraid that not setting amdgpu.vm_update_mode=3 is not an option. If I
> try to play Cities Skylines (linux native version), the game goes 1 fps and
> the system is extremely sluggish. I need to switch to vt1 in order to regain
> control and be able to reboot.

In that case you likely have larger problems.  You should try and figure out
what's going on there.  As Artem suggested, open a bug at
https://gitlab.freedesktop.org/drm/amd/-/issues so we can figure out why GPU
page table updates are not working correctly.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 216840] AMDGPU trace message at boot

2022-12-29 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=216840

--- Comment #3 from Salvador Pérez (carlosalvat...@gmail.com) ---
Hi, Alex, 

I am afraid that not setting amdgpu.vm_update_mode=3 is not an option. If I try
to play Cities Skylines (linux native version), the game goes 1 fps and the
system is extremely sluggish. I need to switch to vt1 in order to regain
control and be able to reboot.

As far as I know, amdgpu.dpm=-1 (auto) is the default. However, I don't
remember why I set to 1 manually, I have to test.

HDMI port seems to be dead (or disabled), I cannot even see the BIOS screen, so
it is not a kernel issue.

Regards.

--
CarloSalvatore

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[RFC] drm/msm/a6xx: Fix devcore register range bugs

2022-12-29 Thread Rob Clark
From: Rob Clark 

RB_MRT_FLAG_BUFFER is 0x8903->0xa91a inclusive.. don't split it (with a
hole) in the ps_cluster_rac and don't accidentially re-dump part of the
range in ps_cluster_rbp.

Signed-off-by: Rob Clark 
---
I'm not 100% sure about this, because the RB_RB_SUB_BLOCK_SEL_CNTL_CD
stuff makes me think the registers dumped are not what the offsets
imply.  But if this is the case, the devcore doesn't capture enough
information to decode these regs properly in the first place!  Either
way there is *something* wrong.

I noticed this because these result in the crashdec tool encountering
only _LO or _HI components of 64b regs that it expects to come in
pairs of 32b dwords.

 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
index 2fb58b7098e4..a03891d844a5 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
@@ -18,12 +18,12 @@ static const u32 a6xx_gras_cluster[] = {
 static const u32 a6xx_ps_cluster_rac[] = {
0x8800, 0x8806, 0x8809, 0x8811, 0x8818, 0x881e, 0x8820, 0x8865,
0x8870, 0x8879, 0x8880, 0x8889, 0x8890, 0x8891, 0x8898, 0x8898,
-   0x88c0, 0x88c1, 0x88d0, 0x88e3, 0x8900, 0x890c, 0x890f, 0x891a,
+   0x88c0, 0x88c1, 0x88d0, 0x88e3, 0x8900, 0x891a,
0x8c00, 0x8c01, 0x8c08, 0x8c10, 0x8c17, 0x8c1f, 0x8c26, 0x8c33,
 };
 
 static const u32 a6xx_ps_cluster_rbp[] = {
-   0x88f0, 0x88f3, 0x890d, 0x890e, 0x8927, 0x8928, 0x8bf0, 0x8bf1,
+   0x88f0, 0x88f3, 0x8927, 0x8928, 0x8bf0, 0x8bf1,
0x8c02, 0x8c07, 0x8c11, 0x8c16, 0x8c20, 0x8c25,
 };
 
-- 
2.38.1



Re: [PATCH V6 1/4] drm: of: Add drm_of_get_dsi_bus helper function

2022-12-29 Thread Linus Walleij
On Thu, Dec 15, 2022 at 7:52 PM Chris Morgan  wrote:

> From: Chris Morgan 
>
> Add helper function to find DSI host for devices where DSI panel is not
> a minor of a DSI bus (such as the Samsung AMS495QA01 panel or the
> official Raspberry Pi touchscreen display).
>
> Signed-off-by: Chris Morgan 
> Signed-off-by: Maya Matuszczyk 
> Reviewed-by: Linus Walleij 

The kernel test robot is complaining because the stub isn't compiling,
because of a copy-paste error (superfluous semicolon).

If you fix this up and resend I think we are ready with the patches!

Yours,
Linus Walleij


Re: [PATCH v3 0/2] Add support for the orisetech ota5601

2022-12-29 Thread Linus Walleij
On Mon, Dec 19, 2022 at 8:52 PM Christophe Branchereau
 wrote:

> Changes since v2:

This v3 patch set applied and pushed to drm-misc-next.

There were some minor checkpatch warnings that I just fixed
up while applying. Check the result in linux-next once it percolates.

Yours,
Linus Walleij


[PATCH] drm/vc4: drop all currently held locks if deadlock happens

2022-12-29 Thread Maíra Canal
If vc4_hdmi_reset_link() returns -EDEADLK, it means that a deadlock
happened in the locking context. This situation should be addressed by
dropping all currently held locks and block until the contended lock
becomes available. Currently, vc4 is not dealing with the deadlock
properly, producing the following output when PROVE_LOCKING is enabled:

[  825.612809] [ cut here ]
[  825.612852] WARNING: CPU: 1 PID: 116 at 
drivers/gpu/drm/drm_modeset_lock.c:276 drm_modeset_drop_locks+0x60/0x68 [drm]
[  825.613458] Modules linked in: 8021q mrp garp stp llc
raspberrypi_cpufreq brcmfmac brcmutil crct10dif_ce hci_uart cfg80211
btqca btbcm bluetooth vc4 raspberrypi_hwmon snd_soc_hdmi_codec cec
clk_raspberrypi ecdh_generic drm_display_helper ecc rfkill
drm_dma_helper drm_kms_helper pwm_bcm2835 bcm2835_thermal bcm2835_rng
rng_core i2c_bcm2835 drm fuse ip_tables x_tables ipv6
[  825.613735] CPU: 1 PID: 116 Comm: kworker/1:2 Tainted: GW 
6.1.0-rc6-01399-g941aae326315 #3
[  825.613759] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT)
[  825.613777] Workqueue: events output_poll_execute [drm_kms_helper]
[  825.614038] pstate: 6005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  825.614063] pc : drm_modeset_drop_locks+0x60/0x68 [drm]
[  825.614603] lr : drm_helper_probe_detect+0x120/0x1b4 [drm_kms_helper]
[  825.614829] sp : 88313bf0
[  825.614844] x29: 88313bf0 x28: cd7778b8b000 x27: 
[  825.614883] x26: 0001 x25: 0001 x24: 677cc35c2758
[  825.614920] x23: cd7707d01430 x22: cd7707c3edc7 x21: 0001
[  825.614958] x20:  x19: 88313c10 x18: b6d3
[  825.614995] x17: cd777835e214 x16: cdcef870 x15: f810
[  825.615033] x14:  x13: 0099 x12: 0002
[  825.615070] x11: 72917988020af800 x10: 72917988020af800 x9 : 72917988020af800
[  825.615108] x8 : 677cc665e0a8 x7 : d00a8c18110c x6 : cd4c0054
[  825.615145] x5 :  x4 : 0001 x3 : 
[  825.615181] x2 : 677cc55e1880 x1 : cdcef8ec x0 : 88313c10
[  825.615219] Call trace:
[  825.615232]  drm_modeset_drop_locks+0x60/0x68 [drm]
[  825.615773]  drm_helper_probe_detect+0x120/0x1b4 [drm_kms_helper]
[  825.616003]  output_poll_execute+0xe4/0x224 [drm_kms_helper]
[  825.616233]  process_one_work+0x2b4/0x618
[  825.616264]  worker_thread+0x24c/0x464
[  825.616288]  kthread+0xec/0x110
[  825.616310]  ret_from_fork+0x10/0x20
[  825.616335] irq event stamp: 7634
[  825.616349] hardirqs last  enabled at (7633): [] 
_raw_spin_unlock_irq+0x3c/0x78
[  825.616384] hardirqs last disabled at (7634): [] 
__schedule+0x134/0x9f0
[  825.616411] softirqs last  enabled at (7630): [] 
local_bh_enable+0x4/0x30 [ipv6]
[  825.617019] softirqs last disabled at (7618): [] 
local_bh_disable+0x4/0x30 [ipv6]
[  825.617586] ---[ end trace  ]---

Therefore, deal with the deadlock as suggested by [1], using the
function drm_modeset_backoff().

[1] https://docs.kernel.org/gpu/drm-kms.html?highlight=kms#kms-locking

Fixes: 6bed2ea3cb38 ("drm/vc4: hdmi: Reset link on hotplug")
Reported-by: Stefan Wahren 
Signed-off-by: Maíra Canal 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 0d3313c71f2f..dfb7f41b28df 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -402,6 +402,7 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi 
*vc4_hdmi,
 {
struct drm_connector *connector = _hdmi->connector;
struct edid *edid;
+   int ret;
 
/*
 * NOTE: This function should really be called with
@@ -430,7 +431,15 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi 
*vc4_hdmi,
cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
kfree(edid);
 
-   vc4_hdmi_reset_link(connector, ctx);
+   for (;;) {
+   ret = vc4_hdmi_reset_link(connector, ctx);
+   if (ret == -EDEADLK) {
+   drm_modeset_backoff(ctx);
+   continue;
+   }
+
+   break;
+   }
 }
 
 static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
-- 
2.38.1



[PATCH v2 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer

2022-12-29 Thread Dmitry Baryshkov
Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
separate functon. This is a preparation for the r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 86 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 ++-
 2 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 78981271b28a..d0d1cb355062 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -400,6 +400,47 @@ static void _dpu_crtc_program_lm_output_roi(struct 
drm_crtc *crtc)
}
 }
 
+static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
+  struct drm_plane *plane,
+  struct dpu_crtc_mixer *mixer,
+  u32 num_mixers,
+  struct dpu_hw_stage_cfg *stage_cfg,
+  enum dpu_stage stage,
+  unsigned int stage_idx,
+  unsigned long *fetch_active,
+  struct dpu_sw_pipe *pipe
+ )
+{
+   uint32_t lm_idx;
+   enum dpu_sspp sspp_idx;
+   struct drm_plane_state *state;
+
+   if (pipe->sspp)
+   return;
+
+   sspp_idx = pipe->sspp->idx;
+
+   state = plane->state;
+
+   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+crtc->base.id,
+stage,
+plane->base.id,
+sspp_idx - SSPP_NONE,
+state->fb ? state->fb->base.id : -1);
+
+   set_bit(sspp_idx, fetch_active);
+
+   stage_cfg->stage[stage][stage_idx] = sspp_idx;
+   stage_cfg->multirect_index[stage][stage_idx] =
+   pipe->multirect_index;
+
+   /* blend config update */
+   for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
+   
mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
+   sspp_idx);
+}
+
 static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
struct dpu_hw_stage_cfg *stage_cfg)
@@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
struct dpu_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
-   uint32_t stage_idx, lm_idx;
-   int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
+   uint32_t lm_idx;
bool bg_alpha_enable = false;
DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
memset(fetch_active, 0, sizeof(fetch_active));
drm_atomic_crtc_for_each_plane(plane, crtc) {
-   enum dpu_sspp sspp_idx;
-
state = plane->state;
if (!state)
continue;
@@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = pstate->pipe.sspp->idx;
-   set_bit(sspp_idx, fetch_active);
-
-   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
-   crtc->base.id,
-   pstate->stage,
-   plane->base.id,
-   sspp_idx - SSPP_VIG0,
-   state->fb ? state->fb->base.id : -1);
-
format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
 
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
bg_alpha_enable = true;
 
-   stage_idx = zpos_cnt[pstate->stage]++;
-   stage_cfg->stage[pstate->stage][stage_idx] =
-   sspp_idx;
-   stage_cfg->multirect_index[pstate->stage][stage_idx] =
-   pstate->pipe.multirect_index;
-
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
-  state, pstate, stage_idx,
+  state, pstate,
   format->base.pixel_format,
   fb ? fb->modifier : 0);
 
+   _dpu_crtc_blend_setup_pipe(crtc, plane,
+  mixer, cstate->num_mixers,
+  stage_cfg, pstate->stage, 0,
+  fetch_active,
+  >pipe);
+
/* blend config update */
for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
-

[PATCH v2 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()

2022-12-29 Thread Dmitry Baryshkov
Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
separate function dpu_plane_sspp_update_pipe(). This is one of
preparational steps to add r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 --
 1 file changed, 63 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3d0c5a36a7dc..b80c5adf91d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -404,12 +404,13 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane 
*plane,
  * _dpu_plane_set_ot_limit - set OT limit for the given plane
  * @plane: Pointer to drm plane
  * @pipe:  Pointer to software pipe
- * @crtc:  Pointer to drm crtc
  * @pipe_cfg:  Pointer to pipe configuration
+ * @frame_rate:CRTC's frame rate
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
struct dpu_sw_pipe *pipe,
-   struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
+   struct dpu_hw_pipe_cfg *pipe_cfg,
+   int frame_rate)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_vbif_set_ot_params ot_params;
@@ -421,7 +422,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
ot_params.width = drm_rect_width(_cfg->src_rect);
ot_params.height = drm_rect_height(_cfg->src_rect);
ot_params.is_wfd = !pdpu->is_rt_pipe;
-   ot_params.frame_rate = drm_mode_vrefresh(>mode);
+   ot_params.frame_rate = frame_rate;
ot_params.vbif_idx = VBIF_RT;
ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
ot_params.rd = true;
@@ -457,26 +458,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane 
*plane,
dpu_vbif_set_qos_remap(dpu_kms, _params);
 }
 
-static void _dpu_plane_set_scanout(struct drm_plane *plane,
-   struct dpu_plane_state *pstate,
-   struct drm_framebuffer *fb)
-{
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
-   struct dpu_kms *kms = _dpu_plane_get_kms(>base);
-   struct msm_gem_address_space *aspace = kms->base.aspace;
-   struct dpu_hw_fmt_layout layout;
-   int ret;
-
-   ret = dpu_format_populate_layout(aspace, fb, );
-   if (ret)
-   DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-   else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
-   trace_dpu_plane_set_scanout(>pipe,
-   );
-   pstate->pipe.sspp->ops.setup_sourceaddress(>pipe, 
);
-   }
-}
-
 static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw,
uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
struct dpu_hw_scaler3_cfg *scale_cfg,
@@ -1102,35 +1083,25 @@ void dpu_plane_set_error(struct drm_plane *plane, bool 
error)
pdpu->is_error = error;
 }
 
-static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
+  struct dpu_sw_pipe *pipe,
+  struct dpu_hw_pipe_cfg *pipe_cfg,
+  const struct dpu_format *fmt,
+  int frame_rate,
+  struct dpu_hw_fmt_layout *layout)
 {
uint32_t src_flags;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct drm_plane_state *state = plane->state;
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
-   struct dpu_sw_pipe *pipe = >pipe;
-   struct drm_crtc *crtc = state->crtc;
-   struct drm_framebuffer *fb = state->fb;
-   bool is_rt_pipe;
-   const struct dpu_format *fmt =
-   to_dpu_format(msm_framebuffer_format(fb));
-   struct dpu_hw_pipe_cfg *pipe_cfg = >pipe_cfg;
 
-   _dpu_plane_set_scanout(plane, pstate, fb);
-
-   pstate->pending = true;
-
-   is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-   pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
-   pdpu->is_rt_pipe = is_rt_pipe;
+   if (layout && pipe->sspp->ops.setup_sourceaddress) {
+   trace_dpu_plane_set_scanout(pipe, layout);
+   pipe->sspp->ops.setup_sourceaddress(pipe, layout);
+   }
 
_dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
-   DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
-   ", %4.4s ubwc %d\n", fb->base.id, 
DRM_RECT_FP_ARG(>src),
-   crtc->base.id, DRM_RECT_ARG(>dst),
-   (char *)>base.pixel_format, 
DPU_FORMAT_IS_UBWC(fmt));
-
/* override for color fill */
if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {

[PATCH v2 16/27] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check()

2022-12-29 Thread Dmitry Baryshkov
The helper drm_atomic_helper_check_plane_state() already checks whether
the scaled and clipped plane falls into the CRTC visible region (and
clears plane_state->visible if it doesn't). Drop the redundant check
from dpu_crtc_atomic_check().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 
 1 file changed, 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 3c33bb4dfaf9..78981271b28a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1129,11 +1129,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
-   struct drm_display_mode *mode;
 
int rc = 0;
 
-   struct drm_rect crtc_rect = { 0 };
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
if (!crtc_state->enable || !crtc_state->active) {
@@ -1144,7 +1142,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return 0;
}
 
-   mode = _state->adjusted_mode;
DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
 
/* force a full mode set if active state changed */
@@ -1154,13 +1151,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
if (cstate->num_mixers)
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
 
-   crtc_rect.x2 = mode->hdisplay;
-   crtc_rect.y2 = mode->vdisplay;
-
/* FIXME: move this to dpu_plane_atomic_check? */
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
-   struct drm_rect dst, clip = crtc_rect;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1173,15 +1166,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
continue;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
-
-   dst = drm_plane_state_dest(pstate);
-   if (!drm_rect_intersect(, )) {
-   DPU_ERROR("invalid vertical/horizontal destination\n");
-   DPU_ERROR("display: " DRM_RECT_FMT " plane: "
- DRM_RECT_FMT "\n", DRM_RECT_ARG(_rect),
- DRM_RECT_ARG());
-   return -E2BIG;
-   }
}
 
atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
-- 
2.39.0



[PATCH v2 17/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state

2022-12-29 Thread Dmitry Baryshkov
Now as all accesses to pipe_cfg and pstate have been cleaned, re-add
struct dpu_hw_pipe_cfg back to dpu_plane_state, so that
dpu_plane_atomic_check() and dpu_plane_atomic_update() do not have a
chance to disagree about src/dst rectangles (currently
dpu_plane_atomic_check() uses unclipped rectangles, while
dpu_plane_atomic_update() uses clipped rectangles calculated by
drm_atomic_helper_check_plane_state()).

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 64 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  1 +
 2 files changed, 29 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 50ce4653bbba..ff32c28ee16a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -963,7 +963,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
const struct drm_crtc_state *crtc_state = NULL;
const struct dpu_format *fmt;
-   struct drm_rect src, dst, fb_rect = { 0 };
+   struct dpu_hw_pipe_cfg *pipe_cfg = >pipe_cfg;
+   struct drm_rect fb_rect = { 0 };
uint32_t min_src_size, max_linewidth;
unsigned int rotation;
uint32_t supported_rotations;
@@ -996,12 +997,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
 
-   src.x1 = new_plane_state->src_x >> 16;
-   src.y1 = new_plane_state->src_y >> 16;
-   src.x2 = src.x1 + (new_plane_state->src_w >> 16);
-   src.y2 = src.y1 + (new_plane_state->src_h >> 16);
+   pipe_cfg->src_rect = new_plane_state->src;
 
-   dst = drm_plane_state_dest(new_plane_state);
+   /* state->src is 16.16, src_rect is not */
+   pipe_cfg->src_rect.x1 >>= 16;
+   pipe_cfg->src_rect.x2 >>= 16;
+   pipe_cfg->src_rect.y1 >>= 16;
+   pipe_cfg->src_rect.y2 >>= 16;
+
+   pipe_cfg->dst_rect = new_plane_state->dst;
 
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
@@ -1020,30 +1024,30 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return -EINVAL;
 
/* check src bounds */
-   } else if (!dpu_plane_validate_src(, _rect, min_src_size)) {
+   } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, 
min_src_size)) {
DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG());
+   DRM_RECT_ARG(_cfg->src_rect));
return -E2BIG;
 
/* valid yuv image */
} else if (DPU_FORMAT_IS_YUV(fmt) &&
-  (src.x1 & 0x1 || src.y1 & 0x1 ||
-   drm_rect_width() & 0x1 ||
-   drm_rect_height() & 0x1)) {
+  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
+   drm_rect_width(_cfg->src_rect) & 0x1 ||
+   drm_rect_height(_cfg->src_rect) & 0x1)) {
DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG());
+   DRM_RECT_ARG(_cfg->src_rect));
return -EINVAL;
 
/* min dst support */
-   } else if (drm_rect_width() < 0x1 || drm_rect_height() < 0x1) {
+   } else if (drm_rect_width(_cfg->dst_rect) < 0x1 || 
drm_rect_height(_cfg->dst_rect) < 0x1) {
DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG());
+   DRM_RECT_ARG(_cfg->dst_rect));
return -EINVAL;
 
/* check decimated source width */
-   } else if (drm_rect_width() > max_linewidth) {
+   } else if (drm_rect_width(_cfg->src_rect) > max_linewidth) {
DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
-   DRM_RECT_ARG(), max_linewidth);
+   DRM_RECT_ARG(_cfg->src_rect), 
max_linewidth);
return -E2BIG;
}
 
@@ -1057,7 +1061,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
(rotation & DRM_MODE_ROTATE_90)) {
-   ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt);
+   ret = dpu_plane_check_inline_rotation(pdpu, sblk, 
pipe_cfg->src_rect, fmt);
if (ret)
return ret;
}
@@ -1132,9 +1136,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
bool is_rt_pipe;
const struct dpu_format *fmt =
to_dpu_format(msm_framebuffer_format(fb));
-   struct dpu_hw_pipe_cfg pipe_cfg;
-
-   memset(_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
+   struct dpu_hw_pipe_cfg 

[PATCH v2 19/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format

2022-12-29 Thread Dmitry Baryshkov
Rewrite dpu_plane's QoS related functions to take struct dpu_sw_pipe and
struct dpu_format as arguments rather than fetching them from the
pstate or drm_framebuffer.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 98 +++
 1 file changed, 47 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index a2c891034512..7fc2c767c6d1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -128,19 +128,18 @@ static struct dpu_kms *_dpu_plane_get_kms(struct 
drm_plane *plane)
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
  * @plane: Pointer to drm plane.
- * @fb:   Pointer to framebuffer associated with the given plane
+ * @fmt: Pointer to source buffer format
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
-   struct drm_framebuffer *fb,
+   const struct dpu_format *fmt,
struct dpu_hw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
-   const struct dpu_format *fmt = NULL;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
int src_width, src_height, dst_height, fps;
u64 plane_prefill_bw;
@@ -152,8 +151,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
pstate = to_dpu_plane_state(plane->state);
mode = >state->crtc->mode;
 
-   fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier);
-
src_width = drm_rect_width(_cfg->src_rect);
src_height = drm_rect_height(_cfg->src_rect);
dst_height = drm_rect_height(_cfg->dst_rect);
@@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, 
struct dpu_hw_pipe_cfg
 /**
  * _dpu_plane_calc_fill_level - calculate fill level of the given source format
  * @plane: Pointer to drm plane
+ * @pipe:  Pointer to software pipe
  * @fmt:   Pointer to source buffer format
  * @src_width: width of source buffer
  * Return: fill level corresponding to the source buffer/format or 0 if error
  */
 static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
+   struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt, u32 src_width)
 {
struct dpu_plane *pdpu;
-   struct dpu_plane_state *pstate;
u32 fixed_buff_size;
u32 total_fl;
 
-   if (!fmt || !plane->state || !src_width || !fmt->bpp) {
+   if (!fmt || !pipe || !src_width || !fmt->bpp) {
DPU_ERROR("invalid arguments\n");
return 0;
}
 
pdpu = to_dpu_plane(plane);
-   pstate = to_dpu_plane_state(plane->state);
fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
 
/* FIXME: in multirect case account for the src_width of all the planes 
*/
@@ -251,7 +248,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
((src_width + 32) * fmt->bpp);
}
} else {
-   if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) 
{
+   if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
total_fl = (fixed_buff_size / 2) * 2 /
((src_width + 32) * fmt->bpp);
} else {
@@ -261,7 +258,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
}
 
DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s w:%u fl:%u\n",
-   pdpu->pipe - SSPP_VIG0,
+   pipe->sspp->idx - SSPP_VIG0,
(char *)>base.pixel_format,
src_width, total_fl);
 
@@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
 /**
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane: Pointer to drm plane
- * @fb:Pointer to framebuffer associated with the 
given plane
+ * @pipe:  Pointer to software pipe
+ * @fmt:   Pointer to source buffer format
  * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-   struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
+   struct dpu_sw_pipe *pipe,
+   const struct dpu_format *fmt, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
-   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   const struct dpu_format *fmt = NULL;
u64 qos_lut;
u32 total_fl = 0, lut_usage;
 
if (!pdpu->is_rt_pipe) {

[PATCH v2 25/27] drm/msm/dpu: rework static color fill code

2022-12-29 Thread Dmitry Baryshkov
Rework static color fill code to separate the pipe / pipe_cfg handling.
This is a preparation for the r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 70 +--
 1 file changed, 41 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index fa59ae007de1..2851f40cb915 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -639,20 +639,54 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe 
*pipe,
fmt);
 }
 
+static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
+   struct dpu_sw_pipe *pipe,
+   struct dpu_hw_pipe_cfg *old_pipe_cfg,
+   u32 fill_color,
+   const struct dpu_format *fmt)
+{
+   struct dpu_hw_pipe_cfg pipe_cfg;
+
+   /* update sspp */
+   if (!pipe->sspp->ops.setup_solidfill)
+   return 0;
+
+   pipe->sspp->ops.setup_solidfill(pipe, fill_color);
+
+   /* override scaler/decimation if solid fill */
+   pipe_cfg.dst_rect = old_pipe_cfg->dst_rect;
+
+   pipe_cfg.src_rect.x1 = 0;
+   pipe_cfg.src_rect.y1 = 0;
+   pipe_cfg.src_rect.x2 =
+   drm_rect_width(_cfg.dst_rect);
+   pipe_cfg.src_rect.y2 =
+   drm_rect_height(_cfg.dst_rect);
+
+   if (pipe->sspp->ops.setup_format)
+   pipe->sspp->ops.setup_format(pipe, fmt, DPU_SSPP_SOLID_FILL);
+
+   if (pipe->sspp->ops.setup_rects)
+   pipe->sspp->ops.setup_rects(pipe, _cfg);
+
+   _dpu_plane_setup_scaler(pipe, fmt, true, _cfg, pstate->rotation);
+
+   return 0;
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
  * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
  * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
- * Returns: 0 on success
  */
-static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
+static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
uint32_t color, uint32_t alpha)
 {
const struct dpu_format *fmt;
const struct drm_plane *plane = >base;
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   struct dpu_hw_pipe_cfg pipe_cfg;
+   u32 fill_color = (color & 0xFF) | ((alpha & 0xFF) << 24);
 
DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -661,34 +695,12 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 * h/w only supports RGB variants
 */
fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR);
+   /* should not happen ever */
+   if (!fmt)
+   return;
 
/* update sspp */
-   if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
-   pstate->pipe.sspp->ops.setup_solidfill(>pipe,
-   (color & 0xFF) | ((alpha & 0xFF) << 24));
-
-   /* override scaler/decimation if solid fill */
-   pipe_cfg.dst_rect = pstate->base.dst;
-
-   pipe_cfg.src_rect.x1 = 0;
-   pipe_cfg.src_rect.y1 = 0;
-   pipe_cfg.src_rect.x2 =
-   drm_rect_width(_cfg.dst_rect);
-   pipe_cfg.src_rect.y2 =
-   drm_rect_height(_cfg.dst_rect);
-
-   if (pstate->pipe.sspp->ops.setup_format)
-   pstate->pipe.sspp->ops.setup_format(>pipe,
-   fmt, DPU_SSPP_SOLID_FILL);
-
-   if (pstate->pipe.sspp->ops.setup_rects)
-   pstate->pipe.sspp->ops.setup_rects(>pipe,
-   _cfg);
-
-   _dpu_plane_setup_scaler(>pipe, fmt, true, _cfg, 
pstate->rotation);
-   }
-
-   return 0;
+   _dpu_plane_color_fill_pipe(pstate, >pipe, >pipe_cfg, 
fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-- 
2.39.0



[PATCH v2 24/27] drm/msm/dpu: rework plane CSC setting

2022-12-29 Thread Dmitry Baryshkov
Rework the code flushing CSC settings for the plane. Separate out the
pipe and pipe_cfg as a preparation for r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +--
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c20e0d9fe0ca..fa59ae007de1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -576,29 +576,18 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
 };
 
-static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, 
const struct dpu_format *fmt)
+static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe, 
const struct dpu_format *fmt)
 {
-   struct dpu_plane_state *pstate = to_dpu_plane_state(pdpu->base.state);
const struct dpu_csc_cfg *csc_ptr;
 
-   if (!pdpu) {
-   DPU_ERROR("invalid plane\n");
-   return NULL;
-   }
-
if (!DPU_FORMAT_IS_YUV(fmt))
return NULL;
 
-   if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
+   if (BIT(DPU_SSPP_CSC_10BIT) & pipe->sspp->cap->features)
csc_ptr = _csc10_YUV2RGB_601L;
else
csc_ptr = _csc_YUV2RGB_601L;
 
-   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-   csc_ptr->csc_mv[0],
-   csc_ptr->csc_mv[1],
-   csc_ptr->csc_mv[2]);
-
return csc_ptr;
 }
 
@@ -1046,6 +1035,27 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return 0;
 }
 
+static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe 
*pipe)
+{
+   const struct dpu_format *format = 
to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
+   const struct dpu_csc_cfg *csc_ptr;
+
+   if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
+   return;
+
+   csc_ptr = _dpu_plane_get_csc(pipe, format);
+   if (!csc_ptr)
+   return;
+
+   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
+   csc_ptr->csc_mv[0],
+   csc_ptr->csc_mv[1],
+   csc_ptr->csc_mv[2]);
+
+   pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+
+}
+
 void dpu_plane_flush(struct drm_plane *plane)
 {
struct dpu_plane *pdpu;
@@ -1069,13 +1079,8 @@ void dpu_plane_flush(struct drm_plane *plane)
else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
/* force 100% alpha */
_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-   else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
-   const struct dpu_format *fmt = 
to_dpu_format(msm_framebuffer_format(plane->state->fb));
-   const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, 
fmt);
-
-   if (csc_ptr)
-   pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
csc_ptr);
-   }
+   else
+   dpu_plane_flush_csc(pdpu, >pipe);
 
/* flag h/w flush complete */
if (plane->state)
-- 
2.39.0



[PATCH v2 21/27] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly

2022-12-29 Thread Dmitry Baryshkov
Rework bandwidth/clock calculation functions to use mode directly rather
than fetching it through the plane data.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 39 ++-
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 7fc2c767c6d1..3d0c5a36a7dc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -127,20 +127,19 @@ static struct dpu_kms *_dpu_plane_get_kms(struct 
drm_plane *plane)
 
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
- * @plane: Pointer to drm plane.
+ * @catalog: Points to dpu catalog structure
  * @fmt: Pointer to source buffer format
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
-static void _dpu_plane_calc_bw(struct drm_plane *plane,
+static u64 _dpu_plane_calc_bw(const struct dpu_mdss_cfg *catalog,
const struct dpu_format *fmt,
+   const struct drm_display_mode *mode,
struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane_state *pstate;
-   struct drm_display_mode *mode;
-   struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
int src_width, src_height, dst_height, fps;
u64 plane_prefill_bw;
u64 plane_bw;
@@ -148,9 +147,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
u64 scale_factor;
int vbp, vpw, vfp;
 
-   pstate = to_dpu_plane_state(plane->state);
-   mode = >state->crtc->mode;
-
src_width = drm_rect_width(_cfg->src_rect);
src_height = drm_rect_height(_cfg->src_rect);
dst_height = drm_rect_height(_cfg->dst_rect);
@@ -158,7 +154,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
vbp = mode->vtotal - mode->vsync_end;
vpw = mode->vsync_end - mode->vsync_start;
vfp = mode->vsync_start - mode->vdisplay;
-   hw_latency_lines =  dpu_kms->catalog->perf->min_prefill_lines;
+   hw_latency_lines =  catalog->perf->min_prefill_lines;
scale_factor = src_height > dst_height ?
mult_frac(src_height, 1, dst_height) : 1;
 
@@ -178,37 +174,36 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
do_div(plane_prefill_bw, hw_latency_lines);
 
 
-   pstate->plane_fetch_bw = max(plane_bw, plane_prefill_bw);
+   return max(plane_bw, plane_prefill_bw);
 }
 
 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
- * @plane: Pointer to drm plane.
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_hw_pipe_cfg *pipe_cfg)
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+   struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane_state *pstate;
-   struct drm_display_mode *mode;
int dst_width, src_height, dst_height, fps;
-
-   pstate = to_dpu_plane_state(plane->state);
-   mode = >state->crtc->mode;
+   u64 plane_clk;
 
src_height = drm_rect_height(_cfg->src_rect);
dst_width = drm_rect_width(_cfg->dst_rect);
dst_height = drm_rect_height(_cfg->dst_rect);
fps = drm_mode_vrefresh(mode);
 
-   pstate->plane_clk =
+   plane_clk =
dst_width * mode->vtotal * fps;
 
if (src_height > dst_height) {
-   pstate->plane_clk *= src_height;
-   do_div(pstate->plane_clk, dst_height);
+   plane_clk *= src_height;
+   do_div(plane_clk, dst_height);
}
+
+   return plane_clk;
 }
 
 /**
@@ -1201,9 +1196,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
_dpu_plane_set_qos_remap(plane, pipe);
}
 
-   _dpu_plane_calc_bw(plane, fmt, >pipe_cfg);
+   pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
>mode, >pipe_cfg);
 
-   _dpu_plane_calc_clk(plane, >pipe_cfg);
+   pstate->plane_clk = _dpu_plane_calc_clk(>mode, >pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.39.0



[PATCH v2 27/27] drm/msm/dpu: add support for wide planes

2022-12-29 Thread Dmitry Baryshkov
Typically SSPP can support rectangle with width up to 2560. However it's
possible to use multirect feature and split source to use the SSPP to
output two consecutive rectangles. This commit brings in this capability
to support wider screen resolutions.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |   8 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 120 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
 3 files changed, 114 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index d0d1cb355062..7f0f467dbabd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -415,7 +415,7 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc 
*crtc,
enum dpu_sspp sspp_idx;
struct drm_plane_state *state;
 
-   if (pipe->sspp)
+   if (!pipe->sspp)
return;
 
sspp_idx = pipe->sspp->idx;
@@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
   fetch_active,
   >pipe);
 
+   _dpu_crtc_blend_setup_pipe(crtc, plane,
+  mixer, cstate->num_mixers,
+  stage_cfg, pstate->stage, 1,
+  fetch_active,
+  >r_pipe);
+
/* blend config update */
for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, 
format);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 2851f40cb915..786b656cc45d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
+   if (!pipe->sspp)
+   return;
+
memset(_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
@@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct 
dpu_plane_state *pstate,
 {
struct dpu_hw_pipe_cfg pipe_cfg;
 
+   if (!pipe->sspp)
+   return 0;
+
/* update sspp */
if (!pipe->sspp->ops.setup_solidfill)
return 0;
@@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
 
/* update sspp */
_dpu_plane_color_fill_pipe(pstate, >pipe, >pipe_cfg, 
fill_color, fmt);
+
+   _dpu_plane_color_fill_pipe(pstate, >r_pipe, 
>r_pipe_cfg, fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
@@ -907,11 +915,13 @@ static int dpu_plane_check_inline_rotation(struct 
dpu_plane *pdpu,
 static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
struct dpu_sw_pipe *pipe,
struct dpu_hw_pipe_cfg *pipe_cfg,
-   uint32_t max_linewidth,
const struct dpu_format *fmt)
 {
uint32_t min_src_size;
 
+   if (!pipe->sspp)
+   return 0;
+
min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
if (DPU_FORMAT_IS_YUV(fmt) &&
@@ -942,12 +952,6 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane 
*pdpu,
DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
DRM_RECT_ARG(_cfg->dst_rect));
return -EINVAL;
-
-   /* check decimated source width */
-   } else if (drm_rect_width(_cfg->src_rect) > max_linewidth) {
-   DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
-   DRM_RECT_ARG(_cfg->src_rect), 
max_linewidth);
-   return -E2BIG;
}
 
return 0;
@@ -961,9 +965,12 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
int ret = 0, min_scale;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+   struct dpu_sw_pipe *pipe = >pipe;
+   struct dpu_sw_pipe *r_pipe = >r_pipe;
const struct drm_crtc_state *crtc_state = NULL;
const struct dpu_format *fmt;
struct dpu_hw_pipe_cfg *pipe_cfg = >pipe_cfg;
+   struct dpu_hw_pipe_cfg *r_pipe_cfg = >r_pipe_cfg;
struct drm_rect fb_rect = { 0 };
uint32_t max_linewidth;
unsigned int rotation;
@@ -987,8 +994,11 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->visible)
return 0;
 
-   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   pipe->multirect_index = 

[PATCH v2 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()

2022-12-29 Thread Dmitry Baryshkov
Split pipe-dependent code from dpu_plane_atomic_check() into the
separate function dpu_plane_atomic_check_pipe(). This is one of
preparational steps to add r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 91 +--
 1 file changed, 53 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index b80c5adf91d2..c20e0d9fe0ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -903,6 +903,55 @@ static int dpu_plane_check_inline_rotation(struct 
dpu_plane *pdpu,
return 0;
 }
 
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+   struct dpu_sw_pipe *pipe,
+   struct dpu_hw_pipe_cfg *pipe_cfg,
+   uint32_t max_linewidth,
+   const struct dpu_format *fmt)
+{
+   uint32_t min_src_size;
+
+   min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
+
+   if (DPU_FORMAT_IS_YUV(fmt) &&
+   (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
+!(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
+   DPU_DEBUG_PLANE(pdpu,
+   "plane doesn't have scaler/csc for yuv\n");
+   return -EINVAL;
+
+   /* check src bounds */
+   } else if (drm_rect_width(_cfg->src_rect) < min_src_size ||
+  drm_rect_height(_cfg->src_rect) < min_src_size) {
+   DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_cfg->src_rect));
+   return -E2BIG;
+
+   /* valid yuv image */
+   } else if (DPU_FORMAT_IS_YUV(fmt) &&
+  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
+   drm_rect_width(_cfg->src_rect) & 0x1 ||
+   drm_rect_height(_cfg->src_rect) & 0x1)) {
+   DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_cfg->src_rect));
+   return -EINVAL;
+
+   /* min dst support */
+   } else if (drm_rect_width(_cfg->dst_rect) < 0x1 || 
drm_rect_height(_cfg->dst_rect) < 0x1) {
+   DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_cfg->dst_rect));
+   return -EINVAL;
+
+   /* check decimated source width */
+   } else if (drm_rect_width(_cfg->src_rect) > max_linewidth) {
+   DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
+   DRM_RECT_ARG(_cfg->src_rect), 
max_linewidth);
+   return -E2BIG;
+   }
+
+   return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
  struct drm_atomic_state *state)
 {
@@ -915,7 +964,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
const struct dpu_format *fmt;
struct dpu_hw_pipe_cfg *pipe_cfg = >pipe_cfg;
struct drm_rect fb_rect = { 0 };
-   uint32_t min_src_size, max_linewidth;
+   uint32_t max_linewidth;
unsigned int rotation;
uint32_t supported_rotations;
const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
@@ -972,43 +1021,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
 
-   min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
-
-   if (DPU_FORMAT_IS_YUV(fmt) &&
-   (!(pipe_hw_caps->features & DPU_SSPP_SCALER) ||
-!(pipe_hw_caps->features & DPU_SSPP_CSC_ANY))) {
-   DPU_DEBUG_PLANE(pdpu,
-   "plane doesn't have scaler/csc for yuv\n");
-   return -EINVAL;
-
-   /* check src bounds */
-   } else if (drm_rect_width(_cfg->src_rect) < min_src_size ||
-  drm_rect_height(_cfg->src_rect) < min_src_size) {
-   DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(_cfg->src_rect));
-   return -E2BIG;
-
-   /* valid yuv image */
-   } else if (DPU_FORMAT_IS_YUV(fmt) &&
-  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
-   drm_rect_width(_cfg->src_rect) & 0x1 ||
-   drm_rect_height(_cfg->src_rect) & 0x1)) {
-   DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(_cfg->src_rect));
-   return -EINVAL;
-
-   /* min dst support */
-   } else if (drm_rect_width(_cfg->dst_rect) < 0x1 || 
drm_rect_height(_cfg->dst_rect) < 0x1) {
-   DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(_cfg->dst_rect));
-   return -EINVAL;
-
-   /* check decimated 

[PATCH v2 20/27] drm/msm/dpu: populate SmartDMA features in hw catalog

2022-12-29 Thread Dmitry Baryshkov
Downstream driver uses dpu->caps->smart_dma_rev to update
sspp->cap->features with the bit corresponding to the supported SmartDMA
version. Upstream driver does not do this, resulting in SSPP subdriver
not enbaling setup_multirect callback. Add corresponding SmartDMA SSPP
feature bits to dpu hw catalog.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

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 2196e205efa5..61e95fb21403 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -21,13 +21,16 @@
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
 
 #define VIG_SDM845_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_SC7180_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_SM8250_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
@@ -42,6 +45,7 @@
 #define DMA_SDM845_MASK \
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
+   BIT(DPU_SSPP_SMART_DMA_V2) |\
BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
 
 #define DMA_CURSOR_SDM845_MASK \
-- 
2.39.0



[PATCH v2 13/27] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check

2022-12-29 Thread Dmitry Baryshkov
Neither source split nor multirect are properly supported at this
moment. Both of these checks depend on normalized_zpos being equal for
several planes (which is never the case for normalized zpos).
Drop these checks to simplify dpu_crtc_atomic_check(). The actual
support for either of these features is not removed from the backend
code (sspp, ctl, etc).

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 166 ++-
 1 file changed, 12 insertions(+), 154 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 04833d91caac..cdaf48a849bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1105,13 +1105,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
drm_crtc_vblank_on(crtc);
 }
 
-struct plane_state {
-   struct dpu_plane_state *dpu_pstate;
-   const struct drm_plane_state *drm_pstate;
-   int stage;
-   u32 pipe_id;
-};
-
 static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
 {
struct drm_crtc *crtc = cstate->crtc;
@@ -1133,29 +1126,22 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
-   struct plane_state *pstates;
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
struct drm_display_mode *mode;
 
-   int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
+   int rc = 0;
 
-   struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
-   int multirect_count = 0;
-   const struct drm_plane_state *pipe_staged[SSPP_MAX];
-   int left_zpos_cnt = 0, right_zpos_cnt = 0;
struct drm_rect crtc_rect = { 0 };
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
-   pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
-
if (!crtc_state->enable || !crtc_state->active) {
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip 
atomic_check\n",
crtc->base.id, crtc_state->enable,
crtc_state->active);
memset(>new_perf, 0, sizeof(cstate->new_perf));
-   goto end;
+   return 0;
}
 
mode = _state->adjusted_mode;
@@ -1165,13 +1151,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
if (crtc_state->active_changed)
crtc_state->mode_changed = true;
 
-   memset(pipe_staged, 0, sizeof(pipe_staged));
-
-   if (cstate->num_mixers) {
-   mixer_width = mode->hdisplay / cstate->num_mixers;
-
+   if (cstate->num_mixers)
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
-   }
 
crtc_rect.x2 = mode->hdisplay;
crtc_rect.y2 = mode->vdisplay;
@@ -1180,38 +1161,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
+   int z_pos;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
DPU_ERROR("%s: failed to get plane%d state, %d\n",
dpu_crtc->name, plane->base.id, rc);
-   goto end;
+   return rc;
}
-   if (cnt >= DPU_STAGE_MAX * 4)
-   continue;
 
if (!pstate->visible)
continue;
 
-   pstates[cnt].dpu_pstate = dpu_pstate;
-   pstates[cnt].drm_pstate = pstate;
-   pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = 
to_dpu_plane_state(pstate)->pipe.sspp->idx;
-
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-   if (pipe_staged[pstates[cnt].pipe_id]) {
-   multirect_plane[multirect_count].r0 =
-   pipe_staged[pstates[cnt].pipe_id];
-   multirect_plane[multirect_count].r1 = pstate;
-   multirect_count++;
-
-   pipe_staged[pstates[cnt].pipe_id] = NULL;
-   } else {
-   pipe_staged[pstates[cnt].pipe_id] = pstate;
-   }
-
-   cnt++;
+   dpu_plane_clear_multirect(pstate);
 
dst = drm_plane_state_dest(pstate);
if (!drm_rect_intersect(, )) {
@@ -1219,63 +1183,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
DPU_ERROR("display: " DRM_RECT_FMT " plane: "
  

[PATCH v2 18/27] drm/msm/dpu: simplify dpu_plane_validate_src()

2022-12-29 Thread Dmitry Baryshkov
Since the driver uses clipped src coordinates, there is no need to check
against the fb coordinates. Remove corresponding checks and inline
dpu_plane_validate_src().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 ---
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ff32c28ee16a..a2c891034512 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -906,25 +906,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
old_pstate->needs_dirtyfb);
 }
 
-static bool dpu_plane_validate_src(struct drm_rect *src,
-  struct drm_rect *fb_rect,
-  uint32_t min_src_size)
-{
-   /* Ensure fb size is supported */
-   if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH ||
-   drm_rect_height(fb_rect) > MAX_IMG_HEIGHT)
-   return false;
-
-   /* Ensure src rect is above the minimum size */
-   if (drm_rect_width(src) < min_src_size ||
-   drm_rect_height(src) < min_src_size)
-   return false;
-
-   /* Ensure src is fully encapsulated in fb */
-   return drm_rect_intersect(fb_rect, src) &&
-   drm_rect_equals(fb_rect, src);
-}
-
 static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
const struct dpu_sspp_sub_blks 
*sblk,
struct drm_rect src, const 
struct dpu_format *fmt)
@@ -1010,6 +991,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
 
+   /* Ensure fb size is supported */
+   if (drm_rect_width(_rect) > MAX_IMG_WIDTH ||
+   drm_rect_height(_rect) > MAX_IMG_HEIGHT) {
+   DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_rect));
+   return -E2BIG;
+   }
+
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
@@ -1024,7 +1013,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
 
/* check src bounds */
-   } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, 
min_src_size)) {
+   } else if (drm_rect_width(_cfg->src_rect) < min_src_size ||
+  drm_rect_height(_cfg->src_rect) < min_src_size) {
DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
DRM_RECT_ARG(_cfg->src_rect));
return -E2BIG;
-- 
2.39.0



[PATCH v2 12/27] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg

2022-12-29 Thread Dmitry Baryshkov
Remove dpu_hw_fmt_layout instance from struct dpu_hw_pipe_cfg, leaving
only src_rect and dst_rect. This way right and left pipes will have
separate dpu_hw_pipe_cfg isntances, while the layout is common to both
of them.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 30 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 10 +++
 3 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 2bd39c13d54d..400d043f37fa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -486,7 +486,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
-   struct dpu_hw_pipe_cfg *cfg)
+   struct dpu_hw_fmt_layout *layout)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
u32 ystride0, ystride1;
@@ -497,41 +497,41 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_sw_pipe *pipe,
return;
 
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
+   for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
DPU_REG_WRITE(>hw, SSPP_SRC0_ADDR + idx + i * 0x4,
-   cfg->layout.plane_addr[i]);
+   layout->plane_addr[i]);
} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
DPU_REG_WRITE(>hw, SSPP_SRC0_ADDR + idx,
-   cfg->layout.plane_addr[0]);
+   layout->plane_addr[0]);
DPU_REG_WRITE(>hw, SSPP_SRC2_ADDR + idx,
-   cfg->layout.plane_addr[2]);
+   layout->plane_addr[2]);
} else {
DPU_REG_WRITE(>hw, SSPP_SRC1_ADDR + idx,
-   cfg->layout.plane_addr[0]);
+   layout->plane_addr[0]);
DPU_REG_WRITE(>hw, SSPP_SRC3_ADDR + idx,
-   cfg->layout.plane_addr[2]);
+   layout->plane_addr[2]);
}
 
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   ystride0 = (cfg->layout.plane_pitch[0]) |
-   (cfg->layout.plane_pitch[1] << 16);
-   ystride1 = (cfg->layout.plane_pitch[2]) |
-   (cfg->layout.plane_pitch[3] << 16);
+   ystride0 = (layout->plane_pitch[0]) |
+   (layout->plane_pitch[1] << 16);
+   ystride1 = (layout->plane_pitch[2]) |
+   (layout->plane_pitch[3] << 16);
} else {
ystride0 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE0 + idx);
ystride1 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE1 + idx);
 
if (pipe->multirect_index == DPU_SSPP_RECT_0) {
ystride0 = (ystride0 & 0x) |
-   (cfg->layout.plane_pitch[0] & 0x);
+   (layout->plane_pitch[0] & 0x);
ystride1 = (ystride1 & 0x)|
-   (cfg->layout.plane_pitch[2] & 0x);
+   (layout->plane_pitch[2] & 0x);
} else {
ystride0 = (ystride0 & 0x) |
-   ((cfg->layout.plane_pitch[0] << 16) &
+   ((layout->plane_pitch[0] << 16) &
 0x);
ystride1 = (ystride1 & 0x) |
-   ((cfg->layout.plane_pitch[2] << 16) &
+   ((layout->plane_pitch[2] << 16) &
 0x);
}
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index c713343378aa..8dad52eb2a90 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -154,13 +154,11 @@ struct dpu_hw_pixel_ext {
 
 /**
  * struct dpu_hw_pipe_cfg : Pipe description
- * @layout:format layout information for programming buffer to hardware
  * @src_rect:  src ROI, caller takes into account the different operations
  * such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
  */
 struct dpu_hw_pipe_cfg {
-   struct dpu_hw_fmt_layout layout;
struct drm_rect src_rect;
struct drm_rect dst_rect;
 };
@@ -243,10 +241,10 @@ struct dpu_hw_sspp_ops {
/**
 * setup_sourceaddress - setup pipe source addresses
 * @pipe: Pointer to software pipe context
-   

[PATCH v2 09/27] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks

2022-12-29 Thread Dmitry Baryshkov
Where feasible, use dpu_sw_pipe rather than a combo of dpu_hw_sspp and
multirect_index/_mode arguments.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 59 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 73 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  9 ++-
 4 files changed, 84 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 93f01f767fd8..f7f81ab08fa2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
-   enum dpu_sspp_multirect_index index,
-   enum dpu_sspp_multirect_mode mode)
+static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
u32 mode_mask;
u32 idx;
 
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ))
return;
 
-   if (index == DPU_SSPP_RECT_SOLO) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
/**
 * if rect index is RECT_SOLO, we cannot expect a
 * virtual plane sharing the same SSPP id. So we go
@@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp 
*ctx,
mode_mask = 0;
} else {
mode_mask = DPU_REG_READ(>hw, SSPP_MULTIRECT_OPMODE + idx);
-   mode_mask |= index;
-   if (mode == DPU_SSPP_MULTIRECT_TIME_MX)
+   mode_mask |= pipe->multirect_index;
+   if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX)
mode_mask |= BIT(2);
else
mode_mask &= ~BIT(2);
@@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp 
*ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
-   const struct dpu_format *fmt, u32 flags,
-   enum dpu_sspp_multirect_index rect_mode)
+static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
+   const struct dpu_format *fmt, u32 flags)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
u32 chroma_samp, unpack, src_format;
u32 opmode = 0;
@@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp 
*ctx,
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ) || !fmt)
return;
 
-   if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+   pipe->multirect_index == DPU_SSPP_RECT_0) {
op_mode_off = SSPP_SRC_OP_MODE;
unpack_pat_off = SSPP_SRC_UNPACK_PATTERN;
format_off = SSPP_SRC_FORMAT;
@@ -443,10 +443,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct 
dpu_hw_sspp *ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_pipe_cfg *cfg,
-   enum dpu_sspp_multirect_index rect_index)
+static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
+   struct dpu_hw_pipe_cfg *cfg)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
@@ -457,7 +457,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
 
c = >hw;
 
-   if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+   pipe->multirect_index == DPU_SSPP_RECT_0) {
src_size_off = SSPP_SRC_SIZE;
src_xy_off = SSPP_SRC_XY;
out_size_off = SSPP_OUT_SIZE;
@@ -478,7 +479,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
dst_size = (drm_rect_height(>dst_rect) << 16) |
drm_rect_width(>dst_rect);
 
-   if (rect_index == DPU_SSPP_RECT_SOLO) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
ystride0 = (cfg->layout.plane_pitch[0]) |
(cfg->layout.plane_pitch[1] << 16);
ystride1 = (cfg->layout.plane_pitch[2]) |
@@ -487,7 +488,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
 
-   if (rect_index == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
 

[PATCH v2 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()

2022-12-29 Thread Dmitry Baryshkov
Move plane state updates from dpu_crtc_atomic_check() to the function
where they belong: to dpu_plane_atomic_check().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 --
 3 files changed, 11 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index cf7be1427298..3c33bb4dfaf9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1126,7 +1126,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
-   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
@@ -1158,11 +1157,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
crtc_rect.x2 = mode->hdisplay;
crtc_rect.y2 = mode->vdisplay;
 
-/* get plane state for all drm planes associated with crtc state */
+   /* FIXME: move this to dpu_plane_atomic_check? */
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
-   int stage;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1176,8 +1174,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-   dpu_plane_clear_multirect(pstate);
-
dst = drm_plane_state_dest(pstate);
if (!drm_rect_intersect(, )) {
DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -1186,18 +1182,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  DRM_RECT_ARG());
return -E2BIG;
}
-
-   /* verify stage setting before using it */
-   stage = DPU_STAGE_0 + pstate->normalized_zpos;
-   if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
-   DPU_ERROR("> %d plane stages assigned\n",
-   
dpu_kms->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
-   return -EINVAL;
-   }
-
-   to_dpu_plane_state(pstate)->stage = stage;
-   DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
-
}
 
atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 0d2a7170e0ab..50ce4653bbba 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -733,14 +733,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
return 0;
 }
 
-void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state)
-{
-   struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
-
-   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-}
-
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 {
struct dpu_plane_state *pstate[R_MAX];
@@ -994,6 +986,16 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->visible)
return 0;
 
+   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+   pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
+   if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
+   DPU_ERROR("> %d plane stages assigned\n",
+   pdpu->catalog->caps->max_mixer_blendstages - 
DPU_STAGE_0);
+   return -EINVAL;
+   }
+
src.x1 = new_plane_state->src_x >> 16;
src.y1 = new_plane_state->src_y >> 16;
src.x2 = src.x1 + (new_plane_state->src_w >> 16);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 55ea221e8488..36a82c06ab7a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -88,12 +88,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
  */
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane);
 
-/**
- * dpu_plane_clear_multirect - clear multirect bits for the given pipe
- * @drm_state: Pointer to DRM plane state
- */
-void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
-
 /**
  * 

[PATCH v2 14/27] drm/msm/dpu: don't use unsupported blend stages

2022-12-29 Thread Dmitry Baryshkov
The dpu_crtc_atomic_check() compares blending stage with DPU_STAGE_MAX
(maximum amount of blending stages supported by the driver), however we
should compare it against .max_mixer_blendstages, the maximum blend
stage supported by the mixer.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index cdaf48a849bc..cf7be1427298 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1126,6 +1126,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
+   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
@@ -1161,7 +1162,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
-   int z_pos;
+   int stage;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1186,17 +1187,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return -E2BIG;
}
 
-   z_pos = pstate->normalized_zpos;
-
-   /* verify z_pos setting before using it */
-   if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
+   /* verify stage setting before using it */
+   stage = DPU_STAGE_0 + pstate->normalized_zpos;
+   if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
DPU_ERROR("> %d plane stages assigned\n",
-   DPU_STAGE_MAX - DPU_STAGE_0);
+   
dpu_kms->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
return -EINVAL;
}
 
-   to_dpu_plane_state(pstate)->stage = z_pos + DPU_STAGE_0;
-   DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
+   to_dpu_plane_state(pstate)->stage = stage;
+   DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
 
}
 
-- 
2.39.0



[PATCH v2 10/27] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()

2022-12-29 Thread Dmitry Baryshkov
There is no need to pass full dpu_hw_pipe_cfg instance to
_dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 7 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index f7f81ab08fa2..176cd6dc9a69 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -415,19 +415,18 @@ static void dpu_hw_sspp_setup_pe_config(struct 
dpu_hw_sspp *ctx,
 }
 
 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_pipe_cfg *sspp,
-   void *scaler_cfg)
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format)
 {
u32 idx;
-   struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
 
-   if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, ) || !sspp
+   if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, )
|| !scaler3_cfg)
return;
 
dpu_hw_setup_scaler3(>hw, scaler3_cfg, idx,
ctx->cap->sblk->scaler_blk.version,
-   sspp->layout.format);
+   format);
 }
 
 static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index f5aae563741a..c713343378aa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -317,13 +317,12 @@ struct dpu_hw_sspp_ops {
 
/**
 * setup_scaler - setup scaler
-* @ctx: Pointer to pipe context
-* @pipe_cfg: Pointer to pipe configuration
 * @scaler_cfg: Pointer to scaler configuration
+* @format: pixel format parameters
 */
void (*setup_scaler)(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_pipe_cfg *pipe_cfg,
-   void *scaler_cfg);
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format);
 
/**
 * get_scaler_ver - get scaler h/w version
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 172a2c012917..cbff4dea8662 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -677,8 +677,8 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe 
*pipe,
if (pipe_hw->ops.setup_scaler &&
pipe->multirect_index != DPU_SSPP_RECT_1)
pipe_hw->ops.setup_scaler(pipe_hw,
-   pipe_cfg,
-   _cfg);
+   _cfg,
+   fmt);
 }
 
 /**
-- 
2.39.0



[PATCH v2 04/27] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c

2022-12-29 Thread Dmitry Baryshkov
As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
SSPP debugfs creation from dpu_plane to dpu_kms. We are going to break
the 1:1 correspondence between planes and SSPPs, so it makes no sense
anymore to create SSPP debugfs entries in dpu_plane.c

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 18 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 
 3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 651621b9794f..8c3e9090be4b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -388,7 +388,6 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
  */
 void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
 
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root);
 int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms 
*kms, struct dentry *entry);
 
 #endif /*_DPU_HW_SSPP_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index b71199511a52..2dfc4748a0e8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t 
mode,
debugfs_create_file(name, mode, parent, regset, _regset32_fops);
 }
 
+static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root)
+{
+   struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
+   int i;
+
+   if (IS_ERR(entry))
+   return;
+
+   for (i = SSPP_NONE; i < SSPP_MAX; i++) {
+   struct dpu_hw_sspp *hw = dpu_rm_get_sspp(_kms->rm, i);
+
+   if (!hw)
+   continue;
+
+   _dpu_hw_sspp_init_debugfs(hw, dpu_kms, entry);
+   }
+}
+
 static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
 {
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index e443799de2c1..cdde7b9ec882 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1399,22 +1399,6 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane 
*plane, bool enable)
_dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
pm_runtime_put_sync(_kms->pdev->dev);
 }
-
-/* SSPP live inside dpu_plane private data only. Enumerate them here. */
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root)
-{
-   struct drm_plane *plane;
-   struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
-
-   if (IS_ERR(entry))
-   return;
-
-   drm_for_each_plane(plane, dpu_kms->dev) {
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
-
-   _dpu_hw_sspp_init_debugfs(pdpu->pipe_hw, dpu_kms, entry);
-   }
-}
 #endif
 
 static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
-- 
2.39.0



[PATCH v2 05/27] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout

2022-12-29 Thread Dmitry Baryshkov
The pipe's layout is not cached, corresponding data structure is zeroed
out each time in the dpu_plane_sspp_atomic_update(), right before the
call to _dpu_plane_set_scanout() -> dpu_format_populate_layout().

Drop plane_addr comparison against previous layout and corresponding
EAGAIN handling.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  4 +---
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index d95540309d4d..ec1001e10f4f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -918,8 +918,7 @@ int dpu_format_populate_layout(
struct drm_framebuffer *fb,
struct dpu_hw_fmt_layout *layout)
 {
-   uint32_t plane_addr[DPU_MAX_PLANES];
-   int i, ret;
+   int ret;
 
if (!fb || !layout) {
DRM_ERROR("invalid arguments\n");
@@ -940,9 +939,6 @@ int dpu_format_populate_layout(
if (ret)
return ret;
 
-   for (i = 0; i < DPU_MAX_PLANES; ++i)
-   plane_addr[i] = layout->plane_addr[i];
-
/* Populate the addresses given the fb */
if (DPU_FORMAT_IS_UBWC(layout->format) ||
DPU_FORMAT_IS_TILE(layout->format))
@@ -950,10 +946,6 @@ int dpu_format_populate_layout(
else
ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
 
-   /* check if anything changed */
-   if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
-   ret = -EAGAIN;
-
return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index cdde7b9ec882..43fb8e00ada6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -476,9 +476,7 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
int ret;
 
ret = dpu_format_populate_layout(aspace, fb, _cfg->layout);
-   if (ret == -EAGAIN)
-   DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
-   else if (ret)
+   if (ret)
DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
-- 
2.39.0



[PATCH v2 11/27] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress

2022-12-29 Thread Dmitry Baryshkov
Move stride programming to dpu_hw_sspp_setup_sourceaddress(), so that
dpu_hw_sspp_setup_rects() programs only source and destination
rectangles.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 57 +++--
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 176cd6dc9a69..2bd39c13d54d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -447,7 +447,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
-   u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
+   u32 src_size, src_xy, dst_size, dst_xy;
u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
u32 idx;
 
@@ -478,44 +478,18 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
dst_size = (drm_rect_height(>dst_rect) << 16) |
drm_rect_width(>dst_rect);
 
-   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   ystride0 = (cfg->layout.plane_pitch[0]) |
-   (cfg->layout.plane_pitch[1] << 16);
-   ystride1 = (cfg->layout.plane_pitch[2]) |
-   (cfg->layout.plane_pitch[3] << 16);
-   } else {
-   ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
-   ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
-
-   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
-   ystride0 = (ystride0 & 0x) |
-   (cfg->layout.plane_pitch[0] & 0x);
-   ystride1 = (ystride1 & 0x)|
-   (cfg->layout.plane_pitch[2] & 0x);
-   } else {
-   ystride0 = (ystride0 & 0x) |
-   ((cfg->layout.plane_pitch[0] << 16) &
-0x);
-   ystride1 = (ystride1 & 0x) |
-   ((cfg->layout.plane_pitch[2] << 16) &
-0x);
-   }
-   }
-
/* rectangle register programming */
DPU_REG_WRITE(c, src_size_off + idx, src_size);
DPU_REG_WRITE(c, src_xy_off + idx, src_xy);
DPU_REG_WRITE(c, out_size_off + idx, dst_size);
DPU_REG_WRITE(c, out_xy_off + idx, dst_xy);
-
-   DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
-   DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
struct dpu_hw_pipe_cfg *cfg)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
+   u32 ystride0, ystride1;
int i;
u32 idx;
 
@@ -537,6 +511,33 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_sw_pipe *pipe,
DPU_REG_WRITE(>hw, SSPP_SRC3_ADDR + idx,
cfg->layout.plane_addr[2]);
}
+
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
+   ystride0 = (cfg->layout.plane_pitch[0]) |
+   (cfg->layout.plane_pitch[1] << 16);
+   ystride1 = (cfg->layout.plane_pitch[2]) |
+   (cfg->layout.plane_pitch[3] << 16);
+   } else {
+   ystride0 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE0 + idx);
+   ystride1 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE1 + idx);
+
+   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
+   ystride0 = (ystride0 & 0x) |
+   (cfg->layout.plane_pitch[0] & 0x);
+   ystride1 = (ystride1 & 0x)|
+   (cfg->layout.plane_pitch[2] & 0x);
+   } else {
+   ystride0 = (ystride0 & 0x) |
+   ((cfg->layout.plane_pitch[0] << 16) &
+0x);
+   ystride1 = (ystride1 & 0x) |
+   ((cfg->layout.plane_pitch[2] << 16) &
+0x);
+   }
+   }
+
+   DPU_REG_WRITE(>hw, SSPP_SRC_YSTRIDE0 + idx, ystride0);
+   DPU_REG_WRITE(>hw, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
-- 
2.39.0



[PATCH v2 07/27] drm/msm/dpu: drop dpu_plane_pipe function

2022-12-29 Thread Dmitry Baryshkov
There no more need for the dpu_plane_pipe() function, crtc code can
access pstate->pipe_hw.idx directly.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 4 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 7 ---
 3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 13ce321283ff..78c21a976bad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = dpu_plane_pipe(plane);
+   sspp_idx = pstate->pipe_hw->idx;
set_bit(sspp_idx, fetch_active);
 
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -1197,7 +1197,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
pstates[cnt].dpu_pstate = dpu_pstate;
pstates[cnt].drm_pstate = pstate;
pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = dpu_plane_pipe(plane);
+   pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 7ba954c7b3e0..493dcf04fa6d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1437,11 +1437,6 @@ static const struct drm_plane_helper_funcs 
dpu_plane_helper_funcs = {
.atomic_update = dpu_plane_atomic_update,
 };
 
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
-{
-   return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
-}
-
 /* initialize plane */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
uint32_t pipe, enum drm_plane_type type,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 0d268729ce81..8786359a191c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -59,13 +59,6 @@ struct dpu_multirect_plane_states {
 #define to_dpu_plane_state(x) \
container_of(x, struct dpu_plane_state, base)
 
-/**
- * dpu_plane_pipe - return sspp identifier for the given plane
- * @plane:   Pointer to DRM plane object
- * Returns: sspp identifier of the given plane
- */
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
-
 /**
  * dpu_plane_flush - final plane operations before commit flush
  * @plane: Pointer to drm plane structure
-- 
2.39.0



[PATCH v2 06/27] drm/msm/dpu: move pipe_hw to dpu_plane_state

2022-12-29 Thread Dmitry Baryshkov
In preparation to adding fully virtualized planes, move struct
dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
it will become a part of state (allocated during atomic check) rather
than part of a plane (allocated during boot).

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 102 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
 2 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 43fb8e00ada6..7ba954c7b3e0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,6 @@ struct dpu_plane {
 
enum dpu_sspp pipe;
 
-   struct dpu_hw_sspp *pipe_hw;
uint32_t color_fill;
bool is_error;
bool is_rt_pipe;
@@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u64 qos_lut;
u32 total_fl = 0, lut_usage;
@@ -310,7 +310,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
fmt ? (char *)>base.pixel_format : NULL,
pdpu->is_rt_pipe, total_fl, qos_lut);
 
-   pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
+   pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
 }
 
 /**
@@ -322,6 +322,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane 
*plane,
struct drm_framebuffer *fb)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u32 danger_lut, safe_lut;
 
@@ -361,7 +362,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane 
*plane,
danger_lut,
safe_lut);
 
-   pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
+   pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
danger_lut, safe_lut);
 }
 
@@ -375,14 +376,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane 
*plane,
bool enable, u32 flags)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
memset(_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-   pipe_qos_cfg.creq_vblank = 
pdpu->pipe_hw->cap->sblk->creq_vblank;
+   pipe_qos_cfg.creq_vblank = 
pstate->pipe_hw->cap->sblk->creq_vblank;
pipe_qos_cfg.danger_vblank =
-   pdpu->pipe_hw->cap->sblk->danger_vblank;
+   pstate->pipe_hw->cap->sblk->danger_vblank;
pipe_qos_cfg.vblank_en = enable;
}
 
@@ -408,7 +410,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
pipe_qos_cfg.danger_vblank,
pdpu->is_rt_pipe);
 
-   pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
+   pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
_qos_cfg);
 }
 
@@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane 
*plane,
struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_vbif_set_ot_params ot_params;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
memset(_params, 0, sizeof(ot_params));
-   ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-   ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
+   ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
+   ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
ot_params.width = drm_rect_width(_cfg->src_rect);
ot_params.height = drm_rect_height(_cfg->src_rect);
ot_params.is_wfd = !pdpu->is_rt_pipe;
ot_params.frame_rate = drm_mode_vrefresh(>mode);
ot_params.vbif_idx = VBIF_RT;
-   ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
+   ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
ot_params.rd = true;
 
dpu_vbif_set_ot_limit(dpu_kms, _params);
@@ -446,14 +449,15 @@ static void _dpu_plane_set_ot_limit(struct drm_plane 
*plane,
 static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_vbif_set_qos_params qos_params;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
memset(_params, 0, 

[PATCH v2 08/27] drm/msm/dpu: introduce struct dpu_sw_pipe

2022-12-29 Thread Dmitry Baryshkov
Wrap SSPP and multirect index/mode into a single structure that
represents software view on the pipe used.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 131 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  10 +-
 5 files changed, 88 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 78c21a976bad..04833d91caac 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = pstate->pipe_hw->idx;
+   sspp_idx = pstate->pipe.sspp->idx;
set_bit(sspp_idx, fetch_active);
 
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -450,11 +450,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
stage_cfg->stage[pstate->stage][stage_idx] =
sspp_idx;
stage_cfg->multirect_index[pstate->stage][stage_idx] =
-   pstate->multirect_index;
+   pstate->pipe.multirect_index;
 
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
   state, pstate, stage_idx,
-  sspp_idx - SSPP_VIG0,
   format->base.pixel_format,
   fb ? fb->modifier : 0);
 
@@ -1197,7 +1196,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
pstates[cnt].dpu_pstate = dpu_pstate;
pstates[cnt].drm_pstate = pstate;
pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx;
+   pstates[cnt].pipe_id = 
to_dpu_plane_state(pstate)->pipe.sspp->idx;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
@@ -1470,7 +1469,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, 
void *data)
state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h);
seq_printf(s, "\tmultirect: mode: %d index: %d\n",
-   pstate->multirect_mode, pstate->multirect_index);
+   pstate->pipe.multirect_mode, 
pstate->pipe.multirect_index);
 
seq_puts(s, "\n");
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 8c3e9090be4b..a96afc53e0f6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -158,15 +158,11 @@ struct dpu_hw_pixel_ext {
  * @src_rect:  src ROI, caller takes into account the different operations
  * such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
- * @index: index of the rectangle of SSPP
- * @mode:  parallel or time multiplex multirect mode
  */
 struct dpu_hw_pipe_cfg {
struct dpu_hw_fmt_layout layout;
struct drm_rect src_rect;
struct drm_rect dst_rect;
-   enum dpu_sspp_multirect_index index;
-   enum dpu_sspp_multirect_mode mode;
 };
 
 /**
@@ -201,6 +197,18 @@ struct dpu_hw_pipe_ts_cfg {
u64 time;
 };
 
+/**
+ * struct dpu_sw_pipe - software pipe description
+ * @sspp:  backing SSPP pipe
+ * @index: index of the rectangle of SSPP
+ * @mode:  parallel or time multiplex multirect mode
+ */
+struct dpu_sw_pipe {
+   struct dpu_hw_sspp *sspp;
+   enum dpu_sspp_multirect_index multirect_index;
+   enum dpu_sspp_multirect_mode multirect_mode;
+};
+
 /**
  * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
  * Caller must call the init function to get the pipe context for each pipe
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 493dcf04fa6d..1b17213235dc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -251,7 +251,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
((src_width + 32) * fmt->bpp);
}
} else {
-   if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
+   if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) 
{
total_fl = (fixed_buff_size / 2) * 2 /
((src_width + 32) * fmt->bpp);
} else {
@@ -310,7 +310,7 @@ 

[PATCH v2 03/27] drm/msm/dpu: move SSPP allocation to the RM

2022-12-29 Thread Dmitry Baryshkov
Follow the example of all other hw blocks and initialize SSPP blocks in
Resource Manager.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 17 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 22 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 12 
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index e1cdd71716f0..e443799de2c1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1275,8 +1275,6 @@ static void dpu_plane_destroy(struct drm_plane *plane)
/* this will destroy the states as well */
drm_plane_cleanup(plane);
 
-   dpu_hw_sspp_destroy(pdpu->pipe_hw);
-
kfree(pdpu);
}
 }
@@ -1482,14 +1480,10 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
pdpu->pipe = pipe;
 
/* initialize underlying h/w driver */
-   pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
-   if (IS_ERR(pdpu->pipe_hw)) {
-   DPU_ERROR("[%u]SSPP init failed\n", pipe);
-   ret = PTR_ERR(pdpu->pipe_hw);
+   pdpu->pipe_hw = dpu_rm_get_sspp(>rm, pipe);
+   if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) 
{
+   DPU_ERROR("[%u]SSPP is invalid\n", pipe);
goto clean_plane;
-   } else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
-   DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-   goto clean_sspp;
}
 
format_list = pdpu->pipe_hw->cap->sblk->format_list;
@@ -1499,7 +1493,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
format_list, num_formats,
supported_format_modifiers, type, NULL);
if (ret)
-   goto clean_sspp;
+   goto clean_plane;
 
pdpu->catalog = kms->catalog;
 
@@ -1532,9 +1526,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
pipe, plane->base.id);
return plane;
 
-clean_sspp:
-   if (pdpu && pdpu->pipe_hw)
-   dpu_hw_sspp_destroy(pdpu->pipe_hw);
 clean_plane:
kfree(pdpu);
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 73b3442e7467..0668009cc9ed 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -8,6 +8,7 @@
 #include "dpu_hw_lm.h"
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_pingpong.h"
+#include "dpu_hw_sspp.h"
 #include "dpu_hw_intf.h"
 #include "dpu_hw_wb.h"
 #include "dpu_hw_dspp.h"
@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
dpu_hw_wb_destroy(rm->hw_wb[i]);
 
+   for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
+   dpu_hw_sspp_destroy(rm->hw_sspp[i]);
+
return 0;
 }
 
@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->dsc_blks[dsc->id - DSC_0] = >base;
}
 
+   for (i = 0; i < cat->sspp_count; i++) {
+   struct dpu_hw_sspp *hw;
+   const struct dpu_sspp_cfg *sspp = >sspp[i];
+
+   if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) {
+   DPU_ERROR("skip intf %d with invalid id\n", sspp->id);
+   continue;
+   }
+
+   hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
+   if (IS_ERR(hw)) {
+   rc = PTR_ERR(hw);
+   DPU_ERROR("failed sspp object creation: err %d\n", rc);
+   goto fail;
+   }
+   rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
+   }
+
return 0;
 
 fail:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 59de72b381f9..d62c2edb2460 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -21,6 +21,7 @@ struct dpu_global_state;
  * @hw_intf: array of intf hardware resources
  * @hw_wb: array of wb hardware resources
  * @dspp_blks: array of dspp hardware resources
+ * @hw_sspp: array of sspp hardware resources
  */
 struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@@ -31,6 +32,7 @@ struct dpu_rm {
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
+   struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
 };
 
 /**
@@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct 
dpu_rm *rm, enum dpu_wb wb_
return rm->hw_wb[wb_idx - WB_0];
 }
 
+/**
+ * dpu_rm_get_sspp - Return a struct dpu_hw_sspp instance 

[PATCH v2 01/27] drm/msm/dpu: set pdpu->is_rt_pipe early in dpu_plane_sspp_atomic_update()

2022-12-29 Thread Dmitry Baryshkov
The function dpu_plane_sspp_atomic_update() updates pdpu->is_rt_pipe
flag, but after the commit 854f6f1c653b ("drm/msm/dpu: update the qos
remap only if the client type changes") it sets the flag late, after all
the qos functions have updated QoS programming. Move the flag update
back to the place where it happended before the mentioned commit to let
the pipe be programmed according to its current RT/non-RT state.

Fixes: 854f6f1c653b ("drm/msm/dpu: update the qos remap only if the client type 
changes")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 86719020afe2..bfd5be89e8b8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1126,7 +1126,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
struct drm_crtc *crtc = state->crtc;
struct drm_framebuffer *fb = state->fb;
-   bool is_rt_pipe, update_qos_remap;
+   bool is_rt_pipe;
const struct dpu_format *fmt =
to_dpu_format(msm_framebuffer_format(fb));
struct dpu_hw_pipe_cfg pipe_cfg;
@@ -1138,6 +1138,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
pstate->pending = true;
 
is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
+   pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
+   pdpu->is_rt_pipe = is_rt_pipe;
+
_dpu_plane_set_qos_ctrl(plane, false, DPU_PLANE_QOS_PANIC_CTRL);
 
DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
@@ -1219,14 +1222,8 @@ static void dpu_plane_sspp_atomic_update(struct 
drm_plane *plane)
_dpu_plane_set_ot_limit(plane, crtc, _cfg);
}
 
-   update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
-   pstate->needs_qos_remap;
-
-   if (update_qos_remap) {
-   if (is_rt_pipe != pdpu->is_rt_pipe)
-   pdpu->is_rt_pipe = is_rt_pipe;
-   else if (pstate->needs_qos_remap)
-   pstate->needs_qos_remap = false;
+   if (pstate->needs_qos_remap) {
+   pstate->needs_qos_remap = false;
_dpu_plane_set_qos_remap(plane);
}
 
-- 
2.39.0



[PATCH v2 02/27] drm/msm/dpu: rename struct dpu_hw_pipe to dpu_hw_sspp

2022-12-29 Thread Dmitry Baryshkov
For all hardware blocks except SSPP the corresponding struct is named
after the block. Rename dpu_hw_pipe (SSPP structure) to dpu_hw_sspp.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 42 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 42 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  2 +-
 3 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 691c471b08c2..93f01f767fd8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -136,7 +136,7 @@
 #define TS_CLK 1920
 
 
-static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
+static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
int s_id,
u32 *idx)
 {
@@ -168,7 +168,7 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
enum dpu_sspp_multirect_index index,
enum dpu_sspp_multirect_mode mode)
 {
@@ -197,7 +197,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe 
*ctx,
DPU_REG_WRITE(>hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
 }
 
-static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
u32 mask, u8 en)
 {
u32 idx;
@@ -218,7 +218,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
DPU_REG_WRITE(>hw, SSPP_VIG_OP_MODE + idx, opmode);
 }
 
-static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
u32 mask, u8 en)
 {
u32 idx;
@@ -239,7 +239,7 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe 
*ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
const struct dpu_format *fmt, u32 flags,
enum dpu_sspp_multirect_index rect_mode)
 {
@@ -356,7 +356,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe 
*ctx,
DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
 }
 
-static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
struct dpu_hw_pixel_ext *pe_ext)
 {
struct dpu_hw_blk_reg_map *c;
@@ -414,7 +414,7 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe 
*ctx,
tot_req_pixels[3]);
 }
 
-static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
+static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
struct dpu_hw_pipe_cfg *sspp,
void *scaler_cfg)
 {
@@ -430,7 +430,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe 
*ctx,
sspp->layout.format);
 }
 
-static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
+static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
 {
u32 idx;
 
@@ -443,7 +443,7 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe 
*ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
struct dpu_hw_pipe_cfg *cfg,
enum dpu_sspp_multirect_index rect_index)
 {
@@ -512,7 +512,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
-static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
struct dpu_hw_pipe_cfg *cfg,
enum dpu_sspp_multirect_index rect_mode)
 {
@@ -539,7 +539,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_hw_pipe *ctx,
}
 }
 
-static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
const struct dpu_csc_cfg *data)
 {
u32 idx;
@@ -556,7 +556,7 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
dpu_hw_csc_setup(>hw, idx, data, csc10);
 }
 
-static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, 
enum
+static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *ctx, u32 color, 
enum
dpu_sspp_multirect_index rect_index)
 {
u32 idx;
@@ -571,7 +571,7 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe 
*ctx, u32 color, enum
color);
 }
 
-static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx,
 

[PATCH v2 00/27] drm/msm/dpu: wide planes support

2022-12-29 Thread Dmitry Baryshkov
It took me a way longer to finish than I expected. And more patches that
I previously hoped (despite having several patches already being merged
from v1).

This patchset brings in multirect usage to support using two SSPP
rectangles for a single plane. Full virtual planes support is omitted
from this pull request, it will come later.

Abhinav, could you please pick up patch 1 for the -fixes? Otherwise QoS
is not programmed correcly.

Changes since v1 (which was ages ago):
- Rebased on top of 6.2-rc1
- Dropped the controversial _dpu_crtc_blend_setup() split patch
- Renamed dpu_hw_pipe to dpu_hw_sspp
- Other misc changes

Dmitry Baryshkov (27):
  drm/msm/dpu: set pdpu->is_rt_pipe early in
dpu_plane_sspp_atomic_update()
  drm/msm/dpu: rename struct dpu_hw_pipe to dpu_hw_sspp
  drm/msm/dpu: move SSPP allocation to the RM
  drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  drm/msm/dpu: move pipe_hw to dpu_plane_state
  drm/msm/dpu: drop dpu_plane_pipe function
  drm/msm/dpu: introduce struct dpu_sw_pipe
  drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  drm/msm/dpu: move stride programming to
dpu_hw_sspp_setup_sourceaddress
  drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg
  drm/msm/dpu: drop src_split and multirect check from
dpu_crtc_atomic_check
  drm/msm/dpu: don't use unsupported blend stages
  drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  drm/msm/dpu: drop redundant plane dst check from
dpu_crtc_atomic_check()
  drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  drm/msm/dpu: simplify dpu_plane_validate_src()
  drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
and dpu_format
  drm/msm/dpu: populate SmartDMA features in hw catalog
  drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
  drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  drm/msm/dpu: rework dpu_plane_atomic_check()
  drm/msm/dpu: rework plane CSC setting
  drm/msm/dpu: rework static color fill code
  drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  drm/msm/dpu: add support for wide planes

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 283 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |  10 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|  10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 163 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   | 104 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  18 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 735 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  20 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c|  22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h|  12 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  25 +-
 11 files changed, 685 insertions(+), 717 deletions(-)

-- 
2.39.0



Re: [PATCH v1] drm/scheduler: Fix lockup in drm_sched_entity_kill()

2022-12-29 Thread Guilherme G. Piccoli
On 29/12/2022 07:15, Dmitry Osipenko wrote:
> [...]
> I'll push the patch to misc-fixes as soon as it will be rebased on
> 6.2-rc. Thanks!
> 
> Best regards,
> Dmitry
> 

Thank you Dmitry, much appreciated!
Cheers,


Guilherme


Re: [PATCH v2 11/11] drm/amd: Request PSP microcode during IP discovery

2022-12-29 Thread Alex Deucher
On Wed, Dec 28, 2022 at 11:32 AM Mario Limonciello
 wrote:
>
> If PSP microcode is required but not available during early init, the
> firmware framebuffer will have already been released and the screen will
> freeze.
>
> Move the request for PSP microcode into the IP discovery phase
> so that if it's not available, IP discovery will fail.
>
> Signed-off-by: Mario Limonciello 

This is probably ok, but I think I'd prefer to just move the
request_firwmare() calls out into ip discovery and leave the rest of
the logic in the PSP code.

Alex


> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 120 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   |   2 -
>  drivers/gpu/drm/amd/amdgpu/psp_v10_0.c| 106 +++
>  drivers/gpu/drm/amd/amdgpu/psp_v11_0.c| 165 --
>  drivers/gpu/drm/amd/amdgpu/psp_v12_0.c| 102 +++
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0.c|  82 -
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c  |  36 
>  drivers/gpu/drm/amd/amdgpu/psp_v3_1.c |  36 
>  8 files changed, 202 insertions(+), 447 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> index c8c538a768fe..6199ab078bc7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> @@ -158,6 +158,40 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
>  MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
>  MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
>
> +MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin");
> +MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin");
> +MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin");
> +MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin");
> +MODULE_FIRMWARE("amdgpu/green_sardine_ta.bin");
> +MODULE_FIRMWARE("amdgpu/raven_asd.bin");
> +MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
> +MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
> +MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
> +MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
> +MODULE_FIRMWARE("amdgpu/raven_ta.bin");
> +MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
> +MODULE_FIRMWARE("amdgpu/renoir_ta.bin");
> +MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin");
> +MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin");
> +MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
> +MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
> +MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
> +MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
> +MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_4_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_4_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
>
>  /* gfx9 */
>  MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
> @@ -1858,12 +1892,30 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct 
> amdgpu_device *adev)
>
>  static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
>  {
> +   char ucode_prefix[30];
> +   int r;
> +
> +   amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, 
> sizeof(ucode_prefix));
> +   adev->psp.adev = adev;
> +
> switch (adev->ip_versions[MP0_HWIP][0]) {
> case IP_VERSION(9, 0, 0):
> +   r = psp_init_sos_microcode(>psp, ucode_prefix);
> +   if (r)
> +   return r;
> +   r = psp_init_asd_microcode(>psp, ucode_prefix);
> +   if (r)
> +   return r;
> amdgpu_device_ip_block_add(adev, _v3_1_ip_block);
> break;
> case IP_VERSION(10, 0, 0):
> case IP_VERSION(10, 0, 1):
> +   r = psp_init_asd_microcode(>psp, ucode_prefix);
> +   if (r)
> +   return r;
> +   r = psp_init_ta_microcode(>psp, ucode_prefix);
> +   if (r)
> +   return r;
> amdgpu_device_ip_block_add(adev, _v10_0_ip_block);
> break;
> case IP_VERSION(11, 0, 0):
> @@ -1871,11 +1923,34 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct 
> amdgpu_device *adev)
> case IP_VERSION(11, 0, 4):
> case IP_VERSION(11, 0, 5):
> case IP_VERSION(11, 0, 9):
> +   r = psp_init_sos_microcode(>psp, ucode_prefix);
> +   if (r)
> +   return r;
> +   r = psp_init_asd_microcode(>psp, ucode_prefix);
> +   if (r)
> +   return r;
> +   r = 

Re: [PATCH v2 00/11] Recover from failure to probe GPU

2022-12-29 Thread Alex Deucher
Patches 1-10 are:
Reviewed-by: Alex Deucher 

On Wed, Dec 28, 2022 at 11:31 AM Mario Limonciello
 wrote:
>
> One of the first thing that KMS drivers do during initialization is
> destroy the system firmware framebuffer by means of
> `drm_aperture_remove_conflicting_pci_framebuffers`
>
> This means that if for any reason the GPU failed to probe the user
> will be stuck with at best a screen frozen at the last thing that
> was shown before the KMS driver continued it's probe.
>
> The problem is most pronounced when new GPU support is introduced
> because users will need to have a recent linux-firmware snapshot
> on their system when they boot a kernel with matching support.
>
> However the problem is further exaggerated in the case of amdgpu because
> it has migrated to "IP discovery" where amdgpu will attempt to load
> on "ALL" AMD GPUs even if the driver is missing support for IP blocks
> contained in that GPU.
>
> IP discovery requires some probing and isn't run until after the
> framebuffer has been destroyed.
>
> This means a situation can occur where a user purchases a new GPU not
> yet supported by a distribution and when booting the installer it will
> "freeze" even if the distribution doesn't have the matching kernel support
> for those IP blocks.
>
> The perfect example of this is Ubuntu 22.10 and the new dGPUs just
> launched by AMD.  The installation media ships with kernel 5.19 (which
> has IP discovery) but the amdgpu support for those IP blocks landed in
> kernel 6.0. The matching linux-firmware was released after 22.10's launch.
> The screen will freeze without nomodeset. Even if a user manages to install
> and then upgrades to kernel 6.0 after install they'll still have the
> problem of missing firmware, and the same experience.
>
> This is quite jarring for users, particularly if they don't know
> that they have to use "nomodeset" to install.
>
> To help the situation make changes to GPU discovery:
> 1) Delay releasing the firmware framebuffer until after IP discovery has
> completed.  This will help the situation of an older kernel that doesn't
> yet support the IP blocks probing a new GPU.
> 2) Request loading all PSP, VCN, SDMA, MES and GC microcode into memory
> during IP discovery. This will help the situation of new enough kernel for
> the IP discovery phase to otherwise pass but missing microcode from
> linux-firmware.git.
>
> Not all requested firmware will be loaded during IP discovery as some of it
> will require larger driver architecture changes. For example SMU firmware
> isn't loaded on certain products, but that's not known until later on when
> the early_init phase of the SMU load occurs.
>
> v1->v2:
>  * Take the suggestion from v1 thread to delay the framebuffer release until
>ip discovery is done. This patch is CC to stable to that older stable
>kernels with IP discovery won't try to probe unknown IP.
>  * Drop changes to drm aperature.
>  * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery.
>
> Mario Limonciello (11):
>   drm/amd: Delay removal of the firmware framebuffer
>   drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
>   drm/amd: Convert SMUv11 microcode init to use
> `amdgpu_ucode_ip_version_decode`
>   drm/amd: Convert SMU v13 to use `amdgpu_ucode_ip_version_decode`
>   drm/amd: Request SDMA microcode during IP discovery
>   drm/amd: Request VCN microcode during IP discovery
>   drm/amd: Request MES microcode during IP discovery
>   drm/amd: Request GFX9 microcode during IP discovery
>   drm/amd: Request GFX10 microcode during IP discovery
>   drm/amd: Request GFX11 microcode during IP discovery
>   drm/amd: Request PSP microcode during IP discovery
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c|   8 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 590 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |   6 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   |   2 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c  |   9 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h  |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 208 ++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c   |  85 +--
>  drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c| 180 +-
>  drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c|  64 +-
>  drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 143 +
>  drivers/gpu/drm/amd/amdgpu/mes_v10_1.c|  28 -
>  drivers/gpu/drm/amd/amdgpu/mes_v11_0.c|  25 +-
>  drivers/gpu/drm/amd/amdgpu/psp_v10_0.c| 106 +---
>  drivers/gpu/drm/amd/amdgpu/psp_v11_0.c| 165 +
>  drivers/gpu/drm/amd/amdgpu/psp_v12_0.c| 102 +--
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0.c|  82 ---
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c  |  36 --
>  drivers/gpu/drm/amd/amdgpu/psp_v3_1.c |  36 --
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c|  61 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c|  42 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c

Re: (subset) [PATCH v2 1/3] dt-bindings: display/msm: Add SM8150 MDSS & DPU

2022-12-29 Thread Bjorn Andersson
On Thu, 29 Dec 2022 11:05:08 +0100, Konrad Dybcio wrote:
> Add bindings for the display hardware on SM8150.
> 
> 

Applied, thanks!

[2/3] arm64: dts: qcom: sm8150: Add DISPCC node
  commit: 2ef3bb17c45c5b83204a845bbe4045eed11bc759
[3/3] arm64: dts: qcom: sm8150: Wire up MDSS
  commit: 98874a46686b78d2f303de1a898b7b7cc611e30c

Best regards,
-- 
Bjorn Andersson 


Re: (subset) [PATCH v6 00/18] mdss-dsi-ctrl binding and dts fixes

2022-12-29 Thread Bjorn Andersson
On Fri, 23 Dec 2022 02:10:07 +, Bryan O'Donoghue wrote:
> V6:
> - Squashes a number of patches per Krzysztof's comments on bisectability
> - Adds in Acked-by Rob and Krzysztof
> 
> V5:
> - Adds compat strings to bindings/display/msm/qcom,SoC-mdss.yaml - Dmitry
> - Re-orders simple fixes to the start of the series to allow backports - 
> Dmitry
> - VDDA and drop of node-names - Krzysztof
> - Deprecates qcom,dsi-ctrl-6g-qcm2290 - Krzysztof, Dmitry
> - Expands set of updated files to include new msm8953 - bod
> - Converts to agreed compat string qcom,SoC-dsi-ctrl hence
>   -  - qcom,mdss-dsi-ctrl-msm8996
>   +  - qcom,msm8996-dsi-ctrl
> - Adds RB where indicated for the compat strings.
> V4:
> - Moves the update of the example from patch #5 to patch #4
> 
> [...]

Applied, thanks!

[10/18] arm64: dts: qcom: msm8916: Add compat qcom,msm8916-dsi-ctrl
commit: cd8cecc723671016a28f88ab13ee31642cb9e391
[11/18] arm64: dts: qcom: msm8953: Add compat qcom,msm8953-dsi-ctrl
commit: 634ecbc6b17ac2beea4d64f84df629520306e8cc
[12/18] arm64: dts: qcom: msm8996: Add compat qcom,msm8996-dsi-ctrl
commit: 5ebe4191286add92e8560915aaeb803578407f12
[13/18] arm64: dts: qcom: sc7180: Add compat qcom,sc7180-dsi-ctrl
commit: a45d0641d110e81826710aa92711e1c2eedecb43
[14/18] arm64: dts: qcom: sc7280: Add compat qcom,sc7280-dsi-ctrl
commit: 5b5e4ac378e5d2b1f881c8a6ea0ae827201ee07d
[15/18] arm64: dts: qcom: sdm630: Add compat qcom,sdm660-dsi-ctrl
commit: 197d28d46315353cfc91d8519b8b561ab08a02cc
[16/18] arm64: dts: qcom: sdm660: Add compat qcom,sdm660-dsi-ctrl
commit: 3381020a778c559c95e31af6d868ad059fbd65e8
[17/18] arm64: dts: qcom: sdm845: Add compat qcom,sdm845-dsi-ctrl
commit: a1a685c312f5bcc6fbf35b647d3bc5cfc6f70c7d
[18/18] arm64: dts: qcom: sm8250: Add compat qcom,sm8250-dsi-ctrl
commit: ff114e399e746e07df56bad1b4aaf540f37d579d

Best regards,
-- 
Bjorn Andersson 


[PATCH v6] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry

2022-12-29 Thread Zheng Wang
If intel_gvt_dma_map_guest_page failed, it will call
 ppgtt_invalidate_spt, which will finally free the spt.
 But the caller function ppgtt_populate_spt_by_guest_entry
 does not notice that, it will free spt again in its error
 path.

Fix this by canceling the mapping of DMA address and freeing sub_spt.
Besides, leave the handle of spt destroy to caller function instead
of callee function when error occurs.

Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support")
Signed-off-by: Zheng Wang 
Reviewed-by: Zhenyu Wang 
---
v6:
- remove the code for setting unused variable to NULL and fix type suggested
by Zhenyu

v5:
- remove unnecessary switch-case code for there is only one particular case,
correct the unmap target from parent_spt to sub_spt.add more details in
commit message. All suggested by Zhenyu

v4:
- fix by undo the mapping of DMA address and free sub_spt suggested by Zhi

v3:
- correct spelling mistake and remove unused variable suggested by Greg

v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz...@163.com/

v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz...@163.com/
---
 drivers/gpu/drm/i915/gvt/gtt.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 51e5e8fb505b..7379e8d98417 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1209,10 +1209,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
for_each_shadow_entry(sub_spt, _se, sub_index) {
ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index,
   PAGE_SIZE, _addr);
-   if (ret) {
-   ppgtt_invalidate_spt(spt);
-   return ret;
-   }
+   if (ret)
+   goto err;
sub_se.val64 = se->val64;
 
/* Copy the PAT field from PDE. */
@@ -1231,6 +1229,17 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
ops->set_pfn(se, sub_spt->shadow_page.mfn);
ppgtt_set_shadow_entry(spt, se, index);
return 0;
+err:
+   /* Cancel the existing addess mappings of DMA addr. */
+   for_each_present_shadow_entry(sub_spt, _se, sub_index) {
+   gvt_vdbg_mm("invalidate 4K entry\n");
+   ppgtt_invalidate_pte(sub_spt, _se);
+   }
+   /* Release the new allocated spt. */
+   trace_spt_change(sub_spt->vgpu->id, "release", sub_spt,
+   sub_spt->guest_page.gfn, sub_spt->shadow_page.type);
+   ppgtt_free_spt(sub_spt);
+   return ret;
 }
 
 static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
-- 
2.25.1



Re: [PATCH 13/19] arch/riscv: rename internal name __xchg to __arch_xchg

2022-12-29 Thread Palmer Dabbelt

On Thu, 22 Dec 2022 03:46:29 PST (-0800), andrzej.ha...@intel.com wrote:

__xchg will be used for non-atomic xchg macro.

Signed-off-by: Andrzej Hajda 
---
 arch/riscv/include/asm/atomic.h  | 2 +-
 arch/riscv/include/asm/cmpxchg.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index 0dfe9d857a762b..bba472928b5393 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -261,7 +261,7 @@ c_t arch_atomic##prefix##_xchg_release(atomic##prefix##_t 
*v, c_t n)\
 static __always_inline \
 c_t arch_atomic##prefix##_xchg(atomic##prefix##_t *v, c_t n)   \
 {  \
-   return __xchg(&(v->counter), n, size);   \
+   return __arch_xchg(&(v->counter), n, size);  \
 }  \
 static __always_inline \
 c_t arch_atomic##prefix##_cmpxchg_relaxed(atomic##prefix##_t *v,   \
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 12debce235e52d..2f4726d3cfcc25 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -114,7 +114,7 @@
_x_, sizeof(*(ptr)));   \
 })

-#define __xchg(ptr, new, size) \
+#define __arch_xchg(ptr, new, size)\
 ({ \
__typeof__(ptr) __ptr = (ptr);  \
__typeof__(new) __new = (new);  \
@@ -143,7 +143,7 @@
 #define arch_xchg(ptr, x)  \
 ({ \
__typeof__(*(ptr)) _x_ = (x);   \
-   (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr)));\
+   (__typeof__(*(ptr))) __arch_xchg((ptr), _x_, sizeof(*(ptr)));   \
 })

 #define xchg32(ptr, x) \


Acked-by: Palmer Dabbelt 

Thanks!


RE: [PATCH 08/18] fbdev/hyperv-fb: Do not set struct fb_info.apertures

2022-12-29 Thread Michael Kelley (LINUX)
From: Thomas Zimmermann  Sent: Monday, December 19, 2022 
8:05 AM
> 
> Generic fbdev drivers use the apertures field in struct fb_info to
> control ownership of the framebuffer memory and graphics device. Do
> not set the values in hyperv-fb.
> 
> Signed-off-by: Thomas Zimmermann 
> ---
>  drivers/video/fbdev/hyperv_fb.c | 17 ++---
>  1 file changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
> index d8edb5635f77..1c7d6ff5a6c0 100644
> --- a/drivers/video/fbdev/hyperv_fb.c
> +++ b/drivers/video/fbdev/hyperv_fb.c
> @@ -988,13 +988,10 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
> fb_info *info)
>   struct pci_dev *pdev  = NULL;
>   void __iomem *fb_virt;
>   int gen2vm = efi_enabled(EFI_BOOT);
> + resource_size_t base, size;
>   phys_addr_t paddr;
>   int ret;
> 
> - info->apertures = alloc_apertures(1);
> - if (!info->apertures)
> - return -ENOMEM;
> -
>   if (!gen2vm) {
>   pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
>   PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
> @@ -1003,8 +1000,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
> fb_info *info)
>   return -ENODEV;
>   }
> 
> - info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
> - info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
> + base = pci_resource_start(pdev, 0);
> + size = pci_resource_len(pdev, 0);
> 
>   /*
>* For Gen 1 VM, we can directly use the contiguous memory
> @@ -1027,8 +1024,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
> fb_info *info)
>   }
>   pr_info("Unable to allocate enough contiguous physical memory 
> on Gen 1 VM. Using MMIO instead.\n");
>   } else {
> - info->apertures->ranges[0].base = screen_info.lfb_base;
> - info->apertures->ranges[0].size = screen_info.lfb_size;
> + base = screen_info.lfb_base;
> + size = screen_info.lfb_size;
>   }
> 
>   /*
> @@ -1070,9 +1067,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
> fb_info *info)
>   info->screen_size = dio_fb_size;
> 
>  getmem_done:
> - aperture_remove_conflicting_devices(info->apertures->ranges[0].base,
> - info->apertures->ranges[0].size,
> - false, KBUILD_MODNAME);
> + aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME);
> 
>   if (gen2vm) {
>   /* framebuffer is reallocated, clear screen_info to avoid 
> misuse from kexec */
> --
> 2.39.0

Reviewed-by: Michael Kelley 



Re: [PATCH 01/14] drm/mipi-dsi: Add a mipi_dsi_dcs_write_seq() macro

2022-12-29 Thread kernel test robot
Hi Javier,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on linus/master v6.2-rc1 next-20221226]
[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/Javier-Martinez-Canillas/drm-mipi-dsi-Add-a-mipi_dsi_dcs_write_seq-macro/20221228-100040
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20221228014757.3170486-2-javierm%40redhat.com
patch subject: [PATCH 01/14] drm/mipi-dsi: Add a mipi_dsi_dcs_write_seq() macro
reproduce:
# 
https://github.com/intel-lab-lkp/linux/commit/6dbe3eb57c38eaa1be1271fe9563406472377dc7
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Javier-Martinez-Canillas/drm-mipi-dsi-Add-a-mipi_dsi_dcs_write_seq-macro/20221228-100040
git checkout 6dbe3eb57c38eaa1be1271fe9563406472377dc7
make menuconfig
# enable CONFIG_COMPILE_TEST, CONFIG_WARN_MISSING_DOCUMENTS, 
CONFIG_WARN_ABI_ERRORS
make htmldocs

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> ./include/drm/drm_mipi_dsi.h:314: warning: expecting prototype for 
>> mipi_dsi_generic_write(). Prototype was for mipi_dsi_generic_write_seq() 
>> instead

vim +314 ./include/drm/drm_mipi_dsi.h

   271  
   272  ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
   273const void *data, size_t len);
   274  ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
   275 const void *data, size_t len);
   276  ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void 
*data,
   277size_t len);
   278  int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi);
   279  int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi);
   280  int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode);
   281  int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 
*format);
   282  int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi);
   283  int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi);
   284  int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi);
   285  int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi);
   286  int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 
start,
   287  u16 end);
   288  int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 
start,
   289u16 end);
   290  int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
   291  int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
   292   enum mipi_dsi_dcs_tear_mode mode);
   293  int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 
format);
   294  int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 
scanline);
   295  int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
   296  u16 brightness);
   297  int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
   298  u16 *brightness);
   299  
   300  /**
   301   * mipi_dsi_generic_write - transmit data using a generic write packet
   302   * @dsi: DSI peripheral device
   303   * @seq: buffer containing the payload
   304   */
   305  #define mipi_dsi_generic_write_seq(dsi, seq...) do {
\
   306  static const u8 d[] = { seq };  
\
   307  struct device *dev = >dev; \
   308  int ret;
\
   309  ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));
\
   310  if (ret < 0) {  
\
   311  dev_err_ratelimited(dev, "transmit data failed: 
%d\n", ret); \
   312  return ret; 
\
   313  }   \
 > 314  } while (0)
   315  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 6.1.0-rc6 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc-11 (Debian 11.3.0-8) 11.3.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=110300
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23900
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23900
CONFIG_LLD_VERSION=0
CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y

Re: [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer

2022-12-29 Thread Javier Martinez Canillas
Hello Mario,

On 12/28/22 17:30, Mario Limonciello wrote:
> Removing the firmware framebuffer from the driver means that even
> if the driver doesn't support the IP blocks in a GPU it will no
> longer be functional after the driver fails to initialize.
> 
> This change will ensure that unsupported IP blocks at least cause
> the driver to work with the EFI framebuffer.
>
> Cc: sta...@vger.kernel.org
> Suggested-by: Alex Deucher 
> Signed-off-by: Mario Limonciello 
> ---

As mentioned, I'm not familiar with this driver but the change looks
good to me. Delaying the firmware-provided framebuffer removal is the
correct thing to do IMO.

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH 03/14] drm/panel-sitronix-st7703: Drop custom DSI write macros

2022-12-29 Thread Javier Martinez Canillas
Hello Guido,

On 12/28/22 13:01, Guido Günther wrote:
> Hi Javier,
> Could you please also cc maintainers on the actual macro addition since
> it's hard to review without seeing what the code gets changed to
> (especially when there's multiple revisions). I assume
>

Sure, I will do it if post another revision. Although the changes are quite
trivial and all the drivers define basically the same macro so no functional
changes are expected.
 
>
> https://lore.kernel.org/dri-devel/20221228014757.3170486-2-javi...@redhat.com/
> 
> is the right one?

Correct.

> Cheers,
>  -- Guido
> 
-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



[PATCH v3 05/21] staging: media: tegra-video: document tegra_channel_get_remote_source_subdev

2022-12-29 Thread Luca Ceresoli
Clarify what this function does.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 9dba6e97ebdd..6aecdd28bd82 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -154,6 +154,9 @@ tegra_channel_get_remote_csi_subdev(struct tegra_vi_channel 
*chan)
return media_entity_to_v4l2_subdev(pad->entity);
 }
 
+/*
+ * Walk up the chain until the initial source (e.g. image sensor)
+ */
 struct v4l2_subdev *
 tegra_channel_get_remote_source_subdev(struct tegra_vi_channel *chan)
 {
-- 
2.34.1



[PATCH v3 21/21] staging: media: tegra-video: add support for Tegra20 parallel input

2022-12-29 Thread Luca Ceresoli
The VI peripheral of Tegra supports capturing from MIPI CSI-2 or parallel
video (called VIP in the docs).

The staging tegra-video driver currently implements MIPI CSI-2 video
capture for Tegra210. Add support for parallel video capture (VIP) on
Tegra20. With the generalizations added to the VI driver in previous
commits, this is only a matter of adding the vip.c and tegra20.c
implementations and registering them.

Unfortunately there was no documentation available for the VI or VIP
peripherals of Tegra20 (or any other Tegra chips). This implementation has
been based entirely on the code from a vendor kernel based on Linux 3.1 and
massively adapted to fit into the tegra-video driver. Parts of this code is
definitely non-optimal to say the least (especially tegra20_vi_enable() and
the single-frame capture logic), but it was impossible to improve it.

Signed-off-by: Luca Ceresoli 

---

Changed in v3 (suggested by Dmitry Osipenko):
 - merged the VIP patch and the Tegra20 patch to avoid chicken-egg problem
   due to the two modules depending on each other at build time
 - move tegra20_vip_soc to vip.c
 - remove channel@0 node from device tree parsing
 - remove unused variable

Changed in v2:
 - fix tegra20_vi_enable() to clear bit when on==false
 - clamp width/height from set/try_fmt to avoid returning sizeimage=0
   (fixes v4l2-compliance)
---
 drivers/staging/media/tegra-video/Makefile  |   2 +
 drivers/staging/media/tegra-video/tegra20.c | 661 
 drivers/staging/media/tegra-video/vi.c  |   3 +
 drivers/staging/media/tegra-video/vi.h  |   3 +
 drivers/staging/media/tegra-video/video.c   |   5 +
 drivers/staging/media/tegra-video/video.h   |   1 +
 drivers/staging/media/tegra-video/vip.c | 290 +
 drivers/staging/media/tegra-video/vip.h |  68 ++
 8 files changed, 1033 insertions(+)
 create mode 100644 drivers/staging/media/tegra-video/tegra20.c
 create mode 100644 drivers/staging/media/tegra-video/vip.c
 create mode 100644 drivers/staging/media/tegra-video/vip.h

diff --git a/drivers/staging/media/tegra-video/Makefile 
b/drivers/staging/media/tegra-video/Makefile
index dfa2ef8f99ef..6c7552e05109 100644
--- a/drivers/staging/media/tegra-video/Makefile
+++ b/drivers/staging/media/tegra-video/Makefile
@@ -2,7 +2,9 @@
 tegra-video-objs := \
video.o \
vi.o \
+   vip.o \
csi.o
 
+tegra-video-$(CONFIG_ARCH_TEGRA_2x_SOC)  += tegra20.o
 tegra-video-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
 obj-$(CONFIG_VIDEO_TEGRA) += tegra-video.o
diff --git a/drivers/staging/media/tegra-video/tegra20.c 
b/drivers/staging/media/tegra-video/tegra20.c
new file mode 100644
index ..ac048bbd58f0
--- /dev/null
+++ b/drivers/staging/media/tegra-video/tegra20.c
@@ -0,0 +1,661 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Tegra20-specific VI implementation
+ *
+ * Copyright (C) 2022 SKIDATA GmbH
+ * Author: Luca Ceresoli 
+ */
+
+/*
+ * This source file contains Tegra20 supported video formats,
+ * VI and VIP SoC specific data, operations and registers accessors.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vip.h"
+#include "vi.h"
+
+#define TEGRA_VI_SYNCPT_WAIT_TIMEOUT   msecs_to_jiffies(200)
+
+/* This are just good-sense numbers. The actual min/max is not documented. */
+#define TEGRA20_MIN_WIDTH  32U
+#define TEGRA20_MIN_HEIGHT 32U
+#define TEGRA20_MAX_WIDTH  2048U
+#define TEGRA20_MAX_HEIGHT 2048U
+
+/* --
+ * Registers
+ */
+
+#define TEGRA_VI_CONT_SYNCPT_OUT_1 0x0060
+#define   VI_CONT_SYNCPT_OUT_1_CONTINUOUS_SYNCPT   BIT(8)
+#define   VI_CONT_SYNCPT_OUT_1_SYNCPT_IDX_SFT  0
+
+#define TEGRA_VI_VI_INPUT_CONTROL  0x0088
+#define   VI_INPUT_FIELD_DETECTBIT(27)
+#define   VI_INPUT_BT656   BIT(25)
+#define   VI_INPUT_YUV_INPUT_FORMAT_SFT8  /* bits [9:8] */
+#define   VI_INPUT_YUV_INPUT_FORMAT_UYVY   (0 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_VYUY   (1 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_YUYV   (2 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_YVYU   (3 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_INPUT_FORMAT_SFT2  /* bits 
[5:2] */
+#define   VI_INPUT_INPUT_FORMAT_YUV422 (0 << 
VI_INPUT_INPUT_FORMAT_SFT)
+#define   VI_INPUT_VIP_INPUT_ENABLEBIT(1)
+
+#define TEGRA_VI_VI_CORE_CONTROL   0x008c
+#define   VI_VI_CORE_CONTROL_PLANAR_CONV_IN_SEL_EXTBIT(31)
+#define   VI_VI_CORE_CONTROL_CSC_INPUT_SEL_EXT BIT(30)
+#define   VI_VI_CORE_CONTROL_INPUT_TO_ALT_MUX_SFT  27
+#define   

[PATCH v3 17/21] staging: media: tegra-video: move syncpt init/free to a per-soc op

2022-12-29 Thread Luca Ceresoli
tegra_channel_host1x_syncpt_init() gets the host1x syncpts needed for the
Tegra210 implementation, and tegra_channel_host1x_syncpts_free() puts
them.

Tegra20 needs to get and put a different syncpt. In preparation for adding
Tegra20 support, move these functions to new ops in the soc-specific
`struct tegra_vi_ops` .

No functional changes.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c | 52 
 drivers/staging/media/tegra-video/vi.c   | 52 ++--
 drivers/staging/media/tegra-video/vi.h   |  5 ++
 3 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 28d3d05c12c4..d47ba79bac75 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -179,6 +179,56 @@ static u32 vi_csi_read(struct tegra_vi_channel *chan, u8 
portno,
 /*
  * Tegra210 VI channel capture operations
  */
+
+static int tegra210_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
+{
+   struct tegra_vi *vi = chan->vi;
+   unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
+   struct host1x_syncpt *fs_sp;
+   struct host1x_syncpt *mw_sp;
+   int ret, i;
+
+   for (i = 0; i < chan->numgangports; i++) {
+   fs_sp = host1x_syncpt_request(>client, flags);
+   if (!fs_sp) {
+   dev_err(vi->dev, "failed to request frame start 
syncpoint\n");
+   ret = -ENOMEM;
+   goto free_syncpts;
+   }
+
+   mw_sp = host1x_syncpt_request(>client, flags);
+   if (!mw_sp) {
+   dev_err(vi->dev, "failed to request memory ack 
syncpoint\n");
+   host1x_syncpt_put(fs_sp);
+   ret = -ENOMEM;
+   goto free_syncpts;
+   }
+
+   chan->frame_start_sp[i] = fs_sp;
+   chan->mw_ack_sp[i] = mw_sp;
+   spin_lock_init(>sp_incr_lock[i]);
+   }
+
+   return 0;
+
+free_syncpts:
+   for (i = 0; i < chan->numgangports; i++) {
+   host1x_syncpt_put(chan->mw_ack_sp[i]);
+   host1x_syncpt_put(chan->frame_start_sp[i]);
+   }
+   return ret;
+}
+
+static void tegra210_channel_host1x_syncpt_free(struct tegra_vi_channel *chan)
+{
+   int i;
+
+   for (i = 0; i < chan->numgangports; i++) {
+   host1x_syncpt_put(chan->mw_ack_sp[i]);
+   host1x_syncpt_put(chan->frame_start_sp[i]);
+   }
+}
+
 static void tegra210_fmt_align(struct v4l2_pix_format *pix, unsigned int bpp)
 {
unsigned int min_bpl;
@@ -758,6 +808,8 @@ static const struct tegra_video_format 
tegra210_video_formats[] = {
 
 /* Tegra210 VI operations */
 static const struct tegra_vi_ops tegra210_vi_ops = {
+   .channel_host1x_syncpt_init = tegra210_channel_host1x_syncpt_init,
+   .channel_host1x_syncpt_free = tegra210_channel_host1x_syncpt_free,
.vi_fmt_align = tegra210_fmt_align,
.vi_start_streaming = tegra210_vi_start_streaming,
.vi_stop_streaming = tegra210_vi_stop_streaming,
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 22f6d6478d3e..760606c65a97 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -973,21 +973,11 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
return 0;
 }
 
-static void tegra_channel_host1x_syncpts_free(struct tegra_vi_channel *chan)
-{
-   int i;
-
-   for (i = 0; i < chan->numgangports; i++) {
-   host1x_syncpt_put(chan->mw_ack_sp[i]);
-   host1x_syncpt_put(chan->frame_start_sp[i]);
-   }
-}
-
 static void tegra_channel_cleanup(struct tegra_vi_channel *chan)
 {
v4l2_ctrl_handler_free(>ctrl_handler);
media_entity_cleanup(>video.entity);
-   tegra_channel_host1x_syncpts_free(chan);
+   chan->vi->ops->channel_host1x_syncpt_free(chan);
mutex_destroy(>video_lock);
 }
 
@@ -1005,42 +995,6 @@ void tegra_channels_cleanup(struct tegra_vi *vi)
}
 }
 
-static int tegra_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
-{
-   struct tegra_vi *vi = chan->vi;
-   unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
-   struct host1x_syncpt *fs_sp;
-   struct host1x_syncpt *mw_sp;
-   int ret, i;
-
-   for (i = 0; i < chan->numgangports; i++) {
-   fs_sp = host1x_syncpt_request(>client, flags);
-   if (!fs_sp) {
-   dev_err(vi->dev, "failed to request frame start 
syncpoint\n");
-   ret = -ENOMEM;
-   goto free_syncpts;
-   }
-
-   mw_sp = host1x_syncpt_request(>client, flags);
-   if (!mw_sp) {
-   

[PATCH v3 01/21] dt-bindings: display: tegra: add Tegra20 VIP

2022-12-29 Thread Luca Ceresoli
VIP is the parallel video capture component within the video input
subsystem of Tegra20 (and other Tegra chips, apparently).

Signed-off-by: Luca Ceresoli 

---

Changed in v3:
 - remove channel@0 node (Krzysztof, Rob, Dmitry)
 - add myself as a maintainer of the whole Tegra video driver (Dmitry)

Changed in v2 (suggested by Krzysztof Kozlowski):
 - remove redundant "bindings" from subject line
 - remove $nodename
 - add channel@0 description
 - add reg: const: 0
---
 .../display/tegra/nvidia,tegra20-vip.yaml | 49 +++
 MAINTAINERS   |  2 +
 2 files changed, 51 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml

diff --git 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml
new file mode 100644
index ..c23fd02dd18e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-vip.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra VIP (parallel video capture) controller
+
+maintainers:
+  - Luca Ceresoli 
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra20-vip
+
+  "#address-cells":
+const: 1
+
+  "#size-cells":
+const: 0
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Port receiving the video stream from the sensor
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Port sending the video stream to the VI
+
+required:
+  - port@0
+  - port@1
+
+unevaluatedProperties: false
+
+required:
+  - compatible
+  - "#address-cells"
+  - "#size-cells"
+  - ports
+
+# see nvidia,tegra20-vi.yaml for an example
diff --git a/MAINTAINERS b/MAINTAINERS
index f61eb221415b..4feb2e1258ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20563,10 +20563,12 @@ TEGRA VIDEO DRIVER
 M: Thierry Reding 
 M: Jonathan Hunter 
 M: Sowjanya Komatineni 
+M: Luca Ceresoli 
 L: linux-me...@vger.kernel.org
 L: linux-te...@vger.kernel.org
 S: Maintained
 F: 
Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
+F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml
 F: drivers/staging/media/tegra-video/
 
 TEGRA XUSB PADCTL DRIVER
-- 
2.34.1



[PATCH v3 20/21] staging: media: tegra-video: add H/V flip controls

2022-12-29 Thread Luca Ceresoli
Tegra20 can do horizontal and vertical image flip, but Tegra210 cannot
(either the hardware, or this driver).

In preparation to adding Tegra20 support, add a flag in struct tegra_vi_soc
so the generic vi.c code knows whether the flip controls should be added or
not.

Also provide a generic implementation that simply sets two flags in the
channel struct. The Tegra20 implementation will enable flipping at stream
start based on those flags.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 14 +-
 drivers/staging/media/tegra-video/vi.h |  8 
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 4a066b61ab8e..d1c6877163c2 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -29,7 +29,7 @@
 #include "vi.h"
 #include "video.h"
 
-#define MAX_CID_CONTROLS   1
+#define MAX_CID_CONTROLS   3
 
 /**
  * struct tegra_vi_graph_entity - Entity in the video graph
@@ -893,6 +893,12 @@ static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY:
chan->syncpt_timeout_retry = ctrl->val;
break;
+   case V4L2_CID_HFLIP:
+   chan->hflip = ctrl->val;
+   break;
+   case V4L2_CID_VFLIP:
+   chan->vflip = ctrl->val;
+   break;
default:
return -EINVAL;
}
@@ -964,6 +970,12 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
v4l2_ctrl_handler_free(>ctrl_handler);
return ret;
}
+
+   if (chan->vi->soc->has_h_v_flip) {
+   v4l2_ctrl_new_std(>ctrl_handler, _ctrl_ops, 
V4L2_CID_HFLIP, 0, 1, 1, 0);
+   v4l2_ctrl_new_std(>ctrl_handler, _ctrl_ops, 
V4L2_CID_VFLIP, 0, 1, 1, 0);
+   }
+
 #endif
 
/* setup the controls */
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 0503eb678556..8fa817757059 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -74,6 +74,7 @@ struct tegra_vi_ops {
  * @hw_revision: VI hw_revision
  * @vi_max_channels: supported max streaming channels
  * @vi_max_clk_hz: VI clock max frequency
+ * @has_h_v_flip: the chip can do H adn V flip, and the driver implements it
  */
 struct tegra_vi_soc {
const struct tegra_video_format *video_formats;
@@ -83,6 +84,7 @@ struct tegra_vi_soc {
u32 hw_revision;
unsigned int vi_max_channels;
unsigned int vi_max_clk_hz;
+   bool has_h_v_flip:1;
 };
 
 /**
@@ -170,6 +172,9 @@ struct tegra_vi {
  * @syncpt_timeout_retry: syncpt timeout retry count for the capture
  * @pg_mode: test pattern generator mode (disabled/direct/patch)
  * @notifier: V4L2 asynchronous subdevs notifier
+ *
+ * @hflip: Horizontal flip is enabled
+ * @vflip: Vertical flip is enabled
  */
 struct tegra_vi_channel {
struct list_head list;
@@ -218,6 +223,9 @@ struct tegra_vi_channel {
enum tegra_vi_pg_mode pg_mode;
 
struct v4l2_async_notifier notifier;
+
+   bool hflip:1;
+   bool vflip:1;
 };
 
 /**
-- 
2.34.1



[PATCH v3 03/21] staging: media: tegra-video: fix .vidioc_enum_fmt_vid_cap to return all formats

2022-12-29 Thread Luca Ceresoli
The .vidioc_enum_fmt_vid_cap (called tegra_channel_enum_format() here)
should return all the supported formats. Instead the current implementation
computes the intersection between the formats it supports and those
supported by the first subdev in the stream (typically the image sensor).

Remove all the unnecessary logic that supports such algorithm. In order to
do this, also change the Tegra210 CSI TPG formats from the current
open-coded implementation in vi_tpg_fmts_bitmap_init() to a const array in
tegra210.c, just like the one that describes the regular formats.

Fixes: 3d8a97eabef0 ("media: tegra-video: Add Tegra210 Video input driver")
Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c |   7 +-
 drivers/staging/media/tegra-video/vi.c   | 103 +--
 drivers/staging/media/tegra-video/vi.h   |   4 -
 3 files changed, 9 insertions(+), 105 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index d58370a84737..eb19dd5107ce 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -683,8 +683,12 @@ enum tegra210_image_format {
V4L2_PIX_FMT_##FOURCC,  \
 }
 
-/* Tegra210 supported video formats */
 static const struct tegra_video_format tegra210_video_formats[] = {
+#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
+   /* VI only support 2 formats in TPG mode */
+   TEGRA210_VIDEO_FMT(RAW10,  10, SRGGB10_1X10,  2, T_R16_I,
SRGGB10),
+   TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8, 
RGBX32),
+#else
/* RAW 8 */
TEGRA210_VIDEO_FMT(RAW8, 8, SRGGB8_1X8, 1, T_L8, SRGGB8),
TEGRA210_VIDEO_FMT(RAW8, 8, SGRBG8_1X8, 1, T_L8, SGRBG8),
@@ -714,6 +718,7 @@ static const struct tegra_video_format 
tegra210_video_formats[] = {
TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_2X8, 2, T_V8_Y8__U8_Y8, YUYV),
TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_2X8, 2, T_Y8_U8__Y8_V8, VYUY),
TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_2X8, 2, T_Y8_V8__Y8_U8, UYVY),
+#endif
 };
 
 /* Tegra210 VI operations */
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 11dd142c98c5..9dba6e97ebdd 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2020 NVIDIA CORPORATION.  All rights reserved.
  */
 
-#include 
 #include 
 #include 
 #include 
@@ -73,15 +72,6 @@ static int tegra_get_format_idx_by_code(struct tegra_vi *vi,
return -1;
 }
 
-static u32 tegra_get_format_fourcc_by_idx(struct tegra_vi *vi,
- unsigned int index)
-{
-   if (index >= vi->soc->nformats)
-   return -EINVAL;
-
-   return vi->soc->video_formats[index].fourcc;
-}
-
 static const struct tegra_video_format *
 tegra_get_format_by_fourcc(struct tegra_vi *vi, u32 fourcc)
 {
@@ -430,19 +420,12 @@ static int tegra_channel_enum_format(struct file *file, 
void *fh,
 struct v4l2_fmtdesc *f)
 {
struct tegra_vi_channel *chan = video_drvdata(file);
-   unsigned int index = 0, i;
-   unsigned long *fmts_bitmap = chan->tpg_fmts_bitmap;
-
-   if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
-   fmts_bitmap = chan->fmts_bitmap;
+   const struct tegra_vi_soc *soc = chan->vi->soc;
 
-   if (f->index >= bitmap_weight(fmts_bitmap, MAX_FORMAT_NUM))
+   if (f->index >= soc->nformats)
return -EINVAL;
 
-   for (i = 0; i < f->index + 1; i++, index++)
-   index = find_next_bit(fmts_bitmap, MAX_FORMAT_NUM, index);
-
-   f->pixelformat = tegra_get_format_fourcc_by_idx(chan->vi, index - 1);
+   f->pixelformat = soc->video_formats[f->index].fourcc;
 
return 0;
 }
@@ -1059,78 +1042,6 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
return 0;
 }
 
-/* VI only support 2 formats in TPG mode */
-static void vi_tpg_fmts_bitmap_init(struct tegra_vi_channel *chan)
-{
-   int index;
-
-   bitmap_zero(chan->tpg_fmts_bitmap, MAX_FORMAT_NUM);
-
-   index = tegra_get_format_idx_by_code(chan->vi,
-MEDIA_BUS_FMT_SRGGB10_1X10, 0);
-   bitmap_set(chan->tpg_fmts_bitmap, index, 1);
-
-   index = tegra_get_format_idx_by_code(chan->vi,
-MEDIA_BUS_FMT_RGB888_1X32_PADHI,
-0);
-   bitmap_set(chan->tpg_fmts_bitmap, index, 1);
-}
-
-static int vi_fmts_bitmap_init(struct tegra_vi_channel *chan)
-{
-   int index, ret, match_code = 0;
-   struct v4l2_subdev *subdev;
-   struct v4l2_subdev_mbus_code_enum code = {
-   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
-   };
-
-   

[PATCH v3 16/21] staging: media: tegra-video: add a per-soc enable/disable op

2022-12-29 Thread Luca Ceresoli
The Tegra20 VI needs an additional operation to enable the VI, add an
operation for that.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 7 +++
 drivers/staging/media/tegra-video/vi.h | 4 
 2 files changed, 11 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index a26eb1ca869f..22f6d6478d3e 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1853,6 +1853,9 @@ static int tegra_vi_probe(struct platform_device *pdev)
vi->client.ops = _client_ops;
vi->client.dev = >dev;
 
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, true);
+
ret = host1x_client_register(>client);
if (ret < 0) {
dev_err(>dev,
@@ -1863,6 +1866,8 @@ static int tegra_vi_probe(struct platform_device *pdev)
return 0;
 
 rpm_disable:
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, false);
pm_runtime_disable(>dev);
return ret;
 }
@@ -1879,6 +1884,8 @@ static int tegra_vi_remove(struct platform_device *pdev)
return err;
}
 
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, false);
pm_runtime_disable(>dev);
 
return 0;
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 879547073371..851c4f3fcb91 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -37,8 +37,11 @@ enum tegra_vi_pg_mode {
TEGRA_VI_PG_PATCH,
 };
 
+struct tegra_vi;
+
 /**
  * struct tegra_vi_ops - Tegra VI operations
+ * @vi_enable: soc-specific operations needed to enable/disable the VI 
peripheral
  * @vi_fmt_align: modify `pix` to fit the hardware alignment
  * requirements and fill image geometry
  * @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
@@ -48,6 +51,7 @@ enum tegra_vi_pg_mode {
  * back any queued buffers.
  */
 struct tegra_vi_ops {
+   int (*vi_enable)(struct tegra_vi *vi, bool on);
void (*vi_fmt_align)(struct v4l2_pix_format *pix, unsigned int bpp);
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
void (*vi_stop_streaming)(struct vb2_queue *vq);
-- 
2.34.1



[PATCH v3 10/21] staging: media: tegra-video: move tegra210_csi_soc to C file

2022-12-29 Thread Luca Ceresoli
This declaration is used only in csi.c, no need to export it elsewhere.

Signed-off-by: Luca Ceresoli 

---

This patch was added in v3.
---
 drivers/staging/media/tegra-video/csi.c | 4 
 drivers/staging/media/tegra-video/csi.h | 4 
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/tegra-video/csi.c 
b/drivers/staging/media/tegra-video/csi.c
index 426e653bd55d..9a03d5ccdf3c 100644
--- a/drivers/staging/media/tegra-video/csi.c
+++ b/drivers/staging/media/tegra-video/csi.c
@@ -792,6 +792,10 @@ static int tegra_csi_remove(struct platform_device *pdev)
return 0;
 }
 
+#if defined(CONFIG_ARCH_TEGRA_210_SOC)
+extern const struct tegra_csi_soc tegra210_csi_soc;
+#endif
+
 static const struct of_device_id tegra_csi_of_id_table[] = {
 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
{ .compatible = "nvidia,tegra210-csi", .data = _csi_soc },
diff --git a/drivers/staging/media/tegra-video/csi.h 
b/drivers/staging/media/tegra-video/csi.h
index 6960ea2e3d36..3e6e5ee1bb1e 100644
--- a/drivers/staging/media/tegra-video/csi.h
+++ b/drivers/staging/media/tegra-video/csi.h
@@ -151,10 +151,6 @@ struct tegra_csi {
struct list_head csi_chans;
 };
 
-#if defined(CONFIG_ARCH_TEGRA_210_SOC)
-extern const struct tegra_csi_soc tegra210_csi_soc;
-#endif
-
 void tegra_csi_error_recover(struct v4l2_subdev *subdev);
 void tegra_csi_calc_settle_time(struct tegra_csi_channel *csi_chan,
u8 csi_port_num,
-- 
2.34.1



[PATCH v3 18/21] staging: media: tegra-video: add syncpts for Tegra20 to struct tegra_vi

2022-12-29 Thread Luca Ceresoli
In preparation to implement Tegra20 parallel video capture, add a variable
to hold the required syncpt and document all the syncpt variables.

Signed-off-by: Luca Ceresoli 

---

Changed in v3:
 - recycle mw_ack_sp[0] instead of adding out_sp

No changes in v2
---
 drivers/staging/media/tegra-video/vi.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 8fadca33bcc9..d5e1ed4217e0 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -117,11 +117,13 @@ struct tegra_vi {
  * @vi: Tegra video input device structure
  * @frame_start_sp: host1x syncpoint pointer to synchronize programmed capture
  * start condition with hardware frame start events through host1x
- * syncpoint counters.
+ * syncpoint counters. (Tegra210)
  * @mw_ack_sp: host1x syncpoint pointer to synchronize programmed memory write
  * ack trigger condition with hardware memory write done at end of
- * frame through host1x syncpoint counters.
+ * frame through host1x syncpoint counters (On Tegra20 used for the
+ *  OUT_1 syncpt)
  * @sp_incr_lock: protects cpu syncpoint increment.
+ * @next_out_sp_idx: next expected value for mw_ack_sp[0], i.e. OUT_1 (Tegra20)
  *
  * @kthread_start_capture: kthread to start capture of single frame when
  * vb buffer is available. This thread programs VI CSI hardware
@@ -173,6 +175,7 @@ struct tegra_vi_channel {
struct host1x_syncpt *mw_ack_sp[GANG_PORTS_MAX];
/* protects the cpu syncpoint increment */
spinlock_t sp_incr_lock[GANG_PORTS_MAX];
+   u32 next_out_sp_idx;
 
struct task_struct *kthread_start_capture;
wait_queue_head_t start_wait;
-- 
2.34.1



[PATCH v3 12/21] staging: media: tegra-video: Kconfig: allow TPG only on Tegra210

2022-12-29 Thread Luca Ceresoli
We are about to add support for the Tegra20 parallel video capture, which
has no TPG. In preparation for that, limit the VIDEO_TEGRA_TPG option to
Tegra210 which is the only implementation currently provided by this
driver.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/media/tegra-video/Kconfig 
b/drivers/staging/media/tegra-video/Kconfig
index df1b2cff2417..c53441822fdf 100644
--- a/drivers/staging/media/tegra-video/Kconfig
+++ b/drivers/staging/media/tegra-video/Kconfig
@@ -15,5 +15,6 @@ config VIDEO_TEGRA
 config VIDEO_TEGRA_TPG
bool "NVIDIA Tegra VI driver TPG mode"
depends on VIDEO_TEGRA
+   depends on ARCH_TEGRA_210_SOC
help
  Say yes here to enable Tegra internal TPG mode
-- 
2.34.1



[PATCH v3 06/21] staging: media: tegra-video: fix typos in comment

2022-12-29 Thread Luca Ceresoli
Add "skip" in "so we can *skip* the current channel" or it doesn't make
sense.

Also add articles where appropriate to fix English grammar.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 6aecdd28bd82..ae7adf640e76 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1762,10 +1762,10 @@ static int tegra_vi_graph_init(struct tegra_vi *vi)
 * Walk the links to parse the full graph. Each channel will have
 * one endpoint of the composite node. Start by parsing the
 * composite node and parse the remote entities in turn.
-* Each channel will register v4l2 async notifier to make the graph
-* independent between the channels so we can the current channel
+* Each channel will register a v4l2 async notifier to make the graph
+* independent between the channels so we can skip the current channel
 * in case of something wrong during graph parsing and continue with
-* next channels.
+* the next channels.
 */
list_for_each_entry(chan, >vi_chans, list) {
struct fwnode_handle *ep, *remote;
-- 
2.34.1



[PATCH v3 11/21] staging: media: tegra-video: remove unneeded include

2022-12-29 Thread Luca Ceresoli
There is only a pointer reference to struct tegra_vi in video.h, thus vi.h
is not needed.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/video.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/video.h 
b/drivers/staging/media/tegra-video/video.h
index fadaf2189dc9..1e9be1474a9c 100644
--- a/drivers/staging/media/tegra-video/video.h
+++ b/drivers/staging/media/tegra-video/video.h
@@ -12,7 +12,6 @@
 #include 
 
 #include "vi.h"
-#include "csi.h"
 
 struct tegra_video_device {
struct v4l2_device v4l2_dev;
-- 
2.34.1



[PATCH v3 08/21] staging: media: tegra-video: slightly simplify cleanup on errors

2022-12-29 Thread Luca Ceresoli
of_node_put(node) does nothing if node == NULL, so it can be moved to the
cleanup section at the bottom.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 0e5067a7986a..c2724e1ecafb 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1263,7 +1263,7 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
struct device_node *node = vi->dev->of_node;
struct device_node *ep = NULL;
struct device_node *ports;
-   struct device_node *port;
+   struct device_node *port = NULL;
unsigned int port_num;
struct device_node *parent;
struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
@@ -1286,7 +1286,6 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
dev_err(vi->dev, "invalid port num %d for %pOF\n",
port_num, port);
ret = -EINVAL;
-   of_node_put(port);
goto cleanup;
}
 
@@ -1309,13 +1308,12 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
 
lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
ret = tegra_vi_channel_alloc(vi, port_num, port, lanes);
-   if (ret < 0) {
-   of_node_put(port);
+   if (ret < 0)
goto cleanup;
-   }
}
 
 cleanup:
+   of_node_put(port);
of_node_put(ports);
return ret;
 }
-- 
2.34.1



[PATCH v3 09/21] staging: media: tegra-video: move private struct declaration to C file

2022-12-29 Thread Luca Ceresoli
struct tegra_vi_graph_entity is an internal implementation detail of the VI
module. Move its declaration from vi.h to vi.c.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 13 +
 drivers/staging/media/tegra-video/vi.h | 13 -
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index c2724e1ecafb..4e48eaa0fbdc 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -31,6 +31,19 @@
 
 #define MAX_CID_CONTROLS   1
 
+/**
+ * struct tegra_vi_graph_entity - Entity in the video graph
+ *
+ * @asd: subdev asynchronous registration information
+ * @entity: media entity from the corresponding V4L2 subdev
+ * @subdev: V4L2 subdev
+ */
+struct tegra_vi_graph_entity {
+   struct v4l2_async_subdev asd;
+   struct media_entity *entity;
+   struct v4l2_subdev *subdev;
+};
+
 static const struct tegra_video_format tegra_default_format = {
.img_dt = TEGRA_IMAGE_DT_RAW10,
.bit_width = 10,
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index dd35c3ac992b..dfd834a69848 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -98,19 +98,6 @@ struct tegra_vi {
struct list_head vi_chans;
 };
 
-/**
- * struct tegra_vi_graph_entity - Entity in the video graph
- *
- * @asd: subdev asynchronous registration information
- * @entity: media entity from the corresponding V4L2 subdev
- * @subdev: V4L2 subdev
- */
-struct tegra_vi_graph_entity {
-   struct v4l2_async_subdev asd;
-   struct media_entity *entity;
-   struct v4l2_subdev *subdev;
-};
-
 /**
  * struct tegra_vi_channel - Tegra video channel
  *
-- 
2.34.1



[PATCH v3 15/21] staging: media: tegra-video: move MIPI calibration calls from VI to CSI

2022-12-29 Thread Luca Ceresoli
The CSI module does not handle all the MIPI lane calibration procedure,
leaving a small part of it to the VI module. In doing this,
tegra_channel_enable_stream() (vi.c) manipulates the private data of the
upstream subdev casting it to struct 'tegra_csi_channel', which will be
wrong after introducing a VIP (parallel video input) channel.

This prevents adding support for the VIP module.  It also breaks the
logical isolation between modules.

Since the lane calibration requirement does not exist in the parallel input
module, moving the calibration function to a per-module op is not
optimal. Instead move the calibration procedure in the CSI module, together
with the rest of the calibration procedures. After this change,
tegra_channel_enable_stream() just calls v4l2_subdev_call() to ask for a
stream start/stop to the CSI module, which in turn knows all the
CSI-specific details to implement it.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/csi.c | 44 
 drivers/staging/media/tegra-video/vi.c  | 54 ++---
 2 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/drivers/staging/media/tegra-video/csi.c 
b/drivers/staging/media/tegra-video/csi.c
index 9a03d5ccdf3c..b93fc879ef3a 100644
--- a/drivers/staging/media/tegra-video/csi.c
+++ b/drivers/staging/media/tegra-video/csi.c
@@ -328,12 +328,42 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
*subdev)
}
 
csi_chan->pg_mode = chan->pg_mode;
+
+   /*
+* Tegra CSI receiver can detect the first LP to HS transition.
+* So, start the CSI stream-on prior to sensor stream-on and
+* vice-versa for stream-off.
+*/
ret = csi->ops->csi_start_streaming(csi_chan);
if (ret < 0)
goto finish_calibration;
 
+   if (csi_chan->mipi) {
+   struct v4l2_subdev *src_subdev;
+   /*
+* TRM has incorrectly documented to wait for done status from
+* calibration logic after CSI interface power on.
+* As per the design, calibration results are latched and 
applied
+* to the pads only when the link is in LP11 state which will 
happen
+* during the sensor stream-on.
+* CSI subdev stream-on triggers start of MIPI pads calibration.
+* Wait for calibration to finish here after sensor subdev 
stream-on.
+*/
+   src_subdev = tegra_channel_get_remote_source_subdev(chan);
+   ret = v4l2_subdev_call(src_subdev, video, s_stream, true);
+   err = tegra_mipi_finish_calibration(csi_chan->mipi);
+
+   if (ret < 0 && ret != -ENOIOCTLCMD)
+   goto disable_csi_stream;
+
+   if (err < 0)
+   dev_warn(csi->dev, "MIPI calibration failed: %d\n", 
err);
+   }
+
return 0;
 
+disable_csi_stream:
+   csi->ops->csi_stop_streaming(csi_chan);
 finish_calibration:
if (csi_chan->mipi)
tegra_mipi_finish_calibration(csi_chan->mipi);
@@ -352,10 +382,24 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
*subdev)
 
 static int tegra_csi_disable_stream(struct v4l2_subdev *subdev)
 {
+   struct tegra_vi_channel *chan = v4l2_get_subdev_hostdata(subdev);
struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
struct tegra_csi *csi = csi_chan->csi;
int err;
 
+   /*
+* Stream-off subdevices in reverse order to stream-on.
+* Remote source subdev in TPG mode is same as CSI subdev.
+*/
+   if (csi_chan->mipi) {
+   struct v4l2_subdev *src_subdev;
+
+   src_subdev = tegra_channel_get_remote_source_subdev(chan);
+   err = v4l2_subdev_call(src_subdev, video, s_stream, false);
+   if (err < 0 && err != -ENOIOCTLCMD)
+   dev_err_probe(csi->dev, err, "source subdev stream off 
failed\n");
+   }
+
csi->ops->csi_stop_streaming(csi_chan);
 
if (csi_chan->mipi) {
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 3762fd273514..a26eb1ca869f 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -187,49 +187,15 @@ tegra_channel_get_remote_source_subdev(struct 
tegra_vi_channel *chan)
 
 static int tegra_channel_enable_stream(struct tegra_vi_channel *chan)
 {
-   struct v4l2_subdev *csi_subdev, *src_subdev;
-   struct tegra_csi_channel *csi_chan;
-   int ret, err;
+   struct v4l2_subdev *subdev;
+   int ret;
 
-   /*
-* Tegra CSI receiver can detect the first LP to HS transition.
-* So, start the CSI stream-on prior to sensor stream-on and
-* vice-versa for stream-off.
-*/
-   csi_subdev = tegra_channel_get_remote_csi_subdev(chan);
-   ret = 

[PATCH v3 14/21] staging: media: tegra-video: move default format to soc-specific data

2022-12-29 Thread Luca Ceresoli
The tegra_default_format in vi.c is specific to Tegra210 CSI.

In preparation for adding Tegra20 VIP support, move the default format to a
new field in the soc-specific `struct tegra_vi_soc`. Instead of an entire
format struct, only store a pointer to an item in the existing format
array.

No functional changes. The format pointed to is the same that used to be in
vi.c.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c |  2 ++
 drivers/staging/media/tegra-video/vi.c   | 11 +--
 drivers/staging/media/tegra-video/vi.h   |  2 ++
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 71483d0c19bf..28d3d05c12c4 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -771,8 +771,10 @@ const struct tegra_vi_soc tegra210_vi_soc = {
.hw_revision = 3,
.vi_max_channels = 6,
 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
+   .default_video_format = _video_formats[0],
.vi_max_clk_hz = 49920,
 #else
+   .default_video_format = _video_formats[4],
.vi_max_clk_hz = 99840,
 #endif
 };
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index a76cad0e3026..3762fd273514 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -44,15 +44,6 @@ struct tegra_vi_graph_entity {
struct v4l2_subdev *subdev;
 };
 
-static const struct tegra_video_format tegra_default_format = {
-   .img_dt = TEGRA_IMAGE_DT_RAW10,
-   .bit_width = 10,
-   .code = MEDIA_BUS_FMT_SRGGB10_1X10,
-   .bpp = 2,
-   .img_fmt = TEGRA_IMAGE_FORMAT_DEF,
-   .fourcc = V4L2_PIX_FMT_SRGGB10,
-};
-
 static inline struct tegra_vi *
 host1x_client_to_vi(struct host1x_client *client)
 {
@@ -,7 +1102,7 @@ static int tegra_channel_init(struct tegra_vi_channel 
*chan)
init_waitqueue_head(>done_wait);
 
/* initialize the video format */
-   chan->fmtinfo = _default_format;
+   chan->fmtinfo = chan->vi->soc->default_video_format;
chan->format.pixelformat = chan->fmtinfo->fourcc;
chan->format.colorspace = V4L2_COLORSPACE_SRGB;
chan->format.field = V4L2_FIELD_NONE;
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 1021c730b595..879547073371 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -58,6 +58,7 @@ struct tegra_vi_ops {
  *
  * @video_formats: supported video formats
  * @nformats: total video formats
+ * @default_video_format: default video format (pointer to a @video_formats 
item)
  * @ops: vi operations
  * @hw_revision: VI hw_revision
  * @vi_max_channels: supported max streaming channels
@@ -66,6 +67,7 @@ struct tegra_vi_ops {
 struct tegra_vi_soc {
const struct tegra_video_format *video_formats;
const unsigned int nformats;
+   const struct tegra_video_format *default_video_format;
const struct tegra_vi_ops *ops;
u32 hw_revision;
unsigned int vi_max_channels;
-- 
2.34.1



[PATCH v3 07/21] staging: media: tegra-video: improve error messages

2022-12-29 Thread Luca Ceresoli
tegra_vi_channels_alloc() can primarily fail for two reasons:

 1. "ports" node not found
 2. port_num > vi->soc->vi_max_channels

Case 1 prints nothing, case 2 has a dev_err(). The caller [tegra_vi_init()]
has a generic dev_err() on any failure. This mean that in case 2 we print
two messages, and in case 1 we only print a generic message.

Remove the generic message and add a specific message when case 1 happens,
so that we always have one specific message without even increasing the
number of dev_dbg*() calls.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index ae7adf640e76..0e5067a7986a 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1272,7 +1272,7 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
 
ports = of_get_child_by_name(node, "ports");
if (!ports)
-   return -ENODEV;
+   return dev_err_probe(vi->dev, -ENODEV, "%pOF: missing 'ports' 
node\n", node);
 
for_each_child_of_node(ports, port) {
if (!of_node_name_eq(port, "port"))
@@ -1824,11 +1824,8 @@ static int tegra_vi_init(struct host1x_client *client)
ret = tegra_vi_tpg_channels_alloc(vi);
else
ret = tegra_vi_channels_alloc(vi);
-   if (ret < 0) {
-   dev_err(vi->dev,
-   "failed to allocate vi channels: %d\n", ret);
+   if (ret < 0)
goto free_chans;
-   }
 
ret = tegra_vi_channels_init(vi);
if (ret < 0)
-- 
2.34.1



[PATCH v3 13/21] staging: media: tegra-video: move tegra_channel_fmt_align to a per-soc op

2022-12-29 Thread Luca Ceresoli
tegra_channel_fmt_align() takes care of the size constraints, alignment and
rounding requirements of the Tegra210 VI peripheral. Tegra20 has different
constraints.

In preparation for adding Tegra20 support, move this function to a new op
in the soc-specific `struct tegra_vi_ops` .

Also move to tegra210.c the T210-specific defines used in the moved code.

No functional changes.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c | 36 ++
 drivers/staging/media/tegra-video/vi.c   | 40 +++-
 drivers/staging/media/tegra-video/vi.h   |  9 ++---
 3 files changed, 44 insertions(+), 41 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index eb19dd5107ce..71483d0c19bf 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -17,6 +17,13 @@
 #include "csi.h"
 #include "vi.h"
 
+#define TEGRA210_MIN_WIDTH 32U
+#define TEGRA210_MAX_WIDTH 32768U
+#define TEGRA210_MIN_HEIGHT32U
+#define TEGRA210_MAX_HEIGHT32768U
+
+#define SURFACE_ALIGN_BYTES64
+
 #define TEGRA_VI_SYNCPT_WAIT_TIMEOUT   msecs_to_jiffies(200)
 
 /* Tegra210 VI registers */
@@ -172,6 +179,34 @@ static u32 vi_csi_read(struct tegra_vi_channel *chan, u8 
portno,
 /*
  * Tegra210 VI channel capture operations
  */
+static void tegra210_fmt_align(struct v4l2_pix_format *pix, unsigned int bpp)
+{
+   unsigned int min_bpl;
+   unsigned int max_bpl;
+   unsigned int bpl;
+
+   /*
+* The transfer alignment requirements are expressed in bytes.
+* Clamp the requested width and height to the limits.
+*/
+   pix->width = clamp(pix->width, TEGRA210_MIN_WIDTH, TEGRA210_MAX_WIDTH);
+   pix->height = clamp(pix->height, TEGRA210_MIN_HEIGHT, 
TEGRA210_MAX_HEIGHT);
+
+   /* Clamp the requested bytes per line value. If the maximum bytes per
+* line value is zero, the module doesn't support user configurable
+* line sizes. Override the requested value with the minimum in that
+* case.
+*/
+   min_bpl = pix->width * bpp;
+   max_bpl = rounddown(TEGRA210_MAX_WIDTH, SURFACE_ALIGN_BYTES);
+   bpl = roundup(pix->bytesperline, SURFACE_ALIGN_BYTES);
+
+   pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
+   pix->sizeimage = pix->bytesperline * pix->height;
+   if (pix->pixelformat == V4L2_PIX_FMT_NV16)
+   pix->sizeimage *= 2;
+}
+
 static int tegra_channel_capture_setup(struct tegra_vi_channel *chan,
   u8 portno)
 {
@@ -723,6 +758,7 @@ static const struct tegra_video_format 
tegra210_video_formats[] = {
 
 /* Tegra210 VI operations */
 static const struct tegra_vi_ops tegra210_vi_ops = {
+   .vi_fmt_align = tegra210_fmt_align,
.vi_start_streaming = tegra210_vi_start_streaming,
.vi_stop_streaming = tegra210_vi_stop_streaming,
 };
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 4e48eaa0fbdc..a76cad0e3026 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -456,36 +456,6 @@ static int tegra_channel_get_format(struct file *file, 
void *fh,
return 0;
 }
 
-static void tegra_channel_fmt_align(struct tegra_vi_channel *chan,
-   struct v4l2_pix_format *pix,
-   unsigned int bpp)
-{
-   unsigned int min_bpl;
-   unsigned int max_bpl;
-   unsigned int bpl;
-
-   /*
-* The transfer alignment requirements are expressed in bytes.
-* Clamp the requested width and height to the limits.
-*/
-   pix->width = clamp(pix->width, TEGRA_MIN_WIDTH, TEGRA_MAX_WIDTH);
-   pix->height = clamp(pix->height, TEGRA_MIN_HEIGHT, TEGRA_MAX_HEIGHT);
-
-   /* Clamp the requested bytes per line value. If the maximum bytes per
-* line value is zero, the module doesn't support user configurable
-* line sizes. Override the requested value with the minimum in that
-* case.
-*/
-   min_bpl = pix->width * bpp;
-   max_bpl = rounddown(TEGRA_MAX_WIDTH, SURFACE_ALIGN_BYTES);
-   bpl = roundup(pix->bytesperline, SURFACE_ALIGN_BYTES);
-
-   pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
-   pix->sizeimage = pix->bytesperline * pix->height;
-   if (pix->pixelformat == V4L2_PIX_FMT_NV16)
-   pix->sizeimage *= 2;
-}
-
 static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
  struct v4l2_pix_format *pix)
 {
@@ -561,7 +531,7 @@ static int __tegra_channel_try_format(struct 
tegra_vi_channel *chan,
return ret;
 
v4l2_fill_pix_format(pix, );
-   tegra_channel_fmt_align(chan, pix, fmtinfo->bpp);
+   

[PATCH v3 19/21] staging: media: tegra-video: add hooks for planar YUV and H/V flip

2022-12-29 Thread Luca Ceresoli
Tegra20 supports planar YUV422 capture, which can be implemented by writing
U and V base address registers in addition to the "main" base buffer
address register.

It also supports H and V flip, which among others requires to write the
start address (i.e. the 1st offset to write, at the end of the buffer or
line) in more registers for Y and, for planar formats, U and V.

Add minimal hooks in VI to allow per-SoC optional support to those
features:

 - variables in struct tegra_vi for the U and V buffer base offsets
 - variables in struct tegra_vi for the Y, U and V buffer start offsets
 - an optional per-soc VI operation to compute those values on queue setup

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c |  4 
 drivers/staging/media/tegra-video/vi.h | 14 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 760606c65a97..4a066b61ab8e 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -92,6 +92,7 @@ tegra_get_format_by_fourcc(struct tegra_vi *vi, u32 fourcc)
 /*
  * videobuf2 queue operations
  */
+
 static int tegra_channel_queue_setup(struct vb2_queue *vq,
 unsigned int *nbuffers,
 unsigned int *nplanes,
@@ -107,6 +108,9 @@ static int tegra_channel_queue_setup(struct vb2_queue *vq,
sizes[0] = chan->format.sizeimage;
alloc_devs[0] = chan->vi->dev;
 
+   if (chan->vi->ops->channel_queue_setup)
+   chan->vi->ops->channel_queue_setup(chan);
+
return 0;
 }
 
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index d5e1ed4217e0..0503eb678556 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -47,6 +47,7 @@ struct tegra_vi_channel;
  * @channel_host1x_syncpt_free: free all synchronization points
  * @vi_fmt_align: modify `pix` to fit the hardware alignment
  * requirements and fill image geometry
+ * @channel_queue_setup: additional operations at the end of 
vb2_ops::queue_setup
  * @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
  * VI for capture and runs capture start and capture finish
  * kthreads for capturing frames to buffer and returns them back.
@@ -58,6 +59,7 @@ struct tegra_vi_ops {
int (*channel_host1x_syncpt_init)(struct tegra_vi_channel *chan);
void (*channel_host1x_syncpt_free)(struct tegra_vi_channel *chan);
void (*vi_fmt_align)(struct v4l2_pix_format *pix, unsigned int bpp);
+   void (*channel_queue_setup)(struct tegra_vi_channel *chan);
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
void (*vi_stop_streaming)(struct vb2_queue *vq);
 };
@@ -148,6 +150,12 @@ struct tegra_vi {
  * @queue: vb2 buffers queue
  * @sequence: V4L2 buffers sequence number
  *
+ * @addr_offset_u: U plane base address, relative to buffer base address (only 
for planar)
+ * @addr_offset_v: V plane base address, relative to buffer base address (only 
for planar)
+ * @start_offset:   1st Y byte to write, relative to buffer base address (for 
H/V flip)
+ * @start_offset_u: 1st U byte to write, relative to buffer base address (for 
H/V flip)
+ * @start_offset_v: 1st V byte to write, relative to buffer base address (for 
H/V flip)
+ *
  * @capture: list of queued buffers for capture
  * @start_lock: protects the capture queued list
  * @done: list of capture done queued buffers
@@ -187,6 +195,12 @@ struct tegra_vi_channel {
struct vb2_queue queue;
u32 sequence;
 
+   unsigned int addr_offset_u;
+   unsigned int addr_offset_v;
+   unsigned int start_offset;
+   unsigned int start_offset_u;
+   unsigned int start_offset_v;
+
struct list_head capture;
/* protects the capture queued list */
spinlock_t start_lock;
-- 
2.34.1



[PATCH v3 02/21] dt-bindings: display: tegra: vi: add 'vip' property and example

2022-12-29 Thread Luca Ceresoli
The Tegra20 VI peripheral can receive parallel input from the VIP parallel
input module. Add it to the allowed properties and augment the existing
nvidia,tegra20-vi example to show a 'vip' property.

Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Luca Ceresoli 

---

Changed in v3 (suggested by Rob Herring):
 - drop 'endpoint', unneeded as there's no extra properties in the
   endpoints

Changed in v2 (suggested by Krzysztof Kozlowski):
 - rename "i2c3" -> "ic2"
 - add review tag
---
 .../display/tegra/nvidia,tegra20-vi.yaml  | 64 +++
 MAINTAINERS   |  1 +
 2 files changed, 65 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
index 782a4b10150a..da9ce76e15ef 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
@@ -74,6 +74,18 @@ properties:
   avdd-dsi-csi-supply:
 description: DSI/CSI power supply. Must supply 1.2 V.
 
+  vip:
+$ref: /schemas/display/tegra/nvidia,tegra20-vip.yaml
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Input from the VIP (parallel input capture) module
+
 patternProperties:
   "^csi@[0-9a-f]+$":
 type: object
@@ -109,6 +121,22 @@ examples:
 #include 
 #include 
 
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+camera@48 {
+compatible = "aptina,mt9v111";
+reg = <0x48>;
+clocks = <_clk>;
+
+port {
+mt9v111_out: endpoint {
+remote-endpoint = <_vip_in>;
+};
+};
+};
+};
+
 vi@5408 {
 compatible = "nvidia,tegra20-vi";
 reg = <0x5408 0x0004>;
@@ -116,6 +144,42 @@ examples:
 clocks = <_car TEGRA20_CLK_VI>;
 resets = <_car 100>;
 reset-names = "vi";
+
+vip {
+compatible = "nvidia,tegra20-vip";
+#address-cells = <1>;
+#size-cells = <0>;
+channel@0 {
+reg = <0>;
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+port@0 {
+reg = <0>;
+vi_vip_in: endpoint {
+remote-endpoint = <_out>;
+};
+};
+port@1 {
+reg = <1>;
+vi_vip_out: endpoint {
+remote-endpoint = <_in>;
+};
+};
+};
+};
+};
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+port@0 {
+reg = <0>;
+vi_in: endpoint {
+remote-endpoint = <_vip_out>;
+};
+};
+};
 };
 
   - |
diff --git a/MAINTAINERS b/MAINTAINERS
index 4feb2e1258ce..dca1c47706f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20568,6 +20568,7 @@ L:  linux-me...@vger.kernel.org
 L: linux-te...@vger.kernel.org
 S: Maintained
 F: 
Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
+F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
 F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml
 F: drivers/staging/media/tegra-video/
 
-- 
2.34.1



[PATCH v3 04/21] staging: media: tegra-video: improve documentation of tegra_video_format fields

2022-12-29 Thread Luca Ceresoli
Some fields are irrelevant for Tegra20/VIP. Add a note to clarify that.

Signed-off-by: Luca Ceresoli 

---

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 183796c8a46a..dd35c3ac992b 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -256,11 +256,11 @@ enum tegra_image_dt {
 /**
  * struct tegra_video_format - Tegra video format description
  *
- * @img_dt: image data type
- * @bit_width: format width in bits per component
+ * @img_dt: MIPI CSI-2 data type (for CSI-2 only)
+ * @bit_width: format width in bits per component (for CSI/Tegra210 only)
  * @code: media bus format code
  * @bpp: bytes per pixel (when stored in memory)
- * @img_fmt: image format
+ * @img_fmt: image format (for CSI/Tegra210 only)
  * @fourcc: V4L2 pixel format FCC identifier
  */
 struct tegra_video_format {
-- 
2.34.1



[PATCH v3 00/21] Add Tegra20 parallel video input capture

2022-12-29 Thread Luca Ceresoli
Tegra20 and other Tegra SoCs have a video input (VI) peripheral that can
receive from either MIPI CSI-2 or parallel video (called respectively "CSI"
and "VIP" in the documentation). The kernel currently has a staging driver
for Tegra210 CSI capture. This patch set adds support for Tegra20 VIP
capture.

Unfortunately I had no real documentation available to base this work on.
I only had a working downstream 3.1 kernel, so I started with the driver
found there and heavily reworked it to fit into the mainline tegra-video
driver structure. The existing code appears written with the intent of
being modular and allow adding new input mechanisms and new SoCs while
keeping a unique VI core module. However its modularity and extensibility
was not enough to add Tegra20 VIP support, so I added some hooks to turn
hard-coded behaviour into per-SoC or per-bus customizable code. There are
also a fix, some generic cleanups and DT bindings.

Quick tour of the patches:

 * Device tree bindings and minor DTS improvements

   01. dt-bindings: display: tegra: add Tegra20 VIP
   02. dt-bindings: display: tegra: vi: add 'vip' property and example

 * A fix

   03. staging: media: tegra-video: fix .vidioc_enum_fmt_vid_cap to return all 
formats

 * Minor improvements to logging, comments, cleanups

   04. staging: media: tegra-video: improve documentation of tegra_video_format 
fields
   05. staging: media: tegra-video: document 
tegra_channel_get_remote_source_subdev
   06. staging: media: tegra-video: fix typos in comment
   07. staging: media: tegra-video: improve error messages
   08. staging: media: tegra-video: slightly simplify cleanup on errors
   09. staging: media: tegra-video: move private struct declaration to C file
   10. staging: media: tegra-video: move tegra210_csi_soc to C file
   11. staging: media: tegra-video: remove unneeded include

 * Preparation to make the VI module generic enough to host Tegra20 and VIP

   12. staging: media: tegra-video: Kconfig: allow TPG only on Tegra210
   13. staging: media: tegra-video: move tegra_channel_fmt_align to a per-soc op
   14. staging: media: tegra-video: move default format to soc-specific data
   15. staging: media: tegra-video: move MIPI calibration calls from VI to CSI
   16. staging: media: tegra-video: add a per-soc enable/disable op
   17. staging: media: tegra-video: move syncpt init/free to a per-soc op
   18. staging: media: tegra-video: add syncpts for Tegra20 to struct tegra_vi
   19. staging: media: tegra-video: add hooks for planar YUV and H/V flip
   20. staging: media: tegra-video: add H/V flip controls

 * Implementation of VIP and Tegra20

   21. staging: media: tegra-video: add support for Tegra20 parallel input

Enjoy!

Changed in v3:
- removed the 'channel@0' node from the device tree representation of vip
- squashed the last two patches (VIP + T20) into one
- small cleanups
- rebase on v6.2-rc1

Changed in v2:
- improved dt-bindings patches based on reviews
- removed patches 3 and 4 adding DT labels without a mainline user
- two small fixes to the last patch

[v2] https://lore.kernel.org/linux-tegra/20221222100328.6e341874@booty/T/#t
[v1] https://lore.kernel.org/linux-tegra/20221124155634.5bc2a423@booty/T/#t

Luca

Luca Ceresoli (21):
  dt-bindings: display: tegra: add Tegra20 VIP
  dt-bindings: display: tegra: vi: add 'vip' property and example
  staging: media: tegra-video: fix .vidioc_enum_fmt_vid_cap to return
all formats
  staging: media: tegra-video: improve documentation of
tegra_video_format fields
  staging: media: tegra-video: document
tegra_channel_get_remote_source_subdev
  staging: media: tegra-video: fix typos in comment
  staging: media: tegra-video: improve error messages
  staging: media: tegra-video: slightly simplify cleanup on errors
  staging: media: tegra-video: move private struct declaration to C file
  staging: media: tegra-video: move tegra210_csi_soc to C file
  staging: media: tegra-video: remove unneeded include
  staging: media: tegra-video: Kconfig: allow TPG only on Tegra210
  staging: media: tegra-video: move tegra_channel_fmt_align to a per-soc
op
  staging: media: tegra-video: move default format to soc-specific data
  staging: media: tegra-video: move MIPI calibration calls from VI to
CSI
  staging: media: tegra-video: add a per-soc enable/disable op
  staging: media: tegra-video: move syncpt init/free to a per-soc op
  staging: media: tegra-video: add syncpts for Tegra20 to struct
tegra_vi
  staging: media: tegra-video: add hooks for planar YUV and H/V flip
  staging: media: tegra-video: add H/V flip controls
  staging: media: tegra-video: add support for Tegra20 parallel input

 .../display/tegra/nvidia,tegra20-vi.yaml  |  64 ++
 .../display/tegra/nvidia,tegra20-vip.yaml |  49 ++
 MAINTAINERS   |   3 +
 drivers/staging/media/tegra-video/Kconfig |   1 +
 drivers/staging/media/tegra-video/Makefile|   2 +
 

[PATCH v3 1/1] dt-bindings: msm: dsi-phy-28nm: Add missing qcom, dsi-phy-regulator-ldo-mode

2022-12-29 Thread Bryan O'Donoghue
Add in missing qcom,dsi-phy-regulator-ldo-mode to the 28nm DSI PHY.
When converting from .txt to .yaml we missed this one.

Fixes: 4dbe55c97741 ("dt-bindings: msm: dsi: add yaml schemas for DSI bindings")
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Bryan O'Donoghue 
---
 .../devicetree/bindings/display/msm/dsi-phy-28nm.yaml | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml
index 3d8540a06fe22..2f1fd140c87df 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml
@@ -34,6 +34,10 @@ properties:
   vddio-supply:
 description: Phandle to vdd-io regulator device node.
 
+  qcom,dsi-phy-regulator-ldo-mode:
+type: boolean
+description: Indicates if the LDO mode PHY regulator is wanted.
+
 required:
   - compatible
   - reg
-- 
2.34.1



[PATCH v3 0/1] Fixup documentation for dsi-phy-28nm

2022-12-29 Thread Bryan O'Donoghue
V3:
Moves change to last item in list so as not to break-up grouping of 
reg/reg-names

V2:
This is the one remaining patch I had from a previous series for
mdss-dsi-ctrl and the dsi-phy. The mdss-dsi-ctrl set became a bigger so I
split out the 28nm phy fixes.

I'm resubmitting with Dmitry's RB as a standalone.

Old: 
https://lore.kernel.org/all/20220630120845.3356144-1-bryan.odonog...@linaro.org/

Bryan O'Donoghue (1):
  dt-bindings: msm: dsi-phy-28nm: Add missing
qcom,dsi-phy-regulator-ldo-mode

 .../devicetree/bindings/display/msm/dsi-phy-28nm.yaml | 4 
 1 file changed, 4 insertions(+)

-- 
2.34.1



Re: [PATCH 1/2] habanalabs/uapi: move uapi file to drm

2022-12-29 Thread Oded Gabbay
On Tue, Dec 27, 2022 at 8:29 PM Jeffrey Hugo  wrote:
>
> On 12/26/2022 2:32 PM, Oded Gabbay wrote:
> > Move the habanalabs.h uapi file from include/uapi/misc to
> > include/uapi/drm, and rename it to habanalabs_accel.h.
> >
> > This is required before moving the actual driver to the accel
> > subsystem.
> >
> > Update MAINTAINERS file accordingly.
> >
> > Signed-off-by: Oded Gabbay 
>
> This would impact the hl-thunk project at
> https://github.com/HabanaAI/hl-thunk as the open userspace, right?  I
> don't appear to see corresponding changes there.  Is there a dev branch
> I'm missing?
I will change it in a few weeks. The driver changes are only inside my
branch, I have time until the next merge cycle.
Oded
>
> -Jeff


Re: [PATCH v3 4/4] arm64: dts: rk3399-pinephone-pro: Add internal display support

2022-12-29 Thread Javier Martinez Canillas
Hello Tom,

On Thu, 29 Dec 2022 at 10:39 Tom Fitzhenry  wrote:

> On 27/12/22 22:03, Javier Martinez Canillas wrote:
> > From: Ondrej Jirman 
> >
> > The phone's display is using Hannstar LCD panel, and Goodix based
> > touchscreen. Support it.
> >
> > Signed-off-by: Ondrej Jirman 
> > Co-developed-by: Martijn Braam 
> > Signed-off-by: Martijn Braam 
> > Co-developed-by: Kamil Trzciński 
> > Signed-off-by: Kamil Trzciński 
> > Signed-off-by: Javier Martinez Canillas 
>
> Tested-by: Tom Fitzhenry 
>
> Display and touchscreen works on my Pinephone Pro, thanks for the
> mainlining!
>

Thanks for testing it!


> > @@ -367,6 +474,10 @@ vcc1v8_codec_en: vcc1v8-codec-en {
> >   };
> >   };
> >
> > + {
> > + status = "okay";
> > +};
>
> Please move  before , to keep this ~alphabetical.


Sure. I’ll do that in v4.

Best regards,
Javier


Re: [PATCH v3 1/4] dt-bindings: display: Add Himax HX8394 panel controller

2022-12-29 Thread Javier Martinez Canillas
Hello Jagan,

On Thu, 29 Dec 2022 at 10:54 Jagan Teki  wrote:

>
[…]


> > > compatible:
> > > items:
> > >   - enum:
> > >   - hannstar,hsd060bhw4
> > >   - const: himax,hx8394
> > >
> > > himax,hx8394 is the actual controller and is denoted as fallback
> compatible.
> > >
> >
> > I see. Do you have an example of a panel controller that does this? I
> > don't see that much value in doing this since you want the DTS to
> > describe the actual HW and so want the panel I believe.
>
> Yes, but the Panel needs to be built on top of the display IC so the
> actual parent here is the display IC and the panel is sub-HW.  This is
> what usually follows, here are some reference bindings.


I see. Thanks for these references.

I’ll adapt the driver and binding schema then according to this and post a
v4.

Best regards,
Javier


Re: [PATCH v2 2/3] arm64: dts: qcom: sm8150: Add DISPCC node

2022-12-29 Thread Dmitry Baryshkov
On Thu, 29 Dec 2022 at 12:05, Konrad Dybcio  wrote:
>
> Years after the SoC support has been added, it's high time for it to
> get dispcc going. Add the node to ensure that.
>
> Tested-by: Marijn Suijten  # Xperia 5
> Reviewed-by: Marijn Suijten 
> Signed-off-by: Konrad Dybcio 

Reviewed-by: Dmitry Baryshkov 


> ---
> v1 -> v2:
> - Pick up tags
> - Remove required-opps
> - Move power-domains up
>  arch/arm64/boot/dts/qcom/sm8150.dtsi | 23 +++
>  1 file changed, 23 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi 
> b/arch/arm64/boot/dts/qcom/sm8150.dtsi
> index a0c57fb798d3..c7935f7a2926 100644
> --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
> @@ -3579,6 +3579,29 @@ camnoc_virt: interconnect@ac0 {
> qcom,bcm-voters = <_bcm_voter>;
> };
>
> +   dispcc: clock-controller@af0 {
> +   compatible = "qcom,sm8150-dispcc";
> +   reg = <0 0x0af0 0 0x1>;
> +   clocks = < RPMH_CXO_CLK>,
> +<0>,
> +<0>,
> +<0>,
> +<0>,
> +<0>,
> +<0>;
> +   clock-names = "bi_tcxo",
> + "dsi0_phy_pll_out_byteclk",
> + "dsi0_phy_pll_out_dsiclk",
> + "dsi1_phy_pll_out_byteclk",
> + "dsi1_phy_pll_out_dsiclk",
> + "dp_phy_pll_link_clk",
> + "dp_phy_pll_vco_div_clk";
> +   power-domains = < SM8150_MMCX>;
> +   #clock-cells = <1>;
> +   #reset-cells = <1>;
> +   #power-domain-cells = <1>;
> +   };
> +
> pdc: interrupt-controller@b22 {
> compatible = "qcom,sm8150-pdc", "qcom,pdc";
> reg = <0 0x0b22 0 0x400>;
> --
> 2.39.0
>


-- 
With best wishes
Dmitry


[PATCH v2] arch: rename all internal names __xchg to __arch_xchg

2022-12-29 Thread Andrzej Hajda
__xchg will be used for non-atomic xchg macro.

Signed-off-by: Andrzej Hajda 
Reviewed-by: Arnd Bergmann 
---
 arch/alpha/include/asm/cmpxchg.h | 6 +++---
 arch/arc/include/asm/cmpxchg.h   | 4 ++--
 arch/arm/include/asm/cmpxchg.h   | 4 ++--
 arch/arm64/include/asm/cmpxchg.h | 4 ++--
 arch/hexagon/include/asm/cmpxchg.h   | 6 +++---
 arch/ia64/include/asm/cmpxchg.h  | 2 +-
 arch/ia64/include/uapi/asm/cmpxchg.h | 4 ++--
 arch/loongarch/include/asm/cmpxchg.h | 4 ++--
 arch/m68k/include/asm/cmpxchg.h  | 6 +++---
 arch/mips/include/asm/cmpxchg.h  | 4 ++--
 arch/openrisc/include/asm/cmpxchg.h  | 4 ++--
 arch/parisc/include/asm/cmpxchg.h| 4 ++--
 arch/powerpc/include/asm/cmpxchg.h   | 4 ++--
 arch/riscv/include/asm/atomic.h  | 2 +-
 arch/riscv/include/asm/cmpxchg.h | 4 ++--
 arch/s390/include/asm/cmpxchg.h  | 4 ++--
 arch/sh/include/asm/cmpxchg.h| 4 ++--
 arch/sparc/include/asm/cmpxchg_32.h  | 4 ++--
 arch/sparc/include/asm/cmpxchg_64.h  | 4 ++--
 arch/xtensa/include/asm/cmpxchg.h| 4 ++--
 20 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/arch/alpha/include/asm/cmpxchg.h b/arch/alpha/include/asm/cmpxchg.h
index 6e0a850aa9d38c..40e8159ef6e794 100644
--- a/arch/alpha/include/asm/cmpxchg.h
+++ b/arch/alpha/include/asm/cmpxchg.h
@@ -6,7 +6,7 @@
  * Atomic exchange routines.
  */
 
-#define xchg(type, args...)__xchg ## type ## _local(args)
+#define xchg(type, args...)__arch_xchg ## type ## 
_local(args)
 #define cmpxchg(type, args...) __cmpxchg ## type ## _local(args)
 #include 
 
@@ -34,7 +34,7 @@
 
 #undef xchg
 #undef cmpxchg
-#define xchg(type, args...)__xchg ##type(args)
+#define xchg(type, args...)__arch_xchg ##type(args)
 #define cmpxchg(type, args...) __cmpxchg ##type(args)
 #include 
 
@@ -48,7 +48,7 @@
__typeof__(*(ptr)) _x_ = (x);   \
smp_mb();   \
__ret = (__typeof__(*(ptr)))\
-   __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr)));  \
+   __arch_xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
smp_mb();   \
__ret;  \
 })
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index c5b544a5fe8106..e138fde067dea5 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -85,7 +85,7 @@
  */
 #ifdef CONFIG_ARC_HAS_LLSC
 
-#define __xchg(ptr, val)   \
+#define __arch_xchg(ptr, val)  \
 ({ \
__asm__ __volatile__(   \
"   ex  %0, [%1]\n" /* set new value */ \
@@ -102,7 +102,7 @@
\
switch(sizeof(*(_p_))) {\
case 4: \
-   _val_ = __xchg(_p_, _val_); \
+   _val_ = __arch_xchg(_p_, _val_);\
break;  \
default:\
BUILD_BUG();\
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
index 4dfe538dfc689b..6953fc05a97886 100644
--- a/arch/arm/include/asm/cmpxchg.h
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -25,7 +25,7 @@
 #define swp_is_buggy
 #endif
 
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int 
size)
+static inline unsigned long __arch_xchg(unsigned long x, volatile void *ptr, 
int size)
 {
extern void __bad_xchg(volatile void *, int);
unsigned long ret;
@@ -115,7 +115,7 @@ static inline unsigned long __xchg(unsigned long x, 
volatile void *ptr, int size
 }
 
 #define arch_xchg_relaxed(ptr, x) ({   \
-   (__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr),   \
+   (__typeof__(*(ptr)))__arch_xchg((unsigned long)(x), (ptr),  
\
   sizeof(*(ptr))); \
 })
 
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index 497acf134d9923..3a36ba58e8c2ef 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -62,7 +62,7 @@ __XCHG_CASE( ,  ,  mb_, 64, dmb ish, nop,  , a, l, "memory")
 #undef __XCHG_CASE
 
 #define __XCHG_GEN(sfx)
\
-static __always_inline  unsigned 

Re: [PATCH] drm/msm/adreno: Make adreno quirks not overwrite each other

2022-12-29 Thread Marijn Suijten
On 2022-12-29 11:18:45, Konrad Dybcio wrote:
> So far the adreno quirks have all been assigned with an OR operator,
> which is problematic, because they were assigned consecutive integer
> values, which makes checking them with an AND operator kind of no bueno..
> 
> Switch to using BIT(n) so that only the quirks that the programmer chose
> are taken into account when evaluating info->quirks & ADRENO_QUIRK_...
> 
> Fixes: b5f103ab98c7 ("drm/msm: gpu: Add A5XX target support")
> Signed-off-by: Konrad Dybcio 

Nice catch!

Reviewed-by: Marijn Suijten 

Not sure if it's the right Fixes commit though, as it would have worked
when ADRENO_QUIRK_LMLOADKILL_DISABLE was added with constant 4 instead
of 3 in 370063ee427a ("drm/msm/adreno: Add A540 support"), but then
using bitflags in an enum value type is invalid anyway, AFAIK.

- Marijn

> ---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h 
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> index c85857c0a228..5eb254c9832a 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> @@ -29,11 +29,9 @@ enum {
>   ADRENO_FW_MAX,
>  };
>  
> -enum adreno_quirks {
> - ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
> - ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
> - ADRENO_QUIRK_LMLOADKILL_DISABLE = 3,
> -};
> +#define ADRENO_QUIRK_TWO_PASS_USE_WFIBIT(0)
> +#define ADRENO_QUIRK_FAULT_DETECT_MASK   BIT(1)
> +#define ADRENO_QUIRK_LMLOADKILL_DISABLE  BIT(2)
>  
>  struct adreno_rev {
>   uint8_t  core;
> @@ -65,7 +63,7 @@ struct adreno_info {
>   const char *name;
>   const char *fw[ADRENO_FW_MAX];
>   uint32_t gmem;
> - enum adreno_quirks quirks;
> + u64 quirks;
>   struct msm_gpu *(*init)(struct drm_device *dev);
>   const char *zapfw;
>   u32 inactive_period;
> -- 
> 2.39.0
> 


[PATCH] drm/msm/adreno: Make adreno quirks not overwrite each other

2022-12-29 Thread Konrad Dybcio
So far the adreno quirks have all been assigned with an OR operator,
which is problematic, because they were assigned consecutive integer
values, which makes checking them with an AND operator kind of no bueno..

Switch to using BIT(n) so that only the quirks that the programmer chose
are taken into account when evaluating info->quirks & ADRENO_QUIRK_...

Fixes: b5f103ab98c7 ("drm/msm: gpu: Add A5XX target support")
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index c85857c0a228..5eb254c9832a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -29,11 +29,9 @@ enum {
ADRENO_FW_MAX,
 };
 
-enum adreno_quirks {
-   ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
-   ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
-   ADRENO_QUIRK_LMLOADKILL_DISABLE = 3,
-};
+#define ADRENO_QUIRK_TWO_PASS_USE_WFI  BIT(0)
+#define ADRENO_QUIRK_FAULT_DETECT_MASK BIT(1)
+#define ADRENO_QUIRK_LMLOADKILL_DISABLEBIT(2)
 
 struct adreno_rev {
uint8_t  core;
@@ -65,7 +63,7 @@ struct adreno_info {
const char *name;
const char *fw[ADRENO_FW_MAX];
uint32_t gmem;
-   enum adreno_quirks quirks;
+   u64 quirks;
struct msm_gpu *(*init)(struct drm_device *dev);
const char *zapfw;
u32 inactive_period;
-- 
2.39.0



Re: [PATCH v1] drm/scheduler: Fix lockup in drm_sched_entity_kill()

2022-12-29 Thread Dmitry Osipenko
Hi,

On 12/27/22 22:28, Guilherme G. Piccoli wrote:
> Hi Dmitry / Christian, thanks for the fix!
> 
> (And thanks Melissa for pointing that, saving me lots of time in
> research heh)
> 
> Is this fix planned to be released on 6.2-rc cycle? I've just tested it
> on Steam Deck, and it resolved a lockup observed (since v6.2-rc1) -
> exactly the same thing mentioned in the commit message.
> 
> FWIW:
> Tested-By: Guilherme G. Piccoli  # Steam Deck
I'll push the patch to misc-fixes as soon as it will be rebased on
6.2-rc. Thanks!

Best regards,
Dmitry



[PATCH v2 2/3] arm64: dts: qcom: sm8150: Add DISPCC node

2022-12-29 Thread Konrad Dybcio
Years after the SoC support has been added, it's high time for it to
get dispcc going. Add the node to ensure that.

Tested-by: Marijn Suijten  # Xperia 5
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
v1 -> v2:
- Pick up tags
- Remove required-opps
- Move power-domains up
 arch/arm64/boot/dts/qcom/sm8150.dtsi | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi 
b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index a0c57fb798d3..c7935f7a2926 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -3579,6 +3579,29 @@ camnoc_virt: interconnect@ac0 {
qcom,bcm-voters = <_bcm_voter>;
};
 
+   dispcc: clock-controller@af0 {
+   compatible = "qcom,sm8150-dispcc";
+   reg = <0 0x0af0 0 0x1>;
+   clocks = < RPMH_CXO_CLK>,
+<0>,
+<0>,
+<0>,
+<0>,
+<0>,
+<0>;
+   clock-names = "bi_tcxo",
+ "dsi0_phy_pll_out_byteclk",
+ "dsi0_phy_pll_out_dsiclk",
+ "dsi1_phy_pll_out_byteclk",
+ "dsi1_phy_pll_out_dsiclk",
+ "dp_phy_pll_link_clk",
+ "dp_phy_pll_vco_div_clk";
+   power-domains = < SM8150_MMCX>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   #power-domain-cells = <1>;
+   };
+
pdc: interrupt-controller@b22 {
compatible = "qcom,sm8150-pdc", "qcom,pdc";
reg = <0 0x0b22 0 0x400>;
-- 
2.39.0



[PATCH v2 3/3] arm64: dts: qcom: sm8150: Wire up MDSS

2022-12-29 Thread Konrad Dybcio
Add required nodes for MDSS and hook up provided clocks in DISPCC.
This setup is almost identical to 8[23]50.

Tested-by: Marijn Suijten  # Xperia 5
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
v1 -> v2:
- Pick up tags
- mdss@ -> display-subsystem@

 arch/arm64/boot/dts/qcom/sm8150.dtsi | 271 ++-
 1 file changed, 267 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi 
b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index c7935f7a2926..f7721ec37b03 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -3579,14 +3580,276 @@ camnoc_virt: interconnect@ac0 {
qcom,bcm-voters = <_bcm_voter>;
};
 
+   mdss: display-subsystem@ae0 {
+   compatible = "qcom,sm8150-mdss";
+   reg = <0 0x0ae0 0 0x1000>;
+   reg-names = "mdss";
+
+   interconnects = <_noc MASTER_MDP_PORT0 _virt 
SLAVE_EBI_CH0>,
+   <_noc MASTER_MDP_PORT1 _virt 
SLAVE_EBI_CH0>;
+   interconnect-names = "mdp0-mem", "mdp1-mem";
+
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < DISP_CC_MDSS_AHB_CLK>,
+< GCC_DISP_HF_AXI_CLK>,
+< GCC_DISP_SF_AXI_CLK>,
+< DISP_CC_MDSS_MDP_CLK>;
+   clock-names = "iface", "bus", "nrt_bus", "core";
+
+   interrupts = ;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   iommus = <_smmu 0x800 0x420>;
+
+   status = "disabled";
+
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+
+   mdss_mdp: display-controller@ae01000 {
+   compatible = "qcom,sm8150-dpu";
+   reg = <0 0x0ae01000 0 0x8f000>,
+ <0 0x0aeb 0 0x2008>;
+   reg-names = "mdp", "vbif";
+
+   clocks = < DISP_CC_MDSS_AHB_CLK>,
+< GCC_DISP_HF_AXI_CLK>,
+< DISP_CC_MDSS_MDP_CLK>,
+< DISP_CC_MDSS_VSYNC_CLK>;
+   clock-names = "iface", "bus", "core", "vsync";
+
+   assigned-clocks = < 
DISP_CC_MDSS_VSYNC_CLK>;
+   assigned-clock-rates = <1920>;
+
+   operating-points-v2 = <_opp_table>;
+   power-domains = < SM8150_MMCX>;
+
+   interrupt-parent = <>;
+   interrupts = <0>;
+
+   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>;
+   };
+   };
+   };
+
+   mdp_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-171428571 {
+   opp-hz = /bits/ 64 <171428571>;
+   required-opps = 
<_opp_low_svs>;
+   };
+
+   opp-3 {
+   opp-hz = /bits/ 64 <3>;
+   required-opps = 
<_opp_svs>;
+   };
+
+   opp-34500 {
+   opp-hz = /bits/ 64 <34500>;
+   required-opps = 
<_opp_svs_l1>;
+   };
+
+   opp-46000 {
+   

[PATCH v2 1/3] dt-bindings: display/msm: Add SM8150 MDSS & DPU

2022-12-29 Thread Konrad Dybcio
Add bindings for the display hardware on SM8150.

Reviewed-by: Rob Herring 
Signed-off-by: Konrad Dybcio 
---
v1 -> v2:
- Pick up tags

 .../bindings/display/msm/qcom,sm8150-dpu.yaml |  92 +
 .../display/msm/qcom,sm8150-mdss.yaml | 330 ++
 2 files changed, 422 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/msm/qcom,sm8150-dpu.yaml
 create mode 100644 
Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml

diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8150-dpu.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sm8150-dpu.yaml
new file mode 100644
index ..2b3f3fe9bdf7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8150-dpu.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/qcom,sm8150-dpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8150 Display DPU
+
+maintainers:
+  - Dmitry Baryshkov 
+
+$ref: /schemas/display/msm/dpu-common.yaml#
+
+properties:
+  compatible:
+const: qcom,sm8150-dpu
+
+  reg:
+items:
+  - description: Address offset and size for mdp register set
+  - description: Address offset and size for vbif register set
+
+  reg-names:
+items:
+  - const: mdp
+  - const: vbif
+
+  clocks:
+items:
+  - description: Display ahb clock
+  - description: Display hf axi clock
+  - description: Display core clock
+  - description: Display vsync clock
+
+  clock-names:
+items:
+  - const: iface
+  - const: bus
+  - const: core
+  - const: vsync
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+#include 
+#include 
+
+display-controller@ae01000 {
+compatible = "qcom,sm8150-dpu";
+reg = <0x0ae01000 0x8f000>,
+  <0x0aeb 0x2008>;
+reg-names = "mdp", "vbif";
+
+clocks = < DISP_CC_MDSS_AHB_CLK>,
+ < GCC_DISP_HF_AXI_CLK>,
+ < DISP_CC_MDSS_MDP_CLK>,
+ < DISP_CC_MDSS_VSYNC_CLK>;
+clock-names = "iface", "bus", "core", "vsync";
+
+assigned-clocks = < DISP_CC_MDSS_VSYNC_CLK>;
+assigned-clock-rates = <1920>;
+
+operating-points-v2 = <_opp_table>;
+power-domains = < SM8150_MMCX>;
+
+interrupt-parent = <>;
+interrupts = <0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+endpoint {
+remote-endpoint = <_in>;
+};
+};
+
+port@1 {
+reg = <1>;
+endpoint {
+remote-endpoint = <_in>;
+};
+};
+};
+};
+...
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml
new file mode 100644
index ..55b41e4573dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml
@@ -0,0 +1,330 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/qcom,sm8150-mdss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8150 Display MDSS
+
+maintainers:
+  - Dmitry Baryshkov 
+
+description:
+  Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
+  sub-blocks like DPU display controller, DSI and DP interfaces etc. Device 
tree
+  bindings of MDSS are mentioned for SM8150 target.
+
+$ref: /schemas/display/msm/mdss-common.yaml#
+
+properties:
+  compatible:
+items:
+  - const: qcom,sm8150-mdss
+
+  clocks:
+items:
+  - description: Display AHB clock from gcc
+  - description: Display hf axi clock
+  - description: Display sf axi clock
+  - description: Display core clock
+
+  clock-names:
+items:
+  - const: iface
+  - const: bus
+  - const: nrt_bus
+  - const: core
+
+  iommus:
+maxItems: 1
+
+  interconnects:
+maxItems: 2
+
+  interconnect-names:
+maxItems: 2
+
+patternProperties:
+  "^display-controller@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+const: qcom,sm8150-dpu
+
+  "^dsi@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+const: qcom,mdss-dsi-ctrl
+
+  "^phy@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+const: qcom,dsi-phy-7nm
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+display-subsystem@ae0 {
+compatible = "qcom,sm8150-mdss";
+reg = <0x0ae0 0x1000>;
+reg-names = "mdss";
+
+interconnects = <_noc 

[drm-misc:drm-misc-next 25/26] drivers/gpu/drm/bridge/panel.c:367 devm_drm_panel_bridge_add_typed() error: 'bridge' dereferencing possible ERR_PTR()

2022-12-29 Thread Dan Carpenter
tree:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
head:   941aae3263153cea91cb306cc889951486e16634
commit: 5ea6b17027810ffbdb5bea7d0a2b1d312dd1021c [25/26] drm/panel: Add 
prepare_prev_first flag to drm_panel
config: nios2-randconfig-m041-20221228
compiler: nios2-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 
| Reported-by: Dan Carpenter 

smatch warnings:
drivers/gpu/drm/bridge/panel.c:367 devm_drm_panel_bridge_add_typed() error: 
'bridge' dereferencing possible ERR_PTR()

vim +/bridge +367 drivers/gpu/drm/bridge/panel.c

89958b7cd9555a Laurent Pinchart 2019-09-04  348  struct drm_bridge 
*devm_drm_panel_bridge_add_typed(struct device *dev,
6707ffb1f5 Eric Anholt  2017-07-18  349 
   struct drm_panel *panel,
6707ffb1f5 Eric Anholt  2017-07-18  350 
   u32 connector_type)
6707ffb1f5 Eric Anholt  2017-07-18  351  {
6707ffb1f5 Eric Anholt  2017-07-18  352 struct drm_bridge 
**ptr, *bridge;
6707ffb1f5 Eric Anholt  2017-07-18  353  
6707ffb1f5 Eric Anholt  2017-07-18  354 ptr = 
devres_alloc(devm_drm_panel_bridge_release, sizeof(*ptr),
6707ffb1f5 Eric Anholt  2017-07-18  355
GFP_KERNEL);
6707ffb1f5 Eric Anholt  2017-07-18  356 if (!ptr)
6707ffb1f5 Eric Anholt  2017-07-18  357 return 
ERR_PTR(-ENOMEM);
6707ffb1f5 Eric Anholt  2017-07-18  358  
89958b7cd9555a Laurent Pinchart 2019-09-04  359 bridge = 
drm_panel_bridge_add_typed(panel, connector_type);
6707ffb1f5 Eric Anholt  2017-07-18  360 if (!IS_ERR(bridge)) {
6707ffb1f5 Eric Anholt  2017-07-18  361 *ptr = bridge;
6707ffb1f5 Eric Anholt  2017-07-18  362 devres_add(dev, 
ptr);
6707ffb1f5 Eric Anholt  2017-07-18  363 } else {
6707ffb1f5 Eric Anholt  2017-07-18  364 
devres_free(ptr);

return -ENOMEM;

6707ffb1f5 Eric Anholt  2017-07-18  365 }
6707ffb1f5 Eric Anholt  2017-07-18  366  
5ea6b17027810f Dave Stevenson   2022-12-05 @367 
bridge->pre_enable_prev_first = panel->prepare_prev_first;
^^

5ea6b17027810f Dave Stevenson   2022-12-05  368  
6707ffb1f5 Eric Anholt  2017-07-18  369 return bridge;
6707ffb1f5 Eric Anholt  2017-07-18  370  }

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp



Re: [PATCH 00/19] Introduce __xchg, non-atomic xchg

2022-12-29 Thread Andrzej Hajda

Forgive me late response - Holidays,

On 22.12.2022 18:21, Andrew Morton wrote:

On Thu, 22 Dec 2022 12:46:16 +0100 Andrzej Hajda  
wrote:


Hi all,

I hope there will be place for such tiny helper in kernel.
Quick cocci analyze shows there is probably few thousands places
where it could be useful.

So to clarify, the intent here is a simple readability cleanup for
existing open-coded exchange operations.


And replace private helpers with common one, see the last patch - the 
ultimate goal

would be to replace all occurrences of fetch_and_zero with __xchg.


The intent is *not* to
identify existing xchg() sites which are unnecessarily atomic and to
optimize them by using the non-atomic version.

Have you considered the latter?


If you mean some way of (semi-)automatic detection of such cases, then 
no. Anyway this could be quite interesting challenge.





I am not sure who is good person to review/ack such patches,

I can take 'em.


so I've used my intuition to construct to/cc lists, sorry for mistakes.
This is the 2nd approach of the same idea, with comments addressed[0].

The helper is tiny and there are advices we can leave without it, so
I want to present few arguments why it would be good to have it:

1. Code readability/simplification/number of lines:

Real example from drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c:
-   previous_min_rate = evport->qos.min_rate;
-   evport->qos.min_rate = min_rate;
+   previous_min_rate = __xchg(evport->qos.min_rate, min_rate);

For sure the code is more compact, and IMHO more readable.

2. Presence of similar helpers in other somehow related languages/libs:

a) Rust[1]: 'replace' from std::mem module, there is also 'take'
 helper (__xchg(, 0)), which is the same as private helper in
 i915 - fetch_and_zero, see latest patch.
b) C++ [2]: 'exchange' from utility header.

If the idea is OK there are still 2 qestions to answer:

1. Name of the helper, __xchg follows kernel conventions,
 but for me Rust names are also OK.

I like replace(), or, shockingly, exchange().

But...   Can we simply make swap() return the previous value?

previous_min_rate = swap(>qos.min_rate, min_rate);


As Alexander already pointed out, swap requires 'references' to two 
variables,

in contrast to xchg which requires reference to variable and value.
So we cannot use swap for cases:
    old_value = __xchg(, new_value);

Regards
Andrzej



Re: [PATCH v3 1/4] dt-bindings: display: Add Himax HX8394 panel controller

2022-12-29 Thread Jagan Teki
On Wed, Dec 28, 2022 at 3:46 AM Javier Martinez Canillas
 wrote:
>
> On Tue, Dec 27, 2022 at 8:37 PM Jagan Teki  wrote:
> >
> > On Wed, Dec 28, 2022 at 12:58 AM Javier Martinez Canillas
> >  wrote:
> > >
> > > Hello Jagan,
> > >
> > > On Tue, Dec 27, 2022 at 7:16 PM Jagan Teki  
> > > wrote:
> > >
> > > [...]
> > >
> > > > > +allOf:
> > > > > +  - $ref: panel-common.yaml#
> > > > > +
> > > > > +properties:
> > > > > +  compatible:
> > > > > +enum:
> > > > > +  # HannStar HSD060BHW4 5.99" 720x1440 TFT LCD panel
> > > > > +  - hannstar,hsd060bhw4
> > > >
> > > > Parent controller can have a compatible where the associated panels
> > > > will be enum list.
> > > >
> > >
> > > I'm not sure to follow what you meant. Could you please elaborate?
> >
> > compatible:
> > items:
> >   - enum:
> >   - hannstar,hsd060bhw4
> >   - const: himax,hx8394
> >
> > himax,hx8394 is the actual controller and is denoted as fallback compatible.
> >
>
> I see. Do you have an example of a panel controller that does this? I
> don't see that much value in doing this since you want the DTS to
> describe the actual HW and so want the panel I believe.

Yes, but the Panel needs to be built on top of the display IC so the
actual parent here is the display IC and the panel is sub-HW.  This is
what usually follows, here are some reference bindings.

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml

Jagan.


Re: WARNING: CPU: 2 PID: 42 at drivers/gpu/drm/drm_modeset_lock.c:276

2022-12-29 Thread Maíra Canal

On 12/29/22 05:37, Maxime Ripard wrote:

On Wed, Dec 28, 2022 at 11:16:11PM +0100, Stefan Wahren wrote:

Hi Maíra,

Am 28.12.22 um 20:49 schrieb Maíra Canal:

Hi Stefan,

I was able to reproduce this error on drm-misc-next. I bisected,
and I got into commit 6bed2ea3cb38. I noticed that the crtc->mutex is
being locked twice, and this might be causing the problem. I wrote a
patch to try to fix this issue, and after applying the patch, I wasn't
able to reproduce the error anymore.

Let me know if you were able to reproduce the warning after applying
this patch.


the patch works as expected and avoid the warning. I tested it on top of
v6.1 with RPi 3 B+ and RPi 4 B.

In case you send the patch please add the Fixes tag so the patch get
backported to stable.


This isn't a proper fix, we do need to take the crtc mutex: it protects
the crtc->state pointer we dereference next, and vc4_hdmi_reset_link can
be called outside of a modeset through the interrupt handler.


Do you suggest calling drm_modeset_unlock after dereferencing crtc->state?

Best Regards,
- Maíra Canal



Maxime


Re: [PATCH 02/19] arch/arc: rename internal name __xchg to __arch_xchg

2022-12-29 Thread Arnd Bergmann
On Thu, Dec 22, 2022, at 12:46, Andrzej Hajda wrote:
> __xchg will be used for non-atomic xchg macro.
>
> Signed-off-by: Andrzej Hajda 
> ---
>  arch/arc/include/asm/cmpxchg.h | 4 ++--

Reviewed-by: Arnd Bergmann 

for all the arch/*/include/asm/cmpxchg.h changes.

Since these patches are all the same, and they have identical
subject and description texts, I would suggest combining them
into a single patch to keep the series more compact.

Having them separate would allow merging the patches through
the individual architecture maintainer trees, but that in turn
would mean waiting longer to get it all merged, but in this
case it seems way easier to go through the asm-generic
tree.

 Arnd


[PATCH] drm/bridge: sii902x: Allow reset line to be tied to a sleepy GPIO controller

2022-12-29 Thread Wadim Egorov
Switch to gpiod_set_value_cansleep() in sii902x_reset().
This is relevant if the reset line is tied to a I2C GPIO
controller.

Signed-off-by: Wadim Egorov 
---
 drivers/gpu/drm/bridge/sii902x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 878fb7d3732b..980611aec2f6 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -240,12 +240,12 @@ static void sii902x_reset(struct sii902x *sii902x)
if (!sii902x->reset_gpio)
return;
 
-   gpiod_set_value(sii902x->reset_gpio, 1);
+   gpiod_set_value_cansleep(sii902x->reset_gpio, 1);
 
/* The datasheet says treset-min = 100us. Make it 150us to be sure. */
usleep_range(150, 200);
 
-   gpiod_set_value(sii902x->reset_gpio, 0);
+   gpiod_set_value_cansleep(sii902x->reset_gpio, 0);
 }
 
 static enum drm_connector_status sii902x_detect(struct sii902x *sii902x)
-- 
2.34.1



  1   2   >