RE: [PATCH v5 3/3] drm/bridge/analogix/anx78xx: Drop conditionals around of_node pointers

2023-08-30 Thread Biju Das
Hi Laurent,

Thanks for the feedback.

> Subject: Re: [PATCH v5 3/3] drm/bridge/analogix/anx78xx: Drop conditionals
> around of_node pointers
> 
> Hi Biju,
> 
> Thank you for the patch.
> 
> On Wed, Aug 30, 2023 at 06:08:19PM +0100, Biju Das wrote:
> > Having conditional around the of_node pointers turns out to make
> > driver code use ugly #ifdef and #if blocks. So drop the conditionals.
> 
> How about doing this for all bridge drivers in one go ?

I will send separate patch for that one later.

Will send V6 with changes suggested for patch#2 first and then will investigate 
creating patch for dropping conditionals for remaining bridge drivers.

Cheers,
Biju

> 
> > Suggested-by: Douglas Anderson 
> > Signed-off-by: Biju Das 
> > ---
> > v5:
> >  * Split from patch#2
> > ---
> >  drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 2 --
> >  1 file changed, 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> > b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> > index 6169db73d2fe..ad8241758896 100644
> > --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> > +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> > @@ -1231,9 +1231,7 @@ static int anx78xx_i2c_probe(struct i2c_client
> > *client)
> >
> > mutex_init(&anx78xx->lock);
> >
> > -#if IS_ENABLED(CONFIG_OF)
> > anx78xx->bridge.of_node = client->dev.of_node; -#endif
> >
> > anx78xx->client = client;
> > i2c_set_clientdata(client, anx78xx);
> 
> --
> Regards,
> 
> Laurent Pinchart


Re: [PATCH] fbdev: Update fbdev source file paths

2023-08-30 Thread Jonathan Neuschäfer
On Wed, Aug 30, 2023 at 09:10:26AM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 29.08.23 um 22:02 schrieb Jonathan Neuschäfer:
> > The files fbmem.c, fb_defio.c, fbsysfs.c, fbmon.c, modedb.c, and
> > fbcmap.c were moved to drivers/video/fbdev, and subsequently to
> > drivers/video/fbdev/core, in the commits listed below.
> > 
> > Reported by kalekale in #kernel (Libera IRC).
> > 
> > Fixes: f7018c213502 ("video: move fbdev to drivers/video/fbdev")
> > Fixes: 19757fc8432a ("fbdev: move fbdev core files to separate directory")
> > Signed-off-by: Jonathan Neuschäfer 
> 
> IMHO these comments might just be removed.

I think it's nice to have some sort of visual separation between groups
of functions in fb.h, which these comments provide at the moment.
Therefore I'm currently leaning towards my patch as it is, but I'm
willing to have my mind changed and do a v2 which just removes the
comments.


Thanks

> 
> Best regards
> Thomas
> 
> > ---
> >   include/linux/fb.h | 12 ++--
> >   1 file changed, 6 insertions(+), 6 deletions(-)
> > 
> > diff --git a/include/linux/fb.h b/include/linux/fb.h
> > index ce7d588edc3e6..3cda5b9f2469b 100644
> > --- a/include/linux/fb.h
> > +++ b/include/linux/fb.h
> > @@ -592,7 +592,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const 
> > char __user *buf,
> > __FB_DEFAULT_SYS_OPS_DRAW, \
> > __FB_DEFAULT_SYS_OPS_MMAP
> > 
> > -/* drivers/video/fbmem.c */
> > +/* drivers/video/fbdev/core/fbmem.c */
> >   extern int register_framebuffer(struct fb_info *fb_info);
> >   extern void unregister_framebuffer(struct fb_info *fb_info);
> >   extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);


signature.asc
Description: PGP signature


Re: [PATCH] drm/tegra: Remove existing framebuffer only if we support display

2023-08-30 Thread Mikko Perttunen

On 8/30/23 13:19, Thomas Zimmermann wrote:

Hi

Am 25.08.23 um 15:22 schrieb Thierry Reding:

From: Thierry Reding 

Tegra DRM doesn't support display on Tegra234 and later, so make sure
not to remove any existing framebuffers in that case.

Signed-off-by: Thierry Reding 
---
  drivers/gpu/drm/tegra/drm.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index b1e1a78e30c6..7a38dadbc264 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1220,9 +1220,11 @@ static int host1x_drm_probe(struct 
host1x_device *dev)

  drm_mode_config_reset(drm);
-    err = drm_aperture_remove_framebuffers(&tegra_drm_driver);
-    if (err < 0)
-    goto hub;
+    if (drm->mode_config.num_crtc > 0) {


If you don't support the hardware, wouldn't it be better to return 
-ENODEV if !num_crtc?


While display is not supported through TegraDRM on Tegra234+, certain 
multimedia accelerators are supported, so we need to finish probe for those.


Cheers,
Mikko



Best regards
Thomas


+    err = drm_aperture_remove_framebuffers(&tegra_drm_driver);
+    if (err < 0)
+    goto hub;
+    }
  err = drm_dev_register(drm, 0);
  if (err < 0)






Re: [PATCH v2 2/2] drm/amdgpu: Create an option to disable soft recovery

2023-08-30 Thread Christian König

Am 31.08.23 um 00:08 schrieb André Almeida:

Create a module option to disable soft recoveries on amdgpu, making
every recovery go through the device reset path. This option makes
easier to force device resets for testing and debugging purposes.

Signed-off-by: André Almeida 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu.h  | 1 +
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 6 ++
  drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 6 +-
  drivers/gpu/drm/amd/include/amd_shared.h | 1 +
  4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 82eaccfce347..5f49e2c0ae7a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1105,6 +1105,7 @@ struct amdgpu_device {
/* Debug */
booldebug_vm;
booldebug_largebar;
+   booldebug_disable_soft_recovery;
  };
  
  static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 0cd48c025433..59e9fe594b51 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -927,6 +927,7 @@ MODULE_PARM_DESC(enforce_isolation, "enforce process 
isolation between graphics
   * - 0x2: Enable simulating large-bar capability on non-large bar system. This
   *   limits the VRAM size reported to ROCm applications to the visible
   *   size, usually 256MB.
+ * - 0x4: Disable GPU soft recovery


"Disable GPU soft recovery, always do a full reset."

Apart from that Reviewed-by: Christian König .

Regards,
Christian.


   */
  MODULE_PARM_DESC(debug_mask, "debug options for amdgpu, disabled by default");
  module_param_named(debug_mask, amdgpu_debug_mask, uint, 0444);
@@ -2046,6 +2047,11 @@ static void amdgpu_init_debug_options(struct 
amdgpu_device *adev)
pr_info("debug: enabled simulating large-bar capability on non-large 
bar system\n");
adev->debug_largebar = true;
}
+
+   if (amdgpu_debug_mask & AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY) {
+   pr_info("debug: soft reset for GPU recovery disabled\n");
+   adev->debug_disable_soft_recovery = true;
+   }
  }
  
  static int amdgpu_pci_probe(struct pci_dev *pdev,

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 80d6e132e409..6a80d3ec887e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -434,8 +434,12 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, 
unsigned int vmid,
   struct dma_fence *fence)
  {
unsigned long flags;
+   ktime_t deadline;
  
-	ktime_t deadline = ktime_add_us(ktime_get(), 1);

+   if (unlikely(ring->adev->debug_disable_soft_recovery))
+   return false;
+
+   deadline = ktime_add_us(ktime_get(), 1);
  
  	if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)

return false;
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h 
b/drivers/gpu/drm/amd/include/amd_shared.h
index 2fd6af2183cc..32ee982be99e 100644
--- a/drivers/gpu/drm/amd/include/amd_shared.h
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
@@ -263,6 +263,7 @@ enum amd_dpm_forced_level;
  enum AMDGPU_DEBUG_MASK {
AMDGPU_DEBUG_VM = BIT(0),
AMDGPU_DEBUG_LARGEBAR = BIT(1),
+   AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY = BIT(2),
  };
  
  /**




Re: [PATCH v2 1/2] drm/amdgpu: Merge debug module parameters

2023-08-30 Thread Christian König




Am 31.08.23 um 00:08 schrieb André Almeida:

Merge all developer debug options available as separated module
parameters in one, making it obvious that are for developers.

Drop the obsolete module options in favor of the new ones.

Signed-off-by: André Almeida 
---
v2:
- drop old module params
- use BIT() macros
- replace global var with adev-> vars
---
  drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  4 ++
  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 48 ++--
  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c  |  2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c   |  2 +-
  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |  2 +-
  drivers/gpu/drm/amd/amdkfd/kfd_crat.c|  2 +-
  drivers/gpu/drm/amd/include/amd_shared.h |  8 
  8 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 4de074243c4d..82eaccfce347 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1101,6 +1101,10 @@ struct amdgpu_device {
booldc_enabled;
/* Mask of active clusters */
uint32_taid_mask;
+
+   /* Debug */
+   booldebug_vm;
+   booldebug_largebar;
  };
  
  static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index fb78a8f47587..8a26bed76505 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1191,7 +1191,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
job->vm_pd_addr = amdgpu_gmc_pd_addr(vm->root.bo);
}
  
-	if (amdgpu_vm_debug) {

+   if (adev->debug_vm) {
/* Invalidate all BOs to test for userspace bugs */
amdgpu_bo_list_for_each_entry(e, p->bo_list) {
struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index f5856b82605e..0cd48c025433 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -140,7 +140,6 @@ int amdgpu_vm_size = -1;
  int amdgpu_vm_fragment_size = -1;
  int amdgpu_vm_block_size = -1;
  int amdgpu_vm_fault_stop;
-int amdgpu_vm_debug;
  int amdgpu_vm_update_mode = -1;
  int amdgpu_exp_hw_support;
  int amdgpu_dc = -1;
@@ -194,6 +193,7 @@ int amdgpu_use_xgmi_p2p = 1;
  int amdgpu_vcnfw_log;
  int amdgpu_sg_display = -1; /* auto */
  int amdgpu_user_partt_mode = AMDGPU_AUTO_COMPUTE_PARTITION_MODE;
+uint amdgpu_debug_mask;
  
  static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
  
@@ -405,13 +405,6 @@ module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444);

  MODULE_PARM_DESC(vm_fault_stop, "Stop on VM fault (0 = never (default), 1 = print 
first, 2 = always)");
  module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444);
  
-/**

- * DOC: vm_debug (int)
- * Debug VM handling (0 = disabled, 1 = enabled). The default is 0 (Disabled).
- */
-MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = 
enabled)");
-module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
-
  /**
   * DOC: vm_update_mode (int)
   * Override VM update mode. VM updated by using CPU (0 = never, 1 = Graphics 
only, 2 = Compute only, 3 = Both). The default
@@ -743,18 +736,6 @@ module_param(send_sigterm, int, 0444);
  MODULE_PARM_DESC(send_sigterm,
"Send sigterm to HSA process on unhandled exception (0 = disable, 1 = 
enable)");
  
-/**

- * DOC: debug_largebar (int)
- * Set debug_largebar as 1 to enable simulating large-bar capability on 
non-large bar
- * system. This limits the VRAM size reported to ROCm applications to the 
visible
- * size, usually 256MB.
- * Default value is 0, diabled.
- */
-int debug_largebar;
-module_param(debug_largebar, int, 0444);
-MODULE_PARM_DESC(debug_largebar,
-   "Debug large-bar flag used to simulate large-bar capability on non-large bar 
machine (0 = disable, 1 = enable)");
-
  /**
   * DOC: halt_if_hws_hang (int)
   * Halt if HWS hang is detected. Default value, 0, disables the halt on hang.
@@ -938,6 +919,18 @@ module_param_named(user_partt_mode, 
amdgpu_user_partt_mode, uint, 0444);
  module_param(enforce_isolation, bool, 0444);
  MODULE_PARM_DESC(enforce_isolation, "enforce process isolation between graphics 
and compute . enforce_isolation = on");
  
+/**

+ * DOC: debug_mask (uint)
+ * Debug options for amdgpu, work as a binary mask with the following options:
+ *
+ * - 0x1: Debug VM handling
+ * - 0x2: Enable simulating large-bar capability on non-large bar system. This
+ *   limits the VRAM size reported to ROCm applications to the visible
+ *   size, usually 256MB.
+ */
+MODULE_PARM_DESC(debug_mask, 

[V11 8/8] drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.7

2023-08-30 Thread Evan Quan
Fulfill the SMU13.0.7 support for Wifi RFI mitigation feature.

Signed-off-by: Evan Quan 
Reviewed-by: Mario Limonciello 
--
v10->v11:
  - downgrade the prompt level on message failure(Lijo)
---
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c  | 59 +++
 1 file changed, 59 insertions(+)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index 62f2886ab4df..d1a93f961e9e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -126,6 +126,7 @@ static struct cmn2asic_msg_mapping 
smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] =
MSG_MAP(AllowGpo,   PPSMC_MSG_SetGpoAllow,  
 0),
MSG_MAP(GetPptLimit,PPSMC_MSG_GetPptLimit,  
   0),
MSG_MAP(NotifyPowerSource,  PPSMC_MSG_NotifyPowerSource,
   0),
+   MSG_MAP(EnableUCLKShadow,   PPSMC_MSG_EnableUCLKShadow, 
   0),
 };
 
 static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
@@ -207,6 +208,7 @@ static struct cmn2asic_mapping 
smu_v13_0_7_table_map[SMU_TABLE_COUNT] = {
TAB_MAP(ACTIVITY_MONITOR_COEFF),
[SMU_TABLE_COMBO_PPTABLE] = {1, TABLE_COMBO_PPTABLE},
TAB_MAP(OVERDRIVE),
+   TAB_MAP(WIFIBAND),
 };
 
 static struct cmn2asic_mapping smu_v13_0_7_pwr_src_map[SMU_POWER_SOURCE_COUNT] 
= {
@@ -503,6 +505,9 @@ static int smu_v13_0_7_tables_init(struct smu_context *smu)
   AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_COMBO_PPTABLE, 
MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE,
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
+   SMU_TABLE_INIT(tables, SMU_TABLE_WIFIBAND,
+  sizeof(WifiBandEntryTable_t), PAGE_SIZE,
+  AMDGPU_GEM_DOMAIN_VRAM);
 
smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), 
GFP_KERNEL);
if (!smu_table->metrics_table)
@@ -2179,6 +2184,57 @@ static int smu_v13_0_7_set_df_cstate(struct smu_context 
*smu,
   NULL);
 }
 
+static bool smu_v13_0_7_wbrf_support_check(struct smu_context *smu)
+{
+   return smu->smc_fw_version > 0x00524600;
+}
+
+static int smu_v13_0_7_set_wbrf_exclusion_ranges(struct smu_context *smu,
+struct exclusion_range 
*exclusion_ranges)
+{
+   WifiBandEntryTable_t wifi_bands;
+   int valid_entries = 0;
+   int ret, i;
+
+   memset(&wifi_bands, 0, sizeof(wifi_bands));
+   for (i = 0; i < ARRAY_SIZE(wifi_bands.WifiBandEntry); i++) {
+   if (!exclusion_ranges[i].start &&
+   !exclusion_ranges[i].end)
+   break;
+
+   /* PMFW expects the inputs to be in Mhz unit */
+   wifi_bands.WifiBandEntry[valid_entries].LowFreq =
+   DIV_ROUND_DOWN_ULL(exclusion_ranges[i].start, 
HZ_IN_MHZ);
+   wifi_bands.WifiBandEntry[valid_entries++].HighFreq =
+   DIV_ROUND_UP_ULL(exclusion_ranges[i].end, HZ_IN_MHZ);
+   }
+   wifi_bands.WifiBandEntryNum = valid_entries;
+
+   /*
+* Per confirm with PMFW team, WifiBandEntryNum = 0 is a valid setting.
+* Considering the scenarios below:
+* - At first the wifi device adds an exclusion range e.g. (2400,2500) 
to
+*   BIOS and our driver gets notified. We will set WifiBandEntryNum = 1
+*   and pass the WifiBandEntry (2400, 2500) to PMFW.
+*
+* - Later the wifi device removes the wifiband list added above and
+*   our driver gets notified again. At this time, driver will set
+*   WifiBandEntryNum = 0 and pass an empty WifiBandEntry list to PMFW.
+*   - PMFW may still need to do some uclk shadow update(e.g. switching
+* from shadow clock back to primary clock) on receiving this.
+*/
+
+   ret = smu_cmn_update_table(smu,
+  SMU_TABLE_WIFIBAND,
+  0,
+  (void *)(&wifi_bands),
+  true);
+   if (ret)
+   dev_warn(smu->adev->dev, "Failed to set wifiband!");
+
+   return ret;
+}
+
 static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
.get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask,
.set_default_dpm_table = smu_v13_0_7_set_default_dpm_table,
@@ -2247,6 +2303,9 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = 
{
.set_mp1_state = smu_v13_0_7_set_mp1_state,
.set_df_cstate = smu_v13_0_7_set_df_cstate,
.gpo_control = smu_v13_0_gpo_control,
+   .is_asic_wbrf_supported = smu_v13_0_7_wbrf_support_check,
+   .enable_uclk_shadow = smu_v13_0_enable_uclk_shadow,
+   .set_wbrf_exclusion_ranges = smu_v13_0_7_set_wbrf_exclusion

[V11 7/8] drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.0

2023-08-30 Thread Evan Quan
Fulfill the SMU13.0.0 support for Wifi RFI mitigation feature.

Signed-off-by: Evan Quan 
Reviewed-by: Mario Limonciello 
--
v10->v11:
  - downgrade the prompt level on message failure(Lijo)
---
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  3 +
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h  |  3 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h  |  3 +
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c|  9 +++
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  | 60 +++
 5 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 60d595344c45..a081e6bb27c4 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -325,6 +325,7 @@ enum smu_table_id
SMU_TABLE_PACE,
SMU_TABLE_ECCINFO,
SMU_TABLE_COMBO_PPTABLE,
+   SMU_TABLE_WIFIBAND,
SMU_TABLE_COUNT,
 };
 
@@ -1501,6 +1502,8 @@ enum smu_baco_seq {
 __dst_size);  \
 })
 
+#define HZ_IN_MHZ  100U
+
 #if !defined(SWSMU_CODE_LAYER_L2) && !defined(SWSMU_CODE_LAYER_L3) && 
!defined(SWSMU_CODE_LAYER_L4)
 int smu_get_power_limit(void *handle,
uint32_t *limit,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
index 297b70b9388f..5bbb60289a79 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
@@ -245,7 +245,8 @@
__SMU_DUMMY_MAP(AllowGpo),  \
__SMU_DUMMY_MAP(Mode2Reset),\
__SMU_DUMMY_MAP(RequestI2cTransaction), \
-   __SMU_DUMMY_MAP(GetMetricsTable),
+   __SMU_DUMMY_MAP(GetMetricsTable), \
+   __SMU_DUMMY_MAP(EnableUCLKShadow),
 
 #undef __SMU_DUMMY_MAP
 #define __SMU_DUMMY_MAP(type)  SMU_MSG_##type
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
index 355c156d871a..dd70b56aa71e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
@@ -299,5 +299,8 @@ int smu_v13_0_update_pcie_parameters(struct smu_context 
*smu,
 uint32_t pcie_gen_cap,
 uint32_t pcie_width_cap);
 
+int smu_v13_0_enable_uclk_shadow(struct smu_context *smu,
+bool enablement);
+
 #endif
 #endif
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 9b62b45ebb7f..6a5cb582aa92 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
@@ -2472,3 +2472,12 @@ int smu_v13_0_update_pcie_parameters(struct smu_context 
*smu,
 
return 0;
 }
+
+int smu_v13_0_enable_uclk_shadow(struct smu_context *smu,
+bool enablement)
+{
+   return smu_cmn_send_smc_msg_with_param(smu,
+  SMU_MSG_EnableUCLKShadow,
+  enablement,
+  NULL);
+}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index fddcd834bcec..5a7a5804794a 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -154,6 +154,7 @@ static struct cmn2asic_msg_mapping 
smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] =
MSG_MAP(AllowGpo,   PPSMC_MSG_SetGpoAllow,  
 0),
MSG_MAP(AllowIHHostInterrupt,   PPSMC_MSG_AllowIHHostInterrupt, 
  0),
MSG_MAP(ReenableAcDcInterrupt,  
PPSMC_MSG_ReenableAcDcInterrupt,   0),
+   MSG_MAP(EnableUCLKShadow,   PPSMC_MSG_EnableUCLKShadow, 
   0),
 };
 
 static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
@@ -237,6 +238,7 @@ static struct cmn2asic_mapping 
smu_v13_0_0_table_map[SMU_TABLE_COUNT] = {
TAB_MAP(I2C_COMMANDS),
TAB_MAP(ECCINFO),
TAB_MAP(OVERDRIVE),
+   TAB_MAP(WIFIBAND),
 };
 
 static struct cmn2asic_mapping smu_v13_0_0_pwr_src_map[SMU_POWER_SOURCE_COUNT] 
= {
@@ -492,6 +494,9 @@ static int smu_v13_0_0_tables_init(struct smu_context *smu)
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
+   SMU_TABLE_INIT(tables, SMU_TABLE_WIFIBAND,
+  sizeof(WifiBandEntryTable_t), PAGE_SIZE,
+  AMDGPU_GEM_DOMAIN_VRAM);
 
smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), 
GFP_KERNEL);
if (!smu_table->metrics_table)
@@ -2603,6 +2608,58 @@ static ssize_t smu_v13_0_0_get_ecc_info(struct 
smu_context *smu,

[V11 5/8] drm/amd/pm: setup the framework to support Wifi RFI mitigation feature

2023-08-30 Thread Evan Quan
With WBRF feature supported, as a driver responding to the frequencies,
amdgpu driver is able to do shadow pstate switching to mitigate possible
interference(between its (G-)DDR memory clocks and local radio module
frequency bands used by Wifi 6/6e/7).

Signed-off-by: Evan Quan 
Reviewed-by: Mario Limonciello 
--
v1->v2:
  - update the prompt for feature support(Lijo)
v8->v9:
  - update parameter document for smu_wbrf_event_handler(Simon)
v9->v10:
v10->v11:
 - correct the logics for wbrf range sorting(Lijo)
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  17 ++
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 195 ++
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  23 +++
 drivers/gpu/drm/amd/pm/swsmu/smu_internal.h   |   3 +
 5 files changed, 240 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 97cb56c791f3..47595b892c1f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -246,6 +246,8 @@ extern int amdgpu_sg_display;
 
 extern int amdgpu_user_partt_mode;
 
+extern int amdgpu_wbrf;
+
 #define AMDGPU_VM_MAX_NUM_CTX  4096
 #define AMDGPU_SG_THRESHOLD(256*1024*1024)
 #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 7691177d87aa..c7231ad89aa0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -195,6 +195,7 @@ int amdgpu_use_xgmi_p2p = 1;
 int amdgpu_vcnfw_log;
 int amdgpu_sg_display = -1; /* auto */
 int amdgpu_user_partt_mode = AMDGPU_AUTO_COMPUTE_PARTITION_MODE;
+int amdgpu_wbrf = -1;
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
@@ -978,6 +979,22 @@ module_param_named(user_partt_mode, 
amdgpu_user_partt_mode, uint, 0444);
 module_param(enforce_isolation, bool, 0444);
 MODULE_PARM_DESC(enforce_isolation, "enforce process isolation between 
graphics and compute . enforce_isolation = on");
 
+/**
+ * DOC: wbrf (int)
+ * Enable Wifi RFI interference mitigation feature.
+ * Due to electrical and mechanical constraints there may be likely 
interference of
+ * relatively high-powered harmonics of the (G-)DDR memory clocks with local 
radio
+ * module frequency bands used by Wifi 6/6e/7. To mitigate the possible RFI 
interference,
+ * with this feature enabled, PMFW will use either “shadowed P-State” or 
“P-State” based
+ * on active list of frequencies in-use (to be avoided) as part of initial 
setting or
+ * P-state transition. However, there may be potential performance impact with 
this
+ * feature enabled.
+ * (0 = disabled, 1 = enabled, -1 = auto (default setting, will be enabled if 
supported))
+ */
+MODULE_PARM_DESC(wbrf,
+   "Enable Wifi RFI interference mitigation (0 = disabled, 1 = enabled, -1 
= auto(default)");
+module_param_named(wbrf, amdgpu_wbrf, int, 0444);
+
 /* These devices are not supported by amdgpu.
  * They are supported by the mach64, r128, radeon drivers
  */
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 222af2fae745..bac2a362a2fc 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -1228,6 +1228,174 @@ static int smu_get_thermal_temperature_range(struct 
smu_context *smu)
return ret;
 }
 
+/**
+ * smu_wbrf_handle_exclusion_ranges - consume the wbrf exclusion ranges
+ *
+ * @smu: smu_context pointer
+ *
+ * Retrieve the wbrf exclusion ranges and send them to PMFW for proper 
handling.
+ * Returns 0 on success, error on failure.
+ */
+static int smu_wbrf_handle_exclusion_ranges(struct smu_context *smu)
+{
+   struct wbrf_ranges_in_out wbrf_exclusion = {0};
+   struct exclusion_range *wifi_bands = wbrf_exclusion.band_list;
+   struct amdgpu_device *adev = smu->adev;
+   uint32_t num_of_wbrf_ranges = MAX_NUM_OF_WBRF_RANGES;
+   uint64_t start, end;
+   int ret, i, j;
+
+   ret = acpi_amd_wbrf_retrieve_exclusions(adev->dev, &wbrf_exclusion);
+   if (ret) {
+   dev_err(adev->dev, "Failed to retrieve exclusion ranges!\n");
+   return ret;
+   }
+
+   /*
+* The exclusion ranges array we got might be filled with holes and 
duplicate
+* entries. For example:
+* {(2400, 2500), (0, 0), (6882, 6962), (2400, 2500), (0, 0), (6117, 
6189), (0, 0)...}
+* We need to do some sortups to eliminate those holes and duplicate 
entries.
+* Expected output: {(2400, 2500), (6117, 6189), (6882, 6962), (0, 
0)...}
+*/
+   for (i = 0; i < num_of_wbrf_ranges; i++) {
+   start = wifi_bands[i].start;
+   end = wifi_bands[i].end;
+
+   /* get the last valid entry to fill the intermediate hole */
+   if (!start && !end) {
+ 

[V11 6/8] drm/amd/pm: add flood detection for wbrf events

2023-08-30 Thread Evan Quan
To protect PMFW from being overloaded.

Signed-off-by: Evan Quan 
Reviewed-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 31 +++
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  7 +
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index bac2a362a2fc..2dbdb4149428 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -1319,7 +1319,8 @@ static int smu_wbrf_event_handler(struct notifier_block 
*nb,
 
switch (action) {
case WBRF_CHANGED:
-   smu_wbrf_handle_exclusion_ranges(smu);
+   schedule_delayed_work(&smu->wbrf_delayed_work,
+ 
msecs_to_jiffies(SMU_WBRF_EVENT_HANDLING_PACE));
break;
default:
return NOTIFY_DONE;
@@ -1328,6 +1329,21 @@ static int smu_wbrf_event_handler(struct notifier_block 
*nb,
return NOTIFY_OK;
 }
 
+/**
+ * smu_wbrf_delayed_work_handler - callback on delayed work timer expired
+ *
+ * @work: struct work_struct pointer
+ *
+ * Flood is over and driver will consume the latest exclusion ranges.
+ */
+static void smu_wbrf_delayed_work_handler(struct work_struct *work)
+{
+   struct smu_context *smu =
+   container_of(work, struct smu_context, wbrf_delayed_work.work);
+
+   smu_wbrf_handle_exclusion_ranges(smu);
+}
+
 /**
  * smu_wbrf_support_check - check wbrf support
  *
@@ -1358,12 +1374,14 @@ static void smu_wbrf_support_check(struct smu_context 
*smu)
  */
 static int smu_wbrf_init(struct smu_context *smu)
 {
-   struct amdgpu_device *adev = smu->adev;
int ret;
 
if (!smu->wbrf_supported)
return 0;
 
+   INIT_DELAYED_WORK(&smu->wbrf_delayed_work,
+ smu_wbrf_delayed_work_handler);
+
smu->wbrf_notifier.notifier_call = smu_wbrf_event_handler;
ret = acpi_amd_wbrf_register_notifier(&smu->wbrf_notifier);
if (ret)
@@ -1374,11 +1392,10 @@ static int smu_wbrf_init(struct smu_context *smu)
 * before our driver loaded. To make sure our driver
 * is awared of those exclusion ranges.
 */
-   ret = smu_wbrf_handle_exclusion_ranges(smu);
-   if (ret)
-   dev_err(adev->dev, "Failed to handle wbrf exclusion ranges\n");
+   schedule_delayed_work(&smu->wbrf_delayed_work,
+ msecs_to_jiffies(SMU_WBRF_EVENT_HANDLING_PACE));
 
-   return ret;
+   return 0;
 }
 
 /**
@@ -1394,6 +1411,8 @@ static void smu_wbrf_fini(struct smu_context *smu)
return;
 
acpi_amd_wbrf_unregister_notifier(&smu->wbrf_notifier);
+
+   cancel_delayed_work_sync(&smu->wbrf_delayed_work);
 }
 
 static int smu_smc_hw_setup(struct smu_context *smu)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 3eb1c72a76f1..60d595344c45 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -480,6 +480,12 @@ struct stb_context {
 
 #define WORKLOAD_POLICY_MAX 7
 
+/*
+ * Configure wbrf event handling pace as there can be only one
+ * event processed every SMU_WBRF_EVENT_HANDLING_PACE ms.
+ */
+#define SMU_WBRF_EVENT_HANDLING_PACE   10
+
 struct smu_context
 {
struct amdgpu_device*adev;
@@ -581,6 +587,7 @@ struct smu_context
/* data structures for wbrf feature support */
boolwbrf_supported;
struct notifier_block   wbrf_notifier;
+   struct delayed_work wbrf_delayed_work;
 };
 
 struct i2c_adapter;
-- 
2.34.1



[V11 4/8] drm/amd/pm: update driver_if and ppsmc headers for coming wbrf feature

2023-08-30 Thread Evan Quan
Add those data structures to support Wifi RFI mitigation feature.

Signed-off-by: Evan Quan 
Reviewed-by: Mario Limonciello 
---
 .../pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h | 14 +-
 .../pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h | 14 +-
 .../amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h   |  3 ++-
 .../amd/pm/swsmu/inc/pmfw_if/smu_v13_0_7_ppsmc.h   |  3 ++-
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
index 9dd1ed5b8940..e481407b6584 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
@@ -391,6 +391,17 @@ typedef struct {
   EccInfo_t  EccInfo[24];
 } EccInfoTable_t;
 
+typedef struct {
+  uint16_t LowFreq;
+  uint16_t HighFreq;
+} WifiOneBand_t;
+
+typedef struct {
+  uint32_t WifiBandEntryNum;
+  WifiOneBand_tWifiBandEntry[11];
+  uint32_t MmHubPadding[8];
+} WifiBandEntryTable_t;
+
 //D3HOT sequences
 typedef enum {
   BACO_SEQUENCE,
@@ -1615,7 +1626,8 @@ typedef struct {
 #define TABLE_I2C_COMMANDS9
 #define TABLE_DRIVER_INFO 10
 #define TABLE_ECCINFO 11
-#define TABLE_COUNT   12
+#define TABLE_WIFIBAND12
+#define TABLE_COUNT   13
 
 //IH Interupt ID
 #define IH_INTERRUPT_ID_TO_DRIVER   0xFE
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
index 62b7c0daff68..1530ca002c6c 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
@@ -392,6 +392,17 @@ typedef struct {
   EccInfo_t  EccInfo[24];
 } EccInfoTable_t;
 
+typedef struct {
+  uint16_t LowFreq;
+  uint16_t HighFreq;
+} WifiOneBand_t;
+
+typedef struct {
+  uint32_t WifiBandEntryNum;
+  WifiOneBand_tWifiBandEntry[11];
+  uint32_t MmHubPadding[8];
+} WifiBandEntryTable_t;
+
 //D3HOT sequences
 typedef enum {
   BACO_SEQUENCE,
@@ -1605,7 +1616,8 @@ typedef struct {
 #define TABLE_I2C_COMMANDS9
 #define TABLE_DRIVER_INFO 10
 #define TABLE_ECCINFO 11
-#define TABLE_COUNT   12
+#define TABLE_WIFIBAND12
+#define TABLE_COUNT   13
 
 //IH Interupt ID
 #define IH_INTERRUPT_ID_TO_DRIVER   0xFE
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h
index 10cff75b44d5..c98cc32d11bd 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h
@@ -138,7 +138,8 @@
 #define PPSMC_MSG_SetBadMemoryPagesRetiredFlagsPerChannel 0x4A
 #define PPSMC_MSG_SetPriorityDeltaGain   0x4B
 #define PPSMC_MSG_AllowIHHostInterrupt   0x4C
-#define PPSMC_Message_Count  0x4D
+#define PPSMC_MSG_EnableUCLKShadow   0x51
+#define PPSMC_Message_Count  0x52
 
 //Debug Dump Message
 #define DEBUGSMC_MSG_TestMessage0x1
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_7_ppsmc.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_7_ppsmc.h
index 6aaefca9b595..a6bf9cdd130e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_7_ppsmc.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_7_ppsmc.h
@@ -134,6 +134,7 @@
 #define PPSMC_MSG_SetBadMemoryPagesRetiredFlagsPerChannel 0x4A
 #define PPSMC_MSG_SetPriorityDeltaGain   0x4B
 #define PPSMC_MSG_AllowIHHostInterrupt   0x4C
-#define PPSMC_Message_Count  0x4D
+#define PPSMC_MSG_EnableUCLKShadow   0x51
+#define PPSMC_Message_Count  0x52
 
 #endif
-- 
2.34.1



[V11 3/8] wifi: mac80211: Add support for WBRF features

2023-08-30 Thread Evan Quan
To support the WBRF mechanism, Wifi adapters utilized in the system must
register the frequencies in use(or unregister those frequencies no longer
used) via the dedicated calls. So that, other drivers responding to the
frequencies can take proper actions to mitigate possible interference.

Co-developed-by: Mario Limonciello 
Signed-off-by: Mario Limonciello 
Co-developed-by: Evan Quan 
Signed-off-by: Evan Quan 
--
v1->v2:
  - place the new added member(`wbrf_supported`) in
ieee80211_local(Johannes)
  - handle chandefs change scenario properly(Johannes)
  - some minor fixes around code sharing and possible invalid input
checks(Johannes)
v2->v3:
  - drop unnecessary input checks and intermediate APIs(Mario)
  - Separate some mac80211 common code(Mario, Johannes)
v3->v4:
  - some minor fixes around return values(Johannes)
v9->v10:
  - get ranges_in->num_of_ranges set and passed in(Johannes)
---
 include/linux/ieee80211.h  |   1 +
 net/mac80211/Makefile  |   2 +
 net/mac80211/chan.c|   9 
 net/mac80211/ieee80211_i.h |   9 
 net/mac80211/main.c|   2 +
 net/mac80211/wbrf.c| 105 +
 6 files changed, 128 insertions(+)
 create mode 100644 net/mac80211/wbrf.c

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 4b998090898e..f995d06da87f 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -4335,6 +4335,7 @@ static inline int ieee80211_get_tdls_action(struct 
sk_buff *skb, u32 hdr_size)
 /* convert frequencies */
 #define MHZ_TO_KHZ(freq) ((freq) * 1000)
 #define KHZ_TO_MHZ(freq) ((freq) / 1000)
+#define KHZ_TO_HZ(freq)  ((freq) * 1000)
 #define PR_KHZ(f) KHZ_TO_MHZ(f), f % 1000
 #define KHZ_F "%d.%03d"
 
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index b8de44da1fb8..d46c36f55fd3 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -65,4 +65,6 @@ rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += \
 
 mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
 
+mac80211-y += wbrf.o
+
 ccflags-y += -DDEBUG
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 68952752b599..458469c224ae 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -506,11 +506,16 @@ static void _ieee80211_change_chanctx(struct 
ieee80211_local *local,
 
WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
 
+   ieee80211_remove_wbrf(local, &ctx->conf.def);
+
ctx->conf.def = *chandef;
 
/* check if min chanctx also changed */
changed = IEEE80211_CHANCTX_CHANGE_WIDTH |
  _ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for);
+
+   ieee80211_add_wbrf(local, &ctx->conf.def);
+
drv_change_chanctx(local, ctx, changed);
 
if (!local->use_chanctx) {
@@ -668,6 +673,8 @@ static int ieee80211_add_chanctx(struct ieee80211_local 
*local,
lockdep_assert_held(&local->mtx);
lockdep_assert_held(&local->chanctx_mtx);
 
+   ieee80211_add_wbrf(local, &ctx->conf.def);
+
if (!local->use_chanctx)
local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
 
@@ -748,6 +755,8 @@ static void ieee80211_del_chanctx(struct ieee80211_local 
*local,
}
 
ieee80211_recalc_idle(local);
+
+   ieee80211_remove_wbrf(local, &ctx->conf.def);
 }
 
 static void ieee80211_free_chanctx(struct ieee80211_local *local,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 91633a0b723e..719f2c892132 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1600,6 +1600,8 @@ struct ieee80211_local {
 
/* extended capabilities provided by mac80211 */
u8 ext_capa[8];
+
+   bool wbrf_supported;
 };
 
 static inline struct ieee80211_sub_if_data *
@@ -2638,4 +2640,11 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct 
ieee80211_sub_if_data *sdata,
const struct ieee80211_eht_cap_elem 
*eht_cap_ie_elem,
u8 eht_cap_len,
struct link_sta_info *link_sta);
+
+void ieee80211_check_wbrf_support(struct ieee80211_local *local);
+void ieee80211_add_wbrf(struct ieee80211_local *local,
+   struct cfg80211_chan_def *chandef);
+void ieee80211_remove_wbrf(struct ieee80211_local *local,
+  struct cfg80211_chan_def *chandef);
+
 #endif /* IEEE80211_I_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 24315d7b3126..b20bdaac84db 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1396,6 +1396,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
debugfs_hw_add(local);
rate_control_add_debugfs(local);
 
+   ieee80211_check_wbrf_support(local);
+
rtnl_lock();
wiphy_lock(hw->wiphy);
 
diff --git a/net/mac80211/wbrf.c b/net/mac80211/wbrf.c
new file mode 100644
index ..63978c7d2bcb
--- /dev/null
+++ b/net/mac80211/wbrf.c
@@ -0,0 +1,105

[V11 2/8] cfg80211: expose nl80211_chan_width_to_mhz for wide sharing

2023-08-30 Thread Evan Quan
The newly added WBRF feature needs this interface for channel
width calculation.

Signed-off-by: Evan Quan 
--
v8->v9:
  - correct typo(Mhz -> MHz) (Johnson)
---
 include/net/cfg80211.h | 8 
 net/wireless/chan.c| 3 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7c7d03aa9d06..8c2a9b748621 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -920,6 +920,14 @@ const struct cfg80211_chan_def *
 cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
const struct cfg80211_chan_def *chandef2);
 
+/**
+ * nl80211_chan_width_to_mhz - get the channel width in MHz
+ * @chan_width: the channel width from &enum nl80211_chan_width
+ * Return: channel width in MHz if the chan_width from &enum nl80211_chan_width
+ * is valid. -1 otherwise.
+ */
+int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width);
+
 /**
  * cfg80211_chandef_valid - check if a channel definition is valid
  * @chandef: the channel definition to check
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 0b7e81db383d..227db04eac42 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -141,7 +141,7 @@ static bool cfg80211_edmg_chandef_valid(const struct 
cfg80211_chan_def *chandef)
return true;
 }
 
-static int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
+int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
 {
int mhz;
 
@@ -190,6 +190,7 @@ static int nl80211_chan_width_to_mhz(enum 
nl80211_chan_width chan_width)
}
return mhz;
 }
+EXPORT_SYMBOL(nl80211_chan_width_to_mhz);
 
 static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
 {
-- 
2.34.1



[V11 1/8] ACPI: Add support for AMD ACPI based Wifi band RFI mitigation feature

2023-08-30 Thread Evan Quan
Due to electrical and mechanical constraints in certain platform designs
there may be likely interference of relatively high-powered harmonics of
the (G-)DDR memory clocks with local radio module frequency bands used
by Wifi 6/6e/7.

To mitigate this, AMD has introduced a mechanism that devices can use to
notify active use of particular frequencies so that other devices can make
relative internal adjustments as necessary to avoid this resonance.

Signed-off-by: Evan Quan 
--
v10->v11:
  - fix typo(Simon)
---
 drivers/acpi/Kconfig  |  17 ++
 drivers/acpi/Makefile |   2 +
 drivers/acpi/amd_wbrf.c   | 414 ++
 include/linux/acpi_amd_wbrf.h | 140 
 4 files changed, 573 insertions(+)
 create mode 100644 drivers/acpi/amd_wbrf.c
 create mode 100644 include/linux/acpi_amd_wbrf.h

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 00dd309b6682..a092ea72d152 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -594,6 +594,23 @@ config ACPI_PRMT
  substantially increase computational overhead related to the
  initialization of some server systems.
 
+config WBRF_AMD_ACPI
+   bool "ACPI based WBRF mechanism introduced by AMD"
+   depends on ACPI
+   default n
+   help
+ Wifi band RFI mitigation mechanism allows multiple drivers from
+ different domains to notify the frequencies in use so that hardware
+ can be reconfigured to avoid harmonic conflicts.
+
+ AMD has introduced an ACPI based mechanism to support WBRF for some
+ platforms with AMD dGPU and WLAN. This needs support from BIOS 
equipped
+ with necessary AML implementations and dGPU firmwares.
+
+ Before enabling this ACPI based mechanism, it is suggested to confirm
+ with the hardware designer/provider first whether your platform
+ equipped with necessary BIOS and firmwares.
+
 endif  # ACPI
 
 config X86_PM_TIMER
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index eaa09bf52f17..a3d2f259d0a5 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -132,3 +132,5 @@ obj-$(CONFIG_ARM64) += arm64/
 obj-$(CONFIG_ACPI_VIOT)+= viot.o
 
 obj-$(CONFIG_RISCV)+= riscv/
+
+obj-$(CONFIG_WBRF_AMD_ACPI)+= amd_wbrf.o
diff --git a/drivers/acpi/amd_wbrf.c b/drivers/acpi/amd_wbrf.c
new file mode 100644
index ..8ee0e2977a30
--- /dev/null
+++ b/drivers/acpi/amd_wbrf.c
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Wifi Band Exclusion Interface (AMD ACPI Implementation)
+ * Copyright (C) 2023 Advanced Micro Devices
+ *
+ */
+
+#include 
+#include 
+
+#define ACPI_AMD_WBRF_METHOD   "\\WBRF"
+
+/*
+ * Functions bit vector for WBRF method
+ *
+ * Bit 0: Supported for any functions other than function 0.
+ * Bit 1: Function 1 (Add / Remove frequency) is supported.
+ * Bit 2: Function 2 (Get frequency list) is supported.
+ */
+#define WBRF_ENABLED   0x0
+#define WBRF_RECORD0x1
+#define WBRF_RETRIEVE  0x2
+
+/* record actions */
+#define WBRF_RECORD_ADD0x0
+#define WBRF_RECORD_REMOVE 0x1
+
+#define WBRF_REVISION  0x1
+
+/*
+ * The data structure used for WBRF_RETRIEVE is not naturally aligned.
+ * And unfortunately the design has been settled down.
+ */
+struct amd_wbrf_ranges_out {
+   u32 num_of_ranges;
+   struct exclusion_range  band_list[MAX_NUM_OF_WBRF_RANGES];
+} __packed;
+
+static const guid_t wifi_acpi_dsm_guid =
+   GUID_INIT(0x7b7656cf, 0xdc3d, 0x4c1c,
+ 0x83, 0xe9, 0x66, 0xe7, 0x21, 0xde, 0x30, 0x70);
+
+static BLOCKING_NOTIFIER_HEAD(wbrf_chain_head);
+
+static int wbrf_dsm(struct acpi_device *adev,
+   u8 fn,
+   union acpi_object *argv4)
+{
+   union acpi_object *obj;
+   int rc;
+
+   obj = acpi_evaluate_dsm(adev->handle, &wifi_acpi_dsm_guid,
+   WBRF_REVISION, fn, argv4);
+   if (!obj)
+   return -ENXIO;
+
+   switch (obj->type) {
+   case ACPI_TYPE_INTEGER:
+   rc = obj->integer.value ? -EINVAL : 0;
+   break;
+   default:
+   rc = -EOPNOTSUPP;
+   }
+
+   ACPI_FREE(obj);
+
+   return rc;
+}
+
+static int wbrf_record(struct acpi_device *adev, uint8_t action,
+  struct wbrf_ranges_in_out *in)
+{
+   union acpi_object argv4;
+   union acpi_object *tmp;
+   u32 num_of_ranges = 0;
+   u32 num_of_elements;
+   u32 arg_idx = 0;
+   u32 loop_idx;
+   int ret;
+
+   if (!in)
+   return -EINVAL;
+
+   for (loop_idx = 0; loop_idx < ARRAY_SIZE(in->band_list);
+loop_idx++)
+   if (in->band_list[loop_idx].start &&
+   in->band_list[loop_idx].end)
+   num_of_ranges++;
+
+   /*
+  

[V11 0/8] Enable Wifi RFI interference mitigation feature support

2023-08-30 Thread Evan Quan
Due to electrical and mechanical constraints in certain platform designs there
may be likely interference of relatively high-powered harmonics of the (G-)DDR
memory clocks with local radio module frequency bands used by Wifi 6/6e/7. To
mitigate possible RFI interference producers can advertise the frequencies in
use and consumers can use this information to avoid using these frequencies for
sensitive features.

The whole patch set is based on Linux 6.5-rc5. With some brief introductions
as below:
Patch1:  Core functionality setup for WBRF feature support
Patch2 - 3:  Bring WBRF support to wifi subsystem.
Patch4 - 8:  Bring WBRF support to AMD graphics driver.

Evan Quan (8):
  ACPI: Add support for AMD ACPI based Wifi band RFI mitigation feature
  cfg80211: expose nl80211_chan_width_to_mhz for wide sharing
  wifi: mac80211: Add support for WBRF features
  drm/amd/pm: update driver_if and ppsmc headers for coming wbrf feature
  drm/amd/pm: setup the framework to support Wifi RFI mitigation feature
  drm/amd/pm: add flood detection for wbrf events
  drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.0
  drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.7

 drivers/acpi/Kconfig  |  17 +
 drivers/acpi/Makefile |   2 +
 drivers/acpi/amd_wbrf.c   | 414 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  17 +
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 214 +
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  33 ++
 .../inc/pmfw_if/smu13_driver_if_v13_0_0.h |  14 +-
 .../inc/pmfw_if/smu13_driver_if_v13_0_7.h |  14 +-
 .../pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h  |   3 +-
 .../pm/swsmu/inc/pmfw_if/smu_v13_0_7_ppsmc.h  |   3 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h  |   3 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h  |   3 +
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c|   9 +
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  |  60 +++
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c  |  59 +++
 drivers/gpu/drm/amd/pm/swsmu/smu_internal.h   |   3 +
 include/linux/acpi_amd_wbrf.h | 140 ++
 include/linux/ieee80211.h |   1 +
 include/net/cfg80211.h|   8 +
 net/mac80211/Makefile |   2 +
 net/mac80211/chan.c   |   9 +
 net/mac80211/ieee80211_i.h|   9 +
 net/mac80211/main.c   |   2 +
 net/mac80211/wbrf.c   | 105 +
 net/wireless/chan.c   |   3 +-
 26 files changed, 1143 insertions(+), 6 deletions(-)
 create mode 100644 drivers/acpi/amd_wbrf.c
 create mode 100644 include/linux/acpi_amd_wbrf.h
 create mode 100644 net/mac80211/wbrf.c

-- 
2.34.1



[git pull] drm CI integration

2023-08-30 Thread Dave Airlie
Hey Linus,

This is a PR to add drm-ci support files to the upstream tree.
This is a bunch of ci integration for the freedesktop gitlab instance
where we currently do upstream userspace testing on diverse sets of GPU
hardware. From my perspective I think it's an experiment worth going with
and seeing how the benefits/noise playout keeping these files useful.

Ideally I'd like to get this so we can do pre-merge testing on PRs eventually.

Below is some info from danvet on why we've ended up making the
decision and how we can roll it back if we decide it was a bad plan.

Why in upstream?

- like documentation, testcases, tools CI integration is one of these things
  where you can waste endless amounts of time if you accidentally have a version
  that doesn't match your source code

- but also like the above, there's a balance, this is the initial cut of what we
  think makes sense to keep in sync vs out-of-tree, probably needs adjustment

- gitlab supports out-of-repo gitlab integration and that's what's been used for
  the kernel in drm, but it results in per-driver fragmentation and lots of
  duplicated effort. the simple act of smashing an arbitrary winner into a topic
  branch already started surfacing patches on dri-devel and sparking good
  cross driver team discussions

Why gitlab?

- it's not any more shit than any of the other CI

- drm userspace uses it extensively for everything in userspace, we have a lot
  of people and experience with this, including integration of hw testing labs

- media userspace like gstreamer is also on gitlab.fd.o, and there's discussion
  to extend this to the media subsystem in some fashion

Can this be shared?

- there's definitely a pile of code that could move to scripts/ if other
  subsystem adopt ci integration in upstream kernel git. other bits are more
  drm/gpu specific like the igt-gpu-tests/tools integration

- docker images can be run locally or in other CI runners

Will we regret this?

- it's all in one directory, intentionally, for easy deletion

- probably 1-2 years in upstream to see whether this is worth it or a Big
  Mistake. that's roughly what it took to _really_ roll out solid CI in the
  bigger userspace projects we have on gitlab.fd.o like mesa3d

Dave + Daniel.

topic/drm-ci-2023-08-31-1:
drm ci for 6.6-rc1

Add CI integration support files for drm subsystem to
gitlab.freedesktop.org instance.
The following changes since commit 3698a75f5a98d0a6599e2878ab25d30a82dd836a:

  Merge tag 'drm-intel-next-fixes-2023-08-24' of
git://anongit.freedesktop.org/drm/drm-intel into drm-next (2023-08-25
12:55:55 +1000)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/topic/drm-ci-2023-08-31-1

for you to fetch changes up to ad6bfe1b66a5c146ec236847eca7af4c8806d666:

  drm: ci: docs: fix build warning - add missing escape (2023-08-29
19:56:11 +0200)


drm ci for 6.6-rc1

Add CI integration support files for drm subsystem to
gitlab.freedesktop.org instance.


Helen Koike (1):
  drm: ci: docs: fix build warning - add missing escape

Tomeu Vizoso (1):
  drm: Add initial ci/ subdirectory

 Documentation/gpu/automated_testing.rst|  144 +
 Documentation/gpu/index.rst|1 +
 MAINTAINERS|8 +
 drivers/gpu/drm/ci/arm.config  |   69 +
 drivers/gpu/drm/ci/arm64.config|  199 ++
 drivers/gpu/drm/ci/build-igt.sh|   35 +
 drivers/gpu/drm/ci/build.sh|  157 ++
 drivers/gpu/drm/ci/build.yml   |  110 +
 drivers/gpu/drm/ci/check-patch.py  |   57 +
 drivers/gpu/drm/ci/container.yml   |   65 +
 drivers/gpu/drm/ci/gitlab-ci.yml   |  251 ++
 drivers/gpu/drm/ci/igt_runner.sh   |   77 +
 drivers/gpu/drm/ci/image-tags.yml  |   15 +
 drivers/gpu/drm/ci/lava-submit.sh  |   57 +
 drivers/gpu/drm/ci/static-checks.yml   |   12 +
 drivers/gpu/drm/ci/test.yml|  335 +++
 drivers/gpu/drm/ci/testlist.txt| 2912 
 drivers/gpu/drm/ci/x86_64.config   |  111 +
 drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt  |   19 +
 drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt |   21 +
 drivers/gpu/drm/ci/xfails/amdgpu-stoney-skips.txt  |2 +
 drivers/gpu/drm/ci/xfails/i915-amly-fails.txt  |   17 +
 drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt |   32 +
 drivers/gpu/drm/ci/xfails/i915-amly-skips.txt  |4 +
 drivers/gpu/drm/ci/xfails/i915-apl-fails.txt   |   58 +
 drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt  |1 +
 drivers/gpu/drm/ci/xfails/i915-apl-skips.txt   |6 +
 drivers/gpu/drm/ci/xfails/i915-cml-fails.txt   |   18 +
 drivers/g

Re: [PATCH 16/16] drm/msm/dpu: add cdm blocks to dpu snapshot

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> Now that CDM block support has been added to DPU lets also add its
> entry to the DPU snapshot to help debugging.
>
> Signed-off-by: Abhinav Kumar 

Reviewed-by: Dmitry Baryshkov 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 
>  1 file changed, 4 insertions(+)


-- 
With best wishes
Dmitry


Re: [PATCH 15/16] drm/msm/dpu: add NV12 in the list of supported WB formats

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> Since CDM block support has now been added for writeback blocks
> add NV12 in the list of supported WB formats.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> index 713dfc079718..978330c6678e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -244,6 +244,7 @@ static const uint32_t wb2_formats[] = {
> DRM_FORMAT_BGRA,
> DRM_FORMAT_BGRX,
> DRM_FORMAT_XBGR,
> +   DRM_FORMAT_NV12,
>  };

No. This way the driver would announce availability of NV12 even on
chipsets where NV12 is not supported for the writeback. Please define
separate formats array.

BTW: does HW only support NV12 for the writeback? What about YV12 or e.g. NV21?

>
>  /*
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


Re: [PATCH 14/16] drm/msm/dpu: do not allow YUV formats if no CDM block is present

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> On chipsets where CDM block is not available OR where support has
> not been added yet do not allow YUV formats for writeback block.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> index 7fc174b33ae2..d8edca9bc964 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> @@ -406,6 +406,12 @@ static int dpu_encoder_phys_wb_atomic_check(
> return ret;
> }
>
> +   if (DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb))) &&
> +   !phys_enc->dpu_kms->catalog->cdm) {
> +   DPU_ERROR("cannot support YUV formats without CDM block\n");
> +   return -EINVAL;
> +   }

Can we have YUV formats in wb_formats if we do not support CDM? That
would be an error.

> +
> return 0;
>  }
>
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


Re: [PATCH 13/16] drm/msm/dpu: reserve cdm blocks for writeback in case of YUV output

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> Reserve CDM blocks for writeback if the format of the output fb
> is YUV. At the moment, the reservation is done only for writeback
> but can easily be extended by relaxing the checks once other
> interfaces are ready to output YUV.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 35 -
>  1 file changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 1b1e07292a9e..7a3d179bdfba 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include "msm_drv.h"
>  #include "dpu_kms.h"
> @@ -615,9 +616,11 @@ static int dpu_encoder_virt_atomic_check(
> struct drm_display_mode *adj_mode;
> struct msm_display_topology topology;
> struct dpu_global_state *global_state;
> +   struct drm_framebuffer *fb;
> struct drm_dsc_config *dsc;
> int i = 0;
> int ret = 0;
> +   bool needs_cdm = false;
>
> if (!drm_enc || !crtc_state || !conn_state) {
> DPU_ERROR("invalid arg(s), drm_enc %d, crtc/conn state 
> %d/%d\n",
> @@ -655,6 +658,22 @@ static int dpu_encoder_virt_atomic_check(
>
> topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, 
> crtc_state, dsc);
>
> +   /*
> +* Use CDM only for writeback at the moment as other interfaces 
> cannot handle it.
> +* if writeback itself cannot handle cdm for some reason it will fail 
> in its atomic_check()
> +* earlier.
> +*/
> +   if (dpu_enc->disp_info.intf_type == INTF_WB && 
> conn_state->writeback_job) {
> +   fb = conn_state->writeback_job->fb;
> +
> +   if (fb && 
> DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb
> +   needs_cdm = true;
> +   if (needs_cdm && !dpu_enc->cur_master->hw_cdm)
> +   crtc_state->mode_changed = true;
> +   else if (!needs_cdm && dpu_enc->cur_master->hw_cdm)
> +   crtc_state->mode_changed = true;
> +   }

What would be the (estimated) check for DP?

> +
> /*
>  * Release and Allocate resources on every modeset
>  * Dont allocate when active is false.
> @@ -664,7 +683,7 @@ static int dpu_encoder_virt_atomic_check(
>
> if (!crtc_state->active_changed || crtc_state->enable)
> ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
> -   drm_enc, crtc_state, topology, false);
> +   drm_enc, crtc_state, topology, 
> needs_cdm);
> }
>
> trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
> @@ -1126,6 +1145,20 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
> drm_encoder *drm_enc,
>
> dpu_enc->dsc_mask = dsc_mask;
>
> +   if (dpu_enc->disp_info.intf_type == INTF_WB && 
> conn_state->writeback_job) {
> +   struct dpu_hw_blk *hw_cdm = NULL;
> +   struct drm_framebuffer *fb;
> +
> +   fb = conn_state->writeback_job->fb;
> +
> +   if (fb && 
> DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb {

You can drop all fb-related conditions here. If we have CDM, we know
that we asked for it. If we do not, it's because we do not need it.

> +   dpu_rm_get_assigned_resources(&dpu_kms->rm, 
> global_state,
> + drm_enc->base.id, 
> DPU_HW_BLK_CDM,
> + &hw_cdm, 1);
> +   }
> +   dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) 
> : NULL;
> +   }
> +
> cstate = to_dpu_crtc_state(crtc_state);
>
> for (i = 0; i < num_lm; i++) {
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


Re: [PATCH 12/16] drm/msm/dpu: plug-in the cdm related bits to writeback setup

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> To setup and enable CDM block for the writeback pipeline, lets
> add the pieces together to set the active bits and the flush
> bits for the CDM block.
>
> Signed-off-by: Abhinav Kumar 

Reviewed-by: Dmitry Baryshkov 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 10 ++
>  1 file changed, 10 insertions(+)


-- 
With best wishes
Dmitry


Re: [PATCH 10/16] drm/msm/dpu: add support to disable CDM block during encoder cleanup

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> In preparation of setting up CDM block, add the logic to disable it
> properly during encoder cleanup.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  | 8 
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 ++
>  2 files changed, 10 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 582680804016..1b1e07292a9e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -26,6 +26,7 @@
>  #include "dpu_hw_dspp.h"
>  #include "dpu_hw_dsc.h"
>  #include "dpu_hw_merge3d.h"
> +#include "dpu_hw_cdm.h"
>  #include "dpu_formats.h"
>  #include "dpu_encoder_phys.h"
>  #include "dpu_crtc.h"
> @@ -2097,6 +2098,13 @@ void dpu_encoder_helper_phys_cleanup(struct 
> dpu_encoder_phys *phys_enc)
> phys_enc->hw_pp->merge_3d->idx);
> }
>
> +   if (phys_enc->hw_cdm && phys_enc->hw_cdm->ops.bind_pingpong_blk && 
> phys_enc->hw_pp) {
> +   phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm,
> +   false, 
> phys_enc->hw_pp->idx);

But it was already bound in the cdm->enable, wasn't it?

Also the update_pending_flush_cdm should be called even for DPU < 5.0,
where there should be no bind_pingpong_blk callback.

> +   if (phys_enc->hw_ctl->ops.update_pending_flush_cdm)
> +   
> phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl);
> +   }
> +
> if (dpu_enc->dsc) {
> dpu_encoder_unprep_dsc(dpu_enc);
> dpu_enc->dsc = NULL;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> index 24dbc28be4f8..510c1c41ddbc 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> @@ -150,6 +150,7 @@ enum dpu_intr_idx {
>   * @hw_pp: Hardware interface to the ping pong registers
>   * @hw_intf:   Hardware interface to the intf registers
>   * @hw_wb: Hardware interface to the wb registers
> + * @hw_cdm:Hardware interface to the CDM registers
>   * @dpu_kms:   Pointer to the dpu_kms top level
>   * @cached_mode:   DRM mode cached at mode_set time, acted on in enable
>   * @enabled:   Whether the encoder has enabled and running a mode
> @@ -178,6 +179,7 @@ struct dpu_encoder_phys {
> struct dpu_hw_pingpong *hw_pp;
> struct dpu_hw_intf *hw_intf;
> struct dpu_hw_wb *hw_wb;
> +   struct dpu_hw_cdm *hw_cdm;
> struct dpu_kms *dpu_kms;
> struct drm_display_mode cached_mode;
> enum dpu_enc_split_role split_role;
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


Re: [PATCH 09/16] drm/msm/dpu: add CDM related logic to dpu_hw_ctl layer

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> CDM block will need its own logic to program the flush and active
> bits in the dpu_hw_ctl layer.
>
> Make necessary changes in dpu_hw_ctl to support CDM programming.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 34 ++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 11 +++
>  2 files changed, 45 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> index c278fb9d2b5b..beced9f19740 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> @@ -29,11 +29,13 @@
>  #define   CTL_DSC_ACTIVE0x0E8
>  #define   CTL_WB_ACTIVE 0x0EC
>  #define   CTL_INTF_ACTIVE   0x0F4
> +#define   CTL_CDM_ACTIVE0x0F8
>  #define   CTL_FETCH_PIPE_ACTIVE 0x0FC
>  #define   CTL_MERGE_3D_FLUSH0x100
>  #define   CTL_DSC_FLUSH0x104
>  #define   CTL_WB_FLUSH  0x108
>  #define   CTL_INTF_FLUSH0x110
> +#define   CTL_CDM_FLUSH0x114
>  #define   CTL_INTF_MASTER   0x134
>  #define   CTL_DSPP_n_FLUSH(n)   ((0x13C) + ((n) * 4))
>
> @@ -43,6 +45,7 @@
>  #define DPU_REG_RESET_TIMEOUT_US2000
>  #define  MERGE_3D_IDX   23
>  #define  DSC_IDX22
> +#define CDM_IDX 26
>  #define  INTF_IDX   31
>  #define WB_IDX  16
>  #define  DSPP_IDX   29  /* From DPU hw rev 7.x.x */
> @@ -104,6 +107,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct 
> dpu_hw_ctl *ctx)
> ctx->pending_wb_flush_mask = 0;
> ctx->pending_merge_3d_flush_mask = 0;
> ctx->pending_dsc_flush_mask = 0;
> +   ctx->pending_cdm_flush_mask = 0;
>
> memset(ctx->pending_dspp_flush_mask, 0,
> sizeof(ctx->pending_dspp_flush_mask));
> @@ -148,6 +152,10 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct 
> dpu_hw_ctl *ctx)
> DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
>   ctx->pending_dsc_flush_mask);
>
> +   if (ctx->pending_flush_mask & BIT(CDM_IDX))
> +   DPU_REG_WRITE(&ctx->hw, CTL_CDM_FLUSH,
> + ctx->pending_cdm_flush_mask);
> +
> DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
>  }
>
> @@ -273,6 +281,12 @@ static void dpu_hw_ctl_update_pending_flush_wb(struct 
> dpu_hw_ctl *ctx,
> }
>  }
>
> +static void dpu_hw_ctl_update_pending_flush_cdm(struct dpu_hw_ctl *ctx)
> +{
> +   ctx->pending_flush_mask |= BIT(CDM_IDX);
> +

unused empty line.

> +}
> +
>  static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
> enum dpu_wb wb)
>  {
> @@ -301,6 +315,12 @@ static void 
> dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx,
> ctx->pending_flush_mask |= BIT(DSC_IDX);
>  }
>
> +static void dpu_hw_ctl_update_pending_flush_cdm_v1(struct dpu_hw_ctl *ctx)
> +{
> +   ctx->pending_cdm_flush_mask |= BIT(0);

I'd assume this is because there is just CDM_0? Then it still might be
better to write BIT(cdm->idx - CDM_0).

> +   ctx->pending_flush_mask |= BIT(CDM_IDX);
> +}
> +
>  static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
> enum dpu_dspp dspp, u32 dspp_sub_blk)
>  {
> @@ -504,6 +524,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
> u32 intf_active = 0;
> u32 wb_active = 0;
> u32 mode_sel = 0;
> +   u32 cdm_active = 0;
>
> /* CTL_TOP[31:28] carries group_id to collate CTL paths
>  * per VM. Explicitly disable it until VM support is
> @@ -517,6 +538,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
>
> intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
> wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
> +   cdm_active = DPU_REG_READ(c, CTL_CDM_ACTIVE);
>
> if (cfg->intf)
> intf_active |= BIT(cfg->intf - INTF_0);
> @@ -534,6 +556,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
>
> if (cfg->dsc)
> DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
> +
> +   if (cfg->cdm)
> +   DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm);
>  }
>
>  static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
> @@ -577,6 +602,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct 
> dpu_hw_ctl *ctx,
> u32 wb_active = 0;
> u32 merge3d_active = 0;
> u32 dsc_active;
> +   u32 cdm_active;
>
> /*
>  * This API resets each portion of the CTL path namely,
> @@ -612,6 +638,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct 
> dpu_hw_ctl *ctx,
> dsc_active &= ~cfg->dsc;
> DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
> }
> +
> +   if (cfg->cdm) {
> +   cdm_active = DPU_REG_READ(c, C

Re: [PATCH 11/16] drm/msm/dpu: add an API to setup the CDM block for writeback

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> Add an API dpu_encoder_helper_phys_setup_cdm() which can be used by
> the writeback encoder to setup the CDM block.
>
> Currently, this is defined and used within the writeback's physical
> encoder layer however, the function can be modified to be used to setup
> the CDM block even for non-writeback interfaces.
>
> Until those modifications are planned and made, keep it local to
> writeback.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |   3 +
>  .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c   | 123 +-
>  2 files changed, 125 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> index 510c1c41ddbc..93a8ae67beff 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> @@ -16,6 +16,7 @@
>  #include "dpu_hw_pingpong.h"
>  #include "dpu_hw_ctl.h"
>  #include "dpu_hw_top.h"
> +#include "dpu_hw_cdm.h"
>  #include "dpu_encoder.h"
>  #include "dpu_crtc.h"
>
> @@ -209,6 +210,7 @@ static inline int dpu_encoder_phys_inc_pending(struct 
> dpu_encoder_phys *phys)
>   * @wbirq_refcount: Reference count of writeback interrupt
>   * @wb_done_timeout_cnt: number of wb done irq timeout errors
>   * @wb_cfg:  writeback block config to store fb related details
> + * @cdm_cfg: cdm block config needed to store writeback block's CDM 
> configuration
>   * @wb_conn: backpointer to writeback connector
>   * @wb_job: backpointer to current writeback job
>   * @dest:   dpu buffer layout for current writeback output buffer
> @@ -218,6 +220,7 @@ struct dpu_encoder_phys_wb {
> atomic_t wbirq_refcount;
> int wb_done_timeout_cnt;
> struct dpu_hw_wb_cfg wb_cfg;
> +   struct dpu_hw_cdm_cfg cdm_cfg;
> struct drm_writeback_connector *wb_conn;
> struct drm_writeback_job *wb_job;
> struct dpu_hw_fmt_layout dest;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> index 4c2736c3ee6d..11935aac9fd5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> @@ -24,6 +24,20 @@
>  #define to_dpu_encoder_phys_wb(x) \
> container_of(x, struct dpu_encoder_phys_wb, base)
>
> +#define TO_S15D16(_x_)((_x_) << 7)
> +
> +static struct dpu_csc_cfg dpu_encoder_phys_wb_rgb2yuv_601l = {
> +   {
> +   TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032),
> +   TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1),
> +   TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc)
> +   },
> +   { 0x00, 0x00, 0x00 },
> +   { 0x0040, 0x0200, 0x0200 },
> +   { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff },
> +   { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 },
> +};

Nit: we probably need to have a single place with all dpu_csc_cfg entries.

> +
>  /**
>   * dpu_encoder_phys_wb_is_master - report wb always as master encoder
>   * @phys_enc:  Pointer to physical encoder
> @@ -225,6 +239,112 @@ static void dpu_encoder_phys_wb_setup_ctl(struct 
> dpu_encoder_phys *phys_enc)
> }
>  }
>
> +/**
> + * dpu_encoder_phys_wb_setup_cdp - setup chroma down sampling block
> + * @phys_enc:Pointer to physical encoder
> + */
> +static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys 
> *phys_enc)
> +{
> +   struct dpu_hw_cdm *hw_cdm;
> +   struct dpu_hw_cdm_cfg *cdm_cfg;
> +   struct dpu_hw_pingpong *hw_pp;
> +   struct dpu_encoder_phys_wb *wb_enc;
> +   const struct msm_format *format;
> +   const struct dpu_format *dpu_fmt;
> +   struct drm_writeback_job *wb_job;
> +   int ret;
> +
> +   if (!phys_enc)
> +   return;
> +
> +   wb_enc = to_dpu_encoder_phys_wb(phys_enc);
> +   cdm_cfg = &wb_enc->cdm_cfg;
> +   hw_pp = phys_enc->hw_pp;
> +   hw_cdm = phys_enc->hw_cdm;
> +   wb_job = wb_enc->wb_job;
> +
> +   format = msm_framebuffer_format(wb_enc->wb_job->fb);
> +   dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, 
> wb_job->fb->modifier);
> +
> +   if (!hw_cdm)
> +   return;
> +
> +   if (!DPU_FORMAT_IS_YUV(dpu_fmt)) {
> +   DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", 
> DRMID(phys_enc->parent),
> + dpu_fmt->base.pixel_format);
> +   if (hw_cdm->ops.disable)
> +   hw_cdm->ops.disable(hw_cdm);
> +
> +   return;
> +   }
> +
> +   memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg));
> +
> +   cdm_cfg->output_width = wb_job->fb->width;
> +   cdm_cfg->output_height = wb_job->fb->height;
> +   cdm_cfg->output_fmt = dpu_fmt;
> +   cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB;
> +   cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ?
> 

Re: [PATCH 08/16] drm/msm/dpu: add support to allocate CDM from RM

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> Even though there is usually only one CDM block, it can be
> used by either HDMI, DisplayPort OR Writeback interfaces.
>
> Hence its allocation needs to be tracked properly by the
> resource manager to ensure appropriate availability of the
> block.

It almost feels like an overkill, as up to now there is at most one CDM block.

>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |  1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 45 +++--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  4 +-
>  5 files changed, 48 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 6cf6597148fd..582680804016 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -663,7 +663,7 @@ static int dpu_encoder_virt_atomic_check(
>
> if (!crtc_state->active_changed || crtc_state->enable)
> ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
> -   drm_enc, crtc_state, topology);
> +   drm_enc, crtc_state, topology, false);
> }
>
> trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> index 34f943102499..07f75f295844 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> @@ -98,6 +98,7 @@ enum dpu_hw_blk_type {
> DPU_HW_BLK_DSPP,
> DPU_HW_BLK_MERGE_3D,
> DPU_HW_BLK_DSC,
> +   DPU_HW_BLK_CDM,
> DPU_HW_BLK_MAX,
>  };
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index b6f53ca6e962..61aa58643fda 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -136,6 +136,7 @@ struct dpu_global_state {
> uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
> uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
> uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
> +   uint32_t cdm_to_enc_id;
>  };
>
>  struct dpu_global_state
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index 7b6444a3fcb1..e7d4beb4661e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -29,10 +29,12 @@ static inline bool reserved_by_other(uint32_t *res_map, 
> int idx,
>  /**
>   * struct dpu_rm_requirements - Reservation requirements parameter bundle
>   * @topology:  selected topology for the display
> + * @needs_cdm: whether the display needs a CDM block for the current mode
>   * @hw_res:   Hardware resources required as reported by the encoders
>   */
>  struct dpu_rm_requirements {
> struct msm_display_topology topology;
> +   bool needs_cdm;
>  };
>
>  int dpu_rm_destroy(struct dpu_rm *rm)
> @@ -505,6 +507,26 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
> return 0;
>  }
>
> +static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
> +  struct dpu_global_state *global_state,
> +  struct drm_encoder *enc)
> +{
> +   /* try allocating only one CDM block */
> +   if (!rm->cdm_blk) {
> +   DPU_ERROR("CDM block does not exist\n");
> +   return -EIO;
> +   }
> +
> +   if (global_state->cdm_to_enc_id) {
> +   DPU_ERROR("CDM_0 is already allocated\n");
> +   return -EIO;
> +   }
> +
> +   global_state->cdm_to_enc_id = enc->base.id;
> +
> +   return 0;
> +}
> +
>  static int _dpu_rm_make_reservation(
> struct dpu_rm *rm,
> struct dpu_global_state *global_state,
> @@ -530,15 +552,25 @@ static int _dpu_rm_make_reservation(
> if (ret)
> return ret;
>
> +   if (reqs->needs_cdm) {
> +   ret = _dpu_rm_reserve_cdm(rm, global_state, enc);
> +   if (ret) {
> +   DPU_ERROR("unable to find CDM blk\n");
> +   return ret;
> +   }
> +   }
> +
> return ret;
>  }
>
>  static int _dpu_rm_populate_requirements(
> struct drm_encoder *enc,
> struct dpu_rm_requirements *reqs,
> -   struct msm_display_topology req_topology)
> +   struct msm_display_topology req_topology,
> +   bool needs_cdm)

Push it to the topology, please. It is a part of the topology at some
point of view.

>  {
> reqs->topology = req_topology;
> +   reqs->needs_cdm = needs_cdm;
>
> DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf:

Re: [PATCH 06/16] drm/msm/dpu: add dpu_hw_cdm abstraction for CDM block

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> CDM block comes with its own set of registers and operations
> which can be done. In-line with other hardware sub-blocks, this
> change adds the dpu_hw_cdm abstraction for the CDM block.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/Makefile|   1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c  | 272 
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h  | 135 ++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |   1 +
>  4 files changed, 409 insertions(+)
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h
>
> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> index 8d02d8c33069..2010cb1ca995 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
> disp/dpu1/dpu_encoder_phys_wb.o \
> disp/dpu1/dpu_formats.o \
> disp/dpu1/dpu_hw_catalog.o \
> +   disp/dpu1/dpu_hw_cdm.o \
> disp/dpu1/dpu_hw_ctl.o \
> disp/dpu1/dpu_hw_dsc.o \
> disp/dpu1/dpu_hw_dsc_1_2.o \
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
> new file mode 100644
> index ..a2f7ee8f54e4
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
> @@ -0,0 +1,272 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2023, The Linux Foundation. All rights reserved.
> + */
> +
> +#include 
> +
> +#include "dpu_hw_mdss.h"
> +#include "dpu_hw_util.h"
> +#include "dpu_hw_catalog.h"
> +#include "dpu_hw_cdm.h"
> +#include "dpu_kms.h"
> +
> +#define CDM_CSC_10_OPMODE  0x000
> +#define CDM_CSC_10_BASE0x004
> +
> +#define CDM_CDWN2_OP_MODE  0x100
> +#define CDM_CDWN2_CLAMP_OUT0x104
> +#define CDM_CDWN2_PARAMS_3D_0  0x108
> +#define CDM_CDWN2_PARAMS_3D_1  0x10C
> +#define CDM_CDWN2_COEFF_COSITE_H_0 0x110
> +#define CDM_CDWN2_COEFF_COSITE_H_1 0x114
> +#define CDM_CDWN2_COEFF_COSITE_H_2 0x118
> +#define CDM_CDWN2_COEFF_OFFSITE_H_00x11C
> +#define CDM_CDWN2_COEFF_OFFSITE_H_10x120
> +#define CDM_CDWN2_COEFF_OFFSITE_H_20x124
> +#define CDM_CDWN2_COEFF_COSITE_V   0x128
> +#define CDM_CDWN2_COEFF_OFFSITE_V  0x12C
> +#define CDM_CDWN2_OUT_SIZE 0x130
> +
> +#define CDM_HDMI_PACK_OP_MODE  0x200
> +#define CDM_CSC_10_MATRIX_COEFF_0  0x004
> +
> +#define CDM_MUX0x224
> +
> +/**
> + * Horizontal coefficients for cosite chroma downscale
> + * s13 representation of coefficients
> + */
> +static u32 cosite_h_coeff[] = {0x0016, 0x01cc, 0x019e};
> +
> +/**
> + * Horizontal coefficients for offsite chroma downscale
> + */
> +static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046};
> +
> +/**
> + * Vertical coefficients for cosite chroma downscale
> + */
> +static u32 cosite_v_coeff[] = {0x00080004};
> +/**
> + * Vertical coefficients for offsite chroma downscale
> + */
> +static u32 offsite_v_coeff[] = {0x00060002};
> +
> +static int dpu_hw_cdm_setup_csc_10bit(struct dpu_hw_cdm *ctx, struct 
> dpu_csc_cfg *data)
> +{
> +   dpu_hw_csc_setup(&ctx->hw, CDM_CSC_10_MATRIX_COEFF_0, data, true);

Where was this defined?

> +
> +   return 0;
> +}
> +
> +static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, struct 
> dpu_hw_cdm_cfg *cfg)
> +{
> +   struct dpu_hw_blk_reg_map *c = &ctx->hw;
> +   u32 opmode = 0;
> +   u32 out_size = 0;
> +
> +   if (cfg->output_bit_depth == CDM_CDWN_OUTPUT_10BIT)
> +   opmode &= ~BIT(7);
> +   else
> +   opmode |= BIT(7);
> +
> +   /* ENABLE DWNS_H bit */
> +   opmode |= BIT(1);
> +
> +   switch (cfg->h_cdwn_type) {
> +   case CDM_CDWN_DISABLE:
> +   /* CLEAR METHOD_H field */
> +   opmode &= ~(0x18);
> +   /* CLEAR DWNS_H bit */
> +   opmode &= ~BIT(1);
> +   break;
> +   case CDM_CDWN_PIXEL_DROP:
> +   /* Clear METHOD_H field (pixel drop is 0) */
> +   opmode &= ~(0x18);
> +   break;
> +   case CDM_CDWN_AVG:
> +   /* Clear METHOD_H field (Average is 0x1) */
> +   opmode &= ~(0x18);
> +   opmode |= (0x1 << 0x3);
> +   break;
> +   case CDM_CDWN_COSITE:
> +   /* Clear METHOD_H field (Average is 0x2) */
> +   opmode &= ~(0x18);
> +   opmode |= (0x2 << 0x3);
> +   /* Co-site horizontal coefficients */
> +   DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_0,
> +   cosite_h_coeff[0]);
> +   DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_1,
> +   cosite_h_

Re: [PATCH 07/16] drm/msm/dpu: add cdm blocks to RM

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar  wrote:
>
> Add the RM APIs necessary to initialize and allocate CDM
> blocks by the rest of the DPU pipeline.

... to be used by the rest?

>
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 17 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  2 ++
>  2 files changed, 19 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index f9215643c71a..7b6444a3fcb1 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_kms.h"
>  #include "dpu_hw_lm.h"
>  #include "dpu_hw_ctl.h"
> +#include "dpu_hw_cdm.h"
>  #include "dpu_hw_pingpong.h"
>  #include "dpu_hw_sspp.h"
>  #include "dpu_hw_intf.h"
> @@ -90,6 +91,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
> }
> }
>
> +   if (rm->cdm_blk)
> +   dpu_hw_cdm_destroy(to_dpu_hw_cdm(rm->cdm_blk));
> +
> for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
> dpu_hw_wb_destroy(rm->hw_wb[i]);
>
> @@ -240,6 +244,19 @@ int dpu_rm_init(struct dpu_rm *rm,
> rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
> }
>
> +   if (cat->cdm) {
> +   struct dpu_hw_cdm *hw;
> +
> +   hw = dpu_hw_cdm_init(cat->cdm, mmio);
> +   /* CDM is optional so no need to bail out */
> +   if (IS_ERR(hw)) {
> +   rc = PTR_ERR(hw);
> +   DPU_DEBUG("failed cdm object creation: err %d\n", rc);

No. If it is a part of the catalog, we should fail here as we do in other cases.


> +   } else {
> +   rm->cdm_blk = &hw->base;
> +   }
> +   }
> +
> 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 2b551566cbf4..29b221491926 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> @@ -22,6 +22,7 @@ struct dpu_global_state;
>   * @hw_wb: array of wb hardware resources
>   * @dspp_blks: array of dspp hardware resources
>   * @hw_sspp: array of sspp hardware resources
> + * @cdm_blk: cdm hardware resource
>   */
>  struct dpu_rm {
> struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
> @@ -33,6 +34,7 @@ struct dpu_rm {
> 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];
> +   struct dpu_hw_blk *cdm_blk;

struct dpu_hw_cdm *cdm (or cdm_blk), please.

>  };
>
>  /**
> --
> 2.40.1
>


--
With best wishes
Dmitry


Re: [PATCH 03/16] drm/msm/dpu: rename dpu_encoder_phys_wb_setup_cdp to match its functionality

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:49, Abhinav Kumar  wrote:
>
> dpu_encoder_phys_wb_setup_cdp() is not programming the chroma down
> prefetch block. Its setting up the display ctl path for writeback.
>
> Hence rename it to dpu_encoder_phys_wb_setup_ctl() to match what its
> actually doing.
>
> Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for 
> writeback")
> Signed-off-by: Abhinav Kumar 

Reviewed-by: Dmitry Baryshkov 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

-- 
With best wishes
Dmitry


Re: [PATCH 02/16] drm/msm/dpu: add formats check for writeback encoder

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:49, Abhinav Kumar  wrote:
>
> In preparation of adding more formats to dpu writeback add

I think it is `preparation to'

Other than that:

Reviewed-by: Dmitry Baryshkov 

> format validation to it to fail any unsupported formats.
>
> Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for 
> writeback")
> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 7 +++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> index 284a88060221..6a1f8e34f18a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> @@ -238,6 +238,7 @@ static int dpu_encoder_phys_wb_atomic_check(
>  {
> struct drm_framebuffer *fb;
> const struct drm_display_mode *mode = &crtc_state->mode;
> +   int ret;
>
> DPU_DEBUG("[atomic_check:%d, \"%s\",%d,%d]\n",
> phys_enc->hw_wb->idx, mode->name, mode->hdisplay, 
> mode->vdisplay);
> @@ -274,6 +275,12 @@ static int dpu_encoder_phys_wb_atomic_check(
> return -EINVAL;
> }
>
> +   ret = drm_atomic_helper_check_wb_encoder_state(phys_enc->parent, 
> conn_state);
> +   if (ret < 0) {
> +   DPU_ERROR("invalid pixel format %p4cc\n", 
> &fb->format->format);
> +   return ret;
> +   }
> +
> return 0;
>  }
>
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


Re: [PATCH 01/16] drm/msm/dpu: fix writeback programming for YUV cases

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:49, Abhinav Kumar  wrote:
>
> For YUV cases, setting the required format bits was missed
> out in the register programming. Lets fix it now in preparation
> of adding YUV formats support for writeback.
>
> Fixes: 84a33d0fd921 ("drm/msm/dpu: add dpu_hw_wb abstraction for writeback 
> blocks")

Since we were not exporting YUV formats, this tag is not correct. This
is a mere functional change, not a fix.

> Signed-off-by: Abhinav Kumar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
> index ebc416400382..0aa598b355e9 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
> @@ -86,6 +86,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx,
> dst_format |= BIT(14); /* DST_ALPHA_X */
> }
>
> +   if (DPU_FORMAT_IS_YUV(fmt))
> +   dst_format |= BIT(15);
> +
> pattern = (fmt->element[3] << 24) |
> (fmt->element[2] << 16) |
> (fmt->element[1] << 8)  |
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


Re: [RFC PATCH 04/10] drm/panel_helper: Introduce drm_panel_helper

2023-08-30 Thread Doug Anderson
Hi,

On Tue, Aug 29, 2023 at 1:38 AM Maxime Ripard  wrote:
>
> On Mon, Aug 28, 2023 at 09:06:29AM -0700, Doug Anderson wrote:
> > > > Shutdown is called any time you reboot a device. That means that if a
> > > > DRM driver is _not_ calling drm_atomic_helper_shutdown() on the
> > > > panel's behalf at shutdown time then the panel won't be powered off
> > > > properly. This feels to me like something that might actually matter.
> > >
> > > It does matter. What I disagree on is that you suggest working around
> > > that brokenness in the core framework. What I'm saying is driver is
> > > broken, we should keep the core framework sane and fix it in the driver.
> > >
> > > It should be fairly easy with a coccinelle script to figure out which
> > > panels are affected, and to add that call in remove.
> >
> > I think I'm confused here. I've already figured out which panels are
> > affected in my patch series, right? It's the set of panels that today
> > try to power the panel off in their shutdown call, right? ...but I
> > think we can't add the call you're suggesting,
> > drm_atomic_helper_shutdown(), to the _panel_'s shutdown callback, can
> > we? We need to add it to the shutdown callback of the top-level DRM
> > driver, right?
>
> I have no idea what happens if we just unbind the panel device from its
> driver.
>
> If we can't, then it's all fine. If we can, then we need figure out how
> to unregister the DRM device (or block the unbinding from happening).

Nothing prevents unbinding the panel driver directly. I just confirmed
on my sc7180-lazor:

cd /sys/bus/dp-aux/drivers/panel-simple-dp-aux
echo aux-2-0008 > unbind

...no errors happened and the panel unbound. I think this is as
expected since I'm not aware of a way to prevent unbinding a driver. I
think the relevant function is unbind_store() in bus.c, right? There
is no failure code returned by device_driver_detach(). Presumably this
is by design?

FWIW, also trying to re-bind didn't work, also as expected (I think).
I think the whole bridge chain would need to be resolved again and
nothing I'm aware of makes that happen. Maybe I'm simply missing
something in my understanding, of course.

If you want to attempt to tackle some of these issues then I'd be more
than happy. I'm already waist deep in yak hair and I think this is too
big of a task for me to add on.

Should this issue block my work, then? Today, panels will at least
cleanly power themselves off if someone tries to unbind them like
that. If I remove the clean power off at driver unbind time and rely
on the DRM driver to power panels off cleanly then if someone directly
unbinds a panel like I've done above then it won't be power sequenced
properly, right?


> > > > Panels tend to be one of those things that really care about their
> > > > power sequencing and can even get damaged (or not turn on properly
> > > > next time) if sequencing is not done properly, so just removing this
> > > > code and putting the blame on the DRM driver seems scary to me.
> > >
> > > Sure, it's bad. But there's no difference compared to the approach you
> > > suggest in that patch: you created a helper, yes, but every driver will
> > > still have to call that helper and if they don't, the panel will still
> > > be called and it's a bug. And we would have to convert everything to
> > > that new helper.
> > >
> > > It's fundamentally the same discussion than what you were opposed to
> > > above.
> >
> > I think the key difference here is that, if I understand correctly,
> > drm_atomic_helper_shutdown() needs to be added to the top-level DRM
> > driver, not to the panel itself. I guess I'm worried that I'll either
> > miss a case or that simply adding a call to
> > drm_atomic_helper_shutdown() in the top-level DRM driver will break
> > something. Well, I suppose I can try it and see what happens...
>
> The more I think about this discussion, the more I think that the
> original intent of the prepared/enabled flags were precisely there to
> prevent a double-disable for drivers with drm_atomic_helper_shutdown(),
> while still shutting down the panel resources when the panel is used
> with a driver that doesn't call it.

Sure, that makes sense.


> Honestly, I think the right thing to do here is to make every driver
> call shutdown, and then you don't need the reference counting anymore.
>
> I had a shot at a (possibly very suboptimal) coccinelle script to look
> for drivers that are KMS drivers but don't call
> drm_atomic_helper_shutdown() at shutdown.
>
> https://paste.ack.tf/bb42e6@raw

Your paste seems to have expired. Maybe you used the default and had
it expire in 1 day? Maybe you could just paste the script in email so
it'll be archived for posterity on lore?


> The result is:
>
> $ make coccicheck COCCI=./test-drm-shutdown.cocci MODE=report
>
> ...
>
> ./drivers/gpu/drm/sti/sti_drv.c:262:30-49: ERROR: KMS driver 
> sti_platform_driver is missing shutdown implementation
> ./drivers/gpu/drm/armada/armada_drv.c:245:30

Re: [PATCH 04/16] drm/msm/dpu: add cdm blocks to sc7280 dpu_hw_catalog

2023-08-30 Thread Dmitry Baryshkov
On Thu, 31 Aug 2023 at 01:49, Abhinav Kumar  wrote:
>
> Add CDM blocks to the sc7280 dpu_hw_catalog to support
> YUV format output from writeback block.
>
> Signed-off-by: Abhinav Kumar 
> ---
>  .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h  |  9 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h  | 13 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |  5 +
>  3 files changed, 27 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h 
> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
> index 3b5061c4402a..5252170f216d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
> @@ -251,10 +251,19 @@ static const struct dpu_mdss_version sc7280_mdss_ver = {
> .core_minor_ver = 2,
>  };
>
> +static const struct dpu_cdm_cfg sc7280_cdm = {
> +   .name = "cdm_0",
> +   .id = CDM_0,
> +   .len = 0x228,
> +   .base = 0x79200,
> +   .features = 0,

No need to.
Also, as the CDM block seems to be common to all existing platforms,
what about moving this definition to dpu_hw_catalog.c next to VBIF
settings?

> +};
> +
>  const struct dpu_mdss_cfg dpu_sc7280_cfg = {
> .mdss_ver = &sc7280_mdss_ver,
> .caps = &sc7280_dpu_caps,
> .mdp = &sc7280_mdp,
> +   .cdm = &sc7280_cdm,
> .ctl_count = ARRAY_SIZE(sc7280_ctl),
> .ctl = sc7280_ctl,
> .sspp_count = ARRAY_SIZE(sc7280_sspp),
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index 6c9634209e9f..4ea7c3f85a95 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -693,6 +693,17 @@ struct dpu_vbif_cfg {
> u32 memtype[MAX_XIN_COUNT];
>  };
>
> +/**
> + * struct dpu_cdm_cfg - information of chroma down blocks
> + * @name   string name for debug purposes
> + * @id enum identifying this block
> + * @base   register offset of this block
> + * @features   bit mask identifying sub-blocks/features
> + */
> +struct dpu_cdm_cfg {
> +   DPU_HW_BLK_INFO;
> +};
> +
>  /**
>   * Define CDP use cases
>   * @DPU_PERF_CDP_UDAGE_RT: real-time use cases
> @@ -816,6 +827,8 @@ struct dpu_mdss_cfg {
> u32 wb_count;
> const struct dpu_wb_cfg *wb;
>
> +   const struct dpu_cdm_cfg *cdm;
> +
> u32 ad_count;
>
> u32 dspp_count;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> index d85157acfbf8..4d6dba18caf0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> @@ -185,6 +185,11 @@ enum dpu_dsc {
> DSC_MAX
>  };
>
> +enum dpu_cdm {
> +   CDM_0 = 1,
> +   CDM_MAX
> +};
> +
>  enum dpu_pingpong {
> PINGPONG_NONE,
> PINGPONG_0,
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


[PATCH 12/16] drm/msm/dpu: plug-in the cdm related bits to writeback setup

2023-08-30 Thread Abhinav Kumar
To setup and enable CDM block for the writeback pipeline, lets
add the pieces together to set the active bits and the flush
bits for the CDM block.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 11935aac9fd5..7fc174b33ae2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -194,6 +194,7 @@ static void dpu_encoder_phys_wb_setup_ctl(struct 
dpu_encoder_phys *phys_enc)
 {
struct dpu_hw_wb *hw_wb;
struct dpu_hw_ctl *ctl;
+   struct dpu_hw_cdm *hw_cdm;
 
if (!phys_enc) {
DPU_ERROR("invalid encoder\n");
@@ -202,6 +203,7 @@ static void dpu_encoder_phys_wb_setup_ctl(struct 
dpu_encoder_phys *phys_enc)
 
hw_wb = phys_enc->hw_wb;
ctl = phys_enc->hw_ctl;
+   hw_cdm = phys_enc->hw_cdm;
 
if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) &&
(phys_enc->hw_ctl &&
@@ -218,6 +220,9 @@ static void dpu_encoder_phys_wb_setup_ctl(struct 
dpu_encoder_phys *phys_enc)
if (mode_3d && hw_pp && hw_pp->merge_3d)
intf_cfg.merge_3d = hw_pp->merge_3d->idx;
 
+   if (hw_cdm)
+   intf_cfg.cdm = hw_cdm->idx;
+
if (phys_enc->hw_pp->merge_3d && 
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode)

phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
mode_3d);
@@ -414,6 +419,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct 
dpu_encoder_phys *phys_enc)
struct dpu_hw_wb *hw_wb;
struct dpu_hw_ctl *hw_ctl;
struct dpu_hw_pingpong *hw_pp;
+   struct dpu_hw_cdm *hw_cdm;
u32 pending_flush = 0;
 
if (!phys_enc)
@@ -422,6 +428,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct 
dpu_encoder_phys *phys_enc)
hw_wb = phys_enc->hw_wb;
hw_pp = phys_enc->hw_pp;
hw_ctl = phys_enc->hw_ctl;
+   hw_cdm = phys_enc->hw_cdm;
 
DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
 
@@ -437,6 +444,9 @@ static void _dpu_encoder_phys_wb_update_flush(struct 
dpu_encoder_phys *phys_enc)
hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
hw_pp->merge_3d->idx);
 
+   if (hw_cdm && hw_ctl->ops.update_pending_flush_cdm)
+   hw_ctl->ops.update_pending_flush_cdm(hw_ctl);
+
if (hw_ctl->ops.get_pending_flush)
pending_flush = hw_ctl->ops.get_pending_flush(hw_ctl);
 
-- 
2.40.1



[PATCH 10/16] drm/msm/dpu: add support to disable CDM block during encoder cleanup

2023-08-30 Thread Abhinav Kumar
In preparation of setting up CDM block, add the logic to disable it
properly during encoder cleanup.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  | 8 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 582680804016..1b1e07292a9e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -26,6 +26,7 @@
 #include "dpu_hw_dspp.h"
 #include "dpu_hw_dsc.h"
 #include "dpu_hw_merge3d.h"
+#include "dpu_hw_cdm.h"
 #include "dpu_formats.h"
 #include "dpu_encoder_phys.h"
 #include "dpu_crtc.h"
@@ -2097,6 +2098,13 @@ void dpu_encoder_helper_phys_cleanup(struct 
dpu_encoder_phys *phys_enc)
phys_enc->hw_pp->merge_3d->idx);
}
 
+   if (phys_enc->hw_cdm && phys_enc->hw_cdm->ops.bind_pingpong_blk && 
phys_enc->hw_pp) {
+   phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm,
+   false, 
phys_enc->hw_pp->idx);
+   if (phys_enc->hw_ctl->ops.update_pending_flush_cdm)
+   
phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl);
+   }
+
if (dpu_enc->dsc) {
dpu_encoder_unprep_dsc(dpu_enc);
dpu_enc->dsc = NULL;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 24dbc28be4f8..510c1c41ddbc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -150,6 +150,7 @@ enum dpu_intr_idx {
  * @hw_pp: Hardware interface to the ping pong registers
  * @hw_intf:   Hardware interface to the intf registers
  * @hw_wb: Hardware interface to the wb registers
+ * @hw_cdm:Hardware interface to the CDM registers
  * @dpu_kms:   Pointer to the dpu_kms top level
  * @cached_mode:   DRM mode cached at mode_set time, acted on in enable
  * @enabled:   Whether the encoder has enabled and running a mode
@@ -178,6 +179,7 @@ struct dpu_encoder_phys {
struct dpu_hw_pingpong *hw_pp;
struct dpu_hw_intf *hw_intf;
struct dpu_hw_wb *hw_wb;
+   struct dpu_hw_cdm *hw_cdm;
struct dpu_kms *dpu_kms;
struct drm_display_mode cached_mode;
enum dpu_enc_split_role split_role;
-- 
2.40.1



[PATCH 16/16] drm/msm/dpu: add cdm blocks to dpu snapshot

2023-08-30 Thread Abhinav Kumar
Now that CDM block support has been added to DPU lets also add its
entry to the DPU snapshot to help debugging.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index aa6ba2cf4b84..a207b18eb112 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -988,6 +988,10 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state 
*disp_state, struct msm_k
}
}
 
+   if (cat->cdm)
+   msm_disp_snapshot_add_block(disp_state, cat->cdm->len,
+   dpu_kms->mmio + cat->cdm->base, 
cat->cdm->name);
+
pm_runtime_put_sync(&dpu_kms->pdev->dev);
 }
 
-- 
2.40.1



[PATCH 13/16] drm/msm/dpu: reserve cdm blocks for writeback in case of YUV output

2023-08-30 Thread Abhinav Kumar
Reserve CDM blocks for writeback if the format of the output fb
is YUV. At the moment, the reservation is done only for writeback
but can easily be extended by relaxing the checks once other
interfaces are ready to output YUV.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 35 -
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 1b1e07292a9e..7a3d179bdfba 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "msm_drv.h"
 #include "dpu_kms.h"
@@ -615,9 +616,11 @@ static int dpu_encoder_virt_atomic_check(
struct drm_display_mode *adj_mode;
struct msm_display_topology topology;
struct dpu_global_state *global_state;
+   struct drm_framebuffer *fb;
struct drm_dsc_config *dsc;
int i = 0;
int ret = 0;
+   bool needs_cdm = false;
 
if (!drm_enc || !crtc_state || !conn_state) {
DPU_ERROR("invalid arg(s), drm_enc %d, crtc/conn state %d/%d\n",
@@ -655,6 +658,22 @@ static int dpu_encoder_virt_atomic_check(
 
topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, 
crtc_state, dsc);
 
+   /*
+* Use CDM only for writeback at the moment as other interfaces cannot 
handle it.
+* if writeback itself cannot handle cdm for some reason it will fail 
in its atomic_check()
+* earlier.
+*/
+   if (dpu_enc->disp_info.intf_type == INTF_WB && 
conn_state->writeback_job) {
+   fb = conn_state->writeback_job->fb;
+
+   if (fb && 
DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb
+   needs_cdm = true;
+   if (needs_cdm && !dpu_enc->cur_master->hw_cdm)
+   crtc_state->mode_changed = true;
+   else if (!needs_cdm && dpu_enc->cur_master->hw_cdm)
+   crtc_state->mode_changed = true;
+   }
+
/*
 * Release and Allocate resources on every modeset
 * Dont allocate when active is false.
@@ -664,7 +683,7 @@ static int dpu_encoder_virt_atomic_check(
 
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
-   drm_enc, crtc_state, topology, false);
+   drm_enc, crtc_state, topology, 
needs_cdm);
}
 
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
@@ -1126,6 +1145,20 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
 
dpu_enc->dsc_mask = dsc_mask;
 
+   if (dpu_enc->disp_info.intf_type == INTF_WB && 
conn_state->writeback_job) {
+   struct dpu_hw_blk *hw_cdm = NULL;
+   struct drm_framebuffer *fb;
+
+   fb = conn_state->writeback_job->fb;
+
+   if (fb && 
DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb {
+   dpu_rm_get_assigned_resources(&dpu_kms->rm, 
global_state,
+ drm_enc->base.id, 
DPU_HW_BLK_CDM,
+ &hw_cdm, 1);
+   }
+   dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : 
NULL;
+   }
+
cstate = to_dpu_crtc_state(crtc_state);
 
for (i = 0; i < num_lm; i++) {
-- 
2.40.1



[PATCH 15/16] drm/msm/dpu: add NV12 in the list of supported WB formats

2023-08-30 Thread Abhinav Kumar
Since CDM block support has now been added for writeback blocks
add NV12 in the list of supported WB formats.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 713dfc079718..978330c6678e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -244,6 +244,7 @@ static const uint32_t wb2_formats[] = {
DRM_FORMAT_BGRA,
DRM_FORMAT_BGRX,
DRM_FORMAT_XBGR,
+   DRM_FORMAT_NV12,
 };
 
 /*
-- 
2.40.1



[PATCH 09/16] drm/msm/dpu: add CDM related logic to dpu_hw_ctl layer

2023-08-30 Thread Abhinav Kumar
CDM block will need its own logic to program the flush and active
bits in the dpu_hw_ctl layer.

Make necessary changes in dpu_hw_ctl to support CDM programming.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 34 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 11 +++
 2 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index c278fb9d2b5b..beced9f19740 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -29,11 +29,13 @@
 #define   CTL_DSC_ACTIVE0x0E8
 #define   CTL_WB_ACTIVE 0x0EC
 #define   CTL_INTF_ACTIVE   0x0F4
+#define   CTL_CDM_ACTIVE0x0F8
 #define   CTL_FETCH_PIPE_ACTIVE 0x0FC
 #define   CTL_MERGE_3D_FLUSH0x100
 #define   CTL_DSC_FLUSH0x104
 #define   CTL_WB_FLUSH  0x108
 #define   CTL_INTF_FLUSH0x110
+#define   CTL_CDM_FLUSH0x114
 #define   CTL_INTF_MASTER   0x134
 #define   CTL_DSPP_n_FLUSH(n)   ((0x13C) + ((n) * 4))
 
@@ -43,6 +45,7 @@
 #define DPU_REG_RESET_TIMEOUT_US2000
 #define  MERGE_3D_IDX   23
 #define  DSC_IDX22
+#define CDM_IDX 26
 #define  INTF_IDX   31
 #define WB_IDX  16
 #define  DSPP_IDX   29  /* From DPU hw rev 7.x.x */
@@ -104,6 +107,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct 
dpu_hw_ctl *ctx)
ctx->pending_wb_flush_mask = 0;
ctx->pending_merge_3d_flush_mask = 0;
ctx->pending_dsc_flush_mask = 0;
+   ctx->pending_cdm_flush_mask = 0;
 
memset(ctx->pending_dspp_flush_mask, 0,
sizeof(ctx->pending_dspp_flush_mask));
@@ -148,6 +152,10 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct 
dpu_hw_ctl *ctx)
DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
  ctx->pending_dsc_flush_mask);
 
+   if (ctx->pending_flush_mask & BIT(CDM_IDX))
+   DPU_REG_WRITE(&ctx->hw, CTL_CDM_FLUSH,
+ ctx->pending_cdm_flush_mask);
+
DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
 }
 
@@ -273,6 +281,12 @@ static void dpu_hw_ctl_update_pending_flush_wb(struct 
dpu_hw_ctl *ctx,
}
 }
 
+static void dpu_hw_ctl_update_pending_flush_cdm(struct dpu_hw_ctl *ctx)
+{
+   ctx->pending_flush_mask |= BIT(CDM_IDX);
+
+}
+
 static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
enum dpu_wb wb)
 {
@@ -301,6 +315,12 @@ static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct 
dpu_hw_ctl *ctx,
ctx->pending_flush_mask |= BIT(DSC_IDX);
 }
 
+static void dpu_hw_ctl_update_pending_flush_cdm_v1(struct dpu_hw_ctl *ctx)
+{
+   ctx->pending_cdm_flush_mask |= BIT(0);
+   ctx->pending_flush_mask |= BIT(CDM_IDX);
+}
+
 static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
enum dpu_dspp dspp, u32 dspp_sub_blk)
 {
@@ -504,6 +524,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
u32 intf_active = 0;
u32 wb_active = 0;
u32 mode_sel = 0;
+   u32 cdm_active = 0;
 
/* CTL_TOP[31:28] carries group_id to collate CTL paths
 * per VM. Explicitly disable it until VM support is
@@ -517,6 +538,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
 
intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
+   cdm_active = DPU_REG_READ(c, CTL_CDM_ACTIVE);
 
if (cfg->intf)
intf_active |= BIT(cfg->intf - INTF_0);
@@ -534,6 +556,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
 
if (cfg->dsc)
DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
+
+   if (cfg->cdm)
+   DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm);
 }
 
 static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
@@ -577,6 +602,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl 
*ctx,
u32 wb_active = 0;
u32 merge3d_active = 0;
u32 dsc_active;
+   u32 cdm_active;
 
/*
 * This API resets each portion of the CTL path namely,
@@ -612,6 +638,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl 
*ctx,
dsc_active &= ~cfg->dsc;
DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
}
+
+   if (cfg->cdm) {
+   cdm_active = DPU_REG_READ(c, CTL_CDM_ACTIVE);
+   cdm_active &= ~cfg->cdm;
+   DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cdm_active);
+   }
 }
 
 static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx,
@@ -645,12 +677,14 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->update_pending_flush_wb = 
dpu_hw_ctl_update_pending_flush_wb_v1;
ops->update_pending_flush_dsc =

[PATCH 14/16] drm/msm/dpu: do not allow YUV formats if no CDM block is present

2023-08-30 Thread Abhinav Kumar
On chipsets where CDM block is not available OR where support has
not been added yet do not allow YUV formats for writeback block.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 7fc174b33ae2..d8edca9bc964 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -406,6 +406,12 @@ static int dpu_encoder_phys_wb_atomic_check(
return ret;
}
 
+   if (DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb))) &&
+   !phys_enc->dpu_kms->catalog->cdm) {
+   DPU_ERROR("cannot support YUV formats without CDM block\n");
+   return -EINVAL;
+   }
+
return 0;
 }
 
-- 
2.40.1



[PATCH 07/16] drm/msm/dpu: add cdm blocks to RM

2023-08-30 Thread Abhinav Kumar
Add the RM APIs necessary to initialize and allocate CDM
blocks by the rest of the DPU pipeline.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 17 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index f9215643c71a..7b6444a3fcb1 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_kms.h"
 #include "dpu_hw_lm.h"
 #include "dpu_hw_ctl.h"
+#include "dpu_hw_cdm.h"
 #include "dpu_hw_pingpong.h"
 #include "dpu_hw_sspp.h"
 #include "dpu_hw_intf.h"
@@ -90,6 +91,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
}
}
 
+   if (rm->cdm_blk)
+   dpu_hw_cdm_destroy(to_dpu_hw_cdm(rm->cdm_blk));
+
for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
dpu_hw_wb_destroy(rm->hw_wb[i]);
 
@@ -240,6 +244,19 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
}
 
+   if (cat->cdm) {
+   struct dpu_hw_cdm *hw;
+
+   hw = dpu_hw_cdm_init(cat->cdm, mmio);
+   /* CDM is optional so no need to bail out */
+   if (IS_ERR(hw)) {
+   rc = PTR_ERR(hw);
+   DPU_DEBUG("failed cdm object creation: err %d\n", rc);
+   } else {
+   rm->cdm_blk = &hw->base;
+   }
+   }
+
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 2b551566cbf4..29b221491926 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -22,6 +22,7 @@ struct dpu_global_state;
  * @hw_wb: array of wb hardware resources
  * @dspp_blks: array of dspp hardware resources
  * @hw_sspp: array of sspp hardware resources
+ * @cdm_blk: cdm hardware resource
  */
 struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@@ -33,6 +34,7 @@ struct dpu_rm {
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];
+   struct dpu_hw_blk *cdm_blk;
 };
 
 /**
-- 
2.40.1



[PATCH 11/16] drm/msm/dpu: add an API to setup the CDM block for writeback

2023-08-30 Thread Abhinav Kumar
Add an API dpu_encoder_helper_phys_setup_cdm() which can be used by
the writeback encoder to setup the CDM block.

Currently, this is defined and used within the writeback's physical
encoder layer however, the function can be modified to be used to setup
the CDM block even for non-writeback interfaces.

Until those modifications are planned and made, keep it local to
writeback.

Signed-off-by: Abhinav Kumar 
---
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |   3 +
 .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c   | 123 +-
 2 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 510c1c41ddbc..93a8ae67beff 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -16,6 +16,7 @@
 #include "dpu_hw_pingpong.h"
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_top.h"
+#include "dpu_hw_cdm.h"
 #include "dpu_encoder.h"
 #include "dpu_crtc.h"
 
@@ -209,6 +210,7 @@ static inline int dpu_encoder_phys_inc_pending(struct 
dpu_encoder_phys *phys)
  * @wbirq_refcount: Reference count of writeback interrupt
  * @wb_done_timeout_cnt: number of wb done irq timeout errors
  * @wb_cfg:  writeback block config to store fb related details
+ * @cdm_cfg: cdm block config needed to store writeback block's CDM 
configuration
  * @wb_conn: backpointer to writeback connector
  * @wb_job: backpointer to current writeback job
  * @dest:   dpu buffer layout for current writeback output buffer
@@ -218,6 +220,7 @@ struct dpu_encoder_phys_wb {
atomic_t wbirq_refcount;
int wb_done_timeout_cnt;
struct dpu_hw_wb_cfg wb_cfg;
+   struct dpu_hw_cdm_cfg cdm_cfg;
struct drm_writeback_connector *wb_conn;
struct drm_writeback_job *wb_job;
struct dpu_hw_fmt_layout dest;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 4c2736c3ee6d..11935aac9fd5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -24,6 +24,20 @@
 #define to_dpu_encoder_phys_wb(x) \
container_of(x, struct dpu_encoder_phys_wb, base)
 
+#define TO_S15D16(_x_)((_x_) << 7)
+
+static struct dpu_csc_cfg dpu_encoder_phys_wb_rgb2yuv_601l = {
+   {
+   TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032),
+   TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1),
+   TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc)
+   },
+   { 0x00, 0x00, 0x00 },
+   { 0x0040, 0x0200, 0x0200 },
+   { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff },
+   { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 },
+};
+
 /**
  * dpu_encoder_phys_wb_is_master - report wb always as master encoder
  * @phys_enc:  Pointer to physical encoder
@@ -225,6 +239,112 @@ static void dpu_encoder_phys_wb_setup_ctl(struct 
dpu_encoder_phys *phys_enc)
}
 }
 
+/**
+ * dpu_encoder_phys_wb_setup_cdp - setup chroma down sampling block
+ * @phys_enc:Pointer to physical encoder
+ */
+static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys 
*phys_enc)
+{
+   struct dpu_hw_cdm *hw_cdm;
+   struct dpu_hw_cdm_cfg *cdm_cfg;
+   struct dpu_hw_pingpong *hw_pp;
+   struct dpu_encoder_phys_wb *wb_enc;
+   const struct msm_format *format;
+   const struct dpu_format *dpu_fmt;
+   struct drm_writeback_job *wb_job;
+   int ret;
+
+   if (!phys_enc)
+   return;
+
+   wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+   cdm_cfg = &wb_enc->cdm_cfg;
+   hw_pp = phys_enc->hw_pp;
+   hw_cdm = phys_enc->hw_cdm;
+   wb_job = wb_enc->wb_job;
+
+   format = msm_framebuffer_format(wb_enc->wb_job->fb);
+   dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, 
wb_job->fb->modifier);
+
+   if (!hw_cdm)
+   return;
+
+   if (!DPU_FORMAT_IS_YUV(dpu_fmt)) {
+   DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", 
DRMID(phys_enc->parent),
+ dpu_fmt->base.pixel_format);
+   if (hw_cdm->ops.disable)
+   hw_cdm->ops.disable(hw_cdm);
+
+   return;
+   }
+
+   memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg));
+
+   cdm_cfg->output_width = wb_job->fb->width;
+   cdm_cfg->output_height = wb_job->fb->height;
+   cdm_cfg->output_fmt = dpu_fmt;
+   cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB;
+   cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ?
+   CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT;
+
+   /* enable 10 bit logic */
+   switch (cdm_cfg->output_fmt->chroma_sample) {
+   case DPU_CHROMA_RGB:
+   cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
+   cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
+   break;
+   case DPU_CHROMA_H2V1:
+   cdm_c

[PATCH 08/16] drm/msm/dpu: add support to allocate CDM from RM

2023-08-30 Thread Abhinav Kumar
Even though there is usually only one CDM block, it can be
used by either HDMI, DisplayPort OR Writeback interfaces.

Hence its allocation needs to be tracked properly by the
resource manager to ensure appropriate availability of the
block.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 45 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  4 +-
 5 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 6cf6597148fd..582680804016 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -663,7 +663,7 @@ static int dpu_encoder_virt_atomic_check(
 
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
-   drm_enc, crtc_state, topology);
+   drm_enc, crtc_state, topology, false);
}
 
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 34f943102499..07f75f295844 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -98,6 +98,7 @@ enum dpu_hw_blk_type {
DPU_HW_BLK_DSPP,
DPU_HW_BLK_MERGE_3D,
DPU_HW_BLK_DSC,
+   DPU_HW_BLK_CDM,
DPU_HW_BLK_MAX,
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index b6f53ca6e962..61aa58643fda 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -136,6 +136,7 @@ struct dpu_global_state {
uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
+   uint32_t cdm_to_enc_id;
 };
 
 struct dpu_global_state
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 7b6444a3fcb1..e7d4beb4661e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -29,10 +29,12 @@ static inline bool reserved_by_other(uint32_t *res_map, int 
idx,
 /**
  * struct dpu_rm_requirements - Reservation requirements parameter bundle
  * @topology:  selected topology for the display
+ * @needs_cdm: whether the display needs a CDM block for the current mode
  * @hw_res:   Hardware resources required as reported by the encoders
  */
 struct dpu_rm_requirements {
struct msm_display_topology topology;
+   bool needs_cdm;
 };
 
 int dpu_rm_destroy(struct dpu_rm *rm)
@@ -505,6 +507,26 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
return 0;
 }
 
+static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
+  struct dpu_global_state *global_state,
+  struct drm_encoder *enc)
+{
+   /* try allocating only one CDM block */
+   if (!rm->cdm_blk) {
+   DPU_ERROR("CDM block does not exist\n");
+   return -EIO;
+   }
+
+   if (global_state->cdm_to_enc_id) {
+   DPU_ERROR("CDM_0 is already allocated\n");
+   return -EIO;
+   }
+
+   global_state->cdm_to_enc_id = enc->base.id;
+
+   return 0;
+}
+
 static int _dpu_rm_make_reservation(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
@@ -530,15 +552,25 @@ static int _dpu_rm_make_reservation(
if (ret)
return ret;
 
+   if (reqs->needs_cdm) {
+   ret = _dpu_rm_reserve_cdm(rm, global_state, enc);
+   if (ret) {
+   DPU_ERROR("unable to find CDM blk\n");
+   return ret;
+   }
+   }
+
return ret;
 }
 
 static int _dpu_rm_populate_requirements(
struct drm_encoder *enc,
struct dpu_rm_requirements *reqs,
-   struct msm_display_topology req_topology)
+   struct msm_display_topology req_topology,
+   bool needs_cdm)
 {
reqs->topology = req_topology;
+   reqs->needs_cdm = needs_cdm;
 
DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
  reqs->topology.num_lm, reqs->topology.num_dsc,
@@ -571,6 +603,7 @@ void dpu_rm_release(struct dpu_global_state *global_state,
ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
_dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
+   _dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id);
 }
 
 int dpu_rm_r

[PATCH 03/16] drm/msm/dpu: rename dpu_encoder_phys_wb_setup_cdp to match its functionality

2023-08-30 Thread Abhinav Kumar
dpu_encoder_phys_wb_setup_cdp() is not programming the chroma down
prefetch block. Its setting up the display ctl path for writeback.

Hence rename it to dpu_encoder_phys_wb_setup_ctl() to match what its
actually doing.

Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for 
writeback")
Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 6a1f8e34f18a..4c2736c3ee6d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -173,10 +173,10 @@ static void dpu_encoder_phys_wb_setup_fb(struct 
dpu_encoder_phys *phys_enc,
 }
 
 /**
- * dpu_encoder_phys_wb_setup_cdp - setup chroma down prefetch block
+ * dpu_encoder_phys_wb_setup_ctl - setup wb pipeline for ctl path
  * @phys_enc:Pointer to physical encoder
  */
-static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc)
+static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc)
 {
struct dpu_hw_wb *hw_wb;
struct dpu_hw_ctl *ctl;
@@ -348,7 +348,7 @@ static void dpu_encoder_phys_wb_setup(
 
dpu_encoder_phys_wb_setup_fb(phys_enc, fb);
 
-   dpu_encoder_phys_wb_setup_cdp(phys_enc);
+   dpu_encoder_phys_wb_setup_ctl(phys_enc);
 
 }
 
-- 
2.40.1



[PATCH 06/16] drm/msm/dpu: add dpu_hw_cdm abstraction for CDM block

2023-08-30 Thread Abhinav Kumar
CDM block comes with its own set of registers and operations
which can be done. In-line with other hardware sub-blocks, this
change adds the dpu_hw_cdm abstraction for the CDM block.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c  | 272 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h  | 135 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |   1 +
 4 files changed, 409 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 8d02d8c33069..2010cb1ca995 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_encoder_phys_wb.o \
disp/dpu1/dpu_formats.o \
disp/dpu1/dpu_hw_catalog.o \
+   disp/dpu1/dpu_hw_cdm.o \
disp/dpu1/dpu_hw_ctl.o \
disp/dpu1/dpu_hw_dsc.o \
disp/dpu1/dpu_hw_dsc_1_2.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
new file mode 100644
index ..a2f7ee8f54e4
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_cdm.h"
+#include "dpu_kms.h"
+
+#define CDM_CSC_10_OPMODE  0x000
+#define CDM_CSC_10_BASE0x004
+
+#define CDM_CDWN2_OP_MODE  0x100
+#define CDM_CDWN2_CLAMP_OUT0x104
+#define CDM_CDWN2_PARAMS_3D_0  0x108
+#define CDM_CDWN2_PARAMS_3D_1  0x10C
+#define CDM_CDWN2_COEFF_COSITE_H_0 0x110
+#define CDM_CDWN2_COEFF_COSITE_H_1 0x114
+#define CDM_CDWN2_COEFF_COSITE_H_2 0x118
+#define CDM_CDWN2_COEFF_OFFSITE_H_00x11C
+#define CDM_CDWN2_COEFF_OFFSITE_H_10x120
+#define CDM_CDWN2_COEFF_OFFSITE_H_20x124
+#define CDM_CDWN2_COEFF_COSITE_V   0x128
+#define CDM_CDWN2_COEFF_OFFSITE_V  0x12C
+#define CDM_CDWN2_OUT_SIZE 0x130
+
+#define CDM_HDMI_PACK_OP_MODE  0x200
+#define CDM_CSC_10_MATRIX_COEFF_0  0x004
+
+#define CDM_MUX0x224
+
+/**
+ * Horizontal coefficients for cosite chroma downscale
+ * s13 representation of coefficients
+ */
+static u32 cosite_h_coeff[] = {0x0016, 0x01cc, 0x019e};
+
+/**
+ * Horizontal coefficients for offsite chroma downscale
+ */
+static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046};
+
+/**
+ * Vertical coefficients for cosite chroma downscale
+ */
+static u32 cosite_v_coeff[] = {0x00080004};
+/**
+ * Vertical coefficients for offsite chroma downscale
+ */
+static u32 offsite_v_coeff[] = {0x00060002};
+
+static int dpu_hw_cdm_setup_csc_10bit(struct dpu_hw_cdm *ctx, struct 
dpu_csc_cfg *data)
+{
+   dpu_hw_csc_setup(&ctx->hw, CDM_CSC_10_MATRIX_COEFF_0, data, true);
+
+   return 0;
+}
+
+static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg 
*cfg)
+{
+   struct dpu_hw_blk_reg_map *c = &ctx->hw;
+   u32 opmode = 0;
+   u32 out_size = 0;
+
+   if (cfg->output_bit_depth == CDM_CDWN_OUTPUT_10BIT)
+   opmode &= ~BIT(7);
+   else
+   opmode |= BIT(7);
+
+   /* ENABLE DWNS_H bit */
+   opmode |= BIT(1);
+
+   switch (cfg->h_cdwn_type) {
+   case CDM_CDWN_DISABLE:
+   /* CLEAR METHOD_H field */
+   opmode &= ~(0x18);
+   /* CLEAR DWNS_H bit */
+   opmode &= ~BIT(1);
+   break;
+   case CDM_CDWN_PIXEL_DROP:
+   /* Clear METHOD_H field (pixel drop is 0) */
+   opmode &= ~(0x18);
+   break;
+   case CDM_CDWN_AVG:
+   /* Clear METHOD_H field (Average is 0x1) */
+   opmode &= ~(0x18);
+   opmode |= (0x1 << 0x3);
+   break;
+   case CDM_CDWN_COSITE:
+   /* Clear METHOD_H field (Average is 0x2) */
+   opmode &= ~(0x18);
+   opmode |= (0x2 << 0x3);
+   /* Co-site horizontal coefficients */
+   DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_0,
+   cosite_h_coeff[0]);
+   DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_1,
+   cosite_h_coeff[1]);
+   DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_2,
+   cosite_h_coeff[2]);
+   break;
+   case CDM_CDWN_OFFSITE:
+   /* Clear METHOD_H field (Average is 0x3) */
+   opmode &= ~(0x18);
+   opmode |= (0x3 << 0x3);
+
+   /* Off-site horizon

[PATCH 05/16] drm/msm/dpu: add cdm blocks to sm8250 dpu_hw_catalog

2023-08-30 Thread Abhinav Kumar
Add CDM blocks to the sm8250 dpu_hw_catalog to support
YUV format output from writeback block.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
index 5f9b437b82a6..2d98d14a0f68 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
@@ -389,10 +389,19 @@ static const struct dpu_mdss_version sm8250_mdss_ver = {
.core_minor_ver = 0,
 };
 
+static const struct dpu_cdm_cfg sm8250_cdm = {
+   .name = "cdm_0",
+   .id = CDM_0,
+   .len = 0x228,
+   .base = 0x79200,
+   .features = 0,
+};
+
 const struct dpu_mdss_cfg dpu_sm8250_cfg = {
.mdss_ver = &sm8250_mdss_ver,
.caps = &sm8250_dpu_caps,
.mdp = &sm8250_mdp,
+   .cdm = &sm8250_cdm,
.ctl_count = ARRAY_SIZE(sm8250_ctl),
.ctl = sm8250_ctl,
.sspp_count = ARRAY_SIZE(sm8250_sspp),
-- 
2.40.1



[PATCH 02/16] drm/msm/dpu: add formats check for writeback encoder

2023-08-30 Thread Abhinav Kumar
In preparation of adding more formats to dpu writeback add
format validation to it to fail any unsupported formats.

Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for 
writeback")
Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 284a88060221..6a1f8e34f18a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -238,6 +238,7 @@ static int dpu_encoder_phys_wb_atomic_check(
 {
struct drm_framebuffer *fb;
const struct drm_display_mode *mode = &crtc_state->mode;
+   int ret;
 
DPU_DEBUG("[atomic_check:%d, \"%s\",%d,%d]\n",
phys_enc->hw_wb->idx, mode->name, mode->hdisplay, 
mode->vdisplay);
@@ -274,6 +275,12 @@ static int dpu_encoder_phys_wb_atomic_check(
return -EINVAL;
}
 
+   ret = drm_atomic_helper_check_wb_encoder_state(phys_enc->parent, 
conn_state);
+   if (ret < 0) {
+   DPU_ERROR("invalid pixel format %p4cc\n", &fb->format->format);
+   return ret;
+   }
+
return 0;
 }
 
-- 
2.40.1



[PATCH 04/16] drm/msm/dpu: add cdm blocks to sc7280 dpu_hw_catalog

2023-08-30 Thread Abhinav Kumar
Add CDM blocks to the sc7280 dpu_hw_catalog to support
YUV format output from writeback block.

Signed-off-by: Abhinav Kumar 
---
 .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h  |  9 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h  | 13 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |  5 +
 3 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
index 3b5061c4402a..5252170f216d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
@@ -251,10 +251,19 @@ static const struct dpu_mdss_version sc7280_mdss_ver = {
.core_minor_ver = 2,
 };
 
+static const struct dpu_cdm_cfg sc7280_cdm = {
+   .name = "cdm_0",
+   .id = CDM_0,
+   .len = 0x228,
+   .base = 0x79200,
+   .features = 0,
+};
+
 const struct dpu_mdss_cfg dpu_sc7280_cfg = {
.mdss_ver = &sc7280_mdss_ver,
.caps = &sc7280_dpu_caps,
.mdp = &sc7280_mdp,
+   .cdm = &sc7280_cdm,
.ctl_count = ARRAY_SIZE(sc7280_ctl),
.ctl = sc7280_ctl,
.sspp_count = ARRAY_SIZE(sc7280_sspp),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 6c9634209e9f..4ea7c3f85a95 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -693,6 +693,17 @@ struct dpu_vbif_cfg {
u32 memtype[MAX_XIN_COUNT];
 };
 
+/**
+ * struct dpu_cdm_cfg - information of chroma down blocks
+ * @name   string name for debug purposes
+ * @id enum identifying this block
+ * @base   register offset of this block
+ * @features   bit mask identifying sub-blocks/features
+ */
+struct dpu_cdm_cfg {
+   DPU_HW_BLK_INFO;
+};
+
 /**
  * Define CDP use cases
  * @DPU_PERF_CDP_UDAGE_RT: real-time use cases
@@ -816,6 +827,8 @@ struct dpu_mdss_cfg {
u32 wb_count;
const struct dpu_wb_cfg *wb;
 
+   const struct dpu_cdm_cfg *cdm;
+
u32 ad_count;
 
u32 dspp_count;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index d85157acfbf8..4d6dba18caf0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -185,6 +185,11 @@ enum dpu_dsc {
DSC_MAX
 };
 
+enum dpu_cdm {
+   CDM_0 = 1,
+   CDM_MAX
+};
+
 enum dpu_pingpong {
PINGPONG_NONE,
PINGPONG_0,
-- 
2.40.1



[PATCH 01/16] drm/msm/dpu: fix writeback programming for YUV cases

2023-08-30 Thread Abhinav Kumar
For YUV cases, setting the required format bits was missed
out in the register programming. Lets fix it now in preparation
of adding YUV formats support for writeback.

Fixes: 84a33d0fd921 ("drm/msm/dpu: add dpu_hw_wb abstraction for writeback 
blocks")
Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
index ebc416400382..0aa598b355e9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
@@ -86,6 +86,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx,
dst_format |= BIT(14); /* DST_ALPHA_X */
}
 
+   if (DPU_FORMAT_IS_YUV(fmt))
+   dst_format |= BIT(15);
+
pattern = (fmt->element[3] << 24) |
(fmt->element[2] << 16) |
(fmt->element[1] << 8)  |
-- 
2.40.1



[PATCH 00/16] Add CDM support for MSM writeback

2023-08-30 Thread Abhinav Kumar
Chroma Down Sampling (CDM) block is a hardware block in the DPU pipeline
which among other things has a CSC block that can convert RGB input
from the DPU to YUV data.

This block can be used with either HDMI, DP or writeback interface.

In this series, lets first add the support for CDM block to be used
with writeback and then follow-up with support for other interfaces such
as DP.

This was validated by adding support to pass custom output format to the
IGT's kms_writeback test-case, specifically only for the output dump
test-case [1].

The usage for this is:

./kms_writeback -d -f 

So for NV12, this can be verified with the below command:

./kms_writeback -d -f NV12

[1] : https://patchwork.freedesktop.org/series/122125/


Abhinav Kumar (16):
  drm/msm/dpu: fix writeback programming for YUV cases
  drm/msm/dpu: add formats check for writeback encoder
  drm/msm/dpu: rename dpu_encoder_phys_wb_setup_cdp to match its
functionality
  drm/msm/dpu: add cdm blocks to sc7280 dpu_hw_catalog
  drm/msm/dpu: add cdm blocks to sm8250 dpu_hw_catalog
  drm/msm/dpu: add dpu_hw_cdm abstraction for CDM block
  drm/msm/dpu: add cdm blocks to RM
  drm/msm/dpu: add support to allocate CDM from RM
  drm/msm/dpu: add CDM related logic to dpu_hw_ctl layer
  drm/msm/dpu: add support to disable CDM block during encoder cleanup
  drm/msm/dpu: add an API to setup the CDM block for writeback
  drm/msm/dpu: plug-in the cdm related bits to writeback setup
  drm/msm/dpu: reserve cdm blocks for writeback in case of YUV output
  drm/msm/dpu: do not allow YUV formats if no CDM block is present
  drm/msm/dpu: add NV12 in the list of supported WB formats
  drm/msm/dpu: add cdm blocks to dpu snapshot

 drivers/gpu/drm/msm/Makefile  |   1 +
 .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h|   9 +
 .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h|   9 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  43 ++-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |   5 +
 .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c   | 150 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|   1 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|  13 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c| 272 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h| 135 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c|  34 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h|  11 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |   7 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c |   3 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   4 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c|  62 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h|   6 +-
 18 files changed, 758 insertions(+), 8 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h

-- 
2.40.1



[PATCH v2 1/2] drm/amdgpu: Merge debug module parameters

2023-08-30 Thread André Almeida
Merge all developer debug options available as separated module
parameters in one, making it obvious that are for developers.

Drop the obsolete module options in favor of the new ones.

Signed-off-by: André Almeida 
---
v2:
- drop old module params
- use BIT() macros
- replace global var with adev-> vars
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  4 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 48 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c   |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_crat.c|  2 +-
 drivers/gpu/drm/amd/include/amd_shared.h |  8 
 8 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 4de074243c4d..82eaccfce347 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1101,6 +1101,10 @@ struct amdgpu_device {
booldc_enabled;
/* Mask of active clusters */
uint32_taid_mask;
+
+   /* Debug */
+   booldebug_vm;
+   booldebug_largebar;
 };
 
 static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index fb78a8f47587..8a26bed76505 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1191,7 +1191,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
job->vm_pd_addr = amdgpu_gmc_pd_addr(vm->root.bo);
}
 
-   if (amdgpu_vm_debug) {
+   if (adev->debug_vm) {
/* Invalidate all BOs to test for userspace bugs */
amdgpu_bo_list_for_each_entry(e, p->bo_list) {
struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index f5856b82605e..0cd48c025433 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -140,7 +140,6 @@ int amdgpu_vm_size = -1;
 int amdgpu_vm_fragment_size = -1;
 int amdgpu_vm_block_size = -1;
 int amdgpu_vm_fault_stop;
-int amdgpu_vm_debug;
 int amdgpu_vm_update_mode = -1;
 int amdgpu_exp_hw_support;
 int amdgpu_dc = -1;
@@ -194,6 +193,7 @@ int amdgpu_use_xgmi_p2p = 1;
 int amdgpu_vcnfw_log;
 int amdgpu_sg_display = -1; /* auto */
 int amdgpu_user_partt_mode = AMDGPU_AUTO_COMPUTE_PARTITION_MODE;
+uint amdgpu_debug_mask;
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
@@ -405,13 +405,6 @@ module_param_named(vm_block_size, amdgpu_vm_block_size, 
int, 0444);
 MODULE_PARM_DESC(vm_fault_stop, "Stop on VM fault (0 = never (default), 1 = 
print first, 2 = always)");
 module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444);
 
-/**
- * DOC: vm_debug (int)
- * Debug VM handling (0 = disabled, 1 = enabled). The default is 0 (Disabled).
- */
-MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = 
enabled)");
-module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
-
 /**
  * DOC: vm_update_mode (int)
  * Override VM update mode. VM updated by using CPU (0 = never, 1 = Graphics 
only, 2 = Compute only, 3 = Both). The default
@@ -743,18 +736,6 @@ module_param(send_sigterm, int, 0444);
 MODULE_PARM_DESC(send_sigterm,
"Send sigterm to HSA process on unhandled exception (0 = disable, 1 = 
enable)");
 
-/**
- * DOC: debug_largebar (int)
- * Set debug_largebar as 1 to enable simulating large-bar capability on 
non-large bar
- * system. This limits the VRAM size reported to ROCm applications to the 
visible
- * size, usually 256MB.
- * Default value is 0, diabled.
- */
-int debug_largebar;
-module_param(debug_largebar, int, 0444);
-MODULE_PARM_DESC(debug_largebar,
-   "Debug large-bar flag used to simulate large-bar capability on 
non-large bar machine (0 = disable, 1 = enable)");
-
 /**
  * DOC: halt_if_hws_hang (int)
  * Halt if HWS hang is detected. Default value, 0, disables the halt on hang.
@@ -938,6 +919,18 @@ module_param_named(user_partt_mode, 
amdgpu_user_partt_mode, uint, 0444);
 module_param(enforce_isolation, bool, 0444);
 MODULE_PARM_DESC(enforce_isolation, "enforce process isolation between 
graphics and compute . enforce_isolation = on");
 
+/**
+ * DOC: debug_mask (uint)
+ * Debug options for amdgpu, work as a binary mask with the following options:
+ *
+ * - 0x1: Debug VM handling
+ * - 0x2: Enable simulating large-bar capability on non-large bar system. This
+ *   limits the VRAM size reported to ROCm applications to the visible
+ *   size, usually 256MB.
+ */
+MODULE_PARM_DESC(debug_mask, "debug options for amdgpu, disabled by default");
+module_param_named(debug_mask, amdgp

[PATCH v2 2/2] drm/amdgpu: Create an option to disable soft recovery

2023-08-30 Thread André Almeida
Create a module option to disable soft recoveries on amdgpu, making
every recovery go through the device reset path. This option makes
easier to force device resets for testing and debugging purposes.

Signed-off-by: André Almeida 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h  | 1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 6 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 6 +-
 drivers/gpu/drm/amd/include/amd_shared.h | 1 +
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 82eaccfce347..5f49e2c0ae7a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1105,6 +1105,7 @@ struct amdgpu_device {
/* Debug */
booldebug_vm;
booldebug_largebar;
+   booldebug_disable_soft_recovery;
 };
 
 static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 0cd48c025433..59e9fe594b51 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -927,6 +927,7 @@ MODULE_PARM_DESC(enforce_isolation, "enforce process 
isolation between graphics
  * - 0x2: Enable simulating large-bar capability on non-large bar system. This
  *   limits the VRAM size reported to ROCm applications to the visible
  *   size, usually 256MB.
+ * - 0x4: Disable GPU soft recovery
  */
 MODULE_PARM_DESC(debug_mask, "debug options for amdgpu, disabled by default");
 module_param_named(debug_mask, amdgpu_debug_mask, uint, 0444);
@@ -2046,6 +2047,11 @@ static void amdgpu_init_debug_options(struct 
amdgpu_device *adev)
pr_info("debug: enabled simulating large-bar capability on 
non-large bar system\n");
adev->debug_largebar = true;
}
+
+   if (amdgpu_debug_mask & AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY) {
+   pr_info("debug: soft reset for GPU recovery disabled\n");
+   adev->debug_disable_soft_recovery = true;
+   }
 }
 
 static int amdgpu_pci_probe(struct pci_dev *pdev,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 80d6e132e409..6a80d3ec887e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -434,8 +434,12 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, 
unsigned int vmid,
   struct dma_fence *fence)
 {
unsigned long flags;
+   ktime_t deadline;
 
-   ktime_t deadline = ktime_add_us(ktime_get(), 1);
+   if (unlikely(ring->adev->debug_disable_soft_recovery))
+   return false;
+
+   deadline = ktime_add_us(ktime_get(), 1);
 
if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || 
!fence)
return false;
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h 
b/drivers/gpu/drm/amd/include/amd_shared.h
index 2fd6af2183cc..32ee982be99e 100644
--- a/drivers/gpu/drm/amd/include/amd_shared.h
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
@@ -263,6 +263,7 @@ enum amd_dpm_forced_level;
 enum AMDGPU_DEBUG_MASK {
AMDGPU_DEBUG_VM = BIT(0),
AMDGPU_DEBUG_LARGEBAR = BIT(1),
+   AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY = BIT(2),
 };
 
 /**
-- 
2.41.0



[PATCH v2 0/2] Merge all debug module parameters

2023-08-30 Thread André Almeida
As suggested by Christian at [0], this patchset merges all debug modules
parameters and creates a new one for disabling soft recovery:

> Maybe we can overload the amdgpu_gpu_recovery module option with this. 
> Or even better merge all the developer module parameter into a 
> amdgpu_debug option. This way it should be pretty obvious that this 
> isn't meant to be used by someone who doesn't know how to use it.

[0] 
https://lore.kernel.org/dri-devel/55f69184-1aa2-55d6-4a10-1560d75c7...@amd.com/

Changelog:
- drop old module params
- use BIT() macros
- replace global var with adev-> vars
v1: https://lore.kernel.org/lkml/20230824162505.173399-1-andrealm...@igalia.com/

André Almeida (2):
  drm/amdgpu: Merge debug module parameters
  drm/amdgpu: Create an option to disable soft recovery

 drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  5 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 54 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c |  6 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c   |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_crat.c|  2 +-
 drivers/gpu/drm/amd/include/amd_shared.h |  9 
 9 files changed, 58 insertions(+), 26 deletions(-)

-- 
2.41.0



Re: [PATCH v4 0/6] drm/i915/dp_link_training: Define a final failure state when link training fails

2023-08-30 Thread Lyude Paul
Other then the name typo (s/Pual/Paul):

Signed-off-by: Lyude Paul  (just since I co-authored
things~)
Reviewed-by: Lyude Paul 

I think we definitely want to make sure we get intel's opinions on this
though, especially regarding the usage of link-status. I think we're close
enough to link-status's intended purpose, but I definitely would like to know
what others think about that since userspace will definitely have to handle
situations like this a bit differently than with SST.

Also - definitely make sure you take a look at Imre's patch series that's
currently on the list (I just finished reviewing it), since it adds some
things to the helpers that might end up being useful here :)

https://patchwork.freedesktop.org/series/122589/

On Thu, 2023-08-24 at 16:50 -0400, Gil Dekel wrote:
> Next version of https://patchwork.freedesktop.org/series/122850/
> 
> v4:
>   Another blunder. I uploaded the patches from my ChromeiumOS kernel dev repo
>   instead of drm-tip/drm-tip. Apologies for the noise :(
> 
> v3:
>   Still learning the ropes of upstream workflow. Apologies for mucking up v2.
>   This is just a re-upload.
> 
> v2:
>   Reorganize into:
>   1) Add for final failure state for SST and MST link training fallback.
>   2) Add a DRM helper for setting downstream MST ports' link-status state.
>   3) Make handling SST and MST connectors simpler via intel_dp.
>   4) Update link-status for downstream MST ports.
>   5) Emit a uevent with the "link-status" trigger property.
> 
> v1:
> Currently, when link training fails after all fallback values have been
> exhausted, the i915 driver seizes to send uevents to userspace. This leave
> userspace thinking that the last passing atomic commit was successful, and 
> that
> all connectors (displays) are connected and operational, when in fact, the 
> last
> link failed to train and the displays remain dark. This manifests as "zombie"
> displays in userspace, in which users observe the displays appear in their
> display settings page, but they are dark and unresponsive.
> 
> Since, at the time of writing, MST link training fallback is not implemented,
> failing MST link training is a significantly more common case then a complete
> SST link training failure. And with users using MST hubs more than ever to
> connect multiple displays via their USB-C ports we observe this case often.
> 
> This patchset series suggest a solution, in which a final failure state is
> defined. In this final state, the connector's bit rate capabilities, namely
> max_link_rate and max_link_lane_count, are set to 0. This effectively set the
> connector's bandwidth to 0Gbps, thus causing all its modes to be pruned in the
> following connector probing.
> 
> Next, with this state defined, we emit a link-status=Bad uevent. The next time
> userspace probes the connector, it should recognize that the connector has no
> modes and ignore it since it is in a bad state.
> 
> I am aware that always sending a uevent and never stopping may result in some
> userspaces having their expectations broken and enter an infinite loop of
> modesets and link-training attempts. However, per DRM link-status spec:
> ```
>  * link-status:
>  *  Connector link-status property to indicate the status of link. The
>  *  default value of link-status is "GOOD". If something fails during or
>  *  after modeset, the kernel driver may set this to "BAD" and issue a
>  *  hotplug uevent. Drivers should update this value using
>  *  drm_connector_set_link_status_property().
>  *
>  *  When user-space receives the hotplug uevent and detects a "BAD"
>  *  link-status, the sink doesn't receive pixels anymore (e.g. the screen
>  *  becomes completely black). The list of available modes may have
>  *  changed. User-space is expected to pick a new mode if the current one
>  *  has disappeared and perform a new modeset with link-status set to
>  *  "GOOD" to re-enable the connector.
> ```
> (form drivers/gpu/drm/drm_connector.c - DOC: standard connector properties)
> 
> it seems reasonable to assume that the suggested state is an extension of the
> spec's guidelines, in which the next new mode userspace picks for a connector
> with no modes is - none, thus breaking the cycle of failed link-training
> attempts.
> 
> I suspect that, maybe, zeroing out the bit rate capabilities is not the right
> way to go, and perhaps marking the connector as disconnected instead may be a
> better solution. However, if marking a connector disconnected is the way to 
> go,
> We will have to iterate over all MST ports in the MST case and mark the 
> spawned
> connectors as disconnected as well.

I -think- this is probably fine, that's likely how I'd 

> 
> As a final note I should add that this approach was tested with ChromeOS as
> userspace, and we observed that the zombie displays stop showing up once the
> connectors are pruned of all their modes and are ignored by userspace.
> 
> For your consideration and guidance

Re: [git pull] drm for 6.6-rc1

2023-08-30 Thread pr-tracker-bot
The pull request you sent on Wed, 30 Aug 2023 11:03:03 +1000:

> git://anongit.freedesktop.org/drm/drm tags/drm-next-2023-08-30

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/461f35f014466c4e26dca6be0f431f57297df3f2

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


Re: [PATCH v4 3/6] drm/dp_mst: Add drm_dp_set_mst_topology_link_status()

2023-08-30 Thread Lyude Paul
On Thu, 2023-08-24 at 16:50 -0400, Gil Dekel wrote:
> Unlike SST, MST can support multiple displays connected to a single
> connector. However, this also means that if the DisplayPort link to the
> top-level MST branch device becomes unstable, then every single branch
> device has an unstable link.
> 
> Since there are multiple downstream ports per connector, setting the
> link status of the parent mstb's port to BAD is not enough. All of the
> downstream mstb ports must also have their link status set to BAD.
> 
> This aligns to how the DP link status logic in DRM works. We notify
> userspace that all of the mstb ports need retraining and apply new lower
> bandwidth constraints to all future atomic commits on the topology that
> follow.
> 
> Since any driver supporting MST needs to figure out which connectors
> live downstream on an MST topology and update their link status in order
> to retrain MST links properly, we add the
> drm_dp_set_mst_topology_link_status() helper. This helper simply marks
> the link status of all connectors living in that topology as bad. We
> will make use of this helper in i915 later in this series.
> 
> Credit: this patch is a refactor of Lyude Pual's original patch:
> https://patchwork.kernel.org/project/dri-devel/patch/20180308232421.14049-5-ly...@redhat.com/

s/Pual/Paul/ (probably want to fix this on the other patches in the series as
well)

> 
> Signed-off-by: Gil Dekel 
> ---
>  drivers/gpu/drm/display/drm_dp_mst_topology.c | 39 +++
>  include/drm/display/drm_dp_mst_helper.h   |  3 ++
>  2 files changed, 42 insertions(+)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index ed96cfcfa304..17cbadfb6ccb 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -3566,6 +3566,45 @@ int drm_dp_get_vc_payload_bw(const struct 
> drm_dp_mst_topology_mgr *mgr,
>  }
>  EXPORT_SYMBOL(drm_dp_get_vc_payload_bw);
> 
> +/**
> + * drm_dp_set_mst_topology_link_status() - set all downstream MST ports' 
> link status
> + * @mgr: MST topology manager to set state for
> + * @status: The new status to set the MST topology to
> + *
> + * Set all downstream ports' link-status within the topology to the given 
> status.
> + */
> +void drm_dp_set_mst_topology_link_status(struct drm_dp_mst_topology_mgr *mgr,
> +  enum drm_link_status status)
> +{
> + struct drm_dp_mst_port *port;
> + struct drm_dp_mst_branch *rmstb;
> + struct drm_dp_mst_branch *mstb =
> + drm_dp_mst_topology_get_mstb_validated(mgr, mgr->mst_primary);
> +
> + list_for_each_entry_reverse(port, &mstb->ports, next) {
> + struct drm_connector *connector = port->connector;
> +
> + if (connector) {
> + mutex_lock(&connector->dev->mode_config.mutex);
> + drm_dbg_kms(
> + connector->dev,
> + "[MST-CONNECTOR:%d:%s] link status %d -> %d\n",
> + connector->base.id, connector->name,
> + connector->state->link_status, status);
> + connector->state->link_status = status;
> + mutex_unlock(&connector->dev->mode_config.mutex);
> + }
> +
> + rmstb = drm_dp_mst_topology_get_mstb_validated(mstb->mgr,
> +port->mstb);
> + if (rmstb) {
> + drm_dp_set_mst_topology_link_status(rmstb->mgr, status);
> + drm_dp_mst_topology_put_mstb(rmstb);
> + }
> + }
> +}
> +EXPORT_SYMBOL(drm_dp_set_mst_topology_link_status);
> +
>  /**
>   * drm_dp_read_mst_cap() - check whether or not a sink supports MST
>   * @aux: The DP AUX channel to use
> diff --git a/include/drm/display/drm_dp_mst_helper.h 
> b/include/drm/display/drm_dp_mst_helper.h
> index ed5c9660563c..855d488bf364 100644
> --- a/include/drm/display/drm_dp_mst_helper.h
> +++ b/include/drm/display/drm_dp_mst_helper.h
> @@ -832,6 +832,9 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector 
> *connector,
>  int drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,
>int link_rate, int link_lane_count);
> 
> +void drm_dp_set_mst_topology_link_status(struct drm_dp_mst_topology_mgr *mgr,
> +  enum drm_link_status status);
> +
>  int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc);
> 
>  void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, 
> uint8_t link_encoding_cap);
> --
> Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [PATCH v2 09/22] drm/dp_mst: Fix fractional bpp scaling in drm_dp_calc_pbn_mode()

2023-08-30 Thread Lyude Paul
Amazing! This work looks awesome Imre, sorry it took me a little bit to get
back to this :). For all of the DP MST helper patches:

Reviewed-by: Lyude Paul 

On Thu, 2023-08-24 at 11:05 +0300, Imre Deak wrote:
> For fractional bpp values passed to the function in a .4 fixed point
> format, the fractional part is currently ignored due to scaling bpp too
> early. Fix this by scaling the overhead factor instead and to avoid an
> overflow multiplying bpp with the overhead factor instead of the clock
> rate.
> 
> While at it simplify the formula, and pass the expected fixed point bpp
> values in the kunit tests.
> 
> Cc: Lyude Paul 
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/display/drm_dp_mst_topology.c  | 7 ++-
>  drivers/gpu/drm/tests/drm_dp_mst_helper_test.c | 8 
>  2 files changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index ed96cfcfa3040..bd0f35a0ea5fb 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -4712,12 +4712,9 @@ int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc)
>* factor in the numerator rather than the denominator to avoid
>* integer overflow
>*/
> + u32 bpp_m = (dsc ? 64 / 16 : 64) * 1006 * bpp;
>  
> - if (dsc)
> - return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 
> 1006),
> - 8 * 54 * 1000 * 1000);
> -
> - return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006),
> + return DIV_ROUND_UP_ULL(mul_u32_u32(clock, bpp_m),
>   8 * 54 * 1000 * 1000);
>  }
>  EXPORT_SYMBOL(drm_dp_calc_pbn_mode);
> diff --git a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c 
> b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c
> index 545beea33e8c7..ea2182815ebe8 100644
> --- a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c
> @@ -40,15 +40,15 @@ static const struct drm_dp_mst_calc_pbn_mode_test 
> drm_dp_mst_calc_pbn_mode_cases
>   },
>   {
>   .clock = 332880,
> - .bpp = 24,
> + .bpp = 24 << 4,
>   .dsc = true,
> - .expected = 50
> + .expected = 1191
>   },
>   {
>   .clock = 324540,
> - .bpp = 24,
> + .bpp = 24 << 4,
>   .dsc = true,
> - .expected = 49
> + .expected = 1161
>   },
>  };
>  

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [RFC 00/33] Add Support for Plane Color Pipeline

2023-08-30 Thread Sebastian Wick
On Wed, Aug 30, 2023 at 08:47:37AM +, Shankar, Uma wrote:
> 
> 
> > -Original Message-
> > From: Harry Wentland 
> > Sent: Wednesday, August 30, 2023 12:56 AM
> > To: Shankar, Uma ; intel-...@lists.freedesktop.org; 
> > dri-
> > de...@lists.freedesktop.org
> > Cc: wayland-de...@lists.freedesktop.org; Ville Syrjala
> > ; Pekka Paalanen 
> > ;
> > Simon Ser ; Melissa Wen ; Jonas Ådahl
> > ; Sebastian Wick ; Shashank
> > Sharma ; Alexander Goins ;
> > Naseer Ahmed ; Christopher Braga
> > 
> > Subject: Re: [RFC 00/33] Add Support for Plane Color Pipeline
> > 
> > +CC Naseer and Chris, FYI
> > 
> > See https://patchwork.freedesktop.org/series/123024/ for whole series.
> > 
> > On 2023-08-29 12:03, Uma Shankar wrote:
> > > Introduction
> > > 
> > >
> > > Modern hardwares have various color processing capabilities both at
> > > pre-blending and post-blending phases in the color pipeline.
> > > The current drm implementation exposes only the post-blending color
> > > hardware blocks. Support for pre-blending hardware is missing.
> > > There are multiple use cases where pre-blending color hardware will be
> > > useful:
> > >   a) Linearization of input buffers encoded in various transfer
> > >  functions.
> > >   b) Color Space conversion
> > >   c) Tone mapping
> > >   d) Frame buffer format conversion
> > >   e) Non-linearization of buffer(apply transfer function)
> > >   f) 3D Luts
> > >
> > > and other miscellaneous color operations.
> > >
> > > Hence, there is a need to expose the color capabilities of the
> > > hardware to user-space. This will help userspace/middleware to use
> > > display hardware for color processing and blending instead of doing it
> > > through GPU shaders.
> > >
> > 
> > Thanks, Uma, for sending this. I've been working on something similar but 
> > you beat
> > me to it. :)
> 
> Thanks Harry for the useful feedback and overall collaboration on this so far.
> 
> > >
> > > Work done so far and relevant references
> > > 
> > >
> > > Some implementation is done by Intel and AMD/Igalia to address the same.
> > > Broad consensus is there that we need a generic API at drm core to
> > > suffice the use case of various HW vendors. Below are the links
> > > capturing the discussion so far.
> > >
> > > Intel's Plane Color Implementation:
> > > https://patchwork.freedesktop.org/series/90825/
> > > AMD's Plane Color Implementation:
> > > https://patchwork.freedesktop.org/series/116862/
> > >
> > >
> > > Hackfest conclusions
> > > 
> > >
> > > HDR/Color Hackfest was organised by Redhat to bring all the industry
> > > stakeholders together and converge on a common uapi expectations.
> > > Participants from Intel, AMD, Nvidia, Collabora, Redhat, Igalia and
> > > other prominent user-space developers and maintainers.
> > >
> > > Discussions happened on the uapi expectations, opens, nature of
> > > hardware of multiple hardware vendors, challenges in generalizing the
> > > same and the path forward. Consensus was made that drm core should
> > > implement descriptive APIs and not go with prescriptive APIs. DRM core
> > > should just expose the hardware capabilities; enabling, customizing
> > > and programming the same should be done by the user-space. Driver should 
> > > just
> > honor the user space request without doing any operations internally.
> > >
> > > Thanks to Simon Ser, for nicely documenting the design consensus and
> > > an UAPI RFC which can be referred to here:
> > >
> > > https://lore.kernel.org/dri-devel/QMers3awXvNCQlyhWdTtsPwkp5ie9bze_hD5
> > >
> > nAccFW7a_RXlWjYB7MoUW_8CKLT2bSQwIXVi5H6VULYIxCdgvryZoAoJnC5lZgyK1Q
> > Wn48
> > > 8=@emersion.fr/
> > >
> > >
> > > Design considerations
> > > =
> > >
> > > Following are the important aspects taken into account while designing
> > > the current RFC
> > > proposal:
> > >
> > >   1. Individual HW blocks can be muxed. (e.g. out of two HW blocks only 
> > > one
> > can be used)
> > >   2. Position of the HW block in the pipeline can be programmable
> > >   3. LUTs can be one dimentional or three dimentional
> > >   4. Number of LUT entries can vary across platforms
> > >   5. Precision of LUT entries can vary across platforms
> > >   6. Distribution of LUT entries may vary. e.g Mutli-segmented, 
> > > Logarithmic,
> > >  Piece-Wise Linear(PWL) etc
> > >   7. There can be parameterized/non-parameterized fixed function HW
> > blocks.
> > >  e.g. Just a hardware bit, to convert from one color space to another.
> > >   8. Custom non-standard HW implementation.
> > >   9. Leaving scope for some vendor defined pescriptive implementation if
> > required.
> > >   10.Scope to handle any modification in hardware as technology evolves
> > >
> > > The current proposal takes into account the above considerations while
> > > keeping the implementation as generic as possible leaving scope for future
> > additions or modifications.
> > >
> > > T

Re: [PATCH v5 3/3] drm/bridge/analogix/anx78xx: Drop conditionals around of_node pointers

2023-08-30 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Wed, Aug 30, 2023 at 06:08:19PM +0100, Biju Das wrote:
> Having conditional around the of_node pointers turns out to make driver
> code use ugly #ifdef and #if blocks. So drop the conditionals.

How about doing this for all bridge drivers in one go ?

> Suggested-by: Douglas Anderson 
> Signed-off-by: Biju Das 
> ---
> v5:
>  * Split from patch#2
> ---
>  drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c 
> b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> index 6169db73d2fe..ad8241758896 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> @@ -1231,9 +1231,7 @@ static int anx78xx_i2c_probe(struct i2c_client *client)
>  
>   mutex_init(&anx78xx->lock);
>  
> -#if IS_ENABLED(CONFIG_OF)
>   anx78xx->bridge.of_node = client->dev.of_node;
> -#endif
>  
>   anx78xx->client = client;
>   i2c_set_clientdata(client, anx78xx);

-- 
Regards,

Laurent Pinchart


Re: [PATCH v3 00/12] drm/bridge: tc358768: Fixes and timings improvements

2023-08-30 Thread Maxim Schwalm
Hi Tomi,

On 29.08.23 08:27, Tomi Valkeinen wrote:
> Hi Maxim,
> 
> On 22/08/2023 19:19, Tomi Valkeinen wrote:
>> This series contains various fixes and cleanups for TC358768. The target
>> of this work is to get TC358768 working on Toradex's AM62 based board,
>> which has the following display pipeline:
>>
>> AM62 DPI -> TC358768 -> LT8912B -> HDMI connector
>>
>> The main thing the series does is to improve the DSI HSW, HFP and VSDly
>> calculations.
>>
>>   Tomi
> 
> Does this version work for you? Can I add your tested-by?

Yes, this series does work fine on the Asus TF700T, so:

Tested-by: Maxim Schwalm  # Asus TF700T

Aside from the TF700T, I have a different kind of tablet, which also has
a TC358768/TC358778 bridge, but it's not running a mainline kernel yet.
So, unfortunately, I can't tell how this patchset fares on it at this
time.

Best regards,
Maxim


Re: [PATCH v5 2/3] drm/bridge: Drop conditionals around of_node pointers

2023-08-30 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

In the commit message, s/pointers/pointer/ as you're only touching a
single one.

On Wed, Aug 30, 2023 at 06:08:18PM +0100, Biju Das wrote:
> The commit c9e358dfc4a8 ("driver-core: remove conditionals around
> devicetree pointers") supposed to remove conditionals around of_node
> pointer, but it missed out drm/bridge.h. So drop #if conditionals by
> adding struct device_node forward declaration.

You can hardly blame commit c9e358dfc4a8 for forgetting drm_bridge, as
that commit dates back from 2011 and the drm_bridge of_node field was
added in 2015 :-)

I would simply copy the rationale from the commit message of
c9e358dfc4a8 and write something like


Having conditional around the of_node pointer of the drm_bridge
structure turns out to make driver code use ugly #ifdef blocks. Drop the
conditionals to simplify drivers. While this slightly increases the size
of struct drm_bridge on non-OF system, the number of bridges used today
and foreseen tomorrow on those systems is very low, so this shouldn't be
an issue.


Reviewed-by: Laurent Pinchart 

> Suggested-by: Douglas Anderson 
> Signed-off-by: Biju Das 

Reviewed-by: Laurent Pinchart 

> ---
> v5:
>  * Split from patch#2
>  * Updated commit description
>  * Added struct device_node forward declaration.
> ---
>  include/drm/drm_bridge.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index c339fc85fd07..843736627f60 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -32,6 +32,8 @@
>  #include 
>  #include 
>  
> +struct device_node;
> +
>  struct drm_bridge;
>  struct drm_bridge_timings;
>  struct drm_connector;
> @@ -716,10 +718,8 @@ struct drm_bridge {
>   struct drm_encoder *encoder;
>   /** @chain_node: used to form a bridge chain */
>   struct list_head chain_node;
> -#ifdef CONFIG_OF
>   /** @of_node: device node pointer to the bridge */
>   struct device_node *of_node;
> -#endif
>   /** @list: to keep track of all added bridges */
>   struct list_head list;
>   /**

-- 
Regards,

Laurent Pinchart


Re: [PATCH v5 3/3] drm/bridge/analogix/anx78xx: Drop conditionals around of_node pointers

2023-08-30 Thread Doug Anderson
Hi,

On Wed, Aug 30, 2023 at 10:08 AM Biju Das  wrote:
>
> Having conditional around the of_node pointers turns out to make driver
> code use ugly #ifdef and #if blocks. So drop the conditionals.
>
> Suggested-by: Douglas Anderson 
> Signed-off-by: Biju Das 
> ---
> v5:
>  * Split from patch#2
> ---
>  drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 2 --
>  1 file changed, 2 deletions(-)

Reviewed-by: Douglas Anderson 

My current plan, assuming no objections, will be to apply all 3
patches to drm-misc-next in about a week. I'd also be fine if someone
else wanted to apply then. ;-)


Re: [PATCH v5 2/3] drm/bridge: Drop conditionals around of_node pointers

2023-08-30 Thread Doug Anderson
Hi,

On Wed, Aug 30, 2023 at 10:08 AM Biju Das  wrote:
>
> The commit c9e358dfc4a8 ("driver-core: remove conditionals around
> devicetree pointers") supposed to remove conditionals around of_node
> pointer, but it missed out drm/bridge.h. So drop #if conditionals by
> adding struct device_node forward declaration.
>
> Suggested-by: Douglas Anderson 
> Signed-off-by: Biju Das 
> ---
> v5:
>  * Split from patch#2
>  * Updated commit description
>  * Added struct device_node forward declaration.
> ---
>  include/drm/drm_bridge.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Douglas Anderson 


Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()

2023-08-30 Thread pstanner
On Wed, 2023-08-30 at 17:29 +0300, Andy Shevchenko wrote:
> On Wed, Aug 30, 2023 at 5:19 PM  wrote:
> > On Wed, 2023-08-30 at 17:11 +0300, Andy Shevchenko wrote:
> > > On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner
> > > 
> > > wrote:
> 
> > > > --- a/include/linux/string.h
> > > > +++ b/include/linux/string.h
> > > 
> > > I'm wondering if this has no side-effects as string.h/string.c
> > > IIRC
> > > is
> > > used also for early stages where some of the APIs are not
> > > available.
> > > 
> > > > @@ -6,6 +6,8 @@
> > > >  #include    /* for size_t */
> > > >  #include   /* for NULL */
> > > >  #include    /* for E2BIG */
> > > > +#include     /* for check_mul_overflow() */
> > > > +#include  /* for ERR_PTR() */
> > > 
> > > Can we preserve order (to some extent)?
> > 
> > Sure. I just put it there so the comments build a congruent block.
> > Which order would you prefer?
> 
> Alphabetical.
> 
> compiler.h
> err.h
> overflow.h
> ...the rest that is a bit unordered...
> 
> > > >  #include 
> > > >  #include 
> 
> ...

I mean I could include my own in a sorted manner – but the existing
ones are not sorted:

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_STRING_H_
#define _LINUX_STRING_H_

#include  /* for inline */
#include /* for size_t */
#include/* for NULL */
#include /* for E2BIG */
#include 
#include 

extern char *strndup_user(const char __user *, long);

We could sort them all, but I'd prefer to do that in a separate patch
so that this commit does not make the impression of doing anything else
than including the two new headers

Such a separate patch could also unify the docstring style, see below

> 
> > > > +/**
> > > > + * memdup_array_user - duplicate array from user space
> > > 
> > > > + *
> > > 
> > > Do we need this blank line?
> > 
> > I more or less directly copied the docstring format from the
> > original
> > functions (v)memdup_user() in mm/util.c
> > I guess this is common style?
> 
> I think it's not. But you may grep kernel source tree and tell which
> one occurs more often with or without this (unneeded) blank line.


It seems to be very much mixed. string.h itself is mixed.
When you look at the bottom of string.h, you'll find functions such as
kbasename() that have the extra line.

That's not really a super decisive point for me, though. We can remove
the line I guess


P.


> 
> > > > + * @src: source address in user space
> > > > + * @n: number of array members to copy
> > > > + * @size: size of one array member
> > > > + *
> > > > + * Return: an ERR_PTR() on failure.  Result is physically
> > > > + * contiguous, to be freed by kfree().
> > > > + */
> 
> ...
> 
> > > > +/**
> > > > + * vmemdup_array_user - duplicate array from user space
> > > 
> > > > + *
> > > 
> > > Redundant?
> > 
> > No, there are two functions:
> >  * memdup_array_user()
> >  * vmemdup_array_user()
> > 
> > On the deeper layers they utilize kmalloc() or kvmalloc(),
> > respectively.
> 
> I guess you misunderstood my comment. I was talking about kernel doc
> (as in the previous function).
> 
> > > > + * @src: source address in user space
> > > > + * @n: number of array members to copy
> > > > + * @size: size of one array member
> > > > + *
> > > > + * Return: an ERR_PTR() on failure.  Result may be not
> > > > + * physically contiguous.  Use kvfree() to free.
> > > > + */
> 
> 



RE: [PATCH] drm/amd/pm: Replace 1-element arrays with flexible array members

2023-08-30 Thread Deucher, Alexander
[Public]

> -Original Message-
> From: Samuel Holland 
> Sent: Wednesday, August 30, 2023 2:58 PM
> To: Quan, Evan ; Deucher, Alexander
> ; Koenig, Christian
> 
> Cc: Samuel Holland ; Daniel Vetter
> ; David Airlie ; Pan, Xinhui
> ; amd-...@lists.freedesktop.org; dri-
> de...@lists.freedesktop.org; linux-ker...@vger.kernel.org
> Subject: [PATCH] drm/amd/pm: Replace 1-element arrays with flexible array
> members
>
> Since commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3"),
> UBSAN_BOUNDS no longer pretends 1-element arrays are unbounded. The
> bounds check is tripped in smu7_get_pp_table_entry_callback_func_v1(),
> while reading from mclk_dep_table.
>
> For consistency, fix all affected struct definitions in this file.
>
> Signed-off-by: Samuel Holland 

+ Gustavo

Please make sure any code that uses these structures properly deals with the 
change in structure size.

Alex

> ---
>
>  .../drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h | 20 +
> --
>  1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h
> b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h
> index b0ac4d121adc..fb5e935ef786 100644
> --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h
> +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h
> @@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State {  typedef struct
> _ATOM_Tonga_State_Array {
>   UCHAR ucRevId;
>   UCHAR ucNumEntries; /* Number of entries. */
> - ATOM_Tonga_State entries[1];/* Dynamically allocate entries. */
> + ATOM_Tonga_State entries[]; /* Dynamically allocate entries. */
>  } ATOM_Tonga_State_Array;
>
>  typedef struct _ATOM_Tonga_MCLK_Dependency_Record { @@ -179,7
> +179,7 @@ typedef struct _ATOM_Tonga_MCLK_Dependency_Record {
> typedef struct _ATOM_Tonga_MCLK_Dependency_Table {
>   UCHAR ucRevId;
>   UCHAR ucNumEntries;
>   /* Number of entries. */
> - ATOM_Tonga_MCLK_Dependency_Record entries[1];
>   /* Dynamically allocate entries. */
> + ATOM_Tonga_MCLK_Dependency_Record entries[];
>   /* Dynamically allocate entries. */
>  } ATOM_Tonga_MCLK_Dependency_Table;
>
>  typedef struct _ATOM_Tonga_SCLK_Dependency_Record { @@ -194,7
> +194,7 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Record {
> typedef struct _ATOM_Tonga_SCLK_Dependency_Table {
>   UCHAR ucRevId;
>   UCHAR ucNumEntries;
>   /* Number of entries. */
> - ATOM_Tonga_SCLK_Dependency_Record entries[1];
>/* Dynamically allocate entries. */
> + ATOM_Tonga_SCLK_Dependency_Record entries[];
>/* Dynamically allocate entries. */
>  } ATOM_Tonga_SCLK_Dependency_Table;
>
>  typedef struct _ATOM_Polaris_SCLK_Dependency_Record { @@ -210,7
> +210,7 @@ typedef struct _ATOM_Polaris_SCLK_Dependency_Record {
> typedef struct _ATOM_Polaris_SCLK_Dependency_Table {
>   UCHAR ucRevId;
>   UCHAR ucNumEntries;
>   /* Number of entries. */
> - ATOM_Polaris_SCLK_Dependency_Record entries[1];
>/* Dynamically allocate entries. */
> + ATOM_Polaris_SCLK_Dependency_Record entries[];
>/* Dynamically allocate entries. */
>  } ATOM_Polaris_SCLK_Dependency_Table;
>
>  typedef struct _ATOM_Tonga_PCIE_Record { @@ -222,7 +222,7 @@ typedef
> struct _ATOM_Tonga_PCIE_Record {  typedef struct
> _ATOM_Tonga_PCIE_Table {
>   UCHAR ucRevId;
>   UCHAR ucNumEntries;
>   /* Number of entries. */
> - ATOM_Tonga_PCIE_Record entries[1];
>   /* Dynamically allocate entries. */
> + ATOM_Tonga_PCIE_Record entries[];
>   /* Dynamically allocate entries. */
>  } ATOM_Tonga_PCIE_Table;
>
>  typedef struct _ATOM_Polaris10_PCIE_Record { @@ -235,7 +235,7 @@
> typedef struct _ATOM_Polaris10_PCIE_Record {  typedef struct
> _ATOM_Polaris10_PCIE_Table {
>   UCHAR ucRevId;
>   UCHAR ucNumEntries; /* Number 
> of entries. */
> - ATOM_Polaris10_PCIE_Record entries[1];  /* 
> Dynamically
> allocate entries. */
> + ATOM_Polaris10_PCIE_Record entries[];   /* 
> Dynamically
> allocate entries. */
>  } ATOM_Polaris10_PCIE_Table;
>
>
> @@ -252,7 +252,7 @@ typedef struct
> _ATOM_Tonga_MM_Dependency_Record {  typedef struct
> _ATOM_Tonga_MM_Dependency_Table {
>   UCHAR ucRevId;
>   UCHAR ucNumEntries;
>   /* Number of entries. */
> - ATOM_Tonga_MM_Dependency_Record entries[1];
>  /* Dynamically allocate entries. */
> + ATOM_Tonga_MM_Dependency_Record entries[];
>  /* Dynamically allocate entries. */
>  } ATOM_Tonga_MM_Dependency_Table;
>
>  typedef struct _ATOM_Tonga_Voltage_Lookup_Record { @@ -265,7 +265,7
> @@ typedef struct _ATOM_Tonga_Voltage_Lookup_Record {  typedef struct
> _ATOM_Tonga_Voltage_Lookup_T

Re: [PATCH AUTOSEL 5.10 13/22] drm/amdgpu: install stub fence into potential unused fence pointers

2023-08-30 Thread Chia-I Wu
On Sun, Jul 23, 2023 at 6:24 PM Sasha Levin  wrote:
>
> From: Lang Yu 
>
> [ Upstream commit 187916e6ed9d0c3b3abc27429f7a5f8c936bd1f0 ]
>
> When using cpu to update page tables, vm update fences are unused.
> Install stub fence into these fence pointers instead of NULL
> to avoid NULL dereference when calling dma_fence_wait() on them.
>
> Suggested-by: Christian König 
> Signed-off-by: Lang Yu 
> Reviewed-by: Christian König 
> Signed-off-by: Alex Deucher 
> Signed-off-by: Sasha Levin 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)

We start getting this warning spew on chromeos, likely from
dma_fence_is_later because the stub fence is on a different timeline:

[  273.334767] WARNING: CPU: 1 PID: 13383 at
include/linux/dma-fence.h:478 amdgpu_sync_keep_later+0x95/0xbd
[  273.334769] Modules linked in: snd_seq_dummy snd_seq snd_seq_device
bridge stp llc tun vhost_vsock vhost vhost_iotlb
vmw_vsock_virtio_transport_common vsock 8021q veth lzo_rle
lzo_compress zram uinput snd_acp_sof_mach snd_acp_mach snd_soc_dmic
xt_cgroup rfcomm xt_MASQUERADE cmac algif_hash algif_skcipher af_alg
btusb btrtl btintel btbcm rtw89_8852ae rtw89_pci rtw89_8852a
rtw89_core snd_sof_amd_renoir snd_sof_xtensa_dsp snd_sof_amd_acp
snd_acp_pci snd_acp_config snd_soc_acpi snd_pci_acp3x snd_sof_pci
snd_sof snd_hda_codec_hdmi snd_sof_utils snd_hda_intel mac80211
snd_intel_dspcfg snd_hda_codec cros_ec_typec snd_hwdep roles
snd_hda_core typec snd_soc_rt5682s snd_soc_rt1019 snd_soc_rl6231
ip6table_nat i2c_piix4 fuse bluetooth ecdh_generic ecc cfg80211
iio_trig_sysfs cros_ec_lid_angle cros_ec_sensors cros_ec_sensors_core
industrialio_triggered_buffer kfifo_buf industrialio cros_ec_sensorhub
r8153_ecm cdc_ether usbnet r8152 mii uvcvideo videobuf2_vmalloc
videobuf2_memops videobuf2_v4l2
[  273.334795]  videobuf2_common joydev
[  273.334799] CPU: 1 PID: 13383 Comm: chrome:cs0 Tainted: GW
   5.10.192-23384-g3d3f0f0c5e4f #1
fe1e7e3b7510aa7b8e01701478119255f825a36f
[  273.334800] Hardware name: Google Dewatt/Dewatt, BIOS
Google_Dewatt.14500.347.0 03/30/2023
[  273.334802] RIP: 0010:amdgpu_sync_keep_later+0x95/0xbd
[  273.334804] Code: 00 00 b8 01 00 00 00 f0 0f c1 43 38 85 c0 74 26
8d 48 01 09 c1 78 24 49 89 1e 5b 41 5e 5d c3 cc cc cc cc e8 4a 94 ac
ff eb ce <0f> 0b 49 8b 06 48 85 c0 75 af eb c2 be 02 00 00 00 48 8d 7b
38 e8
[  273.334805] RSP: 0018:b222c1817b50 EFLAGS: 00010293
[  273.334807] RAX: 89bfc838 RBX: 8aa425e9ed00 RCX: 
[  273.334808] RDX: 8aa426156a98 RSI: 8aa425e9ed00 RDI: 8aa432518918
[  273.334810] RBP: b222c1817b60 R08: 8aa43ca6c0a0 R09: 8aa33af3c9a0
[  273.334811] R10: fcf8c5986600 R11: 87a00fce R12: 0098
[  273.334812] R13: 005e2a00 R14: 8aa432518918 R15: 
[  273.334814] FS:  7e70f8694640() GS:8aa4e608()
knlGS:
[  273.334816] CS:  0010 DS:  ES:  CR0: 80050033
[  273.334817] CR2: 7e70ea049020 CR3: 000178e6e000 CR4: 00750ee0
[  273.334818] PKRU: 5554
[  273.334819] Call Trace:
[  273.334822]  ? __warn+0xa3/0x131
[  273.334824]  ? amdgpu_sync_keep_later+0x95/0xbd
[  273.334826]  ? report_bug+0x97/0xfa
[  273.334829]  ? handle_bug+0x41/0x66
[  273.334832]  ? exc_invalid_op+0x1b/0x72
[  273.334835]  ? asm_exc_invalid_op+0x12/0x20
[  273.334837]  ? native_sched_clock+0x9a/0x9a
[  273.334840]  ? amdgpu_sync_keep_later+0x95/0xbd
[  273.334843]  amdgpu_sync_vm_fence+0x23/0x39
[  273.334846]  amdgpu_cs_ioctl+0x1782/0x1e56
[  273.334851]  ? amdgpu_cs_report_moved_bytes+0x5f/0x5f
[  273.334854]  drm_ioctl_kernel+0xdf/0x150
[  273.334858]  drm_ioctl+0x1f5/0x3d2
[  273.334928]  ? amdgpu_cs_report_moved_bytes+0x5f/0x5f
[  273.334932]  amdgpu_drm_ioctl+0x49/0x81
[  273.334935]  __x64_sys_ioctl+0x7d/0xc8
[  273.334937]  do_syscall_64+0x42/0x54
[  273.334939]  entry_SYSCALL_64_after_hwframe+0x4a/0xaf
[  273.334941] RIP: 0033:0x7e70ff797649
[  273.334943] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10
c7 45 b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10 00 00
00 0f 05 <41> 89 c0 3d 00 f0 ff ff 77 1d 48 8b 45 c8 64 48 2b 04 25 28
00 00
[  273.334945] RSP: 002b:7e70f8693170 EFLAGS: 0246 ORIG_RAX:
0010
[  273.334947] RAX: ffda RBX:  RCX: 7e70ff797649
[  273.334948] RDX: 7e70f8693248 RSI: c0186444 RDI: 0013
[  273.334950] RBP: 7e70f86931c0 R08: 7e70f8693350 R09: 7e70f8693340
[  273.334951] R10: 000a R11: 0246 R12: c0186444
[  273.334952] R13: 7e70f8693380 R14: 7e70f8693248 R15: 0013
[  273.334954] ---[ end trace fc066a0fcea39e8c ]---


Re: [PATCH v1 0/3] udmabuf: Add support for page migration out of movable zone or CMA

2023-08-30 Thread Jason Gunthorpe
On Sun, Aug 27, 2023 at 07:05:59PM +, Kasireddy, Vivek wrote:
> Hi Jason, David,
> 
> > > > Sure, we can simply always fail when we detect ZONE_MOVABLE or
> > > MIGRATE_CMA.
> > > > Maybe that keeps at least some use cases working.
> > >
> > > That seems fairly reasonable
> > AFAICS, failing udmabuf_create() if we detect one or more pages are in
> > ZONE_MOVABLE or MIGRATE_CMA would not be a recoverable failure --
> > as it would result in the failure of Guest GUI (or compositor).

Yes, you can't use whatever this driver is while enabling MOVABLE or
CMA in your kernel boot.

> > I think it makes sense to have a generic version of
> > And, since check_and_migrate_movable_pages() is GUP-specific, would
> > it be ok to create a generic version of that (in mm/migrate.c) which can be
> > used by udmabuf and/or other drivers in the future?
> Sorry, I accidentally sent this earlier email before finishing it.
> What I meant to say is since the same situation (inadvertently pinning pages
> in movable) may probably arise in the future with another driver, 

Why?

It was a big mistake to design a uAPI around taking in a FD and
extracting pages from it, we don't have kernel infrastructure for
that, and code liek that does not belong outside the MM at all.

> I think it makes sense to have a generic (non-GUP) version of
> check_and_migrate_movable_pages() available in migration.h that
> drivers can use to ensure that they don't break memory hotunplug
> accidentally.

Definately not.

Either use the VMA and pin_user_pages(), or implement
pin_user_pages_fd() in core code.

Do not open code something wonky in drivers.

Jason


[PATCH v5 3/3] drm/bridge/analogix/anx78xx: Drop conditionals around of_node pointers

2023-08-30 Thread Biju Das
Having conditional around the of_node pointers turns out to make driver
code use ugly #ifdef and #if blocks. So drop the conditionals.

Suggested-by: Douglas Anderson 
Signed-off-by: Biju Das 
---
v5:
 * Split from patch#2
---
 drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c 
b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index 6169db73d2fe..ad8241758896 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -1231,9 +1231,7 @@ static int anx78xx_i2c_probe(struct i2c_client *client)
 
mutex_init(&anx78xx->lock);
 
-#if IS_ENABLED(CONFIG_OF)
anx78xx->bridge.of_node = client->dev.of_node;
-#endif
 
anx78xx->client = client;
i2c_set_clientdata(client, anx78xx);
-- 
2.25.1



[PATCH v5 2/3] drm/bridge: Drop conditionals around of_node pointers

2023-08-30 Thread Biju Das
The commit c9e358dfc4a8 ("driver-core: remove conditionals around
devicetree pointers") supposed to remove conditionals around of_node
pointer, but it missed out drm/bridge.h. So drop #if conditionals by
adding struct device_node forward declaration.

Suggested-by: Douglas Anderson 
Signed-off-by: Biju Das 
---
v5:
 * Split from patch#2
 * Updated commit description
 * Added struct device_node forward declaration.
---
 include/drm/drm_bridge.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index c339fc85fd07..843736627f60 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -32,6 +32,8 @@
 #include 
 #include 
 
+struct device_node;
+
 struct drm_bridge;
 struct drm_bridge_timings;
 struct drm_connector;
@@ -716,10 +718,8 @@ struct drm_bridge {
struct drm_encoder *encoder;
/** @chain_node: used to form a bridge chain */
struct list_head chain_node;
-#ifdef CONFIG_OF
/** @of_node: device node pointer to the bridge */
struct device_node *of_node;
-#endif
/** @list: to keep track of all added bridges */
struct list_head list;
/**
-- 
2.25.1



[PATCH v5 1/3] drm/bridge/analogix/anx78xx: Drop ID table

2023-08-30 Thread Biju Das
The driver has an ID table, but it uses the wrong API for retrieving match
data and that will lead to a crash, if it is instantiated by user space or
using ID. From this, there is no user for the ID table and let's drop it
from the driver as it saves some memory.

Signed-off-by: Biju Das 
Reviewed-by: Douglas Anderson 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Andy Shevchenko 
Reviewed-by: Helen Koike 
---
v4->v5:
 * Added Rb tag from Andy and Helen.
v3->v4:
 * Added Rb tag from Laurent and Douglas Anderson.
v2->v3:
 * Updated commit header.
v1->v2:
 * Dropped ID table support.
---
 drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c 
b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index 800555aef97f..6169db73d2fe 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -1367,12 +1367,6 @@ static void anx78xx_i2c_remove(struct i2c_client *client)
kfree(anx78xx->edid);
 }
 
-static const struct i2c_device_id anx78xx_id[] = {
-   { "anx7814", 0 },
-   { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(i2c, anx78xx_id);
-
 static const struct of_device_id anx78xx_match_table[] = {
{ .compatible = "analogix,anx7808", .data = anx7808_i2c_addresses },
{ .compatible = "analogix,anx7812", .data = anx781x_i2c_addresses },
@@ -1389,7 +1383,6 @@ static struct i2c_driver anx78xx_driver = {
  },
.probe = anx78xx_i2c_probe,
.remove = anx78xx_i2c_remove,
-   .id_table = anx78xx_id,
 };
 module_i2c_driver(anx78xx_driver);
 
-- 
2.25.1



[PATCH v5 0/3] Drop ID table and conditionals around of_node pointers for anx78xx driver

2023-08-30 Thread Biju Das
This patch series aims to drop ID table and conditionals around of_node 
pointers for anx78xx driver.

While at it, drop conditionals from drm_bridge.h.

v4->v5:
 * Added Rb tag from Andy and Helen for patch#1.
 * Split patch#2 into two
 * Added struct device_node forward declaration for patch#2.
 * Updated commit description for patch#2
v3->v4:
 * Created patch#2 for dropping conditionals around of_node pointers.
 * Added Rb tag from Laurent and Douglas Anderson for patch#1.
v2->v3:
 * Updated commit header.
v1->v2:
 * Dropped ID table support.

Biju Das (3):
  drm/bridge/analogix/anx78xx: Drop ID table
  drm/bridge: Drop conditionals around of_node pointers
  drm/bridge/analogix/anx78xx: Drop conditionals around of_node pointers

 drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 9 -
 include/drm/drm_bridge.h   | 4 ++--
 2 files changed, 2 insertions(+), 11 deletions(-)

-- 
2.25.1



Re: [PATCH v6 0/4] drm: Use full allocated minor range for DRM

2023-08-30 Thread James Zhu

PATCH 1 and 3 are

Tested-by:JamesZhu

Best Regards!

James Zhu

On 2023-07-24 17:14, Michał Winiarski wrote:

64 DRM device nodes is not enough for everyone.
Upgrade it to ~512K (which definitely is more than enough).

To allow testing userspace support for >64 devices, add additional DRM
modparam (force_extended_minors) which causes DRM to skip allocating minors
in 0-192 range.
Additionally - convert minors to use XArray instead of IDR to simplify the
locking.

v1 -> v2:
Don't touch DRM_MINOR_CONTROL and its range (Simon Ser)

v2 -> v3:
Don't use legacy scheme for >=192 minor range (Dave Airlie)
Add modparam for testing (Dave Airlie)
Add lockdep annotation for IDR (Daniel Vetter)

v3 -> v4:
Convert from IDR to XArray (Matthew Wilcox)

v4 -> v5:
Fixup IDR to XArray conversion (Matthew Wilcox)

v5 -> v6:
Also convert Accel to XArray
Rename skip_legacy_minors to force_extended_minors

Michał Winiarski (4):
   drm: Use XArray instead of IDR for minors
   accel: Use XArray instead of IDR for minors
   drm: Expand max DRM device number to full MINORBITS
   drm: Introduce force_extended_minors modparam

  drivers/accel/drm_accel.c  | 110 +++--
  drivers/gpu/drm/drm_drv.c  | 105 ---
  drivers/gpu/drm/drm_file.c |   2 +-
  drivers/gpu/drm/drm_internal.h |   4 --
  include/drm/drm_accel.h|  18 +-
  include/drm/drm_file.h |   5 ++
  6 files changed, 69 insertions(+), 175 deletions(-)


Re: [RFC v1 1/3] mm/mmu_notifier: Add a new notifier for mapping updates (new pages)

2023-08-30 Thread Jason Gunthorpe
On Mon, Aug 28, 2023 at 04:38:01AM +, Kasireddy, Vivek wrote:

> Turns out, calling hmm_range_fault() from the invalidate callback was indeed
> a problem and the reason why new pages were not faulted-in. In other words,
> it looks like the invalidate callback is not the right place to invoke 
> hmm_range_fault()
> as the PTEs may not have been cleared.

Yes, that is correct, you can't even do the locking properly if you
invoke things like this. mmu_interval_read_retry() should continually
fail while you are within the invalidate callback.

Jason


Re: [PATCH v2 08/15] drm/panthor: Add the MMU/VM logical block

2023-08-30 Thread Steven Price
On 30/08/2023 15:53, Boris Brezillon wrote:
> On Wed, 30 Aug 2023 15:12:43 +0100
> Steven Price  wrote:
> 
>> On 29/08/2023 16:33, Boris Brezillon wrote:
>>> On Mon, 14 Aug 2023 16:53:09 +0100
>>> Steven Price  wrote:
>>>   
> +
> +/**
> + * struct panthor_vm_op_ctx - VM operation context
> + *
> + * With VM operations potentially taking place in a dma-signaling path, 
> we
> + * need to make sure everything that might require resource allocation is
> + * pre-allocated upfront. This is what this operation context is far.
> + *
> + * We also collect resources that have been freed, so we can release them
> + * asynchronously, and let the VM_BIND scheduler process the next VM_BIND
> + * request.
> + */
> +struct panthor_vm_op_ctx {
> + /** @rsvd_page_tables: Pages reserved for the MMU page table update. */
> + struct {
> + /** @count: Number of pages reserved. */
> + u32 count;
> +
> + /** @ptr: Point to the first unused page in the @pages table. */
> + u32 ptr;
> +
> + /**
> +  * @page: Array of pages that can be used for an MMU page table 
> update.
> +  *
> +  * After an VM operation, there might be free pages left in 
> this array.
> +  * They should be returned to the pt_cache as part of the 
> op_ctx cleanup.
> +  */
> + void **pages;
> + } rsvd_page_tables;

 Two questions:

 1) Would a mempool simplify the implementation? It looks like a
 reasonable match.  
>>>
>>> Not sure what you mean by mempool,  
>>
>> See include/linux/mempool.h
> 
> Oh, okay.
> 
>>
>>> but I'm using a kmem_cache here for
>>> all page table allocations. The pages that are passed to
>>> panthor_vm_op_ctx::rsvd_page_tables::pages are allocated from this
>>> pool. It's just that for each VM operation we pre-allocate page-tables,
>>> and release those that were not used when the operation is done (we
>>> over-allocate for the worst case scenario).  
>>
>> The mempool could, potentially, replace the rsvd_page_tables structure.
>> The kmem_cache you would still want as that's per-driver.
> 
> Need to have a closer look at the API to make my mind, but at first
> glance it seems to be overkill for what I initially had in mind.

I agree it has more functionality than is needed here - but equally the
code is already there. struct rsvd_page_tables looks to me to be a very
simplified version of it, so rather than reinventing it we could just
use the existing code.

Having said that I haven't tried the conversion, so perhaps there are
issues with the mempool implementation which makes it better to roll our
own.

>>

 2) Does it really make sense to have a separate pool of memory for every
 operation? Instead of having a separate pool for each operation, it
 would be possible to just keep track of the total number needed for all
 outstanding operations. Then a single (per device or maybe per-VM if
 necessary) mempool could be resized to ensure it has the right amount of
 space.  
>>>
>>> The pool is per-driver (see the global pt_cache). rsvd_page_tables just
>>> holds pages needed for a specific VM operation. To be more specific, it
>>> holds pages for the worst case (page table tree is empty, except for the
>>> root page table).  
>>
>> What I'm wondering is to we need to keep the pages for each operation in
>> separate pools.
> 
> I was not really considering it a pool, more a set of pages that will
> be used by the VM operation, some of them being returned to the
> kmem_cache pool if we end up using less (over-provisioning). If we have
> a mempool, say, at the VM level, that means we have 2 levels of caching:
> the kmem_cache itself, and the mempool attached to the VM. Is there any
> benefit here? Do we expect kmem_cache to be too slow for fast/already
> allocated pages?

My understanding is that we can't (easily) ensure that sufficient pages
remain in the kmem_cache. So we need a second level 'cache' to hold the
pages that might be used by the pending VM_BIND operations. That's what
the rsvd_page_tables struct does currently.

> I do see how over-provisioning can cause us to allocate a lot of pages
> that end up being unused, but I fail to see how VM/device level caching
> would solve that, because we still have to dequeue some operations to
> return pages to the intermediate pool, at which point, we've already
> lost, because already queued operations reserved the amount of pages
> they thought they needed for the worst case scenario.
> Operations being queued after that can pick from the returned pages of
> course, but that's already the case right now, because we return pages
> to the kmem_cache as soon as we're done executing a VM operation.

I don't think it would make a difference other than having one shared
data structure rather than many struct rsvd_page_tables 

Re: [PATCH v2 6/6] drm/drm-file: Allow size unit selection in drm_show_memory_stats

2023-08-30 Thread Adrián Larumbe
>> The current implementation will try to pick the highest available
>> unit. This is rather unflexible, and allowing drivers to display BO size
>> statistics through fdinfo in units of their choice might be desirable.
>>
>> The new argument to drm_show_memory_stats is to be interpreted as the
>> integer multiplier of a 10-power of 2, so 1 would give us size in Kib and 2
>> in Mib. If we want drm-file functions to pick the highest unit, then 0
>> should be passed.
>>
>> Signed-off-by: Adrián Larumbe 
>> ---
>>  drivers/gpu/drm/drm_file.c  | 22 +-
>>  drivers/gpu/drm/msm/msm_drv.c   |  2 +-
>>  drivers/gpu/drm/panfrost/panfrost_drv.c |  2 +-
>>  include/drm/drm_file.h  |  5 +++--
>>  4 files changed, 18 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
>> index 762965e3d503..517e1fb8072a 100644
>> --- a/drivers/gpu/drm/drm_file.c
>> +++ b/drivers/gpu/drm/drm_file.c
>> @@ -873,7 +873,7 @@ void drm_send_event(struct drm_device *dev, struct 
>> drm_pending_event *e)
>>  EXPORT_SYMBOL(drm_send_event);
>>
>>  static void print_size(struct drm_printer *p, const char *stat,
>> -  const char *region, u64 sz)
>> +  const char *region, u64 sz, unsigned int unit)
>>  {
>> const char *units[] = {"", " KiB", " MiB"};
>> unsigned u;
>> @@ -881,6 +881,8 @@ static void print_size(struct drm_printer *p, const char 
>> *stat,
>> for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
>> if (sz < SZ_1K)
>> break;
>> +   if (unit > 0 && unit == u)
>> +   break;
>> sz = div_u64(sz, SZ_1K);
>> }
>>
>> @@ -898,17 +900,18 @@ static void print_size(struct drm_printer *p, const 
>> char *stat,
>>  void drm_print_memory_stats(struct drm_printer *p,
>> const struct drm_memory_stats *stats,
>> enum drm_gem_object_status supported_status,
>> -   const char *region)
>> +   const char *region,
>> +   unsigned int unit)
>
>I'm not really adverse to changing what units we use.. or perhaps
>changing the threshold to go to higher units to be 1x or 10x
>of the previous unit.  But I'm less excited about having different
>drivers using different units.
>
>BR,
>-R

Would it be alright if I left it set to the default unit, and allow changing it
at runtime with a debugfs file?

>>  {
>> -   print_size(p, "total", region, stats->private + stats->shared);
>> -   print_size(p, "shared", region, stats->shared);
>> -   print_size(p, "active", region, stats->active);
>> +   print_size(p, "total", region, stats->private + stats->shared, unit);
>> +   print_size(p, "shared", region, stats->shared, unit);
>> +   print_size(p, "active", region, stats->active, unit);
>>
>> if (supported_status & DRM_GEM_OBJECT_RESIDENT)
>> -   print_size(p, "resident", region, stats->resident);
>> +   print_size(p, "resident", region, stats->resident, unit);
>>
>> if (supported_status & DRM_GEM_OBJECT_PURGEABLE)
>> -   print_size(p, "purgeable", region, stats->purgeable);
>> +   print_size(p, "purgeable", region, stats->purgeable, unit);
>>  }
>>  EXPORT_SYMBOL(drm_print_memory_stats);
>>
>> @@ -916,11 +919,12 @@ EXPORT_SYMBOL(drm_print_memory_stats);
>>   * drm_show_memory_stats - Helper to collect and show standard fdinfo 
>> memory stats
>>   * @p: the printer to print output to
>>   * @file: the DRM file
>> + * @unit: multipliyer of power of two exponent of desired unit
>>   *
>>   * Helper to iterate over GEM objects with a handle allocated in the 
>> specified
>>   * file.
>>   */
>> -void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file)
>> +void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file, 
>> unsigned int unit)
>>  {
>> struct drm_gem_object *obj;
>> struct drm_memory_stats status = {};
>> @@ -967,7 +971,7 @@ void drm_show_memory_stats(struct drm_printer *p, struct 
>> drm_file *file)
>> }
>> spin_unlock(&file->table_lock);
>>
>> -   drm_print_memory_stats(p, &status, supported_status, "memory");
>> +   drm_print_memory_stats(p, &status, supported_status, "memory", unit);
>>  }
>>  EXPORT_SYMBOL(drm_show_memory_stats);
>>
>> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
>> index 2a0e3529598b..cd1198151744 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.c
>> +++ b/drivers/gpu/drm/msm/msm_drv.c
>> @@ -1067,7 +1067,7 @@ static void msm_show_fdinfo(struct drm_printer *p, 
>> struct drm_file *file)
>>
>> msm_gpu_show_fdinfo(priv->gpu, file->driver_priv, p);
>>
>> -   drm_show_memory_stats(p, file);
>> +   drm_show_memory_stats(p, file, 0);
>>  }
>>
>>  static const struct fil

[PATCH 0/3] drm/gma500: Fix the failure to map the stolen memory

2023-08-30 Thread Sui Jingfeng
When another discrete video card(SM750 or AST1400) is mounted into the mini
PCIe slot of my ASRock AD2550B-ITX board, the gma500 drivers fails to work.
It probably because the UEFI firmware of that board forget to initialize
the PSB_PGETBL_CTL reg, therefore the value of dev_priv->pge_ctl is 0, then
the value of gtt_phys_start is also 0.

On normal case, the value of the dev_priv->stolen_base is 0xbf80 for
this board, so the value of the vram_stolen_size will be negative in this
case, the calculation of the stolen vram size of drm/gma500 is pasted at
below:

vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
 = 0 - 0xbf80 - 4096 = 1056764 KiB

Which is so large, so this cause the ioremap_wc() fail, see below dmesg for
more information.

 gma500 :00:02.0: enabling device ( -> 0003)
 gma500 :00:02.0: GPU: power management timed out.
 gma500 :00:02.0: [drm] Phys start of GTT: 0x0
 gma500 :00:02.0: [drm] Stolen memory base 0xbf80, size 1056764KiB
 x86/PAT: systemd-udevd:386 conflicting memory types bf80-f000 
write-combining<->uncached-minus
 x86/PAT: memtype_reserve failed [mem 0xbf80-0xefff], track 
write-combining, req write-combining
 ioremap memtype_reserve failed -16
 gma500 :00:02.0: Failure to map stolen base.
 gma500: probe of :00:02.0 failed with error -12

Regardless, we want this driver works even there have another video card
mounted. This patch solve this problem by given 8M stolen memory if the
value of pg->gtt_phys_start is zero. And after apply this patch, it works
fine.

$ dmesg | grep drm

 gma500 :00:02.0: [drm] Phys start of GTT: 0x0
 gma500 :00:02.0: [drm] Stolen memory base 0xbf80, size 8192KiB
 [drm] Initialized gma500 1.0.0 20140314 for :00:02.0 on minor 0
 gma500 :00:02.0: [drm] fb1: gma500drmfb frame buffer device

Sui Jingfeng (3):
  drm/gma500: Print the stolen memory base and size with drm_info()
  drm/gma500: Print the start address of the GTT
  drm/gma500: Fix the failure to map the stolen memory

 drivers/gpu/drm/gma500/gem.c | 10 +++---
 drivers/gpu/drm/gma500/gtt.c |  2 ++
 2 files changed, 9 insertions(+), 3 deletions(-)


base-commit: bb585492db95d4cc7fe3797523ed2bbf5c621d37
-- 
2.34.1



[PATCH 1/3] drm/gma500: Print the stolen memory base and size with drm_info()

2023-08-30 Thread Sui Jingfeng
while at it, also replace the 'K' with 'KiB'.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/gma500/gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index 4b7627a72637..6fe78f61e127 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -344,8 +344,8 @@ int psb_gem_mm_init(struct drm_device *dev)
 
stolen_size = vram_stolen_size;
 
-   dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n",
-   dev_priv->stolen_base, vram_stolen_size / 1024);
+   drm_info(dev, "Stolen memory base 0x%x, size %luKiB\n",
+dev_priv->stolen_base, vram_stolen_size / 1024);
 
pg->stolen_size = stolen_size;
dev_priv->vram_stolen_size = vram_stolen_size;
-- 
2.34.1



[PATCH 2/3] drm/gma500: Print the start address of the GTT

2023-08-30 Thread Sui Jingfeng
The PGTBL_CTL register provides the starting physical memory address of
the Graphics Translation Table (GTT). We want to see what's the value in
it. This patch is useful for debug.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/gma500/gtt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 379bc218aa6b..112418301866 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -243,6 +243,8 @@ static void psb_gtt_init_ranges(struct drm_psb_private 
*dev_priv)
gtt_mem = &pdev->resource[PSB_GATT_RESOURCE];
}
 
+   drm_info(dev, "Phys start of GTT: 0x%llx\n", (u64)gtt_phys_start);
+
pg->gtt_phys_start = gtt_phys_start;
pg->mmu_gatt_start = mmu_gatt_start;
pg->gtt_start = gtt_start;
-- 
2.34.1



[PATCH 3/3] drm/gma500: Fix the failure to map the stolen memory

2023-08-30 Thread Sui Jingfeng
When another discrete video card(SM750 or AST1400) is mounted into the mini
PCIe slot of my ASRock AD2550B-ITX board, the gma500 drivers fails to work.
It probably because the UEFI firmware of that board forget to initialize
the PSB_PGETBL_CTL reg, therefore the value of dev_priv->pge_ctl is 0, then
the value of gtt_phys_start is also 0.

On normal case, the value of the dev_priv->stolen_base is 0xbf80 for
this board, so the value of the vram_stolen_size will be negative in this
case, the calculation of the stolen vram size of drm/gma500 is pasted at
below:

vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
 = 0 - 0xbf80 - 4096 = 1056764 KiB

Which is so large, so this cause the ioremap_wc() fail, see below dmesg for
more information.

 gma500 :00:02.0: enabling device ( -> 0003)
 gma500 :00:02.0: GPU: power management timed out.
 gma500 :00:02.0: [drm] Phys start of GTT: 0x0
 gma500 :00:02.0: [drm] Stolen memory base 0xbf80, size 1056764KiB
 x86/PAT: systemd-udevd:386 conflicting memory types bf80-f000 
write-combining<->uncached-minus
 x86/PAT: memtype_reserve failed [mem 0xbf80-0xefff], track 
write-combining, req write-combining
 ioremap memtype_reserve failed -16
 gma500 :00:02.0: Failure to map stolen base.
 gma500: probe of :00:02.0 failed with error -12

Regardless, we want this driver works even there have another video card
mounted. This patch solve this problem by given 8M stolen memory if the
value of pg->gtt_phys_start is zero. And after apply this patch, it works
fine.

$ dmesg | grep drm

 gma500 :00:02.0: [drm] Phys start of GTT: 0x0
 gma500 :00:02.0: [drm] Stolen memory base 0xbf80, size 8192KiB
 [drm] Initialized gma500 1.0.0 20140314 for :00:02.0 on minor 0
 gma500 :00:02.0: [drm] fb1: gma500drmfb frame buffer device

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/gma500/gem.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index 6fe78f61e127..0e9971bb24fa 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -340,7 +340,11 @@ int psb_gem_mm_init(struct drm_device *dev)
pg = &dev_priv->gtt;
 
pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base);
-   vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - 
PAGE_SIZE;
+
+   if (pg->gtt_phys_start)
+   vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - 
PAGE_SIZE;
+   else
+   vram_stolen_size = 8 * 1024 * 1024;
 
stolen_size = vram_stolen_size;
 
-- 
2.34.1



Re: [PATCH v7 1/1] vfio/nvgpu: Add vfio pci variant module for grace hopper

2023-08-30 Thread Jason Gunthorpe
On Wed, Aug 30, 2023 at 06:50:32AM -0700, Christoph Hellwig wrote:
> I know I'm chiming in a bit late, but what ultimate user space is going
> to use this?  We should not add anything to the kernel that can't
> be used without fully open user space.

qemu will get the matching VFIO userspace patches, I think they were
posted someplace already.

> vfio has traditionally been a bit special as it "just" passes devices
> through, so any user space could just be a user space driver for a
> random device on $FOO bus, including an actual Linux driver in a VM,
> but this driver has very specific semantics for a very specific piece
> of hardware, so it really needs to be treated like a generic GPU driver
> or accelerator driver.

This is basically a pre-CXL driver. It takes a PCI device and some
non-standard CXL-ish metadata and adapts it to VFIO.

In a post-CXL world this same functionality of managing the 'cache
coherent BAR' for VFIO would be done generically by some generic
vfio-cxl driver.

Jason


Re: [PATCH v2 09/15] drm/panthor: Add the FW logical block

2023-08-30 Thread Steven Price
On 29/08/2023 17:15, Boris Brezillon wrote:
> On Wed, 16 Aug 2023 17:01:56 +0100
> Steven Price  wrote:
> 
>> On 09/08/2023 17:53, Boris Brezillon wrote:

[...]

>>> +/**
>>> + * panthor_fw_mem_alloc() - Allocate a FW memory object and map it to the 
>>> MCU VM.
>>> + * @ptdev: Device.
>>> + * @size: Size of the memory block.
>>> + * @bo_flags: BO flags.
>>> + * @vm_map_flags: VM_MAP flags.
>>> + * @va: Virtual address of the MCU mapping.
>>> + * Set to PANTHOR_GEM_ALLOC_VA for automatic VA-assignment. In that case, 
>>> the
>>> + * VA will be allocated in the shared VA space.
>>> + *
>>> + * Return: A valid pointer in case of success, an ERR_PTR() otherwise.
>>> + */
>>> +static struct panthor_fw_mem *
>>> +panthor_fw_mem_alloc(struct panthor_device *ptdev, size_t size,
>>> +u32 bo_flags, u32 vm_map_flags, u64 va)
>>> +{
>>> +   struct panthor_fw_mem *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
>>> +   int ret;
>>> +
>>> +   if (!mem)
>>> +   return ERR_PTR(-ENOMEM);
>>> +
>>> +   mem->bo = panthor_gem_create_and_map(ptdev, ptdev->fw->vm,
>>> +size, bo_flags, vm_map_flags,
>>> +&va, NULL);
>>> +   if (IS_ERR(mem->bo)) {
>>> +   ret = PTR_ERR(mem->bo);
>>> +   mem->bo = NULL;
>>> +   goto err_free_mem;
>>> +   }
>>> +
>>> +   mem->va = va;
>>> +   return mem;
>>> +
>>> +err_free_mem:
>>> +   panthor_fw_mem_free(ptdev, mem);
>>> +   return ERR_PTR(ret);  
>>
>> The error handling seems more complex than needed, how about:
>>
>>  struct panthor_fw_mem *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
>>  struct panthor_gem_object *bo;
>>  int ret;
>>
>>  if (!mem)
>>  return ERR_PTR(-ENOMEM);
>>
>>  bo = panthor_gem_create_and_map(ptdev, ptdev->fw->vm,
>>  size, bo_flags, vm_map_flags,
>>  &va, NULL);
>>
>>  if (IS_ERR(bo)) {
>>  kfree(mem);
>>  return ERR_CAST(bo);
>>  }
>>
>>  mem->bo = bo;
>>  mem->va = va;
>>  return mem;
>>  
>> Which I think also means we don't need the "if (mem->bo)" case in
>> panthor_fw_mem_free().
> 
> Not so sure about that one. I've been adding code to existing functions
> and having a structured error path, with free functions that can deal
> with partially initialized object makes code addition less error-prone.
> I agree on the local bo variable to avoid mem->bo re-initialization
> though.

Yeah the "free accepting NULL" style is generally a good one, so leaving
the NULL check in panthor_fw_mem_free() is fine. It was just in this
case having to explicitly assign NULL before the call to
panthor_fw_mem_free() looked ugly.

>>
>>> +}
>>> +
> 
> [...]
> 
>>> +/**
>>> + * panthor_fw_alloc_suspend_buf_mem() - Allocate a suspend buffer for a 
>>> command stream group.
>>> + * @ptdev: Device.
>>> + * @size: Size of the suspend buffer.
>>> + *
>>> + * Return: A valid pointer in case of success, an ERR_PTR() otherwise.
>>> + */
>>> +struct panthor_fw_mem *
>>> +panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size)
>>> +{
>>> +   return panthor_fw_mem_alloc(ptdev, size,
>>> +   DRM_PANTHOR_BO_NO_MMAP,
>>> +   DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
>>> +   PANTHOR_GEM_ALLOC_VA);
>>> +}
>>> +
>>> +static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
>>> +const struct firmware *fw,
>>> +struct panthor_fw_binary_iter *iter,
>>> +u32 ehdr)
>>> +{
>>> +   struct panthor_fw_binary_section_entry_hdr hdr;
>>> +   struct panthor_fw_section *section;
>>> +   u32 section_size;
>>> +   u32 name_len;
>>> +   int ret;
>>> +
>>> +   ret = panthor_fw_binary_iter_read(ptdev, iter, &hdr, sizeof(hdr));
>>> +   if (ret)
>>> +   return ret;
>>> +
>>> +   if (hdr.data.end < hdr.data.start) {
>>> +   drm_err(&ptdev->base, "Firmware corrupted, data.end < 
>>> data.start (0x%x < 0x%x)\n",
>>> +   hdr.data.end, hdr.data.start);
>>> +   return -EINVAL;
>>> +   }
>>> +
>>> +   if (hdr.va.end < hdr.va.start) {
>>> +   drm_err(&ptdev->base, "Firmware corrupted, hdr.va.end < 
>>> hdr.va.start (0x%x < 0x%x)\n",
>>> +   hdr.va.end, hdr.va.start);
>>> +   return -EINVAL;
>>> +   }
>>> +
>>> +   if (hdr.data.end > fw->size) {
>>> +   drm_err(&ptdev->base, "Firmware corrupted, file truncated? 
>>> data_end=0x%x > fw size=0x%zx\n",
>>> +   hdr.data.end, fw->size);
>>> +   return -EINVAL;
>>> +   }
>>> +
>>> +   if ((hdr.va.start & ~PAGE_MASK) != 0 ||
>>> +   (hdr.va.end & ~PAGE_MASK) != 0) {
>>> +   drm_err(&ptdev->base, "Firmware corrupted, virtual addresses 
>>> not page aligned: 0x%x-0x%x\n",
>>> +   hdr.

Re: [PATCH v3 0/7] GPU workload hints for better performance

2023-08-30 Thread Michel Dänzer
On 8/28/23 17:02, Lazar, Lijo wrote:
> [AMD Official Use Only - General]
> 
> 
> As mentioned with an older version of this series, this is an 'abuse' of 
> power profile interface.
> 
> This series is oversimplifying what PMFW algorithms are supposed to be doing. 
> Whatever this series is doing, FW can do it better.
> 
> To explain in simpler terms - it just tries to boost a profile based on ring 
> type without even knowing how much of activity a job can trigger on a 
> particular ring. A job scheduled to a GFX ring doesn't deserve a profile 
> boost unless it can create a certain level of activity. In CPU terms, a job 
> scheduled to a processor doesn't mean it deserves a frequency boost of that 
> CPU.  At minimum it depends on more details like whether that job is compute 
> bound or memory bound or memory bound. 
> 
> While FW algorithms are designed to do that, this series tries to trivialise 
> all such things.
> 
> Unless you are able to show the tangible benefits in some terms like 
> performance, power, or performance per watt,  I don't think this should be 
> the default behaviour where driver tries to override FW just based on job 
> submissions to rings.

I know at least one tangible benefit this would have: a snappier GNOME desktop 
with lower input → output latency on many laptops. The bootup default profile 
doesn't work well for that IME.

It should also help for issues like
https://gitlab.freedesktop.org/drm/amd/-/issues/1500 .

That said, I agree this approach is very aggressive. I think it might be 
acceptable with AC power, not sure about on battery though. (There might be 
better performance/power profile mechanisms to hook into than AC vs battery)


-- 
Earthling Michel Dänzer|  https://redhat.com
Libre software enthusiast  | Mesa and Xwayland developer



Re: [PATCH v11] drm: Add initial ci/ subdirectory

2023-08-30 Thread Helen Koike




On 30/08/2023 11:57, Maxime Ripard wrote:

On Wed, Aug 30, 2023 at 10:24:49AM -0300, Helen Koike wrote:

Hi all,

Thanks for you comments.

On 30/08/2023 08:37, Maxime Ripard wrote:

On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote:

On Wed, 30 Aug 2023, Maxime Ripard  wrote:

On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote:

On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote:

From: Tomeu Vizoso 

Developers can easily execute several tests on different devices
by just pushing their branch to their fork in a repository hosted
on gitlab.freedesktop.org which has an infrastructure to run jobs
in several runners and farms with different devices.

There are also other automated tools that uprev dependencies,
monitor the infra, and so on that are already used by the Mesa
project, and we can reuse them too.

Also, store expectations about what the DRM drivers are supposed
to pass in the IGT test suite. By storing the test expectations
along with the code, we can make sure both stay in sync with each
other so we can know when a code change breaks those expectations.

Also, include a configuration file that points to the out-of-tree
CI scripts.

This will allow all contributors to drm to reuse the infrastructure
already in gitlab.freedesktop.org to test the driver on several
generations of the hardware.

Signed-off-by: Tomeu Vizoso 
Signed-off-by: Helen Koike 
Acked-by: Daniel Stone 
Acked-by: Rob Clark 
Tested-by: Rob Clark 


Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to
include that branch in linux-next.

But also I'd like to see a lot more acks here, we should be able to at
least pile up a bunch of (driver) maintainers from drm-misc in support of
this. Also maybe media, at least I've heard noises that they're maybe
interested too? Plus anyone else, the more the better.


I'm not really convinced by that approach at all, and most of the issues
I see are shown by the follow-up series here:


I'm not fully convinced either, more like "let's see". In that narrow
sense, ack. I don't see harm in trying, if you're also open to backing
off in case it does not pan out.


https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/

* We hardcode a CI farm setup into the kernel



These could be out of tree.

There is a version outside the kernel tree where you just point the CI
configuration to a url:
https://gitlab.freedesktop.org/gfx-ci/drm-ci/-/merge_requests/1

We were discussing it here 
https://www.linuxtv.org/cgi-bin/mailman/private/linuxtv-ci/2023-August/27.html


It looks like it's private


(I guess Sima's reply didn't got into the mailing list) but the argument of
not having out of tree repo is due to historical bad experience of having to
sync the kernel with the code and it can become messy.


My point is that even though the test strategy might be considered a
"property" of the kernel, how you execute it is definitely not and you
will have as many setups as you have CI farms. You can't put that into
the kernel, just like we don't put the kernel command line in it for
example. >


* We cannot trust that the code being run is actually the one being
  pushed into gitlab



We can improve this if this is a requirement.
For DTS configuration we can work with overlays (which is the current
modification on that patchset). For other changes that are not suitable to
upstream (and should be rare) we can see if we work with the
`-external-fixes` approach or another approach, we can check it case by case
to understand why it is not suitable for upstream.


The existence of that branch in itself is an issue to me. Again, it's a
matter of trust. How can I trust a branch I barely know about, of which
the development is not clear and isn't reviewed by any of the
maintainers of the code that might affect the test outcomes.

Or put another way, if I run the tests on my machine, it won't work. Why
should it work on the CI farm? The branch itself is broken. It might not
be due to any of the work I did, but it's broken still.



* IMO, and I know we disagree here, any IGT test we enable for a given
  platform should work, period. Allowing failures and flaky tests just
  sweeps whatever issue is there under the rug. If the test is at
  fault, we should fix the test, if the driver / kernel is at fault,
  then I certainly want to know about it.


I believe we need a baseline and understand the current status of tests. If
you check the xfails folder in the patch you can see that I had to add a few
tests on *-skips.txt since those tests crashes the system and other on
*-fails.txt that are consistently not passing.


I agree that we need a baseline, but that baseline should be defined by
the tests own merits, not their outcome on a particular platform.

In other words, I want all drivers to follow that baseline, and if they
don't it's a bug we should fix, and we should be vocal about it. We
shouldn't ignore

Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation

2023-08-30 Thread Danilo Krummrich
On Wed, Aug 30, 2023 at 03:42:08PM +0200, Thomas Hellström (Intel) wrote:
> 
> On 8/30/23 14:49, Danilo Krummrich wrote:
> > Hi Thomas,
> > 
> > thanks for having a look!
> > 
> > On Wed, Aug 30, 2023 at 09:27:45AM +0200, Thomas Hellström (Intel) wrote:
> > > Hi, Danilo.
> > > 
> > > Some quick comments since I'm doing some Xe work in this area. Will 
> > > probably
> > > get back with more.
> > > 
> > > On 8/20/23 23:53, Danilo Krummrich wrote:
> > > > So far the DRM GPUVA manager offers common infrastructure to track GPU 
> > > > VA
> > > > allocations and mappings, generically connect GPU VA mappings to their
> > > > backing buffers and perform more complex mapping operations on the GPU 
> > > > VA
> > > > space.
> > > > 
> > > > However, there are more design patterns commonly used by drivers, which
> > > > can potentially be generalized in order to make the DRM GPUVA manager
> > > > represent a basic GPU-VM implementation. In this context, this patch 
> > > > aims
> > > > at generalizing the following elements.
> > > > 
> > > > 1) Provide a common dma-resv for GEM objects not being used outside of
> > > >  this GPU-VM.
> > > > 
> > > > 2) Provide tracking of external GEM objects (GEM objects which are
> > > >  shared with other GPU-VMs).
> > > > 
> > > > 3) Provide functions to efficiently lock all GEM objects dma-resv the
> > > >  GPU-VM contains mappings of.
> > > > 
> > > > 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings
> > > >  of, such that validation of evicted GEM objects is accelerated.
> > > > 
> > > > 5) Provide some convinience functions for common patterns.
> > > > 
> > > > Rather than being designed as a "framework", the target is to make all
> > > > features appear as a collection of optional helper functions, such that
> > > > drivers are free to make use of the DRM GPUVA managers basic
> > > > functionality and opt-in for other features without setting any feature
> > > > flags, just by making use of the corresponding functions.
> > > > 
> > > > Signed-off-by: Danilo Krummrich 
> > > > ---
> > > >drivers/gpu/drm/drm_gpuva_mgr.c | 688 
> > > > +++-
> > > >include/drm/drm_gem.h   |  48 ++-
> > > >include/drm/drm_gpuva_mgr.h | 302 +-
> > > >3 files changed, 1010 insertions(+), 28 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c 
> > > > b/drivers/gpu/drm/drm_gpuva_mgr.c
> > > > index f86bfad74ff8..69872b205961 100644
> > > > --- a/drivers/gpu/drm/drm_gpuva_mgr.c
> > > > +++ b/drivers/gpu/drm/drm_gpuva_mgr.c
> > > > @@ -655,6 +655,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr,
> > > >/**
> > > > * drm_gpuva_manager_init() - initialize a &drm_gpuva_manager
> > > > * @mgr: pointer to the &drm_gpuva_manager to initialize
> > > > + * @drm: the drivers &drm_device
> > > > * @name: the name of the GPU VA space
> > > > * @start_offset: the start offset of the GPU VA space
> > > > * @range: the size of the GPU VA space
> > > > @@ -669,6 +670,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr,
> > > > */
> > > >void
> > > >drm_gpuva_manager_init(struct drm_gpuva_manager *mgr,
> > > > +  struct drm_device *drm,
> > > >const char *name,
> > > >u64 start_offset, u64 range,
> > > >u64 reserve_offset, u64 reserve_range,
> > > > @@ -677,6 +679,11 @@ drm_gpuva_manager_init(struct drm_gpuva_manager 
> > > > *mgr,
> > > > mgr->rb.tree = RB_ROOT_CACHED;
> > > > INIT_LIST_HEAD(&mgr->rb.list);
> > > > +   mt_init(&mgr->mt_ext);
> > > > +
> > > > +   INIT_LIST_HEAD(&mgr->evict.list);
> > > > +   spin_lock_init(&mgr->evict.lock);
> > > > +
> > > > drm_gpuva_check_overflow(start_offset, range);
> > > > mgr->mm_start = start_offset;
> > > > mgr->mm_range = range;
> > > > @@ -694,6 +701,9 @@ drm_gpuva_manager_init(struct drm_gpuva_manager 
> > > > *mgr,
> > > >  reserve_range)))
> > > > __drm_gpuva_insert(mgr, 
> > > > &mgr->kernel_alloc_node);
> > > > }
> > > > +
> > > > +   drm_gem_private_object_init(drm, &mgr->d_obj, 0);
> > > > +   mgr->resv = mgr->d_obj.resv;
> > > >}
> > > >EXPORT_SYMBOL_GPL(drm_gpuva_manager_init);
> > > > @@ -713,10 +723,575 @@ drm_gpuva_manager_destroy(struct 
> > > > drm_gpuva_manager *mgr)
> > > > __drm_gpuva_remove(&mgr->kernel_alloc_node);
> > > > WARN(!RB_EMPTY_ROOT(&mgr->rb.tree.rb_root),
> > > > -"GPUVA tree is not empty, potentially leaking memory.");
> > > > +"GPUVA tree is not empty, potentially leaking memory.\n");
> > > > +
> > > > +   mtree_destroy(&mgr->mt_ext);
> > > > +   WARN(!list_empty(&mgr->evict.list), "Evict list should be 
> > > > empty.\n");
> > > > +
> > > > +   drm_gem_private_obj

Re: [PATCH v11] drm: Add initial ci/ subdirectory

2023-08-30 Thread Maxime Ripard
On Wed, Aug 30, 2023 at 10:24:49AM -0300, Helen Koike wrote:
> Hi all,
> 
> Thanks for you comments.
> 
> On 30/08/2023 08:37, Maxime Ripard wrote:
> > On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote:
> > > On Wed, 30 Aug 2023, Maxime Ripard  wrote:
> > > > On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote:
> > > > > On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote:
> > > > > > From: Tomeu Vizoso 
> > > > > > 
> > > > > > Developers can easily execute several tests on different devices
> > > > > > by just pushing their branch to their fork in a repository hosted
> > > > > > on gitlab.freedesktop.org which has an infrastructure to run jobs
> > > > > > in several runners and farms with different devices.
> > > > > > 
> > > > > > There are also other automated tools that uprev dependencies,
> > > > > > monitor the infra, and so on that are already used by the Mesa
> > > > > > project, and we can reuse them too.
> > > > > > 
> > > > > > Also, store expectations about what the DRM drivers are supposed
> > > > > > to pass in the IGT test suite. By storing the test expectations
> > > > > > along with the code, we can make sure both stay in sync with each
> > > > > > other so we can know when a code change breaks those expectations.
> > > > > > 
> > > > > > Also, include a configuration file that points to the out-of-tree
> > > > > > CI scripts.
> > > > > > 
> > > > > > This will allow all contributors to drm to reuse the infrastructure
> > > > > > already in gitlab.freedesktop.org to test the driver on several
> > > > > > generations of the hardware.
> > > > > > 
> > > > > > Signed-off-by: Tomeu Vizoso 
> > > > > > Signed-off-by: Helen Koike 
> > > > > > Acked-by: Daniel Stone 
> > > > > > Acked-by: Rob Clark 
> > > > > > Tested-by: Rob Clark 
> > > > > 
> > > > > Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr 
> > > > > to
> > > > > include that branch in linux-next.
> > > > > 
> > > > > But also I'd like to see a lot more acks here, we should be able to at
> > > > > least pile up a bunch of (driver) maintainers from drm-misc in 
> > > > > support of
> > > > > this. Also maybe media, at least I've heard noises that they're maybe
> > > > > interested too? Plus anyone else, the more the better.
> > > > 
> > > > I'm not really convinced by that approach at all, and most of the issues
> > > > I see are shown by the follow-up series here:
> > > 
> > > I'm not fully convinced either, more like "let's see". In that narrow
> > > sense, ack. I don't see harm in trying, if you're also open to backing
> > > off in case it does not pan out.
> > > 
> > > > https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/
> > > > 
> > > >* We hardcode a CI farm setup into the kernel
> 
> 
> These could be out of tree.
> 
> There is a version outside the kernel tree where you just point the CI
> configuration to a url:
> https://gitlab.freedesktop.org/gfx-ci/drm-ci/-/merge_requests/1
> 
> We were discussing it here 
> https://www.linuxtv.org/cgi-bin/mailman/private/linuxtv-ci/2023-August/27.html

It looks like it's private

> (I guess Sima's reply didn't got into the mailing list) but the argument of
> not having out of tree repo is due to historical bad experience of having to
> sync the kernel with the code and it can become messy.

My point is that even though the test strategy might be considered a
"property" of the kernel, how you execute it is definitely not and you
will have as many setups as you have CI farms. You can't put that into
the kernel, just like we don't put the kernel command line in it for
example.

> > > > 
> > > >* We cannot trust that the code being run is actually the one being
> > > >  pushed into gitlab
> 
> 
> We can improve this if this is a requirement.
> For DTS configuration we can work with overlays (which is the current
> modification on that patchset). For other changes that are not suitable to
> upstream (and should be rare) we can see if we work with the
> `-external-fixes` approach or another approach, we can check it case by case
> to understand why it is not suitable for upstream.

The existence of that branch in itself is an issue to me. Again, it's a
matter of trust. How can I trust a branch I barely know about, of which
the development is not clear and isn't reviewed by any of the
maintainers of the code that might affect the test outcomes.

Or put another way, if I run the tests on my machine, it won't work. Why
should it work on the CI farm? The branch itself is broken. It might not
be due to any of the work I did, but it's broken still.

> > > >
> > > >* IMO, and I know we disagree here, any IGT test we enable for a 
> > > > given
> > > >  platform should work, period. Allowing failures and flaky tests 
> > > > just
> > > >  sweeps whatever issue is there under the rug. If the test is at
> > > >  fault, we should fix the test, if the driver / kernel is at fault,
> > > > 

Re: [PATCH v2 08/15] drm/panthor: Add the MMU/VM logical block

2023-08-30 Thread Boris Brezillon
On Wed, 30 Aug 2023 15:12:43 +0100
Steven Price  wrote:

> On 29/08/2023 16:33, Boris Brezillon wrote:
> > On Mon, 14 Aug 2023 16:53:09 +0100
> > Steven Price  wrote:
> >   
> >>> +
> >>> +/**
> >>> + * struct panthor_vm_op_ctx - VM operation context
> >>> + *
> >>> + * With VM operations potentially taking place in a dma-signaling path, 
> >>> we
> >>> + * need to make sure everything that might require resource allocation is
> >>> + * pre-allocated upfront. This is what this operation context is far.
> >>> + *
> >>> + * We also collect resources that have been freed, so we can release them
> >>> + * asynchronously, and let the VM_BIND scheduler process the next VM_BIND
> >>> + * request.
> >>> + */
> >>> +struct panthor_vm_op_ctx {
> >>> + /** @rsvd_page_tables: Pages reserved for the MMU page table update. */
> >>> + struct {
> >>> + /** @count: Number of pages reserved. */
> >>> + u32 count;
> >>> +
> >>> + /** @ptr: Point to the first unused page in the @pages table. */
> >>> + u32 ptr;
> >>> +
> >>> + /**
> >>> +  * @page: Array of pages that can be used for an MMU page table 
> >>> update.
> >>> +  *
> >>> +  * After an VM operation, there might be free pages left in 
> >>> this array.
> >>> +  * They should be returned to the pt_cache as part of the 
> >>> op_ctx cleanup.
> >>> +  */
> >>> + void **pages;
> >>> + } rsvd_page_tables;
> >>
> >> Two questions:
> >>
> >> 1) Would a mempool simplify the implementation? It looks like a
> >> reasonable match.  
> > 
> > Not sure what you mean by mempool,  
> 
> See include/linux/mempool.h

Oh, okay.

> 
> > but I'm using a kmem_cache here for
> > all page table allocations. The pages that are passed to
> > panthor_vm_op_ctx::rsvd_page_tables::pages are allocated from this
> > pool. It's just that for each VM operation we pre-allocate page-tables,
> > and release those that were not used when the operation is done (we
> > over-allocate for the worst case scenario).  
> 
> The mempool could, potentially, replace the rsvd_page_tables structure.
> The kmem_cache you would still want as that's per-driver.

Need to have a closer look at the API to make my mind, but at first
glance it seems to be overkill for what I initially had in mind.

> 
> >>
> >> 2) Does it really make sense to have a separate pool of memory for every
> >> operation? Instead of having a separate pool for each operation, it
> >> would be possible to just keep track of the total number needed for all
> >> outstanding operations. Then a single (per device or maybe per-VM if
> >> necessary) mempool could be resized to ensure it has the right amount of
> >> space.  
> > 
> > The pool is per-driver (see the global pt_cache). rsvd_page_tables just
> > holds pages needed for a specific VM operation. To be more specific, it
> > holds pages for the worst case (page table tree is empty, except for the
> > root page table).  
> 
> What I'm wondering is to we need to keep the pages for each operation in
> separate pools.

I was not really considering it a pool, more a set of pages that will
be used by the VM operation, some of them being returned to the
kmem_cache pool if we end up using less (over-provisioning). If we have
a mempool, say, at the VM level, that means we have 2 levels of caching:
the kmem_cache itself, and the mempool attached to the VM. Is there any
benefit here? Do we expect kmem_cache to be too slow for fast/already
allocated pages?

I do see how over-provisioning can cause us to allocate a lot of pages
that end up being unused, but I fail to see how VM/device level caching
would solve that, because we still have to dequeue some operations to
return pages to the intermediate pool, at which point, we've already
lost, because already queued operations reserved the amount of pages
they thought they needed for the worst case scenario.
Operations being queued after that can pick from the returned pages of
course, but that's already the case right now, because we return pages
to the kmem_cache as soon as we're done executing a VM operation.

The only thing that might help is limiting the number of in-flight
VM_BIND jobs per VM (or globally), and then have the submit path return
EBUSY or EGAIN so the userspace driver knows it has to retry at a later
time.

> So instead of having a rsvd_page_tables for each
> operation, can we have one global one which is sized appropriately for
> all operations that are in flight for the device? The operations are
> serialized so there's no contention. Or at least a per-VM pool if we can
> operate on multiple VMs at once.

We can operate on multiple VMs at once (VM is basically your VkDevice,
AKA the logical device), but I'm not too worried about the
synchronization that would be incurred by the caching at the
panthor_device level. I'm just curious to know what value it would add.
I'm also worried that it makes the reservation logic more complex:
we need to track wha

Re: [PATCH v11] drm: Add initial ci/ subdirectory

2023-08-30 Thread Rob Clark
replying to a couple points on this thread

On Wed, Aug 30, 2023 at 6:25 AM Helen Koike  wrote:
>
> Hi all,
>
> Thanks for you comments.
>
> On 30/08/2023 08:37, Maxime Ripard wrote:
> > On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote:
> >> On Wed, 30 Aug 2023, Maxime Ripard  wrote:
> >>> On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote:
>  On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote:
> > From: Tomeu Vizoso 
> >
> > Developers can easily execute several tests on different devices
> > by just pushing their branch to their fork in a repository hosted
> > on gitlab.freedesktop.org which has an infrastructure to run jobs
> > in several runners and farms with different devices.
> >
> > There are also other automated tools that uprev dependencies,
> > monitor the infra, and so on that are already used by the Mesa
> > project, and we can reuse them too.
> >
> > Also, store expectations about what the DRM drivers are supposed
> > to pass in the IGT test suite. By storing the test expectations
> > along with the code, we can make sure both stay in sync with each
> > other so we can know when a code change breaks those expectations.
> >
> > Also, include a configuration file that points to the out-of-tree
> > CI scripts.
> >
> > This will allow all contributors to drm to reuse the infrastructure
> > already in gitlab.freedesktop.org to test the driver on several
> > generations of the hardware.
> >
> > Signed-off-by: Tomeu Vizoso 
> > Signed-off-by: Helen Koike 
> > Acked-by: Daniel Stone 
> > Acked-by: Rob Clark 
> > Tested-by: Rob Clark 
> 
>  Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to
>  include that branch in linux-next.
> 
>  But also I'd like to see a lot more acks here, we should be able to at
>  least pile up a bunch of (driver) maintainers from drm-misc in support of
>  this. Also maybe media, at least I've heard noises that they're maybe
>  interested too? Plus anyone else, the more the better.
> >>>
> >>> I'm not really convinced by that approach at all, and most of the issues
> >>> I see are shown by the follow-up series here:
> >>
> >> I'm not fully convinced either, more like "let's see". In that narrow
> >> sense, ack. I don't see harm in trying, if you're also open to backing
> >> off in case it does not pan out.
> >>
> >>> https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/
> >>>
> >>>* We hardcode a CI farm setup into the kernel

We do have farm status out of tree so we don't need to push a kernel
patch for outages.

Other than that, I can go either way, with the scripts and related yml
in tree or out of tree.  But the expectation files (ie. the patch you
are complaining about) absolutely need to be in-tree.  It must be
possible to update them in sync with driver changes that fix tests.
There may be a bit of related churn initially ie. based on our lengthy
experience at this point with mesa CI, we can't know about all the
flaky tests until people start using CI in anger ;-)

>
>
> These could be out of tree.
>
> There is a version outside the kernel tree where you just point the CI
> configuration to a url:
> https://gitlab.freedesktop.org/gfx-ci/drm-ci/-/merge_requests/1
>
> We were discussing it here
> https://www.linuxtv.org/cgi-bin/mailman/private/linuxtv-ci/2023-August/27.html
>
> (I guess Sima's reply didn't got into the mailing list) but the argument
> of not having out of tree repo is due to historical bad experience of
> having to sync the kernel with the code and it can become messy.
>
>
> >>>
> >>>* We cannot trust that the code being run is actually the one being
> >>>  pushed into gitlab
>
>
> We can improve this if this is a requirement.
> For DTS configuration we can work with overlays (which is the current
> modification on that patchset). For other changes that are not suitable
> to upstream (and should be rare) we can see if we work with the
> `-external-fixes` approach or another approach, we can check it case by
> case to understand why it is not suitable for upstream.
>

IMHO the occasional need for extra patches is a fact of life with the
kernel development process, and we'll have to live with this until
_all_ kernel patches run thru pre-merge CI.  (I'm not holding my
breath, but who knows..)

If some particular board doesn't boot because of some early-rc
breakage elsewhere in the kernel, then we can't run CI.

>
> >>>
> >>>* IMO, and I know we disagree here, any IGT test we enable for a given
> >>>  platform should work, period. Allowing failures and flaky tests just
> >>>  sweeps whatever issue is there under the rug. If the test is at
> >>>  fault, we should fix the test, if the driver / kernel is at fault,
> >>>  then I certainly want to know about it.
>
>
> I believe we need a baseline an

Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()

2023-08-30 Thread Andy Shevchenko
On Wed, Aug 30, 2023 at 5:19 PM  wrote:
> On Wed, 2023-08-30 at 17:11 +0300, Andy Shevchenko wrote:
> > On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner 
> > wrote:

> > > --- a/include/linux/string.h
> > > +++ b/include/linux/string.h
> >
> > I'm wondering if this has no side-effects as string.h/string.c IIRC
> > is
> > used also for early stages where some of the APIs are not available.
> >
> > > @@ -6,6 +6,8 @@
> > >  #include/* for size_t */
> > >  #include   /* for NULL */
> > >  #include/* for E2BIG */
> > > +#include /* for check_mul_overflow() */
> > > +#include  /* for ERR_PTR() */
> >
> > Can we preserve order (to some extent)?
>
> Sure. I just put it there so the comments build a congruent block.
> Which order would you prefer?

Alphabetical.

compiler.h
err.h
overflow.h
...the rest that is a bit unordered...

> > >  #include 
> > >  #include 

...

> > > +/**
> > > + * memdup_array_user - duplicate array from user space
> >
> > > + *
> >
> > Do we need this blank line?
>
> I more or less directly copied the docstring format from the original
> functions (v)memdup_user() in mm/util.c
> I guess this is common style?

I think it's not. But you may grep kernel source tree and tell which
one occurs more often with or without this (unneeded) blank line.

> > > + * @src: source address in user space
> > > + * @n: number of array members to copy
> > > + * @size: size of one array member
> > > + *
> > > + * Return: an ERR_PTR() on failure.  Result is physically
> > > + * contiguous, to be freed by kfree().
> > > + */

...

> > > +/**
> > > + * vmemdup_array_user - duplicate array from user space
> >
> > > + *
> >
> > Redundant?
>
> No, there are two functions:
>  * memdup_array_user()
>  * vmemdup_array_user()
>
> On the deeper layers they utilize kmalloc() or kvmalloc(),
> respectively.

I guess you misunderstood my comment. I was talking about kernel doc
(as in the previous function).

> > > + * @src: source address in user space
> > > + * @n: number of array members to copy
> > > + * @size: size of one array member
> > > + *
> > > + * Return: an ERR_PTR() on failure.  Result may be not
> > > + * physically contiguous.  Use kvfree() to free.
> > > + */


-- 
With Best Regards,
Andy Shevchenko


[PATCH v2 8/8] drm: adv7511: Add hpd_override_enable variable to struct adv7511_chip_info

2023-08-30 Thread Biju Das
As per spec, it is allowed to pulse the HPD signal to indicate that the
EDID information has changed. Some monitors do this when they wake up
from standby or are enabled. When the HPD goes low the adv7511 is
reset and the outputs are disabled which might cause the monitor to
go to standby again. To avoid this we ignore the HPD pin for the
first few seconds after enabling the output. On the other hand,
adv7535 require to enable HPD Override bit for proper HPD.

Add hpd_override_enable variable to struct adv7511_chip_info to handle
this scenario.

Signed-off-by: Biju Das 
---
v1->v2:
 * Restored enum adv7511_type as there are users.
 * Replaced variable type from unsigned->bool.
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 ---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 0d39e32b0793..39c9ece373b0 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -342,6 +342,7 @@ struct adv7511_chip_info {
unsigned int reg_cec_offset;
bool has_dsi;
bool link_config;
+   bool hpd_override_enable;
 };
 
 struct adv7511 {
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index e0ec3c098225..83ff4206b3b7 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511)
 * first few seconds after enabling the output. On the other hand
 * adv7535 require to enable HPD Override bit for proper HPD.
 */
-   if (adv7511->info->type == ADV7535)
+   if (adv7511->info->hpd_override_enable)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
   ADV7535_REG_POWER2_HPD_OVERRIDE,
   ADV7535_REG_POWER2_HPD_OVERRIDE);
@@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
 static void __adv7511_power_off(struct adv7511 *adv7511)
 {
/* TODO: setup additional power down modes */
-   if (adv7511->info->type == ADV7535)
+   if (adv7511->info->hpd_override_enable)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
   ADV7535_REG_POWER2_HPD_OVERRIDE, 0);
 
@@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct 
drm_connector *connector)
status = connector_status_disconnected;
} else {
/* Renable HPD sensing */
-   if (adv7511->info->type == ADV7535)
+   if (adv7511->info->hpd_override_enable)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
   ADV7535_REG_POWER2_HPD_OVERRIDE,
   ADV7535_REG_POWER2_HPD_OVERRIDE);
@@ -1379,6 +1379,7 @@ static const struct adv7511_chip_info adv7535_chip_info = 
{
.num_supplies = ARRAY_SIZE(adv7533_supply_names),
.reg_cec_offset = ADV7533_REG_CEC_OFFSET,
.has_dsi = true,
+   .hpd_override_enable = true,
 };
 
 static const struct i2c_device_id adv7511_i2c_ids[] = {
-- 
2.25.1



[PATCH v2 7/8] drm: adv7511: Add link_config variable to struct adv7511_chip_info

2023-08-30 Thread Biju Das
The ADV7511 needs link configuration whereas ADV75{33,35} does not need
it. Add a variable link_config to struct adv7511_chip_info to handle
this difference.

Signed-off-by: Biju Das 
Reviewed-by: Laurent Pinchart 
---
v1->v2:
 * Add Rb tag from Laurent.
 * Replaced variable type from unsigned->bool.
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 0dd56e311039..0d39e32b0793 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -341,6 +341,7 @@ struct adv7511_chip_info {
unsigned int num_supplies;
unsigned int reg_cec_offset;
bool has_dsi;
+   bool link_config;
 };
 
 struct adv7511 {
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 9d88c29b6f59..e0ec3c098225 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1203,7 +1203,7 @@ static int adv7511_probe(struct i2c_client *i2c)
 
memset(&link_config, 0, sizeof(link_config));
 
-   if (adv7511->info->type == ADV7511)
+   if (adv7511->info->link_config)
ret = adv7511_parse_dt(dev->of_node, &link_config);
else
ret = adv7533_parse_dt(dev->of_node, adv7511);
@@ -1292,7 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c)
 
i2c_set_clientdata(i2c, adv7511);
 
-   if (adv7511->info->type == ADV7511)
+   if (adv7511->info->link_config)
adv7511_set_link_config(adv7511, &link_config);
 
ret = adv7511_cec_init(dev, adv7511);
@@ -1358,6 +1358,7 @@ static const struct adv7511_chip_info adv7511_chip_info = 
{
.type = ADV7511,
.supply_names = adv7511_supply_names,
.num_supplies = ARRAY_SIZE(adv7511_supply_names),
+   .link_config = true,
 };
 
 static const struct adv7511_chip_info adv7533_chip_info = {
-- 
2.25.1



[PATCH v2 6/8] drm: adv7511: Add has_dsi variable to struct adv7511_chip_info

2023-08-30 Thread Biju Das
The ADV7533 and ADV7535 have DSI support. Add a variable has_dsi to
struct adv7511_chip_info for handling configuration related to DSI.

Signed-off-by: Biju Das 
---
v1->v2:
 * Replaced variable type from unsigned->bool.
 * Restored check using type for low_refresh_rate and
   regmap_register_patch().
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h |  1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 10 ++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index a728bfb33d03..0dd56e311039 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -340,6 +340,7 @@ struct adv7511_chip_info {
const char * const *supply_names;
unsigned int num_supplies;
unsigned int reg_cec_offset;
+   bool has_dsi;
 };
 
 struct adv7511 {
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index d806c870bf76..9d88c29b6f59 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
 */
regcache_sync(adv7511->regmap);
 
-   if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535)
+   if (adv7511->info->has_dsi)
adv7533_dsi_power_on(adv7511);
adv7511->powered = true;
 }
@@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511)
 static void adv7511_power_off(struct adv7511 *adv7511)
 {
__adv7511_power_off(adv7511);
-   if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535)
+   if (adv7511->info->has_dsi)
adv7533_dsi_power_off(adv7511);
adv7511->powered = false;
 }
@@ -921,7 +921,7 @@ static enum drm_mode_status 
adv7511_bridge_mode_valid(struct drm_bridge *bridge,
 {
struct adv7511 *adv = bridge_to_adv7511(bridge);
 
-   if (adv->info->type == ADV7533 || adv->info->type == ADV7535)
+   if (adv->info->has_dsi)
return adv7533_mode_valid(adv, mode);
else
return adv7511_mode_valid(adv, mode);
@@ -1311,7 +1311,7 @@ static int adv7511_probe(struct i2c_client *i2c)
 
adv7511_audio_init(dev, adv7511);
 
-   if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) {
+   if (adv7511->info->has_dsi) {
ret = adv7533_attach_dsi(adv7511);
if (ret)
goto err_unregister_audio;
@@ -1367,6 +1367,7 @@ static const struct adv7511_chip_info adv7533_chip_info = 
{
.supply_names = adv7533_supply_names,
.num_supplies = ARRAY_SIZE(adv7533_supply_names),
.reg_cec_offset = ADV7533_REG_CEC_OFFSET,
+   .has_dsi = true,
 };
 
 static const struct adv7511_chip_info adv7535_chip_info = {
@@ -1376,6 +1377,7 @@ static const struct adv7511_chip_info adv7535_chip_info = 
{
.supply_names = adv7533_supply_names,
.num_supplies = ARRAY_SIZE(adv7533_supply_names),
.reg_cec_offset = ADV7533_REG_CEC_OFFSET,
+   .has_dsi = true,
 };
 
 static const struct i2c_device_id adv7511_i2c_ids[] = {
-- 
2.25.1



[PATCH v2 5/8] drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info

2023-08-30 Thread Biju Das
The ADV7533 and ADV7535 have an offset(0x70) for the CEC register map
compared to ADV7511. Add the reg_cec_offset variable to struct
adv7511_chip_info to handle this difference and drop the reg_cec_offset
variable from struct adv7511.

This will avoid assigning reg_cec_offset based on chip type and also
testing for multiple chip types for calling adv7533_patch_cec_registers().

Signed-off-by: Biju Das 
---
v2:
 * New patch.
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h |  2 +-
 drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 14 +++---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c |  8 
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index edf7be9c21d3..a728bfb33d03 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -339,6 +339,7 @@ struct adv7511_chip_info {
unsigned int max_lane_freq_khz;
const char * const *supply_names;
unsigned int num_supplies;
+   unsigned int reg_cec_offset;
 };
 
 struct adv7511 {
@@ -349,7 +350,6 @@ struct adv7511 {
 
struct regmap *regmap;
struct regmap *regmap_cec;
-   unsigned int reg_cec_offset;
enum drm_connector_status status;
bool powered;
 
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
index 2a6b91f752cb..44451a9658a3 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
@@ -33,7 +33,7 @@ static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = {
 
 static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status)
 {
-   unsigned int offset = adv7511->reg_cec_offset;
+   unsigned int offset = adv7511->info->reg_cec_offset;
unsigned int val;
 
if (regmap_read(adv7511->regmap_cec,
@@ -84,7 +84,7 @@ static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 
tx_raw_status)
 
 static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf)
 {
-   unsigned int offset = adv7511->reg_cec_offset;
+   unsigned int offset = adv7511->info->reg_cec_offset;
struct cec_msg msg = {};
unsigned int len;
unsigned int val;
@@ -121,7 +121,7 @@ static void adv7511_cec_rx(struct adv7511 *adv7511, int 
rx_buf)
 
 void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
 {
-   unsigned int offset = adv7511->reg_cec_offset;
+   unsigned int offset = adv7511->info->reg_cec_offset;
const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY |
ADV7511_INT1_CEC_TX_ARBIT_LOST |
ADV7511_INT1_CEC_TX_RETRY_TIMEOUT;
@@ -177,7 +177,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, 
unsigned int irq1)
 static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
 {
struct adv7511 *adv7511 = cec_get_drvdata(adap);
-   unsigned int offset = adv7511->reg_cec_offset;
+   unsigned int offset = adv7511->info->reg_cec_offset;
 
if (adv7511->i2c_cec == NULL)
return -EIO;
@@ -223,7 +223,7 @@ static int adv7511_cec_adap_enable(struct cec_adapter 
*adap, bool enable)
 static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
 {
struct adv7511 *adv7511 = cec_get_drvdata(adap);
-   unsigned int offset = adv7511->reg_cec_offset;
+   unsigned int offset = adv7511->info->reg_cec_offset;
unsigned int i, free_idx = ADV7511_MAX_ADDRS;
 
if (!adv7511->cec_enabled_adap)
@@ -292,7 +292,7 @@ static int adv7511_cec_adap_transmit(struct cec_adapter 
*adap, u8 attempts,
 u32 signal_free_time, struct cec_msg *msg)
 {
struct adv7511 *adv7511 = cec_get_drvdata(adap);
-   unsigned int offset = adv7511->reg_cec_offset;
+   unsigned int offset = adv7511->info->reg_cec_offset;
u8 len = msg->len;
unsigned int i;
 
@@ -345,7 +345,7 @@ static int adv7511_cec_parse_dt(struct device *dev, struct 
adv7511 *adv7511)
 
 int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
 {
-   unsigned int offset = adv7511->reg_cec_offset;
+   unsigned int offset = adv7511->info->reg_cec_offset;
int ret = adv7511_cec_parse_dt(dev, adv7511);
 
if (ret)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 2bcd17953221..d806c870bf76 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1035,7 +1035,7 @@ static bool adv7511_cec_register_volatile(struct device 
*dev, unsigned int reg)
struct i2c_client *i2c = to_i2c_client(dev);
struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
 
-   reg -= adv7511->reg_cec_offset;
+   reg -= adv7511->info->reg_cec_offset;
 
switch (reg) {
case ADV7511_REG_CEC_RX1_FRAME_HDR:
@@

[PATCH v2 4/8] drm: adv7511: Add supply_names and num_supplies variables to struct adv7511_chip_info

2023-08-30 Thread Biju Das
The ADV7511 has 5 power supplies compared to 7 that of ADV75{33,35}. Add
supply_names and num_supplies variables to struct adv7511_chip_info to
handle this difference.

Signed-off-by: Biju Das 
Reviewed-by: Laurent Pinchart 
---
v1->v2:
 * Added Rb tag from Laurent.
 * Added trailing commas for num_supplies in adv753{3,5}_chip_info.
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h |  3 ++-
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 27 ++--
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index f8d61f2fa30e..edf7be9c21d3 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -337,6 +337,8 @@ struct adv7511_chip_info {
enum adv7511_type type;
unsigned int max_mode_clock_khz;
unsigned int max_lane_freq_khz;
+   const char * const *supply_names;
+   unsigned int num_supplies;
 };
 
 struct adv7511 {
@@ -375,7 +377,6 @@ struct adv7511 {
struct gpio_desc *gpio_pd;
 
struct regulator_bulk_data *supplies;
-   unsigned int num_supplies;
 
/* ADV7533 DSI RX related params */
struct device_node *host_node;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 1c76aa5a5d5b..2bcd17953221 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1004,37 +1004,30 @@ static const char * const adv7533_supply_names[] = {
 
 static int adv7511_init_regulators(struct adv7511 *adv)
 {
+   const char * const *supply_names = adv->info->supply_names;
+   unsigned int num_supplies = adv->info->num_supplies;
struct device *dev = &adv->i2c_main->dev;
-   const char * const *supply_names;
unsigned int i;
int ret;
 
-   if (adv->info->type == ADV7511) {
-   supply_names = adv7511_supply_names;
-   adv->num_supplies = ARRAY_SIZE(adv7511_supply_names);
-   } else {
-   supply_names = adv7533_supply_names;
-   adv->num_supplies = ARRAY_SIZE(adv7533_supply_names);
-   }
-
-   adv->supplies = devm_kcalloc(dev, adv->num_supplies,
+   adv->supplies = devm_kcalloc(dev, num_supplies,
 sizeof(*adv->supplies), GFP_KERNEL);
if (!adv->supplies)
return -ENOMEM;
 
-   for (i = 0; i < adv->num_supplies; i++)
+   for (i = 0; i < num_supplies; i++)
adv->supplies[i].supply = supply_names[i];
 
-   ret = devm_regulator_bulk_get(dev, adv->num_supplies, adv->supplies);
+   ret = devm_regulator_bulk_get(dev, num_supplies, adv->supplies);
if (ret)
return ret;
 
-   return regulator_bulk_enable(adv->num_supplies, adv->supplies);
+   return regulator_bulk_enable(num_supplies, adv->supplies);
 }
 
 static void adv7511_uninit_regulators(struct adv7511 *adv)
 {
-   regulator_bulk_disable(adv->num_supplies, adv->supplies);
+   regulator_bulk_disable(adv->info->num_supplies, adv->supplies);
 }
 
 static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg)
@@ -1365,18 +1358,24 @@ static void adv7511_remove(struct i2c_client *i2c)
 
 static const struct adv7511_chip_info adv7511_chip_info = {
.type = ADV7511,
+   .supply_names = adv7511_supply_names,
+   .num_supplies = ARRAY_SIZE(adv7511_supply_names),
 };
 
 static const struct adv7511_chip_info adv7533_chip_info = {
.type = ADV7533,
.max_mode_clock_khz = 8,
.max_lane_freq_khz = 80,
+   .supply_names = adv7533_supply_names,
+   .num_supplies = ARRAY_SIZE(adv7533_supply_names),
 };
 
 static const struct adv7511_chip_info adv7535_chip_info = {
.type = ADV7535,
.max_mode_clock_khz = 148500,
.max_lane_freq_khz = 891000,
+   .supply_names = adv7533_supply_names,
+   .num_supplies = ARRAY_SIZE(adv7533_supply_names),
 };
 
 static const struct i2c_device_id adv7511_i2c_ids[] = {
-- 
2.25.1



[PATCH v2 3/8] drm: adv7511: Add max_lane_freq_khz variable to struct adv7511_chip_info

2023-08-30 Thread Biju Das
The ADV7533 supports a maximum lane clock of 800MHz whereas it is 891MHz
for ADV7535. Add max_lane_freq_khz variable to struct adv7511_chip_info to
handle this difference.

While at it, drop the unused local variable max_lane_freq.

Signed-off-by: Biju Das 
Reviewed-by: Laurent Pinchart 
---
v1->v2:
 * Added Rb tag from Laurent.
 * Replaced max_lane_freq->max_lane_freq_khz in struct adv7511_chip_info.
 * Replaced variable type from unsigned long->unsigned int.
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++
 drivers/gpu/drm/bridge/adv7511/adv7533.c | 5 +
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index b9c6c1e8a353..f8d61f2fa30e 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -336,6 +336,7 @@ enum adv7511_type {
 struct adv7511_chip_info {
enum adv7511_type type;
unsigned int max_mode_clock_khz;
+   unsigned int max_lane_freq_khz;
 };
 
 struct adv7511 {
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 12ceffd6a9eb..1c76aa5a5d5b 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1370,11 +1370,13 @@ static const struct adv7511_chip_info adv7511_chip_info 
= {
 static const struct adv7511_chip_info adv7533_chip_info = {
.type = ADV7533,
.max_mode_clock_khz = 8,
+   .max_lane_freq_khz = 80,
 };
 
 static const struct adv7511_chip_info adv7535_chip_info = {
.type = ADV7535,
.max_mode_clock_khz = 148500,
+   .max_lane_freq_khz = 891000,
 };
 
 static const struct i2c_device_id adv7511_i2c_ids[] = {
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c 
b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index 1d113489754c..4481489aaf5e 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -103,7 +103,6 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
 enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
const struct drm_display_mode *mode)
 {
-   unsigned long max_lane_freq;
struct mipi_dsi_device *dsi = adv->dsi;
u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
 
@@ -112,9 +111,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
return MODE_CLOCK_HIGH;
 
/* Check max clock for each lane */
-   max_lane_freq = (adv->info->type == ADV7533 ? 80 : 891000);
-
-   if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes)
+   if (mode->clock * bpp > adv->info->max_lane_freq_khz * 
adv->num_dsi_lanes)
return MODE_CLOCK_HIGH;
 
return MODE_OK;
-- 
2.25.1



[PATCH v2 2/8] drm: adv7511: Add max_mode_clock_khz variable to struct adv7511_chip_info

2023-08-30 Thread Biju Das
The ADV7533 supports a maximum pixel clock of 80MHz whereas it is 148.5MHz
for ADV7535. Add max_mode_clock_khz variable to struct adv7511_chip_info to
handle this difference.

Signed-off-by: Biju Das 
Reviewed-by: Adam Ford 
Tested-by: Adam Ford  #imx8mm-beacon
Reviewed-by: Laurent Pinchart 
---
 * Added Rb tag from Adam and Laurent
 * Added tested by tag from Adam.
 * Replaced max_mode_clock->max_mode_clock_khz in struct adv7511_chip_info
 * Replaced variable type from unsigned int->unsigned long.
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++
 drivers/gpu/drm/bridge/adv7511/adv7533.c | 2 +-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 59e8ef10d72e..b9c6c1e8a353 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -335,6 +335,7 @@ enum adv7511_type {
 
 struct adv7511_chip_info {
enum adv7511_type type;
+   unsigned int max_mode_clock_khz;
 };
 
 struct adv7511 {
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index d869dbe41873..12ceffd6a9eb 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1369,10 +1369,12 @@ static const struct adv7511_chip_info adv7511_chip_info 
= {
 
 static const struct adv7511_chip_info adv7533_chip_info = {
.type = ADV7533,
+   .max_mode_clock_khz = 8,
 };
 
 static const struct adv7511_chip_info adv7535_chip_info = {
.type = ADV7535,
+   .max_mode_clock_khz = 148500,
 };
 
 static const struct i2c_device_id adv7511_i2c_ids[] = {
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c 
b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index c452c4dc1c3f..1d113489754c 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -108,7 +108,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
 
/* Check max clock for either 7533 or 7535 */
-   if (mode->clock > (adv->info->type == ADV7533 ? 8 : 148500))
+   if (mode->clock > adv->info->max_mode_clock_khz)
return MODE_CLOCK_HIGH;
 
/* Check max clock for each lane */
-- 
2.25.1



[PATCH v2 1/8] drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data()

2023-08-30 Thread Biju Das
Add struct adv7511_chip_info to handle hw differences between various
chips rather checking against the 'type' variable in various places.
Replace 'adv->type'->'info->type' by moving variable 'type' from
struct adv7511 to struct adv7511_chip_info and add adv7511_chip_info as
device data for both OF and ID tables instead of the device type.

Simplify the probe() by replacing of_device_get_match_data() and ID lookup
for retrieving match data with i2c_get_match_data().

Signed-off-by: Biju Das 
Tested-by: Fabio Estevam 
Reviewed-by: Adam Ford 
Reviewed-by: Laurent Pinchart 
---
v1->v2:
 * Added Tested by tag from Fabio Estevam.
 * Added Rb tag from Adam and Laurent.
 * Updated commit description with reason *why* the change is needed.
 * Dropped the local info variable and instead started using
   adv7511->info->type in probe().
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h |  6 +-
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 65 +++-
 drivers/gpu/drm/bridge/adv7511/adv7533.c |  4 +-
 3 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 17445800248d..59e8ef10d72e 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -333,6 +333,10 @@ enum adv7511_type {
 
 #define ADV7511_MAX_ADDRS 3
 
+struct adv7511_chip_info {
+   enum adv7511_type type;
+};
+
 struct adv7511 {
struct i2c_client *i2c_main;
struct i2c_client *i2c_edid;
@@ -377,7 +381,7 @@ struct adv7511 {
u8 num_dsi_lanes;
bool use_timing_gen;
 
-   enum adv7511_type type;
+   const struct adv7511_chip_info *info;
struct platform_device *audio_pdev;
 
struct cec_adapter *cec_adap;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 2611afd2c1c1..d869dbe41873 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511)
 * first few seconds after enabling the output. On the other hand
 * adv7535 require to enable HPD Override bit for proper HPD.
 */
-   if (adv7511->type == ADV7535)
+   if (adv7511->info->type == ADV7535)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
   ADV7535_REG_POWER2_HPD_OVERRIDE,
   ADV7535_REG_POWER2_HPD_OVERRIDE);
@@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
 */
regcache_sync(adv7511->regmap);
 
-   if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
+   if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535)
adv7533_dsi_power_on(adv7511);
adv7511->powered = true;
 }
@@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
 static void __adv7511_power_off(struct adv7511 *adv7511)
 {
/* TODO: setup additional power down modes */
-   if (adv7511->type == ADV7535)
+   if (adv7511->info->type == ADV7535)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
   ADV7535_REG_POWER2_HPD_OVERRIDE, 0);
 
@@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511)
 static void adv7511_power_off(struct adv7511 *adv7511)
 {
__adv7511_power_off(adv7511);
-   if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
+   if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535)
adv7533_dsi_power_off(adv7511);
adv7511->powered = false;
 }
@@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct 
drm_connector *connector)
status = connector_status_disconnected;
} else {
/* Renable HPD sensing */
-   if (adv7511->type == ADV7535)
+   if (adv7511->info->type == ADV7535)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
   ADV7535_REG_POWER2_HPD_OVERRIDE,
   ADV7535_REG_POWER2_HPD_OVERRIDE);
@@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
else
low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
 
-   if (adv7511->type == ADV7511)
+   if (adv7511->info->type == ADV7511)
regmap_update_bits(adv7511->regmap, 0xfb,
   0x6, low_refresh_rate << 1);
else
@@ -921,7 +921,7 @@ static enum drm_mode_status 
adv7511_bridge_mode_valid(struct drm_bridge *bridge,
 {
struct adv7511 *adv = bridge_to_adv7511(bridge);
 
-   if (adv->type == ADV7533 || adv->type == ADV7535)
+   if (adv->info->type == ADV7533 || adv->info->type == ADV7535)
return adv7533_mode_valid(adv,

[PATCH v2 0/8] ADV7511 driver enhancements

2023-08-30 Thread Biju Das
This patch series aims to improve ADV7511 driver by adding
feature bits and data instead of comparing enum adv7511_type for
various hardware differences between ADV7511, ADV7533 and ADV7535.

This patch series tested with[1] on RZ/G2L SMARC EVK which embeds
ADV7535.

[1] https://patchwork.kernel.org/project/linux-renesas-soc/list/?series=762260

v1->v2:
 * Added Rb tag from Adam and Laurent.
 * Added tested by tag from Adam and Fabio.
 * Updated commit description with reason *why* the change is needed.
 * Dropped the local info variable and instead started using
   adv7511->info->type in probe().
 * Replaced max_mode_clock->max_mode_clock_khz in struct adv7511_chip_info
 * Replaced variable type for max_mode_clock_khz from
   unsigned int->unsigned long.
 * Replaced max_lane_freq->max_lane_freq_khz in struct adv7511_chip_info.
 * Replaced max_lane_freq_khz variable type from
   unsigned long->unsigned int.
 * Added trailing commas for num_supplies in adv753{3,5}_chip_info.
 * Added patch#5 for adding the reg_cec_offset variable to struct
   adv7511_chip_info.
 * Replaced has_dsi variable type from unsigned->bool.
 * Restored check using type for low_refresh_rate and
   regmap_register_patch().
 * Replaced link_config variable type from unsigned->bool.
 * Restored enum adv7511_type as there are users.
 * Replaced hpd_override_enable variable type from unsigned->bool.

Biju Das (8):
  drm: adv7511: Add struct adv7511_chip_info and use
i2c_get_match_data()
  drm: adv7511: Add max_mode_clock_khz variable to struct
adv7511_chip_info
  drm: adv7511: Add max_lane_freq_khz variable to struct
adv7511_chip_info
  drm: adv7511: Add supply_names and num_supplies variables to struct
adv7511_chip_info
  drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info
  drm: adv7511: Add has_dsi variable to struct adv7511_chip_info
  drm: adv7511: Add link_config variable to struct adv7511_chip_info
  drm: adv7511: Add hpd_override_enable variable to struct
adv7511_chip_info

 drivers/gpu/drm/bridge/adv7511/adv7511.h |  16 ++-
 drivers/gpu/drm/bridge/adv7511/adv7511_cec.c |  14 +--
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 104 +++
 drivers/gpu/drm/bridge/adv7511/adv7533.c |   7 +-
 4 files changed, 81 insertions(+), 60 deletions(-)

-- 
2.25.1



Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()

2023-08-30 Thread pstanner
On Wed, 2023-08-30 at 17:15 +0300, Andy Shevchenko wrote:
> On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner 
> wrote:
> 
> > +   if (unlikely(check_mul_overflow(n, size, &nbytes)))
> > +   return ERR_PTR(-EINVAL);
> 
> > +   if (unlikely(check_mul_overflow(n, size, &nbytes)))
> > +   return ERR_PTR(-EINVAL);
> 
> Btw, why not -EOVERFLOW ?
> 

Good question, actually.
To be honest I wasn't quite sure which code to pick (-E2BIG was also
once I candidate).

-EINVAL was picked because the idea was that a request overflowing a
size_t could surely be expected to contain an invalid parameter,
because no one would ever request an array _that_ large

?



Re: [PATCH 1/5] drm/debugfs: drop debugfs_init() for the render and accel node v2

2023-08-30 Thread Christian König

Am 30.08.23 um 10:19 schrieb Andi Shyti:

Hi Christian,

On Tue, Aug 29, 2023 at 01:01:11PM +0200, Christian König wrote:

We want to remove per minor debugfs directories. Start by stopping
drivers from adding anything inside of those in the mid layer callback.

v2: drop it for the accel node as well

Signed-off-by: Christian König 
Tested-by: Stanislaw Gruszka 

Reviewed-by: Andi Shyti 


Is that for just this patch or the whole series?

Thanks,
Christian.



Thanks,
Andi




Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()

2023-08-30 Thread pstanner
On Wed, 2023-08-30 at 17:11 +0300, Andy Shevchenko wrote:
> On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner 
> wrote:
> > 
> > Currently, user array duplications are sometimes done without an
> > overflow check. Sometimes the checks are done manually; sometimes
> > the
> > array size is calculated with array_size() and sometimes by
> > calculating
> > n * size directly in code.
> > 
> > Introduce wrappers for arrays for memdup_user() and vmemdup_user()
> > to
> > provide a standardized and safe way for duplicating user arrays.
> > 
> > This is both for new code as well as replacing usage of
> > (v)memdup_user()
> > in existing code that uses, e.g., n * size to calculate array
> > sizes.
> 
> ...
> 
> > --- a/include/linux/string.h
> > +++ b/include/linux/string.h
> 
> I'm wondering if this has no side-effects as string.h/string.c IIRC
> is
> used also for early stages where some of the APIs are not available.
> 
> > @@ -6,6 +6,8 @@
> >  #include    /* for size_t */
> >  #include   /* for NULL */
> >  #include    /* for E2BIG */
> > +#include     /* for check_mul_overflow() */
> > +#include  /* for ERR_PTR() */
> 
> Can we preserve order (to some extent)?

Sure. I just put it there so the comments build a congruent block.
Which order would you prefer?

> 
> >  #include 
> >  #include 
> 
> ...
> 
> > +/**
> > + * memdup_array_user - duplicate array from user space
> 
> > + *
> 
> Do we need this blank line?

I more or less directly copied the docstring format from the original
functions (v)memdup_user() in mm/util.c
I guess this is common style?

> 
> > + * @src: source address in user space
> > + * @n: number of array members to copy
> > + * @size: size of one array member
> > + *
> > + * Return: an ERR_PTR() on failure.  Result is physically
> > + * contiguous, to be freed by kfree().
> > + */
> 
> ...
> 
> > +/**
> > + * vmemdup_array_user - duplicate array from user space
> 
> > + *
> 
> Redundant?

No, there are two functions:
 * memdup_array_user()
 * vmemdup_array_user()

On the deeper layers they utilize kmalloc() or kvmalloc(),
respectively.


Greetings,
P.

> 
> > + * @src: source address in user space
> > + * @n: number of array members to copy
> > + * @size: size of one array member
> > + *
> > + * Return: an ERR_PTR() on failure.  Result may be not
> > + * physically contiguous.  Use kvfree() to free.
> > + */
> 



Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()

2023-08-30 Thread Andy Shevchenko
On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner  wrote:

> +   if (unlikely(check_mul_overflow(n, size, &nbytes)))
> +   return ERR_PTR(-EINVAL);

> +   if (unlikely(check_mul_overflow(n, size, &nbytes)))
> +   return ERR_PTR(-EINVAL);

Btw, why not -EOVERFLOW ?

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v2 08/15] drm/panthor: Add the MMU/VM logical block

2023-08-30 Thread Steven Price
On 29/08/2023 16:33, Boris Brezillon wrote:
> On Mon, 14 Aug 2023 16:53:09 +0100
> Steven Price  wrote:
> 
>>> +
>>> +/**
>>> + * struct panthor_vm_op_ctx - VM operation context
>>> + *
>>> + * With VM operations potentially taking place in a dma-signaling path, we
>>> + * need to make sure everything that might require resource allocation is
>>> + * pre-allocated upfront. This is what this operation context is far.
>>> + *
>>> + * We also collect resources that have been freed, so we can release them
>>> + * asynchronously, and let the VM_BIND scheduler process the next VM_BIND
>>> + * request.
>>> + */
>>> +struct panthor_vm_op_ctx {
>>> +   /** @rsvd_page_tables: Pages reserved for the MMU page table update. */
>>> +   struct {
>>> +   /** @count: Number of pages reserved. */
>>> +   u32 count;
>>> +
>>> +   /** @ptr: Point to the first unused page in the @pages table. */
>>> +   u32 ptr;
>>> +
>>> +   /**
>>> +* @page: Array of pages that can be used for an MMU page table 
>>> update.
>>> +*
>>> +* After an VM operation, there might be free pages left in 
>>> this array.
>>> +* They should be returned to the pt_cache as part of the 
>>> op_ctx cleanup.
>>> +*/
>>> +   void **pages;
>>> +   } rsvd_page_tables;  
>>
>> Two questions:
>>
>> 1) Would a mempool simplify the implementation? It looks like a
>> reasonable match.
> 
> Not sure what you mean by mempool,

See include/linux/mempool.h

> but I'm using a kmem_cache here for
> all page table allocations. The pages that are passed to
> panthor_vm_op_ctx::rsvd_page_tables::pages are allocated from this
> pool. It's just that for each VM operation we pre-allocate page-tables,
> and release those that were not used when the operation is done (we
> over-allocate for the worst case scenario).

The mempool could, potentially, replace the rsvd_page_tables structure.
The kmem_cache you would still want as that's per-driver.

>>
>> 2) Does it really make sense to have a separate pool of memory for every
>> operation? Instead of having a separate pool for each operation, it
>> would be possible to just keep track of the total number needed for all
>> outstanding operations. Then a single (per device or maybe per-VM if
>> necessary) mempool could be resized to ensure it has the right amount of
>> space.
> 
> The pool is per-driver (see the global pt_cache). rsvd_page_tables just
> holds pages needed for a specific VM operation. To be more specific, it
> holds pages for the worst case (page table tree is empty, except for the
> root page table).

What I'm wondering is to we need to keep the pages for each operation in
separate pools. So instead of having a rsvd_page_tables for each
operation, can we have one global one which is sized appropriately for
all operations that are in flight for the device? The operations are
serialized so there's no contention. Or at least a per-VM pool if we can
operate on multiple VMs at once.

>>
>> I'm also a little wary that the VM_BIND infrastructure could potentially
>> be abused to trigger a large amount of kernel allocation as it allocates
>> up-front for the worst case but those pages are not charged to the
>> process (AFAICT). But I haven't fully got my head round that yet.
> 
> Yep, that's problematic, indeed. I considered allocating page tables
> as GEM objects, but the overhead of a GEM object is quite big
> (hundreds of bytes of meta-data) compared to the size of a page table
> (4k), and kmem_cache was just super convenient for this page table
> cache :-).

I think page tables as GEM objects is likely to be overkill, we
obviously also have to be careful not to allow user space to get access
to the contents - whereas GEM objects are usually to provide user space
access ;) I'm not sure quite what the best solution here is, clearly one
'solution' is to just cap the number of outstanding VM_BINDs.

>>
>>> +
>>> +   /** @flags: Combination of drm_panthor_vm_bind_op_flags. */
>>> +   u32 flags;
>>> +
>>> +   /** @va: Virtual range targeted by the VM operation. */
>>> +   struct {
>>> +   /** @addr: Start address. */
>>> +   u64 addr;
>>> +
>>> +   /** @range: Range size. */
>>> +   u64 range;
>>> +   } va;
>>> +
>>> +   /**
>>> +* @returned_vmas: List of panthor_vma objects returned after a VM 
>>> operation.
>>> +*
>>> +* For unmap operations, this will contain all VMAs that were covered 
>>> by the
>>> +* specified VA range.
>>> +*
>>> +* For map operations, this will contain all VMAs that previously 
>>> mapped to
>>> +* the specified VA range.
>>> +*
>>> +* Those VMAs, and the resources they point to will be released as part 
>>> of
>>> +* the op_ctx cleanup operation.
>>> +*/
>>> +   struct list_head returned_vmas;
>>> +
>>> +   /** @map: Fields specific to a map operation. */
>>> +   struct {
>>> +   /** @gem: GEM object information

  1   2   >