Re: [PATCH v3 1/1] drm/panfrost: Replace fdinfo's profiling debugfs knob with sysfs

2024-03-11 Thread Adrián Larumbe
On 11.03.2024 11:02, Boris Brezillon wrote:
> On Wed, 6 Mar 2024 08:33:47 +
> Tvrtko Ursulin  wrote:
> 
> > On 06/03/2024 01:56, Adrián Larumbe wrote:
> > > Debugfs isn't always available in production builds that try to squeeze
> > > every single byte out of the kernel image, but we still need a way to
> > > toggle the timestamp and cycle counter registers so that jobs can be
> > > profiled for fdinfo's drm engine and cycle calculations.
> > > 
> > > Drop the debugfs knob and replace it with a sysfs file that accomplishes
> > > the same functionality, and document its ABI in a separate file.
> > > 
> > > Signed-off-by: Adrián Larumbe 
> > > ---
> > >   .../testing/sysfs-driver-panfrost-profiling   | 10 +
> > >   Documentation/gpu/panfrost.rst|  9 
> > >   drivers/gpu/drm/panfrost/Makefile |  2 -
> > >   drivers/gpu/drm/panfrost/panfrost_debugfs.c   | 21 --
> > >   drivers/gpu/drm/panfrost/panfrost_debugfs.h   | 14 ---
> > >   drivers/gpu/drm/panfrost/panfrost_device.h|  2 +-
> > >   drivers/gpu/drm/panfrost/panfrost_drv.c   | 41 ---
> > >   drivers/gpu/drm/panfrost/panfrost_job.c   |  2 +-
> > >   8 files changed, 57 insertions(+), 44 deletions(-)
> > >   create mode 100644 
> > > Documentation/ABI/testing/sysfs-driver-panfrost-profiling
> > >   delete mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.c
> > >   delete mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.h
> > > 
> > > diff --git a/Documentation/ABI/testing/sysfs-driver-panfrost-profiling 
> > > b/Documentation/ABI/testing/sysfs-driver-panfrost-profiling
> > > new file mode 100644
> > > index ..1d8bb0978920
> > > --- /dev/null
> > > +++ b/Documentation/ABI/testing/sysfs-driver-panfrost-profiling
> > > @@ -0,0 +1,10 @@
> > > +What:/sys/bus/platform/drivers/panfrost/.../profiling
> > > +Date:February 2024
> > > +KernelVersion:   6.8.0
> > > +Contact: Adrian Larumbe 
> > > +Description:
> > > + Get/set drm fdinfo's engine and cycles profiling status.
> > > + Valid values are:
> > > + 0: Don't enable fdinfo job profiling sources.
> > > + 1: Enable fdinfo job profiling sources, this enables both the 
> > > GPU's
> > > +timestamp and cycle counter registers.
> > > \ No newline at end of file
> > > diff --git a/Documentation/gpu/panfrost.rst 
> > > b/Documentation/gpu/panfrost.rst
> > > index b80e41f4b2c5..51ba375fd80d 100644
> > > --- a/Documentation/gpu/panfrost.rst
> > > +++ b/Documentation/gpu/panfrost.rst
> > > @@ -38,3 +38,12 @@ the currently possible format options:
> > >   
> > >   Possible `drm-engine-` key names are: `fragment`, and  `vertex-tiler`.
> > >   `drm-curfreq-` values convey the current operating frequency for that 
> > > engine.
> > > +
> > > +Users must bear in mind that engine and cycle sampling are disabled by 
> > > default,
> > > +because of power saving concerns. `fdinfo` users and benchmark 
> > > applications which
> > > +query the fdinfo file must make sure to toggle the job profiling status 
> > > of the
> > > +driver by writing into the appropriate sysfs node::
> > > +
> > > +echo  > 
> > > /sys/bus/platform/drivers/panfrost/[a-f0-9]*.gpu/profiling  
> > 
> > A late thought - how it would work to not output the inactive fdinfo 
> > keys when this knob is not enabled?
> > 
> > Generic userspace like gputop already handles that and wouldn't show the 
> > stat. Which may be more user friendly than showing stats permanently at 
> > zero. It may be moot once you add the auto-toggle to gputop (or so) but 
> > perhaps worth considering.
> 
> I agree with Tvrtko, if the line being printed in fdinfo relies on some
> sysfs knob to be valid, we'd rather not print the information in that
> case, instead of printing zero.

Me too. I'll go first change both gputop and nvtop to make sure they use the new
sysfs knob for Panfrost, and then submit a new patch that handles printing of
the drm-cycles-* and drm-engine-* stats depending on the profiling knob state.


Re: [PATCH v3 6/7] arm64: dts: qcom: sm8650: add GPU nodes

2024-03-11 Thread Konrad Dybcio




On 2/16/24 12:03, Neil Armstrong wrote:

Add GPU nodes for the SM8650 platform.

Signed-off-by: Neil Armstrong 
---
  arch/arm64/boot/dts/qcom/sm8650.dtsi | 166 +++
  1 file changed, 166 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi 
b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index 62e6ae93a9a8..27dcef27b6ad 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -2589,6 +2589,128 @@ tcsr: clock-controller@1fc {
#reset-cells = <1>;
};
  
+		gpu: gpu@3d0 {

+   compatible = "qcom,adreno-43051401", "qcom,adreno";
+   reg = <0x0 0x03d0 0x0 0x4>,
+ <0x0 0x03d9e000 0x0 0x1000>,
+ <0x0 0x03d61000 0x0 0x800>;
+   reg-names = "kgsl_3d0_reg_memory",
+   "cx_mem",
+   "cx_dbgc";
+
+   interrupts = ;
+
+   iommus = <&adreno_smmu 0 0x0>,
+<&adreno_smmu 1 0x0>;
+
+   operating-points-v2 = <&gpu_opp_table>;
+
+   qcom,gmu = <&gmu>;
+
+   status = "disabled";
+
+   zap-shader {
+   memory-region = <&gpu_micro_code_mem>;
+   };
+
+   /* Speedbin needs more work on A740+, keep only lower 
freqs */
+   gpu_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-68000 {
+   opp-hz = /bits/ 64 <68000>;
+   opp-level = 
;
+   };


I got a memo from krzk that we should be sorting OPPs low-to-high,
could you please reorder these (and under gmu)?

Otherwise lgtm

Konrad


[drm-intel:for-linux-next 4/6] drivers/gpu/drm/i915/display/intel_bios.c:3417:24: error: implicit declaration of function 'intel_opregion_vbt_present'; did you mean 'intel_opregion_asle_present'?

2024-03-11 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm-intel for-linux-next
head:   0e7dd6fe96020e6b7f5e068bf1c66078e0b145d3
commit: 9d9bb71f3e115b75ec5e38f087e159a87fc0413a [4/6] drm/i915: Extract 
opregion vbt presence check
config: sparc64-allmodconfig 
(https://download.01.org/0day-ci/archive/20240312/202403120756.jtkghcip-...@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240312/202403120756.jtkghcip-...@intel.com/reproduce)

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

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/display/intel_bios.c: In function 
'intel_bios_is_lvds_present':
>> drivers/gpu/drm/i915/display/intel_bios.c:3417:24: error: implicit 
>> declaration of function 'intel_opregion_vbt_present'; did you mean 
>> 'intel_opregion_asle_present'? [-Werror=implicit-function-declaration]
3417 | return intel_opregion_vbt_present(i915);
 |^~
 |intel_opregion_asle_present
   cc1: some warnings being treated as errors


vim +3417 drivers/gpu/drm/i915/display/intel_bios.c

  3374  
  3375  /**
  3376   * intel_bios_is_lvds_present - is LVDS present in VBT
  3377   * @i915:   i915 device instance
  3378   * @i2c_pin:i2c pin for LVDS if present
  3379   *
  3380   * Return true if LVDS is present. If no child devices were parsed from 
VBT,
  3381   * assume LVDS is present.
  3382   */
  3383  bool intel_bios_is_lvds_present(struct drm_i915_private *i915, u8 
*i2c_pin)
  3384  {
  3385  const struct intel_bios_encoder_data *devdata;
  3386  
  3387  if (list_empty(&i915->display.vbt.display_devices))
  3388  return true;
  3389  
  3390  list_for_each_entry(devdata, 
&i915->display.vbt.display_devices, node) {
  3391  const struct child_device_config *child = 
&devdata->child;
  3392  
  3393  /* If the device type is not LFP, continue.
  3394   * We have to check both the new identifiers as well as 
the
  3395   * old for compatibility with some BIOSes.
  3396   */
  3397  if (child->device_type != DEVICE_TYPE_INT_LFP &&
  3398  child->device_type != DEVICE_TYPE_LFP)
  3399  continue;
  3400  
  3401  if (intel_gmbus_is_valid_pin(i915, child->i2c_pin))
  3402  *i2c_pin = child->i2c_pin;
  3403  
  3404  /* However, we cannot trust the BIOS writers to populate
  3405   * the VBT correctly.  Since LVDS requires additional
  3406   * information from AIM blocks, a non-zero addin offset 
is
  3407   * a good indicator that the LVDS is actually present.
  3408   */
  3409  if (child->addin_offset)
  3410  return true;
  3411  
  3412  /* But even then some BIOS writers perform some black 
magic
  3413   * and instantiate the device without reference to any
  3414   * additional data.  Trust that if the VBT was written 
into
  3415   * the OpRegion then they have validated the LVDS's 
existence.
  3416   */
> 3417  return intel_opregion_vbt_present(i915);
  3418  }
  3419  
  3420  return false;
  3421  }
  3422  

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


[PATCH v2] Fix divide-by-zero regression on DP MST unplug with nouveau

2024-03-11 Thread Chris Bainbridge
Fix a regression when using nouveau and unplugging a StarTech MSTDP122DP
DisplaypPort 1.2 MST hub (the same regression does not appear when using
a Cable Matters DisplayPort 1.4 MST hub). Trace:

 divide error:  [#1] PREEMPT SMP PTI
 CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.0-rc3+ #744
 Hardware name: Razer Blade/DANA_MB, BIOS 01.01 08/31/2018
 RIP: 0010:drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
 Code: c6 b8 01 00 00 00 75 61 01 c6 41 0f af f3 41 0f af f1 c1 e1 04 48 63 c7 
31 d2 89 ff 48 8b 5d f8 c9 48 0f af f1 48 8d 44 06 ff <48> f7 f7 31 d2 31 c9 31 
f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 31
 RSP: 0018:b2c5c211fa30 EFLAGS: 00010206
 RAX:  RBX:  RCX: 00f59b00
 RDX:  RSI:  RDI: 
 RBP: b2c5c211fa48 R08: 0001 R09: 0020
 R10: 0004 R11:  R12: 00023b4a
 R13: 91d37d165800 R14: 91d36fac6d80 R15: 91d34a764010
 FS:  7f4a1ca3fa80() GS:91d6edbc() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 559491d49000 CR3: 00011d180002 CR4: 003706f0
 Call Trace:
  
  ? show_regs+0x6d/0x80
  ? die+0x37/0xa0
  ? do_trap+0xd4/0xf0
  ? do_error_trap+0x71/0xb0
  ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
  ? exc_divide_error+0x3a/0x70
  ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
  ? asm_exc_divide_error+0x1b/0x20
  ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
  ? drm_dp_calc_pbn_mode+0x2e/0x70 [drm_display_helper]
  nv50_msto_atomic_check+0xda/0x120 [nouveau]
  drm_atomic_helper_check_modeset+0xa87/0xdf0 [drm_kms_helper]
  drm_atomic_helper_check+0x19/0xa0 [drm_kms_helper]
  nv50_disp_atomic_check+0x13f/0x2f0 [nouveau]
  drm_atomic_check_only+0x668/0xb20 [drm]
  ? drm_connector_list_iter_next+0x86/0xc0 [drm]
  drm_atomic_commit+0x58/0xd0 [drm]
  ? __pfx___drm_printfn_info+0x10/0x10 [drm]
  drm_atomic_connector_commit_dpms+0xd7/0x100 [drm]
  drm_mode_obj_set_property_ioctl+0x1c5/0x450 [drm]
  ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
  drm_connector_property_set_ioctl+0x3b/0x60 [drm]
  drm_ioctl_kernel+0xb9/0x120 [drm]
  drm_ioctl+0x2d0/0x550 [drm]
  ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
  nouveau_drm_ioctl+0x61/0xc0 [nouveau]
  __x64_sys_ioctl+0xa0/0xf0
  do_syscall_64+0x76/0x140
  ? do_syscall_64+0x85/0x140
  ? do_syscall_64+0x85/0x140
  entry_SYSCALL_64_after_hwframe+0x6e/0x76
 RIP: 0033:0x7f4a1cd1a94f
 Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 
08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 f0 ff ff 
77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00
 RSP: 002b:7ffd2f1df520 EFLAGS: 0246 ORIG_RAX: 0010
 RAX: ffda RBX: 7ffd2f1df5b0 RCX: 7f4a1cd1a94f
 RDX: 7ffd2f1df5b0 RSI: c01064ab RDI: 000f
 RBP: c01064ab R08: 56347932deb8 R09: 56347a7d99c0
 R10:  R11: 0246 R12: 56347938a220
 R13: 000f R14: 563479d9f3f0 R15: 
  
 Modules linked in: rfcomm xt_conntrack nft_chain_nat xt_MASQUERADE nf_nat 
nf_conntrack_netlink nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xfrm_user 
xfrm_algo xt_addrtype nft_compat nf_tables nfnetlink br_netfilter bridge stp 
llc ccm cmac algif_hash overlay algif_skcipher af_alg bnep binfmt_misc 
snd_sof_pci_intel_cnl snd_sof_intel_hda_common snd_soc_hdac_hda snd_sof_pci 
snd_sof_xtensa_dsp snd_sof_intel_hda snd_sof snd_sof_utils 
snd_soc_acpi_intel_match snd_soc_acpi snd_soc_core snd_compress 
snd_sof_intel_hda_mlink snd_hda_ext_core iwlmvm intel_rapl_msr 
intel_rapl_common intel_tcc_cooling x86_pkg_temp_thermal intel_powerclamp 
mac80211 coretemp kvm_intel snd_hda_codec_hdmi kvm snd_hda_codec_realtek 
snd_hda_codec_generic uvcvideo libarc4 snd_hda_intel snd_intel_dspcfg 
snd_hda_codec iwlwifi videobuf2_vmalloc videobuf2_memops uvc irqbypass btusb 
videobuf2_v4l2 snd_seq_midi crct10dif_pclmul hid_multitouch crc32_pclmul 
snd_seq_midi_event btrtl snd_hwdep videodev polyval_clmulni polyval_generic 
snd_rawmidi
  ghash_clmulni_intel aesni_intel btintel crypto_simd snd_hda_core cryptd 
snd_seq btbcm ee1004 8250_dw videobuf2_common btmtk rapl nls_iso8859_1 mei_hdcp 
thunderbolt bluetooth intel_cstate wmi_bmof intel_wmi_thunderbolt cfg80211 
snd_pcm mc snd_seq_device i2c_i801 r8169 ecdh_generic snd_timer i2c_smbus ecc 
snd mei_me intel_lpss_pci mei ahci intel_lpss soundcore realtek libahci idma64 
intel_pch_thermal i2c_hid_acpi i2c_hid acpi_pad sch_fq_codel msr parport_pc 
ppdev lp parport efi_pstore ip_tables x_tables autofs4 dm_crypt raid10 raid456 
libcrc32c async_raid6_recov async_memcpy async_pq async_xor xor async_tx 
raid6_pq raid1 raid0 joydev input_leds hid_generic usbhid hid nouveau i915 
drm_ttm_helper gpu_sched drm_gpuvm drm_exec i2c_algo_bit drm_buddy ttm 
drm_display_helper drm_kms_helper cec rc_core drm nvme nv

[drm-misc:drm-misc-next 3/3] drivers/iommu/Kconfig:14:error: recursive dependency detected!

2024-03-11 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
head:   b33651a5c98dbd5a919219d8c129d0674ef74299
commit: 674dc7f61aefea81901c21402946074927e63f1a [3/3] drm/panthor: Fix 
undefined panthor_device_suspend/resume symbol issue
config: x86_64-rhel-8.3-rust (attached as .config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 
6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240312/202403120656.gmvnlwml-...@intel.com/reproduce)

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

Note: the drm-misc/drm-misc-next HEAD b33651a5c98dbd5a919219d8c129d0674ef74299 
builds fine.
  It only hurts bisectability.

All errors (new ones prefixed by >>):

>> drivers/iommu/Kconfig:14:error: recursive dependency detected!
   drivers/iommu/Kconfig:14:symbol IOMMU_SUPPORT is selected by DRM_PANTHOR
   drivers/gpu/drm/panthor/Kconfig:3:   symbol DRM_PANTHOR depends on PM
   kernel/power/Kconfig:183:symbol PM is selected by PM_SLEEP
   kernel/power/Kconfig:117:symbol PM_SLEEP depends on HIBERNATE_CALLBACKS
   kernel/power/Kconfig:35: symbol HIBERNATE_CALLBACKS is selected by 
XEN_SAVE_RESTORE
   arch/x86/xen/Kconfig:67: symbol XEN_SAVE_RESTORE depends on XEN
   arch/x86/xen/Kconfig:6:  symbol XEN depends on PARAVIRT
   arch/x86/Kconfig:781:symbol PARAVIRT is selected by HYPERV
   drivers/hv/Kconfig:5:symbol HYPERV depends on X86_LOCAL_APIC
   arch/x86/Kconfig:1106:   symbol X86_LOCAL_APIC depends on X86_UP_APIC
   arch/x86/Kconfig:1081:   symbol X86_UP_APIC prompt is visible depending 
on PCI_MSI
   drivers/pci/Kconfig:39:  symbol PCI_MSI is selected by AMD_IOMMU
   drivers/iommu/amd/Kconfig:3: symbol AMD_IOMMU depends on IOMMU_SUPPORT
   For a resolution refer to Documentation/kbuild/kconfig-language.rst
   subsection "Kconfig recursive dependency limitations"


vim +14 drivers/iommu/Kconfig

68255b628776df Joerg Roedel2011-06-14 @14  menuconfig IOMMU_SUPPORT
68255b628776df Joerg Roedel2011-06-14  15   bool "IOMMU Hardware Support"
e5144c93758519 Arnd Bergmann   2015-01-28  16   depends on MMU
68255b628776df Joerg Roedel2011-06-14  17   default y
a7f7f6248d9740 Masahiro Yamada 2020-06-14  18   help
68255b628776df Joerg Roedel2011-06-14  19 Say Y here if you want to 
compile device drivers for IO Memory
68255b628776df Joerg Roedel2011-06-14  20 Management Units into the 
kernel. These devices usually allow to
68255b628776df Joerg Roedel2011-06-14  21 remap DMA requests and/or 
remap interrupts from other devices on the
68255b628776df Joerg Roedel2011-06-14  22 system.
68255b628776df Joerg Roedel2011-06-14  23  

:: The code at line 14 was first introduced by commit
:: 68255b628776dfafa7f67ca3afd66bd4ba377307 iommu: Move iommu Kconfig 
entries to submenu

:: TO: Joerg Roedel 
:: CC: Joerg Roedel 

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


Re: [10/13] drm/fbdev-generic: Fix locking with drm_client_buffer_vmap_local()

2024-03-11 Thread Sui Jingfeng

Hi,


On 2024/2/27 18:14, Thomas Zimmermann wrote:

Temporarily lock the fbdev buffer object during updates to prevent
memory managers from evicting/moving the buffer. Moving a buffer
object while update its content results in undefined behaviour.

Fbdev-generic updates its buffer object from a shadow buffer. Gem-shmem
and gem-dma helpers do not move buffer objects, so they are safe to be
used with fbdev-generic. Gem-vram and qxl are based on TTM, but pin
buffer objects are part of the vmap operation. So both are also safe
to be used with fbdev-generic.

Amdgpu and nouveau do not pin or lock the buffer object during an
update. Their TTM-based memory management could move the buffer object
while the update is ongoing.

The new vmap_local and vunmap_local helpers hold the buffer object's
reservation lock during the buffer update. This prevents moving the
buffer object on all memory managers.

Signed-off-by: Thomas Zimmermann 
---
  drivers/gpu/drm/drm_client.c| 68 +
  drivers/gpu/drm/drm_fbdev_generic.c |  4 +-
  drivers/gpu/drm/drm_gem.c   | 12 +
  include/drm/drm_client.h| 10 +
  include/drm/drm_gem.h   |  3 ++
  5 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 9403b3f576f7b..2cc81831236b5 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -304,6 +304,66 @@ drm_client_buffer_create(struct drm_client_dev *client, 
u32 width, u32 height,
return ERR_PTR(ret);
  }
  
+/**

+ * drm_client_buffer_vmap_local - Map DRM client buffer into address space
+ * @buffer: DRM client buffer
+ * @map_copy: Returns the mapped memory's address
+ *
+ * This function maps a client buffer into kernel address space. If the
+ * buffer is already mapped, it returns the existing mapping's address.
+ *
+ * Client buffer mappings are not ref'counted. Each call to
+ * drm_client_buffer_vmap_local() should be closely followed by a call to
+ * drm_client_buffer_vunmap_local(). See drm_client_buffer_vmap() for
+ * long-term mappings.
+ *
+ * The returned address is a copy of the internal value. In contrast to
+ * other vmap interfaces, you don't need it for the client's vunmap
+ * function. So you can modify it at will during blit and draw operations.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer,
+struct iosys_map *map_copy)
+{
+   struct drm_gem_object *gem = buffer->gem;
+   struct iosys_map *map = &buffer->map;
+   int ret;
+
+   drm_gem_lock(gem);
+
+   ret = drm_gem_vmap(gem, map);
+   if (ret)
+   goto err_drm_gem_vmap_unlocked;
+   *map_copy = *map;
+
+   return 0;
+
+err_drm_gem_vmap_unlocked:
+   drm_gem_unlock(gem);
+   return 0;
+}
+EXPORT_SYMBOL(drm_client_buffer_vmap_local);
+
+/**
+ * drm_client_buffer_vunmap_local - Unmap DRM client buffer
+ * @buffer: DRM client buffer
+ *
+ * This function removes a client buffer's memory mapping established
+ * with drm_client_buffer_vunmap_local(). Calling this function is only
+ * required by clients that manage their buffer mappings by themselves.
+ */
+void drm_client_buffer_vunmap_local(struct drm_client_buffer *buffer)
+{
+   struct drm_gem_object *gem = buffer->gem;
+   struct iosys_map *map = &buffer->map;
+
+   drm_gem_vunmap(gem, map);
+   drm_gem_unlock(gem);
+}
+EXPORT_SYMBOL(drm_client_buffer_vunmap_local);
+
  /**
   * drm_client_buffer_vmap - Map DRM client buffer into address space
   * @buffer: DRM client buffer
@@ -331,14 +391,6 @@ drm_client_buffer_vmap(struct drm_client_buffer *buffer,
struct iosys_map *map = &buffer->map;
int ret;
  
-	/*

-* FIXME: The dependency on GEM here isn't required, we could
-* convert the driver handle to a dma-buf instead and use the
-* backend-agnostic dma-buf vmap support instead. This would
-* require that the handle2fd prime ioctl is reworked to pull the
-* fd_install step out of the driver backend hooks, to make that
-* final step optional for internal users.
-*/
ret = drm_gem_vmap_unlocked(buffer->gem, map);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index d647d89764cb9..be357f926faec 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_generic.c
@@ -197,14 +197,14 @@ static int drm_fbdev_generic_damage_blit(struct 
drm_fb_helper *fb_helper,
 */
mutex_lock(&fb_helper->lock);
  
-	ret = drm_client_buffer_vmap(buffer, &map);

+   ret = drm_client_buffer_vmap_local(buffer, &map);
if (ret)
goto out;
  
  	dst = map;


Then, please remove the local variable 'dst' (struct iosys_map) at here.
As you said, the ret

Re: [PATCH v4 00/10] Make PCI's devres API more consistent

2024-03-11 Thread Bjorn Helgaas
On Mon, Mar 11, 2024 at 12:45:15PM +0100, Philipp Stanner wrote:
> Gentle ping because the Merge Window opened 8-)

Thanks; I'll look at this for v6.10.  It's too late to add significant
changes for the v6.9 merge window since it's already open.

Bjorn

> On Fri, 2024-03-01 at 12:29 +0100, Philipp Stanner wrote:
> > This v4 now can (hopefully) be applied to linux-next, but not to
> > mainline/master.
> > 
> > Changes in v4:
> >   - Rebase against linux-next
> > 
> > Changes in v3:
> >   - Use the term "PCI devres API" at some forgotten places.
> >   - Fix more grammar errors in patch #3.
> >   - Remove the comment advising to call (the outdated) pcim_intx() in
> > pci.c
> >   - Rename __pcim_request_region_range() flags-field "exclusive" to
> >     "req_flags", since this is what the int actually represents.
> >   - Remove the call to pcim_region_request() from patch #10. (Hans)
> > 
> > Changes in v2:
> >   - Make commit head lines congruent with PCI's style (Bjorn)
> >   - Add missing error checks for devm_add_action(). (Andy)
> >   - Repair the "Returns: " marks for docu generation (Andy)
> >   - Initialize the addr_devres struct with memset(). (Andy)
> >   - Make pcim_intx() a PCI-internal function so that new drivers
> > won't
> >     be encouraged to use the outdated pci_intx() mechanism.
> >     (Andy / Philipp)
> >   - Fix grammar and spelling (Bjorn)
> >   - Be more precise on why pcim_iomap_table() is problematic (Bjorn)
> >   - Provide the actual structs' and functions' names in the commit
> >     messages (Bjorn)
> >   - Remove redundant variable initializers (Andy)
> >   - Regroup PM bitfield members in struct pci_dev (Andy)
> >   - Make pcim_intx() visible only for the PCI subsystem so that
> > new    
> >     drivers won't use this outdated API (Andy, Myself)
> >   - Add a NOTE to pcim_iomap() to warn about this function being
> > the    onee
> >     xception that does just return NULL.
> >   - Consistently use the term "PCI devres API"; also in Patch #10
> > (Bjorn)
> > 
> > 
> > ¡Hola!
> > 
> > PCI's devres API suffers several weaknesses:
> > 
> > 1. There are functions prefixed with pcim_. Those are always managed
> >    counterparts to never-managed functions prefixed with pci_ – or so
> > one
> >    would like to think. There are some apparently unmanaged functions
> >    (all region-request / release functions, and pci_intx()) which
> >    suddenly become managed once the user has initialized the device
> > with
> >    pcim_enable_device() instead of pci_enable_device(). This
> > "sometimes
> >    yes, sometimes no" nature of those functions is confusing and
> >    therefore bug-provoking. In fact, it has already caused a bug in
> > DRM.
> >    The last patch in this series fixes that bug.
> > 2. iomappings: Instead of giving each mapping its own callback, the
> >    existing API uses a statically allocated struct tracking one
> > mapping
> >    per bar. This is not extensible. Especially, you can't create
> >    _ranged_ managed mappings that way, which many drivers want.
> > 3. Managed request functions only exist as "plural versions" with a
> >    bit-mask as a parameter. That's quite over-engineered considering
> >    that each user only ever mapps one, maybe two bars.
> > 
> > This series:
> > - add a set of new "singular" devres functions that use devres the
> > way
> >   its intended, with one callback per resource.
> > - deprecates the existing iomap-table mechanism.
> > - deprecates the hybrid nature of pci_ functions.
> > - preserves backwards compatibility so that drivers using the
> > existing
> >   API won't notice any changes.
> > - adds documentation, especially some warning users about the
> >   complicated nature of PCI's devres.
> > 
> > 
> > Note that this series is based on my "unify pci_iounmap"-series from
> > a
> > few weeks ago. [1]
> > 
> > I tested this on a x86 VM with a simple pci test-device with two
> > regions. Operates and reserves resources as intended on my system.
> > Kasan and kmemleak didn't find any problems.
> > 
> > I believe this series cleans the API up as much as possible without
> > having to port all existing drivers to the new API. Especially, I
> > think
> > that this implementation is easy to extend if the need for new
> > managed
> > functions arises :)
> > 
> > Greetings,
> > P.
> > 
> > Philipp Stanner (10):
> >   PCI: Add new set of devres functions
> >   PCI: Deprecate iomap-table functions
> >   PCI: Warn users about complicated devres nature
> >   PCI: Make devres region requests consistent
> >   PCI: Move dev-enabled status bit to struct pci_dev
> >   PCI: Move pinned status bit to struct pci_dev
> >   PCI: Give pcim_set_mwi() its own devres callback
> >   PCI: Give pci(m)_intx its own devres callback
> >   PCI: Remove legacy pcim_release()
> >   drm/vboxvideo: fix mapping leaks
> > 
> >  drivers/gpu/drm/vboxvideo/vbox_main.c |   20 +-
> >  drivers/pci/devres.c  | 1013 +--
> > --
> >  drivers/pc

Re: [09/13] drm/gem: Acquire reservation lock in drm_gem_{pin/unpin}()

2024-03-11 Thread Sui Jingfeng

Hi,


On 2024/2/27 18:14, Thomas Zimmermann wrote:

Acquire the buffer object's reservation lock in drm_gem_pin() and
remove locking the drivers' GEM callbacks where necessary. Same for
unpin().

DRM drivers and memory managers modified by this patch will now have
correct dma-buf locking semantics: the caller is responsible for
holding the reservation lock when calling the pin or unpin callback.

DRM drivers and memory managers that are not modified will now be
protected against concurent invocation of their pin and unpin callbacks.


'concurent' -> 'concurrent'


PRIME does not implement struct dma_buf_ops.pin, which requires
the caller to hold the reservation lock. It does implement struct
dma_buf_ops.attach, which requires to callee to acquire the
reservation lock.


which requires 'the' callee to acquire the reservation lock.



The PRIME code uses drm_gem_pin(), so locks
are now taken as specified. Same for unpin and detach.

The patch harmonizes GEM pin and unpin to have non-interruptible
reservation locking across all drivers, as is already the case for
vmap and vunmap. This affects gem-shmem, gem-vram, loongson, qxl and
radeon.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Zack Rusin 



Tested with drm/loongson, play with a few days.
Switch to virtual terminal, then switch back is fine.
not found problems yet. So,

Tested-by: Sui Jingfeng 



Re: [PATCH 10/12] drm/imx: ldb: switch to imx_legacy_bridge / drm_bridge_connector

2024-03-11 Thread kernel test robot
Hi Dmitry,

kernel test robot noticed the following build errors:

[auto build test ERROR on 1843e16d2df9d98427ef8045589571749d627cf7]

url:
https://github.com/intel-lab-lkp/linux/commits/Dmitry-Baryshkov/dt-bindings-display-fsl-imx-drm-drop-edid-property-support/20240311-192356
base:   1843e16d2df9d98427ef8045589571749d627cf7
patch link:
https://lore.kernel.org/r/20240311-drm-imx-cleanup-v1-10-e104f05caa51%40linaro.org
patch subject: [PATCH 10/12] drm/imx: ldb: switch to imx_legacy_bridge / 
drm_bridge_connector
config: sparc-allmodconfig 
(https://download.01.org/0day-ci/archive/20240312/202403120545.cbwfr4su-...@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240312/202403120545.cbwfr4su-...@intel.com/reproduce)

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

All errors (new ones prefixed by >>, old ones prefixed by <<):

WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mtd/maps/map_funcs.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
drivers/spmi/hisi-spmi-controller.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/spmi/spmi-pmic-arb.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_cif.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_aec.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_netx.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_pruss.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_mf624.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/pcmcia/pcmcia_rsrc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/pcmcia/yenta_socket.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/pcmcia/i82092.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hwmon/corsair-cpro.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hwmon/mr75203.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/vhost/vringh.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/greybus/greybus.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/greybus/gb-es2.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rpmsg/rpmsg_char.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/iio/adc/ingenic-adc.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/iio/adc/xilinx-ams.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/iio/buffer/kfifo_buf.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-master-hub.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
drivers/fsi/fsi-master-aspeed.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-master-gpio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
drivers/fsi/fsi-master-ast-cf.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/fsi/fsi-scom.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/siox/siox-bus-gpio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/counter/ftm-quaddec.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/core/snd-pcm-dmaengine.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/core/sound_kunit.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/drivers/snd-pcmtest.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/pci/hda/snd-hda-cirrus-scodec-test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/soc/soc-topology-test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/codecs/snd-soc-ab8500-codec.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/codecs/snd-soc-sigmadsp.o
WARNING: modpost: sound/soc/codecs/snd-soc-tlv320adc3xxx: section mismatch in 
reference: adc3xxx_i2c_driver+0x10 (section: .data) -> adc3xxx_i2c_remove 
(section: .exit.text)
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/codecs/snd-soc-wm-adsp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in sound/soc/fsl/imx-pcm-dma.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/intel/avs/boards/snd-soc-avs-da7219.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/intel/avs/boards/snd-soc-avs-dmic.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/intel/avs/boards/snd-soc-avs-i2s-test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/intel/avs/boards/snd-soc-avs-max98927.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/intel/avs/boards/snd-soc-avs-max98357a.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/intel/avs/boards/snd-soc-avs-max98373.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
sound/soc/intel/avs/boards/snd-so

[PATCH v2] drm/i915/hwmon: Fix locking inversion in sysfs getter

2024-03-11 Thread Janusz Krzysztofik
In i915 hwmon sysfs getter path we now take a hwmon_lock, then acquire an
rpm wakeref.  That results in lock inversion:

<4> [197.079335] ==
<4> [197.085473] WARNING: possible circular locking dependency detected
<4> [197.091611] 6.8.0-rc7-Patchwork_129026v7-gc4dc92fb1152+ #1 Not tainted
<4> [197.098096] --
<4> [197.104231] prometheus-node/839 is trying to acquire lock:
<4> [197.109680] 82764d80 (fs_reclaim){+.+.}-{0:0}, at: 
__kmalloc+0x9a/0x350
<4> [197.116939]
but task is already holding lock:
<4> [197.122730] 88811b772a40 (&hwmon->hwmon_lock){+.+.}-{3:3}, at: 
hwm_energy+0x4b/0x100 [i915]
<4> [197.131543]
which lock already depends on the new lock.
...
<4> [197.507922] Chain exists of:
  fs_reclaim --> >->reset.mutex --> &hwmon->hwmon_lock
<4> [197.518528]  Possible unsafe locking scenario:
<4> [197.524411]CPU0CPU1
<4> [197.528916]
<4> [197.533418]   lock(&hwmon->hwmon_lock);
<4> [197.537237]lock(>->reset.mutex);
<4> [197.543376]lock(&hwmon->hwmon_lock);
<4> [197.549682]   lock(fs_reclaim);
...
<4> [197.632548] Call Trace:
<4> [197.634990]  
<4> [197.637088]  dump_stack_lvl+0x64/0xb0
<4> [197.640738]  check_noncircular+0x15e/0x180
<4> [197.652968]  check_prev_add+0xe9/0xce0
<4> [197.656705]  __lock_acquire+0x179f/0x2300
<4> [197.660694]  lock_acquire+0xd8/0x2d0
<4> [197.673009]  fs_reclaim_acquire+0xa1/0xd0
<4> [197.680478]  __kmalloc+0x9a/0x350
<4> [197.689063]  acpi_ns_internalize_name.part.0+0x4a/0xb0
<4> [197.694170]  acpi_ns_get_node_unlocked+0x60/0xf0
<4> [197.720608]  acpi_ns_get_node+0x3b/0x60
<4> [197.724428]  acpi_get_handle+0x57/0xb0
<4> [197.728164]  acpi_has_method+0x20/0x50
<4> [197.731896]  acpi_pci_set_power_state+0x43/0x120
<4> [197.736485]  pci_power_up+0x24/0x1c0
<4> [197.740047]  pci_pm_default_resume_early+0x9/0x30
<4> [197.744725]  pci_pm_runtime_resume+0x2d/0x90
<4> [197.753911]  __rpm_callback+0x3c/0x110
<4> [197.762586]  rpm_callback+0x58/0x70
<4> [197.766064]  rpm_resume+0x51e/0x730
<4> [197.769542]  rpm_resume+0x267/0x730
<4> [197.773020]  rpm_resume+0x267/0x730
<4> [197.776498]  rpm_resume+0x267/0x730
<4> [197.779974]  __pm_runtime_resume+0x49/0x90
<4> [197.784055]  __intel_runtime_pm_get+0x19/0xa0 [i915]
<4> [197.789070]  hwm_energy+0x55/0x100 [i915]
<4> [197.793183]  hwm_read+0x9a/0x310 [i915]
<4> [197.797124]  hwmon_attr_show+0x36/0x120
<4> [197.800946]  dev_attr_show+0x15/0x60
<4> [197.804509]  sysfs_kf_seq_show+0xb5/0x100

Acquire the wakeref before the lock and hold it as long as the lock is
also held.  Follow that pattern across the whole source file where similar
lock inversion can happen.

v2: Keep hardware read under the lock so the whole operation of updating
energy from hardware is still atomic (Guenter),
  - instead, acquire the rpm wakeref before the lock and hold it as long
as the lock is held,
  - use the same aproach for other similar places across the i915_hwmon.c
source file (Rodrigo).

Fixes: c41b8bdcc297 ("drm/i915/hwmon: Show device level energy usage")
Signed-off-by: Janusz Krzysztofik 
Cc: Rodrigo Vivi 
Cc: Guenter Roeck 
Cc:  # v6.2+
---
 drivers/gpu/drm/i915/i915_hwmon.c | 37 ---
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_hwmon.c 
b/drivers/gpu/drm/i915/i915_hwmon.c
index 8c3f443c8347e..b758fd110c204 100644
--- a/drivers/gpu/drm/i915/i915_hwmon.c
+++ b/drivers/gpu/drm/i915/i915_hwmon.c
@@ -72,12 +72,13 @@ hwm_locked_with_pm_intel_uncore_rmw(struct hwm_drvdata 
*ddat,
struct intel_uncore *uncore = ddat->uncore;
intel_wakeref_t wakeref;
 
-   mutex_lock(&hwmon->hwmon_lock);
+   with_intel_runtime_pm(uncore->rpm, wakeref) {
+   mutex_lock(&hwmon->hwmon_lock);
 
-   with_intel_runtime_pm(uncore->rpm, wakeref)
intel_uncore_rmw(uncore, reg, clear, set);
 
-   mutex_unlock(&hwmon->hwmon_lock);
+   mutex_unlock(&hwmon->hwmon_lock);
+   }
 }
 
 /*
@@ -136,20 +137,21 @@ hwm_energy(struct hwm_drvdata *ddat, long *energy)
else
rgaddr = hwmon->rg.energy_status_all;
 
-   mutex_lock(&hwmon->hwmon_lock);
+   with_intel_runtime_pm(uncore->rpm, wakeref) {
+   mutex_lock(&hwmon->hwmon_lock);
 
-   with_intel_runtime_pm(uncore->rpm, wakeref)
reg_val = intel_uncore_read(uncore, rgaddr);
 
-   if (reg_val >= ei->reg_val_prev)
-   ei->accum_energy += reg_val - ei->reg_val_prev;
-   else
-   ei->accum_energy += UINT_MAX - ei->reg_val_prev + reg_val;
-   ei->reg_val_prev = reg_val;
+   if (reg_val >= ei->reg_val_prev)
+   ei->accum_energy += reg_val - ei->reg_val_prev;
+   else
+   ei->accum_energy += UINT_MAX -

Re: [PATCH] drm: Don't return unsupported formats in drm_mode_legacy_fb_format

2024-03-11 Thread Frej Drejhammar
Hi Thomas,

Thanks for the review and suggestions. My experience with the drm parts
of the kernel is limited to some weekends trying to fix the regression,
so I'm afraid I have some questions to check my understanding before
making a v2 of the patch.

Thomas Zimmermann  writes:

> I suggest to switch all fbdev code over to drm_driver_legacy_fb_format
> ()
> first and then modify the format indrm_driver_legacy_fb_format
> ()
> after reading it from drm_fb_legacy_fb_format().

I see how doing the format massaging in drm_driver_legacy_fb_format()
would fix the original regression (starting with the format returned by
drm_mode_legacy_fb_format(), drm_fb_legacy_fb_format() is a typo,
right?). As drm_driver_legacy_fb_format() has only two callers,
drm_mode_addfb() and __drm_fb_helper_find_sizes() that change is
probably less likely to do something unintended. As far as I can tell,
drm_driver_legacy_fb_format() is only used when userland hasn't
specified a format or the kernel is initializing and have no format
information. For these code paths it's clear that only formats which are
actually supported by the hardware are meaningful.

What I can't really see is what "switch all fbdev code over to
drm_driver_legacy_fb_format" would entail and what the benefit would
be. How do I determine when drm_mode_legacy_fb_format() should be
replaced with drm_driver_legacy_fb_format()? I have already mistakenly
considered the change to drm_mode_legacy_fb_format() as harmless and
broken ofdrm... Shouldn't it be enough to make
drm_driver_legacy_fb_format() select a format which is supported by the
driver?

Best regards,

Frej




Re: [PATCH 0/5] drm/i915: cleanup dead code

2024-03-11 Thread Lucas De Marchi

On Mon, Mar 11, 2024 at 05:43:00PM +, Tvrtko Ursulin wrote:


On 06/03/2024 19:36, Lucas De Marchi wrote:

Remove platforms that never had their PCI IDs added to the driver and
are of course marked with requiring force_probe. Note that most of the
code for those platforms is actually used by subsequent ones, so it's
not a huge amount of code being removed.


I had PVC and xehpsdv back in October but could not collect all acks. :(

Last two patches from https://patchwork.freedesktop.org/series/124705/.


oh... I was actually surprised we still had xehpsdv while removing a
WA for PVC, which made me look into removing these platforms.

rebasing your series and comparing yours..my-v2, where my-v2 only has
patches 2 and 4, I have the diff below. I think it's small enough that I
can just take your commits and squash delta. Is that ok to you?

my version is a little bit more aggressive, also doing some renames
s/xehpsdv/xehp/ and dropping some more code
(engine_mask_apply_copy_fuses(), unused registers, default ctx, fw
ranges).

diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h
index 8a8fcd4fceac..bc26dc126104 100644
--- a/Documentation/gpu/rfc/i915_vm_bind.h
+++ b/Documentation/gpu/rfc/i915_vm_bind.h
@@ -93,12 +93,11 @@ struct drm_i915_gem_timeline_fence {
  * Multiple VA mappings can be created to the same section of the 
object
  * (aliasing).
  *
- * The @start, @offset and @length must be 4K page aligned. However 
the DG2
- * and XEHPSDV has 64K page size for device local memory and has 
compact page
- * table. On those platforms, for binding device local-memory objects, 
the
- * @start, @offset and @length must be 64K aligned. Also, UMDs should 
not mix
- * the local memory 64K page and the system memory 4K page bindings in 
the same
- * 2M range.
+ * The @start, @offset and @length must be 4K page aligned. However 
the DG2 has
+ * 64K page size for device local memory and has compact page table. 
On that
+ * platform, for binding device local-memory objects, the @start, 
@offset and
+ * @length must be 64K aligned. Also, UMDs should not mix the local 
memory 64K
+ * page and the system memory 4K page bindings in the same 2M range.
  *
  * Error code -EINVAL will be returned if @start, @offset and @length 
are not
  * properly aligned. In version 1 (See I915_PARAM_VM_BIND_VERSION), 
error code
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 1495b6074492..d3300ae3053f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -386,7 +386,7 @@ struct drm_i915_gem_object {
 * and kernel mode driver for caching policy control after 
GEN12.
 * In the meantime platform specific tables are created to 
translate
 * i915_cache_level into pat index, for more details check the 
macros
-* defined i915/i915_pci.c, e.g. TGL_CACHELEVEL.
+* defined i915/i915_pci.c, e.g. MTL_CACHELEVEL.
 * For backward compatibility, this field contains values 
exactly match
 * the entries of enum i915_cache_level for pre-GEN12 platforms 
(See
 * LEGACY_CACHELEVEL), so that the PTE encode functions for 
these
diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c 
b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
index fa46d2308b0e..1bd0e041e15c 100644
--- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
@@ -500,11 +500,11 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
 }
	 
	 static void

-xehpsdv_ppgtt_insert_huge(struct i915_address_space *vm,
- struct i915_vma_resource *vma_res,
- struct sgt_dma *iter,
- unsigned int pat_index,
- u32 flags)
+xehp_ppgtt_insert_huge(struct i915_address_space *vm,
+  struct i915_vma_resource *vma_res,
+  struct sgt_dma *iter,
+  unsigned int pat_index,
+  u32 flags)
 {
const gen8_pte_t pte_encode = vm->pte_encode(0, pat_index, 
flags);
unsigned int rem = sg_dma_len(iter->sg);
@@ -741,8 +741,8 @@ static void gen8_ppgtt_insert(struct 
i915_address_space *vm,
struct sgt_dma iter = sgt_dma(vma_res);
	 
		if (vma_res->bi.page_sizes.sg > I915_GTT_PAGE_SIZE) {

-   if (GRAPHICS_VER_FULL(vm->i915) >= IP_VER(12, 50))
-   xehpsdv_ppgtt_insert_huge(vm, vma_res, &iter, 
pat_ind

Re: [PATCH] drm/i915/hwmon: Fix locking inversion in sysfs getter

2024-03-11 Thread Rodrigo Vivi
On Mon, Mar 11, 2024 at 07:14:09PM +0100, Janusz Krzysztofik wrote:
> On Monday, 11 March 2024 18:35:43 CET Guenter Roeck wrote:
> > On 3/11/24 09:58, Rodrigo Vivi wrote:
> > > On Mon, Mar 11, 2024 at 09:06:46AM +0100, Janusz Krzysztofik wrote:
> > >> In i915 hwmon sysfs getter path we now take a hwmon_lock, then acquire an
> > >> rpm wakeref.  That results in lock inversion:
> > >>
> > >> <4> [197.079335] ==
> > >> <4> [197.085473] WARNING: possible circular locking dependency detected
> > >> <4> [197.091611] 6.8.0-rc7-Patchwork_129026v7-gc4dc92fb1152+ #1 Not 
> > >> tainted
> > >> <4> [197.098096] --
> > >> <4> [197.104231] prometheus-node/839 is trying to acquire lock:
> > >> <4> [197.109680] 82764d80 (fs_reclaim){+.+.}-{0:0}, at: 
> > >> __kmalloc+0x9a/0x350
> > >> <4> [197.116939]
> > >> but task is already holding lock:
> > >> <4> [197.122730] 88811b772a40 (&hwmon->hwmon_lock){+.+.}-{3:3}, at: 
> > >> hwm_energy+0x4b/0x100 [i915]
> > >> <4> [197.131543]
> > >> which lock already depends on the new lock.
> > >> ...
> > >> <4> [197.507922] Chain exists of:
> > >>fs_reclaim --> >->reset.mutex --> &hwmon->hwmon_lock
> > >> <4> [197.518528]  Possible unsafe locking scenario:
> > >> <4> [197.524411]CPU0CPU1
> > >> <4> [197.528916]
> > >> <4> [197.533418]   lock(&hwmon->hwmon_lock);
> > >> <4> [197.537237]lock(>->reset.mutex);
> > >> <4> [197.543376]lock(&hwmon->hwmon_lock);
> > >> <4> [197.549682]   lock(fs_reclaim);
> > >> ...
> > >> <4> [197.632548] Call Trace:
> > >> <4> [197.634990]  
> > >> <4> [197.637088]  dump_stack_lvl+0x64/0xb0
> > >> <4> [197.640738]  check_noncircular+0x15e/0x180
> > >> <4> [197.652968]  check_prev_add+0xe9/0xce0
> > >> <4> [197.656705]  __lock_acquire+0x179f/0x2300
> > >> <4> [197.660694]  lock_acquire+0xd8/0x2d0
> > >> <4> [197.673009]  fs_reclaim_acquire+0xa1/0xd0
> > >> <4> [197.680478]  __kmalloc+0x9a/0x350
> > >> <4> [197.689063]  acpi_ns_internalize_name.part.0+0x4a/0xb0
> > >> <4> [197.694170]  acpi_ns_get_node_unlocked+0x60/0xf0
> > >> <4> [197.720608]  acpi_ns_get_node+0x3b/0x60
> > >> <4> [197.724428]  acpi_get_handle+0x57/0xb0
> > >> <4> [197.728164]  acpi_has_method+0x20/0x50
> > >> <4> [197.731896]  acpi_pci_set_power_state+0x43/0x120
> > >> <4> [197.736485]  pci_power_up+0x24/0x1c0
> > >> <4> [197.740047]  pci_pm_default_resume_early+0x9/0x30
> > >> <4> [197.744725]  pci_pm_runtime_resume+0x2d/0x90
> > >> <4> [197.753911]  __rpm_callback+0x3c/0x110
> > >> <4> [197.762586]  rpm_callback+0x58/0x70
> > >> <4> [197.766064]  rpm_resume+0x51e/0x730
> > >> <4> [197.769542]  rpm_resume+0x267/0x730
> > >> <4> [197.773020]  rpm_resume+0x267/0x730
> > >> <4> [197.776498]  rpm_resume+0x267/0x730
> > >> <4> [197.779974]  __pm_runtime_resume+0x49/0x90
> > >> <4> [197.784055]  __intel_runtime_pm_get+0x19/0xa0 [i915]
> > >> <4> [197.789070]  hwm_energy+0x55/0x100 [i915]
> > >> <4> [197.793183]  hwm_read+0x9a/0x310 [i915]
> > >> <4> [197.797124]  hwmon_attr_show+0x36/0x120
> > >> <4> [197.800946]  dev_attr_show+0x15/0x60
> > >> <4> [197.804509]  sysfs_kf_seq_show+0xb5/0x100
> > >>
> > >> However, the lock is only intended to protect either a hwmon overflow
> > >> counter or rmw hardware operations.  There is no need to hold the lock,
> > >> only the wakeref, while reading from hardware.
> > >>
> > >> Acquire the lock after hardware read under rpm wakeref.
> > >>
> > >> Fixes: c41b8bdcc297 ("drm/i915/hwmon: Show device level energy usage")
> > >> Signed-off-by: Janusz Krzysztofik 
> > >> Cc:  # v6.2+
> > >> ---
> > >>   drivers/gpu/drm/i915/i915_hwmon.c | 4 ++--
> > >>   1 file changed, 2 insertions(+), 2 deletions(-)
> > >>
> > >> diff --git a/drivers/gpu/drm/i915/i915_hwmon.c 
> > >> b/drivers/gpu/drm/i915/i915_hwmon.c
> > >> index 8c3f443c8347e..faf7670de6e06 100644
> > >> --- a/drivers/gpu/drm/i915/i915_hwmon.c
> > >> +++ b/drivers/gpu/drm/i915/i915_hwmon.c
> > >> @@ -136,11 +136,11 @@ hwm_energy(struct hwm_drvdata *ddat, long *energy)
> > >>  else
> > >>  rgaddr = hwmon->rg.energy_status_all;
> > >>   
> > >> -mutex_lock(&hwmon->hwmon_lock);
> > >> -
> > >>  with_intel_runtime_pm(uncore->rpm, wakeref)
> > >>  reg_val = intel_uncore_read(uncore, rgaddr);
> > >>   
> > >> +mutex_lock(&hwmon->hwmon_lock);
> > >> +
> > > 
> > > This is not enough.
> > > check hwm_locked_with_pm_intel_uncore_rmw()
> > > 
> > > It looks like we need to rethink this lock entirely here.
> > > 
> > 
> > I would have assumed that the lock was supposed to ensure that
> > reading the register value and the subsequent update of accum_energy
> > and reg_val_prev was synchronized. This is no longer the case
> > after this patch has been applied. Given that, I would agree that
> > it would make sense t

Re: [PATCH] drm/i915/hwmon: Fix locking inversion in sysfs getter

2024-03-11 Thread Janusz Krzysztofik
On Monday, 11 March 2024 18:35:43 CET Guenter Roeck wrote:
> On 3/11/24 09:58, Rodrigo Vivi wrote:
> > On Mon, Mar 11, 2024 at 09:06:46AM +0100, Janusz Krzysztofik wrote:
> >> In i915 hwmon sysfs getter path we now take a hwmon_lock, then acquire an
> >> rpm wakeref.  That results in lock inversion:
> >>
> >> <4> [197.079335] ==
> >> <4> [197.085473] WARNING: possible circular locking dependency detected
> >> <4> [197.091611] 6.8.0-rc7-Patchwork_129026v7-gc4dc92fb1152+ #1 Not tainted
> >> <4> [197.098096] --
> >> <4> [197.104231] prometheus-node/839 is trying to acquire lock:
> >> <4> [197.109680] 82764d80 (fs_reclaim){+.+.}-{0:0}, at: 
> >> __kmalloc+0x9a/0x350
> >> <4> [197.116939]
> >> but task is already holding lock:
> >> <4> [197.122730] 88811b772a40 (&hwmon->hwmon_lock){+.+.}-{3:3}, at: 
> >> hwm_energy+0x4b/0x100 [i915]
> >> <4> [197.131543]
> >> which lock already depends on the new lock.
> >> ...
> >> <4> [197.507922] Chain exists of:
> >>fs_reclaim --> >->reset.mutex --> &hwmon->hwmon_lock
> >> <4> [197.518528]  Possible unsafe locking scenario:
> >> <4> [197.524411]CPU0CPU1
> >> <4> [197.528916]
> >> <4> [197.533418]   lock(&hwmon->hwmon_lock);
> >> <4> [197.537237]lock(>->reset.mutex);
> >> <4> [197.543376]lock(&hwmon->hwmon_lock);
> >> <4> [197.549682]   lock(fs_reclaim);
> >> ...
> >> <4> [197.632548] Call Trace:
> >> <4> [197.634990]  
> >> <4> [197.637088]  dump_stack_lvl+0x64/0xb0
> >> <4> [197.640738]  check_noncircular+0x15e/0x180
> >> <4> [197.652968]  check_prev_add+0xe9/0xce0
> >> <4> [197.656705]  __lock_acquire+0x179f/0x2300
> >> <4> [197.660694]  lock_acquire+0xd8/0x2d0
> >> <4> [197.673009]  fs_reclaim_acquire+0xa1/0xd0
> >> <4> [197.680478]  __kmalloc+0x9a/0x350
> >> <4> [197.689063]  acpi_ns_internalize_name.part.0+0x4a/0xb0
> >> <4> [197.694170]  acpi_ns_get_node_unlocked+0x60/0xf0
> >> <4> [197.720608]  acpi_ns_get_node+0x3b/0x60
> >> <4> [197.724428]  acpi_get_handle+0x57/0xb0
> >> <4> [197.728164]  acpi_has_method+0x20/0x50
> >> <4> [197.731896]  acpi_pci_set_power_state+0x43/0x120
> >> <4> [197.736485]  pci_power_up+0x24/0x1c0
> >> <4> [197.740047]  pci_pm_default_resume_early+0x9/0x30
> >> <4> [197.744725]  pci_pm_runtime_resume+0x2d/0x90
> >> <4> [197.753911]  __rpm_callback+0x3c/0x110
> >> <4> [197.762586]  rpm_callback+0x58/0x70
> >> <4> [197.766064]  rpm_resume+0x51e/0x730
> >> <4> [197.769542]  rpm_resume+0x267/0x730
> >> <4> [197.773020]  rpm_resume+0x267/0x730
> >> <4> [197.776498]  rpm_resume+0x267/0x730
> >> <4> [197.779974]  __pm_runtime_resume+0x49/0x90
> >> <4> [197.784055]  __intel_runtime_pm_get+0x19/0xa0 [i915]
> >> <4> [197.789070]  hwm_energy+0x55/0x100 [i915]
> >> <4> [197.793183]  hwm_read+0x9a/0x310 [i915]
> >> <4> [197.797124]  hwmon_attr_show+0x36/0x120
> >> <4> [197.800946]  dev_attr_show+0x15/0x60
> >> <4> [197.804509]  sysfs_kf_seq_show+0xb5/0x100
> >>
> >> However, the lock is only intended to protect either a hwmon overflow
> >> counter or rmw hardware operations.  There is no need to hold the lock,
> >> only the wakeref, while reading from hardware.
> >>
> >> Acquire the lock after hardware read under rpm wakeref.
> >>
> >> Fixes: c41b8bdcc297 ("drm/i915/hwmon: Show device level energy usage")
> >> Signed-off-by: Janusz Krzysztofik 
> >> Cc:  # v6.2+
> >> ---
> >>   drivers/gpu/drm/i915/i915_hwmon.c | 4 ++--
> >>   1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_hwmon.c 
> >> b/drivers/gpu/drm/i915/i915_hwmon.c
> >> index 8c3f443c8347e..faf7670de6e06 100644
> >> --- a/drivers/gpu/drm/i915/i915_hwmon.c
> >> +++ b/drivers/gpu/drm/i915/i915_hwmon.c
> >> @@ -136,11 +136,11 @@ hwm_energy(struct hwm_drvdata *ddat, long *energy)
> >>else
> >>rgaddr = hwmon->rg.energy_status_all;
> >>   
> >> -  mutex_lock(&hwmon->hwmon_lock);
> >> -
> >>with_intel_runtime_pm(uncore->rpm, wakeref)
> >>reg_val = intel_uncore_read(uncore, rgaddr);
> >>   
> >> +  mutex_lock(&hwmon->hwmon_lock);
> >> +
> > 
> > This is not enough.
> > check hwm_locked_with_pm_intel_uncore_rmw()
> > 
> > It looks like we need to rethink this lock entirely here.
> > 
> 
> I would have assumed that the lock was supposed to ensure that
> reading the register value and the subsequent update of accum_energy
> and reg_val_prev was synchronized. This is no longer the case
> after this patch has been applied. Given that, I would agree that
> it would make sense to define what the lock is supposed to protect
> before changing its scope.

Right.  In that case, I propose to take the wakeref before the lock, and keep 
it while the lock is held around the calculations.  Would that be acceptable 
as a quick fix?  If yes then I can take the same approach to also fix other 
places i

Re: [PATCH] drm/msm/dp: move link_ready out of HPD event thread

2024-03-11 Thread Kuogee Hsieh



On 3/8/2024 1:45 PM, Abhinav Kumar wrote:

There are cases where the userspace might still send another
frame after the HPD disconnect causing a modeset cycle after
a disconnect. This messes the internal state machine of MSM DP driver
and can lead to a crash as there can be an imbalance between
bridge_disable() and bridge_enable().

This was also previously reported on [1] for which [2] was posted
and helped resolve the issue by rejecting commits if the DP is not
in connected state.

The change resolved the bug but there can also be another race condition.
If hpd_event_thread does not pick up the EV_USER_NOTIFICATION and process it
link_ready will also not be set to false allowing the frame to sneak in.

Lets move setting link_ready outside of hpd_event_thread() processing to
eliminate a window of race condition.

[1] : https://gitlab.freedesktop.org/drm/msm/-/issues/17
[2] : 
https://lore.kernel.org/all/1664408211-25314-1-git-send-email-quic_khs...@quicinc.com/

Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and 
disable")
Signed-off-by: Abhinav Kumar 

Tested-by: Kuogee Hsieh 

Reviewed-by: Kuogee Hsieh
---
  drivers/gpu/drm/msm/dp/dp_display.c | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 068d44eeaa07..e00092904ccc 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -345,8 +345,6 @@ static int dp_display_send_hpd_notification(struct 
dp_display_private *dp,
 
dp->panel->downstream_ports);
}
  
-	dp->dp_display.link_ready = hpd;

-
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
dp->dp_display.connector_type, hpd);
drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready);
@@ -399,6 +397,8 @@ static int dp_display_process_hpd_high(struct 
dp_display_private *dp)
goto end;
}
  
+	dp->dp_display.link_ready = true;

+
dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);
  
  end:

@@ -466,6 +466,8 @@ static int dp_display_notify_disconnect(struct device *dev)
  {
struct dp_display_private *dp = dev_get_dp_display_private(dev);
  
+	dp->dp_display.link_ready = false;

+
dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
  
  	return 0;

@@ -487,6 +489,7 @@ static int dp_display_handle_port_status_changed(struct 
dp_display_private *dp)
drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
if (dp->hpd_state != ST_DISCONNECTED) {
dp->hpd_state = ST_DISCONNECT_PENDING;
+   dp->dp_display.link_ready = false;
dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
}
} else {


Re: [PATCH v2] drm/amdgpu: add ring buffer information in devcoredump

2024-03-11 Thread Christian König

Am 11.03.24 um 16:11 schrieb Sunil Khatri:

Add relevant ringbuffer information such as
rptr, wptr,rb mask, ring name, ring size and also
the rings content for each ring on a gpu reset.

Signed-off-by: Sunil Khatri 


I think printing the mask still might be useful, but that's just a nit pick.

With or without it the patch is Reviewed-by: Christian König 



Regards,
Christian.


---
  drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 21 +
  1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
index 6d059f853adc..a0dbccad2f53 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
@@ -215,6 +215,27 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, 
size_t count,
   fault_info->status);
}
  
+	drm_printf(&p, "Ring buffer information\n");

+   for (int i = 0; i < coredump->adev->num_rings; i++) {
+   int j = 0;
+   struct amdgpu_ring *ring = coredump->adev->rings[i];
+
+   drm_printf(&p, "ring name: %s\n", ring->name);
+   drm_printf(&p, "Rptr: 0x%llx Wptr: 0x%llx RB mask: %x\n",
+  amdgpu_ring_get_rptr(ring),
+  amdgpu_ring_get_wptr(ring),
+  ring->buf_mask);
+   drm_printf(&p, "Ring size in dwords: %d\n",
+  ring->ring_size / 4);
+   drm_printf(&p, "Ring contents\n");
+   drm_printf(&p, "Offset \t Value\n");
+
+   while (j < ring->ring_size) {
+   drm_printf(&p, "0x%x \t 0x%x\n", j, ring->ring[j/4]);
+   j += 4;
+   }
+   }
+
if (coredump->reset_vram_lost)
drm_printf(&p, "VRAM is lost due to GPU reset!\n");
if (coredump->adev->reset_info.num_regs) {




Re: [PATCH v2 28/28] fbdev/p9100: Drop now unused driver p9100

2024-03-11 Thread Sam Ravnborg
Hi Arnd.

On Mon, Mar 11, 2024 at 03:05:25PM +0100, Arnd Bergmann wrote:
> On Sat, Mar 9, 2024, at 19:15, Sam Ravnborg via B4 Relay wrote:
> > From: Sam Ravnborg 
> >
> > The p9100 driver is only relevant for the Sparcbook 3 machine,
> > and with sun4m support removed this driver is no longer relevant.
> >
> > Signed-off-by: Sam Ravnborg 
> > Acked-by: Arnd Bergmann 
> > Acked-by: Thomas Zimmermann 
> > Cc: "David S. Miller" 
> > Cc: Arnd Bergmann 
> > Cc: Andreas Larsson 
> > Cc: Helge Deller 
> > ---
> >  drivers/video/fbdev/Kconfig  |   8 -
> >  drivers/video/fbdev/Makefile |   1 -
> >  drivers/video/fbdev/p9100.c  | 372 
> > ---
> >  3 files changed, 381 deletions(-)
> 
> I tried to figure out if there are other drivers in the same
> category and found the list at
> https://everything2.com/title/Sun+graphics+cards
> 
> As far as I can tell, the only SBUS graphics that were
> shipped on sparc64 are FB_FFB and FB_CG6, so we could
> go further and remove BW2, CG3, TCX, CG14 and LEO as
> well.

Looks like you are right, so we can drop more - good.
As you already wrote - let's get the current patch set processed first.

I did a quick hack on top of my current sparc32 patches.
This is nice reduction of ~2700 lines and 5 fbdev drivers less to care
about.

Sam


Re: [PATCH 0/5] drm/i915: cleanup dead code

2024-03-11 Thread Tvrtko Ursulin



On 06/03/2024 19:36, Lucas De Marchi wrote:

Remove platforms that never had their PCI IDs added to the driver and
are of course marked with requiring force_probe. Note that most of the
code for those platforms is actually used by subsequent ones, so it's
not a huge amount of code being removed.


I had PVC and xehpsdv back in October but could not collect all acks. :(

Last two patches from https://patchwork.freedesktop.org/series/124705/.

Regards,

Tvrtko


drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h is also changed on the
xe side, but that should be ok: the defines are there only for compat
reasons while building the display side (and none of these platforms
have display, so it's build-issue only).

First patch is what motivated the others and was submitted alone
@ 20240306144723.1826977-1-lucas.demar...@intel.com .
While loooking at this WA I was wondering why we still had some of that
code around.

Build-tested only for now.

Lucas De Marchi (5):
   drm/i915: Drop WA 16015675438
   drm/i915: Drop dead code for xehpsdv
   drm/i915: Update IP_VER(12, 50)
   drm/i915: Drop dead code for pvc
   drm/i915: Remove special handling for !RCS_MASK()

  Documentation/gpu/rfc/i915_vm_bind.h  |  11 +-
  .../gpu/drm/i915/gem/i915_gem_object_types.h  |   2 +-
  .../gpu/drm/i915/gem/selftests/huge_pages.c   |   4 +-
  .../i915/gem/selftests/i915_gem_client_blt.c  |   8 +-
  drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |   5 +-
  drivers/gpu/drm/i915/gt/gen8_ppgtt.c  |  40 ++--
  drivers/gpu/drm/i915/gt/intel_engine_cs.c |  43 +---
  .../drm/i915/gt/intel_execlists_submission.c  |  10 +-
  drivers/gpu/drm/i915/gt/intel_gsc.c   |  15 --
  drivers/gpu/drm/i915/gt/intel_gt.c|   4 +-
  drivers/gpu/drm/i915/gt/intel_gt_mcr.c|  52 +
  drivers/gpu/drm/i915/gt/intel_gt_mcr.h|   2 +-
  drivers/gpu/drm/i915/gt/intel_gt_regs.h   |  59 --
  drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c   |  21 +-
  drivers/gpu/drm/i915/gt/intel_gtt.c   |   2 +-
  drivers/gpu/drm/i915/gt/intel_lrc.c   |  51 +
  drivers/gpu/drm/i915/gt/intel_migrate.c   |  22 +-
  drivers/gpu/drm/i915/gt/intel_mocs.c  |  52 +
  drivers/gpu/drm/i915/gt/intel_rps.c   |   6 +-
  drivers/gpu/drm/i915/gt/intel_sseu.c  |  13 +-
  drivers/gpu/drm/i915/gt/intel_workarounds.c   | 193 +-
  drivers/gpu/drm/i915/gt/uc/intel_guc.c|   6 +-
  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|   4 +-
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |   2 +-
  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |   1 -
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c |   2 +-
  drivers/gpu/drm/i915/gt/uc/intel_uc.c |   4 -
  drivers/gpu/drm/i915/i915_debugfs.c   |  12 --
  drivers/gpu/drm/i915/i915_drv.h   |  13 --
  drivers/gpu/drm/i915/i915_getparam.c  |   4 +-
  drivers/gpu/drm/i915/i915_gpu_error.c |   5 +-
  drivers/gpu/drm/i915/i915_hwmon.c |   6 -
  drivers/gpu/drm/i915/i915_pci.c   |  61 +-
  drivers/gpu/drm/i915/i915_perf.c  |  19 +-
  drivers/gpu/drm/i915/i915_query.c |   2 +-
  drivers/gpu/drm/i915/i915_reg.h   |   4 +-
  drivers/gpu/drm/i915/intel_clock_gating.c |  26 +--
  drivers/gpu/drm/i915/intel_device_info.c  |   2 -
  drivers/gpu/drm/i915/intel_device_info.h  |   2 -
  drivers/gpu/drm/i915/intel_step.c |  80 +---
  drivers/gpu/drm/i915/intel_uncore.c   | 159 +--
  drivers/gpu/drm/i915/selftests/intel_uncore.c |   3 -
  .../gpu/drm/xe/compat-i915-headers/i915_drv.h |   6 -
  43 files changed, 110 insertions(+), 928 deletions(-)



Re: [PATCH 02/12] dt-bindings: display: imx/ldb: drop ddc-i2c-bus property

2024-03-11 Thread Rob Herring


On Mon, 11 Mar 2024 13:20:10 +0200, Dmitry Baryshkov wrote:
> The in-kernel DT files do not use ddc-i2c-bus property with the iMX LVDS
> Display Bridge. If in future a need arises to support such usecase, the
> panel-simple should be used, which is able to handle the DDC bus.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  Documentation/devicetree/bindings/display/imx/ldb.txt | 1 -
>  1 file changed, 1 deletion(-)
> 

Acked-by: Rob Herring 



Re: [PATCH 01/12] dt-bindings: display: fsl-imx-drm: drop edid property support

2024-03-11 Thread Rob Herring


On Mon, 11 Mar 2024 13:20:09 +0200, Dmitry Baryshkov wrote:
> None of the in-kernel DT files ever used edid override with the
> fsl-imx-drm driver. In case the EDID needs to be specified manually, DRM
> core allows one to either override it via the debugfs or to load it via
> request_firmware by using DRM_LOAD_EDID_FIRMWARE. In all other cases
> EDID and/or modes are to be provided as a part of the panel driver.
> 
> Drop the edid property from the fsl-imx-drm bindings.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt | 2 --
>  1 file changed, 2 deletions(-)
> 

Acked-by: Rob Herring 



Re: [PATCH] drm/i915/hwmon: Fix locking inversion in sysfs getter

2024-03-11 Thread Guenter Roeck

On 3/11/24 09:58, Rodrigo Vivi wrote:

On Mon, Mar 11, 2024 at 09:06:46AM +0100, Janusz Krzysztofik wrote:

In i915 hwmon sysfs getter path we now take a hwmon_lock, then acquire an
rpm wakeref.  That results in lock inversion:

<4> [197.079335] ==
<4> [197.085473] WARNING: possible circular locking dependency detected
<4> [197.091611] 6.8.0-rc7-Patchwork_129026v7-gc4dc92fb1152+ #1 Not tainted
<4> [197.098096] --
<4> [197.104231] prometheus-node/839 is trying to acquire lock:
<4> [197.109680] 82764d80 (fs_reclaim){+.+.}-{0:0}, at: 
__kmalloc+0x9a/0x350
<4> [197.116939]
but task is already holding lock:
<4> [197.122730] 88811b772a40 (&hwmon->hwmon_lock){+.+.}-{3:3}, at: 
hwm_energy+0x4b/0x100 [i915]
<4> [197.131543]
which lock already depends on the new lock.
...
<4> [197.507922] Chain exists of:
   fs_reclaim --> >->reset.mutex --> &hwmon->hwmon_lock
<4> [197.518528]  Possible unsafe locking scenario:
<4> [197.524411]CPU0CPU1
<4> [197.528916]
<4> [197.533418]   lock(&hwmon->hwmon_lock);
<4> [197.537237]lock(>->reset.mutex);
<4> [197.543376]lock(&hwmon->hwmon_lock);
<4> [197.549682]   lock(fs_reclaim);
...
<4> [197.632548] Call Trace:
<4> [197.634990]  
<4> [197.637088]  dump_stack_lvl+0x64/0xb0
<4> [197.640738]  check_noncircular+0x15e/0x180
<4> [197.652968]  check_prev_add+0xe9/0xce0
<4> [197.656705]  __lock_acquire+0x179f/0x2300
<4> [197.660694]  lock_acquire+0xd8/0x2d0
<4> [197.673009]  fs_reclaim_acquire+0xa1/0xd0
<4> [197.680478]  __kmalloc+0x9a/0x350
<4> [197.689063]  acpi_ns_internalize_name.part.0+0x4a/0xb0
<4> [197.694170]  acpi_ns_get_node_unlocked+0x60/0xf0
<4> [197.720608]  acpi_ns_get_node+0x3b/0x60
<4> [197.724428]  acpi_get_handle+0x57/0xb0
<4> [197.728164]  acpi_has_method+0x20/0x50
<4> [197.731896]  acpi_pci_set_power_state+0x43/0x120
<4> [197.736485]  pci_power_up+0x24/0x1c0
<4> [197.740047]  pci_pm_default_resume_early+0x9/0x30
<4> [197.744725]  pci_pm_runtime_resume+0x2d/0x90
<4> [197.753911]  __rpm_callback+0x3c/0x110
<4> [197.762586]  rpm_callback+0x58/0x70
<4> [197.766064]  rpm_resume+0x51e/0x730
<4> [197.769542]  rpm_resume+0x267/0x730
<4> [197.773020]  rpm_resume+0x267/0x730
<4> [197.776498]  rpm_resume+0x267/0x730
<4> [197.779974]  __pm_runtime_resume+0x49/0x90
<4> [197.784055]  __intel_runtime_pm_get+0x19/0xa0 [i915]
<4> [197.789070]  hwm_energy+0x55/0x100 [i915]
<4> [197.793183]  hwm_read+0x9a/0x310 [i915]
<4> [197.797124]  hwmon_attr_show+0x36/0x120
<4> [197.800946]  dev_attr_show+0x15/0x60
<4> [197.804509]  sysfs_kf_seq_show+0xb5/0x100

However, the lock is only intended to protect either a hwmon overflow
counter or rmw hardware operations.  There is no need to hold the lock,
only the wakeref, while reading from hardware.

Acquire the lock after hardware read under rpm wakeref.

Fixes: c41b8bdcc297 ("drm/i915/hwmon: Show device level energy usage")
Signed-off-by: Janusz Krzysztofik 
Cc:  # v6.2+
---
  drivers/gpu/drm/i915/i915_hwmon.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_hwmon.c 
b/drivers/gpu/drm/i915/i915_hwmon.c
index 8c3f443c8347e..faf7670de6e06 100644
--- a/drivers/gpu/drm/i915/i915_hwmon.c
+++ b/drivers/gpu/drm/i915/i915_hwmon.c
@@ -136,11 +136,11 @@ hwm_energy(struct hwm_drvdata *ddat, long *energy)
else
rgaddr = hwmon->rg.energy_status_all;
  
-	mutex_lock(&hwmon->hwmon_lock);

-
with_intel_runtime_pm(uncore->rpm, wakeref)
reg_val = intel_uncore_read(uncore, rgaddr);
  
+	mutex_lock(&hwmon->hwmon_lock);

+


This is not enough.
check hwm_locked_with_pm_intel_uncore_rmw()

It looks like we need to rethink this lock entirely here.



I would have assumed that the lock was supposed to ensure that
reading the register value and the subsequent update of accum_energy
and reg_val_prev was synchronized. This is no longer the case
after this patch has been applied. Given that, I would agree that
it would make sense to define what the lock is supposed to protect
before changing its scope.

Guenter



[PATCH v3 14/28] sparc32: Drop unused mmu models

2024-03-11 Thread Sam Ravnborg
Drop mmu models not used by LEON, including their header files.
This includes removal of unused includes in various files to fix the
build.

With this change SHMLBA is always PAGE_SIZE so use the
asm-generic variant of shmparam.h for sparc32.
__ARCH_FORCE_SHMLBA is then no longer defined, but
this should be OK if my analysis is correct.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---

Posted v3 here to avoid resending the whole series.
In v3 the asm-generic shmparam.h are introduced and a few
unused variables (reported by kernel test robot) was dropped.

Sam


 arch/sparc/include/asm/mxcc.h| 138 -
 arch/sparc/include/asm/ross.h| 192 ---
 arch/sparc/include/asm/shmparam.h|   2 +-
 arch/sparc/include/asm/shmparam_32.h |  10 -
 arch/sparc/include/asm/swift.h   | 107 
 arch/sparc/include/asm/tsunami.h |  65 ---
 arch/sparc/include/asm/turbosparc.h  | 126 -
 arch/sparc/include/asm/viking.h  | 255 -
 arch/sparc/kernel/entry.S|   1 -
 arch/sparc/mm/Makefile   |   1 -
 arch/sparc/mm/hypersparc.S   | 414 --
 arch/sparc/mm/io-unit.c  |   1 -
 arch/sparc/mm/iommu.c|  31 +-
 arch/sparc/mm/mm_32.h|   1 -
 arch/sparc/mm/srmmu.c| 780 +--
 arch/sparc/mm/swift.S| 256 -
 arch/sparc/mm/tsunami.S  | 132 -
 arch/sparc/mm/viking.S   | 284 --
 18 files changed, 22 insertions(+), 2774 deletions(-)
 delete mode 100644 arch/sparc/include/asm/mxcc.h
 delete mode 100644 arch/sparc/include/asm/ross.h
 delete mode 100644 arch/sparc/include/asm/shmparam_32.h
 delete mode 100644 arch/sparc/include/asm/swift.h
 delete mode 100644 arch/sparc/include/asm/tsunami.h
 delete mode 100644 arch/sparc/include/asm/turbosparc.h
 delete mode 100644 arch/sparc/include/asm/viking.h
 delete mode 100644 arch/sparc/mm/hypersparc.S
 delete mode 100644 arch/sparc/mm/swift.S
 delete mode 100644 arch/sparc/mm/tsunami.S
 delete mode 100644 arch/sparc/mm/viking.S

diff --git a/arch/sparc/include/asm/mxcc.h b/arch/sparc/include/asm/mxcc.h
deleted file mode 100644
index 3a2561bea4dd..
--- a/arch/sparc/include/asm/mxcc.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * mxcc.h:  Definitions of the Viking MXCC registers
- *
- * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_MXCC_H
-#define _SPARC_MXCC_H
-
-/* These registers are accessed through ASI 0x2. */
-#define MXCC_DATSTREAM   0x1C0  /* Data stream register */
-#define MXCC_SRCSTREAM   0x1C00100  /* Source stream register */
-#define MXCC_DESSTREAM   0x1C00200  /* Destination stream register */
-#define MXCC_RMCOUNT 0x1C00300  /* Count of references and misses */
-#define MXCC_STEST   0x1C00804  /* Internal self-test */
-#define MXCC_CREG0x1C00A04  /* Control register */
-#define MXCC_SREG0x1C00B00  /* Status register */
-#define MXCC_RREG0x1C00C04  /* Reset register */
-#define MXCC_EREG0x1C00E00  /* Error code register */
-#define MXCC_PREG0x1C00F04  /* Address port register */
-
-/* Some MXCC constants. */
-#define MXCC_STREAM_SIZE 0x20   /* Size in bytes of one stream r/w */
-
-/* The MXCC Control Register:
- *
- * --
- * |   | RRC | RSV |PRE|MCE|PARE|ECE|RSV|
- * --
- *  31  1098-6   5   43   2  1-0
- *
- * RRC: Controls what you read from MXCC_RMCOUNT reg.
- *  0=Misses 1=References
- * PRE: Prefetch enable
- * MCE: Multiple Command Enable
- * PARE: Parity enable
- * ECE: External cache enable
- */
-
-#define MXCC_CTL_RRC   0x0200
-#define MXCC_CTL_PRE   0x0020
-#define MXCC_CTL_MCE   0x0010
-#define MXCC_CTL_PARE  0x0008
-#define MXCC_CTL_ECE   0x0004
-
-/* The MXCC Error Register:
- *
- * 
- * |ME| RSV|CE|PEW|PEE|ASE|EIV| MOPC|ECODE|PRIV|RSV|HPADDR|
- * 
- *  31   30 29  28  27  26  25 24-15  14-7   6  5-3   2-0
- *
- * ME: Multiple Errors have occurred
- * CE: Cache consistency Error
- * PEW: Parity Error during a Write operation
- * PEE: Parity Error involving the External cache
- * ASE: ASynchronous Error
- * EIV: This register is toast
- * MOPC: MXCC Operation Code for instance causing error
- * ECODE: The Error CODE
- * PRIV: A privileged mode error? 0=no 1=yes
- * HPADDR: High PhysicalADDRess bits (35-32)
- */
-
-#define MXCC_ERR_ME 0x8000
-#define MXCC_ERR_CE 0x2000
-#define MXCC_ERR_PEW0x1000
-#define MXCC_ERR_PEE0x0800
-#define MXCC_ERR_ASE0x0400

Re: [PATCH RFC v2 5/5] drm/msm/hdmi: make use of the drm_connector_hdmi framework

2024-03-11 Thread Dmitry Baryshkov
On Mon, 11 Mar 2024 at 19:06, Maxime Ripard  wrote:
>
> On Mon, Mar 11, 2024 at 05:55:36PM +0200, Dmitry Baryshkov wrote:
> > On Mon, 11 Mar 2024 at 17:46, Maxime Ripard  wrote:
> > >
> > > Hi,
> > >
> > > On Sat, Mar 09, 2024 at 12:31:32PM +0200, Dmitry Baryshkov wrote:
> > > > Setup the HDMI connector on the MSM HDMI outputs. Make use of
> > > > atomic_check hook and of the provided Infoframe infrastructure.
> > > >
> > > > Note: for now only AVI Infoframes are enabled. Audio Infoframes are
> > > > currenly handled separately. This will be fixed for the final version.
> > > >
> > > > Signed-off-by: Dmitry Baryshkov 
> > >
> > > I had a look at the driver, and it looks like mode_set and mode_valid
> > > could use the connector_state tmds_char_rate instead of pixclock and
> > > drm_connector_hdmi_compute_mode_clock respectively instead of
> > > calculating it by themselves.
> >
> > Ack, I'll take a look.b
> >
> > >
> > > We can probably remove hdmi->pixclock entirely if we manage to pass the
> > > connector state to msm_hdmi_power_on.
> >
> > I'd like to defer this for a moment, I have a pending series moving
> > MSM HDMI PHY drivers to generic PHY subsystem. However that patchset
> > reworks the way the PHY is setup, so it doesn't make sense to rework
> > msm_hdmi_power_on().
> >
> > >
> > > And that's unrelated to this series, but we can also remove
> > > hdmi->hdmi_mode for drm_display_info.is_hdmi.
> >
> > Yes, that's the plan, once I rework the audio infoframe handling.
>
> Sure, if it makes more sense to defer it for now, then let's postpone it
> :)

I hope to fix this one for v3. Audio InfoFrame should be converted too.

-- 
With best wishes
Dmitry


Re: [PATCH RFC v2 5/5] drm/msm/hdmi: make use of the drm_connector_hdmi framework

2024-03-11 Thread Maxime Ripard
On Mon, Mar 11, 2024 at 05:55:36PM +0200, Dmitry Baryshkov wrote:
> On Mon, 11 Mar 2024 at 17:46, Maxime Ripard  wrote:
> >
> > Hi,
> >
> > On Sat, Mar 09, 2024 at 12:31:32PM +0200, Dmitry Baryshkov wrote:
> > > Setup the HDMI connector on the MSM HDMI outputs. Make use of
> > > atomic_check hook and of the provided Infoframe infrastructure.
> > >
> > > Note: for now only AVI Infoframes are enabled. Audio Infoframes are
> > > currenly handled separately. This will be fixed for the final version.
> > >
> > > Signed-off-by: Dmitry Baryshkov 
> >
> > I had a look at the driver, and it looks like mode_set and mode_valid
> > could use the connector_state tmds_char_rate instead of pixclock and
> > drm_connector_hdmi_compute_mode_clock respectively instead of
> > calculating it by themselves.
> 
> Ack, I'll take a look.b
> 
> >
> > We can probably remove hdmi->pixclock entirely if we manage to pass the
> > connector state to msm_hdmi_power_on.
> 
> I'd like to defer this for a moment, I have a pending series moving
> MSM HDMI PHY drivers to generic PHY subsystem. However that patchset
> reworks the way the PHY is setup, so it doesn't make sense to rework
> msm_hdmi_power_on().
> 
> >
> > And that's unrelated to this series, but we can also remove
> > hdmi->hdmi_mode for drm_display_info.is_hdmi.
> 
> Yes, that's the plan, once I rework the audio infoframe handling.

Sure, if it makes more sense to defer it for now, then let's postpone it
:)

Maxime


signature.asc
Description: PGP signature


[PATCH 3/3] accel/qaic: Add fifo queued debugfs

2024-03-11 Thread Jeffrey Hugo
When debugging functional issues with workload input processing, it is
useful to know if requests are backing up in the fifo, or perhaps
getting stuck elsewhere. To answer the question of how many requests are
in the fifo, implement a "queued" debugfs entry per-dbc that returns the
number of pending requests when read.

Signed-off-by: Jeffrey Hugo 
Reviewed-by: Carl Vanderlip 
Reviewed-by: Pranjal Ramajor Asha Kanojiya 
---
 drivers/accel/qaic/qaic.h |  1 +
 drivers/accel/qaic/qaic_data.c|  9 +
 drivers/accel/qaic/qaic_debugfs.c | 31 +++
 3 files changed, 41 insertions(+)

diff --git a/drivers/accel/qaic/qaic.h b/drivers/accel/qaic/qaic.h
index 03d9c9fbffb3..02561b6cecc6 100644
--- a/drivers/accel/qaic/qaic.h
+++ b/drivers/accel/qaic/qaic.h
@@ -288,6 +288,7 @@ int disable_dbc(struct qaic_device *qdev, u32 dbc_id, 
struct qaic_user *usr);
 void enable_dbc(struct qaic_device *qdev, u32 dbc_id, struct qaic_user *usr);
 void wakeup_dbc(struct qaic_device *qdev, u32 dbc_id);
 void release_dbc(struct qaic_device *qdev, u32 dbc_id);
+void qaic_data_get_fifo_info(struct dma_bridge_chan *dbc, u32 *head, u32 
*tail);
 
 void wake_all_cntl(struct qaic_device *qdev);
 void qaic_dev_reset_clean_local_state(struct qaic_device *qdev);
diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c
index 2459fe4a3f95..e86e71c1cdd8 100644
--- a/drivers/accel/qaic/qaic_data.c
+++ b/drivers/accel/qaic/qaic_data.c
@@ -1981,3 +1981,12 @@ void release_dbc(struct qaic_device *qdev, u32 dbc_id)
dbc->in_use = false;
wake_up(&dbc->dbc_release);
 }
+
+void qaic_data_get_fifo_info(struct dma_bridge_chan *dbc, u32 *head, u32 *tail)
+{
+   if (!dbc || !head || !tail)
+   return;
+
+   *head = readl(dbc->dbc_base + REQHP_OFF);
+   *tail = readl(dbc->dbc_base + REQTP_OFF);
+}
diff --git a/drivers/accel/qaic/qaic_debugfs.c 
b/drivers/accel/qaic/qaic_debugfs.c
index 9d56cd451b64..12a65b98701d 100644
--- a/drivers/accel/qaic/qaic_debugfs.c
+++ b/drivers/accel/qaic/qaic_debugfs.c
@@ -97,6 +97,36 @@ static const struct file_operations fifo_size_fops = {
.release = single_release,
 };
 
+static int read_dbc_queued(struct seq_file *s, void *unused)
+{
+   struct dma_bridge_chan *dbc = s->private;
+   u32 tail = 0, head = 0;
+
+   qaic_data_get_fifo_info(dbc, &head, &tail);
+
+   if (head == U32_MAX || tail == U32_MAX)
+   seq_printf(s, "%u\n", 0);
+   else if (head > tail)
+   seq_printf(s, "%u\n", dbc->nelem - head + tail);
+   else
+   seq_printf(s, "%u\n", tail - head);
+
+   return 0;
+}
+
+static int queued_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, read_dbc_queued, inode->i_private);
+}
+
+static const struct file_operations queued_fops = {
+   .owner = THIS_MODULE,
+   .open = queued_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+};
+
 void qaic_debugfs_init(struct qaic_drm_device *qddev)
 {
struct qaic_device *qdev = qddev->qdev;
@@ -112,6 +142,7 @@ void qaic_debugfs_init(struct qaic_drm_device *qddev)
snprintf(name, QAIC_DBC_DIR_NAME, "dbc%03u", i);
debugfs_dir = debugfs_create_dir(name, debugfs_root);
debugfs_create_file("fifo_size", 0400, debugfs_dir, 
&qdev->dbc[i], &fifo_size_fops);
+   debugfs_create_file("queued", 0400, debugfs_dir, &qdev->dbc[i], 
&queued_fops);
}
 }
 
-- 
2.34.1



[PATCH 1/3] accel/qaic: Add bootlog debugfs

2024-03-11 Thread Jeffrey Hugo
During the boot process of AIC100, the bootloaders (PBL and SBL) log
messages to device RAM. During SBL, if the host opens the QAIC_LOGGING
channel, SBL will offload the contents of the log buffer to the host,
and stream any new messages that SBL logs.

This log of the boot process can be very useful for an initial triage of
any boot related issues. For example, if SBL rejects one of the runtime
firmware images for a validation failure, SBL will log a reason why.

Add the ability of the driver to open the logging channel, receive the
messages, and store them. Also define a debugfs entry called "bootlog"
by hooking into the DRM debugfs framework. When the bootlog debugfs
entry is read, the current contents of the log that the host is caching
is displayed to the user. The driver will retain the cache until it
detects that the device has rebooted.  At that point, the cache will be
freed, and the driver will wait for a new log. With this scheme, the
driver will only have a cache of the log from the current device boot.
Note that if the driver initializes a device and it is already in the
runtime state (QSM), no bootlog will be available through this mechanism
because the driver and SBL have not communicated.

Signed-off-by: Jeffrey Hugo 
Reviewed-by: Carl Vanderlip 
Reviewed-by: Pranjal Ramajor Asha Kanojiya 
---
 drivers/accel/qaic/Makefile   |   2 +
 drivers/accel/qaic/qaic.h |   8 +
 drivers/accel/qaic/qaic_debugfs.c | 271 ++
 drivers/accel/qaic/qaic_debugfs.h |  20 +++
 drivers/accel/qaic/qaic_drv.c |  16 +-
 5 files changed, 316 insertions(+), 1 deletion(-)
 create mode 100644 drivers/accel/qaic/qaic_debugfs.c
 create mode 100644 drivers/accel/qaic/qaic_debugfs.h

diff --git a/drivers/accel/qaic/Makefile b/drivers/accel/qaic/Makefile
index 3f7f6dfde7f2..2cadcc1baa0e 100644
--- a/drivers/accel/qaic/Makefile
+++ b/drivers/accel/qaic/Makefile
@@ -11,3 +11,5 @@ qaic-y := \
qaic_data.o \
qaic_drv.o \
qaic_timesync.o
+
+qaic-$(CONFIG_DEBUG_FS) += qaic_debugfs.o
diff --git a/drivers/accel/qaic/qaic.h b/drivers/accel/qaic/qaic.h
index 9256653b3036..03d9c9fbffb3 100644
--- a/drivers/accel/qaic/qaic.h
+++ b/drivers/accel/qaic/qaic.h
@@ -153,6 +153,14 @@ struct qaic_device {
struct mhi_device   *qts_ch;
/* Work queue for tasks related to MHI "QAIC_TIMESYNC" channel */
struct workqueue_struct *qts_wq;
+   /* Head of list of page allocated by MHI bootlog device */
+   struct list_headbootlog;
+   /* MHI bootlog channel device */
+   struct mhi_device   *bootlog_ch;
+   /* Work queue for tasks related to MHI bootlog device */
+   struct workqueue_struct *bootlog_wq;
+   /* Synchronizes access of pages in MHI bootlog device */
+   struct mutexbootlog_mutex;
 };
 
 struct qaic_drm_device {
diff --git a/drivers/accel/qaic/qaic_debugfs.c 
b/drivers/accel/qaic/qaic_debugfs.c
new file mode 100644
index ..4f87fe29be1a
--- /dev/null
+++ b/drivers/accel/qaic/qaic_debugfs.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
+/* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights 
reserved. */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qaic.h"
+#include "qaic_debugfs.h"
+
+#define BOOTLOG_POOL_SIZE  16
+#define BOOTLOG_MSG_SIZE   512
+
+struct bootlog_msg {
+   /* Buffer for bootlog messages */
+   char str[BOOTLOG_MSG_SIZE];
+   /* Root struct of device, used to access device resources */
+   struct qaic_device *qdev;
+   /* Work struct to schedule work coming on QAIC_LOGGING channel */
+   struct work_struct work;
+};
+
+struct bootlog_page {
+   /* Node in list of bootlog pages maintained by root device struct */
+   struct list_head node;
+   /* Total size of the buffer that holds the bootlogs. It is PAGE_SIZE */
+   unsigned int size;
+   /* Offset for the next bootlog */
+   unsigned int offset;
+};
+
+static int bootlog_show(struct seq_file *s, void *unused)
+{
+   struct bootlog_page *page;
+   struct qaic_device *qdev;
+   void *page_end;
+   void *log;
+
+   qdev = s->private;
+   mutex_lock(&qdev->bootlog_mutex);
+   list_for_each_entry(page, &qdev->bootlog, node) {
+   log = page + 1;
+   page_end = (void *)page + page->offset;
+   while (log < page_end) {
+   seq_printf(s, "%s", (char *)log);
+   log += strlen(log) + 1;
+   }
+   }
+   mutex_unlock(&qdev->bootlog_mutex);
+
+   return 0;
+}
+
+static int bootlog_fops_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, bootlog_show, inode->i_private);
+}
+
+static const struct file_operations boot

[PATCH 2/3] accel/qaic: Add fifo size debugfs

2024-03-11 Thread Jeffrey Hugo
Each DMA Bridge Channel (dbc) has a unique configured fifo size which is
specified by the userspace client of that dbc. Since the fifo is
circular, it is useful to know the configured size when debugging
issues.

Add a per-dbc subdirectory in debugfs and in each subdirectory add a
fifo_size entry that will display the size of that dbc's fifo when read.

Signed-off-by: Jeffrey Hugo 
Reviewed-by: Carl Vanderlip 
Reviewed-by: Pranjal Ramajor Asha Kanojiya 
---
 drivers/accel/qaic/qaic_debugfs.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/accel/qaic/qaic_debugfs.c 
b/drivers/accel/qaic/qaic_debugfs.c
index 4f87fe29be1a..9d56cd451b64 100644
--- a/drivers/accel/qaic/qaic_debugfs.c
+++ b/drivers/accel/qaic/qaic_debugfs.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -20,6 +21,7 @@
 
 #define BOOTLOG_POOL_SIZE  16
 #define BOOTLOG_MSG_SIZE   512
+#define QAIC_DBC_DIR_NAME  9
 
 struct bootlog_msg {
/* Buffer for bootlog messages */
@@ -74,14 +76,43 @@ static const struct file_operations bootlog_fops = {
.release = single_release,
 };
 
+static int read_dbc_fifo_size(struct seq_file *s, void *unused)
+{
+   struct dma_bridge_chan *dbc = s->private;
+
+   seq_printf(s, "%u\n", dbc->nelem);
+   return 0;
+}
+
+static int fifo_size_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, read_dbc_fifo_size, inode->i_private);
+}
+
+static const struct file_operations fifo_size_fops = {
+   .owner = THIS_MODULE,
+   .open = fifo_size_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+};
+
 void qaic_debugfs_init(struct qaic_drm_device *qddev)
 {
struct qaic_device *qdev = qddev->qdev;
struct dentry *debugfs_root;
+   struct dentry *debugfs_dir;
+   char name[QAIC_DBC_DIR_NAME];
+   u32 i;
 
debugfs_root = to_drm(qddev)->debugfs_root;
 
debugfs_create_file("bootlog", 0400, debugfs_root, qdev, &bootlog_fops);
+   for (i = 0; i < qdev->num_dbc; ++i) {
+   snprintf(name, QAIC_DBC_DIR_NAME, "dbc%03u", i);
+   debugfs_dir = debugfs_create_dir(name, debugfs_root);
+   debugfs_create_file("fifo_size", 0400, debugfs_dir, 
&qdev->dbc[i], &fifo_size_fops);
+   }
 }
 
 static struct bootlog_page *alloc_bootlog_page(struct qaic_device *qdev)
-- 
2.34.1



[PATCH 0/3] accel/qaic: Add debugfs entries

2024-03-11 Thread Jeffrey Hugo
Add 3 debugfs entries that can be useful in debugging a variety of
issues.

bootlog - output the device bootloader log

fifo_size - output the configured dbc fifo size

queued - output how many requests are queued in the dbc fifo

Bootlog is unique to the device, where as fifo_size/queued is per-dbc.

Jeffrey Hugo (3):
  accel/qaic: Add bootlog debugfs
  accel/qaic: Add fifo size debugfs
  accel/qaic: Add fifo queued debugfs

 drivers/accel/qaic/Makefile   |   2 +
 drivers/accel/qaic/qaic.h |   9 +
 drivers/accel/qaic/qaic_data.c|   9 +
 drivers/accel/qaic/qaic_debugfs.c | 333 ++
 drivers/accel/qaic/qaic_debugfs.h |  20 ++
 drivers/accel/qaic/qaic_drv.c |  16 +-
 6 files changed, 388 insertions(+), 1 deletion(-)
 create mode 100644 drivers/accel/qaic/qaic_debugfs.c
 create mode 100644 drivers/accel/qaic/qaic_debugfs.h

-- 
2.34.1



Re: [PATCH] drm/i915/hwmon: Fix locking inversion in sysfs getter

2024-03-11 Thread Rodrigo Vivi
On Mon, Mar 11, 2024 at 09:06:46AM +0100, Janusz Krzysztofik wrote:
> In i915 hwmon sysfs getter path we now take a hwmon_lock, then acquire an
> rpm wakeref.  That results in lock inversion:
> 
> <4> [197.079335] ==
> <4> [197.085473] WARNING: possible circular locking dependency detected
> <4> [197.091611] 6.8.0-rc7-Patchwork_129026v7-gc4dc92fb1152+ #1 Not tainted
> <4> [197.098096] --
> <4> [197.104231] prometheus-node/839 is trying to acquire lock:
> <4> [197.109680] 82764d80 (fs_reclaim){+.+.}-{0:0}, at: 
> __kmalloc+0x9a/0x350
> <4> [197.116939]
> but task is already holding lock:
> <4> [197.122730] 88811b772a40 (&hwmon->hwmon_lock){+.+.}-{3:3}, at: 
> hwm_energy+0x4b/0x100 [i915]
> <4> [197.131543]
> which lock already depends on the new lock.
> ...
> <4> [197.507922] Chain exists of:
>   fs_reclaim --> >->reset.mutex --> &hwmon->hwmon_lock
> <4> [197.518528]  Possible unsafe locking scenario:
> <4> [197.524411]CPU0CPU1
> <4> [197.528916]
> <4> [197.533418]   lock(&hwmon->hwmon_lock);
> <4> [197.537237]lock(>->reset.mutex);
> <4> [197.543376]lock(&hwmon->hwmon_lock);
> <4> [197.549682]   lock(fs_reclaim);
> ...
> <4> [197.632548] Call Trace:
> <4> [197.634990]  
> <4> [197.637088]  dump_stack_lvl+0x64/0xb0
> <4> [197.640738]  check_noncircular+0x15e/0x180
> <4> [197.652968]  check_prev_add+0xe9/0xce0
> <4> [197.656705]  __lock_acquire+0x179f/0x2300
> <4> [197.660694]  lock_acquire+0xd8/0x2d0
> <4> [197.673009]  fs_reclaim_acquire+0xa1/0xd0
> <4> [197.680478]  __kmalloc+0x9a/0x350
> <4> [197.689063]  acpi_ns_internalize_name.part.0+0x4a/0xb0
> <4> [197.694170]  acpi_ns_get_node_unlocked+0x60/0xf0
> <4> [197.720608]  acpi_ns_get_node+0x3b/0x60
> <4> [197.724428]  acpi_get_handle+0x57/0xb0
> <4> [197.728164]  acpi_has_method+0x20/0x50
> <4> [197.731896]  acpi_pci_set_power_state+0x43/0x120
> <4> [197.736485]  pci_power_up+0x24/0x1c0
> <4> [197.740047]  pci_pm_default_resume_early+0x9/0x30
> <4> [197.744725]  pci_pm_runtime_resume+0x2d/0x90
> <4> [197.753911]  __rpm_callback+0x3c/0x110
> <4> [197.762586]  rpm_callback+0x58/0x70
> <4> [197.766064]  rpm_resume+0x51e/0x730
> <4> [197.769542]  rpm_resume+0x267/0x730
> <4> [197.773020]  rpm_resume+0x267/0x730
> <4> [197.776498]  rpm_resume+0x267/0x730
> <4> [197.779974]  __pm_runtime_resume+0x49/0x90
> <4> [197.784055]  __intel_runtime_pm_get+0x19/0xa0 [i915]
> <4> [197.789070]  hwm_energy+0x55/0x100 [i915]
> <4> [197.793183]  hwm_read+0x9a/0x310 [i915]
> <4> [197.797124]  hwmon_attr_show+0x36/0x120
> <4> [197.800946]  dev_attr_show+0x15/0x60
> <4> [197.804509]  sysfs_kf_seq_show+0xb5/0x100
> 
> However, the lock is only intended to protect either a hwmon overflow
> counter or rmw hardware operations.  There is no need to hold the lock,
> only the wakeref, while reading from hardware.
> 
> Acquire the lock after hardware read under rpm wakeref.
> 
> Fixes: c41b8bdcc297 ("drm/i915/hwmon: Show device level energy usage")
> Signed-off-by: Janusz Krzysztofik 
> Cc:  # v6.2+
> ---
>  drivers/gpu/drm/i915/i915_hwmon.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_hwmon.c 
> b/drivers/gpu/drm/i915/i915_hwmon.c
> index 8c3f443c8347e..faf7670de6e06 100644
> --- a/drivers/gpu/drm/i915/i915_hwmon.c
> +++ b/drivers/gpu/drm/i915/i915_hwmon.c
> @@ -136,11 +136,11 @@ hwm_energy(struct hwm_drvdata *ddat, long *energy)
>   else
>   rgaddr = hwmon->rg.energy_status_all;
>  
> - mutex_lock(&hwmon->hwmon_lock);
> -
>   with_intel_runtime_pm(uncore->rpm, wakeref)
>   reg_val = intel_uncore_read(uncore, rgaddr);
>  
> + mutex_lock(&hwmon->hwmon_lock);
> +

This is not enough.
check hwm_locked_with_pm_intel_uncore_rmw()

It looks like we need to rethink this lock entirely here.


struct mutex hwmon_lock;/* counter overflow \
logic and rmw */

do we really need to protect the rmw?

This also shows me that we have other places with intel_uncore_rmw
without the with runtime_pm.

perhaps we need to stop using the with_rpm macro and use explicit
rpm calls before the hwmon_locks before the rmw?

perhaps we need a more granular lock?

notice that I'm just brainstorming/thinking out loud... someone need
to go there an run an deeper analisys on this lock and rpm calls
on hwmon.

>   if (reg_val >= ei->reg_val_prev)
>   ei->accum_energy += reg_val - ei->reg_val_prev;
>   else
> -- 
> 2.43.0
> 


Re: drm/msm: DisplayPort hard-reset on hotplug regression in 6.8-rc1

2024-03-11 Thread Abhinav Kumar




On 3/11/2024 6:43 AM, Johan Hovold wrote:

On Sat, Mar 09, 2024 at 05:30:17PM +0100, Johan Hovold wrote:

On Fri, Mar 08, 2024 at 09:50:17AM -0800, Abhinav Kumar wrote:

On 3/8/2024 4:43 AM, Johan Hovold wrote:



For this last remaining reset with the stacktrace you have mentioned
below, I do not think this was introduced due to PM runtime series. We
have had this report earlier with the same stacktrace as well in earlier
kernels which didnt have PM runtime support:



But, it seems like there is another race condition in this code
resulting in this issue again.

I have posted my analysis with the patch here as a RFC y'day:

https://patchwork.freedesktop.org/patch/581758/

I missed CCing you and Bjorn on the RFC but when I post it as a patch
either today/tomm, will CC you both.


Ok, thanks. I'll take a closer look at that next week. It's not clear to
me what that race looks like after reading the commit message. It would
be good to have some more details in there (e.g. the sequence of events
that breaks the state machine) and some way to reproduce the issue
reliably.


I was able to reproduce the reset with some of my debug printks in place
after reapplying the reverted hpd notify change so I have an explanation
for (one of) the ways we can up in this state now.

This does not match description of the problem in the fix linked to
above and I don't think that patch solves the underlying issue even if
it may make the race window somewhat smaller. More details below.
  


Its the same condition you described below that enable does not go 
through and we bail out as we are in ST_DISCONNECTED.



We now also have Bjorn's call trace from a different Qualcomm platform
triggering an unclocked access on disconnect, something which would
trigger a reset by the hypervisor on sc8280xp platforms like the X13s:



[ 2030.379583] Kernel panic - not syncing: Asynchronous SError Interrupt
[ 2030.379586] CPU: 0 PID: 239 Comm: kworker/0:2 Not tainted 
6.8.0-rc4-next-20240216-00015-gc937d3c43ffe-dirty #219
[ 2030.379590] Hardware name: Qualcomm Technologies, Inc. Robotics RB3gen2 (DT)
[ 2030.379592] Workqueue: events output_poll_execute [drm_kms_helper]
[ 2030.379642] Call trace:



[ 2030.379722]  wait_for_completion_timeout+0x14/0x20
[ 2030.379727]  dp_ctrl_push_idle+0x34/0x8c [msm]
[ 2030.379844]  dp_bridge_atomic_disable+0x18/0x24 [msm]
[ 2030.379959]  drm_atomic_bridge_chain_disable+0x6c/0xb4 [drm]
[ 2030.380150]  drm_atomic_helper_commit_modeset_disables+0x174/0x57c 
[drm_kms_helper]
[ 2030.380200]  msm_atomic_commit_tail+0x1b4/0x474 [msm]
[ 2030.380316]  commit_tail+0xa4/0x158 [drm_kms_helper]
[ 2030.380369]  drm_atomic_helper_commit+0x24c/0x26c [drm_kms_helper]
[ 2030.380418]  drm_atomic_commit+0xa8/0xd4 [drm]
[ 2030.380529]  drm_client_modeset_commit_atomic+0x16c/0x244 [drm]
[ 2030.380641]  drm_client_modeset_commit_locked+0x50/0x168 [drm]
[ 2030.380753]  drm_client_modeset_commit+0x2c/0x54 [drm]
[ 2030.380865]  __drm_fb_helper_restore_fbdev_mode_unlocked+0x60/0xa4 
[drm_kms_helper]
[ 2030.380915]  drm_fb_helper_hotplug_event+0xe0/0xf4 [drm_kms_helper]
[ 2030.380965]  msm_fbdev_client_hotplug+0x28/0xc8 [msm]
[ 2030.381081]  drm_client_dev_hotplug+0x94/0x118 [drm]
[ 2030.381192]  output_poll_execute+0x214/0x26c [drm_kms_helper]
[ 2030.381241]  process_scheduled_works+0x19c/0x2cc
[ 2030.381249]  worker_thread+0x290/0x3cc
[ 2030.381255]  kthread+0xfc/0x184
[ 2030.381260]  ret_from_fork+0x10/0x20

The above could happen if the convoluted hotplug state machine breaks
down so that the device is runtime suspended before
dp_bridge_atomic_disable() is called.



Yes, state machine got broken and I have explained how in the commit
text of the RFC. But its not necessarily due to PM runtime but a
sequence of events happening from userspace exposing this breakage.


After looking at this some more today, I agree with you. The
observations I've reported are consistent with what would happen if the
link clock is disabled when dp_bridge_atomic_disable() is called.

That clock is disabled in dp_bridge_atomic_post_disable() before runtime
suspending, but perhaps there are some further paths that can end up
disabling it.


Turns out there are paths like that and we hit those more often before
reverting e467e0bde881 ("drm/msm/dp: use drm_bridge_hpd_notify().

Specifically, when a previous connect attempt did not enable the bridge
fully so that it is still in the ST_MAINLINK_READY when we receive a
disconnect event, dp_hpd_unplug_handle() will turn of the link clock.

[  204.527625] msm-dp-display ae98000.displayport-controller: 
dp_bridge_hpd_notify - link_ready = 1, status = 2
[  204.531553] msm-dp-display ae98000.displayport-controller: 
dp_hpd_unplug_handle
[  204.533261] msm-dp-display ae98000.displayport-controller: dp_ctrl_off_link

A racing connect event, such as the one I described earlier, can then
try to enable the bridge again but dp_bridge_atomic_enable() just bails
out early (and leaks a rpm reference) because we're n

Re: [PATCH] drm/amdgpu: add ring buffer information in devcoredump

2024-03-11 Thread Christian König

Am 11.03.24 um 15:48 schrieb Khatri, Sunil:


On 3/11/2024 7:29 PM, Christian König wrote:



Am 11.03.24 um 13:22 schrieb Sunil Khatri:

Add relevant ringbuffer information such as
rptr, wptr, ring name, ring size and also
the ring contents for each ring on a gpu reset.

Signed-off-by: Sunil Khatri 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 21 +
  1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c

index 6d059f853adc..1992760039da 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
@@ -215,6 +215,27 @@ amdgpu_devcoredump_read(char *buffer, loff_t 
offset, size_t count,

 fault_info->status);
  }
  +    drm_printf(&p, "Ring buffer information\n");
+    for (int i = 0; i < coredump->adev->num_rings; i++) {
+    int j = 0;
+    struct amdgpu_ring *ring = coredump->adev->rings[i];
+
+    drm_printf(&p, "ring name: %s\n", ring->name);
+    drm_printf(&p, "Rptr: 0x%llx Wptr: 0x%llx\n",
+   amdgpu_ring_get_rptr(ring) & ring->buf_mask,
+   amdgpu_ring_get_wptr(ring) & ring->buf_mask);


Don't apply the mask here. We do have some use cases where the rptr 
and wptr are outside the ring buffer.

Sure i will remove the mask.



+    drm_printf(&p, "Ring size in dwords: %d\n",
+   ring->ring_size / 4);


Rather print the mask as additional value here.

Does that help adding the mask value ?


I think it should help as a reminder that rptr & wptr needs to be masked 
to become valid indexes.


Some hw generations have really crude workarounds where we have to 
allocate an extra page after the ring buffer because the hw is buddy and 
sometimes tries to read command from there as well.


So when we see a hang with some rptr and wptr values which don't fit 
into the mask we will know that the hw has another issue in that direction.


Regards,
Christian.




+    drm_printf(&p, "Ring contents\n");
+    drm_printf(&p, "Offset \t Value\n");
+
+    while (j < ring->ring_size) {
+    drm_printf(&p, "0x%x \t 0x%x\n", j, ring->ring[j/4]);
+    j += 4;
+    }



+    drm_printf(&p, "Ring dumped\n");


That seems superfluous.


Noted


Regards
Sunil



Regards,
Christian.


+    }
+
  if (coredump->reset_vram_lost)
  drm_printf(&p, "VRAM is lost due to GPU reset!\n");
  if (coredump->adev->reset_info.num_regs) {






Re: [RFC PATCH] drm/msm/dp: move link_ready out of HPD event thread

2024-03-11 Thread Kuogee Hsieh



On 3/6/2024 11:50 AM, Abhinav Kumar wrote:

There are cases where the userspace might still send another
frame after the HPD disconnect causing a modeset cycle after
a disconnect. This messes the internal state machine of MSM DP driver
and can lead to a crash as there can be an imbalance between
bridge_disable() and bridge_enable().

This was also previously reported on [1] for which [2] was posted
and helped resolve the issue by rejecting commits if the DP is not
in connected state.

The change resolved the bug but there can also be another race condition.
If hpd_event_thread does not pick up the EV_USER_NOTIFICATION and process it
link_ready will also not be set to false allowing the frame to sneak in.

Lets move setting link_ready outside of hpd_event_thread() processing to
eliminate a window of race condition.

[1] : https://gitlab.freedesktop.org/drm/msm/-/issues/17
[2] : 
https://lore.kernel.org/all/1664408211-25314-1-git-send-email-quic_khs...@quicinc.com/

Signed-off-by: Abhinav Kumar 

Tested-by: Kuogee Hsieh 
Reviewed-by: Kuogee Hsieh 

---
  drivers/gpu/drm/msm/dp/dp_display.c | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 068d44eeaa07..e00092904ccc 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -345,8 +345,6 @@ static int dp_display_send_hpd_notification(struct 
dp_display_private *dp,
 
dp->panel->downstream_ports);
}
  
-	dp->dp_display.link_ready = hpd;

-
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
dp->dp_display.connector_type, hpd);
drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready);
@@ -399,6 +397,8 @@ static int dp_display_process_hpd_high(struct 
dp_display_private *dp)
goto end;
}
  
+	dp->dp_display.link_ready = true;

+
dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);
  
  end:

@@ -466,6 +466,8 @@ static int dp_display_notify_disconnect(struct device *dev)
  {
struct dp_display_private *dp = dev_get_dp_display_private(dev);
  
+	dp->dp_display.link_ready = false;

+
dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
  
  	return 0;

@@ -487,6 +489,7 @@ static int dp_display_handle_port_status_changed(struct 
dp_display_private *dp)
drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
if (dp->hpd_state != ST_DISCONNECTED) {
dp->hpd_state = ST_DISCONNECT_PENDING;
+   dp->dp_display.link_ready = false;
dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
}
} else {


Re: [PATCH 4/5] drm/i915: Drop dead code for pvc

2024-03-11 Thread Rodrigo Vivi
On Mon, Mar 11, 2024 at 10:35:20AM -0500, Lucas De Marchi wrote:
> On Mon, Mar 11, 2024 at 11:29:31AM -0400, Rodrigo Vivi wrote:
> > > @@ -2907,9 +2829,7 @@ engine_init_workarounds(struct intel_engine_cs 
> > > *engine, struct i915_wa_list *wal
> > >   if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE)
> > >   general_render_compute_wa_init(engine, wal);
> > > 
> > > - if (engine->class == COMPUTE_CLASS)
> > > - ccs_engine_wa_init(engine, wal);
> > > - else if (engine->class == RENDER_CLASS)
> > 
> > I don't believe we need to remove this chunk since we are not deleting the 
> > ccs_engine_wa_init.
> > If we want to keep that as a placeholder we should also keep the caller as 
> > well.
> 
> right... I had removed it but brought it back since I noticed the
> kernel-doc mentions and forgot to bring back the caller too. I will fix
> this in next rev.

thanks!
with that:

Reviewed-by: Rodrigo Vivi 


> 
> 
> thanks
> Lucas De Marchi


Re: [PATCH 3/5] drm/i915: Update IP_VER(12, 50)

2024-03-11 Thread Rodrigo Vivi
On Mon, Mar 11, 2024 at 10:29:45AM -0500, Lucas De Marchi wrote:
> On Mon, Mar 11, 2024 at 11:18:03AM -0400, Rodrigo Vivi wrote:
> > On Wed, Mar 06, 2024 at 11:36:41AM -0800, Lucas De Marchi wrote:
> > > With no platform declaring graphics/media IP_VER(12, 50),
> > 
> > this is not true.
> > We still have
> > 
> > #define XE_HPM_FEATURES \
> > .__runtime.media.ip.ver = 12, \
> >.__runtime.media.ip.rel = 50
> 
> 
> 
> > > -#define XE_HPM_FEATURES \
> > > - .__runtime.media.ip.ver = 12, \
> > > - .__runtime.media.ip.rel = 50
> > > -
> 
> ^ being removed here since all the users, like below, are overriding it.
> 
> > >  #define DG2_FEATURES \
> > >   XE_HP_FEATURES, \
> > > - XE_HPM_FEATURES, \
> > >   DGFX_FEATURES, \
> > > + .__runtime.graphics.ip.ver = 12, \
> > >   .__runtime.graphics.ip.rel = 55, \
> > > + .__runtime.media.ip.ver = 12, \
> > >   .__runtime.media.ip.rel = 55, \
> 
> ^^
> 
> After applying until this patch:
> 
> $ git grep -e "rel[[:space:]]*=" -- drivers/gpu/drm/i915/i915_pci.c
> drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 10,
> drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 55, \
> drivers/gpu/drm/i915/i915_pci.c:.__runtime.media.ip.rel = 55, \
> drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 60,
> drivers/gpu/drm/i915/i915_pci.c:.__runtime.media.ip.rel = 60,
> drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 70,
> 
> should I reword anything in the commit message to make my intent
> clearer?

doh! sorry.. I read the first line of the commit message and stopped.

perhaps we could do that HPM removal in a separate patch before this one?

Reviewed-by: Rodrigo Vivi 

on the final result, whatever you decide to split or to rephrase the msg.

> 
> thanks
> Lucas De Marchi


Re: [PATCH] Fix divide-by-zero on DP unplug with nouveau

2024-03-11 Thread Imre Deak
On Mon, Mar 11, 2024 at 06:09:29PM +0200, Imre Deak wrote:
> On Sat, Feb 10, 2024 at 09:24:59PM +, Chris Bainbridge wrote:
> 
> Sorry for the delay.
> 
> > The following trace occurs when using nouveau and unplugging a DP MST
> > adaptor:
> > 
> >  divide error:  [#1] PREEMPT SMP PTI
> >  CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.0-rc3+ #744
> >  Hardware name: Razer Blade/DANA_MB, BIOS 01.01 08/31/2018
> >  RIP: 0010:drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >  Code: c6 b8 01 00 00 00 75 61 01 c6 41 0f af f3 41 0f af f1 c1 e1 04 48 63 
> > c7 31 d2 89 ff 48 8b 5d f8 c9 48 0f af f1 48 8d 44 06 ff <48> f7 f7 31 d2 
> > 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 31
> >  RSP: 0018:b2c5c211fa30 EFLAGS: 00010206
> >  RAX:  RBX:  RCX: 00f59b00
> >  RDX:  RSI:  RDI: 
> >  RBP: b2c5c211fa48 R08: 0001 R09: 0020
> >  R10: 0004 R11:  R12: 00023b4a
> >  R13: 91d37d165800 R14: 91d36fac6d80 R15: 91d34a764010
> >  FS:  7f4a1ca3fa80() GS:91d6edbc() 
> > knlGS:
> >  CS:  0010 DS:  ES:  CR0: 80050033
> >  CR2: 559491d49000 CR3: 00011d180002 CR4: 003706f0
> >  Call Trace:
> >   
> >   ? show_regs+0x6d/0x80
> >   ? die+0x37/0xa0
> >   ? do_trap+0xd4/0xf0
> >   ? do_error_trap+0x71/0xb0
> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >   ? exc_divide_error+0x3a/0x70
> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >   ? asm_exc_divide_error+0x1b/0x20
> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >   ? drm_dp_calc_pbn_mode+0x2e/0x70 [drm_display_helper]
> >   nv50_msto_atomic_check+0xda/0x120 [nouveau]
> >   drm_atomic_helper_check_modeset+0xa87/0xdf0 [drm_kms_helper]
> >   drm_atomic_helper_check+0x19/0xa0 [drm_kms_helper]
> >   nv50_disp_atomic_check+0x13f/0x2f0 [nouveau]
> >   drm_atomic_check_only+0x668/0xb20 [drm]
> >   ? drm_connector_list_iter_next+0x86/0xc0 [drm]
> >   drm_atomic_commit+0x58/0xd0 [drm]
> >   ? __pfx___drm_printfn_info+0x10/0x10 [drm]
> >   drm_atomic_connector_commit_dpms+0xd7/0x100 [drm]
> >   drm_mode_obj_set_property_ioctl+0x1c5/0x450 [drm]
> >   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
> >   drm_connector_property_set_ioctl+0x3b/0x60 [drm]
> >   drm_ioctl_kernel+0xb9/0x120 [drm]
> >   drm_ioctl+0x2d0/0x550 [drm]
> >   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
> >   nouveau_drm_ioctl+0x61/0xc0 [nouveau]
> >   __x64_sys_ioctl+0xa0/0xf0
> >   do_syscall_64+0x76/0x140
> >   ? do_syscall_64+0x85/0x140
> >   ? do_syscall_64+0x85/0x140
> >   entry_SYSCALL_64_after_hwframe+0x6e/0x76
> >  RIP: 0033:0x7f4a1cd1a94f
> >  Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 
> > 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 
> > f0 ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00
> >  RSP: 002b:7ffd2f1df520 EFLAGS: 0246 ORIG_RAX: 0010
> >  RAX: ffda RBX: 7ffd2f1df5b0 RCX: 7f4a1cd1a94f
> >  RDX: 7ffd2f1df5b0 RSI: c01064ab RDI: 000f
> >  RBP: c01064ab R08: 56347932deb8 R09: 56347a7d99c0
> >  R10:  R11: 0246 R12: 56347938a220
> >  R13: 000f R14: 563479d9f3f0 R15: 
> >   
> >  Modules linked in: rfcomm xt_conntrack nft_chain_nat xt_MASQUERADE nf_nat 
> > nf_conntrack_netlink nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xfrm_user 
> > xfrm_algo xt_addrtype nft_compat nf_tables nfnetlink br_netfilter bridge 
> > stp llc ccm cmac algif_hash overlay algif_skcipher af_alg bnep binfmt_misc 
> > snd_sof_pci_intel_cnl snd_sof_intel_hda_common snd_soc_hdac_hda snd_sof_pci 
> > snd_sof_xtensa_dsp snd_sof_intel_hda snd_sof snd_sof_utils 
> > snd_soc_acpi_intel_match snd_soc_acpi snd_soc_core snd_compress 
> > snd_sof_intel_hda_mlink snd_hda_ext_core iwlmvm intel_rapl_msr 
> > intel_rapl_common intel_tcc_cooling x86_pkg_temp_thermal intel_powerclamp 
> > mac80211 coretemp kvm_intel snd_hda_codec_hdmi kvm snd_hda_codec_realtek 
> > snd_hda_codec_generic uvcvideo libarc4 snd_hda_intel snd_intel_dspcfg 
> > snd_hda_codec iwlwifi videobuf2_vmalloc videobuf2_memops uvc irqbypass 
> > btusb videobuf2_v4l2 snd_seq_midi crct10dif_pclmul hid_multitouch 
> > crc32_pclmul snd_seq_midi_event btrtl snd_hwdep videodev polyval_clmulni 
> > polyval_generic snd_rawmidi
> >   ghash_clmulni_intel aesni_intel btintel crypto_simd snd_hda_core cryptd 
> > snd_seq btbcm ee1004 8250_dw videobuf2_common btmtk rapl nls_iso8859_1 
> > mei_hdcp thunderbolt bluetooth intel_cstate wmi_bmof intel_wmi_thunderbolt 
> > cfg80211 snd_pcm mc snd_seq_device i2c_i801 r8169 ecdh_generic snd_timer 
> > i2c_smbus ecc snd mei_me intel_lpss_pci mei ahci intel_lpss soundcore 
> > realtek libahci idma64 intel_pch_thermal i2c_hid_acpi i2c_hid acpi_pad 
> > sc

Re: [PATCH] Fix divide-by-zero on DP unplug with nouveau

2024-03-11 Thread Linux regression tracking (Thorsten Leemhuis)
On 11.03.24 17:09, Imre Deak wrote:
> On Sat, Feb 10, 2024 at 09:24:59PM +, Chris Bainbridge wrote:
> Sorry for the delay.

Happens, thx for looking onto this!

>> The following trace occurs when using nouveau and unplugging a DP MST
>> adaptor:
> [...] 
>> +if (bpp_x16 == 0)
>> +return 0;
> 
> Could you please move the check to the beginnig of the function and add
> a debug message in case bpp_x16 is 0?
> 
> It looks odd that a driver calls this function with a 0 bpp_x16, and
> ideally it should be fixed in the driver. However as it's a regression
> and we don't have a better idea now:
> 
> Acked-by: Imre Deak 

Chris: as this went into 6.8, please consider adding a stable-tag to
ensure Greg picks this up.

Ciao, Thorsten



Re: [PATCH] Revert "drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue"

2024-03-11 Thread Liviu Dudau
On Mon, Mar 11, 2024 at 05:52:59PM +0200, Jani Nikula wrote:
> On Mon, 11 Mar 2024, Liviu Dudau  wrote:
> > On Mon, Mar 11, 2024 at 04:49:30PM +0200, Jani Nikula wrote:
> >> On Mon, 11 Mar 2024, Liviu Dudau  wrote:
> >> > So with this revert we're OK with an undefined symbol if !CONFIG_PM, but 
> >> > we're not happy
> >> > with a recursive dependency that is only triggered for COMPILE_TEST? I 
> >> > would've thought
> >> > IOMMU_SUPPORT options is a better one.
> >> 
> >> It's a real config.
> >> 
> >> # CONFIG_COMPILE_TEST is not set
> >
> > So I can select CONFIG_ARM64 and CONFIG_X86_LOCAL_APIC at the same time? 
> > DRM_PANTHOR depends on ARM || ARM64
> > and X86_LOCAL_APIC depends on X86_64. At some moment the recursive 
> > dependency detector should've stopped as
> > there are no common dependencies between DRM_PANTHOR and X86_LOCAL_APIC and 
> > going further just triggers false
> > positives. I'm curious how you've created your config now.
> 
> The thing is, I don't have *any* of the dependencies ARM || ARM64 ||
> COMPILE_TEST set in the config that triggered this. I don't have
> DRM_PANTHOR set. But make olddefconfig detects a circular dependency
> nonetheless.
> 
> It's possible the issue is in kconfig. I don't know. But not being able
> to even dodge the warning makes it a show stopper. I wouldn't even know
> what to change in the config.

Understood, thanks for clarifying the condition under which you've discovered
the issue. I assumed (appologies!) that you were generating or using a crafted
.config for testing new drivers.

Reverting is then a better option for olddefconfig case, thanks for the patch
and the quick merge.

Best regards,
Liviu

> 
> 
> BR,
> Jani.
> 
> 
> -- 
> Jani Nikula, Intel

-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯


Re: [PATCH] Fix divide-by-zero on DP unplug with nouveau

2024-03-11 Thread Imre Deak
On Sat, Feb 10, 2024 at 09:24:59PM +, Chris Bainbridge wrote:

Sorry for the delay.

> The following trace occurs when using nouveau and unplugging a DP MST
> adaptor:
> 
>  divide error:  [#1] PREEMPT SMP PTI
>  CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.0-rc3+ #744
>  Hardware name: Razer Blade/DANA_MB, BIOS 01.01 08/31/2018
>  RIP: 0010:drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>  Code: c6 b8 01 00 00 00 75 61 01 c6 41 0f af f3 41 0f af f1 c1 e1 04 48 63 
> c7 31 d2 89 ff 48 8b 5d f8 c9 48 0f af f1 48 8d 44 06 ff <48> f7 f7 31 d2 31 
> c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 31
>  RSP: 0018:b2c5c211fa30 EFLAGS: 00010206
>  RAX:  RBX:  RCX: 00f59b00
>  RDX:  RSI:  RDI: 
>  RBP: b2c5c211fa48 R08: 0001 R09: 0020
>  R10: 0004 R11:  R12: 00023b4a
>  R13: 91d37d165800 R14: 91d36fac6d80 R15: 91d34a764010
>  FS:  7f4a1ca3fa80() GS:91d6edbc() knlGS:
>  CS:  0010 DS:  ES:  CR0: 80050033
>  CR2: 559491d49000 CR3: 00011d180002 CR4: 003706f0
>  Call Trace:
>   
>   ? show_regs+0x6d/0x80
>   ? die+0x37/0xa0
>   ? do_trap+0xd4/0xf0
>   ? do_error_trap+0x71/0xb0
>   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>   ? exc_divide_error+0x3a/0x70
>   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>   ? asm_exc_divide_error+0x1b/0x20
>   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>   ? drm_dp_calc_pbn_mode+0x2e/0x70 [drm_display_helper]
>   nv50_msto_atomic_check+0xda/0x120 [nouveau]
>   drm_atomic_helper_check_modeset+0xa87/0xdf0 [drm_kms_helper]
>   drm_atomic_helper_check+0x19/0xa0 [drm_kms_helper]
>   nv50_disp_atomic_check+0x13f/0x2f0 [nouveau]
>   drm_atomic_check_only+0x668/0xb20 [drm]
>   ? drm_connector_list_iter_next+0x86/0xc0 [drm]
>   drm_atomic_commit+0x58/0xd0 [drm]
>   ? __pfx___drm_printfn_info+0x10/0x10 [drm]
>   drm_atomic_connector_commit_dpms+0xd7/0x100 [drm]
>   drm_mode_obj_set_property_ioctl+0x1c5/0x450 [drm]
>   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
>   drm_connector_property_set_ioctl+0x3b/0x60 [drm]
>   drm_ioctl_kernel+0xb9/0x120 [drm]
>   drm_ioctl+0x2d0/0x550 [drm]
>   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
>   nouveau_drm_ioctl+0x61/0xc0 [nouveau]
>   __x64_sys_ioctl+0xa0/0xf0
>   do_syscall_64+0x76/0x140
>   ? do_syscall_64+0x85/0x140
>   ? do_syscall_64+0x85/0x140
>   entry_SYSCALL_64_after_hwframe+0x6e/0x76
>  RIP: 0033:0x7f4a1cd1a94f
>  Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 
> 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 f0 
> ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00
>  RSP: 002b:7ffd2f1df520 EFLAGS: 0246 ORIG_RAX: 0010
>  RAX: ffda RBX: 7ffd2f1df5b0 RCX: 7f4a1cd1a94f
>  RDX: 7ffd2f1df5b0 RSI: c01064ab RDI: 000f
>  RBP: c01064ab R08: 56347932deb8 R09: 56347a7d99c0
>  R10:  R11: 0246 R12: 56347938a220
>  R13: 000f R14: 563479d9f3f0 R15: 
>   
>  Modules linked in: rfcomm xt_conntrack nft_chain_nat xt_MASQUERADE nf_nat 
> nf_conntrack_netlink nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xfrm_user 
> xfrm_algo xt_addrtype nft_compat nf_tables nfnetlink br_netfilter bridge stp 
> llc ccm cmac algif_hash overlay algif_skcipher af_alg bnep binfmt_misc 
> snd_sof_pci_intel_cnl snd_sof_intel_hda_common snd_soc_hdac_hda snd_sof_pci 
> snd_sof_xtensa_dsp snd_sof_intel_hda snd_sof snd_sof_utils 
> snd_soc_acpi_intel_match snd_soc_acpi snd_soc_core snd_compress 
> snd_sof_intel_hda_mlink snd_hda_ext_core iwlmvm intel_rapl_msr 
> intel_rapl_common intel_tcc_cooling x86_pkg_temp_thermal intel_powerclamp 
> mac80211 coretemp kvm_intel snd_hda_codec_hdmi kvm snd_hda_codec_realtek 
> snd_hda_codec_generic uvcvideo libarc4 snd_hda_intel snd_intel_dspcfg 
> snd_hda_codec iwlwifi videobuf2_vmalloc videobuf2_memops uvc irqbypass btusb 
> videobuf2_v4l2 snd_seq_midi crct10dif_pclmul hid_multitouch crc32_pclmul 
> snd_seq_midi_event btrtl snd_hwdep videodev polyval_clmulni polyval_generic 
> snd_rawmidi
>   ghash_clmulni_intel aesni_intel btintel crypto_simd snd_hda_core cryptd 
> snd_seq btbcm ee1004 8250_dw videobuf2_common btmtk rapl nls_iso8859_1 
> mei_hdcp thunderbolt bluetooth intel_cstate wmi_bmof intel_wmi_thunderbolt 
> cfg80211 snd_pcm mc snd_seq_device i2c_i801 r8169 ecdh_generic snd_timer 
> i2c_smbus ecc snd mei_me intel_lpss_pci mei ahci intel_lpss soundcore realtek 
> libahci idma64 intel_pch_thermal i2c_hid_acpi i2c_hid acpi_pad sch_fq_codel 
> msr parport_pc ppdev lp parport efi_pstore ip_tables x_tables autofs4 
> dm_crypt raid10 raid456 libcrc32c async_raid6_recov async_memcpy async_pq 
> async_xor xor async_tx raid6_pq raid1 raid0 joydev input_leds hid_generic 
> usbh

Re: [PATCH v2] drm/drm_connector: Document Colorspace property variants

2024-03-11 Thread Sebastian Wick
On Thu, Mar 07, 2024 at 10:29:22AM +0200, Pekka Paalanen wrote:
> On Wed, 6 Mar 2024 17:42:09 +0100
> Sebastian Wick  wrote:
> 
> > On Wed, Mar 06, 2024 at 10:27:21AM +0200, Pekka Paalanen wrote:
> > > On Tue,  5 Mar 2024 14:51:49 +0100
> > > Sebastian Wick  wrote:
> > >   
> > > > The initial idea of the Colorspace prop was that this maps 1:1 to
> > > > InfoFrames/SDP but KMS does not give user space enough information nor
> > > > control over the output format to figure out which variants can be used
> > > > for a given KMS commit. At the same time, properties like Broadcast RGB
> > > > expect full range quantization range being produced by user space from
> > > > the CRTC and drivers to convert to the range expected by the sink for
> > > > the chosen output format, mode, InfoFrames, etc.
> > > > 
> > > > This change documents the reality of the Colorspace property. The
> > > > Default variant unfortunately is very much driver specific and not
> > > > reflected by the EDID. The BT2020 variants are in active use by generic
> > > > compositors which have expectations from the driver about the
> > > > conversions it has to do when selecting certain output formats.
> > > > 
> > > > Everything else is also marked as undefined. Coming up with valid
> > > > behavior that makes it usable from user space and consistent with other
> > > > KMS properties for those variants is left as an exercise for whoever
> > > > wants to use them.
> > > > 
> > > > v2:
> > > >  * Talk about "pixel operation properties" that user space configures
> > > >  * Mention that user space is responsible for checking the EDID for sink
> > > >support
> > > >  * Make it clear that drivers can choose between RGB and YCbCr on their
> > > >own
> > > > 
> > > > Signed-off-by: Sebastian Wick 
> > > > ---
> > > >  drivers/gpu/drm/drm_connector.c | 79 +
> > > >  include/drm/drm_connector.h |  8 
> > > >  2 files changed, 61 insertions(+), 26 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_connector.c 
> > > > b/drivers/gpu/drm/drm_connector.c
> > > > index b0516505f7ae..65cdcc7d22db 100644
> > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > +++ b/drivers/gpu/drm/drm_connector.c
> > > > @@ -2147,24 +2147,67 @@ 
> > > > EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
> > > >   * DOC: standard connector properties
> > > >   *
> > > >   * Colorspace:
> > > > - * This property helps select a suitable colorspace based on the 
> > > > sink
> > > > - * capability. Modern sink devices support wider gamut like BT2020.
> > > > - * This helps switch to BT2020 mode if the BT2020 encoded video 
> > > > stream
> > > > - * is being played by the user, same for any other colorspace. 
> > > > Thereby
> > > > - * giving a good visual experience to users.
> > > > - *
> > > > - * The expectation from userspace is that it should parse the EDID
> > > > - * and get supported colorspaces. Use this property and switch to 
> > > > the
> > > > - * one supported. Sink supported colorspaces should be retrieved by
> > > > - * userspace from EDID and driver will not explicitly expose them.
> > > > - *
> > > > - * Basically the expectation from userspace is:
> > > > - *  - Set up CRTC DEGAMMA/CTM/GAMMA to convert to some sink
> > > > - *colorspace
> > > > - *  - Set this new property to let the sink know what it
> > > > - *converted the CRTC output to.
> > > > - *  - This property is just to inform sink what colorspace
> > > > - *source is trying to drive.
> > > > + * This property is used to inform the driver about the color 
> > > > encoding
> > > > + * user space configured the pixel operation properties to produce.
> > > > + * The variants set the colorimetry, transfer characteristics, and 
> > > > which
> > > > + * YCbCr conversion should be used when necessary.
> > > > + * The transfer characteristics from HDR_OUTPUT_METADATA takes 
> > > > precedence
> > > > + * over this property.
> > > > + * User space always configures the pixel operation properties to 
> > > > produce
> > > > + * full quantization range data (see the Broadcast RGB property).
> > > > + *
> > > > + * Drivers inform the sink about what colorimetry, transfer
> > > > + * characteristics, YCbCr conversion, and quantization range to 
> > > > expect
> > > > + * (this can depend on the output mode, output format and other
> > > > + * properties). Drivers also convert the user space provided data 
> > > > to what
> > > > + * the sink expects.  
> > > 
> > > Hi Sebastian,
> > > 
> > > should it be more explicit that drivers are allowed to do only
> > > RGB->YCbCr and quantization range conversions, but not TF nor gamut
> > > conversions?
> > > 
> > > That is, if the driver cannot pick the TF implied by "Colorspace"
> > > property for the sink, then it cannot pick another TF for the sink and
> > > silently convert. It t

RE: [REGRESSION] Divide-by-zero on DisplayPort MST unplug with nouveau

2024-03-11 Thread Saarinen, Jani


> -Original Message-
> From: Jani Nikula 
> Sent: Monday, 11 March 2024 18.03
> To: Saarinen, Jani ; Linux regressions mailing list
> ; Deak, Imre 
> Cc: Chris Bainbridge ; intel-gfx  g...@lists.freedesktop.org>; David Airlie ; Daniel Vetter
> ; ML dri-devel 
> Subject: RE: [REGRESSION] Divide-by-zero on DisplayPort MST unplug with
> nouveau
> 
> On Mon, 11 Mar 2024, "Saarinen, Jani"  wrote:
> > Hi,
> >
> >> -Original Message-
> >> From: Intel-gfx  On Behalf
> >> Of Linux regression tracking (Thorsten Leemhuis)
> >> Sent: Monday, 11 March 2024 17.53
> >> To: Deak, Imre 
> >> Cc: regressi...@lists.linux.dev; Chris Bainbridge
> >> ; intel-gfx
> >> ;
> >> David Airlie ; Daniel Vetter ; ML
> >> dri-devel 
> >> Subject: Re: [REGRESSION] Divide-by-zero on DisplayPort MST unplug
> >> with nouveau
> >>
> >> On 07.03.24 18:58, Chris Bainbridge wrote:
> >> > - Forwarded message from Chris Bainbridge
> >> >  -
> >> >
> >> > Date: Sat, 10 Feb 2024 21:24:59 +
> >>
> >> Hmm, it looks like nobody is looking into this regression. Is there a
> >> good reason?
> >>
> >> Imre, or did you maybe just miss that Chris' regression seems to be
> >> caused by a commit of yours? He initally proposed a fix (the
> >> forwarded mail that is quoted here) more a month ago already here:
> >> https://lore.kernel.org/all/ZcfpqwnkSoiJxeT9@debian.local/
> >>
> >> Chris recently filed a ticket, too:
> >> https://gitlab.freedesktop.org/drm/misc/kernel/-/issues/36
> > Please file
> > https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.htm
> > l
> 
> Well, please don't. It's *not* an i915 bug.
Right, sorry about this. Let Imre to comment then. 

> 
> BR,
> Jani.
> 
> >>
> >> Mostly silence there as well. :-/
> >>
> >> Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker'
> >> hat)
> >>
> >> P.S: Chris, sorry, I had missed that you initially proposed the fix a
> >> month ago; if I had noticed this earlier I had sent a mail like this one 
> >> earlier.
> >> --
> >> Everything you wanna know about Linux kernel regression tracking:
> >> https://linux-regtracking.leemhuis.info/about/#tldr
> >> If I did something stupid, please tell me, as explained on that page.
> >>
> >> > From: Chris Bainbridge 
> >> > To: dri-devel@lists.freedesktop.org
> >> > Cc: ly...@redhat.com, ville.syrj...@linux.intel.com,
> >> stanislav.lisovs...@intel.com,
> >> >  mrip...@kernel.org, imre.d...@intel.com
> >> > Subject: [PATCH] Fix divide-by-zero on DP unplug with nouveau
> >> >
> >> > The following trace occurs when using nouveau and unplugging a DP
> >> > MST
> >> > adaptor:
> >> >>  divide error:  [#1] PREEMPT SMP PTI
> >> >  CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.0-rc3+ #744  Hardware
> >> > name: Razer Blade/DANA_MB, BIOS 01.01 08/31/2018
> >> >  RIP: 0010:drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >> >  Code: c6 b8 01 00 00 00 75 61 01 c6 41 0f af f3 41 0f af f1 c1 e1
> >> > 04
> >> > 48 63 c7 31 d2 89 ff 48 8b 5d f8 c9 48 0f af f1 48 8d 44 06 ff <48>
> >> > f7
> >> > f7 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 31
> >> >  RSP: 0018:b2c5c211fa30 EFLAGS: 00010206
> >> >  RAX:  RBX:  RCX: 00f59b00
> >> >  RDX:  RSI:  RDI:
> >> 
> >> >  RBP: b2c5c211fa48 R08: 0001 R09:
> >> 0020
> >> >  R10: 0004 R11:  R12:
> >> 00023b4a
> >> >  R13: 91d37d165800 R14: 91d36fac6d80 R15: 91d34a764010
> >> >  FS:  7f4a1ca3fa80() GS:91d6edbc()
> >> > knlGS:
> >> >  CS:  0010 DS:  ES:  CR0: 80050033
> >> >  CR2: 559491d49000 CR3: 00011d180002 CR4:
> >> 003706f0
> >> > Call Trace:
> >> >   
> >> >   ? show_regs+0x6d/0x80
> >> >   ? die+0x37/0xa0
> >> >   ? do_trap+0xd4/0xf0
> >> >   ? do_error_trap+0x71/0xb0
> >> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >> >   ? exc_divide_error+0x3a/0x70
> >> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >> >   ? asm_exc_divide_error+0x1b/0x20
> >> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >> >   ? drm_dp_calc_pbn_mode+0x2e/0x70 [drm_display_helper]
> >> >   nv50_msto_atomic_check+0xda/0x120 [nouveau]
> >> >   drm_atomic_helper_check_modeset+0xa87/0xdf0 [drm_kms_helper]
> >> >   drm_atomic_helper_check+0x19/0xa0 [drm_kms_helper]
> >> >   nv50_disp_atomic_check+0x13f/0x2f0 [nouveau]
> >> >   drm_atomic_check_only+0x668/0xb20 [drm]
> >> >   ? drm_connector_list_iter_next+0x86/0xc0 [drm]
> >> >   drm_atomic_commit+0x58/0xd0 [drm]
> >> >   ? __pfx___drm_printfn_info+0x10/0x10 [drm]
> >> >   drm_atomic_connector_commit_dpms+0xd7/0x100 [drm]
> >> >   drm_mode_obj_set_property_ioctl+0x1c5/0x450 [drm]
> >> >   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
> >> >   drm_connector_property_set_ioctl+0x3b/0x60 [drm]
> >> >   drm_ioctl_kernel+0xb9/0x120 [drm]
> >> >   drm_ioctl+0x2d0/0x550 [drm]

RE: [REGRESSION] Divide-by-zero on DisplayPort MST unplug with nouveau

2024-03-11 Thread Jani Nikula
On Mon, 11 Mar 2024, "Saarinen, Jani"  wrote:
> Hi, 
>
>> -Original Message-
>> From: Intel-gfx  On Behalf Of Linux
>> regression tracking (Thorsten Leemhuis)
>> Sent: Monday, 11 March 2024 17.53
>> To: Deak, Imre 
>> Cc: regressi...@lists.linux.dev; Chris Bainbridge
>> ; intel-gfx ;
>> David Airlie ; Daniel Vetter ; ML 
>> dri-devel
>> 
>> Subject: Re: [REGRESSION] Divide-by-zero on DisplayPort MST unplug with
>> nouveau
>> 
>> On 07.03.24 18:58, Chris Bainbridge wrote:
>> > - Forwarded message from Chris Bainbridge
>> >  -
>> >
>> > Date: Sat, 10 Feb 2024 21:24:59 +
>> 
>> Hmm, it looks like nobody is looking into this regression. Is there a good
>> reason?
>> 
>> Imre, or did you maybe just miss that Chris' regression seems to be caused by
>> a commit of yours? He initally proposed a fix (the forwarded mail that is
>> quoted here) more a month ago already here:
>> https://lore.kernel.org/all/ZcfpqwnkSoiJxeT9@debian.local/
>> 
>> Chris recently filed a ticket, too:
>> https://gitlab.freedesktop.org/drm/misc/kernel/-/issues/36
> Please file 
> https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html 

Well, please don't. It's *not* an i915 bug.

BR,
Jani.

>> 
>> Mostly silence there as well. :-/
>> 
>> Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)
>> 
>> P.S: Chris, sorry, I had missed that you initially proposed the fix a month 
>> ago; if
>> I had noticed this earlier I had sent a mail like this one earlier.
>> --
>> Everything you wanna know about Linux kernel regression tracking:
>> https://linux-regtracking.leemhuis.info/about/#tldr
>> If I did something stupid, please tell me, as explained on that page.
>> 
>> > From: Chris Bainbridge 
>> > To: dri-devel@lists.freedesktop.org
>> > Cc: ly...@redhat.com, ville.syrj...@linux.intel.com,
>> stanislav.lisovs...@intel.com,
>> >mrip...@kernel.org, imre.d...@intel.com
>> > Subject: [PATCH] Fix divide-by-zero on DP unplug with nouveau
>> >
>> > The following trace occurs when using nouveau and unplugging a DP MST
>> > adaptor:
>> >>  divide error:  [#1] PREEMPT SMP PTI
>> >  CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.0-rc3+ #744  Hardware
>> > name: Razer Blade/DANA_MB, BIOS 01.01 08/31/2018
>> >  RIP: 0010:drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>> >  Code: c6 b8 01 00 00 00 75 61 01 c6 41 0f af f3 41 0f af f1 c1 e1 04
>> > 48 63 c7 31 d2 89 ff 48 8b 5d f8 c9 48 0f af f1 48 8d 44 06 ff <48> f7
>> > f7 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 31
>> >  RSP: 0018:b2c5c211fa30 EFLAGS: 00010206
>> >  RAX:  RBX:  RCX: 00f59b00
>> >  RDX:  RSI:  RDI:
>> 
>> >  RBP: b2c5c211fa48 R08: 0001 R09:
>> 0020
>> >  R10: 0004 R11:  R12:
>> 00023b4a
>> >  R13: 91d37d165800 R14: 91d36fac6d80 R15: 91d34a764010
>> >  FS:  7f4a1ca3fa80() GS:91d6edbc()
>> > knlGS:
>> >  CS:  0010 DS:  ES:  CR0: 80050033
>> >  CR2: 559491d49000 CR3: 00011d180002 CR4:
>> 003706f0
>> > Call Trace:
>> >   
>> >   ? show_regs+0x6d/0x80
>> >   ? die+0x37/0xa0
>> >   ? do_trap+0xd4/0xf0
>> >   ? do_error_trap+0x71/0xb0
>> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>> >   ? exc_divide_error+0x3a/0x70
>> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>> >   ? asm_exc_divide_error+0x1b/0x20
>> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>> >   ? drm_dp_calc_pbn_mode+0x2e/0x70 [drm_display_helper]
>> >   nv50_msto_atomic_check+0xda/0x120 [nouveau]
>> >   drm_atomic_helper_check_modeset+0xa87/0xdf0 [drm_kms_helper]
>> >   drm_atomic_helper_check+0x19/0xa0 [drm_kms_helper]
>> >   nv50_disp_atomic_check+0x13f/0x2f0 [nouveau]
>> >   drm_atomic_check_only+0x668/0xb20 [drm]
>> >   ? drm_connector_list_iter_next+0x86/0xc0 [drm]
>> >   drm_atomic_commit+0x58/0xd0 [drm]
>> >   ? __pfx___drm_printfn_info+0x10/0x10 [drm]
>> >   drm_atomic_connector_commit_dpms+0xd7/0x100 [drm]
>> >   drm_mode_obj_set_property_ioctl+0x1c5/0x450 [drm]
>> >   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
>> >   drm_connector_property_set_ioctl+0x3b/0x60 [drm]
>> >   drm_ioctl_kernel+0xb9/0x120 [drm]
>> >   drm_ioctl+0x2d0/0x550 [drm]
>> >   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
>> >   nouveau_drm_ioctl+0x61/0xc0 [nouveau]
>> >   __x64_sys_ioctl+0xa0/0xf0
>> >   do_syscall_64+0x76/0x140
>> >   ? do_syscall_64+0x85/0x140
>> >   ? do_syscall_64+0x85/0x140
>> >   entry_SYSCALL_64_after_hwframe+0x6e/0x76
>> >  RIP: 0033:0x7f4a1cd1a94f
>> >  Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48
>> > 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89
>> > c0 3d 00 f0 ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00
>> >  RSP: 002b:7ffd2f1df520 EFLAGS: 0246 ORIG_RAX:
>> > 0010
>> >  RAX: ff

[PATCH v2] drm: Document requirements for driver-specific KMS props in new drivers

2024-03-11 Thread Sebastian Wick
When extending support for a driver-specific KMS property to additional
drivers, we should apply all the requirements for new properties and
make sure the semantics are the same and documented.

v2: devs of the driver which introduced property shall help and ack

Signed-off-by: Sebastian Wick 
---
 Documentation/gpu/drm-kms.rst | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 13d3627d8bc0..b98b98359c90 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -496,6 +496,13 @@ addition to the one mentioned above:
 
 * An IGT test must be submitted where reasonable.
 
+For historical reasons, non-standard, driver-specific properties exist. If a 
KMS
+driver wants to add support for one of those properties, the requirements for
+new properties apply where possible. Additionally, the documented behavior must
+match the de facto semantics of the existing property to ensure compatibility.
+Developers of the driver that first added the property should help with those
+tasks and must ACK the documented behavior if possible.
+
 Property Types and Blob Property Support
 
 
-- 
2.44.0



RE: [REGRESSION] Divide-by-zero on DisplayPort MST unplug with nouveau

2024-03-11 Thread Saarinen, Jani
Hi, 

> -Original Message-
> From: Intel-gfx  On Behalf Of Linux
> regression tracking (Thorsten Leemhuis)
> Sent: Monday, 11 March 2024 17.53
> To: Deak, Imre 
> Cc: regressi...@lists.linux.dev; Chris Bainbridge
> ; intel-gfx ;
> David Airlie ; Daniel Vetter ; ML dri-devel
> 
> Subject: Re: [REGRESSION] Divide-by-zero on DisplayPort MST unplug with
> nouveau
> 
> On 07.03.24 18:58, Chris Bainbridge wrote:
> > - Forwarded message from Chris Bainbridge
> >  -
> >
> > Date: Sat, 10 Feb 2024 21:24:59 +
> 
> Hmm, it looks like nobody is looking into this regression. Is there a good
> reason?
> 
> Imre, or did you maybe just miss that Chris' regression seems to be caused by
> a commit of yours? He initally proposed a fix (the forwarded mail that is
> quoted here) more a month ago already here:
> https://lore.kernel.org/all/ZcfpqwnkSoiJxeT9@debian.local/
> 
> Chris recently filed a ticket, too:
> https://gitlab.freedesktop.org/drm/misc/kernel/-/issues/36
Please file 
https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html 
> 
> Mostly silence there as well. :-/
> 
> Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)
> 
> P.S: Chris, sorry, I had missed that you initially proposed the fix a month 
> ago; if
> I had noticed this earlier I had sent a mail like this one earlier.
> --
> Everything you wanna know about Linux kernel regression tracking:
> https://linux-regtracking.leemhuis.info/about/#tldr
> If I did something stupid, please tell me, as explained on that page.
> 
> > From: Chris Bainbridge 
> > To: dri-devel@lists.freedesktop.org
> > Cc: ly...@redhat.com, ville.syrj...@linux.intel.com,
> stanislav.lisovs...@intel.com,
> > mrip...@kernel.org, imre.d...@intel.com
> > Subject: [PATCH] Fix divide-by-zero on DP unplug with nouveau
> >
> > The following trace occurs when using nouveau and unplugging a DP MST
> > adaptor:
> >>  divide error:  [#1] PREEMPT SMP PTI
> >  CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.0-rc3+ #744  Hardware
> > name: Razer Blade/DANA_MB, BIOS 01.01 08/31/2018
> >  RIP: 0010:drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >  Code: c6 b8 01 00 00 00 75 61 01 c6 41 0f af f3 41 0f af f1 c1 e1 04
> > 48 63 c7 31 d2 89 ff 48 8b 5d f8 c9 48 0f af f1 48 8d 44 06 ff <48> f7
> > f7 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 31
> >  RSP: 0018:b2c5c211fa30 EFLAGS: 00010206
> >  RAX:  RBX:  RCX: 00f59b00
> >  RDX:  RSI:  RDI:
> 
> >  RBP: b2c5c211fa48 R08: 0001 R09:
> 0020
> >  R10: 0004 R11:  R12:
> 00023b4a
> >  R13: 91d37d165800 R14: 91d36fac6d80 R15: 91d34a764010
> >  FS:  7f4a1ca3fa80() GS:91d6edbc()
> > knlGS:
> >  CS:  0010 DS:  ES:  CR0: 80050033
> >  CR2: 559491d49000 CR3: 00011d180002 CR4:
> 003706f0
> > Call Trace:
> >   
> >   ? show_regs+0x6d/0x80
> >   ? die+0x37/0xa0
> >   ? do_trap+0xd4/0xf0
> >   ? do_error_trap+0x71/0xb0
> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >   ? exc_divide_error+0x3a/0x70
> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >   ? asm_exc_divide_error+0x1b/0x20
> >   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
> >   ? drm_dp_calc_pbn_mode+0x2e/0x70 [drm_display_helper]
> >   nv50_msto_atomic_check+0xda/0x120 [nouveau]
> >   drm_atomic_helper_check_modeset+0xa87/0xdf0 [drm_kms_helper]
> >   drm_atomic_helper_check+0x19/0xa0 [drm_kms_helper]
> >   nv50_disp_atomic_check+0x13f/0x2f0 [nouveau]
> >   drm_atomic_check_only+0x668/0xb20 [drm]
> >   ? drm_connector_list_iter_next+0x86/0xc0 [drm]
> >   drm_atomic_commit+0x58/0xd0 [drm]
> >   ? __pfx___drm_printfn_info+0x10/0x10 [drm]
> >   drm_atomic_connector_commit_dpms+0xd7/0x100 [drm]
> >   drm_mode_obj_set_property_ioctl+0x1c5/0x450 [drm]
> >   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
> >   drm_connector_property_set_ioctl+0x3b/0x60 [drm]
> >   drm_ioctl_kernel+0xb9/0x120 [drm]
> >   drm_ioctl+0x2d0/0x550 [drm]
> >   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
> >   nouveau_drm_ioctl+0x61/0xc0 [nouveau]
> >   __x64_sys_ioctl+0xa0/0xf0
> >   do_syscall_64+0x76/0x140
> >   ? do_syscall_64+0x85/0x140
> >   ? do_syscall_64+0x85/0x140
> >   entry_SYSCALL_64_after_hwframe+0x6e/0x76
> >  RIP: 0033:0x7f4a1cd1a94f
> >  Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48
> > 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89
> > c0 3d 00 f0 ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00
> >  RSP: 002b:7ffd2f1df520 EFLAGS: 0246 ORIG_RAX:
> > 0010
> >  RAX: ffda RBX: 7ffd2f1df5b0 RCX: 7f4a1cd1a94f
> >  RDX: 7ffd2f1df5b0 RSI: c01064ab RDI: 000f
> >  RBP: c01064ab R08: 56347932deb8 R09:
> 56347a7d99c0
> >  R10:  R11: 0

Re: [PATCH RFC v2 5/5] drm/msm/hdmi: make use of the drm_connector_hdmi framework

2024-03-11 Thread Dmitry Baryshkov
On Mon, 11 Mar 2024 at 17:46, Maxime Ripard  wrote:
>
> Hi,
>
> On Sat, Mar 09, 2024 at 12:31:32PM +0200, Dmitry Baryshkov wrote:
> > Setup the HDMI connector on the MSM HDMI outputs. Make use of
> > atomic_check hook and of the provided Infoframe infrastructure.
> >
> > Note: for now only AVI Infoframes are enabled. Audio Infoframes are
> > currenly handled separately. This will be fixed for the final version.
> >
> > Signed-off-by: Dmitry Baryshkov 
>
> I had a look at the driver, and it looks like mode_set and mode_valid
> could use the connector_state tmds_char_rate instead of pixclock and
> drm_connector_hdmi_compute_mode_clock respectively instead of
> calculating it by themselves.

Ack, I'll take a look.b

>
> We can probably remove hdmi->pixclock entirely if we manage to pass the
> connector state to msm_hdmi_power_on.

I'd like to defer this for a moment, I have a pending series moving
MSM HDMI PHY drivers to generic PHY subsystem. However that patchset
reworks the way the PHY is setup, so it doesn't make sense to rework
msm_hdmi_power_on().

>
> And that's unrelated to this series, but we can also remove
> hdmi->hdmi_mode for drm_display_info.is_hdmi.

Yes, that's the plan, once I rework the audio infoframe handling.

-- 
With best wishes
Dmitry


Re: [REGRESSION] Divide-by-zero on DisplayPort MST unplug with nouveau

2024-03-11 Thread Linux regression tracking (Thorsten Leemhuis)
On 07.03.24 18:58, Chris Bainbridge wrote:
> - Forwarded message from Chris Bainbridge  
> -
> 
> Date: Sat, 10 Feb 2024 21:24:59 +

Hmm, it looks like nobody is looking into this regression. Is there a
good reason?

Imre, or did you maybe just miss that Chris' regression seems to be
caused by a commit of yours? He initally proposed a fix (the forwarded
mail that is quoted here) more a month ago already here:
https://lore.kernel.org/all/ZcfpqwnkSoiJxeT9@debian.local/

Chris recently filed a ticket, too:
https://gitlab.freedesktop.org/drm/misc/kernel/-/issues/36

Mostly silence there as well. :-/

Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)

P.S: Chris, sorry, I had missed that you initially proposed the fix a
month ago; if I had noticed this earlier I had sent a mail like this one
earlier.
--
Everything you wanna know about Linux kernel regression tracking:
https://linux-regtracking.leemhuis.info/about/#tldr
If I did something stupid, please tell me, as explained on that page.

> From: Chris Bainbridge 
> To: dri-devel@lists.freedesktop.org
> Cc: ly...@redhat.com, ville.syrj...@linux.intel.com, 
> stanislav.lisovs...@intel.com,
>   mrip...@kernel.org, imre.d...@intel.com
> Subject: [PATCH] Fix divide-by-zero on DP unplug with nouveau
> 
> The following trace occurs when using nouveau and unplugging a DP MST
> adaptor:
>>  divide error:  [#1] PREEMPT SMP PTI
>  CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.0-rc3+ #744
>  Hardware name: Razer Blade/DANA_MB, BIOS 01.01 08/31/2018
>  RIP: 0010:drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>  Code: c6 b8 01 00 00 00 75 61 01 c6 41 0f af f3 41 0f af f1 c1 e1 04 48 63 
> c7 31 d2 89 ff 48 8b 5d f8 c9 48 0f af f1 48 8d 44 06 ff <48> f7 f7 31 d2 31 
> c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 31
>  RSP: 0018:b2c5c211fa30 EFLAGS: 00010206
>  RAX:  RBX:  RCX: 00f59b00
>  RDX:  RSI:  RDI: 
>  RBP: b2c5c211fa48 R08: 0001 R09: 0020
>  R10: 0004 R11:  R12: 00023b4a
>  R13: 91d37d165800 R14: 91d36fac6d80 R15: 91d34a764010
>  FS:  7f4a1ca3fa80() GS:91d6edbc() knlGS:
>  CS:  0010 DS:  ES:  CR0: 80050033
>  CR2: 559491d49000 CR3: 00011d180002 CR4: 003706f0
>  Call Trace:
>   
>   ? show_regs+0x6d/0x80
>   ? die+0x37/0xa0
>   ? do_trap+0xd4/0xf0
>   ? do_error_trap+0x71/0xb0
>   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>   ? exc_divide_error+0x3a/0x70
>   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>   ? asm_exc_divide_error+0x1b/0x20
>   ? drm_dp_bw_overhead+0xb4/0x110 [drm_display_helper]
>   ? drm_dp_calc_pbn_mode+0x2e/0x70 [drm_display_helper]
>   nv50_msto_atomic_check+0xda/0x120 [nouveau]
>   drm_atomic_helper_check_modeset+0xa87/0xdf0 [drm_kms_helper]
>   drm_atomic_helper_check+0x19/0xa0 [drm_kms_helper]
>   nv50_disp_atomic_check+0x13f/0x2f0 [nouveau]
>   drm_atomic_check_only+0x668/0xb20 [drm]
>   ? drm_connector_list_iter_next+0x86/0xc0 [drm]
>   drm_atomic_commit+0x58/0xd0 [drm]
>   ? __pfx___drm_printfn_info+0x10/0x10 [drm]
>   drm_atomic_connector_commit_dpms+0xd7/0x100 [drm]
>   drm_mode_obj_set_property_ioctl+0x1c5/0x450 [drm]
>   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
>   drm_connector_property_set_ioctl+0x3b/0x60 [drm]
>   drm_ioctl_kernel+0xb9/0x120 [drm]
>   drm_ioctl+0x2d0/0x550 [drm]
>   ? __pfx_drm_connector_property_set_ioctl+0x10/0x10 [drm]
>   nouveau_drm_ioctl+0x61/0xc0 [nouveau]
>   __x64_sys_ioctl+0xa0/0xf0
>   do_syscall_64+0x76/0x140
>   ? do_syscall_64+0x85/0x140
>   ? do_syscall_64+0x85/0x140
>   entry_SYSCALL_64_after_hwframe+0x6e/0x76
>  RIP: 0033:0x7f4a1cd1a94f
>  Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 
> 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 f0 
> ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00
>  RSP: 002b:7ffd2f1df520 EFLAGS: 0246 ORIG_RAX: 0010
>  RAX: ffda RBX: 7ffd2f1df5b0 RCX: 7f4a1cd1a94f
>  RDX: 7ffd2f1df5b0 RSI: c01064ab RDI: 000f
>  RBP: c01064ab R08: 56347932deb8 R09: 56347a7d99c0
>  R10:  R11: 0246 R12: 56347938a220
>  R13: 000f R14: 563479d9f3f0 R15: 
>   
>  Modules linked in: rfcomm xt_conntrack nft_chain_nat xt_MASQUERADE nf_nat 
> nf_conntrack_netlink nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xfrm_user 
> xfrm_algo xt_addrtype nft_compat nf_tables nfnetlink br_netfilter bridge stp 
> llc ccm cmac algif_hash overlay algif_skcipher af_alg bnep binfmt_misc 
> snd_sof_pci_intel_cnl snd_sof_intel_hda_common snd_soc_hdac_hda snd_sof_pci 
> snd_sof_xtensa_dsp snd_sof_intel_hda snd_sof snd_sof_utils 
> snd_soc_acpi_intel_match snd_soc_acpi snd_soc_core snd_compress 
> snd_sof_intel_hda_mlink sn

Re: [PATCH] Revert "drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue"

2024-03-11 Thread Jani Nikula
On Mon, 11 Mar 2024, Liviu Dudau  wrote:
> On Mon, Mar 11, 2024 at 04:49:30PM +0200, Jani Nikula wrote:
>> On Mon, 11 Mar 2024, Liviu Dudau  wrote:
>> > So with this revert we're OK with an undefined symbol if !CONFIG_PM, but 
>> > we're not happy
>> > with a recursive dependency that is only triggered for COMPILE_TEST? I 
>> > would've thought
>> > IOMMU_SUPPORT options is a better one.
>> 
>> It's a real config.
>> 
>> # CONFIG_COMPILE_TEST is not set
>
> So I can select CONFIG_ARM64 and CONFIG_X86_LOCAL_APIC at the same time? 
> DRM_PANTHOR depends on ARM || ARM64
> and X86_LOCAL_APIC depends on X86_64. At some moment the recursive dependency 
> detector should've stopped as
> there are no common dependencies between DRM_PANTHOR and X86_LOCAL_APIC and 
> going further just triggers false
> positives. I'm curious how you've created your config now.

The thing is, I don't have *any* of the dependencies ARM || ARM64 ||
COMPILE_TEST set in the config that triggered this. I don't have
DRM_PANTHOR set. But make olddefconfig detects a circular dependency
nonetheless.

It's possible the issue is in kconfig. I don't know. But not being able
to even dodge the warning makes it a show stopper. I wouldn't even know
what to change in the config.


BR,
Jani.


-- 
Jani Nikula, Intel


Re: [PATCH RFC v2 5/5] drm/msm/hdmi: make use of the drm_connector_hdmi framework

2024-03-11 Thread Maxime Ripard
Hi,

On Sat, Mar 09, 2024 at 12:31:32PM +0200, Dmitry Baryshkov wrote:
> Setup the HDMI connector on the MSM HDMI outputs. Make use of
> atomic_check hook and of the provided Infoframe infrastructure.
> 
> Note: for now only AVI Infoframes are enabled. Audio Infoframes are
> currenly handled separately. This will be fixed for the final version.
> 
> Signed-off-by: Dmitry Baryshkov 

I had a look at the driver, and it looks like mode_set and mode_valid
could use the connector_state tmds_char_rate instead of pixclock and
drm_connector_hdmi_compute_mode_clock respectively instead of
calculating it by themselves.

We can probably remove hdmi->pixclock entirely if we manage to pass the
connector state to msm_hdmi_power_on.

And that's unrelated to this series, but we can also remove
hdmi->hdmi_mode for drm_display_info.is_hdmi.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH RFC v2 0/5] drm/msm: make use of the HDMI connector infrastructure

2024-03-11 Thread Maxime Ripard
Hi,

On Sat, Mar 09, 2024 at 12:31:27PM +0200, Dmitry Baryshkov wrote:
> This patchset sits on top Maxime's HDMI connector patchset ([1]).
> 
> Currently this is an RFC exploring the interface between HDMI bridges
> and HDMI connector code. This has been lightly verified on the Qualcomm
> DB820c, which has native HDMI output. If this approach is considered to
> be acceptable, I'll finish MSM HDMI bridge conversion (reworking the
> Audio Infoframe code). Other bridges can follow the same approach (we
> have lt9611 / lt9611uxc / adv7511 on Qualcomm hardware).
> 
> [1] https://patchwork.freedesktop.org/series/122421/
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
> Changes in v2:
> - Dropped drm_connector_hdmi_setup(). Instead added
>   drm_connector_hdmi_init() to be used by drm_bridge_connector.
> - Changed the drm_bridge_connector to act as a proxy for the HDMI
>   connector  infrastructure. This removes most of the logic from
>   the bridge drivers.
> - Link to v1: 
> https://lore.kernel.org/r/20240308-bridge-hdmi-connector-v1-0-90b693550...@linaro.org

Overall, aside from the small comments on individual patches, I think
it's in good shape right now.

Thanks!
Maxime


signature.asc
Description: PGP signature


Re: [PATCH RFC v2 2/5] drm/connector: hdmi: add drm_connector_hdmi_init

2024-03-11 Thread Maxime Ripard
Hi,

On Sat, Mar 09, 2024 at 12:31:29PM +0200, Dmitry Baryshkov wrote:
> To support connectors which do all the management on their own (like
> drm_bridge_connector), add drm_connector_hdmi_init() in addition to
> drmm_connector_hdmi_init().
> 
> Signed-off-by: Dmitry Baryshkov 

That's only slightly relevante, but I think it could be occasion to
switch to drmm_connector_init for drm_bridge_connector too.

It's something we want to migrate to anyway, so it would be nice to do
it as part of this series so we don't need the extra init function.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH] Revert "drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue"

2024-03-11 Thread Liviu Dudau
On Mon, Mar 11, 2024 at 04:49:30PM +0200, Jani Nikula wrote:
> On Mon, 11 Mar 2024, Liviu Dudau  wrote:
> > On Mon, Mar 11, 2024 at 02:26:50PM +0200, Jani Nikula wrote:
> >> On Mon, 11 Mar 2024, Boris Brezillon  wrote:
> >> > On Mon, 11 Mar 2024 13:51:46 +0200
> >> > Jani Nikula  wrote:
> >> >
> >> >> On Mon, 11 Mar 2024, Boris Brezillon  
> >> >> wrote:
> >> >> > On Mon, 11 Mar 2024 13:16:19 +0200
> >> >> > Jani Nikula  wrote:
> >> >> >  
> >> >> >> This reverts commit 674dc7f61aefea81901c21402946074927e63f1a.
> >> >> >> 
> >> >> >> The commit causes a recursive dependency in kconfig:
> >> >> >> 
> >> >> >> drivers/iommu/Kconfig:14:error: recursive dependency detected!
> >> >> >> drivers/iommu/Kconfig:14:symbol IOMMU_SUPPORT is selected by 
> >> >> >> DRM_PANTHOR
> >> >> >> drivers/gpu/drm/panthor/Kconfig:3:   symbol DRM_PANTHOR depends on PM
> >> >> >> kernel/power/Kconfig:183:symbol PM is selected by PM_SLEEP
> >> >> >> kernel/power/Kconfig:117:symbol PM_SLEEP depends on 
> >> >> >> HIBERNATE_CALLBACKS
> >> >> >> kernel/power/Kconfig:35: symbol HIBERNATE_CALLBACKS is selected 
> >> >> >> by XEN_SAVE_RESTORE
> >> >> >> arch/x86/xen/Kconfig:67: symbol XEN_SAVE_RESTORE depends on XEN
> >> >> >> arch/x86/xen/Kconfig:6:  symbol XEN depends on PARAVIRT
> >> >> >> arch/x86/Kconfig:781:symbol PARAVIRT is selected by HYPERV
> >> >> >> drivers/hv/Kconfig:5:symbol HYPERV depends on X86_LOCAL_APIC
> >> >> >> arch/x86/Kconfig:1106:   symbol X86_LOCAL_APIC depends on 
> >> >> >> X86_UP_APIC
> >> >> >> arch/x86/Kconfig:1081:   symbol X86_UP_APIC prompt is visible 
> >> >> >> depending on PCI_MSI
> >> >> >> drivers/pci/Kconfig:39:  symbol PCI_MSI is selected by AMD_IOMMU
> >> >> >> drivers/iommu/amd/Kconfig:3: symbol AMD_IOMMU depends on 
> >> >> >> IOMMU_SUPPORT
> >> >> >> For a resolution refer to Documentation/kbuild/kconfig-language.rst
> >> >> >> subsection "Kconfig recursive dependency limitations"
> >> >> >> 
> >> >> >> Fixes: 674dc7f61aef ("drm/panthor: Fix undefined 
> >> >> >> panthor_device_suspend/resume symbol issue")
> >> >> >> Cc: Boris Brezillon 
> >> >> >> Cc: Liviu Dudau 
> >> >> >> Cc: Steven Price 
> >> >> >> Signed-off-by: Jani Nikula   
> >> >> >
> >> >> > Acked-by: Boris Brezillon   
> >> >> 
> >> >> Your suggestion select -> depends on IOMMU_SUPPORT seems to also work,
> >> >> at least for me. Want to send a patch for that instead of me merging the
> >> >> revert?
> >> >
> >> > I replied on the other thread :-). I think we're better off reverting
> >> > the faulty commit, so we can discuss how to fix the original issue
> >> > properly without blocking the build.
> >> 
> >> Thanks, pushed to drm-misc-next.
> >
> > So with this revert we're OK with an undefined symbol if !CONFIG_PM, but 
> > we're not happy
> > with a recursive dependency that is only triggered for COMPILE_TEST? I 
> > would've thought
> > IOMMU_SUPPORT options is a better one.
> 
> It's a real config.
> 
> # CONFIG_COMPILE_TEST is not set

So I can select CONFIG_ARM64 and CONFIG_X86_LOCAL_APIC at the same time? 
DRM_PANTHOR depends on ARM || ARM64
and X86_LOCAL_APIC depends on X86_64. At some moment the recursive dependency 
detector should've stopped as
there are no common dependencies between DRM_PANTHOR and X86_LOCAL_APIC and 
going further just triggers false
positives. I'm curious how you've created your config now.

Best regards,
Liviu

> 
> BR,
> Jani.
> 
> >
> > Best regards,
> > Liviu
> >
> >> 
> >> BR,
> >> Jani.
> >> 
> >> 
> >> -- 
> >> Jani Nikula, Intel
> 
> -- 
> Jani Nikula, Intel

-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯


Re: [PATCH 4/5] drm/i915: Drop dead code for pvc

2024-03-11 Thread Lucas De Marchi

On Mon, Mar 11, 2024 at 11:29:31AM -0400, Rodrigo Vivi wrote:

@@ -2907,9 +2829,7 @@ engine_init_workarounds(struct intel_engine_cs *engine, 
struct i915_wa_list *wal
if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE)
general_render_compute_wa_init(engine, wal);

-   if (engine->class == COMPUTE_CLASS)
-   ccs_engine_wa_init(engine, wal);
-   else if (engine->class == RENDER_CLASS)


I don't believe we need to remove this chunk since we are not deleting the 
ccs_engine_wa_init.
If we want to keep that as a placeholder we should also keep the caller as well.


right... I had removed it but brought it back since I noticed the
kernel-doc mentions and forgot to bring back the caller too. I will fix
this in next rev.


thanks
Lucas De Marchi


Re: [PATCH 3/5] drm/i915: Update IP_VER(12, 50)

2024-03-11 Thread Lucas De Marchi

On Mon, Mar 11, 2024 at 11:18:03AM -0400, Rodrigo Vivi wrote:

On Wed, Mar 06, 2024 at 11:36:41AM -0800, Lucas De Marchi wrote:

With no platform declaring graphics/media IP_VER(12, 50),


this is not true.
We still have

#define XE_HPM_FEATURES \
.__runtime.media.ip.ver = 12, \
   .__runtime.media.ip.rel = 50





-#define XE_HPM_FEATURES \
-   .__runtime.media.ip.ver = 12, \
-   .__runtime.media.ip.rel = 50
-


^ being removed here since all the users, like below, are overriding it.


 #define DG2_FEATURES \
XE_HP_FEATURES, \
-   XE_HPM_FEATURES, \
DGFX_FEATURES, \
+   .__runtime.graphics.ip.ver = 12, \
.__runtime.graphics.ip.rel = 55, \
+   .__runtime.media.ip.ver = 12, \
.__runtime.media.ip.rel = 55, \


  ^^

After applying until this patch:

$ git grep -e "rel[[:space:]]*=" -- drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 10,
drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 55, \
drivers/gpu/drm/i915/i915_pci.c:.__runtime.media.ip.rel = 55, \
drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 60,
drivers/gpu/drm/i915/i915_pci.c:.__runtime.media.ip.rel = 60,
drivers/gpu/drm/i915/i915_pci.c:.__runtime.graphics.ip.rel = 70,

should I reword anything in the commit message to make my intent
clearer?

thanks
Lucas De Marchi


Re: [PATCH 4/5] drm/i915: Drop dead code for pvc

2024-03-11 Thread Rodrigo Vivi
On Wed, Mar 06, 2024 at 11:36:42AM -0800, Lucas De Marchi wrote:
> PCI IDs for PVC were never added and platform always marked with
> force_probe. Drop what's not used and rename some places as needed.
> 
> The registers not used anymore are also removed.
> 
> Signed-off-by: Lucas De Marchi 
> ---
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |   2 +-
>  drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |   3 -
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c |  33 
>  drivers/gpu/drm/i915/gt/intel_gt_mcr.c|  30 +---
>  drivers/gpu/drm/i915/gt/intel_gt_regs.h   |   9 --
>  drivers/gpu/drm/i915/gt/intel_mocs.c  |  19 ---
>  drivers/gpu/drm/i915/gt/intel_rps.c   |   4 +-
>  drivers/gpu/drm/i915/gt/intel_sseu.c  |   9 +-
>  drivers/gpu/drm/i915/gt/intel_workarounds.c   |  90 +--
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c |   4 -
>  drivers/gpu/drm/i915/i915_debugfs.c   |  12 --
>  drivers/gpu/drm/i915/i915_drv.h   |   9 --
>  drivers/gpu/drm/i915/i915_pci.c   |  36 -
>  drivers/gpu/drm/i915/i915_reg.h   |   1 -
>  drivers/gpu/drm/i915/intel_clock_gating.c |  16 +-
>  drivers/gpu/drm/i915/intel_device_info.c  |   1 -
>  drivers/gpu/drm/i915/intel_device_info.h  |   1 -
>  drivers/gpu/drm/i915/intel_step.c |  70 +
>  drivers/gpu/drm/i915/intel_uncore.c   | 142 --
>  drivers/gpu/drm/i915/selftests/intel_uncore.c |   2 -
>  .../gpu/drm/xe/compat-i915-headers/i915_drv.h |   4 -
>  21 files changed, 12 insertions(+), 485 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
> b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index 0c5cdab278b6..d3300ae3053f 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -386,7 +386,7 @@ struct drm_i915_gem_object {
>* and kernel mode driver for caching policy control after GEN12.
>* In the meantime platform specific tables are created to translate
>* i915_cache_level into pat index, for more details check the macros
> -  * defined i915/i915_pci.c, e.g. PVC_CACHELEVEL.
> +  * defined i915/i915_pci.c, e.g. MTL_CACHELEVEL.
>* For backward compatibility, this field contains values exactly match
>* the entries of enum i915_cache_level for pre-GEN12 platforms (See
>* LEGACY_CACHELEVEL), so that the PTE encode functions for these
> diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
> index 24d1c28201fa..2e27bcb52e0d 100644
> --- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
> @@ -189,9 +189,6 @@ static bool gen12_needs_ccs_aux_inv(struct 
> intel_engine_cs *engine)
>  {
>   i915_reg_t reg = gen12_get_aux_inv_reg(engine);
>  
> - if (IS_PONTEVECCHIO(engine->i915))
> - return false;
> -
>   /*
>* So far platforms supported by i915 having flat ccs do not require
>* AUX invalidation. Check also whether the engine requires it.
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index 75bde8c1aa5d..396f5fe993c3 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -839,38 +839,6 @@ static void engine_mask_apply_compute_fuses(struct 
> intel_gt *gt)
>   }
>  }
>  
> -static void engine_mask_apply_copy_fuses(struct intel_gt *gt)
> -{
> - struct drm_i915_private *i915 = gt->i915;
> - struct intel_gt_info *info = >->info;
> - unsigned long meml3_mask;
> - unsigned long quad;
> -
> - if (!(GRAPHICS_VER_FULL(i915) >= IP_VER(12, 60) &&
> -   GRAPHICS_VER_FULL(i915) < IP_VER(12, 70)))
> - return;
> -
> - meml3_mask = intel_uncore_read(gt->uncore, GEN10_MIRROR_FUSE3);
> - meml3_mask = REG_FIELD_GET(GEN12_MEML3_EN_MASK, meml3_mask);
> -
> - /*
> -  * Link Copy engines may be fused off according to meml3_mask. Each
> -  * bit is a quad that houses 2 Link Copy and two Sub Copy engines.
> -  */
> - for_each_clear_bit(quad, &meml3_mask, GEN12_MAX_MSLICES) {
> - unsigned int instance = quad * 2 + 1;
> - intel_engine_mask_t mask = GENMASK(_BCS(instance + 1),
> -_BCS(instance));
> -
> - if (mask & info->engine_mask) {
> - gt_dbg(gt, "bcs%u fused off\n", instance);
> - gt_dbg(gt, "bcs%u fused off\n", instance + 1);
> -
> - info->engine_mask &= ~mask;
> - }
> - }
> -}
> -
>  /*
>   * Determine which engines are fused off in our particular hardware.
>   * Note that we have a catch-22 situation where we need to be able to access
> @@ -889,7 +857,6 @@ static intel_engine_mask_t init_engine_mask(struct 
> intel_gt *gt)
>  
>   

Re: [PATCH 3/5] drm/i915: Update IP_VER(12, 50)

2024-03-11 Thread Rodrigo Vivi
On Wed, Mar 06, 2024 at 11:36:41AM -0800, Lucas De Marchi wrote:
> With no platform declaring graphics/media IP_VER(12, 50),

this is not true.
We still have

#define XE_HPM_FEATURES \
.__runtime.media.ip.ver = 12, \
.__runtime.media.ip.rel = 50

 replace the
> checks throughout the code with IP_VER(12, 55) so the code makes sense
> by itself with no additional explanation of previous baggage.
> 
> The info override for the various _info is then changed so the version
> definition is clearer without pointless overrides.
> 
> Signed-off-by: Lucas De Marchi 
> ---
>  drivers/gpu/drm/i915/gem/selftests/huge_pages.c  |  4 ++--
>  .../gpu/drm/i915/gem/selftests/i915_gem_client_blt.c |  8 
>  drivers/gpu/drm/i915/gt/gen8_engine_cs.c |  2 +-
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c|  5 ++---
>  drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 10 +-
>  drivers/gpu/drm/i915/gt/intel_gt.c   |  4 ++--
>  drivers/gpu/drm/i915/gt/intel_gt_mcr.c   |  4 ++--
>  drivers/gpu/drm/i915/gt/intel_gt_mcr.h   |  2 +-
>  drivers/gpu/drm/i915/gt/intel_gtt.c  |  2 +-
>  drivers/gpu/drm/i915/gt/intel_lrc.c  |  8 
>  drivers/gpu/drm/i915/gt/intel_migrate.c  |  4 ++--
>  drivers/gpu/drm/i915/gt/intel_mocs.c |  2 +-
>  drivers/gpu/drm/i915/gt/intel_sseu.c |  4 ++--
>  drivers/gpu/drm/i915/gt/intel_workarounds.c  |  4 ++--
>  drivers/gpu/drm/i915/gt/uc/intel_guc.c   |  2 +-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c   |  4 ++--
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c|  2 +-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c|  2 +-
>  drivers/gpu/drm/i915/i915_getparam.c |  4 ++--
>  drivers/gpu/drm/i915/i915_gpu_error.c|  5 ++---
>  drivers/gpu/drm/i915/i915_pci.c  | 12 
>  drivers/gpu/drm/i915/i915_perf.c |  8 
>  drivers/gpu/drm/i915/i915_query.c|  2 +-
>  drivers/gpu/drm/i915/intel_uncore.c  |  2 +-
>  24 files changed, 50 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
> b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> index 3ff3d8889c6c..edb54903be0a 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> @@ -713,7 +713,7 @@ static int igt_ppgtt_huge_fill(void *arg)
>  {
>   struct drm_i915_private *i915 = arg;
>   unsigned int supported = RUNTIME_INFO(i915)->page_sizes;
> - bool has_pte64 = GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50);
> + bool has_pte64 = GRAPHICS_VER_FULL(i915) >= IP_VER(12, 55);
>   struct i915_address_space *vm;
>   struct i915_gem_context *ctx;
>   unsigned long max_pages;
> @@ -857,7 +857,7 @@ static int igt_ppgtt_huge_fill(void *arg)
>  static int igt_ppgtt_64K(void *arg)
>  {
>   struct drm_i915_private *i915 = arg;
> - bool has_pte64 = GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50);
> + bool has_pte64 = GRAPHICS_VER_FULL(i915) >= IP_VER(12, 55);
>   struct drm_i915_gem_object *obj;
>   struct i915_address_space *vm;
>   struct i915_gem_context *ctx;
> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c 
> b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
> index 10a7847f1b04..bac15196b4d2 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
> @@ -117,7 +117,7 @@ static bool fastblit_supports_x_tiling(const struct 
> drm_i915_private *i915)
>   if (gen < 12)
>   return true;
>  
> - if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 50))
> + if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 55))
>   return false;
>  
>   return HAS_DISPLAY(i915);
> @@ -166,7 +166,7 @@ static int prepare_blit(const struct tiled_blits *t,
>   src_pitch = t->width; /* in dwords */
>   if (src->tiling == CLIENT_TILING_Y) {
>   src_tiles = XY_FAST_COPY_BLT_D0_SRC_TILE_MODE(YMAJOR);
> - if (GRAPHICS_VER_FULL(to_i915(batch->base.dev)) >= 
> IP_VER(12, 50))
> + if (GRAPHICS_VER_FULL(to_i915(batch->base.dev)) >= 
> IP_VER(12, 55))
>   src_4t = XY_FAST_COPY_BLT_D1_SRC_TILE4;
>   } else if (src->tiling == CLIENT_TILING_X) {
>   src_tiles = XY_FAST_COPY_BLT_D0_SRC_TILE_MODE(TILE_X);
> @@ -177,7 +177,7 @@ static int prepare_blit(const struct tiled_blits *t,
>   dst_pitch = t->width; /* in dwords */
>   if (dst->tiling == CLIENT_TILING_Y) {
>   dst_tiles = XY_FAST_COPY_BLT_D0_DST_TILE_MODE(YMAJOR);
> - if (GRAPHICS_VER_FULL(to_i915(batch->base.dev)) >= 
> IP_VER(12, 50))
> + 

Re: drm/msm: DisplayPort hard-reset on hotplug regression in 6.8-rc1

2024-03-11 Thread Johan Hovold
On Mon, Mar 11, 2024 at 02:43:24PM +0100, Johan Hovold wrote:

> So, while it may still be theoretically possible to hit the resets after
> the revert, the HPD notify revert effectively "fixed" the regression in
> 6.8-rc1 by removing the preconditions that now made us hit it (i.e. the
> half-initialised bridge).
> 
> It seems the hotplug state machine needs to be reworked completely, but
> at least we're roughly back where we were with 6.7 (including that the
> bus clocks will never be turned of because of the rpm leaks on
> disconnect).

#regzbot introduced: e467e0bde881
#regzbot fix: 664bad6af3cb


Re: [PATCH 2/5] drm/i915: Drop dead code for xehpsdv

2024-03-11 Thread Rodrigo Vivi
On Wed, Mar 06, 2024 at 11:36:40AM -0800, Lucas De Marchi wrote:
> PCI IDs for XEHPSDV were never added and platform always marked with
> force_probe. Drop what's not used and rename some places to either be
> xehp or dg2, depending on the platform/IP checks.
> 
> The registers not used anymore are also removed.
> 
> Signed-off-by: Lucas De Marchi 
> ---
> 
> Potential problem here that needs a deeper look, the changes in
> __gen12_fw_ranges. Some ranges had comments saying they were XEHPSDV so
> I removed them, but it needs to be double checked with spec and CI
> results.

I have checked the specs and your patch looks right because those
bits should be reserved for DG2.

But the main issue I see is that we were using that (wrongly?) for
DG2 so far. So it probably deserves a separate patch anyway.

With this patch only removing the comments and a separate patch
to remove that for DG2 (and standalone CI run on that patch by itself):

Reviewed-by: Rodrigo Vivi 

> 
>  Documentation/gpu/rfc/i915_vm_bind.h  | 11 +--
>  drivers/gpu/drm/i915/gt/gen8_ppgtt.c  | 40 
>  drivers/gpu/drm/i915/gt/intel_gsc.c   | 15 ---
>  drivers/gpu/drm/i915/gt/intel_gt_mcr.c| 20 +---
>  drivers/gpu/drm/i915/gt/intel_gt_regs.h   | 50 --
>  drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c   | 21 ++--
>  drivers/gpu/drm/i915/gt/intel_lrc.c   | 43 -
>  drivers/gpu/drm/i915/gt/intel_migrate.c   | 18 ++--
>  drivers/gpu/drm/i915/gt/intel_mocs.c  | 31 --
>  drivers/gpu/drm/i915/gt/intel_rps.c   |  2 -
>  drivers/gpu/drm/i915/gt/intel_workarounds.c   | 95 ---
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c |  4 +-
>  drivers/gpu/drm/i915/i915_drv.h   |  4 -
>  drivers/gpu/drm/i915/i915_hwmon.c |  6 --
>  drivers/gpu/drm/i915/i915_pci.c   | 17 
>  drivers/gpu/drm/i915/i915_perf.c  | 11 +--
>  drivers/gpu/drm/i915/i915_reg.h   |  3 +-
>  drivers/gpu/drm/i915/intel_clock_gating.c | 10 --
>  drivers/gpu/drm/i915/intel_device_info.c  |  1 -
>  drivers/gpu/drm/i915/intel_device_info.h  |  1 -
>  drivers/gpu/drm/i915/intel_step.c | 10 --
>  drivers/gpu/drm/i915/intel_uncore.c   | 15 +--
>  drivers/gpu/drm/i915/selftests/intel_uncore.c |  1 -
>  .../gpu/drm/xe/compat-i915-headers/i915_drv.h |  2 -
>  24 files changed, 51 insertions(+), 380 deletions(-)
> 
> diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
> b/Documentation/gpu/rfc/i915_vm_bind.h
> index 8a8fcd4fceac..bc26dc126104 100644
> --- a/Documentation/gpu/rfc/i915_vm_bind.h
> +++ b/Documentation/gpu/rfc/i915_vm_bind.h
> @@ -93,12 +93,11 @@ struct drm_i915_gem_timeline_fence {
>   * Multiple VA mappings can be created to the same section of the object
>   * (aliasing).
>   *
> - * The @start, @offset and @length must be 4K page aligned. However the DG2
> - * and XEHPSDV has 64K page size for device local memory and has compact page
> - * table. On those platforms, for binding device local-memory objects, the
> - * @start, @offset and @length must be 64K aligned. Also, UMDs should not mix
> - * the local memory 64K page and the system memory 4K page bindings in the 
> same
> - * 2M range.
> + * The @start, @offset and @length must be 4K page aligned. However the DG2 
> has
> + * 64K page size for device local memory and has compact page table. On that
> + * platform, for binding device local-memory objects, the @start, @offset and
> + * @length must be 64K aligned. Also, UMDs should not mix the local memory 
> 64K
> + * page and the system memory 4K page bindings in the same 2M range.
>   *
>   * Error code -EINVAL will be returned if @start, @offset and @length are not
>   * properly aligned. In version 1 (See I915_PARAM_VM_BIND_VERSION), error 
> code
> diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c 
> b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
> index fa46d2308b0e..1bd0e041e15c 100644
> --- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
> +++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
> @@ -500,11 +500,11 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
>  }
>  
>  static void
> -xehpsdv_ppgtt_insert_huge(struct i915_address_space *vm,
> -   struct i915_vma_resource *vma_res,
> -   struct sgt_dma *iter,
> -   unsigned int pat_index,
> -   u32 flags)
> +xehp_ppgtt_insert_huge(struct i915_address_space *vm,
> +struct i915_vma_resource *vma_res,
> +struct sgt_dma *iter,
> +unsigned int pat_index,
> +u32 flags)
>  {
>   const gen8_pte_t pte_encode = vm->pte_encode(0, pat_index, flags);
>   unsigned int rem = sg_dma_len(iter->sg);
> @@ -741,8 +741,8 @@ static void gen8_ppgtt_insert(struct i915_address_space 
> *vm,
>   struct sgt_dma iter = sgt_dma(vma_res);
>  
>   if (vma_res->bi.page_sizes.sg > I915_GTT_PAGE_SIZE) {
> - 

[PATCH AUTOSEL 5.15 3/5] drm/amdgpu: Enable gpu reset for S3 abort cases on Raven series

2024-03-11 Thread Sasha Levin
From: Prike Liang 

[ Upstream commit c671ec01311b4744b377f98b0b4c6d033fe569b3 ]

Currently, GPU resets can now be performed successfully on the Raven
series. While GPU reset is required for the S3 suspend abort case.
So now can enable gpu reset for S3 abort cases on the Raven series.

Signed-off-by: Prike Liang 
Acked-by: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/soc15.c | 45 +-
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 6a3486f52d698..ef5b3eedc8615 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -605,11 +605,34 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
return AMD_RESET_METHOD_MODE1;
 }
 
+static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
+{
+   u32 sol_reg;
+
+   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
+
+   /* Will reset for the following suspend abort cases.
+* 1) Only reset limit on APU side, dGPU hasn't checked yet.
+* 2) S3 suspend abort and TOS already launched.
+*/
+   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
+   !adev->suspend_complete &&
+   sol_reg)
+   return true;
+
+   return false;
+}
+
 static int soc15_asic_reset(struct amdgpu_device *adev)
 {
/* original raven doesn't have full asic reset */
-   if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
-   (adev->apu_flags & AMD_APU_IS_RAVEN2))
+   /* On the latest Raven, the GPU reset can be performed
+* successfully. So now, temporarily enable it for the
+* S3 suspend abort case.
+*/
+   if (((adev->apu_flags & AMD_APU_IS_RAVEN) ||
+   (adev->apu_flags & AMD_APU_IS_RAVEN2)) &&
+   !soc15_need_reset_on_resume(adev))
return 0;
 
switch (soc15_asic_reset_method(adev)) {
@@ -1490,24 +1513,6 @@ static int soc15_common_suspend(void *handle)
return soc15_common_hw_fini(adev);
 }
 
-static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
-{
-   u32 sol_reg;
-
-   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
-
-   /* Will reset for the following suspend abort cases.
-* 1) Only reset limit on APU side, dGPU hasn't checked yet.
-* 2) S3 suspend abort and TOS already launched.
-*/
-   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
-   !adev->suspend_complete &&
-   sol_reg)
-   return true;
-
-   return false;
-}
-
 static int soc15_common_resume(void *handle)
 {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-- 
2.43.0



[PATCH AUTOSEL 6.1 08/13] drm/amdgpu: Enable gpu reset for S3 abort cases on Raven series

2024-03-11 Thread Sasha Levin
From: Prike Liang 

[ Upstream commit c671ec01311b4744b377f98b0b4c6d033fe569b3 ]

Currently, GPU resets can now be performed successfully on the Raven
series. While GPU reset is required for the S3 suspend abort case.
So now can enable gpu reset for S3 abort cases on the Raven series.

Signed-off-by: Prike Liang 
Acked-by: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/soc15.c | 45 +-
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 489c89465c78b..c373a2a3248eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -584,11 +584,34 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
return AMD_RESET_METHOD_MODE1;
 }
 
+static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
+{
+   u32 sol_reg;
+
+   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
+
+   /* Will reset for the following suspend abort cases.
+* 1) Only reset limit on APU side, dGPU hasn't checked yet.
+* 2) S3 suspend abort and TOS already launched.
+*/
+   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
+   !adev->suspend_complete &&
+   sol_reg)
+   return true;
+
+   return false;
+}
+
 static int soc15_asic_reset(struct amdgpu_device *adev)
 {
/* original raven doesn't have full asic reset */
-   if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
-   (adev->apu_flags & AMD_APU_IS_RAVEN2))
+   /* On the latest Raven, the GPU reset can be performed
+* successfully. So now, temporarily enable it for the
+* S3 suspend abort case.
+*/
+   if (((adev->apu_flags & AMD_APU_IS_RAVEN) ||
+   (adev->apu_flags & AMD_APU_IS_RAVEN2)) &&
+   !soc15_need_reset_on_resume(adev))
return 0;
 
switch (soc15_asic_reset_method(adev)) {
@@ -1285,24 +1308,6 @@ static int soc15_common_suspend(void *handle)
return soc15_common_hw_fini(adev);
 }
 
-static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
-{
-   u32 sol_reg;
-
-   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
-
-   /* Will reset for the following suspend abort cases.
-* 1) Only reset limit on APU side, dGPU hasn't checked yet.
-* 2) S3 suspend abort and TOS already launched.
-*/
-   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
-   !adev->suspend_complete &&
-   sol_reg)
-   return true;
-
-   return false;
-}
-
 static int soc15_common_resume(void *handle)
 {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-- 
2.43.0



[PATCH AUTOSEL 6.6 11/17] drm/amdgpu: Enable gpu reset for S3 abort cases on Raven series

2024-03-11 Thread Sasha Levin
From: Prike Liang 

[ Upstream commit c671ec01311b4744b377f98b0b4c6d033fe569b3 ]

Currently, GPU resets can now be performed successfully on the Raven
series. While GPU reset is required for the S3 suspend abort case.
So now can enable gpu reset for S3 abort cases on the Raven series.

Signed-off-by: Prike Liang 
Acked-by: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/soc15.c | 45 +-
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 2a7c606d1d191..a41ed67ea9fea 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -574,11 +574,34 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
return AMD_RESET_METHOD_MODE1;
 }
 
+static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
+{
+   u32 sol_reg;
+
+   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
+
+   /* Will reset for the following suspend abort cases.
+* 1) Only reset limit on APU side, dGPU hasn't checked yet.
+* 2) S3 suspend abort and TOS already launched.
+*/
+   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
+   !adev->suspend_complete &&
+   sol_reg)
+   return true;
+
+   return false;
+}
+
 static int soc15_asic_reset(struct amdgpu_device *adev)
 {
/* original raven doesn't have full asic reset */
-   if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
-   (adev->apu_flags & AMD_APU_IS_RAVEN2))
+   /* On the latest Raven, the GPU reset can be performed
+* successfully. So now, temporarily enable it for the
+* S3 suspend abort case.
+*/
+   if (((adev->apu_flags & AMD_APU_IS_RAVEN) ||
+   (adev->apu_flags & AMD_APU_IS_RAVEN2)) &&
+   !soc15_need_reset_on_resume(adev))
return 0;
 
switch (soc15_asic_reset_method(adev)) {
@@ -1296,24 +1319,6 @@ static int soc15_common_suspend(void *handle)
return soc15_common_hw_fini(adev);
 }
 
-static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
-{
-   u32 sol_reg;
-
-   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
-
-   /* Will reset for the following suspend abort cases.
-* 1) Only reset limit on APU side, dGPU hasn't checked yet.
-* 2) S3 suspend abort and TOS already launched.
-*/
-   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
-   !adev->suspend_complete &&
-   sol_reg)
-   return true;
-
-   return false;
-}
-
 static int soc15_common_resume(void *handle)
 {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-- 
2.43.0



[PATCH AUTOSEL 6.6 06/17] drm/ttm/tests: depend on UML || COMPILE_TEST

2024-03-11 Thread Sasha Levin
From: Christian König 

[ Upstream commit 9d3f8a723c7950e56e0b95ab84b572caee29e065 ]

At least the device test requires that no other driver using TTM is
loaded. So make those unit tests depend on UML || COMPILE_TEST to
prevent people from trying them on bare metal.

Signed-off-by: Christian König 
Acked-by: Alex Deucher 
Link: https://lore.kernel.org/all/20240219230116.77b8ad68@yea/
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 3caa020391c75..ec4abf9ff47b5 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -198,7 +198,7 @@ config DRM_TTM
 config DRM_TTM_KUNIT_TEST
 tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
 default n
-depends on DRM && KUNIT && MMU
+depends on DRM && KUNIT && MMU && (UML || COMPILE_TEST)
 select DRM_TTM
 select DRM_EXPORT_FOR_TESTS if m
 select DRM_KUNIT_TEST_HELPERS
@@ -206,7 +206,8 @@ config DRM_TTM_KUNIT_TEST
 help
   Enables unit tests for TTM, a GPU memory manager subsystem used
   to manage memory buffers. This option is mostly useful for kernel
-  developers.
+  developers. It depends on (UML || COMPILE_TEST) since no other driver
+  which uses TTM can be loaded while running the tests.
 
   If in doubt, say "N".
 
-- 
2.43.0



[PATCH AUTOSEL 6.7 17/23] drm/buddy: check range allocation matches alignment

2024-03-11 Thread Sasha Levin
From: Matthew Auld 

[ Upstream commit 2986314aa811c8a23aeb292edd30315495d54966 ]

Likely not a big deal for real users, but for consistency we should
respect the min_page_size here. Main issue is that bias allocations
turns into normal range allocation if the range and size matches
exactly, and in the next patch we want to add some unit tests for this
part of the api.

Signed-off-by: Matthew Auld 
Cc: Arunpravin Paneer Selvam 
Cc: Christian König 
Reviewed-by: Arunpravin Paneer Selvam 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20240219121851.25774-5-matthew.a...@intel.com
Signed-off-by: Christian König 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/drm_buddy.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index f3a6ac908f815..5ebdd6f8f36e6 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -771,8 +771,12 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
return -EINVAL;
 
/* Actual range allocation */
-   if (start + size == end)
+   if (start + size == end) {
+   if (!IS_ALIGNED(start | end, min_block_size))
+   return -EINVAL;
+
return __drm_buddy_alloc_range(mm, start, size, NULL, blocks);
+   }
 
original_size = size;
original_min_size = min_block_size;
-- 
2.43.0



[PATCH AUTOSEL 6.7 16/23] drm/amdgpu: Enable gpu reset for S3 abort cases on Raven series

2024-03-11 Thread Sasha Levin
From: Prike Liang 

[ Upstream commit c671ec01311b4744b377f98b0b4c6d033fe569b3 ]

Currently, GPU resets can now be performed successfully on the Raven
series. While GPU reset is required for the S3 suspend abort case.
So now can enable gpu reset for S3 abort cases on the Raven series.

Signed-off-by: Prike Liang 
Acked-by: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/soc15.c | 45 +-
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 9b5af3f1383a7..f9ba1803046d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -574,11 +574,34 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
return AMD_RESET_METHOD_MODE1;
 }
 
+static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
+{
+   u32 sol_reg;
+
+   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
+
+   /* Will reset for the following suspend abort cases.
+* 1) Only reset limit on APU side, dGPU hasn't checked yet.
+* 2) S3 suspend abort and TOS already launched.
+*/
+   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
+   !adev->suspend_complete &&
+   sol_reg)
+   return true;
+
+   return false;
+}
+
 static int soc15_asic_reset(struct amdgpu_device *adev)
 {
/* original raven doesn't have full asic reset */
-   if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
-   (adev->apu_flags & AMD_APU_IS_RAVEN2))
+   /* On the latest Raven, the GPU reset can be performed
+* successfully. So now, temporarily enable it for the
+* S3 suspend abort case.
+*/
+   if (((adev->apu_flags & AMD_APU_IS_RAVEN) ||
+   (adev->apu_flags & AMD_APU_IS_RAVEN2)) &&
+   !soc15_need_reset_on_resume(adev))
return 0;
 
switch (soc15_asic_reset_method(adev)) {
@@ -1297,24 +1320,6 @@ static int soc15_common_suspend(void *handle)
return soc15_common_hw_fini(adev);
 }
 
-static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
-{
-   u32 sol_reg;
-
-   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
-
-   /* Will reset for the following suspend abort cases.
-* 1) Only reset limit on APU side, dGPU hasn't checked yet.
-* 2) S3 suspend abort and TOS already launched.
-*/
-   if (adev->flags & AMD_IS_APU && adev->in_s3 &&
-   !adev->suspend_complete &&
-   sol_reg)
-   return true;
-
-   return false;
-}
-
 static int soc15_common_resume(void *handle)
 {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-- 
2.43.0



[PATCH AUTOSEL 6.7 11/23] drm/ttm/tests: depend on UML || COMPILE_TEST

2024-03-11 Thread Sasha Levin
From: Christian König 

[ Upstream commit 9d3f8a723c7950e56e0b95ab84b572caee29e065 ]

At least the device test requires that no other driver using TTM is
loaded. So make those unit tests depend on UML || COMPILE_TEST to
prevent people from trying them on bare metal.

Signed-off-by: Christian König 
Acked-by: Alex Deucher 
Link: https://lore.kernel.org/all/20240219230116.77b8ad68@yea/
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 3eee8636f847a..9b079f3a1b811 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -198,7 +198,7 @@ config DRM_TTM
 config DRM_TTM_KUNIT_TEST
 tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
 default n
-depends on DRM && KUNIT && MMU
+depends on DRM && KUNIT && MMU && (UML || COMPILE_TEST)
 select DRM_TTM
 select DRM_EXPORT_FOR_TESTS if m
 select DRM_KUNIT_TEST_HELPERS
@@ -206,7 +206,8 @@ config DRM_TTM_KUNIT_TEST
 help
   Enables unit tests for TTM, a GPU memory manager subsystem used
   to manage memory buffers. This option is mostly useful for kernel
-  developers.
+  developers. It depends on (UML || COMPILE_TEST) since no other driver
+  which uses TTM can be loaded while running the tests.
 
   If in doubt, say "N".
 
-- 
2.43.0



Re: [RFC PATCH v4 08/42] drm/doc/rfc: Describe why prescriptive color pipeline is needed

2024-03-11 Thread Pekka Paalanen
On Mon, 26 Feb 2024 16:10:22 -0500
Harry Wentland  wrote:

> v4:
>  - Drop IOCTL docs since we dropped the IOCTLs (Pekka)
>  - Clarify reading and setting of COLOR_PIPELINE prop (Pekka)
>  - Add blurb about not requiring to reject a pipeline due to
>incompatible ops, as long as op can be bypassed (Pekka)
>  - Dropped informational strings (such as input CSC) as they're
>not actually intended to be advertised (Pekka)
> 
> v3:
>  - Describe DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE (Sebastian)
>  - Ask for clear documentation of colorop behavior (Sebastian)
> 
> v2:
>  - Update colorop visualizations to match reality (Sebastian, Alex Hung)
>  - Updated wording (Pekka)
>  - Change BYPASS wording to make it non-mandatory (Sebastian)
>  - Drop cover-letter-like paragraph from COLOR_PIPELINE Plane Property
>section (Pekka)
>  - Use PQ EOTF instead of its inverse in Pipeline Programming example 
> (Melissa)
>  - Add "Driver Implementer's Guide" section (Pekka)
>  - Add "Driver Forward/Backward Compatibility" section (Sebastian, Pekka)
> 
> Signed-off-by: Harry Wentland 
> ---
>  Documentation/gpu/rfc/color_pipeline.rst | 360 +++
>  1 file changed, 360 insertions(+)
>  create mode 100644 Documentation/gpu/rfc/color_pipeline.rst
> 
> diff --git a/Documentation/gpu/rfc/color_pipeline.rst 
> b/Documentation/gpu/rfc/color_pipeline.rst
> new file mode 100644
> index ..6c653e17054a
> --- /dev/null
> +++ b/Documentation/gpu/rfc/color_pipeline.rst
> @@ -0,0 +1,360 @@
> +
> +Linux Color Pipeline API
> +
> +
> +What problem are we solving?
> +
> +
> +We would like to support pre-, and post-blending complex color
> +transformations in display controller hardware in order to allow for
> +HW-supported HDR use-cases, as well as to provide support to
> +color-managed applications, such as video or image editors.
> +
> +It is possible to support an HDR output on HW supporting the Colorspace
> +and HDR Metadata drm_connector properties, but that requires the
> +compositor or application to render and compose the content into one
> +final buffer intended for display. Doing so is costly.
> +
> +Most modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other
> +operations to support color transformations. These operations are often
> +implemented in fixed-function HW and therefore much more power efficient than
> +performing similar operations via shaders or CPU.
> +
> +We would like to make use of this HW functionality to support complex color
> +transformations with no, or minimal CPU or shader load.
> +
> +
> +How are other OSes solving this problem?
> +
> +
> +The most widely supported use-cases regard HDR content, whether video or
> +gaming.
> +
> +Most OSes will specify the source content format (color gamut, encoding 
> transfer
> +function, and other metadata, such as max and average light levels) to a 
> driver.
> +Drivers will then program their fixed-function HW accordingly to map from a
> +source content buffer's space to a display's space.
> +
> +When fixed-function HW is not available the compositor will assemble a 
> shader to
> +ask the GPU to perform the transformation from the source content format to 
> the
> +display's format.
> +
> +A compositor's mapping function and a driver's mapping function are usually
> +entirely separate concepts. On OSes where a HW vendor has no insight into
> +closed-source compositor code such a vendor will tune their color management
> +code to visually match the compositor's. On other OSes, where both mapping
> +functions are open to an implementer they will ensure both mappings match.
> +
> +This results in mapping algorithm lock-in, meaning that no-one alone can
> +experiment with or introduce new mapping algorithms and achieve
> +consistent results regardless of which implementation path is taken.
> +
> +Why is Linux different?
> +===
> +
> +Unlike other OSes, where there is one compositor for one or more drivers, on
> +Linux we have a many-to-many relationship. Many compositors; many drivers.
> +In addition each compositor vendor or community has their own view of how
> +color management should be done. This is what makes Linux so beautiful.
> +
> +This means that a HW vendor can now no longer tune their driver to one
> +compositor, as tuning it to one could make it look fairly different from
> +another compositor's color mapping.
> +
> +We need a better solution.
> +
> +
> +Descriptive API
> +===
> +
> +An API that describes the source and destination colorspaces is a descriptive
> +API. It describes the input and output color spaces but does not describe
> +how precisely they should be mapped. Such a mapping includes many minute
> +design decision that can greatly affect the look of the final result.
> +
> +It is not feasible to describe such mapping with enough detail to ensure the
>

[PATCH v2] drm/amdgpu: add ring buffer information in devcoredump

2024-03-11 Thread Sunil Khatri
Add relevant ringbuffer information such as
rptr, wptr,rb mask, ring name, ring size and also
the rings content for each ring on a gpu reset.

Signed-off-by: Sunil Khatri 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
index 6d059f853adc..a0dbccad2f53 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
@@ -215,6 +215,27 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, 
size_t count,
   fault_info->status);
}
 
+   drm_printf(&p, "Ring buffer information\n");
+   for (int i = 0; i < coredump->adev->num_rings; i++) {
+   int j = 0;
+   struct amdgpu_ring *ring = coredump->adev->rings[i];
+
+   drm_printf(&p, "ring name: %s\n", ring->name);
+   drm_printf(&p, "Rptr: 0x%llx Wptr: 0x%llx RB mask: %x\n",
+  amdgpu_ring_get_rptr(ring),
+  amdgpu_ring_get_wptr(ring),
+  ring->buf_mask);
+   drm_printf(&p, "Ring size in dwords: %d\n",
+  ring->ring_size / 4);
+   drm_printf(&p, "Ring contents\n");
+   drm_printf(&p, "Offset \t Value\n");
+
+   while (j < ring->ring_size) {
+   drm_printf(&p, "0x%x \t 0x%x\n", j, ring->ring[j/4]);
+   j += 4;
+   }
+   }
+
if (coredump->reset_vram_lost)
drm_printf(&p, "VRAM is lost due to GPU reset!\n");
if (coredump->adev->reset_info.num_regs) {
-- 
2.34.1



Re: [PATCH] Revert "drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue"

2024-03-11 Thread Boris Brezillon
On Mon, 11 Mar 2024 14:41:42 +
Liviu Dudau  wrote:

> On Mon, Mar 11, 2024 at 02:26:50PM +0200, Jani Nikula wrote:
> > On Mon, 11 Mar 2024, Boris Brezillon  wrote: 
> >  
> > > On Mon, 11 Mar 2024 13:51:46 +0200
> > > Jani Nikula  wrote:
> > >  
> > >> On Mon, 11 Mar 2024, Boris Brezillon  
> > >> wrote:  
> > >> > On Mon, 11 Mar 2024 13:16:19 +0200
> > >> > Jani Nikula  wrote:
> > >> >
> > >> >> This reverts commit 674dc7f61aefea81901c21402946074927e63f1a.
> > >> >> 
> > >> >> The commit causes a recursive dependency in kconfig:
> > >> >> 
> > >> >> drivers/iommu/Kconfig:14:error: recursive dependency detected!
> > >> >> drivers/iommu/Kconfig:14: symbol IOMMU_SUPPORT is selected by 
> > >> >> DRM_PANTHOR
> > >> >> drivers/gpu/drm/panthor/Kconfig:3:symbol DRM_PANTHOR depends on PM
> > >> >> kernel/power/Kconfig:183: symbol PM is selected by PM_SLEEP
> > >> >> kernel/power/Kconfig:117: symbol PM_SLEEP depends on 
> > >> >> HIBERNATE_CALLBACKS
> > >> >> kernel/power/Kconfig:35:  symbol HIBERNATE_CALLBACKS is selected 
> > >> >> by XEN_SAVE_RESTORE
> > >> >> arch/x86/xen/Kconfig:67:  symbol XEN_SAVE_RESTORE depends on XEN
> > >> >> arch/x86/xen/Kconfig:6:   symbol XEN depends on PARAVIRT
> > >> >> arch/x86/Kconfig:781: symbol PARAVIRT is selected by HYPERV
> > >> >> drivers/hv/Kconfig:5: symbol HYPERV depends on X86_LOCAL_APIC
> > >> >> arch/x86/Kconfig:1106:symbol X86_LOCAL_APIC depends on 
> > >> >> X86_UP_APIC
> > >> >> arch/x86/Kconfig:1081:symbol X86_UP_APIC prompt is visible 
> > >> >> depending on PCI_MSI
> > >> >> drivers/pci/Kconfig:39:   symbol PCI_MSI is selected by AMD_IOMMU
> > >> >> drivers/iommu/amd/Kconfig:3:  symbol AMD_IOMMU depends on 
> > >> >> IOMMU_SUPPORT
> > >> >> For a resolution refer to Documentation/kbuild/kconfig-language.rst
> > >> >> subsection "Kconfig recursive dependency limitations"
> > >> >> 
> > >> >> Fixes: 674dc7f61aef ("drm/panthor: Fix undefined 
> > >> >> panthor_device_suspend/resume symbol issue")
> > >> >> Cc: Boris Brezillon 
> > >> >> Cc: Liviu Dudau 
> > >> >> Cc: Steven Price 
> > >> >> Signed-off-by: Jani Nikula 
> > >> >
> > >> > Acked-by: Boris Brezillon 
> > >> 
> > >> Your suggestion select -> depends on IOMMU_SUPPORT seems to also work,
> > >> at least for me. Want to send a patch for that instead of me merging the
> > >> revert?  
> > >
> > > I replied on the other thread :-). I think we're better off reverting
> > > the faulty commit, so we can discuss how to fix the original issue
> > > properly without blocking the build.  
> > 
> > Thanks, pushed to drm-misc-next.  
> 
> So with this revert we're OK with an undefined symbol if !CONFIG_PM, but 
> we're not happy
> with a recursive dependency that is only triggered for COMPILE_TEST? I 
> would've thought
> IOMMU_SUPPORT options is a better one.

No worries, we have plenty of time to fix this. Just didn't want to
rush a fix before discussing it with you and Steve.


[PATCH v9 27/27] drm/sun4i: hdmi: Switch to HDMI connector

2024-03-11 Thread Maxime Ripard
The new HDMI connector infrastructure allows to remove some boilerplate,
especially to generate infoframes. Let's switch to it.

Reviewed-by: Jernej Skrabec 
Acked-by: Sui Jingfeng 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 80 ++
 1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index b7cf369b1906..8a9106a39f23 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -34,34 +34,28 @@
container_of_const(e, struct sun4i_hdmi, encoder)
 
 #define drm_connector_to_sun4i_hdmi(c) \
container_of_const(c, struct sun4i_hdmi, connector)
 
-static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
-  struct drm_display_mode *mode)
+static int sun4i_hdmi_write_infoframe(struct drm_connector *connector,
+ enum hdmi_infoframe_type type,
+ const u8 *buffer, size_t len)
 {
-   struct hdmi_avi_infoframe frame;
-   u8 buffer[17];
-   int i, ret;
+   struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+   int i;
 
-   ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
-  &hdmi->connector, mode);
-   if (ret < 0) {
-   DRM_ERROR("Failed to get infoframes from mode\n");
-   return ret;
+   if (type != HDMI_INFOFRAME_TYPE_AVI) {
+   drm_err(connector->dev,
+   "Unsupported infoframe type: %u\n", type);
+   return 0;
}
 
-   ret = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
-   if (ret < 0) {
-   DRM_ERROR("Failed to pack infoframes\n");
-   return ret;
-   }
-
-   for (i = 0; i < sizeof(buffer); i++)
+   for (i = 0; i < len; i++)
writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i));
 
return 0;
+
 }
 
 static void sun4i_hdmi_disable(struct drm_encoder *encoder,
   struct drm_atomic_state *state)
 {
@@ -80,18 +74,22 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder,
 static void sun4i_hdmi_enable(struct drm_encoder *encoder,
  struct drm_atomic_state *state)
 {
struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-   struct drm_display_info *display = &hdmi->connector.display_info;
+   struct drm_connector *connector = &hdmi->connector;
+   struct drm_display_info *display = &connector->display_info;
+   struct drm_connector_state *conn_state =
+   drm_atomic_get_new_connector_state(state, connector);
+   unsigned long long tmds_rate = conn_state->hdmi.tmds_char_rate;
unsigned int x, y;
u32 val = 0;
 
DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
 
-   clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
-   clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
+   clk_set_rate(hdmi->mod_clk, tmds_rate);
+   clk_set_rate(hdmi->tmds_clk, tmds_rate);
 
/* Set input sync enable */
writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC,
   hdmi->base + SUN4I_HDMI_UNKNOWN_REG);
 
@@ -140,11 +138,12 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 
writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
 
clk_prepare_enable(hdmi->tmds_clk);
 
-   sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
+   drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
+
val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
 
val = SUN4I_HDMI_VID_CTRL_ENABLE;
@@ -193,23 +192,26 @@ static int sun4i_hdmi_connector_atomic_check(struct 
drm_connector *connector,
struct drm_crtc_state *crtc_state = crtc->state;
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
enum drm_mode_status status;
 
status = sun4i_hdmi_connector_clock_valid(connector, mode,
- mode->clock * 1000);
+ 
conn_state->hdmi.tmds_char_rate);
if (status != MODE_OK)
return -EINVAL;
 
return 0;
 }
 
 static enum drm_mode_status
 sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   return sun4i_hdmi_connector_clock_valid(connector, mode,
-   mode->clock * 1000);
+   unsigned long long rate =
+   drm_connector_hdmi_compute_mode_clock(mode, 8,

[PATCH v9 25/27] drm/vc4: tests: Convert to plane creation helper

2024-03-11 Thread Maxime Ripard
Now that we have a plane create helper for kunit mocked drivers, let's
convert to it in vc4.

Reviewed-by: Maíra Canal 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 34 +++---
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c 
b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
index 973f5f929097..14357db82238 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
@@ -1,43 +1,25 @@
 // SPDX-License-Identifier: GPL-2.0
 
-#include 
-#include 
-#include 
+#include 
 #include 
 
 #include 
 
 #include "vc4_mock.h"
 
-static const struct drm_plane_helper_funcs vc4_dummy_plane_helper_funcs = {
-};
-
-static const struct drm_plane_funcs vc4_dummy_plane_funcs = {
-   .atomic_destroy_state   = drm_atomic_helper_plane_destroy_state,
-   .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
-   .reset  = drm_atomic_helper_plane_reset,
-};
-
-static const uint32_t vc4_dummy_plane_formats[] = {
-   DRM_FORMAT_XRGB,
-};
-
 struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
  enum drm_plane_type type)
 {
struct drm_plane *plane;
 
-   plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
-0,
-&vc4_dummy_plane_funcs,
-vc4_dummy_plane_formats,
-
ARRAY_SIZE(vc4_dummy_plane_formats),
-NULL,
-DRM_PLANE_TYPE_PRIMARY,
-NULL);
-   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
+   KUNIT_ASSERT_EQ(test, type, DRM_PLANE_TYPE_PRIMARY);
 
-   drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
+   plane = drm_kunit_helper_create_primary_plane(test, drm,
+ NULL,
+ NULL,
+ NULL, 0,
+ NULL);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
return plane;
 }

-- 
2.43.2



[PATCH v9 26/27] drm/rockchip: inno_hdmi: Switch to HDMI connector

2024-03-11 Thread Maxime Ripard
The new HDMI connector infrastructure allows to remove some boilerplate,
especially to generate infoframes. Let's switch to it.

Reviewed-by: Heiko Stuebner 
Acked-by: Heiko Stuebner 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/rockchip/inno_hdmi.c | 143 +--
 1 file changed, 52 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 1d2261643743..d59947679042 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -65,13 +65,11 @@ struct inno_hdmi {
const struct inno_hdmi_variant *variant;
 };
 
 struct inno_hdmi_connector_state {
struct drm_connector_state  base;
-   unsigned intenc_out_format;
unsigned intcolorimetry;
-   boolrgb_limited_range;
 };
 
 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
 {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
@@ -255,90 +253,53 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
 
inno_hdmi_standby(hdmi);
 }
 
-static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
-   enum hdmi_infoframe_type type)
+static int inno_hdmi_disable_frame(struct drm_connector *connector,
+  enum hdmi_infoframe_type type)
 {
-   struct drm_connector *connector = &hdmi->connector;
-
-   if (type != HDMI_INFOFRAME_TYPE_AVI) {
-   drm_err(connector->dev,
-   "Unsupported infoframe type: %u\n", type);
-   return;
-   }
-
-   hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
-}
-
-static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
- union hdmi_infoframe *frame, enum 
hdmi_infoframe_type type)
-{
-   struct drm_connector *connector = &hdmi->connector;
-   u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
-   ssize_t rc, i;
+   struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
 
if (type != HDMI_INFOFRAME_TYPE_AVI) {
drm_err(connector->dev,
"Unsupported infoframe type: %u\n", type);
return 0;
}
 
-   inno_hdmi_disable_frame(hdmi, type);
+   hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
 
-   rc = hdmi_infoframe_pack(frame, packed_frame,
-sizeof(packed_frame));
-   if (rc < 0)
-   return rc;
+   return 0;
+}
 
-   for (i = 0; i < rc; i++)
+static int inno_hdmi_upload_frame(struct drm_connector *connector,
+ enum hdmi_infoframe_type type,
+ const u8 *buffer, size_t len)
+{
+   struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
+   u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
+   ssize_t i;
+
+   if (type != HDMI_INFOFRAME_TYPE_AVI) {
+   drm_err(connector->dev,
+   "Unsupported infoframe type: %u\n", type);
+   return 0;
+   }
+
+   inno_hdmi_disable_frame(connector, type);
+
+   for (i = 0; i < len; i++)
hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
packed_frame[i]);
 
return 0;
 }
 
-static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
- struct drm_display_mode *mode)
-{
-   struct drm_connector *connector = &hdmi->connector;
-   struct drm_connector_state *conn_state = connector->state;
-   struct inno_hdmi_connector_state *inno_conn_state =
-   to_inno_hdmi_conn_state(conn_state);
-   union hdmi_infoframe frame;
-   int rc;
-
-   rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- &hdmi->connector,
- mode);
-   if (rc) {
-   inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
-   return rc;
-   }
-
-   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
-   frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
-   else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
-   frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
-   else
-   frame.avi.colorspace = HDMI_COLORSPACE_RGB;
-
-   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
-   drm_hdmi_avi_infoframe_quant_range(&frame.avi,
-  connector, mode,
-  
inno_conn_state->rgb_limited_range ?
-  
HDMI_QUANTIZATION_RANGE_LIMITED :
-

[PATCH v9 24/27] drm/vc4: tests: Remove vc4_dummy_plane structure

2024-03-11 Thread Maxime Ripard
The vc4_dummy_plane structure was introduced as a mean to add
mock-specific fields.

However, we never really used it and it's still strictly equivalent to
vc4_plane (which is in the same situation vs drm_plane), so we can
simply remove the vc4_dummy_plane structure and make the mock code
cleaner.

Reviewed-by: Maíra Canal 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/tests/vc4_mock.c   |  6 ++
 drivers/gpu/drm/vc4/tests/vc4_mock.h   |  9 ++---
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 14 +-
 3 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c 
b/drivers/gpu/drm/vc4/tests/vc4_mock.c
index becb3dbaa548..0731a7d85d7a 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c
@@ -107,20 +107,18 @@ static const struct vc4_mock_desc vc5_mock =
 );
 
 static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
const struct vc4_mock_pipe_desc *pipe)
 {
-   struct vc4_dummy_plane *dummy_plane;
struct drm_plane *plane;
struct vc4_dummy_crtc *dummy_crtc;
struct drm_crtc *crtc;
unsigned int i;
 
-   dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
-   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+   plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-   plane = &dummy_plane->plane.base;
dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
 
crtc = &dummy_crtc->crtc.base;
for (i = 0; i < pipe->noutputs; i++) {
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h 
b/drivers/gpu/drm/vc4/tests/vc4_mock.h
index 2d0b339bd9f3..002b6218960c 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.h
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h
@@ -19,17 +19,12 @@ struct drm_crtc *vc4_find_crtc_for_encoder(struct kunit 
*test,
return crtc;
 
return NULL;
 }
 
-struct vc4_dummy_plane {
-   struct vc4_plane plane;
-};
-
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
-   struct drm_device *drm,
-   enum drm_plane_type type);
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+ enum drm_plane_type type);
 
 struct vc4_dummy_crtc {
struct vc4_crtc crtc;
 };
 
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c 
b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
index 62b18f5f41db..973f5f929097 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
@@ -20,28 +20,24 @@ static const struct drm_plane_funcs vc4_dummy_plane_funcs = 
{
 
 static const uint32_t vc4_dummy_plane_formats[] = {
DRM_FORMAT_XRGB,
 };
 
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
-   struct drm_device *drm,
-   enum drm_plane_type type)
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+ enum drm_plane_type type)
 {
-   struct vc4_dummy_plane *dummy_plane;
struct drm_plane *plane;
 
-   dummy_plane = drmm_universal_plane_alloc(drm,
-struct vc4_dummy_plane, 
plane.base,
+   plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
 0,
 &vc4_dummy_plane_funcs,
 vc4_dummy_plane_formats,
 
ARRAY_SIZE(vc4_dummy_plane_formats),
 NULL,
 DRM_PLANE_TYPE_PRIMARY,
 NULL);
-   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-   plane = &dummy_plane->plane.base;
drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
 
-   return dummy_plane;
+   return plane;
 }

-- 
2.43.2



[PATCH v9 23/27] drm/vc4: hdmi: Switch to HDMI connector

2024-03-11 Thread Maxime Ripard
The new HDMI connector infrastructure allows us to remove a lot of
boilerplate, so let's switch to it.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 638 +
 drivers/gpu/drm/vc4/vc4_hdmi.h |  44 +--
 drivers/gpu/drm/vc4/vc4_hdmi_phy.c |   6 +-
 3 files changed, 86 insertions(+), 602 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 34f807ed1c31..1f489cbe0c90 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -108,29 +108,10 @@
 #define HSM_MIN_CLOCK_FREQ 12000
 #define CEC_CLOCK_FREQ 4
 
 #define HDMI_14_MAX_TMDS_CLK   (340 * 1000 * 1000)
 
-static const char * const output_format_str[] = {
-   [VC4_HDMI_OUTPUT_RGB]   = "RGB",
-   [VC4_HDMI_OUTPUT_YUV420]= "YUV 4:2:0",
-   [VC4_HDMI_OUTPUT_YUV422]= "YUV 4:2:2",
-   [VC4_HDMI_OUTPUT_YUV444]= "YUV 4:4:4",
-};
-
-static const char *vc4_hdmi_output_fmt_str(enum vc4_hdmi_output_format fmt)
-{
-   if (fmt >= ARRAY_SIZE(output_format_str))
-   return "invalid";
-
-   return output_format_str[fmt];
-}
-
-static unsigned long long
-vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
-   unsigned int bpc, enum 
vc4_hdmi_output_format fmt);
-
 static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
 {
struct drm_display_info *display = &vc4_hdmi->connector.display_info;
 
lockdep_assert_held(&vc4_hdmi->mutex);
@@ -145,32 +126,17 @@ static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi 
*vc4_hdmi)
return true;
 }
 
 static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
   unsigned int bpc,
-  enum vc4_hdmi_output_format fmt)
+  enum hdmi_colorspace fmt)
 {
-   unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, 
bpc, fmt);
+   unsigned long long clock = drm_connector_hdmi_compute_mode_clock(mode, 
bpc, fmt);
 
return clock > HDMI_14_MAX_TMDS_CLK;
 }
 
-static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi,
-  struct vc4_hdmi_connector_state *vc4_state)
-{
-   const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-   struct drm_display_info *display = &vc4_hdmi->connector.display_info;
-
-   if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED)
-   return false;
-   else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL)
-   return true;
-
-   return !display->is_hdmi ||
-   drm_default_rgb_quant_range(mode) == 
HDMI_QUANTIZATION_RANGE_FULL;
-}
-
 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
 {
struct drm_debugfs_entry *entry = m->private;
struct vc4_hdmi *vc4_hdmi = entry->file.data;
struct drm_device *drm = vc4_hdmi->connector.dev;
@@ -518,11 +484,11 @@ static int vc4_hdmi_connector_get_modes(struct 
drm_connector *connector)
if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) {
struct drm_device *drm = connector->dev;
const struct drm_display_mode *mode;
 
list_for_each_entry(mode, &connector->probed_modes, head) {
-   if (vc4_hdmi_mode_needs_scrambling(mode, 8, 
VC4_HDMI_OUTPUT_RGB)) {
+   if (vc4_hdmi_mode_needs_scrambling(mode, 8, 
HDMI_COLORSPACE_RGB)) {
drm_warn_once(drm, "The core clock cannot reach 
frequencies high enough to support 4k @ 60Hz.");
drm_warn_once(drm, "Please change your 
config.txt file to add hdmi_enable_4kp60.");
}
}
}
@@ -533,16 +499,12 @@ static int vc4_hdmi_connector_get_modes(struct 
drm_connector *connector)
 static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
   struct drm_atomic_state *state)
 {
struct drm_connector_state *old_state =
drm_atomic_get_old_connector_state(state, connector);
-   struct vc4_hdmi_connector_state *old_vc4_state =
-   conn_state_to_vc4_hdmi_conn_state(old_state);
struct drm_connector_state *new_state =
drm_atomic_get_new_connector_state(state, connector);
-   struct vc4_hdmi_connector_state *new_vc4_state =
-   conn_state_to_vc4_hdmi_conn_state(new_state);
struct drm_crtc *crtc = new_state->crtc;
 
if (!crtc)
return 0;
 
@@ -570,174 +532,62 @@ static int vc4_hdmi_connector_atomic_check(struct 
drm_connector *connector,
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret)
return ret;
}
 
-   if (old_state->color

[PATCH v9 22/27] drm/connector: hdmi: Create Infoframe DebugFS entries

2024-03-11 Thread Maxime Ripard
There has been some discussions recently about the infoframes sent by
drivers and if they were properly generated.

In parallel, there's been some interest in creating an infoframe-decode
tool similar to edid-decode.

Both would be much easier if we were to expose the infoframes programmed
in the hardware. It won't be perfect since we have no guarantee that
it's actually what goes through the wire, but it's the best we can do.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_debugfs.c | 110 ++
 1 file changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 08fcefd804bc..160389f3d84b 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -518,10 +518,118 @@ static const struct file_operations drm_connector_fops = 
{
.llseek = seq_lseek,
.release = single_release,
.write = connector_write
 };
 
+struct debugfs_wrapper {
+   struct drm_connector *connector;
+   struct drm_connector_hdmi_infoframe *frame;
+};
+
+#define HDMI_MAX_INFOFRAME_SIZE29
+
+static ssize_t
+infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t 
*ppos)
+{
+   const struct debugfs_wrapper *wrapper = filp->private_data;
+   struct drm_connector *connector = wrapper->connector;
+   struct drm_connector_hdmi_infoframe *infoframe = wrapper->frame;
+   union hdmi_infoframe *frame = &infoframe->data;
+   u8 buf[HDMI_MAX_INFOFRAME_SIZE];
+   ssize_t len = 0;
+
+   mutex_lock(&connector->hdmi.infoframes.lock);
+
+   if (!infoframe->set)
+   goto out;
+
+   len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
+   if (len < 0)
+   goto out;
+
+   len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+
+out:
+   mutex_unlock(&connector->hdmi.infoframes.lock);
+   return len;
+}
+
+static const struct file_operations infoframe_fops = {
+   .owner   = THIS_MODULE,
+   .open= simple_open,
+   .read= infoframe_read,
+};
+
+static int create_hdmi_infoframe_file(struct drm_connector *connector,
+ struct dentry *parent,
+ const char *filename,
+ struct drm_connector_hdmi_infoframe 
*frame)
+{
+   struct drm_device *dev = connector->dev;
+   struct debugfs_wrapper *wrapper;
+   struct dentry *file;
+
+   wrapper = drmm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
+   if (!wrapper)
+   return -ENOMEM;
+
+   wrapper->connector = connector;
+   wrapper->frame = frame;
+
+   file = debugfs_create_file(filename, 0400, parent, wrapper, 
&infoframe_fops);
+   if (IS_ERR(file))
+   return PTR_ERR(file);
+
+   return 0;
+}
+
+#define CREATE_HDMI_INFOFRAME_FILE(c, p, i)\
+   create_hdmi_infoframe_file(c, p, #i, &(c)->hdmi.infoframes.i)
+
+static int create_hdmi_infoframe_files(struct drm_connector *connector,
+  struct dentry *parent)
+{
+   int ret;
+
+   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, audio);
+   if (ret)
+   return ret;
+
+   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, avi);
+   if (ret)
+   return ret;
+
+   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdr_drm);
+   if (ret)
+   return ret;
+
+   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, spd);
+   if (ret)
+   return ret;
+
+   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdmi);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static void hdmi_debugfs_add(struct drm_connector *connector)
+{
+   struct dentry *dir;
+
+   if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector->connector_type == DRM_MODE_CONNECTOR_HDMIB))
+   return;
+
+   dir = debugfs_create_dir("infoframes", connector->debugfs_entry);
+   if (IS_ERR(dir))
+   return;
+
+   create_hdmi_infoframe_files(connector, dir);
+}
+
 void drm_debugfs_connector_add(struct drm_connector *connector)
 {
struct drm_device *dev = connector->dev;
struct dentry *root;
 
@@ -545,10 +653,12 @@ void drm_debugfs_connector_add(struct drm_connector 
*connector)
 
/* max bpc */
debugfs_create_file("output_bpc", 0444, root, connector,
&output_bpc_fops);
 
+   hdmi_debugfs_add(connector);
+
if (connector->funcs->debugfs_init)
connector->funcs->debugfs_init(connector, root);
 }
 
 void drm_debugfs_connector_remove(struct drm_connector *connector)

-- 
2.43.2



[PATCH v9 21/27] drm/tests: Add infoframes test

2024-03-11 Thread Maxime Ripard
The previous patch added the generation of the infoframes matching an
HDMI connector state. Let's add a few tests to make sure it works as
expected.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/tests/drm_connector_test.c | 219 +
 1 file changed, 219 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c 
b/drivers/gpu/drm/tests/drm_connector_test.c
index c3f7a3ba6808..fd64b2d2a60e 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -217,10 +217,221 @@ static void drm_test_connector_hdmi_init_null_ddc(struct 
kunit *test)
   BIT(HDMI_COLORSPACE_RGB),
   8);
KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
+/*
+ * Test that the registration of an HDMI connector with a NULL vendor
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  NULL, "Product",
+  &dummy_funcs,
+  &dummy_hdmi_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  &priv->ddc,
+  BIT(HDMI_COLORSPACE_RGB),
+  8);
+   KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with a NULL product
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  "Vendor", NULL,
+  &dummy_funcs,
+  &dummy_hdmi_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  &priv->ddc,
+  BIT(HDMI_COLORSPACE_RGB),
+  8);
+   KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a valid, shorter than
+ * the max length, product name succeeds, and is stored padded with 0.
+ */
+static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+   'P', 'r', 'o', 'd',
+   };
+   const char *product_name = "Prod";
+   int ret;
+
+   KUNIT_ASSERT_LT(test, strlen(product_name), 
DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  "Vendor", product_name,
+  &dummy_funcs,
+  &dummy_hdmi_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  &priv->ddc,
+  BIT(HDMI_COLORSPACE_RGB),
+  8);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+   KUNIT_EXPECT_MEMEQ(test,
+  priv->connector.hdmi.product,
+  expected_product,
+  sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registration of a connector with a valid, at max
+ * length, product name succeeds, and is stored padded without any
+ * trailing \0.
+ */
+static void drm_test_connector_hdmi_init_product_length_exact(struct kunit 
*test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+   'P', 'r', 'o', 'd', 'u', 'c', 't',
+   'P', 'r', 'o', 'd', 'u', 'c', 't',
+   'P', 'r',
+   };
+   const char *product_name = "ProductProductPr";
+   int ret;
+
+   KUNIT_ASSERT_EQ(test, strlen(product_name), 
DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  "Vendor", product_name,
+  &dummy_funcs,
+  &dummy_hdmi_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  &priv->ddc,
+  BIT(HDMI_COLORSPACE_RGB),
+  8);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+   KUNIT_EXPECT_MEMEQ(test,
+  priv->connector.hdmi.product,
+  expected_product,
+  sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registr

[PATCH v9 20/27] drm/connector: hdmi: Add Infoframes generation

2024-03-11 Thread Maxime Ripard
Infoframes in KMS is usually handled by a bunch of low-level helpers
that require quite some boilerplate for drivers. This leads to
discrepancies with how drivers generate them, and which are actually
sent.

Now that we have everything needed to generate them in the HDMI
connector state, we can generate them in our common logic so that
drivers can simply reuse what we precomputed.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/Kconfig|   1 +
 drivers/gpu/drm/drm_atomic_state_helper.c  | 323 +
 drivers/gpu/drm/drm_connector.c|  14 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |   1 +
 drivers/gpu/drm/tests/drm_connector_test.c |  12 +
 include/drm/drm_atomic_state_helper.h  |   8 +
 include/drm/drm_connector.h| 133 +
 7 files changed, 492 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 872edb47bb53..ad9c467e20ce 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -97,10 +97,11 @@ config DRM_KUNIT_TEST
  If in doubt, say "N".
 
 config DRM_KMS_HELPER
tristate
depends on DRM
+   select DRM_DISPLAY_HDMI_HELPER
help
  CRTC helpers for KMS drivers.
 
 config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
 bool "Enable refcount backtrace history in the DP MST helpers"
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index e66272c0d006..2bf53666fc9d 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -36,10 +36,12 @@
 #include 
 #include 
 #include 
 #include 
 
+#include 
+
 #include 
 #include 
 
 /**
  * DOC: atomic state reset and initialization
@@ -912,10 +914,143 @@ hdmi_compute_config(const struct drm_connector 
*connector,
}
 
return -EINVAL;
 }
 
+static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
+  struct drm_connector_state *state)
+{
+   const struct drm_display_mode *mode =
+   connector_state_get_mode(state);
+   struct drm_connector_hdmi_infoframe *infoframe =
+   &state->hdmi.infoframes.avi;
+   struct hdmi_avi_infoframe *frame =
+   &infoframe->data.avi;
+   bool is_full_range = state->hdmi.is_full_range;
+   enum hdmi_quantization_range rgb_quant_range =
+   is_full_range ? HDMI_QUANTIZATION_RANGE_FULL : 
HDMI_QUANTIZATION_RANGE_LIMITED;
+   int ret;
+
+   ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);
+   if (ret)
+   return ret;
+
+   frame->colorspace = state->hdmi.output_format;
+
+   drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, 
rgb_quant_range);
+   drm_hdmi_avi_infoframe_colorimetry(frame, state);
+   drm_hdmi_avi_infoframe_bars(frame, state);
+
+   infoframe->set = true;
+
+   return 0;
+}
+
+static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
+  struct drm_connector_state *state)
+{
+   struct drm_connector_hdmi_infoframe *infoframe =
+   &state->hdmi.infoframes.spd;
+   struct hdmi_spd_infoframe *frame =
+   &infoframe->data.spd;
+   int ret;
+
+   ret = hdmi_spd_infoframe_init(frame,
+ connector->hdmi.vendor,
+ connector->hdmi.product);
+   if (ret)
+   return ret;
+
+   frame->sdi = HDMI_SPD_SDI_PC;
+
+   infoframe->set = true;
+
+   return 0;
+}
+
+static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
+  struct drm_connector_state *state)
+{
+   struct drm_connector_hdmi_infoframe *infoframe =
+   &state->hdmi.infoframes.hdr_drm;
+   struct hdmi_drm_infoframe *frame =
+   &infoframe->data.drm;
+   int ret;
+
+   if (connector->max_bpc < 10)
+   return 0;
+
+   if (!state->hdr_output_metadata)
+   return 0;
+
+   ret = drm_hdmi_infoframe_set_hdr_metadata(frame, state);
+   if (ret)
+   return ret;
+
+   infoframe->set = true;
+
+   return 0;
+}
+
+static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector 
*connector,
+  struct drm_connector_state 
*state)
+{
+   const struct drm_display_info *info = &connector->display_info;
+   const struct drm_display_mode *mode =
+   connector_state_get_mode(state);
+   struct drm_connector_hdmi_infoframe *infoframe =
+   &state->hdmi.infoframes.hdmi;
+   struct hdmi_vendor_infoframe *frame =
+   &infoframe->data.vendor.hdmi;
+   int ret;
+
+   if (!info->has_hdmi_infoframe)
+   return 0;
+
+   ret = drm

[PATCH v9 19/27] drm/tests: Add RGB Quantization tests

2024-03-11 Thread Maxime Ripard
The previous commit added the infrastructure to the connector state to
track what RGB Quantization should be used in a given state for an HDMI
connector.

Let's add some kunit tests to make sure it works as expected.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 563 +
 1 file changed, 563 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 3de15cec2f5f..dcc0f7486f49 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -350,10 +350,564 @@ static void 
drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a mode that isn't the
+ * VIC-1 mode, we will get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *conn_state;
+   struct drm_atomic_state *state;
+   struct drm_display_mode *preferred;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+8);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   conn = &priv->connector;
+   KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+   KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+   conn_state = drm_atomic_get_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+   KUNIT_ASSERT_EQ(test,
+   conn_state->hdmi.broadcast_rgb,
+   DRM_HDMI_BROADCAST_RGB_AUTO);
+
+   ret = drm_atomic_check_only(state);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   conn_state = drm_atomic_get_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+   KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
+ * a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit 
*test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *conn_state;
+   struct drm_atomic_state *state;
+   struct drm_display_mode *mode;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+8);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   conn = &priv->connector;
+   KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   mode = drm_display_mode_from_cea_vic(drm, 1);
+   KUNIT_ASSERT_NOT_NULL(test, mode);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+   conn_state = drm_atomic_get_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+   KUNIT_ASSERT_EQ(test,
+   conn_state->hdmi.broadcast_rgb,
+   DRM_HDMI_BROADCAST_RGB_AUTO);
+
+   ret = drm_atomic_check_only(state);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   conn_state = drm_atomic_get_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+   KUNIT_EXPECT_TRUE(test,

[PATCH v9 16/27] drm/connector: hdmi: Add Broadcast RGB property

2024-03-11 Thread Maxime Ripard
The i915 driver has a property to force the RGB range of an HDMI output.
The vc4 driver then implemented the same property with the same
semantics. KWin has support for it, and a PR for mutter is also there to
support it.

Both drivers implementing the same property with the same semantics,
plus the userspace having support for it, is proof enough that it's
pretty much a de-facto standard now and we can provide helpers for it.

Let's plumb it into the newly created HDMI connector.

Reviewed-by: Dave Stevenson 
Acked-by: Pekka Paalanen 
Reviewed-by: Sebastian Wick 
Signed-off-by: Maxime Ripard 
---
 Documentation/gpu/kms-properties.csv  |  1 -
 drivers/gpu/drm/drm_atomic.c  |  2 +
 drivers/gpu/drm/drm_atomic_state_helper.c |  4 +-
 drivers/gpu/drm/drm_atomic_uapi.c |  4 ++
 drivers/gpu/drm/drm_connector.c   | 88 +++
 include/drm/drm_connector.h   | 36 +
 6 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/Documentation/gpu/kms-properties.csv 
b/Documentation/gpu/kms-properties.csv
index 0f9590834829..caef14c532d4 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -15,11 +15,10 @@ Owner Module/Drivers,Group,Property Name,Type,Property 
Values,Object attached,De
 ,,“saturation”,RANGE,"Min=0, Max=100",Connector,TBD
 ,,“hue”,RANGE,"Min=0, Max=100",Connector,TBD
 ,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0x",Connector,property to 
suggest an X offset for a connector
 ,,“suggested Y”,RANGE,"Min=0, Max=0x",Connector,property to suggest an 
Y offset for a connector
 ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" 
}",Connector,TDB
-i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 
16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is 
set, the hardware will be programmed with the result of the multiplication of 
CTM by the limited range matrix to ensure the pixels normally in the range 
0..1.0 are remapped to the range 16/255..235/255."
 ,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
 ,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } 
etc.",Connector,TBD
 ,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
 ,,"""right_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
 ,,"""top_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 26f9e525c0a0..3e57d98d8418 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1143,10 +1143,12 @@ static void drm_atomic_connector_print_state(struct 
drm_printer *p,
drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
drm_printf(p, "\tcolorspace=%s\n", 
drm_get_colorspace_name(state->colorspace));
 
if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+   drm_printf(p, "\tbroadcast_rgb=%s\n",
+  
drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
drm_printf(p, "\toutput_format=%s\n",
   
drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
drm_printf(p, "\ttmds_char_rate=%llu\n", 
state->hdmi.tmds_char_rate);
}
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 9f517599f117..0e8fb653965a 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -587,10 +587,11 @@ void __drm_atomic_helper_connector_hdmi_reset(struct 
drm_connector *connector,
 {
unsigned int max_bpc = connector->max_bpc;
 
new_state->max_bpc = max_bpc;
new_state->max_requested_bpc = max_bpc;
+   new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
 
 /**
  * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
@@ -911,11 +912,12 @@ int drm_atomic_helper_connector_hdmi_check(struct 
drm_connector *connector,
 
ret = hdmi_compute_config(connector, new_state, mode);
if (ret)
return ret;
 
-   if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
+   if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
+   old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
old_state->hdmi.output_format != new_state->hdmi.output_format) {
struct drm_crtc *crtc = new_state->crtc;
struct drm_crtc_state *crtc_state;
 
crtc_state = drm_atomic_get_crtc_state(state, crtc);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_u

[PATCH v9 18/27] drm/connector: hdmi: Add RGB Quantization Range to the connector state

2024-03-11 Thread Maxime Ripard
HDMI controller drivers will need to figure out the RGB range they need
to configure based on a mode and property values. Let's expose that in
the HDMI connector state so drivers can just use that value.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_atomic.c  |  1 +
 drivers/gpu/drm/drm_atomic_state_helper.c | 29 +
 include/drm/drm_connector.h   |  6 ++
 3 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3e57d98d8418..ec6c6beda5c9 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1145,10 +1145,11 @@ static void drm_atomic_connector_print_state(struct 
drm_printer *p,
 
if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
drm_printf(p, "\tbroadcast_rgb=%s\n",
   
drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
+   drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range 
? 'y' : 'n');
drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
drm_printf(p, "\toutput_format=%s\n",
   
drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
drm_printf(p, "\ttmds_char_rate=%llu\n", 
state->hdmi.tmds_char_rate);
}
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 0e8fb653965a..e66272c0d006 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -662,10 +662,37 @@ connector_state_get_mode(const struct drm_connector_state 
*conn_state)
return NULL;
 
return &crtc_state->mode;
 }
 
+static bool hdmi_is_full_range(const struct drm_connector *connector,
+  const struct drm_connector_state *state)
+{
+   const struct drm_display_info *display = &connector->display_info;
+   const struct drm_display_mode *mode =
+   connector_state_get_mode(state);
+
+   /*
+* The Broadcast RGB property only applies to RGB format, and
+* i915 just assumes limited range for YCbCr output, so let's
+* just do the same.
+*/
+   if (state->hdmi.output_format != HDMI_COLORSPACE_RGB)
+   return false;
+
+   if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL)
+   return true;
+
+   if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
+   return false;
+
+   if (!display->is_hdmi)
+   return true;
+
+   return drm_default_rgb_quant_range(mode) == 
HDMI_QUANTIZATION_RANGE_FULL ? true : false;
+}
+
 static bool
 sink_supports_format_bpc(const struct drm_connector *connector,
 const struct drm_display_info *info,
 const struct drm_display_mode *mode,
 unsigned int format, unsigned int bpc)
@@ -908,10 +935,12 @@ int drm_atomic_helper_connector_hdmi_check(struct 
drm_connector *connector,
drm_atomic_get_new_connector_state(state, connector);
const struct drm_display_mode *mode =
connector_state_get_mode(new_state);
int ret;
 
+   new_state->hdmi.is_full_range = hdmi_is_full_range(connector, 
new_state);
+
ret = hdmi_compute_config(connector, new_state, mode);
if (ret)
return ret;
 
if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index bb6b6a36ade3..3eaf4d54364d 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1068,10 +1068,16 @@ struct drm_connector_state {
 * @broadcast_rgb: Connector property to pass the
 * Broadcast RGB selection value.
 */
enum drm_hdmi_broadcast_rgb broadcast_rgb;
 
+   /**
+* @is_full_range: Is the output supposed to use a full
+* RGB Quantization Range or not?
+*/
+   bool is_full_range;
+
/**
 * @output_bpc: Bits per color channel to output.
 */
unsigned int output_bpc;
 

-- 
2.43.2



[PATCH v9 15/27] drm/tests: Add HDMI connector bpc and format tests

2024-03-11 Thread Maxime Ripard
The previous patch added the bpc and format an HDMI connector needs to
be set up with for a given connector state.

Let's add a few tests to make sure it works as expected.

Signed-off-by: Maxime Ripard 
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 504 +
 drivers/gpu/drm/tests/drm_kunit_edid.h | 160 +++
 2 files changed, 664 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index f010fde0eb69..c0f26422e925 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -368,10 +368,60 @@ static void 
drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that if we have an HDMI connector but a !HDMI display, we always
+ * output RGB with 8 bpc.
+ */
+static void drm_test_check_output_bpc_dvi(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *conn_state;
+   struct drm_display_info *info;
+   struct drm_display_mode *preferred;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB) |
+
BIT(HDMI_COLORSPACE_YUV422) |
+
BIT(HDMI_COLORSPACE_YUV444),
+12);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   conn = &priv->connector;
+   ret = set_connector_edid(test, conn,
+test_edid_dvi_1080p,
+ARRAY_SIZE(test_edid_dvi_1080p));
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   info = &conn->display_info;
+   KUNIT_ASSERT_FALSE(test, info->is_hdmi);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   conn_state = conn->state;
+   KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+   KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+   KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 
HDMI_COLORSPACE_RGB);
+}
+
 /*
  * Test that when doing a commit which would use RGB 8bpc, the TMDS
  * clock rate stored in the connector state is equal to the mode clock
  */
 static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
@@ -560,14 +610,468 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct 
kunit *test)
 
ret = drm_atomic_check_only(state);
KUNIT_EXPECT_LT(test, ret, 0);
 }
 
+/*
+ * Test that if:
+ * - We have an HDMI connector supporting RGB only
+ * - The chosen mode has a TMDS character rate higher than the display
+ *   supports in RGB/12bpc
+ * - The chosen mode has a TMDS character rate lower than the display
+ *   supports in RGB/10bpc.
+ *
+ * Then we will pick the latter, and the computed TMDS character rate
+ * will be equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *conn_state;
+   struct drm_display_info *info;
+   struct drm_display_mode *preferred;
+   unsigned long long rate;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+12);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   conn = &priv->connector;
+   ret = set_connector_edid(test, conn,
+test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+
ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   info = &conn->display_info;
+   KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+   KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+   KUNIT

[PATCH v9 17/27] drm/tests: Add tests for Broadcast RGB property

2024-03-11 Thread Maxime Ripard
This had a bunch of kunit tests to make sure our code to handle the
Broadcast RGB property behaves properly.

This requires bringing a bit of infrastructure to create mock HDMI
connectors, with custom EDIDs.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 151 +
 drivers/gpu/drm/tests/drm_connector_test.c | 116 
 2 files changed, 267 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index c0f26422e925..3de15cec2f5f 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -222,10 +222,138 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
KUNIT_ASSERT_EQ(test, ret, 0);
 
return priv;
 }
 
+/*
+ * Test that if we change the RGB quantization property to a different
+ * value, we trigger a mode change on the connector's CRTC, which will
+ * in turn disable/enable the connector.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *old_conn_state;
+   struct drm_connector_state *new_conn_state;
+   struct drm_crtc_state *crtc_state;
+   struct drm_atomic_state *state;
+   struct drm_display_mode *preferred;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+8);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   conn = &priv->connector;
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+   new_conn_state = drm_atomic_get_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+   new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+   KUNIT_ASSERT_NE(test,
+   old_conn_state->hdmi.broadcast_rgb,
+   new_conn_state->hdmi.broadcast_rgb);
+
+   ret = drm_atomic_check_only(state);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+   KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, 
DRM_HDMI_BROADCAST_RGB_FULL);
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+   KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we set the RGB quantization property to the same value,
+ * we don't trigger a mode change on the connector's CRTC and leave the
+ * connector unaffected.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit 
*test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *old_conn_state;
+   struct drm_connector_state *new_conn_state;
+   struct drm_crtc_state *crtc_state;
+   struct drm_atomic_state *state;
+   struct drm_display_mode *preferred;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+8);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   conn = &priv->connector;
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+   new_conn_state = drm_atomic_get_connector_state(state, conn);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_con

[PATCH v9 14/27] drm/connector: hdmi: Compute bpc and format automatically

2024-03-11 Thread Maxime Ripard
Now that we have all the infrastructure needed, we can add some code
that will, for a given connector state and mode, compute the best output
format and bpc.

The algorithm is equivalent to the one already found in i915 and vc4.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_atomic_state_helper.c  | 184 -
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  25 ++-
 2 files changed, 197 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 448b4a73d1c8..9f517599f117 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -29,10 +29,11 @@
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
@@ -660,10 +661,100 @@ connector_state_get_mode(const struct 
drm_connector_state *conn_state)
return NULL;
 
return &crtc_state->mode;
 }
 
+static bool
+sink_supports_format_bpc(const struct drm_connector *connector,
+const struct drm_display_info *info,
+const struct drm_display_mode *mode,
+unsigned int format, unsigned int bpc)
+{
+   struct drm_device *dev = connector->dev;
+   u8 vic = drm_match_cea_mode(mode);
+
+   if (vic == 1 && bpc != 8) {
+   drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
+   return false;
+   }
+
+   if (!info->is_hdmi &&
+   (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
+   drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
+   return false;
+   }
+
+   if (!(connector->hdmi.supported_formats & BIT(format))) {
+   drm_dbg(dev, "%s format unsupported by the connector.\n",
+   drm_hdmi_connector_get_output_format_name(format));
+   return false;
+   }
+
+   switch (format) {
+   case HDMI_COLORSPACE_RGB:
+   drm_dbg(dev, "RGB Format, checking the constraints.\n");
+
+   if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
+   return false;
+
+   if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & 
DRM_EDID_HDMI_DC_30)) {
+   drm_dbg(dev, "10 BPC but sink doesn't support Deep 
Color 30.\n");
+   return false;
+   }
+
+   if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & 
DRM_EDID_HDMI_DC_36)) {
+   drm_dbg(dev, "12 BPC but sink doesn't support Deep 
Color 36.\n");
+   return false;
+   }
+
+   drm_dbg(dev, "RGB format supported in that configuration.\n");
+
+   return true;
+
+   case HDMI_COLORSPACE_YUV422:
+   drm_dbg(dev, "YUV422 format, checking the constraints.\n");
+
+   if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+   drm_dbg(dev, "Sink doesn't support YUV422.\n");
+   return false;
+   }
+
+   if (bpc != 12) {
+   drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
+   return false;
+   }
+
+   drm_dbg(dev, "YUV422 format supported in that 
configuration.\n");
+
+   return true;
+
+   case HDMI_COLORSPACE_YUV444:
+   drm_dbg(dev, "YUV444 format, checking the constraints.\n");
+
+   if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
+   drm_dbg(dev, "Sink doesn't support YUV444.\n");
+   return false;
+   }
+
+   if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & 
DRM_EDID_HDMI_DC_30)) {
+   drm_dbg(dev, "10 BPC but sink doesn't support Deep 
Color 30.\n");
+   return false;
+   }
+
+   if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & 
DRM_EDID_HDMI_DC_36)) {
+   drm_dbg(dev, "12 BPC but sink doesn't support Deep 
Color 36.\n");
+   return false;
+   }
+
+   drm_dbg(dev, "YUV444 format supported in that 
configuration.\n");
+
+   return true;
+   }
+
+   return false;
+}
+
 static enum drm_mode_status
 hdmi_clock_valid(const struct drm_connector *connector,
 const struct drm_display_mode *mode,
 unsigned long long clock)
 {
@@ -704,10 +795,99 @@ hdmi_compute_clock(const struct drm_connector *connector,
state->hdmi.tmds_char_rate = clock;
 
return 0;
 }
 
+static bool
+hdmi_try_format_bpc(const struct drm_connector *connector,
+   struct drm_connector_state *state,
+   const struct drm_display_mode *mode,
+   unsigned int bpc, enum hdmi_colorspace fmt)
+{
+   const struct drm_

[PATCH v9 12/27] drm/connector: hdmi: Add custom hook to filter TMDS character rate

2024-03-11 Thread Maxime Ripard
Most of the HDMI controllers have an upper TMDS character rate limit
they can't exceed. On "embedded"-grade display controllers, it will
typically be lower than what high-grade monitors can provide these days,
so drivers will filter the TMDS character rate based on the controller
capabilities.

To make that easier to handle for drivers, let's provide an optional
hook to be implemented by drivers so they can tell the HDMI controller
helpers if a given TMDS character rate is reachable for them or not.

This will then be useful to figure out the best format and bpc count for
a given mode.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_atomic_state_helper.c  |  9 +++
 drivers/gpu/drm/drm_connector.c|  4 +++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  4 +++
 drivers/gpu/drm/tests/drm_connector_test.c | 14 ++
 include/drm/drm_connector.h| 30 ++
 5 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 63a96c691460..448b4a73d1c8 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -665,15 +665,24 @@ connector_state_get_mode(const struct drm_connector_state 
*conn_state)
 static enum drm_mode_status
 hdmi_clock_valid(const struct drm_connector *connector,
 const struct drm_display_mode *mode,
 unsigned long long clock)
 {
+   const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
const struct drm_display_info *info = &connector->display_info;
 
if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
return MODE_CLOCK_HIGH;
 
+   if (funcs && funcs->tmds_char_rate_valid) {
+   enum drm_mode_status status;
+
+   status = funcs->tmds_char_rate_valid(connector, mode, clock);
+   if (status != MODE_OK)
+   return status;
+   }
+
return MODE_OK;
 }
 
 static int
 hdmi_compute_clock(const struct drm_connector *connector,
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8cc1332f11c2..591d2d500f61 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -455,10 +455,11 @@ EXPORT_SYMBOL(drmm_connector_init);
 /**
  * drmm_connector_hdmi_init - Init a preallocated HDMI connector
  * @dev: DRM device
  * @connector: A pointer to the HDMI connector to init
  * @funcs: callbacks for this connector
+ * @hdmi_funcs: HDMI-related callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
  * @supported_formats: Bitmask of @hdmi_colorspace listing supported output 
formats
  * @max_bpc: Maximum bits per char the HDMI connector supports
  *
@@ -474,10 +475,11 @@ EXPORT_SYMBOL(drmm_connector_init);
  * Zero on success, error code on failure.
  */
 int drmm_connector_hdmi_init(struct drm_device *dev,
 struct drm_connector *connector,
 const struct drm_connector_funcs *funcs,
+const struct drm_connector_hdmi_funcs *hdmi_funcs,
 int connector_type,
 struct i2c_adapter *ddc,
 unsigned long supported_formats,
 unsigned int max_bpc)
 {
@@ -510,10 +512,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
connector->max_bpc = max_bpc;
 
if (max_bpc > 8)
drm_connector_attach_hdr_output_metadata_property(connector);
 
+   connector->hdmi.funcs = hdmi_funcs;
+
return 0;
 }
 EXPORT_SYMBOL(drmm_connector_hdmi_init);
 
 /**
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index dfed45b250a5..989661ad3aee 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -108,10 +108,13 @@ static int set_connector_edid(struct kunit *test, struct 
drm_connector *connecto
KUNIT_ASSERT_GT(test, ret, 0);
 
return 0;
 }
 
+static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
+};
+
 static int dummy_connector_get_modes(struct drm_connector *connector)
 {
struct drm_atomic_helper_connector_hdmi_priv *priv =
connector_to_priv(connector);
const struct drm_edid *edid;
@@ -190,10 +193,11 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
enc->possible_crtcs = drm_crtc_mask(priv->crtc);
 
conn = &priv->connector;
ret = drmm_connector_hdmi_init(drm, conn,
   &dummy_connector_funcs,
+  &dummy_connector_hdmi_funcs,
   

[PATCH v9 13/27] drm/tests: Add HDMI connector rate filter hook tests

2024-03-11 Thread Maxime Ripard
The previous patch adds a new hook for HDMI connectors to filter out
configurations based on the TMDS character rate. Let's add some tests to
make sure it works as expected.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 65 ++
 1 file changed, 65 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 989661ad3aee..5a8750153510 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -111,10 +111,22 @@ static int set_connector_edid(struct kunit *test, struct 
drm_connector *connecto
 }
 
 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
 };
 
+static enum drm_mode_status
+reject_connector_tmds_char_rate_valid(const struct drm_connector *connector,
+  const struct drm_display_mode *mode,
+  unsigned long long tmds_rate)
+{
+   return MODE_BAD;
+}
+
+static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
+   .tmds_char_rate_valid   = reject_connector_tmds_char_rate_valid,
+};
+
 static int dummy_connector_get_modes(struct drm_connector *connector)
 {
struct drm_atomic_helper_connector_hdmi_priv *priv =
connector_to_priv(connector);
const struct drm_edid *edid;
@@ -489,11 +501,64 @@ static void 
drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, 
HDMI_COLORSPACE_RGB);
KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock 
* 1500);
 }
 
+/*
+ * Test that if we filter a rate through our hook, it's indeed rejected
+ * by the whole atomic_check logic.
+ *
+ * We do so by first doing a commit on the pipeline to make sure that it
+ * works, change the HDMI helpers pointer, and then try the same commit
+ * again to see if it fails as it should.
+ */
+static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_atomic_state *state;
+   struct drm_display_mode *preferred;
+   struct drm_crtc_state *crtc_state;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+8);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   conn = &priv->connector;
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   /* You shouldn't be doing that at home. */
+   conn->hdmi.funcs = &reject_connector_hdmi_funcs;
+
+   state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+   crtc_state = drm_atomic_get_crtc_state(state, crtc);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+   crtc_state->connectors_changed = true;
+
+   ret = drm_atomic_check_only(state);
+   KUNIT_EXPECT_LT(test, ret, 0);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+   KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),

-- 
2.43.2



[PATCH v9 11/27] drm/tests: Add TDMS character rate connector state tests

2024-03-11 Thread Maxime Ripard
The previous patch stores in the connector state the expected TMDS
character rate matching the configuration of the HDMI connector. Let's
add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 166 
 drivers/gpu/drm/tests/drm_kunit_edid.h | 216 +
 2 files changed, 382 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index f2acbd4c216c..dfed45b250a5 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -345,13 +345,156 @@ static void 
drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that when doing a commit which would use RGB 8bpc, the TMDS
+ * clock rate stored in the connector state is equal to the mode clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *conn_state;
+   struct drm_display_mode *preferred;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+8);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   conn = &priv->connector;
+   ret = set_connector_edid(test, conn,
+test_edid_hdmi_1080p_rgb_max_200mhz,
+
ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+   KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   conn_state = conn->state;
+   KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+   KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
+   KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, 
HDMI_COLORSPACE_RGB);
+   KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock 
* 1000);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 10bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.25 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_modeset_acquire_ctx *ctx;
+   struct drm_connector_state *conn_state;
+   struct drm_display_mode *preferred;
+   struct drm_connector *conn;
+   struct drm_device *drm;
+   struct drm_crtc *crtc;
+   int ret;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB),
+10);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   conn = &priv->connector;
+   ret = set_connector_edid(test, conn,
+test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+
ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+   preferred = find_preferred_mode(conn);
+   KUNIT_ASSERT_NOT_NULL(test, preferred);
+   KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+   drm = &priv->drm;
+   crtc = priv->crtc;
+   ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   conn_state = conn->state;
+   KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+   KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
+   KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, 
HDMI_COLORSPACE_RGB);
+   KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock 
* 1250);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 12bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.5 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_h

[PATCH v9 09/27] drm/tests: Add HDMI TDMS character rate tests

2024-03-11 Thread Maxime Ripard
The previous patch added an helper to compute the TMDS character rate on
an HDMI connector. Let's add a few tests to make sure it works as
expected.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/tests/drm_connector_test.c | 323 +
 1 file changed, 323 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c 
b/drivers/gpu/drm/tests/drm_connector_test.c
index 72f22ec951d6..4d1ac744a844 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -6,11 +6,13 @@
 #include 
 
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #include 
 
 #include "../drm_crtc_internal.h"
 
@@ -604,13 +606,334 @@ static struct kunit_case 
drm_hdmi_connector_get_output_format_name_tests[] = {
 static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite 
= {
.name = "drm_hdmi_connector_get_output_format_name",
.test_cases = drm_hdmi_connector_get_output_format_name_tests,
 };
 
+/*
+ * Test that for a given mode, with 8bpc and an RGB output the TMDS
+ * character rate is equal to the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb(struct kunit 
*test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const struct drm_display_mode *mode;
+   unsigned long long rate;
+   struct drm_device *drm = &priv->drm;
+
+   mode = drm_display_mode_from_cea_vic(drm, 16);
+   KUNIT_ASSERT_NOT_NULL(test, mode);
+
+   KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+   rate = drm_connector_hdmi_compute_mode_clock(mode, 8, 
HDMI_COLORSPACE_RGB);
+   KUNIT_ASSERT_GT(test, rate, 0);
+   KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
+}
+
+/*
+ * Test that for a given mode, with 10bpc and an RGB output the TMDS
+ * character rate is equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc(struct 
kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const struct drm_display_mode *mode;
+   unsigned long long rate;
+   struct drm_device *drm = &priv->drm;
+
+   mode = drm_display_mode_from_cea_vic(drm, 16);
+   KUNIT_ASSERT_NOT_NULL(test, mode);
+
+   KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+   rate = drm_connector_hdmi_compute_mode_clock(mode, 10, 
HDMI_COLORSPACE_RGB);
+   KUNIT_ASSERT_GT(test, rate, 0);
+   KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void 
drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit 
*test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const struct drm_display_mode *mode;
+   unsigned long long rate;
+   struct drm_device *drm = &priv->drm;
+
+   mode = drm_display_mode_from_cea_vic(drm, 1);
+   KUNIT_ASSERT_NOT_NULL(test, mode);
+
+   rate = drm_connector_hdmi_compute_mode_clock(mode, 10, 
HDMI_COLORSPACE_RGB);
+   KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, with 12bpc and an RGB output the TMDS
+ * character rate is equal to 1.5 times the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc(struct 
kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const struct drm_display_mode *mode;
+   unsigned long long rate;
+   struct drm_device *drm = &priv->drm;
+
+   mode = drm_display_mode_from_cea_vic(drm, 16);
+   KUNIT_ASSERT_NOT_NULL(test, mode);
+
+   KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+   rate = drm_connector_hdmi_compute_mode_clock(mode, 12, 
HDMI_COLORSPACE_RGB);
+   KUNIT_ASSERT_GT(test, rate, 0);
+   KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void 
drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit 
*test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const struct drm_display_mode *mode;
+   unsigned long long rate;
+   struct drm_device *drm = &priv->drm;
+
+   mode = drm_display_mode_from_cea_vic(drm, 1);
+   KUNIT_ASSERT_NOT_NULL(test, mode);
+
+   rate = drm_connector_hdmi_compute_mode_clock(mode, 12, 
HDMI_COLORSPACE_RGB);
+   KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a mode with the pixel repetition flag, the TMDS
+ * character rate is indeed double the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_double(struct 
kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   const struct drm_display_mode *mode;
+   unsigned long long ra

[PATCH v9 08/27] drm/connector: hdmi: Add HDMI compute clock helper

2024-03-11 Thread Maxime Ripard
A lot of HDMI drivers have some variation of the formula to calculate
the TMDS character rate from a mode, but few of them actually take all
parameters into account.

Let's create a helper to provide that rate taking all parameters into
account.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_connector.c | 71 +
 include/drm/drm_connector.h |  5 +++
 2 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b629c8e990f4..8cc1332f11c2 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2895,10 +2895,81 @@ void drm_connector_update_privacy_screen(const struct 
drm_connector_state *conne
/* The hw_state property value may have changed, update it. */
drm_connector_update_privacy_screen_properties(connector, false);
 }
 EXPORT_SYMBOL(drm_connector_update_privacy_screen);
 
+/**
+ * drm_connector_hdmi_compute_mode_clock() - Computes the TMDS Character Rate
+ * @mode: Display mode to compute the clock for
+ * @bpc: Bits per character
+ * @fmt: Output Pixel Format used
+ *
+ * Returns the TMDS Character Rate for a given mode, bpc count and output 
format.
+ *
+ * RETURNS:
+ * The TMDS Character Rate, in Hertz, or 0 on error.
+ */
+unsigned long long
+drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+ unsigned int bpc,
+ enum hdmi_colorspace fmt)
+{
+   unsigned long long clock = mode->clock * 1000ULL;
+   unsigned int vic = drm_match_cea_mode(mode);
+
+   /*
+* CTA-861-G Spec, section 5.4 - Color Coding and Quantization
+* mandates that VIC 1 always uses 8 bpc.
+*/
+   if (vic == 1 && bpc != 8)
+   return 0;
+
+   /*
+* HDMI 2.0 Spec, section 7.1 - YCbCr 4:2:0 Pixel Encoding
+* specifies that YUV420 encoding is only available for those
+* VICs.
+*/
+   if (fmt == HDMI_COLORSPACE_YUV420 &&
+   !(vic == 96 || vic == 97 || vic == 101 ||
+ vic == 102 || vic == 106 || vic == 107))
+   return 0;
+
+   if (fmt == HDMI_COLORSPACE_YUV422) {
+   /*
+* HDMI 1.4b Spec, section 6.2.3 - Pixel Encoding Requirements
+* specifies that YUV422 is 36-bit only.
+*/
+   if (bpc != 12)
+   return 0;
+
+   /*
+* HDMI 1.0 Spec, section 6.5 - Pixel Encoding
+* specifies that YUV422 requires two 12-bits components per
+* pixel clock, which is equivalent in our calculation to three
+* 8-bits components
+*/
+   bpc = 8;
+   }
+
+   /*
+* HDMI 2.0 Spec, Section 7.1 - YCbCr 4:2:0 Pixel Encoding
+* specifies that YUV420 encoding is carried at a TMDS Character Rate
+* equal to half the pixel clock rate.
+*/
+   if (fmt == HDMI_COLORSPACE_YUV420)
+   clock = clock / 2;
+
+   if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+   clock = clock * 2;
+
+   clock = clock * bpc;
+   do_div(clock, 8);
+
+   return clock;
+}
+EXPORT_SYMBOL(drm_connector_hdmi_compute_mode_clock);
+
 int drm_connector_set_obj_prop(struct drm_mode_object *obj,
struct drm_property *property,
uint64_t value)
 {
int ret = -EINVAL;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 29883e6f8e50..a859ad7ee04b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -36,10 +36,11 @@
 
 struct drm_connector_helper_funcs;
 struct drm_modeset_acquire_ctx;
 struct drm_device;
 struct drm_crtc;
+struct drm_display_mode;
 struct drm_encoder;
 struct drm_panel;
 struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
@@ -2092,10 +2093,14 @@ int drm_connector_attach_max_bpc_property(struct 
drm_connector *connector,
 void drm_connector_create_privacy_screen_properties(struct drm_connector 
*conn);
 void drm_connector_attach_privacy_screen_properties(struct drm_connector 
*conn);
 void drm_connector_attach_privacy_screen_provider(
struct drm_connector *connector, struct drm_privacy_screen *priv);
 void drm_connector_update_privacy_screen(const struct drm_connector_state 
*connector_state);
+unsigned long long
+drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+ unsigned int bpc,
+ enum hdmi_colorspace fmt);
 
 /**
  * struct drm_tile_group - Tile group metadata
  * @refcount: reference count
  * @dev: DRM device

-- 
2.43.2



[PATCH v9 10/27] drm/connector: hdmi: Calculate TMDS character rate

2024-03-11 Thread Maxime Ripard
Most HDMI drivers have some code to calculate the TMDS character rate,
usually to adjust an internal clock to match what the mode requires.

Since the TMDS character rates mostly depends on the resolution, whether
we need to repeat pixels or not, the bpc count and the format, we can
now derive it from the HDMI connector state that stores all those infos
and remove the duplication from drivers.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_atomic.c   |  1 +
 drivers/gpu/drm/drm_atomic_state_helper.c  | 66 ++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  3 +
 include/drm/drm_connector.h|  5 ++
 4 files changed, 75 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 8730137baa86..26f9e525c0a0 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1146,10 +1146,11 @@ static void drm_atomic_connector_print_state(struct 
drm_printer *p,
if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
drm_printf(p, "\toutput_format=%s\n",
   
drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
+   drm_printf(p, "\ttmds_char_rate=%llu\n", 
state->hdmi.tmds_char_rate);
}
 
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
if (state->writeback_job && state->writeback_job->fb)
drm_printf(p, "\tfb=%d\n", 
state->writeback_job->fb->base.id);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index ae99765c45de..63a96c691460 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -638,10 +638,67 @@ int drm_atomic_helper_connector_tv_check(struct 
drm_connector *connector,
 
return 0;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 
+static const struct drm_display_mode *
+connector_state_get_mode(const struct drm_connector_state *conn_state)
+{
+   struct drm_atomic_state *state;
+   struct drm_crtc_state *crtc_state;
+   struct drm_crtc *crtc;
+
+   state = conn_state->state;
+   if (!state)
+   return NULL;
+
+   crtc = conn_state->crtc;
+   if (!crtc)
+   return NULL;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   if (!crtc_state)
+   return NULL;
+
+   return &crtc_state->mode;
+}
+
+static enum drm_mode_status
+hdmi_clock_valid(const struct drm_connector *connector,
+const struct drm_display_mode *mode,
+unsigned long long clock)
+{
+   const struct drm_display_info *info = &connector->display_info;
+
+   if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
+   return MODE_CLOCK_HIGH;
+
+   return MODE_OK;
+}
+
+static int
+hdmi_compute_clock(const struct drm_connector *connector,
+  struct drm_connector_state *state,
+  const struct drm_display_mode *mode,
+  unsigned int bpc, enum hdmi_colorspace fmt)
+{
+   enum drm_mode_status status;
+   unsigned long long clock;
+
+   clock = drm_connector_hdmi_compute_mode_clock(mode, bpc, fmt);
+   if (!clock)
+   return -EINVAL;
+
+   status = hdmi_clock_valid(connector, mode, clock);
+   if (status != MODE_OK)
+   return -EINVAL;
+
+   state->hdmi.tmds_char_rate = clock;
+
+   return 0;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector 
atomic state
  * @connector: DRM Connector
  * @state: the DRM State object
  *
@@ -657,10 +714,19 @@ int drm_atomic_helper_connector_hdmi_check(struct 
drm_connector *connector,
 {
struct drm_connector_state *old_state =
drm_atomic_get_old_connector_state(state, connector);
struct drm_connector_state *new_state =
drm_atomic_get_new_connector_state(state, connector);
+   const struct drm_display_mode *mode =
+   connector_state_get_mode(new_state);
+   int ret;
+
+   ret = hdmi_compute_clock(connector, new_state, mode,
+new_state->hdmi.output_bpc,
+new_state->hdmi.output_format);
+   if (ret)
+   return ret;
 
if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
old_state->hdmi.output_format != new_state->hdmi.output_format) {
struct drm_crtc *crtc = new_state->crtc;
struct drm_crtc_state *crtc_state;
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 1c3dd8a98fb0..f2acb

[PATCH v9 07/27] drm/tests: Add output formats tests

2024-03-11 Thread Maxime Ripard
Now that we track the HDMI output format as part of the connector state,
let's add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 32 +++
 drivers/gpu/drm/tests/drm_connector_test.c | 99 +-
 2 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index a129ea5f014c..1c3dd8a98fb0 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -345,10 +345,19 @@ static void 
drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 }
 
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+   /*
+* TODO: We should have tests to check that a change in the
+* format triggers a CRTC mode change just like we do for the
+* RGB Quantization and BPC.
+*
+* However, we don't have any way to control which format gets
+* picked up aside from changing the BPC or mode which would
+* already trigger a mode change.
+*/
{ }
 };
 
 static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
.name   = "drm_atomic_helper_connector_hdmi_check",
@@ -425,14 +434,37 @@ static void drm_test_check_bpc_12_value(struct kunit 
*test)
KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
 }
 
+/*
+ * Test that the value of the output format property out of reset is set
+ * to RGB, even if the driver supports more than that.
+ */
+static void drm_test_check_format_value(struct kunit *test)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv;
+   struct drm_connector_state *conn_state;
+   struct drm_connector *conn;
+
+   priv = drm_atomic_helper_connector_hdmi_init(test,
+BIT(HDMI_COLORSPACE_RGB) |
+
BIT(HDMI_COLORSPACE_YUV422) |
+
BIT(HDMI_COLORSPACE_YUV444),
+8);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   conn = &priv->connector;
+   conn_state = conn->state;
+   KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 
HDMI_COLORSPACE_RGB);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
KUNIT_CASE(drm_test_check_bpc_8_value),
KUNIT_CASE(drm_test_check_bpc_10_value),
KUNIT_CASE(drm_test_check_bpc_12_value),
+   KUNIT_CASE(drm_test_check_format_value),
{ }
 };
 
 static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = {
.name   = "drm_atomic_helper_connector_hdmi_reset",
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c 
b/drivers/gpu/drm/tests/drm_connector_test.c
index 9589867bdf7c..72f22ec951d6 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -346,10 +346,46 @@ static void drm_test_connector_hdmi_init_bpc_12(struct 
kunit *test)
prop = priv->drm.mode_config.hdr_output_metadata_property;
KUNIT_ASSERT_NOT_NULL(test, prop);
KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, 
prop->base.id));
 }
 
+/*
+ * Test that the registration of an HDMI connector with no supported
+ * format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  &dummy_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  &priv->ddc,
+  0,
+  8);
+   KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector not listing RGB as a
+ * supported format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  &dummy_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  &priv->ddc,
+  BIT(HDMI_COLORSPACE_YUV422),
+  8);
+   KUNIT_EXPECT_LT(test, ret, 0);
+}
+

[PATCH v9 06/27] drm/connector: hdmi: Add support for output format

2024-03-11 Thread Maxime Ripard
Just like BPC, we'll add support for automatic selection of the output
format for HDMI connectors.

Let's add the needed defaults and fields for now.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_atomic.c   |  2 ++
 drivers/gpu/drm/drm_atomic_state_helper.c  |  3 ++-
 drivers/gpu/drm/drm_connector.c| 31 ++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 22 +++
 drivers/gpu/drm/tests/drm_connector_test.c |  9 +++
 include/drm/drm_connector.h| 20 ++
 6 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 4e11cfb4518b..8730137baa86 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1144,10 +1144,12 @@ static void drm_atomic_connector_print_state(struct 
drm_printer *p,
drm_printf(p, "\tcolorspace=%s\n", 
drm_get_colorspace_name(state->colorspace));
 
if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
+   drm_printf(p, "\toutput_format=%s\n",
+  
drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
}
 
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
if (state->writeback_job && state->writeback_job->fb)
drm_printf(p, "\tfb=%d\n", 
state->writeback_job->fb->base.id);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 460454904fe3..ae99765c45de 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -658,11 +658,12 @@ int drm_atomic_helper_connector_hdmi_check(struct 
drm_connector *connector,
struct drm_connector_state *old_state =
drm_atomic_get_old_connector_state(state, connector);
struct drm_connector_state *new_state =
drm_atomic_get_new_connector_state(state, connector);
 
-   if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) {
+   if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
+   old_state->hdmi.output_format != new_state->hdmi.output_format) {
struct drm_crtc *crtc = new_state->crtc;
struct drm_crtc_state *crtc_state;
 
crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state))
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index da51a2bcb978..b629c8e990f4 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -457,10 +457,11 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @dev: DRM device
  * @connector: A pointer to the HDMI connector to init
  * @funcs: callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
+ * @supported_formats: Bitmask of @hdmi_colorspace listing supported output 
formats
  * @max_bpc: Maximum bits per char the HDMI connector supports
  *
  * Initialises a preallocated HDMI connector. Connectors can be
  * subclassed as part of driver connector objects.
  *
@@ -475,25 +476,31 @@ EXPORT_SYMBOL(drmm_connector_init);
 int drmm_connector_hdmi_init(struct drm_device *dev,
 struct drm_connector *connector,
 const struct drm_connector_funcs *funcs,
 int connector_type,
 struct i2c_adapter *ddc,
+unsigned long supported_formats,
 unsigned int max_bpc)
 {
int ret;
 
if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
  connector_type == DRM_MODE_CONNECTOR_HDMIB))
return -EINVAL;
 
+   if (!supported_formats || !(supported_formats & 
BIT(HDMI_COLORSPACE_RGB)))
+   return -EINVAL;
+
if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
return -EINVAL;
 
ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
if (ret)
return ret;
 
+   connector->hdmi.supported_formats = supported_formats;
+
/*
 * drm_connector_attach_max_bpc_property() requires the
 * connector to have a state.
 */
if (connector->funcs->reset)
@@ -1199,10 +1206,34 @@ static const u32 dp_colorspaces =
BIT(DRM_MODE_COLORIMETRY_SYCC_601) |
BIT(DRM_MODE_COLORIMETRY_OPYCC_601) |
BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |
BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
 
+static const char * const output_format_str[] = {
+   [HDMI_COLORSPACE_RGB]   = "RGB",
+   [HDMI_COLORSPACE_Y

[PATCH v9 03/27] drm/connector: hdmi: Create an HDMI sub-state

2024-03-11 Thread Maxime Ripard
The next features we will need to share across drivers will need to
store some parameters for drivers to use, such as the selected output
format.

Let's create a new connector sub-state dedicated to HDMI controllers,
that will eventually store everything we need.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_atomic_state_helper.c | 35 +++
 include/drm/drm_atomic_state_helper.h |  4 
 include/drm/drm_connector.h   |  7 +++
 3 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 519228eb1095..7ad1dffe66d9 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -569,10 +569,26 @@ void drm_atomic_helper_connector_tv_reset(struct 
drm_connector *connector)
 
drm_atomic_helper_connector_tv_margins_reset(connector);
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 
+/**
+ * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI 
@drm_connector_state resources
+ * @connector: DRM connector
+ * @new_state: connector state to reset
+ *
+ * Initializes all HDMI resources from a @drm_connector_state without
+ * actually allocating it. This is useful for HDMI drivers, in
+ * combination with __drm_atomic_helper_connector_reset() or
+ * drm_atomic_helper_connector_reset().
+ */
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+ struct drm_connector_state 
*new_state)
+{
+}
+EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
+
 /**
  * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
  * @connector: DRM Connector
  * @state: the DRM State object
  *
@@ -618,10 +634,29 @@ int drm_atomic_helper_connector_tv_check(struct 
drm_connector *connector,
 
return 0;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 
+/**
+ * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector 
atomic state
+ * @connector: DRM Connector
+ * @state: the DRM State object
+ *
+ * Provides a default connector state check handler for HDMI connectors.
+ * Checks that a desired connector update is valid, and updates various
+ * fields of derived state.
+ *
+ * RETURNS:
+ * Zero on success, or an errno code otherwise.
+ */
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
  * @state: atomic connector state
  *
diff --git a/include/drm/drm_atomic_state_helper.h 
b/include/drm/drm_atomic_state_helper.h
index b9740edb2658..d59d2b3aef9a 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -69,11 +69,15 @@ void drm_atomic_helper_plane_destroy_state(struct drm_plane 
*plane,
 void __drm_atomic_helper_connector_state_reset(struct drm_connector_state 
*conn_state,
   struct drm_connector *connector);
 void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
 struct drm_connector_state 
*conn_state);
 void drm_atomic_helper_connector_reset(struct drm_connector *connector);
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+ struct drm_connector_state 
*new_state);
 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+  struct drm_atomic_state *state);
 int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
 struct drm_atomic_state *state);
 void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector 
*connector);
 void
 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 4491c4c2fb6e..000a2a156619 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1029,10 +1029,17 @@ struct drm_connector_state {
/**
 * @hdr_output_metadata:
 * DRM blob property for HDR output metadata
 */
struct drm_property_blob *hdr_output_metadata;
+
+   /**
+* @hdmi: HDMI-related variable and properties. Filled by
+* @drm_atomic_helper_connector_hdmi_check().
+*/
+   struct {
+   } hdmi;
 };
 
 /**
  * struct drm_connector_funcs - control connectors on a given device
  *

-- 
2.43.2



[PATCH v9 05/27] drm/tests: Add output bpc tests

2024-03-11 Thread Maxime Ripard
Now that we're tracking the output bpc count in the connector state,
let's add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/tests/Makefile |   1 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 436 +
 drivers/gpu/drm/tests/drm_connector_test.c | 140 +++
 drivers/gpu/drm/tests/drm_kunit_edid.h | 106 +
 4 files changed, 683 insertions(+)

diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
index d6183b3d7688..b29ddfd90596 100644
--- a/drivers/gpu/drm/tests/Makefile
+++ b/drivers/gpu/drm/tests/Makefile
@@ -2,10 +2,11 @@
 
 obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \
drm_kunit_helpers.o
 
 obj-$(CONFIG_DRM_KUNIT_TEST) += \
+   drm_atomic_state_helper_test.o \
drm_buddy_test.o \
drm_cmdline_parser_test.o \
drm_connector_test.o \
drm_damage_helper_test.o \
drm_dp_mst_helper_test.o \
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c 
b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
new file mode 100644
index ..5d1a1dbff433
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Kunit test for drm_atomic_state_helper functions
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../drm_crtc_internal.h"
+
+#include 
+
+#include "drm_kunit_edid.h"
+
+struct drm_atomic_helper_connector_hdmi_priv {
+   struct drm_device drm;
+   struct drm_plane *plane;
+   struct drm_crtc *crtc;
+   struct drm_encoder encoder;
+   struct drm_connector connector;
+
+   const char *current_edid;
+   size_t current_edid_len;
+};
+
+#define connector_to_priv(c) \
+   container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, 
connector)
+
+static struct drm_display_mode *find_preferred_mode(struct drm_connector 
*connector)
+{
+   struct drm_device *drm = connector->dev;
+   struct drm_display_mode *mode, *preferred;
+
+   mutex_lock(&drm->mode_config.mutex);
+   preferred = list_first_entry(&connector->modes, struct 
drm_display_mode, head);
+   list_for_each_entry(mode, &connector->modes, head)
+   if (mode->type & DRM_MODE_TYPE_PREFERRED)
+   preferred = mode;
+   mutex_unlock(&drm->mode_config.mutex);
+
+   return preferred;
+}
+
+static int light_up_connector(struct kunit *test,
+ struct drm_device *drm,
+ struct drm_crtc *crtc,
+ struct drm_connector *connector,
+ struct drm_display_mode *mode,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+   struct drm_atomic_state *state;
+   struct drm_connector_state *conn_state;
+   struct drm_crtc_state *crtc_state;
+   int ret;
+
+   state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+   conn_state = drm_atomic_get_connector_state(state, connector);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+   ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+
+   crtc_state = drm_atomic_get_crtc_state(state, crtc);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+   ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+
+   crtc_state->enable = true;
+   crtc_state->active = true;
+
+   ret = drm_atomic_commit(state);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   return 0;
+}
+
+static int set_connector_edid(struct kunit *test, struct drm_connector 
*connector,
+ const char *edid, size_t edid_len)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv =
+   connector_to_priv(connector);
+   struct drm_device *drm = connector->dev;
+   int ret;
+
+   priv->current_edid = edid;
+   priv->current_edid_len = edid_len;
+
+   mutex_lock(&drm->mode_config.mutex);
+   ret = connector->funcs->fill_modes(connector, 4096, 4096);
+   mutex_unlock(&drm->mode_config.mutex);
+   KUNIT_ASSERT_GT(test, ret, 0);
+
+   return 0;
+}
+
+static int dummy_connector_get_modes(struct drm_connector *connector)
+{
+   struct drm_atomic_helper_connector_hdmi_priv *priv =
+   connector_to_priv(connector);
+   const struct drm_edid *edid;
+   unsigned int num_modes;
+
+   edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len);
+   if (!edid)
+   return -EINVAL;
+
+   drm_edid_connector_update(connector, edid);
+   num_modes = drm_edid_connector_add_modes(connector);
+
+   drm_edid_free(edid)

[PATCH v9 04/27] drm/connector: hdmi: Add output BPC to the connector state

2024-03-11 Thread Maxime Ripard
We'll add automatic selection of the output BPC in a following patch,
but let's add it to the HDMI connector state already.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_atomic.c   |  5 +
 drivers/gpu/drm/drm_atomic_state_helper.c  | 20 
 drivers/gpu/drm/drm_connector.c| 20 +++-
 drivers/gpu/drm/tests/drm_connector_test.c | 12 
 include/drm/drm_connector.h| 12 +++-
 5 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a91737adf8e7..4e11cfb4518b 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1141,10 +1141,15 @@ static void drm_atomic_connector_print_state(struct 
drm_printer *p,
drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : 
"(null)");
drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
drm_printf(p, "\tcolorspace=%s\n", 
drm_get_colorspace_name(state->colorspace));
 
+   if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+   connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+   drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
+   }
+
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
if (state->writeback_job && state->writeback_job->fb)
drm_printf(p, "\tfb=%d\n", 
state->writeback_job->fb->base.id);
 
if (connector->funcs->atomic_print_state)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 7ad1dffe66d9..460454904fe3 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -582,10 +582,14 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
  * drm_atomic_helper_connector_reset().
  */
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
  struct drm_connector_state 
*new_state)
 {
+   unsigned int max_bpc = connector->max_bpc;
+
+   new_state->max_bpc = max_bpc;
+   new_state->max_requested_bpc = max_bpc;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
 
 /**
  * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
@@ -649,10 +653,26 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
  * Zero on success, or an errno code otherwise.
  */
 int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
   struct drm_atomic_state *state)
 {
+   struct drm_connector_state *old_state =
+   drm_atomic_get_old_connector_state(state, connector);
+   struct drm_connector_state *new_state =
+   drm_atomic_get_new_connector_state(state, connector);
+
+   if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) {
+   struct drm_crtc *crtc = new_state->crtc;
+   struct drm_crtc_state *crtc_state;
+
+   crtc_state = drm_atomic_get_crtc_state(state, crtc);
+   if (IS_ERR(crtc_state))
+   return PTR_ERR(crtc_state);
+
+   crtc_state->mode_changed = true;
+   }
+
return 0;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
 
 /**
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index d9961cce8245..da51a2bcb978 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -457,10 +457,11 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @dev: DRM device
  * @connector: A pointer to the HDMI connector to init
  * @funcs: callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
+ * @max_bpc: Maximum bits per char the HDMI connector supports
  *
  * Initialises a preallocated HDMI connector. Connectors can be
  * subclassed as part of driver connector objects.
  *
  * Cleanup is automatically handled with a call to
@@ -473,22 +474,39 @@ EXPORT_SYMBOL(drmm_connector_init);
  */
 int drmm_connector_hdmi_init(struct drm_device *dev,
 struct drm_connector *connector,
 const struct drm_connector_funcs *funcs,
 int connector_type,
-struct i2c_adapter *ddc)
+struct i2c_adapter *ddc,
+unsigned int max_bpc)
 {
int ret;
 
if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
  connector_type == DRM_MODE_CONNECTOR_HDMIB))
return -EINVAL;
 
+   if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
+   return -EINVAL;
+
ret = drmm_connector_init(dev, connecto

[PATCH v9 02/27] drm/tests: connector: Add tests for drmm_connector_hdmi_init

2024-03-11 Thread Maxime Ripard
We just introduced a new initialization function for our connectors, so
let's build a kunit test suite for it as well.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/tests/drm_connector_test.c | 123 +
 1 file changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c 
b/drivers/gpu/drm/tests/drm_connector_test.c
index 44f82ed2a958..261d4109946d 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -170,10 +170,132 @@ static struct kunit_suite drmm_connector_init_test_suite 
= {
.name = "drmm_connector_init",
.init = drm_test_connector_init,
.test_cases = drmm_connector_init_tests,
 };
 
+/*
+ * Test that the registration of a bog standard connector works as
+ * expected and doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_valid(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  &dummy_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  &priv->ddc);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector without a DDC adapter
+ * doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  &dummy_funcs,
+  DRM_MODE_CONNECTOR_HDMIA,
+  NULL);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with an HDMI
+ * connector type succeeds.
+ */
+static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   unsigned int connector_type = *(unsigned int *)test->param_value;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  &dummy_funcs,
+  connector_type,
+  &priv->ddc);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
+   DRM_MODE_CONNECTOR_HDMIA,
+   DRM_MODE_CONNECTOR_HDMIB,
+};
+
+static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char 
*desc)
+{
+   sprintf(desc, "%s", drm_get_connector_type_name(*type));
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
+ drm_connector_hdmi_init_type_valid_tests,
+ drm_connector_hdmi_init_type_desc);
+
+/*
+ * Test that the registration of an HDMI connector with an !HDMI
+ * connector type fails.
+ */
+static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
+{
+   struct drm_connector_init_priv *priv = test->priv;
+   unsigned int connector_type = *(unsigned int *)test->param_value;
+   int ret;
+
+   ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+  &dummy_funcs,
+  connector_type,
+  &priv->ddc);
+   KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
+   DRM_MODE_CONNECTOR_Unknown,
+   DRM_MODE_CONNECTOR_VGA,
+   DRM_MODE_CONNECTOR_DVII,
+   DRM_MODE_CONNECTOR_DVID,
+   DRM_MODE_CONNECTOR_DVIA,
+   DRM_MODE_CONNECTOR_Composite,
+   DRM_MODE_CONNECTOR_SVIDEO,
+   DRM_MODE_CONNECTOR_LVDS,
+   DRM_MODE_CONNECTOR_Component,
+   DRM_MODE_CONNECTOR_9PinDIN,
+   DRM_MODE_CONNECTOR_DisplayPort,
+   DRM_MODE_CONNECTOR_TV,
+   DRM_MODE_CONNECTOR_eDP,
+   DRM_MODE_CONNECTOR_VIRTUAL,
+   DRM_MODE_CONNECTOR_DSI,
+   DRM_MODE_CONNECTOR_DPI,
+   DRM_MODE_CONNECTOR_WRITEBACK,
+   DRM_MODE_CONNECTOR_SPI,
+   DRM_MODE_CONNECTOR_USB,
+};
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
+ drm_connector_hdmi_init_type_invalid_tests,
+ drm_connector_hdmi_init_type_desc);
+
+static struct kunit_case drmm_connector_hdmi_init_tests[] = {
+   KUNIT_CASE(drm_test_connector_hdmi_init_valid),
+   KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
+   KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
+drm_connector_hdmi_init_type_valid_gen_params),
+   KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
+drm_connector_hdmi_init_type_invalid_gen_params),
+   { }
+};
+
+static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
+   .nam

[PATCH v9 01/27] drm/connector: Introduce an HDMI connector initialization function

2024-03-11 Thread Maxime Ripard
A lot of the various HDMI drivers duplicate some logic that depends on
the HDMI spec itself and not really a particular hardware
implementation.

Output BPC or format selection, infoframe generation are good examples
of such areas.

This creates a lot of boilerplate, with a lot of variations, which makes
it hard for userspace to rely on, and makes it difficult to get it right
for drivers.

In the next patches, we'll add a lot of infrastructure around the
drm_connector and drm_connector_state structures, which will allow to
abstract away the duplicated logic. This infrastructure comes with a few
requirements though, and thus we need a new initialization function.

Hopefully, this will make drivers simpler to handle, and their behaviour
more consistent.

Reviewed-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_connector.c | 39 +++
 include/drm/drm_connector.h |  5 +
 2 files changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b0516505f7ae..d9961cce8245 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -450,10 +450,49 @@ int drmm_connector_init(struct drm_device *dev,
 
return 0;
 }
 EXPORT_SYMBOL(drmm_connector_init);
 
+/**
+ * drmm_connector_hdmi_init - Init a preallocated HDMI connector
+ * @dev: DRM device
+ * @connector: A pointer to the HDMI connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ * @ddc: optional pointer to the associated ddc adapter
+ *
+ * Initialises a preallocated HDMI connector. Connectors can be
+ * subclassed as part of driver connector objects.
+ *
+ * Cleanup is automatically handled with a call to
+ * drm_connector_cleanup() in a DRM-managed action.
+ *
+ * The connector structure should be allocated with drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_hdmi_init(struct drm_device *dev,
+struct drm_connector *connector,
+const struct drm_connector_funcs *funcs,
+int connector_type,
+struct i2c_adapter *ddc)
+{
+   int ret;
+
+   if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector_type == DRM_MODE_CONNECTOR_HDMIB))
+   return -EINVAL;
+
+   ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drmm_connector_hdmi_init);
+
 /**
  * drm_connector_attach_edid_property - attach edid property.
  * @connector: the connector
  *
  * Some connector types like DRM_MODE_CONNECTOR_VIRTUAL do not get a
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fe88d7fc6b8f..4491c4c2fb6e 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1902,10 +1902,15 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
 int drmm_connector_init(struct drm_device *dev,
struct drm_connector *connector,
const struct drm_connector_funcs *funcs,
int connector_type,
struct i2c_adapter *ddc);
+int drmm_connector_hdmi_init(struct drm_device *dev,
+struct drm_connector *connector,
+const struct drm_connector_funcs *funcs,
+int connector_type,
+struct i2c_adapter *ddc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);
 int drm_connector_attach_encoder(struct drm_connector *connector,
  struct drm_encoder *encoder);

-- 
2.43.2



[PATCH v9 00/27] drm/connector: Create HDMI Connector infrastructure

2024-03-11 Thread Maxime Ripard
Hi,

Here's a series that creates some extra infrastructure specifically
targeted at HDMI controllers.

The idea behind this series came from a recent discussion on IRC during
which we discussed infoframes generation of i915 vs everything else.

Infoframes generation code still requires some decent boilerplate, with
each driver doing some variation of it.

In parallel, while working on vc4, we ended up converting a lot of i915
logic (mostly around format / bpc selection, and scrambler setup) to
apply on top of a driver that relies only on helpers.

While currently sitting in the vc4 driver, none of that logic actually
relies on any driver or hardware-specific behaviour.

The only missing piece to make it shareable are a bunch of extra
variables stored in a state (current bpc, format, RGB range selection,
etc.).

The initial implementation was relying on some generic subclass of
drm_connector to address HDMI connectors, with a bunch of helpers that
will take care of all the "HDMI Spec" related code. Scrambler setup is
missing at the moment but can easily be plugged in.

The feedback was that creating a connector subclass like was done for
writeback would prevent the adoption of those helpers since it couldn't
be used in all situations (like when the connector driver can implement
multiple output) and required more churn to cast between the
drm_connector and its subclass. The decision was thus to provide a set
of helper and to store the required variables in drm_connector and
drm_connector_state. This what has been implemented now.

Hans Verkuil also expressed interest in implementing a mechanism in v4l2
to retrieve infoframes from HDMI receiver and implementing a tool to
decode (and eventually check) infoframes. His current work on
edid-decode to enable that based on that series can be found here:
https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil

And some more context here:
https://lore.kernel.org/dri-devel/50db7366-cd3d-4675-aaad-b85720223...@xs4all.nl/

This series thus leverages the infoframe generation code to expose it
through debugfs.

I also used the occasion to unit-test everything but the infoframe
generation, which can come later once I get a proper understanding of
what the infoframe are supposed to look like. This required to add some
extra kunit helpers and infrastructure to have multiple EDIDs and allow
each test to run with a particular set of capabilities.

This entire series has been tested on a Pi4, passes all its unittests
(125 new tests), and has only been build-tested for sunxi and rockchip.

Let me know what you think,
Maxime

Signed-off-by: Maxime Ripard 
---
Changes in v9:
- Generate every infoframe but the HDMI vendor one if has_hdmi_infoframe
  isn't set
- Fix typos in the doc
- Removed undef for inexisting macro
- Improve the Broadcast RGB sanitation test
- Make EDID bytes array const
- Link to v8: 
https://lore.kernel.org/r/20240307-kms-hdmi-connector-state-v8-0-ef6a6f319...@kernel.org

Changes in v8:
- Drop applied patches
- Drop the YUV limited range mention in the Broadcast RGB documentation
- Rephrase the vc4_dummy_plane removal commit log
- Move infroframe mutex initialisation to the main drm_connector_init
  function to make sure it's always initialised
- Link to v7: 
https://lore.kernel.org/r/20240222-kms-hdmi-connector-state-v7-0-8f4af575f...@kernel.org

Changes in v7:
- Rebased on top of current next
- Only consider the Broadcast RGB property if the output format is RGB,
  and use a limited range otherwise
- Document the fact that Broadcast RGB only applies if the output format
  is RGB
- Add some test to make sure we always get a limited range if we have a
  YCbCr output format.
- Link to v6: 
https://lore.kernel.org/r/20240212-kms-hdmi-connector-state-v6-0-f4bcdc979...@kernel.org

Changes in v6:
- Rebased on top of current next
- Split the tests into separate patches
- Improve the Broadcast RGB documentation
- Link to v5: 
https://lore.kernel.org/r/20231207-kms-hdmi-connector-state-v5-0-6538e19d6...@kernel.org

Changes in v5:
- Dropped the connector init arg checking patch, and the related kunit
  tests
- Dropped HDMI Vendor infoframes in rockchip inno_hdmi
- Fixed the build warnings
- Link to v4: 
https://lore.kernel.org/r/20231128-kms-hdmi-connector-state-v4-0-c76021583...@kernel.org

Changes in v4:
- Create unit tests for everything but infoframes
- Fix a number of bugs identified by the unit tests
- Rename DRM (Dynamic Range and Mastering) infoframe file to HDR_DRM
- Drop RFC status
- Link to v3: 
https://lore.kernel.org/r/20231031-kms-hdmi-connector-state-v3-0-328b0fae4...@kernel.org

Changes in v3:
- Made sure the series work on the RaspberryPi4
- Handle YUV420 in the char clock rate computation
- Use the maximum bpc value the connector allows at reset
- Expose the RGB Limited vs Full Range value in the connector state
  instead of through a helper
- Fix Broadcast RGB documentation
- Add more debug logging
- Small fixes here and there
- Link to v2

Re: [PATCH] Revert "drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue"

2024-03-11 Thread Jani Nikula
On Mon, 11 Mar 2024, Liviu Dudau  wrote:
> On Mon, Mar 11, 2024 at 02:26:50PM +0200, Jani Nikula wrote:
>> On Mon, 11 Mar 2024, Boris Brezillon  wrote:
>> > On Mon, 11 Mar 2024 13:51:46 +0200
>> > Jani Nikula  wrote:
>> >
>> >> On Mon, 11 Mar 2024, Boris Brezillon  
>> >> wrote:
>> >> > On Mon, 11 Mar 2024 13:16:19 +0200
>> >> > Jani Nikula  wrote:
>> >> >  
>> >> >> This reverts commit 674dc7f61aefea81901c21402946074927e63f1a.
>> >> >> 
>> >> >> The commit causes a recursive dependency in kconfig:
>> >> >> 
>> >> >> drivers/iommu/Kconfig:14:error: recursive dependency detected!
>> >> >> drivers/iommu/Kconfig:14:  symbol IOMMU_SUPPORT is selected by 
>> >> >> DRM_PANTHOR
>> >> >> drivers/gpu/drm/panthor/Kconfig:3: symbol DRM_PANTHOR depends on PM
>> >> >> kernel/power/Kconfig:183:  symbol PM is selected by PM_SLEEP
>> >> >> kernel/power/Kconfig:117:  symbol PM_SLEEP depends on 
>> >> >> HIBERNATE_CALLBACKS
>> >> >> kernel/power/Kconfig:35:   symbol HIBERNATE_CALLBACKS is selected 
>> >> >> by XEN_SAVE_RESTORE
>> >> >> arch/x86/xen/Kconfig:67:   symbol XEN_SAVE_RESTORE depends on XEN
>> >> >> arch/x86/xen/Kconfig:6:symbol XEN depends on PARAVIRT
>> >> >> arch/x86/Kconfig:781:  symbol PARAVIRT is selected by HYPERV
>> >> >> drivers/hv/Kconfig:5:  symbol HYPERV depends on X86_LOCAL_APIC
>> >> >> arch/x86/Kconfig:1106: symbol X86_LOCAL_APIC depends on X86_UP_APIC
>> >> >> arch/x86/Kconfig:1081: symbol X86_UP_APIC prompt is visible depending 
>> >> >> on PCI_MSI
>> >> >> drivers/pci/Kconfig:39:symbol PCI_MSI is selected by AMD_IOMMU
>> >> >> drivers/iommu/amd/Kconfig:3:   symbol AMD_IOMMU depends on 
>> >> >> IOMMU_SUPPORT
>> >> >> For a resolution refer to Documentation/kbuild/kconfig-language.rst
>> >> >> subsection "Kconfig recursive dependency limitations"
>> >> >> 
>> >> >> Fixes: 674dc7f61aef ("drm/panthor: Fix undefined 
>> >> >> panthor_device_suspend/resume symbol issue")
>> >> >> Cc: Boris Brezillon 
>> >> >> Cc: Liviu Dudau 
>> >> >> Cc: Steven Price 
>> >> >> Signed-off-by: Jani Nikula   
>> >> >
>> >> > Acked-by: Boris Brezillon   
>> >> 
>> >> Your suggestion select -> depends on IOMMU_SUPPORT seems to also work,
>> >> at least for me. Want to send a patch for that instead of me merging the
>> >> revert?
>> >
>> > I replied on the other thread :-). I think we're better off reverting
>> > the faulty commit, so we can discuss how to fix the original issue
>> > properly without blocking the build.
>> 
>> Thanks, pushed to drm-misc-next.
>
> So with this revert we're OK with an undefined symbol if !CONFIG_PM, but 
> we're not happy
> with a recursive dependency that is only triggered for COMPILE_TEST? I 
> would've thought
> IOMMU_SUPPORT options is a better one.

It's a real config.

# CONFIG_COMPILE_TEST is not set

BR,
Jani.

>
> Best regards,
> Liviu
>
>> 
>> BR,
>> Jani.
>> 
>> 
>> -- 
>> Jani Nikula, Intel

-- 
Jani Nikula, Intel


Re: [PATCH] drm/amdgpu: add ring buffer information in devcoredump

2024-03-11 Thread Khatri, Sunil



On 3/11/2024 7:29 PM, Christian König wrote:



Am 11.03.24 um 13:22 schrieb Sunil Khatri:

Add relevant ringbuffer information such as
rptr, wptr, ring name, ring size and also
the ring contents for each ring on a gpu reset.

Signed-off-by: Sunil Khatri 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 21 +
  1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c

index 6d059f853adc..1992760039da 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
@@ -215,6 +215,27 @@ amdgpu_devcoredump_read(char *buffer, loff_t 
offset, size_t count,

 fault_info->status);
  }
  +    drm_printf(&p, "Ring buffer information\n");
+    for (int i = 0; i < coredump->adev->num_rings; i++) {
+    int j = 0;
+    struct amdgpu_ring *ring = coredump->adev->rings[i];
+
+    drm_printf(&p, "ring name: %s\n", ring->name);
+    drm_printf(&p, "Rptr: 0x%llx Wptr: 0x%llx\n",
+   amdgpu_ring_get_rptr(ring) & ring->buf_mask,
+   amdgpu_ring_get_wptr(ring) & ring->buf_mask);


Don't apply the mask here. We do have some use cases where the rptr 
and wptr are outside the ring buffer.

Sure i will remove the mask.



+    drm_printf(&p, "Ring size in dwords: %d\n",
+   ring->ring_size / 4);


Rather print the mask as additional value here.

Does that help adding the mask value ?



+    drm_printf(&p, "Ring contents\n");
+    drm_printf(&p, "Offset \t Value\n");
+
+    while (j < ring->ring_size) {
+    drm_printf(&p, "0x%x \t 0x%x\n", j, ring->ring[j/4]);
+    j += 4;
+    }



+    drm_printf(&p, "Ring dumped\n");


That seems superfluous.


Noted


Regards
Sunil



Regards,
Christian.


+    }
+
  if (coredump->reset_vram_lost)
  drm_printf(&p, "VRAM is lost due to GPU reset!\n");
  if (coredump->adev->reset_info.num_regs) {




Re: Proposal to add CRIU support to DRM render nodes

2024-03-11 Thread Tvrtko Ursulin



Hi Felix,

On 06/12/2023 21:23, Felix Kuehling wrote:
Executive Summary: We need to add CRIU support to DRM render nodes in 
order to maintain CRIU support for ROCm application once they start 
relying on render nodes for more GPU memory management. In this email 
I'm providing some background why we are doing this, and outlining some 
of the problems we need to solve to checkpoint and restore render node 
state and shared memory (DMABuf) state. I have some thoughts on the API 
design, leaning on what we did for KFD, but would like to get feedback 
from the DRI community regarding that API and to what extent there is 
interest in making that generic.


We are working on using DRM render nodes for virtual address mappings in 
ROCm applications to implement the CUDA11-style VM API and improve 
interoperability between graphics and compute. This uses DMABufs for 
sharing buffer objects between KFD and multiple render node devices, as 
well as between processes. In the long run this also provides a path to 
moving all or most memory management from the KFD ioctl API to libdrm.


Once ROCm user mode starts using render nodes for virtual address 
management, that creates a problem for checkpointing and restoring ROCm 
applications with CRIU. Currently there is no support for checkpointing 
and restoring render node state, other than CPU virtual address 
mappings. Support will be needed for checkpointing GEM buffer objects 
and handles, their GPU virtual address mappings and memory sharing 
relationships between devices and processes.


Eventually, if full CRIU support for graphics applications is desired, 
more state would need to be captured, including scheduler contexts and 
BO lists. Most of this state is driver-specific.


After some internal discussions we decided to take our design process 
public as this potentially touches DRM GEM and DMABuf APIs and may have 
implications for other drivers in the future.


One basic question before going into any API details: Is there a desire 
to have CRIU support for other DRM drivers?


This sounds like a very interesting feature on the overall, although I 
cannot answer on the last question here.


Funnily enough, it has a tiny relation to an i915 feature I recently 
implemented on Mesa's request, which is to be able to "upload" the GPU 
context from the GPU hang error state and replay the hanging request. It 
is kind of (at a stretch) a very special tiny subset of checkout and 
restore so I am not mentioning it as a curiosity.


And there is also another partical conceptual intersect with the (at the 
moment not yet upstream) i915 online debugger. This part being in the 
area of discovering and enumerating GPU resources beloning to the client.


I don't see an immediate design or code sharing opportunities though but 
just mentioning.


I did spend some time reading your plugin and kernel implementation out 
of curiousity and have some comments and questions.


With that out of the way, some considerations for a possible DRM CRIU 
API (either generic of AMDGPU driver specific): The API goes through 
several phases during checkpoint and restore:


Checkpoint:

 1. Process-info (enumerates objects and sizes so user mode can allocate
memory for the checkpoint, stops execution on the GPU)
 2. Checkpoint (store object metadata for BOs, queues, etc.)
 3. Unpause (resumes execution after the checkpoint is complete)

Restore:

 1. Restore (restore objects, VMAs are not in the right place at this time)
 2. Resume (final fixups after the VMAs are sorted out, resume execution)


Btw is check-pointing guaranteeing all relevant activity is idled? For 
instance dma_resv objects are free of fences which would need to 
restored for things to continue executing sensibly? Or how is that handled?


For some more background about our implementation in KFD, you can refer 
to this whitepaper: 
https://github.com/checkpoint-restore/criu/blob/criu-dev/plugins/amdgpu/README.md


Potential objections to a KFD-style CRIU API in DRM render nodes, I'll 
address each of them in more detail below:


  * Opaque information in the checkpoint data that user mode can't
interpret or do anything with
  * A second API for creating objects (e.g. BOs) that is separate from
the regular BO creation API
  * Kernel mode would need to be involved in restoring BO sharing
relationships rather than replaying BO creation, export and import
from user mode

# Opaque information in the checkpoint

This comes out of ABI compatibility considerations. Adding any new 
objects or attributes to the driver/HW state that needs to be 
checkpointed could potentially break the ABI of the CRIU 
checkpoint/restore ioctl if the plugin needs to parse that information. 
Therefore, much of the information in our KFD CRIU ioctl API is opaque. 
It is written by kernel mode in the checkpoint, it is consumed by kernel 
mode when restoring the checkpoint, but user mode doesn't care about the 
contents or binary lay

Re: [PATCH] Revert "drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue"

2024-03-11 Thread Liviu Dudau
On Mon, Mar 11, 2024 at 02:26:50PM +0200, Jani Nikula wrote:
> On Mon, 11 Mar 2024, Boris Brezillon  wrote:
> > On Mon, 11 Mar 2024 13:51:46 +0200
> > Jani Nikula  wrote:
> >
> >> On Mon, 11 Mar 2024, Boris Brezillon  wrote:
> >> > On Mon, 11 Mar 2024 13:16:19 +0200
> >> > Jani Nikula  wrote:
> >> >  
> >> >> This reverts commit 674dc7f61aefea81901c21402946074927e63f1a.
> >> >> 
> >> >> The commit causes a recursive dependency in kconfig:
> >> >> 
> >> >> drivers/iommu/Kconfig:14:error: recursive dependency detected!
> >> >> drivers/iommu/Kconfig:14:   symbol IOMMU_SUPPORT is selected by 
> >> >> DRM_PANTHOR
> >> >> drivers/gpu/drm/panthor/Kconfig:3:  symbol DRM_PANTHOR depends on PM
> >> >> kernel/power/Kconfig:183:   symbol PM is selected by PM_SLEEP
> >> >> kernel/power/Kconfig:117:   symbol PM_SLEEP depends on 
> >> >> HIBERNATE_CALLBACKS
> >> >> kernel/power/Kconfig:35:symbol HIBERNATE_CALLBACKS is selected 
> >> >> by XEN_SAVE_RESTORE
> >> >> arch/x86/xen/Kconfig:67:symbol XEN_SAVE_RESTORE depends on XEN
> >> >> arch/x86/xen/Kconfig:6: symbol XEN depends on PARAVIRT
> >> >> arch/x86/Kconfig:781:   symbol PARAVIRT is selected by HYPERV
> >> >> drivers/hv/Kconfig:5:   symbol HYPERV depends on X86_LOCAL_APIC
> >> >> arch/x86/Kconfig:1106:  symbol X86_LOCAL_APIC depends on X86_UP_APIC
> >> >> arch/x86/Kconfig:1081:  symbol X86_UP_APIC prompt is visible depending 
> >> >> on PCI_MSI
> >> >> drivers/pci/Kconfig:39: symbol PCI_MSI is selected by AMD_IOMMU
> >> >> drivers/iommu/amd/Kconfig:3:symbol AMD_IOMMU depends on 
> >> >> IOMMU_SUPPORT
> >> >> For a resolution refer to Documentation/kbuild/kconfig-language.rst
> >> >> subsection "Kconfig recursive dependency limitations"
> >> >> 
> >> >> Fixes: 674dc7f61aef ("drm/panthor: Fix undefined 
> >> >> panthor_device_suspend/resume symbol issue")
> >> >> Cc: Boris Brezillon 
> >> >> Cc: Liviu Dudau 
> >> >> Cc: Steven Price 
> >> >> Signed-off-by: Jani Nikula   
> >> >
> >> > Acked-by: Boris Brezillon   
> >> 
> >> Your suggestion select -> depends on IOMMU_SUPPORT seems to also work,
> >> at least for me. Want to send a patch for that instead of me merging the
> >> revert?
> >
> > I replied on the other thread :-). I think we're better off reverting
> > the faulty commit, so we can discuss how to fix the original issue
> > properly without blocking the build.
> 
> Thanks, pushed to drm-misc-next.

So with this revert we're OK with an undefined symbol if !CONFIG_PM, but we're 
not happy
with a recursive dependency that is only triggered for COMPILE_TEST? I would've 
thought
IOMMU_SUPPORT options is a better one.

Best regards,
Liviu

> 
> BR,
> Jani.
> 
> 
> -- 
> Jani Nikula, Intel

-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯


Re: [PATCH v2 28/28] fbdev/p9100: Drop now unused driver p9100

2024-03-11 Thread Arnd Bergmann
On Sat, Mar 9, 2024, at 19:15, Sam Ravnborg via B4 Relay wrote:
> From: Sam Ravnborg 
>
> The p9100 driver is only relevant for the Sparcbook 3 machine,
> and with sun4m support removed this driver is no longer relevant.
>
> Signed-off-by: Sam Ravnborg 
> Acked-by: Arnd Bergmann 
> Acked-by: Thomas Zimmermann 
> Cc: "David S. Miller" 
> Cc: Arnd Bergmann 
> Cc: Andreas Larsson 
> Cc: Helge Deller 
> ---
>  drivers/video/fbdev/Kconfig  |   8 -
>  drivers/video/fbdev/Makefile |   1 -
>  drivers/video/fbdev/p9100.c  | 372 
> ---
>  3 files changed, 381 deletions(-)

I tried to figure out if there are other drivers in the same
category and found the list at
https://everything2.com/title/Sun+graphics+cards

As far as I can tell, the only SBUS graphics that were
shipped on sparc64 are FB_FFB and FB_CG6, so we could
go further and remove BW2, CG3, TCX, CG14 and LEO as
well.

No need to change anything here for the moment, dropping
p9100 is already a step in the right direction.

 Arnd


Re: [PATCH 3/3] drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue

2024-03-11 Thread Boris Brezillon
On Mon, 11 Mar 2024 14:59:39 +0100
Boris Brezillon  wrote:

> On Mon, 11 Mar 2024 14:58:37 +0100
> Boris Brezillon  wrote:
> 
> > On Mon, 11 Mar 2024 13:46:23 +
> > Steven Price  wrote:
> >   
> > > On 11/03/2024 13:36, Robin Murphy wrote:
> > > > On 2024-03-11 1:22 pm, Boris Brezillon wrote:  
> > > >> On Mon, 11 Mar 2024 13:11:28 +
> > > >> Robin Murphy  wrote:
> > > >>  
> > > >>> On 2024-03-11 11:52 am, Boris Brezillon wrote:  
> > >  On Mon, 11 Mar 2024 13:49:56 +0200
> > >  Jani Nikula  wrote:
> > >      
> > > > On Mon, 11 Mar 2024, Boris Brezillon
> > > >  wrote:  
> > > >> On Mon, 11 Mar 2024 13:05:01 +0200
> > > >> Jani Nikula  wrote:
> > > >>   
> > > >>> This breaks the config for me:
> > > >>>
> > > >>>     SYNC    include/config/auto.conf.cmd
> > > >>>     GEN Makefile
> > > >>> drivers/iommu/Kconfig:14:error: recursive dependency detected!
> > > >>> drivers/iommu/Kconfig:14:    symbol IOMMU_SUPPORT is selected by
> > > >>> DRM_PANTHOR
> > > >>> drivers/gpu/drm/panthor/Kconfig:3:    symbol DRM_PANTHOR depends
> > > >>> on PM
> > > >>> kernel/power/Kconfig:183:    symbol PM is selected by PM_SLEEP
> > > >>> kernel/power/Kconfig:117:    symbol PM_SLEEP depends on
> > > >>> HIBERNATE_CALLBACKS
> > > >>> kernel/power/Kconfig:35:    symbol HIBERNATE_CALLBACKS is
> > > >>> selected by XEN_SAVE_RESTORE
> > > >>> arch/x86/xen/Kconfig:67:    symbol XEN_SAVE_RESTORE depends on XEN
> > > >>> arch/x86/xen/Kconfig:6:    symbol XEN depends on PARAVIRT
> > > >>> arch/x86/Kconfig:781:    symbol PARAVIRT is selected by HYPERV
> > > >>> drivers/hv/Kconfig:5:    symbol HYPERV depends on X86_LOCAL_APIC
> > > >>> arch/x86/Kconfig:1106:    symbol X86_LOCAL_APIC depends on
> > > >>> X86_UP_APIC
> > > >>> arch/x86/Kconfig:1081:    symbol X86_UP_APIC prompt is visible
> > > >>> depending on PCI_MSI
> > > >>> drivers/pci/Kconfig:39:    symbol PCI_MSI is selected by AMD_IOMMU
> > > >>> drivers/iommu/amd/Kconfig:3:    symbol AMD_IOMMU depends on
> > > >>> IOMMU_SUPPORT  
> > > >>
> > > >> Uh, I guess we want a "depends on IOMMU_SUPPORT" instead of "select
> > > >> IOMMU_SUPPORT" in panthor then.  
> > > >
> > > > That works for me.  
> > > 
> > >  Let's revert the faulty commit first. We'll see if Steve has a
> > >  different solution for the original issue.  
> > > >>>
> > > >>> FWIW, the reasoning in the offending commit seems incredibly tenuous.
> > > >>> There are far more practical reasons for building an arm/arm64 kernel
> > > >>> without PM - for debugging or whatever, and where one may even still
> > > >>> want a usable GPU, let alone just a non-broken build - than there are
> > > >>> for building this driver for x86. Using pm_ptr() is trivial, and if 
> > > >>> you
> > > >>> want to support COMPILE_TEST then there's really no justifiable excuse
> > > >>> not to.  
> > > >>
> > > >> The problem is not just about using pm_ptr(), but also making sure
> > > >> panthor_device_resume/suspend() are called called in the init/unplug
> > > >> path when !PM, as I don't think the PM helpers automate that for us. I
> > > >> was just aiming for a simple fix that wouldn't force me to test the !PM
> > > >> case...  
> > > > Fair enough, at worst we could always have a runtime check and refuse to
> > > > probe in conditions we don't think are worth the bother of implementing
> > > > fully-functional support for. However if we want to make an argument for
> > > > only supporting "realistic" configs at build time then that is an
> > > > argument for dropping COMPILE_TEST as well.  
> > > 
> > > Can we just replace the "depends on PM" with "select PM"? In my
> > > (admittedly very limited) testing this works. Otherwise I think we need
> > > to bite the bullet and support !PM in some way (maybe just as Robin
> > > suggests with a runtime bail out).
> > 
> > I won't have time to test it this week, but if someone is interested,
> > here's a diff implementing manual resume/suspend in the init/unplug
> > path:
> >   
> > --->8---
> 
> This time with the diff :-)
> 
> --->8---  
> diff --git a/drivers/gpu/drm/panthor/panthor_device.c 
> b/drivers/gpu/drm/panthor/panthor_device.c
> index 69deb8e17778..3d05e7358f0e 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.c
> +++ b/drivers/gpu/drm/panthor/panthor_device.c
> @@ -87,6 +87,10 @@ void panthor_device_unplug(struct panthor_device *ptdev)
> pm_runtime_dont_use_autosuspend(ptdev->base.dev);
> pm_runtime_put_sync_suspend(ptdev->base.dev);
>  
> +   /* If PM is disabled, we need to call the suspend handler manually. */
> +   if (!IS_ENABLED(CONFIG_PM))
> +   panthor_device_suspend(ptdev->base.dev);
> +
> /* Report the unplug operation as done to unblock concurrent
>  * panthor_device_unplug() ca

  1   2   >