Re: [PATCH v1 24/35] drm/vc4: vec: Add support for more analog TV standards

2022-07-29 Thread Mateusz Kwiatkowski

Hi Maxime,

I think that declaring PAL-B and SECAM-B as the only supported 576i 
norms is a bit random.


Norms B, D, G, H, I, K, K1 and L (for both PAL and SECAM) are 
essentially identical if we're talking about baseband signals, AFAIK 
they only differ when those are modulated as RF signals. I'm not sure if 
there's a point to differentiating those (that's more about patch 05/35) 
unless we need to deal with some device that actually features an RF 
modulator.


But if we do want to have all those norms separate, then I'd say that 
VC4 should declare support for all of those, and all should map to the 
same VEC settings. Some users from e.g. the UK might think that they 
won't get proper picture if PAL-I is not on the list of supported norms. 
Same goes for e.g. SECAM-D/K in the former Soviet territories, and so on.


Best regards,
Mateusz Kwiatkowski

W dniu 29.07.2022 o 18:35, Maxime Ripard pisze:

From: Mateusz Kwiatkowski 

Add support for the following composite output modes (all of them are
somewhat more obscure than the previously defined ones):

- NTSC_443 - NTSC-style signal with the chroma subcarrier shifted to
   4.43361875 MHz (the PAL subcarrier frequency). Never used for
   broadcasting, but sometimes used as a hack to play NTSC content in PAL
   regions (e.g. on VCRs).
- PAL_N - PAL with alternative chroma subcarrier frequency,
   3.58205625 MHz. Used as a broadcast standard in Argentina, Paraguay
   and Uruguay to fit 576i50 with colour in 6 MHz channel raster.
- PAL60 - 480i60 signal with PAL-style color at normal European PAL
   frequency. Another non-standard, non-broadcast mode, used in similar
   contexts as NTSC_443. Some displays support one but not the other.
- SECAM - French frequency-modulated analog color standard; also have
   been broadcast in Eastern Europe and various parts of Africa and Asia.
   Uses the same 576i50 timings as PAL.

Also added some comments explaining color subcarrier frequency
registers.

Signed-off-by: Mateusz Kwiatkowski 
Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index e40b55de1b3c..91d343238b0f 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -46,6 +46,7 @@
  #define VEC_CONFIG0_YDEL(x)   ((x) << 26)
  #define VEC_CONFIG0_CDEL_MASK GENMASK(25, 24)
  #define VEC_CONFIG0_CDEL(x)   ((x) << 24)
+#define VEC_CONFIG0_SECAM_STD  BIT(21)
  #define VEC_CONFIG0_PBPR_FIL  BIT(18)
  #define VEC_CONFIG0_CHROMA_GAIN_MASK  GENMASK(17, 16)
  #define VEC_CONFIG0_CHROMA_GAIN_UNITY (0 << 16)
@@ -76,6 +77,27 @@
  #define VEC_SOFT_RESET0x10c
  #define VEC_CLMP0_START   0x144
  #define VEC_CLMP0_END 0x148
+
+/*
+ * These set the color subcarrier frequency
+ * if VEC_CONFIG1_CUSTOM_FREQ is enabled.
+ *
+ * VEC_FREQ1_0 contains the most significant 16-bit half-word,
+ * VEC_FREQ3_2 contains the least significant 16-bit half-word.
+ * 0x8000 seems to be equivalent to the pixel clock
+ * (which itself is the VEC clock divided by 8).
+ *
+ * Reference values (with the default pixel clock of 13.5 MHz):
+ *
+ * NTSC  (3579545.[45] Hz) - 0x21F07C1F
+ * PAL   (4433618.75 Hz)   - 0x2A098ACB
+ * PAL-M (3575611.[888111] Hz) - 0x21E6EFE3
+ * PAL-N (3582056.25 Hz)   - 0x21F69446
+ *
+ * NOTE: For SECAM, it is used as the Dr center frequency,
+ * regardless of whether VEC_CONFIG1_CUSTOM_FREQ is enabled or not;
+ * that is specified as 4406250 Hz, which corresponds to 0x29C71C72.
+ */
  #define VEC_FREQ3_2   0x180
  #define VEC_FREQ1_0   0x184
  
@@ -118,6 +140,14 @@
  
  #define VEC_INTERRUPT_CONTROL		0x190

  #define VEC_INTERRUPT_STATUS  0x194
+
+/*
+ * Db center frequency for SECAM; the clock for this is the same as for
+ * VEC_FREQ3_2/VEC_FREQ1_0, which is used for Dr center frequency.
+ *
+ * This is specified as 425 Hz, which corresponds to 0x284BDA13.
+ * That is also the default value, so no need to set it explicitly.
+ */
  #define VEC_FCW_SECAM_B   0x198
  #define VEC_SECAM_GAIN_VAL0x19c
  
@@ -194,9 +224,13 @@ connector_to_vc4_vec(struct drm_connector *connector)
  
  enum vc4_vec_tv_mode_id {

VC4_VEC_TV_MODE_NTSC,
+   VC4_VEC_TV_MODE_NTSC_443,
VC4_VEC_TV_MODE_NTSC_J,
VC4_VEC_TV_MODE_PAL,
+   VC4_VEC_TV_MODE_PAL_60,
VC4_VEC_TV_MODE_PAL_M,
+   VC4_VEC_TV_MODE_PAL_N,
+   VC4_VEC_TV_MODE_SECAM,
  };
  
  struct vc4_vec_tv_mode {

@@ -234,6 +268,12 @@ static const struct debugfs_reg32 vec_regs[] = {
  };
  
  static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {

+   {
+   .mode = DRM_MODE_TV_NORM_NTSC_443,
+   .config0 = VEC_CONFIG0_NTSC_STD,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+   .custom_freq = 0x2a098acb,
+   },
{
.mode = DRM_MODE_

Re: [PATCH v1 20/35] drm/vc4: vec: Switch for common modes

2022-07-29 Thread Mateusz Kwiatkowski

Hi Maxime,

I'm just noting that the modelines you defined in drm_modes.c are 
different to the ones you're removing here.


The horizontal sync differences probably doesn't matter too much, VC4 
uses those only as a hint anyway and generates sync autonomously, so the 
slight differences will only cause the image to slightly shift horizontally.


But you're also changing the 480i vertical sync (vsync_start is now 488 
instead of 487, etc.). Are you sure that this won't break anything? This 
will probably shift the image by 1 line (which for the 480i might 
actually mean going out of spec), and I _think_ it might control the odd 
vs. even field first modes on some drivers. I won't be able to test this 
before Monday, but I'm just pointing out the potential issue.


BTW, I've seen a similar thing in the sun4i driver changes (patch 32/35) 
and the differences in vertical sync are even more dramatic. It's 
entirely possible that the current timings in sun4i are broken and the 
new ones are correct (the new ones certainly look saner to me), but I'd 
double-check if that driver does not have any quirks that would 
_require_ such weird settings.


Best regards,
Mateusz Kwiatkowski

W dniu 29.07.2022 o 18:35, Maxime Ripard pisze:

Now that the core has a definition for the 525 and 625 lines analog TV
modes, let's switch to it for vc4.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 8f30a530b2d5..255bba563fce 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -224,38 +224,24 @@ static const struct debugfs_reg32 vec_regs[] = {
VC4_REG32(VEC_DAC_MISC),
  };
  
-static const struct drm_display_mode ntsc_mode = {

-   DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
-720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
-480, 480 + 7, 480 + 7 + 6, 525, 0,
-DRM_MODE_FLAG_INTERLACE)
-};
-
-static const struct drm_display_mode pal_mode = {
-   DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
-720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
-576, 576 + 4, 576 + 4 + 6, 625, 0,
-DRM_MODE_FLAG_INTERLACE)
-};
-
  static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
[VC4_VEC_TV_MODE_NTSC] = {
-   .mode = &ntsc_mode,
+   .mode = &drm_mode_480i,
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_NTSC_J] = {
-   .mode = &ntsc_mode,
+   .mode = &drm_mode_480i,
.config0 = VEC_CONFIG0_NTSC_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_PAL] = {
-   .mode = &pal_mode,
+   .mode = &drm_mode_576i,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_PAL_M] = {
-   .mode = &pal_mode,
+   .mode = &drm_mode_576i,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
.custom_freq = 0x223b61d1,





Re: [PATCH v1 14/35] drm/atomic-helper: Add an analog TV atomic_check implementation

2022-07-29 Thread Mateusz Kwiatkowski

Hi Maxime,

I'm pretty sure that PAL-60 and SECAM-60 should be tied to the 480i 
mode. Those are non-standard "norms" that use 60 Hz sync (which is 
largely synonymous with 480i in the analog TV world) with PAL/SECAM 
color encoding.


Best regards,
Mateusz Kwiatkowski

W dniu 29.07.2022 o 18:34, Maxime Ripard pisze:

The analog TV connector drivers share some atomic_check logic, and the new
TV standard property have created a bunch of new constraints that needs to
be shared across drivers too.

Let's create an atomic_check helper for those use cases.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 6d14cb0c64b1..fce5569bd66a 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -552,6 +552,93 @@ void drm_atomic_helper_connector_tv_reset(struct 
drm_connector *connector)
  }
  EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
  
+/**

+ * @drm_atomic_helper_connector_tv_check: Validate an analog TV connector state
+ * @connector: DRM Connector
+ * @state: the DRM State object
+ *
+ * Checks the state object to see if the requested state is valid for an
+ * analog TV connector.
+ *
+ * Returns:
+ * Zero for success, a negative error code on error.
+ */
+int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
+struct drm_atomic_state *state)
+{
+   struct drm_connector_state *old_conn_state =
+   drm_atomic_get_old_connector_state(state, connector);
+   struct drm_connector_state *new_conn_state =
+   drm_atomic_get_new_connector_state(state, connector);
+   const struct drm_display_mode *mode;
+   struct drm_crtc_state *crtc_state;
+   struct drm_crtc *crtc;
+
+   crtc = new_conn_state->crtc;
+   if (!crtc)
+   return 0;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   if (!crtc_state)
+   return -EINVAL;
+
+   switch (new_conn_state->tv.norm) {
+   case DRM_MODE_TV_NORM_NTSC_443:
+   fallthrough;
+   case DRM_MODE_TV_NORM_NTSC_J:
+   fallthrough;
+   case DRM_MODE_TV_NORM_NTSC_M:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_M:
+   mode = &drm_mode_480i;
+   break;
+
+   case DRM_MODE_TV_NORM_PAL_60:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_B:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_D:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_G:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_H:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_I:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_N:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_NC:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_60:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_B:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_D:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_G:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_K:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_K1:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_L:
+   mode = &drm_mode_576i;
+   break;
+
+   default:
+   return -EINVAL;
+   }
+
+   if (!drm_mode_equal(mode, &crtc_state->mode))
+   return -EINVAL;
+
+   if (old_conn_state->tv.norm != new_conn_state->tv.norm)
+   crtc_state->mode_changed = true;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
+
  /**
   * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
   * @connector: connector object
diff --git a/include/drm/drm_atomic_state_helper.h 
b/include/drm/drm_atomic_state_helper.h
index c8fbce795ee7..b9740edb2658 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -26,6 +26,7 @@
  
  #include 
  
+struct drm_atomic_state;

  struct drm_bridge;
  struct drm_bridge_state;
  struct drm_crtc;
@@ -71,6 +72,8 @@ 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_tv_reset(struct drm_connector *connector);
+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,





Re: [PATCH 1/3] dma-buf: Add ioctl to query mmap info

2022-07-29 Thread kernel test robot
Hi Rob,

I love your patch! Yet something to improve:

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

url:
https://github.com/intel-lab-lkp/linux/commits/Rob-Clark/dma-buf-map-info-support/20220730-010844
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
6e2c0490769ef8a95b61304389116ccc85c53e12
config: arm-randconfig-r033-20220729 
(https://download.01.org/0day-ci/archive/20220730/202207301450.m4ick2bg-...@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 
52cd00cabf479aa7eb6dbb063b7ba41ea57bce9e)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# 
https://github.com/intel-lab-lkp/linux/commit/203f14a73a179d6c5fbfa4813e45fde2a9ae9860
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Rob-Clark/dma-buf-map-info-support/20220730-010844
git checkout 203f14a73a179d6c5fbfa4813e45fde2a9ae9860
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=arm SHELL=/bin/bash drivers/dma-buf/

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

All errors (new ones prefixed by >>):

>> drivers/dma-buf/dma-buf.c:346:19: error: passing 'const void *' to parameter 
>> of type 'void *' discards qualifiers 
>> [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
   if (copy_to_user(uarg, &arg, sizeof(arg)))
^~~~
   include/linux/uaccess.h:157:27: note: passing argument to parameter 'to' here
   copy_to_user(void __user *to, const void *from, unsigned long n)
 ^
   1 error generated.


vim +346 drivers/dma-buf/dma-buf.c

   328  
   329  static long dma_buf_info(struct dma_buf *dmabuf, const void __user 
*uarg)
   330  {
   331  struct dma_buf_info arg;
   332  
   333  if (copy_from_user(&arg, uarg, sizeof(arg)))
   334  return -EFAULT;
   335  
   336  switch (arg.param) {
   337  case DMA_BUF_INFO_VM_PROT:
   338  if (!dmabuf->ops->mmap_info)
   339  return -ENOSYS;
   340  arg.value = dmabuf->ops->mmap_info(dmabuf);
   341  break;
   342  default:
   343  return -EINVAL;
   344  }
   345  
 > 346  if (copy_to_user(uarg, &arg, sizeof(arg)))
   347  return -EFAULT;
   348  
   349  return 0;
   350  }
   351  

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


Re: Stack-frame warnings in display_mode_vba_32.c

2022-07-29 Thread Paul E. McKenney
On Fri, Jul 29, 2022 at 11:41:55PM -0300, André Almeida wrote:
> Hi Paul,
> 
> Às 23:25 de 29/07/22, Paul E. McKenney escreveu:
> > Hello!
> > 
> > I am seeing the following in allmodconfig builds of recent -next on x86:
> > 
> > drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c: 
> > In function 
> > ‘DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation’:
> > drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c:1659:1:
> >  error: the frame size of 2144 bytes is larger than 2048 bytes 
> > [-Werror=frame-larger-than=]
> >  1659 | }
> >   | ^
> > drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c: 
> > In function ‘dml32_ModeSupportAndSystemConfigurationFull’:
> > drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c:3799:1:
> >  error: the frame size of 2480 bytes is larger than 2048 bytes 
> > [-Werror=frame-larger-than=]
> >  3799 | } // ModeSupportAndSystemConfigurationFull
> >   | ^
> 
> I think they are fixed at amd-staging-drm-next:
> 
> git log --oneline amd/amd-staging-drm-next
> drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
> 953daa61981b drm/amd/display: Reduce stack size in the mode support function
> 361e705e712d drm/amd/display: reduce stack for
> dml32_CalculatePrefetchSchedule
> f2dbf5a4dd1e drm/amd/display: reduce stack for
> dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport
> a0a68cda2ef8 drm/amd/display: reduce stack for dml32_CalculateVMRowAndSwath
> ca6730ca0f01 drm/amd/display: reduce stack for
> dml32_CalculateSwathAndDETConfiguration
> 593eef8c1a5e drm/amd/display: reduce stack size in dcn32 dml (v2)
> 
> https://gitlab.freedesktop.org/agd5f/linux/-/commits/amd-staging-drm-next/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c

Very good, thank you!  I will test again on the next -next.

Thanx, Paul

> > Bisection located the commit shown below.  Doing an allmodconfig build
> > on this commit reproduces the error, its parent builds fine.
> > 
> > Thoughts?
> > 
> > Thanx, Paul
> > 
> > 
> > 
> > commit 3876a8b5e241081b2a519f848a65c00d8e6cd124
> > Author: Guenter Roeck 
> > Date:   Tue Jul 12 15:42:47 2022 -0700
> > 
> > drm/amd/display: Enable building new display engine with KCOV enabled
> > 
> > The new display engine uses floating point math, which is not supported
> > by KCOV. Commit 9d1d02ff3678 ("drm/amd/display: Don't build DCN1 when 
> > kcov
> > is enabled") tried to work around the problem by disabling
> > CONFIG_DRM_AMD_DC_DCN if KCOV_INSTRUMENT_ALL and KCOV_ENABLE_COMPARISONS
> > are enabled. The result is that KCOV can not be enabled on systems which
> > require this display engine. A much simpler and less invasive solution 
> > is
> > to disable KCOV selectively when compiling the display enagine while
> > keeping it enabled for the rest of the kernel.
> > 
> > Fixes: 9d1d02ff3678 ("drm/amd/display: Don't build DCN1 when kcov is 
> > enabled")
> > Cc: Arnd Bergmann 
> > Cc: Leo Li 
> > Reviewed-by: Harry Wentland 
> > Signed-off-by: Guenter Roeck 
> > Signed-off-by: Alex Deucher 
> > 
> > diff --git a/drivers/gpu/drm/amd/display/Kconfig 
> > b/drivers/gpu/drm/amd/display/Kconfig
> > index b4029c0d5d8c5..96cbc87f7b6b8 100644
> > --- a/drivers/gpu/drm/amd/display/Kconfig
> > +++ b/drivers/gpu/drm/amd/display/Kconfig
> > @@ -6,7 +6,7 @@ config DRM_AMD_DC
> > bool "AMD DC - Enable new display engine"
> > default y
> > select SND_HDA_COMPONENT if SND_HDA_CORE
> > -   select DRM_AMD_DC_DCN if (X86 || PPC64) && !(KCOV_INSTRUMENT_ALL && 
> > KCOV_ENABLE_COMPARISONS)
> > +   select DRM_AMD_DC_DCN if (X86 || PPC64)
> > help
> >   Choose this option if you want to use the new display engine
> >   support for AMDGPU. This adds required support for Vega and
> > diff --git a/drivers/gpu/drm/amd/display/dc/Makefile 
> > b/drivers/gpu/drm/amd/display/dc/Makefile
> > index 273f8f2c8e020..b9effadfc4bb7 100644
> > --- a/drivers/gpu/drm/amd/display/dc/Makefile
> > +++ b/drivers/gpu/drm/amd/display/dc/Makefile
> > @@ -25,6 +25,9 @@
> >  DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual
> >  
> >  ifdef CONFIG_DRM_AMD_DC_DCN
> > +
> > +KCOV_INSTRUMENT := n
> > +
> >  DC_LIBS += dcn20
> >  DC_LIBS += dsc
> >  DC_LIBS += dcn10


[PATCHv2 -next] drm/amdgpu: double free error and freeing uninitialized null pointer

2022-07-29 Thread Sebin Sebastian
Fix a double free and an uninitialized pointer read error. Both tmp and
new are pointing at same address and both are freed which leads to
double free. Adding a check to verify if new and tmp are free in the
error_free label fixes the double free issue. new is not initialized to
null which also leads to a free on an uninitialized pointer.

Suggested by: S. Amaranath 
Signed-off-by: Sebin Sebastian 
---
Changes in v2:
Updated patch body as suggested by André Almeida 
Reworked to implement a check in error_free for fixing double free error
as suggested by S. Amaranath 

 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index e2eec985adb3..cb00c7d6f50b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1705,7 +1705,7 @@ static ssize_t 
amdgpu_reset_dump_register_list_write(struct file *f,
 {
struct amdgpu_device *adev = (struct amdgpu_device 
*)file_inode(f)->i_private;
char reg_offset[11];
-   uint32_t *new, *tmp = NULL;
+   uint32_t *new = NULL, *tmp = NULL;
int ret, i = 0, len = 0;
 
do {
@@ -1747,7 +1747,8 @@ static ssize_t 
amdgpu_reset_dump_register_list_write(struct file *f,
ret = size;
 
 error_free:
-   kfree(tmp);
+   if (tmp != new)
+   kfree(tmp);
kfree(new);
return ret;
 }
-- 
2.34.1



Re: [PATCH v1 22/35] drm/vc4: vec: Use TV Reset implementation

2022-07-29 Thread kernel test robot
Hi Maxime,

I love your patch! Perhaps something to improve:

[auto build test WARNING on 37b355fdaf31ee18bda9a93c2a438dc1cbf57ec9]

url:
https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/drm-Analog-TV-Improvements/20220730-004859
base:   37b355fdaf31ee18bda9a93c2a438dc1cbf57ec9
config: powerpc-allmodconfig 
(https://download.01.org/0day-ci/archive/20220730/202207301024.h3rifgqo-...@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/2f380bf85052b89ae0ffc6cfdf2dc91cdcde5a75
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Maxime-Ripard/drm-Analog-TV-Improvements/20220730-004859
git checkout 2f380bf85052b89ae0ffc6cfdf2dc91cdcde5a75
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=powerpc SHELL=/bin/bash drivers/gpu/drm/vc4/

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

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/vc4/vc4_vec.c:257:6: warning: no previous prototype for 
>> 'vc4_vec_connector_reset' [-Wmissing-prototypes]
 257 | void vc4_vec_connector_reset(struct drm_connector *connector)
 |  ^~~


vim +/vc4_vec_connector_reset +257 drivers/gpu/drm/vc4/vc4_vec.c

   256  
 > 257  void vc4_vec_connector_reset(struct drm_connector *connector)
   258  {
   259  drm_atomic_helper_connector_reset(connector);
   260  drm_atomic_helper_connector_tv_reset(connector);
   261  }
   262  

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


Re: [PATCH 1/3] dma-buf: Add ioctl to query mmap info

2022-07-29 Thread kernel test robot
Hi Rob,

I love your patch! Perhaps something to improve:

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

url:
https://github.com/intel-lab-lkp/linux/commits/Rob-Clark/dma-buf-map-info-support/20220730-010844
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
6e2c0490769ef8a95b61304389116ccc85c53e12
config: m68k-randconfig-s032-20220729 
(https://download.01.org/0day-ci/archive/20220730/202207301057.kvtytw6h-...@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# 
https://github.com/intel-lab-lkp/linux/commit/203f14a73a179d6c5fbfa4813e45fde2a9ae9860
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Rob-Clark/dma-buf-map-info-support/20220730-010844
git checkout 203f14a73a179d6c5fbfa4813e45fde2a9ae9860
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 
CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=m68k 
SHELL=/bin/bash

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

sparse warnings: (new ones prefixed by >>)
>> drivers/dma-buf/dma-buf.c:346:26: sparse: sparse: incorrect type in argument 
>> 1 (different modifiers) @@ expected void [noderef] __user *to @@ got 
>> void const [noderef] __user *uarg @@
   drivers/dma-buf/dma-buf.c:346:26: sparse: expected void [noderef] __user 
*to
   drivers/dma-buf/dma-buf.c:346:26: sparse: got void const [noderef] 
__user *uarg

vim +346 drivers/dma-buf/dma-buf.c

   328  
   329  static long dma_buf_info(struct dma_buf *dmabuf, const void __user 
*uarg)
   330  {
   331  struct dma_buf_info arg;
   332  
   333  if (copy_from_user(&arg, uarg, sizeof(arg)))
   334  return -EFAULT;
   335  
   336  switch (arg.param) {
   337  case DMA_BUF_INFO_VM_PROT:
   338  if (!dmabuf->ops->mmap_info)
   339  return -ENOSYS;
   340  arg.value = dmabuf->ops->mmap_info(dmabuf);
   341  break;
   342  default:
   343  return -EINVAL;
   344  }
   345  
 > 346  if (copy_to_user(uarg, &arg, sizeof(arg)))
   347  return -EFAULT;
   348  
   349  return 0;
   350  }
   351  

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


Re: Stack-frame warnings in display_mode_vba_32.c

2022-07-29 Thread André Almeida
Hi Paul,

Às 23:25 de 29/07/22, Paul E. McKenney escreveu:
> Hello!
> 
> I am seeing the following in allmodconfig builds of recent -next on x86:
> 
> drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c: In 
> function 
> ‘DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation’:
> drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c:1659:1:
>  error: the frame size of 2144 bytes is larger than 2048 bytes 
> [-Werror=frame-larger-than=]
>  1659 | }
>   | ^
> drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c: In 
> function ‘dml32_ModeSupportAndSystemConfigurationFull’:
> drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c:3799:1:
>  error: the frame size of 2480 bytes is larger than 2048 bytes 
> [-Werror=frame-larger-than=]
>  3799 | } // ModeSupportAndSystemConfigurationFull
>   | ^

I think they are fixed at amd-staging-drm-next:

git log --oneline amd/amd-staging-drm-next
drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
953daa61981b drm/amd/display: Reduce stack size in the mode support function
361e705e712d drm/amd/display: reduce stack for
dml32_CalculatePrefetchSchedule
f2dbf5a4dd1e drm/amd/display: reduce stack for
dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport
a0a68cda2ef8 drm/amd/display: reduce stack for dml32_CalculateVMRowAndSwath
ca6730ca0f01 drm/amd/display: reduce stack for
dml32_CalculateSwathAndDETConfiguration
593eef8c1a5e drm/amd/display: reduce stack size in dcn32 dml (v2)

https://gitlab.freedesktop.org/agd5f/linux/-/commits/amd-staging-drm-next/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c

> 
> Bisection located the commit shown below.  Doing an allmodconfig build
> on this commit reproduces the error, its parent builds fine.
> 
> Thoughts?
> 
>   Thanx, Paul
> 
> 
> 
> commit 3876a8b5e241081b2a519f848a65c00d8e6cd124
> Author: Guenter Roeck 
> Date:   Tue Jul 12 15:42:47 2022 -0700
> 
> drm/amd/display: Enable building new display engine with KCOV enabled
> 
> The new display engine uses floating point math, which is not supported
> by KCOV. Commit 9d1d02ff3678 ("drm/amd/display: Don't build DCN1 when kcov
> is enabled") tried to work around the problem by disabling
> CONFIG_DRM_AMD_DC_DCN if KCOV_INSTRUMENT_ALL and KCOV_ENABLE_COMPARISONS
> are enabled. The result is that KCOV can not be enabled on systems which
> require this display engine. A much simpler and less invasive solution is
> to disable KCOV selectively when compiling the display enagine while
> keeping it enabled for the rest of the kernel.
> 
> Fixes: 9d1d02ff3678 ("drm/amd/display: Don't build DCN1 when kcov is 
> enabled")
> Cc: Arnd Bergmann 
> Cc: Leo Li 
> Reviewed-by: Harry Wentland 
> Signed-off-by: Guenter Roeck 
> Signed-off-by: Alex Deucher 
> 
> diff --git a/drivers/gpu/drm/amd/display/Kconfig 
> b/drivers/gpu/drm/amd/display/Kconfig
> index b4029c0d5d8c5..96cbc87f7b6b8 100644
> --- a/drivers/gpu/drm/amd/display/Kconfig
> +++ b/drivers/gpu/drm/amd/display/Kconfig
> @@ -6,7 +6,7 @@ config DRM_AMD_DC
>   bool "AMD DC - Enable new display engine"
>   default y
>   select SND_HDA_COMPONENT if SND_HDA_CORE
> - select DRM_AMD_DC_DCN if (X86 || PPC64) && !(KCOV_INSTRUMENT_ALL && 
> KCOV_ENABLE_COMPARISONS)
> + select DRM_AMD_DC_DCN if (X86 || PPC64)
>   help
> Choose this option if you want to use the new display engine
> support for AMDGPU. This adds required support for Vega and
> diff --git a/drivers/gpu/drm/amd/display/dc/Makefile 
> b/drivers/gpu/drm/amd/display/dc/Makefile
> index 273f8f2c8e020..b9effadfc4bb7 100644
> --- a/drivers/gpu/drm/amd/display/dc/Makefile
> +++ b/drivers/gpu/drm/amd/display/dc/Makefile
> @@ -25,6 +25,9 @@
>  DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual
>  
>  ifdef CONFIG_DRM_AMD_DC_DCN
> +
> +KCOV_INSTRUMENT := n
> +
>  DC_LIBS += dcn20
>  DC_LIBS += dsc
>  DC_LIBS += dcn10


Stack-frame warnings in display_mode_vba_32.c

2022-07-29 Thread Paul E. McKenney
Hello!

I am seeing the following in allmodconfig builds of recent -next on x86:

drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c: In 
function 
‘DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation’:
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c:1659:1:
 error: the frame size of 2144 bytes is larger than 2048 bytes 
[-Werror=frame-larger-than=]
 1659 | }
  | ^
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c: In 
function ‘dml32_ModeSupportAndSystemConfigurationFull’:
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn32/display_mode_vba_32.c:3799:1:
 error: the frame size of 2480 bytes is larger than 2048 bytes 
[-Werror=frame-larger-than=]
 3799 | } // ModeSupportAndSystemConfigurationFull
  | ^

Bisection located the commit shown below.  Doing an allmodconfig build
on this commit reproduces the error, its parent builds fine.

Thoughts?

Thanx, Paul



commit 3876a8b5e241081b2a519f848a65c00d8e6cd124
Author: Guenter Roeck 
Date:   Tue Jul 12 15:42:47 2022 -0700

drm/amd/display: Enable building new display engine with KCOV enabled

The new display engine uses floating point math, which is not supported
by KCOV. Commit 9d1d02ff3678 ("drm/amd/display: Don't build DCN1 when kcov
is enabled") tried to work around the problem by disabling
CONFIG_DRM_AMD_DC_DCN if KCOV_INSTRUMENT_ALL and KCOV_ENABLE_COMPARISONS
are enabled. The result is that KCOV can not be enabled on systems which
require this display engine. A much simpler and less invasive solution is
to disable KCOV selectively when compiling the display enagine while
keeping it enabled for the rest of the kernel.

Fixes: 9d1d02ff3678 ("drm/amd/display: Don't build DCN1 when kcov is 
enabled")
Cc: Arnd Bergmann 
Cc: Leo Li 
Reviewed-by: Harry Wentland 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alex Deucher 

diff --git a/drivers/gpu/drm/amd/display/Kconfig 
b/drivers/gpu/drm/amd/display/Kconfig
index b4029c0d5d8c5..96cbc87f7b6b8 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -6,7 +6,7 @@ config DRM_AMD_DC
bool "AMD DC - Enable new display engine"
default y
select SND_HDA_COMPONENT if SND_HDA_CORE
-   select DRM_AMD_DC_DCN if (X86 || PPC64) && !(KCOV_INSTRUMENT_ALL && 
KCOV_ENABLE_COMPARISONS)
+   select DRM_AMD_DC_DCN if (X86 || PPC64)
help
  Choose this option if you want to use the new display engine
  support for AMDGPU. This adds required support for Vega and
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile 
b/drivers/gpu/drm/amd/display/dc/Makefile
index 273f8f2c8e020..b9effadfc4bb7 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -25,6 +25,9 @@
 DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual
 
 ifdef CONFIG_DRM_AMD_DC_DCN
+
+KCOV_INSTRUMENT := n
+
 DC_LIBS += dcn20
 DC_LIBS += dsc
 DC_LIBS += dcn10


[PATCH v2 3/3] drm/amd/display: include missing headers

2022-07-29 Thread Magali Lemes
Add missing headers to solve the following warnings from sparse:

drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/dcn20_fpu.c:656:17: warning: 
symbol 'ddr4_wm_table_gs' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/dcn20_fpu.c:693:17: warning: 
symbol 'lpddr4_wm_table_gs' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/dcn20_fpu.c:730:17: warning: 
symbol 'lpddr4_wm_table_with_disabled_ppt' was not declared. Should it be 
static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/dcn20_fpu.c:767:17: warning: 
symbol 'ddr4_wm_table_rn' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/dcn20_fpu.c:804:17: warning: 
symbol 'ddr4_1R_wm_table_rn' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/dcn20_fpu.c:841:17: warning: 
symbol 'lpddr4_wm_table_rn' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn301/dcn301_fpu.c:217:17: 
warning: symbol 'ddr4_wm_table' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn301/dcn301_fpu.c:254:17: 
warning: symbol 'lpddr5_wm_table' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn31/dcn31_fpu.c:53:30: warning: 
symbol 'dcn3_1_ip' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn31/dcn31_fpu.c:197:30: warning: 
symbol 'dcn3_15_ip' was not declared. Should it be static?
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn31/dcn31_fpu.c:293:30: warning: 
symbol 'dcn3_16_ip' was not declared. Should it be static?

Fixes: 490d2bc889f1 ("drm/amd/display: move FPU code on dcn21 clk_mgr")
Fixes: 83916f9a32a4 ("drm/amd/display: move FPU code from dcn301 clk mgr to DML 
folder")
Fixes: 26f4712aedbd ("drm/amd/display: move FPU related code from dcn31 to 
dml/dcn31 folder")
Fixes: fa896297b31b ("drm/amd/display: move FPU related code from dcn315 to 
dml/dcn31 folder")
Fixes: 3f8951cc123f ("drm/amd/display: move FPU related code from dcn316 to 
dml/dcn31 folder")
Signed-off-by: Magali Lemes 
Reviewed-by: Maíra Canal 
Reviewed-by: Melissa Wen 
---
Changes in v2:
  - split commit (Melissa)
  - update the commit message accordingly
  - add Fixes and Reviewed-by tags.

 drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c   | 1 +
 drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c | 1 +
 drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c   | 3 +++
 3 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
index ca44df4fca74..d34e0f1314d9 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
@@ -30,6 +30,7 @@
 #include "dchubbub.h"
 #include "dcn20/dcn20_resource.h"
 #include "dcn21/dcn21_resource.h"
+#include "clk_mgr/dcn21/rn_clk_mgr.h"
 
 #include "dcn20_fpu.h"
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
index 7ef66e511ec8..d211cf6d234c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
@@ -26,6 +26,7 @@
 #include "clk_mgr.h"
 #include "dcn20/dcn20_resource.h"
 #include "dcn301/dcn301_resource.h"
+#include "clk_mgr/dcn301/vg_clk_mgr.h"
 
 #include "dml/dcn20/dcn20_fpu.h"
 #include "dcn301_fpu.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
index 5664653ba5ac..149a1b17cdf3 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
@@ -25,6 +25,9 @@
 
 #include "resource.h"
 #include "clk_mgr.h"
+#include "dcn31/dcn31_resource.h"
+#include "dcn315/dcn315_resource.h"
+#include "dcn316/dcn316_resource.h"
 
 #include "dml/dcn20/dcn20_fpu.h"
 #include "dcn31_fpu.h"
-- 
2.37.1



[PATCH v2 2/3] drm/amd/display: remove header from source file

2022-07-29 Thread Magali Lemes
Since "rn_clk_mgr.h" needs ‘struct clk_mgr_internal’ which is declared
in "clk_mgr_internal.h", include "clk_mgr_internal.h" in "rn_clk_mgr.h"
instead of in its source file.
Because of the change above, change the order of '#include
"rn_clk_mgr.h"', so that the necessary structs are visible to
dcn20_clk_mgr.h.

Signed-off-by: Magali Lemes 
Reviewed-by: Maíra Canal 
Reviewed-by: Melissa Wen 
---
Changes in v2:
  - split commit (Melissa).

 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 3 +--
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h | 1 +
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
index 0202dc682682..ca6dfd2d7561 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
@@ -24,10 +24,9 @@
  */
 
 #include "dccg.h"
-#include "clk_mgr_internal.h"
+#include "rn_clk_mgr.h"
 
 #include "dcn20/dcn20_clk_mgr.h"
-#include "rn_clk_mgr.h"
 #include "dml/dcn20/dcn20_fpu.h"
 
 #include "dce100/dce_clk_mgr.h"
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h
index 2e088c5171b2..f1319957e400 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h
@@ -28,6 +28,7 @@
 
 #include "clk_mgr.h"
 #include "dm_pp_smu.h"
+#include "clk_mgr_internal.h"
 
 extern struct wm_table ddr4_wm_table_gs;
 extern struct wm_table lpddr4_wm_table_gs;
-- 
2.37.1



[PATCH v2 1/3] drm/amd/display: make variables static

2022-07-29 Thread Magali Lemes
As "dcn3_1_soc", "dcn3_15_soc", and "dcn3_16_soc" are not used outside
of their corresponding "dcn3*_fpu.c", make them static and remove their
extern declaration.

Fixes: 26f4712aedbd ("drm/amd/display: move FPU related code from dcn31 to 
dml/dcn31 folder")
Fixes: fa896297b31b ("drm/amd/display: move FPU related code from dcn315 to 
dml/dcn31 folder")
Fixes: 3f8951cc123f ("drm/amd/display: move FPU related code from dcn316 to 
dml/dcn31 folder")
Signed-off-by: Magali Lemes 
Reviewed-by: Maíra Canal 
Reviewed-by: Melissa Wen 
---
Changes in v2:
  - remove the extern declaration of "dcn3_15_soc" and "dcn3_16_soc"
  instead of just fixing their type (Melissa and André)
  - apply this fix to "dcn3_1_soc" as well
  - update the commit message accordingly
  - add Fixes and Reviewed-by tags.

 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h   | 1 -
 drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h | 1 -
 drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h | 1 -
 drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c| 6 +++---
 4 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h 
b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
index 41f8ec99da6b..901436591ed4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
@@ -32,7 +32,6 @@
container_of(pool, struct dcn31_resource_pool, base)
 
 extern struct _vcs_dpi_ip_params_st dcn3_1_ip;
-extern struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc;
 
 struct dcn31_resource_pool {
struct resource_pool base;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h 
b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
index 39929fa67a51..22849eaa6f24 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
@@ -32,7 +32,6 @@
container_of(pool, struct dcn315_resource_pool, base)
 
 extern struct _vcs_dpi_ip_params_st dcn3_15_ip;
-extern struct _vcs_dpi_ip_params_st dcn3_15_soc;
 
 struct dcn315_resource_pool {
struct resource_pool base;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h 
b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
index 0dc5a6c13ae7..aba6d634131b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
@@ -32,7 +32,6 @@
container_of(pool, struct dcn316_resource_pool, base)
 
 extern struct _vcs_dpi_ip_params_st dcn3_16_ip;
-extern struct _vcs_dpi_ip_params_st dcn3_16_soc;
 
 struct dcn316_resource_pool {
struct resource_pool base;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
index e36cfa5985ea..5664653ba5ac 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
@@ -114,7 +114,7 @@ struct _vcs_dpi_ip_params_st dcn3_1_ip = {
.dcc_supported = true,
 };
 
-struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = {
+static struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
@@ -259,7 +259,7 @@ struct _vcs_dpi_ip_params_st dcn3_15_ip = {
.dcc_supported = true,
 };
 
-struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
+static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
.sr_exit_time_us = 9.0,
.sr_enter_plus_exit_time_us = 11.0,
.sr_exit_z8_time_us = 50.0,
@@ -355,7 +355,7 @@ struct _vcs_dpi_ip_params_st dcn3_16_ip = {
.dcc_supported = true,
 };
 
-struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = {
+static struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
-- 
2.37.1



Re: [PATCH v3 03/11] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()

2022-07-29 Thread Stephen Boyd
Quoting Marijn Suijten (2022-06-29 15:53:23)
> Add the devres and non-devres variant of
> clk_hw_register_fixed_factor_parent_hw() for registering a fixed factor
> clock with clk_hw parent pointer instead of parent name.
> 
> Signed-off-by: Marijn Suijten 
> ---

Applied to clk-next


Re: [PATCH v3 02/11] clk: mux: Introduce devm_clk_hw_register_mux_parent_hws()

2022-07-29 Thread Stephen Boyd
Quoting Marijn Suijten (2022-06-29 15:53:22)
> Add the devres variant of clk_hw_register_mux_hws() for registering a
> mux clock with clk_hw parent pointers instead of parent names.
> 
> Signed-off-by: Marijn Suijten 
> Reviewed-by: Dmitry Baryshkov 
> ---

Applied to clk-next


Re: [PATCH v3 01/11] clk: divider: Introduce devm_clk_hw_register_divider_parent_hw()

2022-07-29 Thread Stephen Boyd
Quoting Marijn Suijten (2022-06-29 15:53:21)
> Add the devres variant of clk_hw_register_divider_parent_hw() for
> registering a divider clock with clk_hw parent pointer instead of parent
> name.
> 
> Signed-off-by: Marijn Suijten 
> Reviewed-by: Dmitry Baryshkov 
> ---

Applied to clk-next


Re: [PATCH v3 00/11] drm/msm/dsi_phy: Replace parent names with clk_hw pointers

2022-07-29 Thread Stephen Boyd
Quoting Dmitry Baryshkov (2022-07-14 03:19:12)
> On 30/06/2022 01:53, Marijn Suijten wrote:
> > Marijn Suijten (11):
> >clk: divider: Introduce devm_clk_hw_register_divider_parent_hw()
> >clk: mux: Introduce devm_clk_hw_register_mux_parent_hws()
> >clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()
> 
> Stephen, do we stand a chance of landing patches 1-3 into 5.20? We would 
> like to merge the series into 5.21 through the msm-next. Landing clk 
> patches in 5.20 would save us from using immutable branches, etc.
> 

Sure I can land the first three patches now for 5.20


Re: [PATCH] dt-bindings: display: use spi-peripheral-props.yaml

2022-07-29 Thread Rob Herring
On Wed, 27 Jul 2022 18:43:12 +0200, Krzysztof Kozlowski wrote:
> Instead of listing directly properties typical for SPI peripherals,
> reference the spi-peripheral-props.yaml schema.  This allows using all
> properties typical for SPI-connected devices, even these which device
> bindings author did not tried yet.
> 
> Remove the spi-* properties which now come via spi-peripheral-props.yaml
> schema, except for the cases when device schema adds some constraints
> like maximum frequency.
> 
> While changing additionalProperties->unevaluatedProperties, put it in
> typical place, just before example DTS.
> 
> The sitronix,st7735r references also panel-common.yaml and lists
> explicitly allowed properties, thus here reference only
> spi-peripheral-props.yaml for purpose of documenting the SPI slave
> device and bringing spi-max-frequency type validation.
> 
> Signed-off-by: Krzysztof Kozlowski 
> 
> ---
> 
> Technically, this depends on [1] merged to SPI tree, if we want to
> preserve existing behavior of not allowing SPI CPHA and CPOL in each of
> schemas in this patch.
> 
> If this patch comes independently via different tree, the SPI CPHA and
> CPOL will be allowed for brief period of time, before [1] is merged.
> This will not have negative impact, just DT schema checks will be
> loosened for that period.
> 
> [1] 
> https://lore.kernel.org/all/20220722191539.90641-2-krzysztof.kozlow...@linaro.org/
> ---
>  .../devicetree/bindings/display/panel/lg,lg4573.yaml   | 2 +-
>  .../devicetree/bindings/display/sitronix,st7735r.yaml  | 1 +
>  .../devicetree/bindings/display/solomon,ssd1307fb.yaml | 7 +++
>  3 files changed, 5 insertions(+), 5 deletions(-)
> 

Applied, thanks!


Re: [RFC PATCH 1/2] drm/panel-edp: Allow overriding the eDP EDID

2022-07-29 Thread Doug Anderson
Hi,

On Thu, Jul 21, 2022 at 4:36 AM Dmitry Baryshkov
 wrote:
>
> On Thu, 21 Jul 2022 at 01:55, Douglas Anderson  wrote:
> >
> > I found that writing to `/sys/kernel/debug/dri/*/eDP*/edid_override`
> > wasn't working for me. I could see the new EDID take effect in
> > `/sys/class/drm/card*-eDP*/edid` but userspace wasn't seeing it..
> >
> > The problem was that panel-edp was caching the EDID that it read and
> > using that over and over again.
> >
> > Let's change panel-edp to look at the EDID that's stored in the
> > connector. This is still a cache, which is important since this
> > function is called multiple times and readin the EDID is slow, but
> > this property is automatically updated by drm_get_edid() (which reads
> > the EDID) and also updated when writing the edid_override in debugfs.
> >
> > Fixes: 63358e24ee79 ("drm/panel: panel-simple: Cache the EDID as long as we 
> > retain power")
> > Signed-off-by: Douglas Anderson 
>
> A different proposal for you to consider:
> Change drm_get_edid/drm_do_get_edid to return int rather than struct
> edid, while caching the EDID in the connector. Or maybe add a new API
> drm_read_edid() and make drm_get_edid() deprecated in favour of it.
> The goal should be to let all drivers use connector-cached EDID rather
> than getting  the EDID, parsing it and kfree()ing it immediately
> afterwards.

I think the majority of drivers don't actually want the cached EDID
behavior so the edp-panel case is actually pretty rare. For everyone
else I think DRM is handling things in a pretty reasonable way.
Looking closely, it looks like there have been a bunch of patches
landed in this area recently and so I assume people are happy enough
with the current design for the majority of cases.

I guess your point though, is that the way I'm using the API right now
in ${SUBJECT} patch is a bit gross and maybe the DRM core needs a
helper of some sort for this case? Essentially what we're saying is
that we have inside knowledge this is a built-in panel and thus the
EDID will never change and it's a waste of time to read it again and
again. We could somehow tell the DRM core that.

I guess I could add a function like drm_edid_read_if_needed(). That
would essentially use the existing blob if it was there and read it
otherwise. Does that work? Basically:

def drm_edid_read_if_needed(...):
  if (connector->edid_blob_ptr)
return dupe_edid(connector->edid_blob_ptr);
  return drm_edid_read(...);

I guess maybe we'd want a _ddc variant too.

Adding Jani since the recent patches I see touching this were his and
there are even comments there about what to do about drivers that want
to cache the EDID.


> Most probably we should be able to move
> drm_connector_update_edid_property() into drm_do_get_edid() and drop
> it from the rest of the code. This might require additional thought
> about locking, to ensure that nobody pulls the cached edid out from
> under our feet.

This all looks like it's moving now, actually. Looking around at
recent changes, I see that now the property gets updated in a
different call.

Old (deprecated)
1. drm_get_edid() <-- Updates the EDID property
2. drm_add_edid_modes()

New:
1. drm_edid_read()
2. drm_edid_connector_update() <-- Updates the EDID property


 > Extra "bonus" points to consider:
> - Maybe it's time to add get_edid() to the drm_panel interface, teach
> panel_bridge about it and let drm_bridge_connector handle all the
> details?
>
> So, while this looks like a longer path, I think it's worth checking
> that we can refactor this piece of code.

It's certainly interesting to consider. At the moment, though, it
doesn't look super easy to do. Points to note:

1. We don't necessarily want to cache the EDID for all display types.
For builtin panels it makes sense to do so, but it's less obvious for
external displays. _In theory_ we could try to cache the EDID for
external devices if we're really certain that we'll notice when
they're unplugged / re-plugged again but I'm not convinced that all
drivers always handle this. In any case, I tend to assume that when
we're dealing with external displays we're a little less interested in
trying to optimize all of the milliseconds away. If nothing else there
are hundreds of milliseconds of hotplug detect debounce happening for
external displays. Yes, we could have a rule about only caching the
EDID only for eDP displays but then the motivation of moving it out of
edp-panel and to drm_bridge_connector is a lot less.

2. At the moment, drm_bridge_connector only calls get_modes() if it
doesn't have get_edid() implemented. At the moment the panel-edp code
actually _combines_ the EDID and any hardcoded modes that were
specified. I think we'd have to resolve this difference if we do what
you suggest. The panel-edp behavior comes from before the split out of
panel-simple and dates from 2013 when panel-simple was first added.
Certainly we could arbitrarily change one behavior or the other but I
don't know what the fallout w

Re: [PATCH 1/3] dma-buf: Add ioctl to query mmap info

2022-07-29 Thread kernel test robot
Hi Rob,

I love your patch! Perhaps something to improve:

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

url:
https://github.com/intel-lab-lkp/linux/commits/Rob-Clark/dma-buf-map-info-support/20220730-010844
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
6e2c0490769ef8a95b61304389116ccc85c53e12
config: arc-randconfig-r043-20220729 
(https://download.01.org/0day-ci/archive/20220730/202207300546.hb4u217w-...@intel.com/config)
compiler: arceb-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/203f14a73a179d6c5fbfa4813e45fde2a9ae9860
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Rob-Clark/dma-buf-map-info-support/20220730-010844
git checkout 203f14a73a179d6c5fbfa4813e45fde2a9ae9860
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=arc SHELL=/bin/bash drivers/dma-buf/

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

All warnings (new ones prefixed by >>):

   drivers/dma-buf/dma-buf.c: In function 'dma_buf_info':
>> drivers/dma-buf/dma-buf.c:346:26: warning: passing argument 1 of 
>> 'copy_to_user' discards 'const' qualifier from pointer target type 
>> [-Wdiscarded-qualifiers]
 346 | if (copy_to_user(uarg, &arg, sizeof(arg)))
 |  ^~~~
   In file included from include/linux/sched/task.h:11,
from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from drivers/dma-buf/dma-buf.c:14:
   include/linux/uaccess.h:157:27: note: expected 'void *' but argument is of 
type 'const void *'
 157 | copy_to_user(void __user *to, const void *from, unsigned long n)
 |  ~^~


vim +346 drivers/dma-buf/dma-buf.c

   328  
   329  static long dma_buf_info(struct dma_buf *dmabuf, const void __user 
*uarg)
   330  {
   331  struct dma_buf_info arg;
   332  
   333  if (copy_from_user(&arg, uarg, sizeof(arg)))
   334  return -EFAULT;
   335  
   336  switch (arg.param) {
   337  case DMA_BUF_INFO_VM_PROT:
   338  if (!dmabuf->ops->mmap_info)
   339  return -ENOSYS;
   340  arg.value = dmabuf->ops->mmap_info(dmabuf);
   341  break;
   342  default:
   343  return -EINVAL;
   344  }
   345  
 > 346  if (copy_to_user(uarg, &arg, sizeof(arg)))
   347  return -EFAULT;
   348  
   349  return 0;
   350  }
   351  

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


Re: [git pull] drm fixes for 5.19 final (part 2)

2022-07-29 Thread pr-tracker-bot
The pull request you sent on Sat, 30 Jul 2022 06:24:26 +1000:

> git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-07-30

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

Thank you!

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


[pull] amdgpu, amdkfd drm-next-5.20

2022-07-29 Thread Alex Deucher
Hi Dave, Daniel,

Fixes for 5.20.  Mainly for new IPs.

The following changes since commit 2bc7ea71a73747a77e7f83bc085b0d2393235410:

  Merge tag 'topic/nouveau-misc-2022-07-27' of 
git://anongit.freedesktop.org/drm/drm into drm-next (2022-07-27 11:34:07 +1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-next-5.20-2022-07-29

for you to fetch changes up to 64f991590ff4410041a70ee7ec2db079bc953929:

  drm/amd/display: Fix a compilation failure on PowerPC caused by FPU code 
(2022-07-29 15:24:38 -0400)


amd-drm-next-5.20-2022-07-29:

amdgpu:
- Misc spelling and grammar fixes
- DC whitespace cleanups
- ACP smatch fix
- GFX 11.0 updates
- PSP 13.0 updates
- VCN 4.0 updates
- DC FP fix for PPC64
- Misc bug fixes

amdkfd:
- SVM fixes


Alex Sierra (2):
  drm/amdkfd: track unified memory reservation with xnack off
  drm/amdgpu: add debugfs for kfd system and ttm mem used

Chengming Gui (2):
  drm/amd/amdgpu: add additional page fault settings for gfx11
  drm/amd/amdgpu: add memory training support for PSP_V13

Dan Carpenter (1):
  drm/amd/display: fix signedness bug in execute_synaptics_rc_command()

Evan Quan (3):
  drm/amdgpu: drop non-necessary call trace dump
  drm/amd/pm: update driver if header for SMU 13.0.0
  drm/amd/pm: enable GFX ULV feature support for SMU13.0.0

Guchun Chen (1):
  drm/amdgpu: use adev_to_drm for consistency

Jack Xiao (1):
  drm/amdgpu: move mes self test after drm sched re-started

Jiapeng Chong (20):
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting
  drm/amd/display: Clean up some inconsistent indenting

Jonathan Kim (1):
  drm/amdgpu: fix hive reference leak when reflecting psp topology info

Lang Yu (2):
  drm/amdkfd: fix kgd_mem memory leak when importing dmabuf
  drm/amdkfd: remove an unnecessary amdgpu_bo_ref

Maíra Canal (1):
  drm/amd/display: Remove unused struct freesync_context

Philip Yang (3):
  drm/amdgpu: Allow TTM to evict svm bo from same process
  drm/amdkfd: Set svm range max pages
  drm/amdkfd: Split giant svm range

Rodrigo Siqueira (1):
  drm/amd/display: Fix a compilation failure on PowerPC caused by FPU code

Roy Sun (1):
  drm/amdgpu: Fix the incomplete product number

Shikai Guo (1):
  drm/amd/pm: Add get_gfx_off_status interface for yellow carp

Sonny Jiang (5):
  drm/amdgpu: fix a vcn4 boot poll bug in emulation mode
  drm/amdgpu: add VCN function in NBIO v7.7
  drm/amdgpu: add VCN_4_0_2 firmware support
  drm/amdgpu: vcn_4_0_2 video codec query
  drm/amdgpu: enable VCN cg and JPEG cg/pg

Vijendar Mukunda (1):
  drm/amdgpu: fix i2s_pdata out of bound array access

Xiaojian Du (4):
  drm/amdgpu: send msg to IMU for the front-door loading
  drm/amdgpu: add header files for MP 13.0.4
  drm/amdgpu: add files for PSP 13.0.4
  drm/amdgpu: enable support for psp 13.0.4 block

Yang Li (1):
  drm/amd/display: remove unneeded semicolon

Yifan Zhang (1):
  drm/amdgpu: correct RLC_RLCS_BOOTLOAD_STATUS offset and index

Yu Zhe (1):
  drm/amdkfd: use time_is_before_jiffies(a + b) to replace "jiffies - a > b"

wangjianli (1):
  drm/amdgpu/dc/dce: fix repeated words in comments

 drivers/gpu/drm/amd/amdgpu/Makefile|   3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c|   8 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h |   7 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c   |   9 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c   |  51 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c  |   4 +-
 drivers/gpu/drm/amd/am

[git pull] drm fixes for 5.19 final (part 2)

2022-07-29 Thread Dave Airlie
Hey Linus,

Maxime had the dog^Wmailing list server eat his homework^Wmisc pull
request. Two more small fixes, one in nouveau svm code and the other
in simpledrm.

Thanks,
Dave.

drm-fixes-2022-07-30:
drm fixes for 5.19 final (part 2)

nouveau:
- page migration fix

simpledrm:
- fix mode_valid return value
The following changes since commit f16a2f593d0095e82e6b7f9d776f869c8ab45952:

  Merge tag 'drm-intel-fixes-2022-07-28-1' of
git://anongit.freedesktop.org/drm/drm-intel into drm-fixes (2022-07-29
11:39:13 +1000)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-07-30

for you to fetch changes up to ce156c8a1811c96a243590abd0e9b5a3b72c1f3a:

  Merge tag 'drm-misc-fixes-2022-07-29' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2022-07-30
06:09:57 +1000)


drm fixes for 5.19 final (part 2)

nouveau:
- page migration fix

simpledrm:
- fix mode_valid return value


Alistair Popple (1):
  nouveau/svm: Fix to migrate all requested pages

Dave Airlie (1):
  Merge tag 'drm-misc-fixes-2022-07-29' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

Nathan Chancellor (1):
  drm/simpledrm: Fix return type of
simpledrm_simple_display_pipe_mode_valid()

 drivers/gpu/drm/nouveau/nouveau_dmem.c | 6 +-
 drivers/gpu/drm/tiny/simpledrm.c   | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)


Re: [PATCH v1 33/35] drm/connector: Remove TV modes property

2022-07-29 Thread kernel test robot
Hi Maxime,

I love your patch! Yet something to improve:

[auto build test ERROR on 37b355fdaf31ee18bda9a93c2a438dc1cbf57ec9]

url:
https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/drm-Analog-TV-Improvements/20220730-004859
base:   37b355fdaf31ee18bda9a93c2a438dc1cbf57ec9
config: riscv-randconfig-r042-20220729 
(https://download.01.org/0day-ci/archive/20220730/202207300454.3ric8wpm-...@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
8dfaecc4c24494337933aff9d9166486ca0949f1)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install riscv cross compiling tool for clang build
# apt-get install binutils-riscv-linux-gnu
# 
https://github.com/intel-lab-lkp/linux/commit/83327cd72054a9c8d02b6f632453a8bdc90d3797
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Maxime-Ripard/drm-Analog-TV-Improvements/20220730-004859
git checkout 83327cd72054a9c8d02b6f632453a8bdc90d3797
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=riscv SHELL=/bin/bash drivers/gpu/drm/

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

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/nouveau/dispnv04/tvnv17.c:656:51: error: too many arguments 
>> to function call, expected 2, have 3
   drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names);
   ~^~
   include/drm/drm_connector.h:1807:5: note: 'drm_mode_create_tv_properties' 
declared here
   int drm_mode_create_tv_properties(struct drm_device *dev,
   ^
   1 error generated.


vim +656 drivers/gpu/drm/nouveau/dispnv04/tvnv17.c

6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
633  
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
634  static int nv17_tv_create_resources(struct drm_encoder *encoder,
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
635 struct drm_connector *connector)
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
636  {
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
637 struct drm_device *dev = encoder->dev;
77145f1cbdf8d2 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2012-07-31  
638 struct nouveau_drm *drm = nouveau_drm(dev);
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
639 struct drm_mode_config *conf = &dev->mode_config;
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
640 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
cb75d97e9c7774 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2012-07-11  
641 struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
642 int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS :
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
643 NUM_LD_TV_NORMS;
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
644 int i;
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
645  
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
646 if (nouveau_tv_norm) {
2574c809d7c0f0 drivers/gpu/drm/nouveau/dispnv04/tvnv17.c YueHaibing 2019-12-30  
647 i = match_string(nv17_tv_norm_names, num_tv_norms,
2574c809d7c0f0 drivers/gpu/drm/nouveau/dispnv04/tvnv17.c YueHaibing 2019-12-30  
648  nouveau_tv_norm);
2574c809d7c0f0 drivers/gpu/drm/nouveau/dispnv04/tvnv17.c YueHaibing 2019-12-30  
649 if (i < 0)
77145f1cbdf8d2 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2012-07-31  
650 NV_WARN(drm, "Invalid TV norm setting \"%s\"\n",
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
651 nouveau_tv_norm);
2574c809d7c0f0 drivers/gpu/drm/nouveau/dispnv04/tvnv17.c YueHaibing 2019-12-30  
652 else
2574c809d7c0f0 drivers/gpu/drm/nouveau/dispnv04/tvnv17.c YueHaibing 2019-12-30  
653 tv_enc->tv_norm = i;
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
654 }
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_tv.c Ben Skeggs 2009-12-11  
655  
6ee738610f41b5 drivers/gpu/drm/nouveau/nv17_

Re: [PATCH v1 33/35] drm/connector: Remove TV modes property

2022-07-29 Thread kernel test robot
Hi Maxime,

I love your patch! Yet something to improve:

[auto build test ERROR on 37b355fdaf31ee18bda9a93c2a438dc1cbf57ec9]

url:
https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/drm-Analog-TV-Improvements/20220730-004859
base:   37b355fdaf31ee18bda9a93c2a438dc1cbf57ec9
config: hexagon-randconfig-r041-20220729 
(https://download.01.org/0day-ci/archive/20220730/202207300305.egsdojh4-...@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
8dfaecc4c24494337933aff9d9166486ca0949f1)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/83327cd72054a9c8d02b6f632453a8bdc90d3797
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Maxime-Ripard/drm-Analog-TV-Improvements/20220730-004859
git checkout 83327cd72054a9c8d02b6f632453a8bdc90d3797
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/gpu/drm/i2c/

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

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/i2c/ch7006_drv.c:253:51: error: too many arguments to 
>> function call, expected 2, have 3
   drm_mode_create_tv_properties(dev, NUM_TV_NORMS, 
ch7006_tv_norm_names);
   ~^~~~
   include/drm/drm_connector.h:1807:5: note: 'drm_mode_create_tv_properties' 
declared here
   int drm_mode_create_tv_properties(struct drm_device *dev,
   ^
   1 error generated.


vim +253 drivers/gpu/drm/i2c/ch7006_drv.c

6ee738610f41b5 Ben Skeggs   2009-12-11  245  
6ee738610f41b5 Ben Skeggs   2009-12-11  246  static int 
ch7006_encoder_create_resources(struct drm_encoder *encoder,
6ee738610f41b5 Ben Skeggs   2009-12-11  247 
   struct drm_connector *connector)
6ee738610f41b5 Ben Skeggs   2009-12-11  248  {
6ee738610f41b5 Ben Skeggs   2009-12-11  249 struct ch7006_priv *priv = 
to_ch7006_priv(encoder);
6ee738610f41b5 Ben Skeggs   2009-12-11  250 struct drm_device *dev = 
encoder->dev;
6ee738610f41b5 Ben Skeggs   2009-12-11  251 struct drm_mode_config *conf = 
&dev->mode_config;
6ee738610f41b5 Ben Skeggs   2009-12-11  252  
6ee738610f41b5 Ben Skeggs   2009-12-11 @253 
drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names);
6ee738610f41b5 Ben Skeggs   2009-12-11  254  
d9bc3c02e36d84 Sascha Hauer 2012-02-06  255 priv->scale_property = 
drm_property_create_range(dev, 0, "scale", 0, 2);
44084efc2fd804 Insu Yun 2016-01-28  256 if (!priv->scale_property)
44084efc2fd804 Insu Yun 2016-01-28  257 return -ENOMEM;
6ee738610f41b5 Ben Skeggs   2009-12-11  258  
ec61c71d0dba24 Rob Clark2012-10-11  259 
drm_object_attach_property(&connector->base, 
conf->tv_select_subconnector_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  260   
priv->select_subconnector);
ec61c71d0dba24 Rob Clark2012-10-11  261 
drm_object_attach_property(&connector->base, conf->tv_subconnector_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  262   
priv->subconnector);
ec61c71d0dba24 Rob Clark2012-10-11  263 
drm_object_attach_property(&connector->base, conf->tv_left_margin_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  264   
priv->hmargin);
ec61c71d0dba24 Rob Clark2012-10-11  265 
drm_object_attach_property(&connector->base, conf->tv_bottom_margin_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  266   
priv->vmargin);
ec61c71d0dba24 Rob Clark2012-10-11  267 
drm_object_attach_property(&connector->base, conf->tv_mode_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  268   
priv->norm);
ec61c71d0dba24 Rob Clark2012-10-11  269 
drm_object_attach_property(&connector->base, conf->tv_brightness_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  270   
priv->brightness);
ec61c71d0dba24 Rob Clark2012-10-11  271 
drm_object_attach_property(&connector->base, conf->tv_contrast_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  272   
priv->contrast);
ec61c71d0dba24 Rob Clark2012-10-11  273 
drm_object_attach_property(&connector->base, 
conf->tv_flicker_reduction_property,
6ee738610f41b5 Ben Skeggs   2009-12-11  274   
priv->fli

Re: [RFC PATCH] drm/edid: Make 144 Hz not preferred on Sharp LQ140M1JW46

2022-07-29 Thread Doug Anderson
Hi,

On Fri, Jul 29, 2022 at 9:41 AM Maxime Ripard  wrote:
>
> On Fri, Jul 29, 2022 at 07:50:20AM -0700, Doug Anderson wrote:
> > On Fri, Jul 29, 2022 at 12:51 AM Maxime Ripard  wrote:
> > >
> > > On Thu, Jul 28, 2022 at 02:18:38PM -0700, Doug Anderson wrote:
> > > > Hi,
> > > >
> > > > On Thu, Jul 28, 2022 at 10:34 AM Abhinav Kumar
> > > >  wrote:
> > > > >
> > > > > Hi Rob and Doug
> > > > >
> > > > > On 7/22/2022 10:36 AM, Rob Clark wrote:
> > > > > > On Fri, Jul 22, 2022 at 9:48 AM Doug Anderson 
> > > > > >  wrote:
> > > > > >>
> > > > > >> Hi,
> > > > > >>
> > > > > >> On Fri, Jul 22, 2022 at 9:37 AM Abhinav Kumar 
> > > > > >>  wrote:
> > > > > >>>
> > > > > >>> + sankeerth
> > > > > >>>
> > > > > >>> Hi Doug
> > > > > >>>
> > > > > >>> On 7/21/2022 3:23 PM, Douglas Anderson wrote:
> > > > >  The Sharp LQ140M1JW46 panel is on the Qualcomm sc7280 CRD 
> > > > >  reference
> > > > >  board. This panel supports 144 Hz and 60 Hz. In the EDID, the 
> > > > >  144 Hz
> > > > >  mode is listed first and thus is marked preferred. The EDID 
> > > > >  decode I
> > > > >  ran says:
> > > > > 
> > > > >  First detailed timing includes the native pixel format and 
> > > > >  preferred
> > > > >  refresh rate.
> > > > > 
> > > > >  ...
> > > > > 
> > > > >  Detailed Timing Descriptors:
> > > > >    DTD 1:  1920x1080  143.981 Hz  16:9   166.587 kHz  346.500 
> > > > >  MHz
> > > > > Hfront   48 Hsync  32 Hback  80 Hpol N
> > > > > Vfront3 Vsync   5 Vback  69 Vpol N
> > > > >    DTD 2:  1920x1080   59.990 Hz  16:969.409 kHz  144.370 
> > > > >  MHz
> > > > > Hfront   48 Hsync  32 Hback  80 Hpol N
> > > > > Vfront3 Vsync   5 Vback  69 Vpol N
> > > > > 
> > > > >  I'm proposing here that the above is actually a bug and that the 
> > > > >  60 Hz
> > > > >  mode really should be considered preferred by Linux.
> > > > >
> > > > > Its a bit tricky to say that this is a bug but I think we can 
> > > > > certainly
> > > > > add here that for an internal display we would have ideally had the
> > > > > lower resolution first to indicate it as default.
> > > >
> > > > Yeah, it gets into the vagueness of the EDID spec in general. As far
> > > > as I can find it's really up to the monitor to decide by what means it
> > > > chooses the "preferred" refresh rate if the monitor can support many.
> > > > Some displays may decide that the normal rate is "preferred" and some
> > > > may decide that the high refresh rate is "preferred". Neither display
> > > > is "wrong" per say, but it's nice to have some consistency here and to
> > > > make it so that otherwise "dumb" userspace will get something
> > > > reasonable by default. I'll change it to say:
> > > >
> > > > While the EDID spec appears to allow a display to use any criteria for
> > > > picking which refresh mode is "preferred" or "optimal", that vagueness
> > > > is a bit annoying. From Linux's point of view let's choose the 60 Hz
> > > > one as the default.
> > >
> > > And if we start making that decision, it should be for all panels with a
> > > similar constraint, so most likely handled by the core, and the new
> > > policy properly documented.
> > >
> > > Doing that just for a single panel is weird.
> >
> > Yeah, though having a "general policy" in the core can be problematic.
> >
> > In general I think panel EDIDs are only trustworthy as far as you can
> > throw them. They are notorious for having wrong and incorrect
> > information, which is why the EDID quirk list exists to begin with.
> > Trying to change how we're going to interpret all EDIDs, even all
> > EDIDs for eDP panels, seems like it will break someone somewhere.
> > Maybe there are EDIDs out there that were only ever validated at the
> > higher refresh rate and they don't work / flicker / cause digitizer
> > noise at the lower refresh rate. Heck, we've seen eDP panel vendors
> > that can't even get their checksum correct, so I'm not sure I want to
> > make a global assertion that all panels validated their "secondary"
> > display mode.
> >
> > In this particular case, we have validated that this particular Sharp
> > panel works fine at the lower refresh rate.
> >
> > I would also note that, as far as I understand it, ODMs actually can
> > request different EDIDs from the panel vendors. In the past we have
> > been able to get panel vendors to change EDIDs. Thus for most panels
> > I'd expect that we would discover this early, change the EDID default,
> > and be done with it. The case here is a little unusual in that by the
> > time we got involved and started digging into this panel too many were
> > created and nobody wants to throw away those old panels. This is why
> > I'm treating it as a quirk/bug. Really: we should have updated the
> > EDID of the panel but we're unable to in this 

[PATCH 2/3] drm/prime: Wire up mmap_info support

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

Just plumbing the thing thru an extra layer.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/drm_prime.c | 12 
 include/drm/drm_drv.h   |  7 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index e3f09f18110c..f58586e131c5 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -784,6 +784,17 @@ int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct 
vm_area_struct *vma)
 }
 EXPORT_SYMBOL(drm_gem_dmabuf_mmap);
 
+static int drm_gem_dmabuf_mmap_info(struct dma_buf *dma_buf)
+{
+   struct drm_gem_object *obj = dma_buf->priv;
+   struct drm_device *dev = obj->dev;
+
+   if (!dev->driver->gem_prime_mmap_info)
+   return -ENOSYS;
+
+   return dev->driver->gem_prime_mmap_info(obj);
+}
+
 static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  {
.cache_sgt_mapping = true,
.attach = drm_gem_map_attach,
@@ -792,6 +803,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  
{
.unmap_dma_buf = drm_gem_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
.mmap = drm_gem_dmabuf_mmap,
+   .mmap_info = drm_gem_dmabuf_mmap_info,
.vmap = drm_gem_dmabuf_vmap,
.vunmap = drm_gem_dmabuf_vunmap,
 };
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index f6159acb8856..797c0f8c2dd0 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -355,6 +355,13 @@ struct drm_driver {
 */
int (*gem_prime_mmap)(struct drm_gem_object *obj, struct vm_area_struct 
*vma);
 
+   /**
+* @gem_prim_mmap_info:
+*
+* Get info about mmap setup by gem_prime_mmap.  See 
dma_buf_ops:mmap_info.
+*/
+   int (*gem_prime_mmap_info)(struct drm_gem_object *obj);
+
/**
 * @dumb_create:
 *
-- 
2.36.1



[PATCH 3/3] drm/msm/prime: Add mmap_info support

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

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.c   |  1 +
 drivers/gpu/drm/msm/msm_drv.h   |  1 +
 drivers/gpu/drm/msm/msm_gem_prime.c | 11 +++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1ca4a92ba96e..4979aa8187ec 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1044,6 +1044,7 @@ static const struct drm_driver msm_driver = {
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import_sg_table = msm_gem_prime_import_sg_table,
.gem_prime_mmap = msm_gem_prime_mmap,
+   .gem_prime_mmap_info= msm_gem_prime_mmap_info,
 #ifdef CONFIG_DEBUG_FS
.debugfs_init   = msm_debugfs_init,
 #endif
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 7330d7b5de8e..b4ace34ec889 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -271,6 +271,7 @@ void msm_gem_shrinker_init(struct drm_device *dev);
 void msm_gem_shrinker_cleanup(struct drm_device *dev);
 
 int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
+int msm_gem_prime_mmap_info(struct drm_gem_object *obj);
 struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj);
 int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
 void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c 
b/drivers/gpu/drm/msm/msm_gem_prime.c
index c1d91863df05..2bacab7a1921 100644
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 
 #include 
 
@@ -26,6 +27,16 @@ int msm_gem_prime_mmap(struct drm_gem_object *obj, struct 
vm_area_struct *vma)
return drm_gem_prime_mmap(obj, vma);
 }
 
+int msm_gem_prime_mmap_info(struct drm_gem_object *obj)
+{
+   struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+   if (msm_obj->flags & MSM_BO_WC)
+   return DMA_BUF_VM_PROT_WC;
+
+   return DMA_BUF_VM_PROT_CACHED;
+}
+
 struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
-- 
2.36.1



[PATCH 0/3] dma-buf: map-info support

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

See 1/3 for motivation.

Rob Clark (3):
  dma-buf: Add ioctl to query mmap info
  drm/prime: Wire up mmap_info support
  drm/msm/prime: Add mmap_info support

 drivers/dma-buf/dma-buf.c   | 26 ++
 drivers/gpu/drm/drm_prime.c | 12 
 drivers/gpu/drm/msm/msm_drv.c   |  1 +
 drivers/gpu/drm/msm/msm_drv.h   |  1 +
 drivers/gpu/drm/msm/msm_gem_prime.c | 11 +++
 include/drm/drm_drv.h   |  7 +++
 include/linux/dma-buf.h |  7 +++
 include/uapi/linux/dma-buf.h| 28 
 8 files changed, 93 insertions(+)

-- 
2.36.1



[PATCH 1/3] dma-buf: Add ioctl to query mmap info

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

This is a fairly narrowly focused interface, providing a way for a VMM
in userspace to tell the guest kernel what pgprot settings to use when
mapping a buffer to guest userspace.

For buffers that get mapped into guest userspace, virglrenderer returns
a dma-buf fd to the VMM (crosvm or qemu).  In addition to mapping the
pages into the guest VM, it needs to report to drm/virtio in the guest
the cache settings to use for guest userspace.  In particular, on some
architectures, creating aliased mappings with different cache attributes
is frowned upon, so it is important that the guest mappings have the
same cache attributes as any potential host mappings.

Signed-off-by: Rob Clark 
---
 drivers/dma-buf/dma-buf.c| 26 ++
 include/linux/dma-buf.h  |  7 +++
 include/uapi/linux/dma-buf.h | 28 
 3 files changed, 61 insertions(+)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 32f55640890c..d02d6c2a3b49 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -326,6 +326,29 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const 
char __user *buf)
return 0;
 }
 
+static long dma_buf_info(struct dma_buf *dmabuf, const void __user *uarg)
+{
+   struct dma_buf_info arg;
+
+   if (copy_from_user(&arg, uarg, sizeof(arg)))
+   return -EFAULT;
+
+   switch (arg.param) {
+   case DMA_BUF_INFO_VM_PROT:
+   if (!dmabuf->ops->mmap_info)
+   return -ENOSYS;
+   arg.value = dmabuf->ops->mmap_info(dmabuf);
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   if (copy_to_user(uarg, &arg, sizeof(arg)))
+   return -EFAULT;
+
+   return 0;
+}
+
 static long dma_buf_ioctl(struct file *file,
  unsigned int cmd, unsigned long arg)
 {
@@ -369,6 +392,9 @@ static long dma_buf_ioctl(struct file *file,
case DMA_BUF_SET_NAME_B:
return dma_buf_set_name(dmabuf, (const char __user *)arg);
 
+   case DMA_BUF_IOCTL_INFO:
+   return dma_buf_info(dmabuf, (const void __user *)arg);
+
default:
return -ENOTTY;
}
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 71731796c8c3..6f4de64a5937 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -283,6 +283,13 @@ struct dma_buf_ops {
 */
int (*mmap)(struct dma_buf *, struct vm_area_struct *vma);
 
+   /**
+* @mmap_info:
+*
+* Return mmapping info for the buffer.  See DMA_BUF_INFO_VM_PROT.
+*/
+   int (*mmap_info)(struct dma_buf *);
+
int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map);
void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map);
 };
diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h
index b1523cb8ab30..a41adac0f46a 100644
--- a/include/uapi/linux/dma-buf.h
+++ b/include/uapi/linux/dma-buf.h
@@ -85,6 +85,32 @@ struct dma_buf_sync {
 
 #define DMA_BUF_NAME_LEN   32
 
+
+/**
+ * struct dma_buf_info - Query info about the buffer.
+ */
+struct dma_buf_info {
+
+#define DMA_BUF_INFO_VM_PROT  1
+#  define DMA_BUF_VM_PROT_WC  0
+#  define DMA_BUF_VM_PROT_CACHED  1
+
+   /**
+* @param: Which param to query
+*
+* DMA_BUF_INFO_BM_PROT:
+* Query the access permissions of userspace mmap's of this buffer.
+* Returns one of DMA_BUF_VM_PROT_x
+*/
+   __u32 param;
+   __u32 pad;
+
+   /**
+* @value: Return value of the query.
+*/
+   __u64 value;
+};
+
 #define DMA_BUF_BASE   'b'
 #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
 
@@ -95,4 +121,6 @@ struct dma_buf_sync {
 #define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, __u32)
 #define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, __u64)
 
+#define DMA_BUF_IOCTL_INFO _IOWR(DMA_BUF_BASE, 2, struct dma_buf_info)
+
 #endif
-- 
2.36.1



Re: [PATCH v3 09/15] drm/gem: Add LRU/shrinker helper

2022-07-29 Thread Dmitry Osipenko
On 7/29/22 18:40, Rob Clark wrote:
> On Fri, Jul 29, 2022 at 8:27 AM Dmitry Osipenko
>  wrote:
>>
>> On 7/26/22 20:50, Rob Clark wrote:
>>> +/**
>>> + * drm_gem_lru_move_tail_locked - move the object to the tail of the LRU
>>> + *
>>> + * If the object is already in this LRU it will be moved to the
>>> + * tail.  Otherwise it will be removed from whichever other LRU
>>> + * it is in (if any) and moved into this LRU.
>>> + *
>>> + * Call with LRU lock held.
>>> + *
>>> + * @lru: The LRU to move the object into.
>>> + * @obj: The GEM object to move into this LRU
>>> + */
>>> +void
>>> +drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct 
>>> drm_gem_object *obj)
>>> +{
>>> + lockdep_assert_held_once(lru->lock);
>>> +
>>> + if (obj->lru)
>>> + lru_remove(obj);
>>
>> The obj->lru also needs to be locked if lru != obj->lru, isn't it? And
>> then we should add lockdep_assert_held_once(obj->lru->lock).
>>
> 
> It is expected (mentioned in comment on drm_gem_lru::lock) that all
> lru's are sharing the same lock.  Possibly that could be made more
> obvious?  Having per-lru locks wouldn't really work for accessing the
> single drm_gem_object::lru_node.

Right, my bad. I began to update the DRM-SHMEM shrinker patches on top
of the shrinker helper, but missed that the lock is shared when was
looking at this patch again today.

Adding comment to the code about the shared lock may help a tad, but
it's not really necessary. It was my fault that I forgot about it.

Thank you!

-- 
Best regards,
Dmitry


[PATCH v1 16/35] drm/vc4: vec: Convert to atomic helpers

2022-07-29 Thread Maxime Ripard
The VC4 VEC driver still uses legacy enable and disable hook
implementation. Let's convert to the atomic variants.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 17a6afac61cd..ba0a81250d08 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -375,7 +375,8 @@ static int vc4_vec_connector_init(struct drm_device *dev, 
struct vc4_vec *vec)
return 0;
 }
 
-static void vc4_vec_encoder_disable(struct drm_encoder *encoder)
+static void vc4_vec_encoder_disable(struct drm_encoder *encoder,
+   struct drm_atomic_state *state)
 {
struct drm_device *drm = encoder->dev;
struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
@@ -406,7 +407,8 @@ static void vc4_vec_encoder_disable(struct drm_encoder 
*encoder)
drm_dev_exit(idx);
 }
 
-static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
+static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
+  struct drm_atomic_state *state)
 {
struct drm_device *drm = encoder->dev;
struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
@@ -508,9 +510,9 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder 
*encoder,
 }
 
 static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
-   .disable = vc4_vec_encoder_disable,
-   .enable = vc4_vec_encoder_enable,
.atomic_check = vc4_vec_encoder_atomic_check,
+   .atomic_disable = vc4_vec_encoder_disable,
+   .atomic_enable = vc4_vec_encoder_enable,
.atomic_mode_set = vc4_vec_encoder_atomic_mode_set,
 };
 

-- 
b4 0.10.0-dev-49460


[PATCH v1 27/35] drm/sun4i: tv: Merge mode_set into atomic_enable

2022-07-29 Thread Maxime Ripard
Our mode_set implementation can be merged into our atomic_enable
implementation to simplify things, so let's do this.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index f7aad995ab5b..3944da9a3c34 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -359,23 +359,13 @@ static void sun4i_tv_enable(struct drm_encoder *encoder,
 {
struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
-
-   DRM_DEBUG_DRIVER("Enabling the TV Output\n");
-
-   sunxi_engine_apply_color_correction(crtc->engine);
-
-   regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
-  SUN4I_TVE_EN_ENABLE,
-  SUN4I_TVE_EN_ENABLE);
-}
-
-static void sun4i_tv_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
-   struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
+   struct drm_crtc_state *crtc_state =
+   drm_atomic_get_new_crtc_state(state, encoder->crtc);
+   struct drm_display_mode *mode = &crtc_state->mode;
const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);
 
+   DRM_DEBUG_DRIVER("Enabling the TV Output\n");
+
/* Enable and map the DAC to the output */
regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
   SUN4I_TVE_EN_DAC_MAP_MASK,
@@ -468,12 +458,17 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
  SUN4I_TVE_RESYNC_FIELD : 0));
 
regmap_write(tv->regs, SUN4I_TVE_SLAVE_REG, 0);
+
+   sunxi_engine_apply_color_correction(crtc->engine);
+
+   regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
+  SUN4I_TVE_EN_ENABLE,
+  SUN4I_TVE_EN_ENABLE);
 }
 
 static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
.atomic_disable = sun4i_tv_disable,
.atomic_enable  = sun4i_tv_enable,
-   .mode_set   = sun4i_tv_mode_set,
 };
 
 static int sun4i_tv_comp_get_modes(struct drm_connector *connector)

-- 
b4 0.10.0-dev-49460


[PATCH v1 03/35] drm/atomic: Add TV subconnector property to get/set_property

2022-07-29 Thread Maxime Ripard
The subconnector property was created by drm_mode_create_tv_properties(),
but wasn't exposed to the userspace through the generic
atomic_get/set_property implementation, and wasn't stored in any generic
state structure.

Let's solve this.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index c74c78a28171..c06d0639d552 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -688,6 +688,8 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
return -EINVAL;
} else if (property == config->tv_select_subconnector_property) {
state->tv.select_subconnector = val;
+   } else if (property == config->tv_subconnector_property) {
+   state->tv.subconnector = val;
} else if (property == config->tv_left_margin_property) {
state->tv.margins.left = val;
} else if (property == config->tv_right_margin_property) {
@@ -796,6 +798,8 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = connector->dpms;
} else if (property == config->tv_select_subconnector_property) {
*val = state->tv.select_subconnector;
+   } else if (property == config->tv_subconnector_property) {
+   *val = state->tv.subconnector;
} else if (property == config->tv_left_margin_property) {
*val = state->tv.margins.left;
} else if (property == config->tv_right_margin_property) {
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f8091edf9a33..1e9996b33cc8 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -672,6 +672,7 @@ struct drm_connector_tv_margins {
 /**
  * struct drm_tv_connector_state - TV connector related states
  * @select_subconnector: selected subconnector
+ * @subconnector: detected subconnector
  * @margins: TV margins
  * @mode: TV mode
  * @brightness: brightness in percent
@@ -683,6 +684,7 @@ struct drm_connector_tv_margins {
  */
 struct drm_tv_connector_state {
enum drm_mode_subconnector select_subconnector;
+   enum drm_mode_subconnector subconnector;
struct drm_connector_tv_margins margins;
unsigned int mode;
unsigned int brightness;

-- 
b4 0.10.0-dev-49460


[PATCH v1 22/35] drm/vc4: vec: Use TV Reset implementation

2022-07-29 Thread Maxime Ripard
The analog TV properties created by the drm_mode_create_tv_properties() are
not properly initialised at reset. Let's switch our implementation to call
drm_atomic_helper_connector_tv_reset().

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index fba15a14787e..6f4536bf537f 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -254,6 +254,12 @@ vc4_vec_connector_detect(struct drm_connector *connector, 
bool force)
return connector_status_unknown;
 }
 
+void vc4_vec_connector_reset(struct drm_connector *connector)
+{
+   drm_atomic_helper_connector_reset(connector);
+   drm_atomic_helper_connector_tv_reset(connector);
+}
+
 static int vc4_vec_connector_get_modes(struct drm_connector *connector)
 {
struct drm_connector_state *state = connector->state;
@@ -274,7 +280,7 @@ static int vc4_vec_connector_get_modes(struct drm_connector 
*connector)
 static const struct drm_connector_funcs vc4_vec_connector_funcs = {
.detect = vc4_vec_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
-   .reset = drm_atomic_helper_connector_reset,
+   .reset = vc4_vec_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };

-- 
b4 0.10.0-dev-49460


[PATCH v1 26/35] drm/sun4i: tv: Convert to atomic hooks

2022-07-29 Thread Maxime Ripard
The VC4 VEC driver still uses legacy enable and disable hook
implementation. Let's convert to the atomic variants.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 53152d77c392..f7aad995ab5b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -339,7 +339,8 @@ static void sun4i_tv_mode_to_drm_mode(const struct tv_mode 
*tv_mode,
mode->vtotal = mode->vsync_end  + tv_mode->vback_porch;
 }
 
-static void sun4i_tv_disable(struct drm_encoder *encoder)
+static void sun4i_tv_disable(struct drm_encoder *encoder,
+   struct drm_atomic_state *state)
 {
struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
@@ -353,7 +354,8 @@ static void sun4i_tv_disable(struct drm_encoder *encoder)
sunxi_engine_disable_color_correction(crtc->engine);
 }
 
-static void sun4i_tv_enable(struct drm_encoder *encoder)
+static void sun4i_tv_enable(struct drm_encoder *encoder,
+   struct drm_atomic_state *state)
 {
struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
@@ -469,8 +471,8 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
 }
 
 static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
-   .disable= sun4i_tv_disable,
-   .enable = sun4i_tv_enable,
+   .atomic_disable = sun4i_tv_disable,
+   .atomic_enable  = sun4i_tv_enable,
.mode_set   = sun4i_tv_mode_set,
 };
 

-- 
b4 0.10.0-dev-49460


[PATCH v1 09/35] drm/modes: Move named modes parsing to a separate function

2022-07-29 Thread Maxime Ripard
The current construction of the named mode parsing doesn't allow to extend
it easily. Let's move it to a separate function so we can add more
parameters and modes.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 06a006e0b2e3..e85099df0326 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1773,6 +1773,28 @@ static const char * const drm_named_modes_whitelist[] = {
"PAL",
 };
 
+static bool drm_mode_parse_cmdline_named_mode(const char *name,
+ unsigned int name_end,
+ struct drm_cmdline_mode 
*cmdline_mode)
+{
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
+   int ret;
+
+   ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
+   if (ret != name_end)
+   continue;
+
+   strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
+   cmdline_mode->specified = true;
+
+   return true;
+   }
+
+   return false;
+}
+
 /**
  * drm_mode_parse_command_line_for_connector - parse command line modeline for 
connector
  * @mode_option: optional per connector mode option
@@ -1809,7 +1831,7 @@ bool drm_mode_parse_command_line_for_connector(const char 
*mode_option,
const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
const char *options_ptr = NULL;
char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL;
-   int i, len, ret;
+   int len, ret;
 
memset(mode, 0, sizeof(*mode));
mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
@@ -1848,18 +1870,14 @@ bool drm_mode_parse_command_line_for_connector(const 
char *mode_option,
parse_extras = true;
}
 
-   /* First check for a named mode */
-   for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
-   ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
-   if (ret == mode_end) {
-   if (refresh_ptr)
-   return false; /* named + refresh is invalid */
+   /*
+* Having a mode that starts by a letter (and thus is named) and
+* an at-sign (used to specify a refresh rate) is disallowed.
+*/
+   if (!isdigit(name[0]) && refresh_ptr)
+   return false;
 
-   strcpy(mode->name, drm_named_modes_whitelist[i]);
-   mode->specified = true;
-   break;
-   }
-   }
+   drm_mode_parse_cmdline_named_mode(name, mode_end, mode);
 
/* No named mode? Check for a normal mode argument, e.g. 1024x768 */
if (!mode->specified && isdigit(name[0])) {

-- 
b4 0.10.0-dev-49460


[PATCH v1 06/35] drm/connector: Only register TV mode property if present

2022-07-29 Thread Maxime Ripard
The drm_create_tv_properties() will create the TV mode property
unconditionally.

However, since we'll gradually phase it out, let's register it only if we
have a list passed as an argument. This will make the transition easier.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 68a4e47f85a9..d73a68764b6e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1684,7 +1684,6 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
struct drm_property *tv_selector;
struct drm_property *tv_subconnector;
struct drm_property *tv_norm;
-   unsigned int i;
 
if (dev->mode_config.tv_select_subconnector_property)
return 0;
@@ -1723,15 +1722,19 @@ int drm_mode_create_tv_properties(struct drm_device 
*dev,
goto nomem;
dev->mode_config.tv_norm_property = tv_norm;
 
-   dev->mode_config.tv_mode_property =
-   drm_property_create(dev, DRM_MODE_PROP_ENUM,
-   "mode", num_modes);
-   if (!dev->mode_config.tv_mode_property)
-   goto nomem;
+   if (num_modes) {
+   unsigned int i;
 
-   for (i = 0; i < num_modes; i++)
-   drm_property_add_enum(dev->mode_config.tv_mode_property,
- i, modes[i]);
+   dev->mode_config.tv_mode_property =
+   drm_property_create(dev, DRM_MODE_PROP_ENUM,
+   "mode", num_modes);
+   if (!dev->mode_config.tv_mode_property)
+   goto nomem;
+
+   for (i = 0; i < num_modes; i++)
+   drm_property_add_enum(dev->mode_config.tv_mode_property,
+ i, modes[i]);
+   }
 
dev->mode_config.tv_brightness_property =
drm_property_create_range(dev, 0, "brightness", 0, 100);

-- 
b4 0.10.0-dev-49460


[PATCH v1 33/35] drm/connector: Remove TV modes property

2022-07-29 Thread Maxime Ripard
Now that all the other drivers have been converted to the new style TV mode
property, let's get rid of the old one.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d7ff6c644c2f..d52e87e8e6aa 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -698,8 +698,6 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
state->tv.margins.top = val;
} else if (property == config->tv_bottom_margin_property) {
state->tv.margins.bottom = val;
-   } else if (property == config->tv_mode_property) {
-   state->tv.mode = val;
} else if (property == config->tv_norm_property) {
state->tv.norm = val;
} else if (property == config->tv_brightness_property) {
@@ -810,8 +808,6 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->tv.margins.top;
} else if (property == config->tv_bottom_margin_property) {
*val = state->tv.margins.bottom;
-   } else if (property == config->tv_mode_property) {
-   *val = state->tv.mode;
} else if (property == config->tv_norm_property) {
*val = state->tv.norm;
} else if (property == config->tv_brightness_property) {
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index d73a68764b6e..5e138159f2de 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1650,9 +1650,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
  * 0 on success or a negative error code on failure.
  */
 int drm_mode_create_tv_properties(struct drm_device *dev,
- unsigned int supported_tv_norms,
- unsigned int num_modes,
- const char * const modes[])
+ unsigned int supported_tv_norms)
 {
static const struct drm_prop_enum_list tv_norm_values[] = {
{ __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
@@ -1722,20 +1720,6 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
goto nomem;
dev->mode_config.tv_norm_property = tv_norm;
 
-   if (num_modes) {
-   unsigned int i;
-
-   dev->mode_config.tv_mode_property =
-   drm_property_create(dev, DRM_MODE_PROP_ENUM,
-   "mode", num_modes);
-   if (!dev->mode_config.tv_mode_property)
-   goto nomem;
-
-   for (i = 0; i < num_modes; i++)
-   drm_property_add_enum(dev->mode_config.tv_mode_property,
- i, modes[i]);
-   }
-
dev->mode_config.tv_brightness_property =
drm_property_create_range(dev, 0, "brightness", 0, 100);
if (!dev->mode_config.tv_brightness_property)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index bed52423776e..1d4025663530 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -526,8 +526,7 @@ static int sun4i_tv_bind(struct device *dev, struct device 
*master,
 
ret = drm_mode_create_tv_properties(drm,
DRM_MODE_TV_NORM_NTSC_M |
-   DRM_MODE_TV_NORM_PAL_B,
-   0, NULL);
+   DRM_MODE_TV_NORM_PAL_B);
if (ret)
goto err_cleanup_connector;
 
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 91d343238b0f..2e7e964928b3 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -704,8 +704,7 @@ static int vc4_vec_bind(struct device *dev, struct device 
*master, void *data)
DRM_MODE_TV_NORM_PAL_B |
DRM_MODE_TV_NORM_PAL_M |
DRM_MODE_TV_NORM_PAL_N |
-   DRM_MODE_TV_NORM_SECAM_B,
-   0, NULL);
+   DRM_MODE_TV_NORM_SECAM_B);
if (ret)
return ret;
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 78275e68ff66..e535dca6376e 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -712,7 +712,6 @@ struct drm_tv_connector_state {
enum drm_mode_subconnector select_subconnector;
enum drm_mode_subconnector subconnector;
struct drm_connector_tv_margins margins;
-   unsigned int mode;
unsigned int norm;
unsigned int brightness;
unsigned int contrast;
@@ -1806,9 +1805,7 @@ void drm_connector_at

[PATCH v1 19/35] drm/vc4: vec: Fix timings for VEC modes

2022-07-29 Thread Maxime Ripard
From: Mateusz Kwiatkowski 

This commit fixes vertical timings of the VEC (composite output) modes
to accurately represent the 525-line ("NTSC") and 625-line ("PAL") ITU-R
standards.

Previous timings were actually defined as 502 and 601 lines, resulting
in non-standard 62.69 Hz and 52 Hz signals being generated,
respectively.

Signed-off-by: Mateusz Kwiatkowski 
Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index a9fefd92f0f1..8f30a530b2d5 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -227,14 +227,14 @@ static const struct debugfs_reg32 vec_regs[] = {
 static const struct drm_display_mode ntsc_mode = {
DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
-480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0,
+480, 480 + 7, 480 + 7 + 6, 525, 0,
 DRM_MODE_FLAG_INTERLACE)
 };
 
 static const struct drm_display_mode pal_mode = {
DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
-576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0,
+576, 576 + 4, 576 + 4 + 6, 625, 0,
 DRM_MODE_FLAG_INTERLACE)
 };
 

-- 
b4 0.10.0-dev-49460


[PATCH v1 29/35] drm/sun4i: tv: Remove useless destroy function

2022-07-29 Thread Maxime Ripard
Our destroy implementation is just calling the generic helper, so let's
just remove our function and directly use the helper.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 52bbba8f19dc..6d7e1d51569a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -491,15 +491,9 @@ static const struct drm_connector_helper_funcs 
sun4i_tv_comp_connector_helper_fu
.get_modes  = sun4i_tv_comp_get_modes,
 };
 
-static void
-sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
-{
-   drm_connector_cleanup(connector);
-}
-
 static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
-   .destroy= sun4i_tv_comp_connector_destroy,
+   .destroy= drm_connector_cleanup,
.reset  = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,

-- 
b4 0.10.0-dev-49460


[PATCH v1 12/35] drmi/modes: Properly generate a drm_display_mode from a named mode

2022-07-29 Thread Maxime Ripard
The framework will get the drm_display_mode from the drm_cmdline_mode it
got by parsing the video command line argument by calling
drm_connector_pick_cmdline_mode().

The heavy lifting will then be done by the drm_mode_create_from_cmdline_mode()
function.

In the case of the named modes though, there's no real code to make that
translation and we rely on the drivers to guess which actual display mode
we meant.

Let's modify drm_mode_create_from_cmdline_mode() to properly generate the
drm_display_mode we mean when passing a named mode.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 78ea520f2822..ecb2e83cf860 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1967,6 +1967,28 @@ bool drm_mode_parse_command_line_for_connector(const 
char *mode_option,
 }
 EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
 
+static struct drm_display_mode *drm_named_mode(struct drm_device *dev,
+  struct drm_cmdline_mode *cmd)
+{
+   struct drm_display_mode *mode;
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) {
+   const struct drm_named_mode *named_mode = &drm_named_modes[i];
+
+   if (strcmp(cmd->name, named_mode->name))
+   continue;
+
+   mode = drm_mode_duplicate(dev, named_mode->mode);
+   if (!mode)
+   return NULL;
+
+   return mode;
+   }
+
+   return NULL;
+}
+
 /**
  * drm_mode_create_from_cmdline_mode - convert a command line modeline into a 
DRM display mode
  * @dev: DRM device to create the new mode for
@@ -1984,7 +2006,9 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
if (cmd->xres == 0 || cmd->yres == 0)
return NULL;
 
-   if (cmd->cvt)
+   if (strlen(cmd->name))
+   mode = drm_named_mode(dev, cmd);
+   else if (cmd->cvt)
mode = drm_cvt_mode(dev,
cmd->xres, cmd->yres,
cmd->refresh_specified ? cmd->refresh : 60,
diff --git a/drivers/gpu/drm/tests/drm_mode_test.c 
b/drivers/gpu/drm/tests/drm_mode_test.c
index 0f71519788a7..006b73a61fd4 100644
--- a/drivers/gpu/drm/tests/drm_mode_test.c
+++ b/drivers/gpu/drm/tests/drm_mode_test.c
@@ -34,6 +34,18 @@ static int drm_mode_connector_get_modes(struct drm_connector 
*connector)
if (ret)
return ret;
 
+   mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
+   if (!mode)
+   return -ENOMEM;
+
+   drm_mode_probed_add(connector, mode);
+
+   mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);
+   if (!mode)
+   return -ENOMEM;
+
+   drm_mode_probed_add(connector, mode);
+
return 0;
 }
 
@@ -75,6 +87,9 @@ static int drm_mode_test_init(struct kunit *test)
return ret;
drm_connector_helper_add(&priv->connector, 
&drm_mode_connector_helper_funcs);
 
+   priv->connector.interlace_allowed = true;
+   priv->connector.doublescan_allowed = true;
+
return 0;
 }
 
@@ -115,8 +130,62 @@ static void drm_mode_res_1920_1080_60(struct kunit *test)
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
 }
 
+static void drm_mode_named_ntsc(struct kunit *test)
+{
+   struct drm_mode_test_priv *priv = test->priv;
+   struct drm_device *drm = priv->drm;
+   struct drm_connector *connector = &priv->connector;
+   struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+   struct drm_display_mode *mode;
+   const char *cmdline = "NTSC";
+   int ret;
+
+   KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+   connector,
+   
cmdline_mode));
+
+   mutex_lock(&drm->mode_config.mutex);
+   ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
+   mutex_unlock(&drm->mode_config.mutex);
+   KUNIT_ASSERT_GT(test, ret, 0);
+
+   mode = drm_connector_pick_cmdline_mode(connector);
+   KUNIT_ASSERT_PTR_NE(test, mode, NULL);
+
+   KUNIT_EXPECT_TRUE(test, drm_mode_equal(&drm_mode_480i, mode));
+}
+
+static void drm_mode_named_pal(struct kunit *test)
+{
+   struct drm_mode_test_priv *priv = test->priv;
+   struct drm_device *drm = priv->drm;
+   struct drm_connector *connector = &priv->connector;
+   struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+   struct drm_display_mode *mode;
+   const char *cmdline = "PAL";
+   int ret;
+
+   KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+   connector,
+ 

[PATCH v1 35/35] drm/modes: Introduce more named modes

2022-07-29 Thread Maxime Ripard
Now that we can easily extend the named modes list, let's add a few more
analog TV modes that were used in the wild, and some unit tests to make
sure it works as intended.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 3634ac9f787d..09ed5ce7746d 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1853,7 +1853,9 @@ struct drm_named_mode {
 
 static const struct drm_named_mode drm_named_modes[] = {
{ "NTSC", &drm_mode_480i, DRM_MODE_TV_NORM_NTSC_M, },
+   { "NTSC_J", &drm_mode_480i, DRM_MODE_TV_NORM_NTSC_J, },
{ "PAL", &drm_mode_576i, DRM_MODE_TV_NORM_PAL_B, },
+   { "PAL_M", &drm_mode_480i, DRM_MODE_TV_NORM_PAL_M, },
 };
 
 static bool drm_mode_parse_cmdline_named_mode(const char *name,
diff --git a/drivers/gpu/drm/tests/drm_mode_test.c 
b/drivers/gpu/drm/tests/drm_mode_test.c
index 006b73a61fd4..991eb8ed687c 100644
--- a/drivers/gpu/drm/tests/drm_mode_test.c
+++ b/drivers/gpu/drm/tests/drm_mode_test.c
@@ -156,6 +156,32 @@ static void drm_mode_named_ntsc(struct kunit *test)
KUNIT_EXPECT_TRUE(test, drm_mode_equal(&drm_mode_480i, mode));
 }
 
+static void drm_mode_named_ntsc_j(struct kunit *test)
+{
+   struct drm_mode_test_priv *priv = test->priv;
+   struct drm_device *drm = priv->drm;
+   struct drm_connector *connector = &priv->connector;
+   struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+   struct drm_display_mode *mode;
+   const char *cmdline = "NTSC_J";
+   int ret;
+
+   KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+   connector,
+   
cmdline_mode));
+
+   mutex_lock(&drm->mode_config.mutex);
+   ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
+   mutex_unlock(&drm->mode_config.mutex);
+   KUNIT_ASSERT_GT(test, ret, 0);
+
+   mode = drm_connector_pick_cmdline_mode(connector);
+   KUNIT_ASSERT_PTR_NE(test, mode, NULL);
+
+   KUNIT_EXPECT_TRUE(test, drm_mode_equal(&drm_mode_480i, mode));
+}
+
 static void drm_mode_named_pal(struct kunit *test)
 {
struct drm_mode_test_priv *priv = test->priv;
@@ -182,10 +208,38 @@ static void drm_mode_named_pal(struct kunit *test)
KUNIT_EXPECT_TRUE(test, drm_mode_equal(&drm_mode_576i, mode));
 }
 
+static void drm_mode_named_pal_m(struct kunit *test)
+{
+   struct drm_mode_test_priv *priv = test->priv;
+   struct drm_device *drm = priv->drm;
+   struct drm_connector *connector = &priv->connector;
+   struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+   struct drm_display_mode *mode;
+   const char *cmdline = "PAL_M";
+   int ret;
+
+   KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+   connector,
+   
cmdline_mode));
+
+   mutex_lock(&drm->mode_config.mutex);
+   ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
+   mutex_unlock(&drm->mode_config.mutex);
+   KUNIT_ASSERT_GT(test, ret, 0);
+
+   mode = drm_connector_pick_cmdline_mode(connector);
+   KUNIT_ASSERT_PTR_NE(test, mode, NULL);
+
+   KUNIT_EXPECT_TRUE(test, drm_mode_equal(&drm_mode_480i, mode));
+}
+
 static struct kunit_case drm_mode_tests[] = {
KUNIT_CASE(drm_mode_res_1920_1080_60),
KUNIT_CASE(drm_mode_named_ntsc),
+   KUNIT_CASE(drm_mode_named_ntsc_j),
KUNIT_CASE(drm_mode_named_pal),
+   KUNIT_CASE(drm_mode_named_pal_m),
{}
 };
 

-- 
b4 0.10.0-dev-49460


[PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

2022-07-29 Thread Maxime Ripard
Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
modes in the drivers.

Since those modes are fairly standards, and that we'll need to use them in
more places in the future, let's move the meson definition into the
framework.

The meson one was chosen because vc4's isn't accurate and doesn't amount to
525 and 625 lines.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 304004fb80aa..a4c1bd688338 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -48,6 +48,24 @@
 
 #include "drm_crtc_internal.h"
 
+const struct drm_display_mode drm_mode_480i = {
+   DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
+720, 739, 801, 858, 0,
+480, 488, 494, 525, 0,
+DRM_MODE_FLAG_INTERLACE),
+   .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
+};
+EXPORT_SYMBOL_GPL(drm_mode_480i);
+
+const struct drm_display_mode drm_mode_576i = {
+   DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
+720, 732, 795, 864, 0,
+576, 580, 586, 625, 0,
+DRM_MODE_FLAG_INTERLACE),
+   .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
+};
+EXPORT_SYMBOL_GPL(drm_mode_576i);
+
 /**
  * drm_mode_debug_printmodeline - print a mode to dmesg
  * @mode: mode to print
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c 
b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
index 8110a6e39320..98ec3e563155 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
@@ -45,21 +45,11 @@ struct meson_encoder_cvbs {
 struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
{ /* PAL */
.enci = &meson_cvbs_enci_pal,
-   .mode = {
-   DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
-720, 732, 795, 864, 0, 576, 580, 586, 625, 0,
-DRM_MODE_FLAG_INTERLACE),
-   .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
-   },
+   .mode = &drm_mode_576i,
},
{ /* NTSC */
.enci = &meson_cvbs_enci_ntsc,
-   .mode = {
-   DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
-   720, 739, 801, 858, 0, 480, 488, 494, 525, 0,
-   DRM_MODE_FLAG_INTERLACE),
-   .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
-   },
+   .mode = &drm_mode_480i,
},
 };
 
@@ -71,7 +61,7 @@ meson_cvbs_get_mode(const struct drm_display_mode *req_mode)
for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
 
-   if (drm_mode_match(req_mode, &meson_mode->mode,
+   if (drm_mode_match(req_mode, meson_mode->mode,
   DRM_MODE_MATCH_TIMINGS |
   DRM_MODE_MATCH_CLOCK |
   DRM_MODE_MATCH_FLAGS |
@@ -104,7 +94,7 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge 
*bridge,
for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
 
-   mode = drm_mode_duplicate(priv->drm, &meson_mode->mode);
+   mode = drm_mode_duplicate(priv->drm, meson_mode->mode);
if (!mode) {
dev_err(priv->dev, "Failed to create a new display 
mode\n");
return 0;
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h 
b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
index 61d9d183ce7f..26cefb202924 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
@@ -16,7 +16,7 @@
 
 struct meson_cvbs_mode {
struct meson_cvbs_enci_mode *enci;
-   struct drm_display_mode mode;
+   const struct drm_display_mode *mode;
 };
 
 #define MESON_CVBS_MODES_COUNT 2
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index a80ae9639e96..b4a440e2688c 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -394,6 +394,9 @@ struct drm_display_mode {
 
 };
 
+extern const struct drm_display_mode drm_mode_480i;
+extern const struct drm_display_mode drm_mode_576i;
+
 /**
  * DRM_MODE_FMT - printf string for &struct drm_display_mode
  */

-- 
b4 0.10.0-dev-49460


[PATCH v1 18/35] drm/vc4: vec: Remove redundant atomic_mode_set

2022-07-29 Thread Maxime Ripard
From: Mateusz Kwiatkowski 

Let's remove the superfluous tv_mode field, which was redundant with the
mode field in struct drm_tv_connector_state.

Signed-off-by: Mateusz Kwiatkowski 
Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 02cef4134f2f..a9fefd92f0f1 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -171,8 +171,6 @@ struct vc4_vec {
 
struct clk *clock;
 
-   const struct vc4_vec_tv_mode *tv_mode;
-
struct debugfs_regset32 regset;
 };
 
@@ -316,7 +314,6 @@ static int vc4_vec_connector_init(struct drm_device *dev, 
struct vc4_vec *vec)
drm_object_attach_property(&connector->base,
   dev->mode_config.tv_mode_property,
   VC4_VEC_TV_MODE_NTSC);
-   vec->tv_mode = &vc4_vec_tv_modes[VC4_VEC_TV_MODE_NTSC];
 
drm_connector_attach_encoder(connector, &vec->encoder.base);
 
@@ -360,6 +357,11 @@ static void vc4_vec_encoder_enable(struct drm_encoder 
*encoder,
 {
struct drm_device *drm = encoder->dev;
struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
+   struct drm_connector *connector = &vec->connector;
+   struct drm_connector_state *conn_state =
+   drm_atomic_get_new_connector_state(state, connector);
+   const struct vc4_vec_tv_mode *tv_mode =
+   &vc4_vec_tv_modes[conn_state->tv.mode];
int idx, ret;
 
if (!drm_dev_enter(drm, &idx))
@@ -418,15 +420,14 @@ static void vc4_vec_encoder_enable(struct drm_encoder 
*encoder,
/* Mask all interrupts. */
VEC_WRITE(VEC_MASK0, 0);
 
-   VEC_WRITE(VEC_CONFIG0, vec->tv_mode->config0);
-   VEC_WRITE(VEC_CONFIG1, vec->tv_mode->config1);
+   VEC_WRITE(VEC_CONFIG0, tv_mode->config0);
+   VEC_WRITE(VEC_CONFIG1, tv_mode->config1);
 
-   if (vec->tv_mode->custom_freq != 0) {
+   if (tv_mode->custom_freq != 0) {
VEC_WRITE(VEC_FREQ3_2,
- (vec->tv_mode->custom_freq >> 16) &
- 0x);
+ (tv_mode->custom_freq >> 16) & 0x);
VEC_WRITE(VEC_FREQ1_0,
- vec->tv_mode->custom_freq & 0x);
+ tv_mode->custom_freq & 0x);
}
 
VEC_WRITE(VEC_DAC_MISC,
@@ -442,15 +443,6 @@ static void vc4_vec_encoder_enable(struct drm_encoder 
*encoder,
drm_dev_exit(idx);
 }
 
-static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder,
-   struct drm_crtc_state *crtc_state,
-   struct drm_connector_state *conn_state)
-{
-   struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
-
-   vec->tv_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
-}
-
 static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -470,7 +462,6 @@ static const struct drm_encoder_helper_funcs 
vc4_vec_encoder_helper_funcs = {
.atomic_check = vc4_vec_encoder_atomic_check,
.atomic_disable = vc4_vec_encoder_disable,
.atomic_enable = vc4_vec_encoder_enable,
-   .atomic_mode_set = vc4_vec_encoder_atomic_mode_set,
 };
 
 static int vc4_vec_late_register(struct drm_encoder *encoder)

-- 
b4 0.10.0-dev-49460


[PATCH v1 28/35] drm/sun4i: tv: Remove useless function

2022-07-29 Thread Maxime Ripard
The drm_connector_to_sun4i_tv() function isn't used anywhere in the driver,
so let's remove it.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 3944da9a3c34..52bbba8f19dc 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -275,13 +275,6 @@ drm_encoder_to_sun4i_tv(struct drm_encoder *encoder)
encoder);
 }
 
-static inline struct sun4i_tv *
-drm_connector_to_sun4i_tv(struct drm_connector *connector)
-{
-   return container_of(connector, struct sun4i_tv,
-   connector);
-}
-
 /*
  * FIXME: If only the drm_display_mode private field was usable, this
  * could go away...

-- 
b4 0.10.0-dev-49460


[PATCH v1 17/35] drm/vc4: vec: Refactor VEC TV mode setting

2022-07-29 Thread Maxime Ripard
From: Mateusz Kwiatkowski 

Change the mode_set function pointer logic to declarative config0,
config1 and custom_freq fields, to make TV mode setting logic more
concise and uniform.

Signed-off-by: Mateusz Kwiatkowski 
Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index ba0a81250d08..02cef4134f2f 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -194,7 +194,9 @@ enum vc4_vec_tv_mode_id {
 
 struct vc4_vec_tv_mode {
const struct drm_display_mode *mode;
-   void (*mode_set)(struct vc4_vec *vec);
+   u32 config0;
+   u32 config1;
+   u32 custom_freq;
 };
 
 static const struct debugfs_reg32 vec_regs[] = {
@@ -224,34 +226,6 @@ static const struct debugfs_reg32 vec_regs[] = {
VC4_REG32(VEC_DAC_MISC),
 };
 
-static void vc4_vec_ntsc_mode_set(struct vc4_vec *vec)
-{
-   struct drm_device *drm = vec->connector.dev;
-   int idx;
-
-   if (!drm_dev_enter(drm, &idx))
-   return;
-
-   VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN);
-   VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS);
-
-   drm_dev_exit(idx);
-}
-
-static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec)
-{
-   struct drm_device *drm = vec->connector.dev;
-   int idx;
-
-   if (!drm_dev_enter(drm, &idx))
-   return;
-
-   VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD);
-   VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS);
-
-   drm_dev_exit(idx);
-}
-
 static const struct drm_display_mode ntsc_mode = {
DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
@@ -259,37 +233,6 @@ static const struct drm_display_mode ntsc_mode = {
 DRM_MODE_FLAG_INTERLACE)
 };
 
-static void vc4_vec_pal_mode_set(struct vc4_vec *vec)
-{
-   struct drm_device *drm = vec->connector.dev;
-   int idx;
-
-   if (!drm_dev_enter(drm, &idx))
-   return;
-
-   VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD);
-   VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS);
-
-   drm_dev_exit(idx);
-}
-
-static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec)
-{
-   struct drm_device *drm = vec->connector.dev;
-   int idx;
-
-   if (!drm_dev_enter(drm, &idx))
-   return;
-
-   VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD);
-   VEC_WRITE(VEC_CONFIG1,
- VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ);
-   VEC_WRITE(VEC_FREQ3_2, 0x223b);
-   VEC_WRITE(VEC_FREQ1_0, 0x61d1);
-
-   drm_dev_exit(idx);
-}
-
 static const struct drm_display_mode pal_mode = {
DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
@@ -300,19 +243,24 @@ static const struct drm_display_mode pal_mode = {
 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
[VC4_VEC_TV_MODE_NTSC] = {
.mode = &ntsc_mode,
-   .mode_set = vc4_vec_ntsc_mode_set,
+   .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_NTSC_J] = {
.mode = &ntsc_mode,
-   .mode_set = vc4_vec_ntsc_j_mode_set,
+   .config0 = VEC_CONFIG0_NTSC_STD,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_PAL] = {
.mode = &pal_mode,
-   .mode_set = vc4_vec_pal_mode_set,
+   .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_PAL_M] = {
.mode = &pal_mode,
-   .mode_set = vc4_vec_pal_m_mode_set,
+   .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+   .custom_freq = 0x223b61d1,
},
 };
 
@@ -470,7 +418,16 @@ static void vc4_vec_encoder_enable(struct drm_encoder 
*encoder,
/* Mask all interrupts. */
VEC_WRITE(VEC_MASK0, 0);
 
-   vec->tv_mode->mode_set(vec);
+   VEC_WRITE(VEC_CONFIG0, vec->tv_mode->config0);
+   VEC_WRITE(VEC_CONFIG1, vec->tv_mode->config1);
+
+   if (vec->tv_mode->custom_freq != 0) {
+   VEC_WRITE(VEC_FREQ3_2,
+ (vec->tv_mode->custom_freq >> 16) &
+ 0x);
+   VEC_WRITE(VEC_FREQ1_0,
+ vec->tv_mode->custom_freq & 0x);
+   }
 
VEC_WRITE(VEC_DAC_MISC,
  VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N);

-- 
b4 0.10.0-dev-49460


[PATCH v1 07/35] drm/modes: Only consider bpp and refresh before options

2022-07-29 Thread Maxime Ripard
Some video= options might have a value that contains a dash. However, the
command line parsing mode considers all dashes as the separator between the
mode and the bpp count.

Let's rework the parsing code a bit to only consider a dash as the bpp
separator if it before a comma, the options separator.

A follow-up patch will add a unit-test for this once such an option is
introduced.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index a4c1bd688338..06a006e0b2e3 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1819,20 +1819,22 @@ bool drm_mode_parse_command_line_for_connector(const 
char *mode_option,
 
name = mode_option;
 
+   /* Locate the start of named options */
+   options_ptr = strchr(name, ',');
+   if (options_ptr)
+   options_off = options_ptr - name;
+   else
+   options_off = strlen(name);
+
/* Try to locate the bpp and refresh specifiers, if any */
-   bpp_ptr = strchr(name, '-');
+   bpp_ptr = strnchr(name, options_off, '-');
if (bpp_ptr)
bpp_off = bpp_ptr - name;
 
-   refresh_ptr = strchr(name, '@');
+   refresh_ptr = strnchr(name, options_off, '@');
if (refresh_ptr)
refresh_off = refresh_ptr - name;
 
-   /* Locate the start of named options */
-   options_ptr = strchr(name, ',');
-   if (options_ptr)
-   options_off = options_ptr - name;
-
/* Locate the end of the name / resolution, and parse it */
if (bpp_ptr) {
mode_end = bpp_off;

-- 
b4 0.10.0-dev-49460


[PATCH v1 15/35] drm/vc4: vec: Remove empty mode_fixup

2022-07-29 Thread Maxime Ripard
The mode_fixup hooks are deprecated, and the behaviour we implement is the
default one anyway. Let's remove it.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 457529e5d857..17a6afac61cd 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -483,14 +483,6 @@ static void vc4_vec_encoder_enable(struct drm_encoder 
*encoder)
drm_dev_exit(idx);
 }
 
-
-static bool vc4_vec_encoder_mode_fixup(struct drm_encoder *encoder,
-  const struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode)
-{
-   return true;
-}
-
 static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -518,7 +510,6 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder 
*encoder,
 static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
.disable = vc4_vec_encoder_disable,
.enable = vc4_vec_encoder_enable,
-   .mode_fixup = vc4_vec_encoder_mode_fixup,
.atomic_check = vc4_vec_encoder_atomic_check,
.atomic_mode_set = vc4_vec_encoder_atomic_mode_set,
 };

-- 
b4 0.10.0-dev-49460


[PATCH v1 25/35] drm/sun4i: tv: Remove unused mode_valid

2022-07-29 Thread Maxime Ripard
The mode_valid implementation is pretty much a nop, let's remove it.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 94883abe0dfd..53152d77c392 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -497,16 +497,8 @@ static int sun4i_tv_comp_get_modes(struct drm_connector 
*connector)
return i;
 }
 
-static int sun4i_tv_comp_mode_valid(struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   /* TODO */
-   return MODE_OK;
-}
-
 static const struct drm_connector_helper_funcs 
sun4i_tv_comp_connector_helper_funcs = {
.get_modes  = sun4i_tv_comp_get_modes,
-   .mode_valid = sun4i_tv_comp_mode_valid,
 };
 
 static void

-- 
b4 0.10.0-dev-49460


[PATCH v1 05/35] drm/connector: Add TV standard property

2022-07-29 Thread Maxime Ripard
The TV mode property has been around for a while now to select and get the
current TV mode output on an analog TV connector.

Despite that property name being generic, its content isn't and has been
driver-specific which makes it hard to build any generic behaviour on top
of it, both in kernel and user-space.

Let's create a new bitmask tv norm property, that can contain any of the
analog TV standards currently supported by kernel drivers. Each driver can
then pass in a bitmask of the modes it supports.

We'll then be able to phase out the older tv mode property.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index c06d0639d552..d7ff6c644c2f 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -700,6 +700,8 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
state->tv.margins.bottom = val;
} else if (property == config->tv_mode_property) {
state->tv.mode = val;
+   } else if (property == config->tv_norm_property) {
+   state->tv.norm = val;
} else if (property == config->tv_brightness_property) {
state->tv.brightness = val;
} else if (property == config->tv_contrast_property) {
@@ -810,6 +812,8 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->tv.margins.bottom;
} else if (property == config->tv_mode_property) {
*val = state->tv.mode;
+   } else if (property == config->tv_norm_property) {
+   *val = state->tv.norm;
} else if (property == config->tv_brightness_property) {
*val = state->tv.brightness;
} else if (property == config->tv_contrast_property) {
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index e3142c8142b3..68a4e47f85a9 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1637,6 +1637,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
 /**
  * drm_mode_create_tv_properties - create TV specific connector properties
  * @dev: DRM device
+ * @supported_tv_norms: Bitmask of TV norms supported (See DRM_MODE_TV_NORM_*)
  * @num_modes: number of different TV formats (modes) supported
  * @modes: array of pointers to strings containing name of each format
  *
@@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
  * 0 on success or a negative error code on failure.
  */
 int drm_mode_create_tv_properties(struct drm_device *dev,
+ unsigned int supported_tv_norms,
  unsigned int num_modes,
  const char * const modes[])
 {
+   static const struct drm_prop_enum_list tv_norm_values[] = {
+   { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
+   { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
+   };
struct drm_property *tv_selector;
struct drm_property *tv_subconnector;
+   struct drm_property *tv_norm;
unsigned int i;
 
if (dev->mode_config.tv_select_subconnector_property)
@@ -1686,6 +1716,13 @@ int drm_mode_create_

[PATCH v1 31/35] drm/sun4i: tv: Add missing reset assertion

2022-07-29 Thread Maxime Ripard
The reset line is deasserted at bind, and asserted if we ever encounter an
error there. However, it's never deasserted in unbind which will lead to a
resource unbalance.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index ad6a3739bfa9..74ff5ad6a8b9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -605,6 +605,7 @@ static void sun4i_tv_unbind(struct device *dev, struct 
device *master,
drm_connector_cleanup(&tv->connector);
drm_encoder_cleanup(&tv->encoder);
clk_disable_unprepare(tv->clk);
+   reset_control_assert(tv->reset);
 }
 
 static const struct component_ops sun4i_tv_ops = {

-- 
b4 0.10.0-dev-49460


[PATCH v1 32/35] drm/sun4i: tv: Convert to the new TV mode property

2022-07-29 Thread Maxime Ripard
Now that the core can deal fine with analog TV modes, let's convert the
sun4i TV driver to leverage those new features.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 74ff5ad6a8b9..bed52423776e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -140,23 +140,15 @@ struct resync_parameters {
 struct tv_mode {
char*name;
 
+   unsigned inttv_mode;
+   const struct drm_display_mode   *display_mode;
+
u32 mode;
u32 chroma_freq;
u16 back_porch;
u16 front_porch;
-   u16 line_number;
u16 vblank_level;
 
-   u32 hdisplay;
-   u16 hfront_porch;
-   u16 hsync_len;
-   u16 hback_porch;
-
-   u32 vdisplay;
-   u16 vfront_porch;
-   u16 vsync_len;
-   u16 vback_porch;
-
boolyc_en;
booldac3_en;
booldac_bit25_en;
@@ -212,7 +204,8 @@ static const struct resync_parameters pal_resync_parameters 
= {
 
 static const struct tv_mode tv_modes[] = {
{
-   .name   = "NTSC",
+   .tv_mode= DRM_MODE_TV_NORM_NTSC_M,
+   .display_mode   = &drm_mode_480i,
.mode   = SUN4I_TVE_CFG0_RES_480i,
.chroma_freq= 0x21f07c1f,
.yc_en  = true,
@@ -221,17 +214,6 @@ static const struct tv_mode tv_modes[] = {
 
.back_porch = 118,
.front_porch= 32,
-   .line_number= 525,
-
-   .hdisplay   = 720,
-   .hfront_porch   = 18,
-   .hsync_len  = 2,
-   .hback_porch= 118,
-
-   .vdisplay   = 480,
-   .vfront_porch   = 26,
-   .vsync_len  = 2,
-   .vback_porch= 17,
 
.vblank_level   = 240,
 
@@ -241,23 +223,13 @@ static const struct tv_mode tv_modes[] = {
.resync_params  = &ntsc_resync_parameters,
},
{
-   .name   = "PAL",
+   .tv_mode= DRM_MODE_TV_NORM_PAL_B,
+   .display_mode   = &drm_mode_576i,
.mode   = SUN4I_TVE_CFG0_RES_576i,
.chroma_freq= 0x2a098acb,
 
.back_porch = 138,
.front_porch= 24,
-   .line_number= 625,
-
-   .hdisplay   = 720,
-   .hfront_porch   = 3,
-   .hsync_len  = 2,
-   .hback_porch= 139,
-
-   .vdisplay   = 576,
-   .vfront_porch   = 28,
-   .vsync_len  = 2,
-   .vback_porch= 19,
 
.vblank_level   = 252,
 
@@ -275,63 +247,21 @@ drm_encoder_to_sun4i_tv(struct drm_encoder *encoder)
encoder);
 }
 
-/*
- * FIXME: If only the drm_display_mode private field was usable, this
- * could go away...
- *
- * So far, it doesn't seem to be preserved when the mode is passed by
- * to mode_set for some reason.
- */
-static const struct tv_mode *sun4i_tv_find_tv_by_mode(const struct 
drm_display_mode *mode)
+static const struct tv_mode *
+sun4i_tv_find_tv_by_mode(unsigned int mode)
 {
int i;
 
-   /* First try to identify the mode by name */
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
const struct tv_mode *tv_mode = &tv_modes[i];
 
-   DRM_DEBUG_DRIVER("Comparing mode %s vs %s",
-mode->name, tv_mode->name);
-
-   if (!strcmp(mode->name, tv_mode->name))
-   return tv_mode;
-   }
-
-   /* Then by number of lines */
-   for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
-   const struct tv_mode *tv_mode = &tv_modes[i];
-
-   DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)",
-mode->name, tv_mode->name,
-mode->vdisplay, tv_mode->vdisplay);
-
-   if (mode->vdisplay == tv_mode->vdisplay)
+   if (tv_mode->tv_mode == mode)
return tv_mode;
}
 
return NULL;
 }
 
-static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
- struct drm_display_mode *mode)
-{
-   DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name);
-
-   mode->type = DRM_MODE_TYPE_DRIVER;
-   mode->clock = 13500;
-   mode->flags = DRM_MODE_FLAG_INTERLACE;
-
-   mode->hdisplay = tv_mode->hdisplay;
-   mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch;
-   mode->hsync_end = mode->hsync_start + tv_mode->hsync_len;
-   mode->htotal = mode->hsync_end  + tv_mo

[PATCH v1 11/35] drm/modes: Fill drm_cmdline mode from named modes

2022-07-29 Thread Maxime Ripard
The current code to deal with named modes will only set the mode name, and
then it's up to drivers to try to match that name to whatever mode or
configuration they see fit.

The plan is to remove that need and move the named mode handling out of
drivers and into the core, and only rely on modes and properties. Let's
start by properly filling drm_cmdline_mode from a named mode.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 1421e5da49e0..78ea520f2822 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1770,11 +1770,12 @@ static int drm_mode_parse_cmdline_options(const char 
*str,
 
 struct drm_named_mode {
const char *name;
+   const struct drm_display_mode *mode;
 };
 
 static const struct drm_named_mode drm_named_modes[] = {
-   { "NTSC", },
-   { "PAL", },
+   { "NTSC", &drm_mode_480i, },
+   { "PAL", &drm_mode_576i, },
 };
 
 static bool drm_mode_parse_cmdline_named_mode(const char *name,
@@ -1792,6 +1793,9 @@ static bool drm_mode_parse_cmdline_named_mode(const char 
*name,
continue;
 
strcpy(cmdline_mode->name, mode->name);
+   cmdline_mode->xres = mode->mode->hdisplay;
+   cmdline_mode->yres = mode->mode->vdisplay;
+   cmdline_mode->interlace = !!(mode->mode->flags & 
DRM_MODE_FLAG_INTERLACE);
cmdline_mode->specified = true;
 
return true;

-- 
b4 0.10.0-dev-49460


[PATCH v1 24/35] drm/vc4: vec: Add support for more analog TV standards

2022-07-29 Thread Maxime Ripard
From: Mateusz Kwiatkowski 

Add support for the following composite output modes (all of them are
somewhat more obscure than the previously defined ones):

- NTSC_443 - NTSC-style signal with the chroma subcarrier shifted to
  4.43361875 MHz (the PAL subcarrier frequency). Never used for
  broadcasting, but sometimes used as a hack to play NTSC content in PAL
  regions (e.g. on VCRs).
- PAL_N - PAL with alternative chroma subcarrier frequency,
  3.58205625 MHz. Used as a broadcast standard in Argentina, Paraguay
  and Uruguay to fit 576i50 with colour in 6 MHz channel raster.
- PAL60 - 480i60 signal with PAL-style color at normal European PAL
  frequency. Another non-standard, non-broadcast mode, used in similar
  contexts as NTSC_443. Some displays support one but not the other.
- SECAM - French frequency-modulated analog color standard; also have
  been broadcast in Eastern Europe and various parts of Africa and Asia.
  Uses the same 576i50 timings as PAL.

Also added some comments explaining color subcarrier frequency
registers.

Signed-off-by: Mateusz Kwiatkowski 
Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index e40b55de1b3c..91d343238b0f 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -46,6 +46,7 @@
 #define VEC_CONFIG0_YDEL(x)((x) << 26)
 #define VEC_CONFIG0_CDEL_MASK  GENMASK(25, 24)
 #define VEC_CONFIG0_CDEL(x)((x) << 24)
+#define VEC_CONFIG0_SECAM_STD  BIT(21)
 #define VEC_CONFIG0_PBPR_FIL   BIT(18)
 #define VEC_CONFIG0_CHROMA_GAIN_MASK   GENMASK(17, 16)
 #define VEC_CONFIG0_CHROMA_GAIN_UNITY  (0 << 16)
@@ -76,6 +77,27 @@
 #define VEC_SOFT_RESET 0x10c
 #define VEC_CLMP0_START0x144
 #define VEC_CLMP0_END  0x148
+
+/*
+ * These set the color subcarrier frequency
+ * if VEC_CONFIG1_CUSTOM_FREQ is enabled.
+ *
+ * VEC_FREQ1_0 contains the most significant 16-bit half-word,
+ * VEC_FREQ3_2 contains the least significant 16-bit half-word.
+ * 0x8000 seems to be equivalent to the pixel clock
+ * (which itself is the VEC clock divided by 8).
+ *
+ * Reference values (with the default pixel clock of 13.5 MHz):
+ *
+ * NTSC  (3579545.[45] Hz) - 0x21F07C1F
+ * PAL   (4433618.75 Hz)   - 0x2A098ACB
+ * PAL-M (3575611.[888111] Hz) - 0x21E6EFE3
+ * PAL-N (3582056.25 Hz)   - 0x21F69446
+ *
+ * NOTE: For SECAM, it is used as the Dr center frequency,
+ * regardless of whether VEC_CONFIG1_CUSTOM_FREQ is enabled or not;
+ * that is specified as 4406250 Hz, which corresponds to 0x29C71C72.
+ */
 #define VEC_FREQ3_20x180
 #define VEC_FREQ1_00x184
 
@@ -118,6 +140,14 @@
 
 #define VEC_INTERRUPT_CONTROL  0x190
 #define VEC_INTERRUPT_STATUS   0x194
+
+/*
+ * Db center frequency for SECAM; the clock for this is the same as for
+ * VEC_FREQ3_2/VEC_FREQ1_0, which is used for Dr center frequency.
+ *
+ * This is specified as 425 Hz, which corresponds to 0x284BDA13.
+ * That is also the default value, so no need to set it explicitly.
+ */
 #define VEC_FCW_SECAM_B0x198
 #define VEC_SECAM_GAIN_VAL 0x19c
 
@@ -194,9 +224,13 @@ connector_to_vc4_vec(struct drm_connector *connector)
 
 enum vc4_vec_tv_mode_id {
VC4_VEC_TV_MODE_NTSC,
+   VC4_VEC_TV_MODE_NTSC_443,
VC4_VEC_TV_MODE_NTSC_J,
VC4_VEC_TV_MODE_PAL,
+   VC4_VEC_TV_MODE_PAL_60,
VC4_VEC_TV_MODE_PAL_M,
+   VC4_VEC_TV_MODE_PAL_N,
+   VC4_VEC_TV_MODE_SECAM,
 };
 
 struct vc4_vec_tv_mode {
@@ -234,6 +268,12 @@ static const struct debugfs_reg32 vec_regs[] = {
 };
 
 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
+   {
+   .mode = DRM_MODE_TV_NORM_NTSC_443,
+   .config0 = VEC_CONFIG0_NTSC_STD,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+   .custom_freq = 0x2a098acb,
+   },
{
.mode = DRM_MODE_TV_NORM_NTSC_M,
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
@@ -244,6 +284,12 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
.config0 = VEC_CONFIG0_NTSC_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
+   {
+   .mode = DRM_MODE_TV_NORM_PAL_60,
+   .config0 = VEC_CONFIG0_PAL_M_STD,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+   .custom_freq = 0x2a098acb,
+   },
{
.mode = DRM_MODE_TV_NORM_PAL_B,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
@@ -254,6 +300,17 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
.config0 = VEC_CONFIG0_PAL_M_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
+   {
+   .mode = DRM_MODE_TV_NORM_PAL_N,
+   .config0 = VEC_CONFIG0_PAL_N_STD,
+

[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a command-line option

2022-07-29 Thread Maxime Ripard
Our new tv mode option allows to specify the TV mode from a property.
However, it can still be useful, for example to avoid any boot time
artifact, to set that property directly from the kernel command line.

Let's add some code to allow it, and some unit tests to exercise that code.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index fce5569bd66a..49da8d8236f5 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -490,6 +490,7 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
 {
struct drm_device *dev = connector->dev;
+   struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
struct drm_connector_state *state = connector->state;
struct drm_property *prop;
uint64_t val;
@@ -500,6 +501,9 @@ void drm_atomic_helper_connector_tv_reset(struct 
drm_connector *connector)
   prop, &val))
state->tv.norm = val;
 
+   if (cmdline->tv_mode)
+   state->tv.norm = cmdline->tv_mode;
+
prop = dev->mode_config.tv_select_subconnector_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index ecb2e83cf860..3634ac9f787d 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1677,6 +1677,80 @@ static int drm_mode_parse_panel_orientation(const char 
*delim,
return 0;
 }
 
+#define TV_OPTION_EQUAL(value, len, option) \
+   ((strlen(option) == len) && !strncmp(value, option, len))
+
+static int drm_mode_parse_tv_mode(const char *delim,
+ struct drm_cmdline_mode *mode)
+{
+   const char *value;
+   unsigned int len;
+
+   if (*delim != '=')
+   return -EINVAL;
+
+   value = delim + 1;
+   delim = strchr(value, ',');
+   if (!delim)
+   delim = value + strlen(value);
+
+   len = delim - value;
+   if (TV_OPTION_EQUAL(value, len, "NTSC-443"))
+   mode->tv_mode = DRM_MODE_TV_NORM_NTSC_443;
+   else if (TV_OPTION_EQUAL(value, len, "NTSC-J"))
+   mode->tv_mode = DRM_MODE_TV_NORM_NTSC_J;
+   else if (TV_OPTION_EQUAL(value, len, "NTSC-M"))
+   mode->tv_mode = DRM_MODE_TV_NORM_NTSC_M;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-60"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_60;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-B"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_B;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-D"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_D;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-G"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_G;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-H"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_H;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-I"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_I;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-M"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_M;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-N"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_N;
+   else if (TV_OPTION_EQUAL(value, len, "PAL-NC"))
+   mode->tv_mode = DRM_MODE_TV_NORM_PAL_NC;
+   else if (TV_OPTION_EQUAL(value, len, "SECAM-60"))
+   mode->tv_mode = DRM_MODE_TV_NORM_SECAM_60;
+   else if (TV_OPTION_EQUAL(value, len, "SECAM-B"))
+   mode->tv_mode = DRM_MODE_TV_NORM_SECAM_B;
+   else if (TV_OPTION_EQUAL(value, len, "SECAM-D"))
+   mode->tv_mode = DRM_MODE_TV_NORM_SECAM_D;
+   else if (TV_OPTION_EQUAL(value, len, "SECAM-G"))
+   mode->tv_mode = DRM_MODE_TV_NORM_SECAM_G;
+   else if (TV_OPTION_EQUAL(value, len, "SECAM-K"))
+   mode->tv_mode = DRM_MODE_TV_NORM_SECAM_K;
+   else if (TV_OPTION_EQUAL(value, len, "SECAM-K1"))
+   mode->tv_mode = DRM_MODE_TV_NORM_SECAM_K1;
+   else if (TV_OPTION_EQUAL(value, len, "SECAM-L"))
+   mode->tv_mode = DRM_MODE_TV_NORM_SECAM_L;
+   else if (TV_OPTION_EQUAL(value, len, "HD480I"))
+   mode->tv_mode = DRM_MODE_TV_NORM_HD480I;
+   else if (TV_OPTION_EQUAL(value, len, "HD480P"))
+   mode->tv_mode = DRM_MODE_TV_NORM_HD480P;
+   else if (TV_OPTION_EQUAL(value, len, "HD576I"))
+   mode->tv_mode = DRM_MODE_TV_NORM_HD576I;
+   else if (TV_OPTION_EQUAL(value, len, "HD576P"))
+   mode->tv_mode = DRM_MODE_TV_NORM_HD576P;
+   else if (TV_OPTION_EQUAL(value, len, "HD720P"))
+   mode->tv_mode = DRM_MODE_TV_NORM_HD720P;
+   else if (TV_OPTION_EQUAL(value, len, "HD1080I"))
+  

[PATCH v1 20/35] drm/vc4: vec: Switch for common modes

2022-07-29 Thread Maxime Ripard
Now that the core has a definition for the 525 and 625 lines analog TV
modes, let's switch to it for vc4.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 8f30a530b2d5..255bba563fce 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -224,38 +224,24 @@ static const struct debugfs_reg32 vec_regs[] = {
VC4_REG32(VEC_DAC_MISC),
 };
 
-static const struct drm_display_mode ntsc_mode = {
-   DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
-720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
-480, 480 + 7, 480 + 7 + 6, 525, 0,
-DRM_MODE_FLAG_INTERLACE)
-};
-
-static const struct drm_display_mode pal_mode = {
-   DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
-720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
-576, 576 + 4, 576 + 4 + 6, 625, 0,
-DRM_MODE_FLAG_INTERLACE)
-};
-
 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
[VC4_VEC_TV_MODE_NTSC] = {
-   .mode = &ntsc_mode,
+   .mode = &drm_mode_480i,
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_NTSC_J] = {
-   .mode = &ntsc_mode,
+   .mode = &drm_mode_480i,
.config0 = VEC_CONFIG0_NTSC_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_PAL] = {
-   .mode = &pal_mode,
+   .mode = &drm_mode_576i,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_PAL_M] = {
-   .mode = &pal_mode,
+   .mode = &drm_mode_576i,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
.custom_freq = 0x223b61d1,

-- 
b4 0.10.0-dev-49460


[PATCH v1 08/35] drm/client: Add some tests for drm_connector_pick_cmdline_mode()

2022-07-29 Thread Maxime Ripard
drm_connector_pick_cmdline_mode() is in charge of finding a proper
drm_display_mode from the definition we got in the video= command line
argument.

Let's add some unit tests to make sure we're not getting any regressions
there.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index bbc535cc50dd..ee6b8f193c24 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -1237,3 +1237,7 @@ int drm_client_modeset_dpms(struct drm_client_dev 
*client, int mode)
return ret;
 }
 EXPORT_SYMBOL(drm_client_modeset_dpms);
+
+#ifdef CONFIG_DRM_KUNIT_TEST
+#include "tests/drm_mode_test.c"
+#endif
diff --git a/drivers/gpu/drm/tests/drm_mode_test.c 
b/drivers/gpu/drm/tests/drm_mode_test.c
new file mode 100644
index ..0f71519788a7
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_mode_test.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Maxime Ripard 
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct drm_mode_test_priv {
+   struct device *dev;
+   struct drm_device *drm;
+   struct drm_connector connector;
+};
+
+static const struct drm_mode_config_funcs drm_mode_config_funcs = {
+};
+
+static const struct drm_driver drm_mode_driver = {
+};
+
+static int drm_mode_connector_get_modes(struct drm_connector *connector)
+{
+   struct drm_display_mode *mode;
+   int ret;
+
+   ret = drm_add_modes_noedid(connector, 1920, 1200);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static const struct drm_connector_helper_funcs drm_mode_connector_helper_funcs 
= {
+   .get_modes = drm_mode_connector_get_modes,
+};
+
+static const struct drm_connector_funcs drm_mode_connector_funcs = {
+};
+
+static int drm_mode_test_init(struct kunit *test)
+{
+   struct drm_mode_test_priv *priv;
+   int ret;
+
+   priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return -ENOMEM;
+   test->priv = priv;
+
+   priv->dev = root_device_register("drm-mode-test");
+   if (IS_ERR(priv->dev))
+   return PTR_ERR(priv->dev);
+
+   priv->drm = drm_dev_alloc(&drm_mode_driver, priv->dev);
+   if (IS_ERR(priv->drm))
+   return PTR_ERR(priv->drm);
+   priv->drm->mode_config.funcs = &drm_mode_config_funcs;
+
+   ret = drmm_mode_config_init(priv->drm);
+   if (ret)
+   return ret;
+
+   ret = drmm_connector_init(priv->drm, &priv->connector,
+ &drm_mode_connector_funcs,
+ DRM_MODE_CONNECTOR_Unknown,
+ NULL);
+   if (ret)
+   return ret;
+   drm_connector_helper_add(&priv->connector, 
&drm_mode_connector_helper_funcs);
+
+   return 0;
+}
+
+static void drm_mode_test_exit(struct kunit *test)
+{
+   struct drm_mode_test_priv *priv = test->priv;
+
+   drm_dev_put(priv->drm);
+   root_device_unregister(priv->dev);
+}
+
+static void drm_mode_res_1920_1080_60(struct kunit *test)
+{
+   struct drm_mode_test_priv *priv = test->priv;
+   struct drm_device *drm = priv->drm;
+   struct drm_connector *connector = &priv->connector;
+   struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+   struct drm_display_mode *expected_mode, *mode;
+   const char *cmdline = "1920x1080@60";
+   int ret;
+
+   expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);
+   KUNIT_ASSERT_PTR_NE(test, expected_mode, NULL);
+
+   KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+   connector,
+   
cmdline_mode));
+
+   mutex_lock(&drm->mode_config.mutex);
+   ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
+   mutex_unlock(&drm->mode_config.mutex);
+   KUNIT_ASSERT_GT(test, ret, 0);
+
+   mode = drm_connector_pick_cmdline_mode(connector);
+   KUNIT_ASSERT_PTR_NE(test, mode, NULL);
+
+   KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
+}
+
+static struct kunit_case drm_mode_tests[] = {
+   KUNIT_CASE(drm_mode_res_1920_1080_60),
+   {}
+};
+
+static struct kunit_suite drm_mode_test_suite = {
+   .name = "drm_mode",
+   .init = drm_mode_test_init,
+   .exit = drm_mode_test_exit,
+   .test_cases = drm_mode_tests
+};
+
+kunit_test_suite(drm_mode_test_suite);
+MODULE_AUTHOR("Maxime Ripard ");
+MODULE_LICENSE("GPL");

-- 
b4 0.10.0-dev-49460


[PATCH v1 14/35] drm/atomic-helper: Add an analog TV atomic_check implementation

2022-07-29 Thread Maxime Ripard
The analog TV connector drivers share some atomic_check logic, and the new
TV standard property have created a bunch of new constraints that needs to
be shared across drivers too.

Let's create an atomic_check helper for those use cases.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 6d14cb0c64b1..fce5569bd66a 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -552,6 +552,93 @@ void drm_atomic_helper_connector_tv_reset(struct 
drm_connector *connector)
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 
+/**
+ * @drm_atomic_helper_connector_tv_check: Validate an analog TV connector state
+ * @connector: DRM Connector
+ * @state: the DRM State object
+ *
+ * Checks the state object to see if the requested state is valid for an
+ * analog TV connector.
+ *
+ * Returns:
+ * Zero for success, a negative error code on error.
+ */
+int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
+struct drm_atomic_state *state)
+{
+   struct drm_connector_state *old_conn_state =
+   drm_atomic_get_old_connector_state(state, connector);
+   struct drm_connector_state *new_conn_state =
+   drm_atomic_get_new_connector_state(state, connector);
+   const struct drm_display_mode *mode;
+   struct drm_crtc_state *crtc_state;
+   struct drm_crtc *crtc;
+
+   crtc = new_conn_state->crtc;
+   if (!crtc)
+   return 0;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   if (!crtc_state)
+   return -EINVAL;
+
+   switch (new_conn_state->tv.norm) {
+   case DRM_MODE_TV_NORM_NTSC_443:
+   fallthrough;
+   case DRM_MODE_TV_NORM_NTSC_J:
+   fallthrough;
+   case DRM_MODE_TV_NORM_NTSC_M:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_M:
+   mode = &drm_mode_480i;
+   break;
+
+   case DRM_MODE_TV_NORM_PAL_60:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_B:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_D:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_G:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_H:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_I:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_N:
+   fallthrough;
+   case DRM_MODE_TV_NORM_PAL_NC:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_60:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_B:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_D:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_G:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_K:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_K1:
+   fallthrough;
+   case DRM_MODE_TV_NORM_SECAM_L:
+   mode = &drm_mode_576i;
+   break;
+
+   default:
+   return -EINVAL;
+   }
+
+   if (!drm_mode_equal(mode, &crtc_state->mode))
+   return -EINVAL;
+
+   if (old_conn_state->tv.norm != new_conn_state->tv.norm)
+   crtc_state->mode_changed = true;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
diff --git a/include/drm/drm_atomic_state_helper.h 
b/include/drm/drm_atomic_state_helper.h
index c8fbce795ee7..b9740edb2658 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -26,6 +26,7 @@
 
 #include 
 
+struct drm_atomic_state;
 struct drm_bridge;
 struct drm_bridge_state;
 struct drm_crtc;
@@ -71,6 +72,8 @@ 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_tv_reset(struct drm_connector *connector);
+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,

-- 
b4 0.10.0-dev-49460


[PATCH v1 21/35] drm/vc4: vec: Fix definition of PAL-M mode

2022-07-29 Thread Maxime Ripard
From: Mateusz Kwiatkowski 

PAL-M is a Brazilian analog TV standard that uses a PAL-style chroma
subcarrier at 3.575611[888111] MHz on top of 525-line (480i60) timings.
This commit makes the driver actually use the proper VEC preset for this
mode instead of just changing PAL subcarrier frequency.

Signed-off-by: Mateusz Kwiatkowski 
Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 255bba563fce..fba15a14787e 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -69,6 +69,7 @@
 #define VEC_CONFIG0_STD_MASK   GENMASK(1, 0)
 #define VEC_CONFIG0_NTSC_STD   0
 #define VEC_CONFIG0_PAL_BDGHI_STD  1
+#define VEC_CONFIG0_PAL_M_STD  2
 #define VEC_CONFIG0_PAL_N_STD  3
 
 #define VEC_SCHPH  0x108
@@ -241,10 +242,9 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
[VC4_VEC_TV_MODE_PAL_M] = {
-   .mode = &drm_mode_576i,
-   .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
-   .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
-   .custom_freq = 0x223b61d1,
+   .mode = &drm_mode_480i,
+   .config0 = VEC_CONFIG0_PAL_M_STD,
+   .config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
 };
 

-- 
b4 0.10.0-dev-49460


[PATCH v1 13/35] drm/atomic-helper: Add a TV properties reset helper

2022-07-29 Thread Maxime Ripard
The drm_tv_create_properties() function will create a bunch of properties,
but it's up to each and every driver using that function to properly reset
the state of these properties leading to inconsistent behaviours.

Let's create a helper that will take care of it.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index dfb57217253b..6d14cb0c64b1 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -481,6 +481,77 @@ void drm_atomic_helper_connector_tv_margins_reset(struct 
drm_connector *connecto
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
 
+/**
+ * drm_atomic_helper_connector_tv_reset - Resets Analog TV connector properties
+ * @connector: DRM connector
+ *
+ * Resets the analog TV properties attached to a connector
+ */
+void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_connector_state *state = connector->state;
+   struct drm_property *prop;
+   uint64_t val;
+
+   prop = dev->mode_config.tv_norm_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.norm = val;
+
+   prop = dev->mode_config.tv_select_subconnector_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.select_subconnector = val;
+
+   prop = dev->mode_config.tv_subconnector_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.subconnector = val;
+
+   prop = dev->mode_config.tv_brightness_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.brightness = val;
+
+   prop = dev->mode_config.tv_contrast_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.contrast = val;
+
+   prop = dev->mode_config.tv_flicker_reduction_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.flicker_reduction = val;
+
+   prop = dev->mode_config.tv_overscan_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.overscan = val;
+
+   prop = dev->mode_config.tv_saturation_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.saturation = val;
+
+   prop = dev->mode_config.tv_hue_property;
+   if (prop)
+   if (!drm_object_property_get_default_value(&connector->base,
+  prop, &val))
+   state->tv.hue = val;
+
+   drm_atomic_helper_connector_tv_margins_reset(connector);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
diff --git a/include/drm/drm_atomic_state_helper.h 
b/include/drm/drm_atomic_state_helper.h
index 192766656b88..c8fbce795ee7 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -70,6 +70,7 @@ void __drm_atomic_helper_connector_state_reset(struct 
drm_connector_state *conn_
 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_tv_reset(struct drm_connector *connector);
 void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector 
*connector);
 void
 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,

-- 
b4 0.10.0-dev-49460


[PATCH v1 10/35] drm/modes: Switch to named mode descriptors

2022-07-29 Thread Maxime Ripard
The current named mode parsing relies only the mode name, and doesn't allow
to specify any other parameter.

Let's convert that string list to an array of a custom structure that will
hold the name and some additional parameters in the future.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index e85099df0326..1421e5da49e0 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1768,9 +1768,13 @@ static int drm_mode_parse_cmdline_options(const char 
*str,
return 0;
 }
 
-static const char * const drm_named_modes_whitelist[] = {
-   "NTSC",
-   "PAL",
+struct drm_named_mode {
+   const char *name;
+};
+
+static const struct drm_named_mode drm_named_modes[] = {
+   { "NTSC", },
+   { "PAL", },
 };
 
 static bool drm_mode_parse_cmdline_named_mode(const char *name,
@@ -1779,14 +1783,15 @@ static bool drm_mode_parse_cmdline_named_mode(const 
char *name,
 {
unsigned int i;
 
-   for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
+   for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) {
+   const struct drm_named_mode *mode = &drm_named_modes[i];
int ret;
 
-   ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
+   ret = str_has_prefix(name, mode->name);
if (ret != name_end)
continue;
 
-   strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
+   strcpy(cmdline_mode->name, mode->name);
cmdline_mode->specified = true;
 
return true;

-- 
b4 0.10.0-dev-49460


[PATCH v1 30/35] drm/sun4i: tv: Rename error label

2022-07-29 Thread Maxime Ripard
The other error labels in sun4i_tv_bind() are named after the task they
perform (err_disable_clk to call clk_disable_unprepare for example).

However, the err_cleanup_connector is named after the calling site
(drm_connector_init failing) and will actually cleanup the encoder. Let's
rename it to err_cleanup_encoder to be consistent.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 6d7e1d51569a..ad6a3739bfa9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -580,7 +580,7 @@ static int sun4i_tv_bind(struct device *dev, struct device 
*master,
if (ret) {
dev_err(dev,
"Couldn't initialise the Composite connector\n");
-   goto err_cleanup_connector;
+   goto err_cleanup_encoder;
}
tv->connector.interlace_allowed = true;
 
@@ -588,7 +588,7 @@ static int sun4i_tv_bind(struct device *dev, struct device 
*master,
 
return 0;
 
-err_cleanup_connector:
+err_cleanup_encoder:
drm_encoder_cleanup(&tv->encoder);
 err_disable_clk:
clk_disable_unprepare(tv->clk);

-- 
b4 0.10.0-dev-49460


[PATCH v1 23/35] drm/vc4: vec: Convert to the new TV mode property

2022-07-29 Thread Maxime Ripard
Now that the core can deal fine with analog TV modes, let's convert the vc4
VEC driver to leverage those new features.

We've added some backward compatibility to support the old TV mode property
and translate it into the new TV norm property.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 6f4536bf537f..e40b55de1b3c 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -172,6 +172,8 @@ struct vc4_vec {
 
struct clk *clock;
 
+   struct drm_property *tv_mode_property;
+
struct debugfs_regset32 regset;
 };
 
@@ -184,6 +186,12 @@ encoder_to_vc4_vec(struct drm_encoder *encoder)
return container_of(encoder, struct vc4_vec, encoder.base);
 }
 
+static inline struct vc4_vec *
+connector_to_vc4_vec(struct drm_connector *connector)
+{
+   return container_of(connector, struct vc4_vec, connector);
+}
+
 enum vc4_vec_tv_mode_id {
VC4_VEC_TV_MODE_NTSC,
VC4_VEC_TV_MODE_NTSC_J,
@@ -192,7 +200,7 @@ enum vc4_vec_tv_mode_id {
 };
 
 struct vc4_vec_tv_mode {
-   const struct drm_display_mode *mode;
+   unsigned int mode;
u32 config0;
u32 config1;
u32 custom_freq;
@@ -226,28 +234,50 @@ static const struct debugfs_reg32 vec_regs[] = {
 };
 
 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
-   [VC4_VEC_TV_MODE_NTSC] = {
-   .mode = &drm_mode_480i,
+   {
+   .mode = DRM_MODE_TV_NORM_NTSC_M,
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
-   [VC4_VEC_TV_MODE_NTSC_J] = {
-   .mode = &drm_mode_480i,
+   {
+   .mode = DRM_MODE_TV_NORM_NTSC_J,
.config0 = VEC_CONFIG0_NTSC_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
-   [VC4_VEC_TV_MODE_PAL] = {
-   .mode = &drm_mode_576i,
+   {
+   .mode = DRM_MODE_TV_NORM_PAL_B,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
-   [VC4_VEC_TV_MODE_PAL_M] = {
-   .mode = &drm_mode_480i,
+   {
+   .mode = DRM_MODE_TV_NORM_PAL_M,
.config0 = VEC_CONFIG0_PAL_M_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
 };
 
+static inline const struct vc4_vec_tv_mode *
+vc4_vec_tv_mode_lookup(unsigned int mode)
+{
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(vc4_vec_tv_modes); i++) {
+   const struct vc4_vec_tv_mode *tv_mode = &vc4_vec_tv_modes[i];
+
+   if (tv_mode->mode == mode)
+   return tv_mode;
+   }
+
+   return NULL;
+}
+
+static const struct drm_prop_enum_list tv_mode_names[] = {
+   { VC4_VEC_TV_MODE_NTSC, "NTSC", },
+   { VC4_VEC_TV_MODE_NTSC_J, "NTSC-J", },
+   { VC4_VEC_TV_MODE_PAL, "PAL", },
+   { VC4_VEC_TV_MODE_PAL_M, "PAL-M", },
+};
+
 static enum drm_connector_status
 vc4_vec_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -262,11 +292,17 @@ void vc4_vec_connector_reset(struct drm_connector 
*connector)
 
 static int vc4_vec_connector_get_modes(struct drm_connector *connector)
 {
-   struct drm_connector_state *state = connector->state;
struct drm_display_mode *mode;
 
-   mode = drm_mode_duplicate(connector->dev,
- vc4_vec_tv_modes[state->tv.mode].mode);
+   mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
+   if (!mode) {
+   DRM_ERROR("Failed to create a new display mode\n");
+   return -ENOMEM;
+   }
+
+   drm_mode_probed_add(connector, mode);
+
+   mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);
if (!mode) {
DRM_ERROR("Failed to create a new display mode\n");
return -ENOMEM;
@@ -277,21 +313,95 @@ static int vc4_vec_connector_get_modes(struct 
drm_connector *connector)
return 1;
 }
 
+static int
+vc4_vec_connector_set_property(struct drm_connector *connector,
+  struct drm_connector_state *state,
+  struct drm_property *property,
+  uint64_t val)
+{
+   struct vc4_vec *vec = connector_to_vc4_vec(connector);
+
+   if (property != vec->tv_mode_property)
+   return -EINVAL;
+
+   switch (val) {
+   case VC4_VEC_TV_MODE_NTSC:
+   state->tv.norm = DRM_MODE_TV_NORM_NTSC_M;
+   break;
+
+   case VC4_VEC_TV_MODE_NTSC_J:
+   state->tv.norm = DRM_MODE_TV_NORM_NTSC_J;
+   break;
+
+   case VC4_VEC_TV_MODE_PAL:
+   state->tv.norm = DRM_MODE_TV_NORM_PAL_B;
+   break;
+
+   case VC4_VEC_TV_MODE_PAL_M:
+   state->tv.norm = DRM_MODE_TV_NORM_PAL_M;
+   break;
+
+   default:
+   return -EI

Re: [PATCH v2] drm/tests: Split up test cases in igt_check_drm_format_min_pitch

2022-07-29 Thread Melissa Wen
On 07/29, Maíra Canal wrote:
> The igt_check_drm_format_min_pitch() function had a lot of
> KUNIT_EXPECT_* calls, all of which ended up allocating and initializing
> various test assertion structures on the stack.
> 
> This behavior was producing -Wframe-larger-than warnings on PowerPC, i386,
> and MIPS architectures, such as:
> 
> drivers/gpu/drm/tests/drm_format_test.c: In function 
> 'igt_check_drm_format_min_pitch':
> drivers/gpu/drm/tests/drm_format_test.c:271:1: error: the frame size of
> 3712 bytes is larger than 2048 bytes
> 
> So, the igt_check_drm_format_min_pitch() test case was split into three
> smaller functions: one testing single plane formats, one testing
> multi-planar formats, and the other testing tiled formats.
> 
> Fixes: 0421bb0baa84 ("drm: selftest: convert drm_format selftest to KUnit")
> Reported-by: kernel test robot 
> Reported-by: Guenter Roeck 
> Signed-off-by: Maíra Canal 
> Tested-by: Guenter Roeck 
> Reviewed-by: André Almeida 

Applied to drm-misc-next

Thanks,

Melissa
> ---
> v1 -> v2:
> - Add Guenter's Tested-by tag.
> - Add André's Reviewed-by tag.
> - Replace "multiple planes" for "multi-planar" (André Almeida).
> - Add Fixes tag (Melissa Wen).
> ---
>  drivers/gpu/drm/tests/drm_format_test.c | 16 ++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_format_test.c 
> b/drivers/gpu/drm/tests/drm_format_test.c
> index 056cb8599d6d..afb4bca72187 100644
> --- a/drivers/gpu/drm/tests/drm_format_test.c
> +++ b/drivers/gpu/drm/tests/drm_format_test.c
> @@ -91,7 +91,7 @@ static void igt_check_drm_format_block_height(struct kunit 
> *test)
>   KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
>  }
>  
> -static void igt_check_drm_format_min_pitch(struct kunit *test)
> +static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit 
> *test)
>  {
>   const struct drm_format_info *info = NULL;
>  
> @@ -175,6 +175,11 @@ static void igt_check_drm_format_min_pitch(struct kunit 
> *test)
>   (uint64_t)UINT_MAX * 4);
>   KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 
> 1)),
>   (uint64_t)(UINT_MAX - 1) * 4);
> +}
> +
> +static void igt_check_drm_format_min_pitch_for_multi_planar(struct kunit 
> *test)
> +{
> + const struct drm_format_info *info = NULL;
>  
>   /* Test 2 planes format */
>   info = drm_format_info(DRM_FORMAT_NV12);
> @@ -249,6 +254,11 @@ static void igt_check_drm_format_min_pitch(struct kunit 
> *test)
>   (uint64_t)(UINT_MAX - 1) / 2);
>   KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) 
> / 2),
>   (uint64_t)(UINT_MAX - 1) / 2);
> +}
> +
> +static void igt_check_drm_format_min_pitch_for_tiled_format(struct kunit 
> *test)
> +{
> + const struct drm_format_info *info = NULL;
>  
>   /* Test tiled format */
>   info = drm_format_info(DRM_FORMAT_X0L2);
> @@ -273,7 +283,9 @@ static void igt_check_drm_format_min_pitch(struct kunit 
> *test)
>  static struct kunit_case drm_format_tests[] = {
>   KUNIT_CASE(igt_check_drm_format_block_width),
>   KUNIT_CASE(igt_check_drm_format_block_height),
> - KUNIT_CASE(igt_check_drm_format_min_pitch),
> + KUNIT_CASE(igt_check_drm_format_min_pitch_for_single_plane),
> + KUNIT_CASE(igt_check_drm_format_min_pitch_for_multi_planar),
> + KUNIT_CASE(igt_check_drm_format_min_pitch_for_tiled_format),
>   { }
>  };
>  
> -- 
> 2.37.1
> 


signature.asc
Description: PGP signature


Re: [RFC PATCH] drm/edid: Make 144 Hz not preferred on Sharp LQ140M1JW46

2022-07-29 Thread Maxime Ripard
On Fri, Jul 29, 2022 at 07:50:20AM -0700, Doug Anderson wrote:
> On Fri, Jul 29, 2022 at 12:51 AM Maxime Ripard  wrote:
> >
> > On Thu, Jul 28, 2022 at 02:18:38PM -0700, Doug Anderson wrote:
> > > Hi,
> > >
> > > On Thu, Jul 28, 2022 at 10:34 AM Abhinav Kumar
> > >  wrote:
> > > >
> > > > Hi Rob and Doug
> > > >
> > > > On 7/22/2022 10:36 AM, Rob Clark wrote:
> > > > > On Fri, Jul 22, 2022 at 9:48 AM Doug Anderson  
> > > > > wrote:
> > > > >>
> > > > >> Hi,
> > > > >>
> > > > >> On Fri, Jul 22, 2022 at 9:37 AM Abhinav Kumar 
> > > > >>  wrote:
> > > > >>>
> > > > >>> + sankeerth
> > > > >>>
> > > > >>> Hi Doug
> > > > >>>
> > > > >>> On 7/21/2022 3:23 PM, Douglas Anderson wrote:
> > > >  The Sharp LQ140M1JW46 panel is on the Qualcomm sc7280 CRD reference
> > > >  board. This panel supports 144 Hz and 60 Hz. In the EDID, the 144 
> > > >  Hz
> > > >  mode is listed first and thus is marked preferred. The EDID decode 
> > > >  I
> > > >  ran says:
> > > > 
> > > >  First detailed timing includes the native pixel format and 
> > > >  preferred
> > > >  refresh rate.
> > > > 
> > > >  ...
> > > > 
> > > >  Detailed Timing Descriptors:
> > > >    DTD 1:  1920x1080  143.981 Hz  16:9   166.587 kHz  346.500 
> > > >  MHz
> > > > Hfront   48 Hsync  32 Hback  80 Hpol N
> > > > Vfront3 Vsync   5 Vback  69 Vpol N
> > > >    DTD 2:  1920x1080   59.990 Hz  16:969.409 kHz  144.370 
> > > >  MHz
> > > > Hfront   48 Hsync  32 Hback  80 Hpol N
> > > > Vfront3 Vsync   5 Vback  69 Vpol N
> > > > 
> > > >  I'm proposing here that the above is actually a bug and that the 
> > > >  60 Hz
> > > >  mode really should be considered preferred by Linux.
> > > >
> > > > Its a bit tricky to say that this is a bug but I think we can certainly
> > > > add here that for an internal display we would have ideally had the
> > > > lower resolution first to indicate it as default.
> > >
> > > Yeah, it gets into the vagueness of the EDID spec in general. As far
> > > as I can find it's really up to the monitor to decide by what means it
> > > chooses the "preferred" refresh rate if the monitor can support many.
> > > Some displays may decide that the normal rate is "preferred" and some
> > > may decide that the high refresh rate is "preferred". Neither display
> > > is "wrong" per say, but it's nice to have some consistency here and to
> > > make it so that otherwise "dumb" userspace will get something
> > > reasonable by default. I'll change it to say:
> > >
> > > While the EDID spec appears to allow a display to use any criteria for
> > > picking which refresh mode is "preferred" or "optimal", that vagueness
> > > is a bit annoying. From Linux's point of view let's choose the 60 Hz
> > > one as the default.
> >
> > And if we start making that decision, it should be for all panels with a
> > similar constraint, so most likely handled by the core, and the new
> > policy properly documented.
> >
> > Doing that just for a single panel is weird.
> 
> Yeah, though having a "general policy" in the core can be problematic.
> 
> In general I think panel EDIDs are only trustworthy as far as you can
> throw them. They are notorious for having wrong and incorrect
> information, which is why the EDID quirk list exists to begin with.
> Trying to change how we're going to interpret all EDIDs, even all
> EDIDs for eDP panels, seems like it will break someone somewhere.
> Maybe there are EDIDs out there that were only ever validated at the
> higher refresh rate and they don't work / flicker / cause digitizer
> noise at the lower refresh rate. Heck, we've seen eDP panel vendors
> that can't even get their checksum correct, so I'm not sure I want to
> make a global assertion that all panels validated their "secondary"
> display mode.
>
> In this particular case, we have validated that this particular Sharp
> panel works fine at the lower refresh rate.
> 
> I would also note that, as far as I understand it, ODMs actually can
> request different EDIDs from the panel vendors. In the past we have
> been able to get panel vendors to change EDIDs. Thus for most panels
> I'd expect that we would discover this early, change the EDID default,
> and be done with it. The case here is a little unusual in that by the
> time we got involved and started digging into this panel too many were
> created and nobody wants to throw away those old panels. This is why
> I'm treating it as a quirk/bug. Really: we should have updated the
> EDID of the panel but we're unable to in this case.

You raise some good points, but most of the discussion around that patch
were mostly around performances, power consumption and so on.

This is very much a policy decision, and if there is some panel where
the EDID reports 60Hz but is broken, then that panel should be the
exception

RE: [PATCH] drm/kmb: fix dereference before NULL check in kmb_plane_atomic_update()

2022-07-29 Thread Chrisanthus, Anitha
Agree with Thomas, drm_atomic_commit() will not call kmb_atomic_update() with a 
NULL plane. This is not an actual bug.

Thanks,
Anitha 

> -Original Message-
> From: Thomas Zimmermann 
> Sent: Friday, July 29, 2022 7:26 AM
> To: Zeng Jingxiang ; Chrisanthus, Anitha
> ; edmund.j@intel.com; airl...@linux.ie;
> dan...@ffwll.ch; laurent.pinch...@ideasonboard.com; max...@cerno.tech;
> ville.syrj...@linux.intel.com
> Cc: Zeng Jingxiang ; linux-ker...@vger.kernel.org;
> dri-devel@lists.freedesktop.org
> Subject: Re: [PATCH] drm/kmb: fix dereference before NULL check in
> kmb_plane_atomic_update()
> 
> Hi
> 
> Am 29.07.22 um 16:23 schrieb Thomas Zimmermann:
> > Hi
> >
> > Am 29.07.22 um 05:07 schrieb Zeng Jingxiang:
> >> From: Zeng Jingxiang 
> >>
> >> The "plane" pointer was access before checking if it was NULL.
> >>
> >> The drm_atomic_get_old_plane_state() function will dereference
> >> the pointer "plane".
> >> 345    struct drm_plane_state *old_plane_state =
> >>     drm_atomic_get_old_plane_state(state, plane);
> >> 346    struct drm_plane_state *new_plane_state =
> >>     drm_atomic_get_new_plane_state(state, plane);
> >>
> >> A NULL check for "plane" indicates that it may be NULL
> >> 363    if (!plane || !new_plane_state || !old_plane_state)
> >
> > Is this an actual bug that happens?
> >
> > All planes should always have a state. Therefore the tests for
> > !new_plane_state and !old_plane_state can be removed, I'd say.
> 
> Just to clarify: moving the test for !plane before using one of the
> get_plane_state functions is a correct bugfix.
> 
> Best regards
> Thomas
> 
> >
> > Best regards
> > Thomas
> >
> >>
> >> Fixes: 977697e20b3d ("drm/atomic: Pass the full state to planes atomic
> >> disable and update")
> >> Fixes: 37418bf14c13 ("drm: Use state helper instead of the plane state
> >> pointer")
> >> Signed-off-by: Zeng Jingxiang 
> >> ---
> >>   drivers/gpu/drm/kmb/kmb_plane.c | 13 -
> >>   1 file changed, 8 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/kmb/kmb_plane.c
> >> b/drivers/gpu/drm/kmb/kmb_plane.c
> >> index 2735b8eb3537..d2bc998b65ce 100644
> >> --- a/drivers/gpu/drm/kmb/kmb_plane.c
> >> +++ b/drivers/gpu/drm/kmb/kmb_plane.c
> >> @@ -342,10 +342,7 @@ static void kmb_plane_set_alpha(struct
> >> kmb_drm_private *kmb,
> >>   static void kmb_plane_atomic_update(struct drm_plane *plane,
> >>   struct drm_atomic_state *state)
> >>   {
> >> -    struct drm_plane_state *old_plane_state =
> >> drm_atomic_get_old_plane_state(state,
> >> - plane);
> >> -    struct drm_plane_state *new_plane_state =
> >> drm_atomic_get_new_plane_state(state,
> >> - plane);
> >> +    struct drm_plane_state *old_plane_state, *new_plane_state;
> >>   struct drm_framebuffer *fb;
> >>   struct kmb_drm_private *kmb;
> >>   unsigned int width;
> >> @@ -360,7 +357,13 @@ static void kmb_plane_atomic_update(struct
> >> drm_plane *plane,
> >>   static dma_addr_t addr[MAX_SUB_PLANES];
> >>   struct disp_cfg *init_disp_cfg;
> >> -    if (!plane || !new_plane_state || !old_plane_state)
> >> +    if (!plane)
> >> +    return;
> >> +
> >> +    old_plane_state = drm_atomic_get_old_plane_state(state, plane);
> >> +    new_plane_state = drm_atomic_get_new_plane_state(state, plane);
> >> +
> >> +    if (!new_plane_state || !old_plane_state)
> >>   return;
> >>   fb = new_plane_state->fb;
> >
> 
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Ivo Totev


[PATCH v1 02/35] drm/connector: Rename subconnector state variable

2022-07-29 Thread Maxime Ripard
There is two TV subconnector related properties registered by
drm_mode_create_tv_properties(): subconnector and select subconnector.

While the select subconnector property is stored in the kernel by the
drm_tv_connector_state structure, the subconnector property isn't stored
anywhere.

Worse, the select subconnector property is stored in a field called
subconnector, creating some ambiguity about which property content we're
accessing.

Let's rename that field to one called select_subconnector to make it move
obvious what it's about.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 79730fa1dd8e..c74c78a28171 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -687,7 +687,7 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
 */
return -EINVAL;
} else if (property == config->tv_select_subconnector_property) {
-   state->tv.subconnector = val;
+   state->tv.select_subconnector = val;
} else if (property == config->tv_left_margin_property) {
state->tv.margins.left = val;
} else if (property == config->tv_right_margin_property) {
@@ -795,7 +795,7 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
else
*val = connector->dpms;
} else if (property == config->tv_select_subconnector_property) {
-   *val = state->tv.subconnector;
+   *val = state->tv.select_subconnector;
} else if (property == config->tv_left_margin_property) {
*val = state->tv.margins.left;
} else if (property == config->tv_right_margin_property) {
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f185ad862cb1..f8091edf9a33 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -682,7 +682,7 @@ struct drm_connector_tv_margins {
  * @hue: hue in percent
  */
 struct drm_tv_connector_state {
-   enum drm_mode_subconnector subconnector;
+   enum drm_mode_subconnector select_subconnector;
struct drm_connector_tv_margins margins;
unsigned int mode;
unsigned int brightness;

-- 
b4 0.10.0-dev-49460


[PATCH v1 01/35] drm/atomic-helper: Rename drm_atomic_helper_connector_tv_reset to avoid ambiguity

2022-07-29 Thread Maxime Ripard
We currently have two sets of TV properties.

The first one is there to deal with analog TV properties, creating
properties such as the TV mode, subconnectors, saturation, hue and so on.
It's created by calling the drm_mode_create_tv_properties() function.

The second one is there to deal with properties that might be useful on a
TV, creating the overscan margins for example. It's created by calling the
drm_mode_create_tv_margin_properties().

However, we also have a drm_atomic_helper_connector_tv_reset() function
that will reset the TV margin properties to their default values, and thus
is supposed to be called for the latter set. This creates an ambiguity due
to the inconsistent naming.

We can thus rename the drm_atomic_helper_connector_tv_reset() function to
drm_atomic_helper_connector_tv_margins_reset() to remove that ambiguity
and hopefully make it more obvious.

Signed-off-by: Maxime Ripard 

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index bf31b9d92094..dfb57217253b 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -464,12 +464,12 @@ void drm_atomic_helper_connector_reset(struct 
drm_connector *connector)
 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
 
 /**
- * drm_atomic_helper_connector_tv_reset - Resets TV connector properties
+ * drm_atomic_helper_connector_tv_margins_reset - Resets TV connector 
properties
  * @connector: DRM connector
  *
  * Resets the TV-related properties attached to a connector.
  */
-void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
+void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector 
*connector)
 {
struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
struct drm_connector_state *state = connector->state;
@@ -479,7 +479,7 @@ void drm_atomic_helper_connector_tv_reset(struct 
drm_connector *connector)
state->tv.margins.top = cmdline->tv_margins.top;
state->tv.margins.bottom = cmdline->tv_margins.bottom;
 }
-EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
 
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
diff --git a/drivers/gpu/drm/gud/gud_connector.c 
b/drivers/gpu/drm/gud/gud_connector.c
index d0addd478815..fa636206f232 100644
--- a/drivers/gpu/drm/gud/gud_connector.c
+++ b/drivers/gpu/drm/gud/gud_connector.c
@@ -355,7 +355,7 @@ static void gud_connector_reset(struct drm_connector 
*connector)
drm_atomic_helper_connector_reset(connector);
connector->state->tv = gconn->initial_tv_state;
/* Set margins from command line */
-   drm_atomic_helper_connector_tv_reset(connector);
+   drm_atomic_helper_connector_tv_margins_reset(connector);
if (gconn->initial_brightness >= 0)
connector->state->tv.brightness = gconn->initial_brightness;
 }
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 719a3c3b4ef6..66e38760d5aa 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -397,7 +397,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector 
*connector)
new_state->base.max_bpc = 8;
new_state->base.max_requested_bpc = 8;
new_state->output_format = VC4_HDMI_OUTPUT_RGB;
-   drm_atomic_helper_connector_tv_reset(connector);
+   drm_atomic_helper_connector_tv_margins_reset(connector);
 }
 
 static struct drm_connector_state *
diff --git a/include/drm/drm_atomic_state_helper.h 
b/include/drm/drm_atomic_state_helper.h
index 3f8f1d627f7c..192766656b88 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -70,7 +70,7 @@ void __drm_atomic_helper_connector_state_reset(struct 
drm_connector_state *conn_
 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_tv_reset(struct drm_connector *connector);
+void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector 
*connector);
 void
 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
   struct drm_connector_state *state);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 2c6fa746efac..f185ad862cb1 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -671,7 +671,7 @@ struct drm_connector_tv_margins {
 
 /**
  * struct drm_tv_connector_state - TV connector related states
- * @subconnector: selected subconnector
+ * @select_subconnector: selected subconnector
  * @margins: TV margins
  * @mode: TV mode
  * @brightness: brightness in percent

-- 
b4 0.10.0-dev-49460


[PATCH v1 00/35] drm: Analog TV Improvements

2022-07-29 Thread Maxime Ripard
Hi,

Here's a series aiming at improving the command line named modes support,
and more importantly how we deal with all the analog TV variants.

The named modes support were initially introduced to allow to specify the
analog TV mode to be used.

However, this was causing multiple issues:

  * The mode name parsed on the command line was passed directly to the
driver, which had to figure out which mode it was suppose to match;

  * Figuring that out wasn't really easy, since the video= argument or what
the userspace might not even have a name in the first place, but
instead could have passed a mode with the same timings;

  * The fallback to matching on the timings was mostly working as long as
we were supporting one 525 lines (most likely NSTC) and one 625 lines
(PAL), but couldn't differentiate between two modes with the same
timings (NTSC vs PAL-M vs NSTC-J for example); 

  * There was also some overlap with the tv mode property registered by 
drm_mode_create_tv_properties(), but named modes weren't interacting
with that property at all.

  * Even though that property was generic, its possible values were
specific to each drivers, which made some generic support difficult.

Thus, I chose to tackle in multiple steps:

  * A new TV norm property was introduced, with generic values, each driver
reporting through a bitmask what standard it supports to the userspace;

  * This option was added to the command line parsing code to be able to
specify it on the kernel command line, and new atomic_check and reset
helpers were created to integrate properly into atomic KMS;

  * The named mode parsing code is now creating a proper display mode for
the given named mode, and the TV standard will thus be part of the
connector state;

  * Two drivers were converted and tested for now (vc4 and sun4i), with
some backward compatibility code to translate the old TV mode to the
new TV mode;

Unit tests were created along the way. Nouveau, ch7006 and gud are
currently broken for now since I expect that work to be reworked fairly
significantly. I'm also not entirely sure about how to migrate GUD to the
new property.

Let me know what you think,
Maxime

Cc: Geert Uytterhoeven 
Cc: "Noralf Trønnes" 
Cc: Dave Stevenson 
Cc: Dom Cobley 
Cc: Phil Elwell 
Cc: Maarten Lankhorst 
Cc: Thomas Zimmermann 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: 
Signed-off-by: Maxime Ripard 

---
Mateusz Kwiatkowski (5):
  drm/vc4: vec: Refactor VEC TV mode setting
  drm/vc4: vec: Remove redundant atomic_mode_set
  drm/vc4: vec: Fix timings for VEC modes
  drm/vc4: vec: Fix definition of PAL-M mode
  drm/vc4: vec: Add support for more analog TV standards

Maxime Ripard (30):
  drm/atomic-helper: Rename drm_atomic_helper_connector_tv_reset to avoid 
ambiguity
  drm/connector: Rename subconnector state variable
  drm/atomic: Add TV subconnector property to get/set_property
  drm/modes: Introduce 480i and 576i modes
  drm/connector: Add TV standard property
  drm/connector: Only register TV mode property if present
  drm/modes: Only consider bpp and refresh before options
  drm/client: Add some tests for drm_connector_pick_cmdline_mode()
  drm/modes: Move named modes parsing to a separate function
  drm/modes: Switch to named mode descriptors
  drm/modes: Fill drm_cmdline mode from named modes
  drmi/modes: Properly generate a drm_display_mode from a named mode
  drm/atomic-helper: Add a TV properties reset helper
  drm/atomic-helper: Add an analog TV atomic_check implementation
  drm/vc4: vec: Remove empty mode_fixup
  drm/vc4: vec: Convert to atomic helpers
  drm/vc4: vec: Switch for common modes
  drm/vc4: vec: Use TV Reset implementation
  drm/vc4: vec: Convert to the new TV mode property
  drm/sun4i: tv: Remove unused mode_valid
  drm/sun4i: tv: Convert to atomic hooks
  drm/sun4i: tv: Merge mode_set into atomic_enable
  drm/sun4i: tv: Remove useless function
  drm/sun4i: tv: Remove useless destroy function
  drm/sun4i: tv: Rename error label
  drm/sun4i: tv: Add missing reset assertion
  drm/sun4i: tv: Convert to the new TV mode property
  drm/connector: Remove TV modes property
  drm/modes: Introduce the tv_mode property as a command-line option
  drm/modes: Introduce more named modes

 drivers/gpu/drm/drm_atomic_state_helper.c   | 166 +-
 drivers/gpu/drm/drm_atomic_uapi.c   |  12 +-
 drivers/gpu/drm/drm_client_modeset.c|   4 +
 drivers/gpu/drm/drm_connector.c |  46 ++-
 drivers/gpu/drm/drm_modes.c | 198 +--
 drivers/gpu/drm/gud/gud_connector.c |   2 +-
 drivers/gpu/drm/meson/meson_encoder_cvbs.c  |  18 +-
 drivers/gpu/drm/meson/meson_encoder_cvbs.h  |   2 +-
 drivers/gpu/drm/sun4i/sun4i_tv.c| 173 +++---
 drivers/gpu/drm/tests/d

[PATCH 1/2] drm/i915: Change semantics of context isolation reporting to UM

2022-07-29 Thread Adrian Larumbe
I915_PARAM_HAS_CONTEXT_ISOLATION was already being used as a boolean by
both Iris and Vulkan , and stood for the guarantee that, when creating a
new context, it would not contain register state from preexisting ones.

However, the actual param ioctl was returning a bitmask for the
engines in which isolation is supported, and IGT gem_ctx_isolation was
exploiting this wrong semantics when making decisions about which
engines support it.

This is a uAPI documentation change that precedes the actual change in
the getparam ioctl.

Signed-off-by: Adrian Larumbe 
---
 include/uapi/drm/i915_drm.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 094f6e377793..09adb7ea01d1 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -692,10 +692,6 @@ typedef struct drm_i915_irq_wait {
  * supports) that all state set by this context will not leak to any other
  * context.
  *
- * As not every engine across every gen support contexts, the returned
- * value reports the support of context isolation for individual engines by
- * returning a bitmask of each engine class set to true if that class supports
- * isolation.
  */
 #define I915_PARAM_HAS_CONTEXT_ISOLATION 50
 
-- 
2.37.0



[PATCH 0/2] Context isolation uAPI fixes

2022-07-29 Thread Adrian Larumbe
This patch series addresses the concerns in
https://gitlab.freedesktop.org/drm/intel/-/issues/4264

Parallel work has be done on IGT to test changes in the kernel driver:
https://lists.freedesktop.org/archives/igt-dev/2022-May/041600.html

Test-with: 20220516205000.2960491-1-adrian.laru...@collabora.com

Adrian Larumbe (2):
  drm/i915: Change semantics of context isolation reporting to UM
  drm/i915: force getparam ioctl return bool for HAS_CONTEXT_ISOLATION

 drivers/gpu/drm/i915/gt/intel_engine_user.c | 14 ++
 drivers/gpu/drm/i915/gt/intel_engine_user.h |  1 +
 drivers/gpu/drm/i915/i915_getparam.c|  2 +-
 include/uapi/drm/i915_drm.h |  4 
 4 files changed, 16 insertions(+), 5 deletions(-)

-- 
2.37.0



[PATCH 2/2] drm/i915: force getparam ioctl return bool for HAS_CONTEXT_ISOLATION

2022-07-29 Thread Adrian Larumbe
In a previous commit, the uAPI documentation for this param was updated
to reflect the actual usage expected by Iris. Now make sure the driver
does indeed return a boolean value rather than an engine bitmask.

Signed-off-by: Adrian Larumbe 
---
 drivers/gpu/drm/i915/gt/intel_engine_user.c | 14 ++
 drivers/gpu/drm/i915/gt/intel_engine_user.h |  1 +
 drivers/gpu/drm/i915/i915_getparam.c|  2 +-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index 46a174f8aa00..7bdee1c9d940 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -306,3 +306,17 @@ unsigned int intel_engines_has_context_isolation(struct 
drm_i915_private *i915)
 
return which;
 }
+
+bool engines_context_isolated(struct drm_i915_private *i915)
+{
+   struct intel_engine_cs *engine;
+
+   if (!DRIVER_CAPS(i915)->has_logical_contexts)
+   return false;
+
+   for_each_uabi_engine(engine, i915)
+   if (!engine->default_state)
+   return false;
+
+   return true;
+}
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.h 
b/drivers/gpu/drm/i915/gt/intel_engine_user.h
index 3dc7e8ab9fbc..760167db07d5 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.h
@@ -15,6 +15,7 @@ struct intel_engine_cs *
 intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);
 
 unsigned int intel_engines_has_context_isolation(struct drm_i915_private 
*i915);
+bool engines_context_isolated(struct drm_i915_private *i915);
 
 void intel_engine_add_user(struct intel_engine_cs *engine);
 void intel_engines_driver_register(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
b/drivers/gpu/drm/i915/i915_getparam.c
index 6fd15b39570c..dd31cc00c529 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -145,7 +145,7 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
value = 1;
break;
case I915_PARAM_HAS_CONTEXT_ISOLATION:
-   value = intel_engines_has_context_isolation(i915);
+   value = engines_context_isolated(i915);
break;
case I915_PARAM_SLICE_MASK:
/* Not supported from Xe_HP onward; use topology queries */
-- 
2.37.0



Re: [PATCH v6 1/2] drm/panfrost: Add specific register offset macros for JS and MMU AS

2022-07-29 Thread Alyssa Rosenzweig
Reviewed-by: Alyssa Rosenzweig 

On Fri, Jul 29, 2022 at 03:46:09PM +0100, Adri??n Larumbe wrote:
> Each Panfrost job has its own job slot and MMU address space set of
> registers, which are selected with a job-specific index.
> 
> Turn the shift and stride used for selection of the right register set base
> into a define rather than using magic numbers.
> 
> Signed-off-by: Adri??n Larumbe 
> ---
>  drivers/gpu/drm/panfrost/panfrost_regs.h | 42 ++--
>  1 file changed, 24 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
> b/drivers/gpu/drm/panfrost/panfrost_regs.h
> index accb4fa3adb8..919f44ac853d 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_regs.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
> @@ -226,23 +226,25 @@
>  #define JOB_INT_MASK_DONE(j) BIT(j)
>  
>  #define JS_BASE  0x1800
> -#define JS_HEAD_LO(n)(JS_BASE + ((n) * 0x80) + 0x00)
> -#define JS_HEAD_HI(n)(JS_BASE + ((n) * 0x80) + 0x04)
> -#define JS_TAIL_LO(n)(JS_BASE + ((n) * 0x80) + 0x08)
> -#define JS_TAIL_HI(n)(JS_BASE + ((n) * 0x80) + 0x0c)
> -#define JS_AFFINITY_LO(n)(JS_BASE + ((n) * 0x80) + 0x10)
> -#define JS_AFFINITY_HI(n)(JS_BASE + ((n) * 0x80) + 0x14)
> -#define JS_CONFIG(n) (JS_BASE + ((n) * 0x80) + 0x18)
> -#define JS_XAFFINITY(n)  (JS_BASE + ((n) * 0x80) + 0x1c)
> -#define JS_COMMAND(n)(JS_BASE + ((n) * 0x80) + 0x20)
> -#define JS_STATUS(n) (JS_BASE + ((n) * 0x80) + 0x24)
> -#define JS_HEAD_NEXT_LO(n)   (JS_BASE + ((n) * 0x80) + 0x40)
> -#define JS_HEAD_NEXT_HI(n)   (JS_BASE + ((n) * 0x80) + 0x44)
> -#define JS_AFFINITY_NEXT_LO(n)   (JS_BASE + ((n) * 0x80) + 0x50)
> -#define JS_AFFINITY_NEXT_HI(n)   (JS_BASE + ((n) * 0x80) + 0x54)
> -#define JS_CONFIG_NEXT(n)(JS_BASE + ((n) * 0x80) + 0x58)
> -#define JS_COMMAND_NEXT(n)   (JS_BASE + ((n) * 0x80) + 0x60)
> -#define JS_FLUSH_ID_NEXT(n)  (JS_BASE + ((n) * 0x80) + 0x70)
> +#define JS_SLOT_STRIDE   0x80
> +
> +#define JS_HEAD_LO(n)(JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x00)
> +#define JS_HEAD_HI(n)(JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x04)
> +#define JS_TAIL_LO(n)(JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x08)
> +#define JS_TAIL_HI(n)(JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x0c)
> +#define JS_AFFINITY_LO(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x10)
> +#define JS_AFFINITY_HI(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x14)
> +#define JS_CONFIG(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x18)
> +#define JS_XAFFINITY(n)  (JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x1c)
> +#define JS_COMMAND(n)(JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x20)
> +#define JS_STATUS(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x24)
> +#define JS_HEAD_NEXT_LO(n)   (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x40)
> +#define JS_HEAD_NEXT_HI(n)   (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x44)
> +#define JS_AFFINITY_NEXT_LO(n)   (JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x50)
> +#define JS_AFFINITY_NEXT_HI(n)   (JS_BASE + ((n) * 
> JS_SLOT_STRIDE) + 0x54)
> +#define JS_CONFIG_NEXT(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x58)
> +#define JS_COMMAND_NEXT(n)   (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x60)
> +#define JS_FLUSH_ID_NEXT(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
> 0x70)
>  
>  /* Possible values of JS_CONFIG and JS_CONFIG_NEXT registers */
>  #define JS_CONFIG_START_FLUSH_CLEAN  BIT(8)
> @@ -281,7 +283,9 @@
>  #define AS_COMMAND_FLUSH_MEM 0x05/* Wait for memory accesses to 
> complete, flush all the L1s cache then
>  flush all L2 caches then 
> issue a flush region command to all MMUs */
>  
> -#define MMU_AS(as)   (0x2400 + ((as) << 6))
> +#define MMU_BASE 0x2400
> +#define MMU_AS_SHIFT 0x06
> +#define MMU_AS(as)   (MMU_BASE + ((as) << MMU_AS_SHIFT))
>  
>  #define AS_TRANSTAB_LO(as)   (MMU_AS(as) + 0x00) /* (RW) Translation 
> Table Base Address for address space n, low word */
>  #define AS_TRANSTAB_HI(as)   (MMU_AS(as) + 0x04) /* (RW) Translation 
> Table Base Address for address space n, high word */
> @@ -300,6 +304,8 @@
>  #define AS_FAULTEXTRA_LO(as) (MMU_AS(as) + 0x38) /* (RO) Secondary 
> fault address for address space n, low word */
>  #define AS_FAULTEXTRA_HI(as) (MMU_AS(as) + 0x3C) /* (RO) Secondary 
> fault address for address space n, high word */
>  
> +#define MMU_AS_STRIDE(1 << MMU_

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

2022-07-29 Thread Rob Clark
On Tue, Jul 26, 2022 at 11:17 AM Tomeu Vizoso
 wrote:
>
> And use it to store expectations about what the DRM drivers are
> supposed to pass in the IGT test suite.
>
> Also include a configuration file that points to the out-of-tree CI
> scripts.
>
> By storing the test expectations along the code we can make sure both
> stay in sync with each other, and so we can know when a code change
> breaks those expectations.
>
> This will allow all contributors to drm to reuse the infrastructure
> already in gitlab.freedesktop.org to test the driver on several
> generations of the hardware.
>
> v2:
>   - Fix names of result expectation files to match SoC
>   - Don't execute tests that are going to skip on all boards
>
> v3:
>   - Remove tracking of dmesg output during test execution
>
> v4:
>   - Move up to drivers/gpu/drm
>   - Add support for a bunch of other drivers
>   - Explain how to incorporate fixes for CI from a
> ${TARGET_BRANCH}-external-fixes branch
>   - Remove tests that pass from expected results file, to reduce the
> size of in-tree files
>   - Add docs about how to deal with outages in automated testing labs
>   - Specify the exact SHA of the CI scripts to be used
>
> v5:
>   - Remove unneeded skips from Meson expectations file
>   - Use a more advanced runner that detects flakes automatically
>   - Use a more succint format for the expectations
>   - Run many more tests (and use sharding to finish in time)
>   - Use skip lists to avoid hanging machines
>   - Add some build testing
>   - Build IGT in each pipeline for faster uprevs
>   - List failures in the GitLab UI
>
> Signed-off-by: Tomeu Vizoso 
> Reviewed-by: Neil Armstrong 

This looks good to me

Reviewed-by: Rob Clark 


> ---
>  Documentation/gpu/automated_testing.rst   | 84 ++
>  drivers/gpu/drm/ci/amdgpu-stoney-fails.txt| 13 +++
>  drivers/gpu/drm/ci/amdgpu-stoney-flakes.txt   | 20 +
>  drivers/gpu/drm/ci/amdgpu-stoney-skips.txt|  2 +
>  drivers/gpu/drm/ci/gitlab-ci.yml  | 13 +++
>  drivers/gpu/drm/ci/i915-amly-flakes.txt   | 32 +++
>  drivers/gpu/drm/ci/i915-amly-skips.txt|  2 +
>  drivers/gpu/drm/ci/i915-apl-fails.txt | 29 +++
>  drivers/gpu/drm/ci/i915-apl-flakes.txt|  1 +
>  drivers/gpu/drm/ci/i915-apl-skips.txt |  2 +
>  drivers/gpu/drm/ci/i915-cml-flakes.txt| 36 
>  drivers/gpu/drm/ci/i915-glk-flakes.txt| 40 +
>  drivers/gpu/drm/ci/i915-glk-skips.txt |  2 +
>  drivers/gpu/drm/ci/i915-kbl-fails.txt |  8 ++
>  drivers/gpu/drm/ci/i915-kbl-flakes.txt| 24 ++
>  drivers/gpu/drm/ci/i915-kbl-skips.txt |  2 +
>  drivers/gpu/drm/ci/i915-tgl-fails.txt | 19 
>  drivers/gpu/drm/ci/i915-tgl-flakes.txt|  6 ++
>  drivers/gpu/drm/ci/i915-tgl-skips.txt |  8 ++
>  drivers/gpu/drm/ci/i915-whl-fails.txt | 30 +++
>  drivers/gpu/drm/ci/i915-whl-flakes.txt|  1 +
>  drivers/gpu/drm/ci/mediatek-mt8173-fails.txt  | 29 +++
>  drivers/gpu/drm/ci/mediatek-mt8183-fails.txt  | 10 +++
>  drivers/gpu/drm/ci/mediatek-mt8183-flakes.txt | 14 +++
>  drivers/gpu/drm/ci/meson-g12b-fails.txt   |  5 ++
>  drivers/gpu/drm/ci/meson-g12b-flakes.txt  |  4 +
>  drivers/gpu/drm/ci/msm-apq8016-fails.txt  | 15 
>  drivers/gpu/drm/ci/msm-apq8016-flakes.txt |  4 +
>  drivers/gpu/drm/ci/msm-apq8096-fails.txt  |  2 +
>  drivers/gpu/drm/ci/msm-apq8096-flakes.txt |  4 +
>  drivers/gpu/drm/ci/msm-apq8096-skips.txt  |  2 +
>  drivers/gpu/drm/ci/msm-sc7180-fails.txt   | 22 +
>  drivers/gpu/drm/ci/msm-sc7180-flakes.txt  | 14 +++
>  drivers/gpu/drm/ci/msm-sc7180-skips.txt   | 18 
>  drivers/gpu/drm/ci/msm-sdm845-fails.txt   | 44 ++
>  drivers/gpu/drm/ci/msm-sdm845-flakes.txt  | 33 +++
>  drivers/gpu/drm/ci/msm-sdm845-skips.txt   |  2 +
>  drivers/gpu/drm/ci/rockchip-rk3288-fails.txt  | 75 
>  drivers/gpu/drm/ci/rockchip-rk3288-flakes.txt |  5 ++
>  drivers/gpu/drm/ci/rockchip-rk3288-skips.txt  | 46 ++
>  drivers/gpu/drm/ci/rockchip-rk3399-fails.txt  | 86 +++
>  drivers/gpu/drm/ci/rockchip-rk3399-flakes.txt | 25 ++
>  drivers/gpu/drm/ci/rockchip-rk3399-skips.txt  |  5 ++
>  drivers/gpu/drm/ci/virtio_gpu-none-fails.txt  | 38 
>  drivers/gpu/drm/ci/virtio_gpu-none-flakes.txt |  0
>  drivers/gpu/drm/ci/virtio_gpu-none-skips.txt  |  6 ++
>  46 files changed, 882 insertions(+)
>  create mode 100644 Documentation/gpu/automated_testing.rst
>  create mode 100644 drivers/gpu/drm/ci/amdgpu-stoney-fails.txt
>  create mode 100644 drivers/gpu/drm/ci/amdgpu-stoney-flakes.txt
>  create mode 100644 drivers/gpu/drm/ci/amdgpu-stoney-skips.txt
>  create mode 100644 drivers/gpu/drm/ci/gitlab-ci.yml
>  create mode 100644 drivers/gpu/drm/ci/i915-amly-flakes.txt
>  create mode 100644 drivers/gpu/drm/ci/i915-amly-skips.txt
>  create mode 100644 drivers/gpu/drm/ci/i915-apl-fails

Re: [PATCH v3 09/15] drm/gem: Add LRU/shrinker helper

2022-07-29 Thread Rob Clark
On Fri, Jul 29, 2022 at 8:27 AM Dmitry Osipenko
 wrote:
>
> On 7/26/22 20:50, Rob Clark wrote:
> > +/**
> > + * drm_gem_lru_move_tail_locked - move the object to the tail of the LRU
> > + *
> > + * If the object is already in this LRU it will be moved to the
> > + * tail.  Otherwise it will be removed from whichever other LRU
> > + * it is in (if any) and moved into this LRU.
> > + *
> > + * Call with LRU lock held.
> > + *
> > + * @lru: The LRU to move the object into.
> > + * @obj: The GEM object to move into this LRU
> > + */
> > +void
> > +drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct 
> > drm_gem_object *obj)
> > +{
> > + lockdep_assert_held_once(lru->lock);
> > +
> > + if (obj->lru)
> > + lru_remove(obj);
>
> The obj->lru also needs to be locked if lru != obj->lru, isn't it? And
> then we should add lockdep_assert_held_once(obj->lru->lock).
>

It is expected (mentioned in comment on drm_gem_lru::lock) that all
lru's are sharing the same lock.  Possibly that could be made more
obvious?  Having per-lru locks wouldn't really work for accessing the
single drm_gem_object::lru_node.

BR,
-R


Re: [PATCH v3 09/15] drm/gem: Add LRU/shrinker helper

2022-07-29 Thread Dmitry Osipenko
On 7/26/22 20:50, Rob Clark wrote:
> +/**
> + * drm_gem_lru_move_tail_locked - move the object to the tail of the LRU
> + *
> + * If the object is already in this LRU it will be moved to the
> + * tail.  Otherwise it will be removed from whichever other LRU
> + * it is in (if any) and moved into this LRU.
> + *
> + * Call with LRU lock held.
> + *
> + * @lru: The LRU to move the object into.
> + * @obj: The GEM object to move into this LRU
> + */
> +void
> +drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct drm_gem_object 
> *obj)
> +{
> + lockdep_assert_held_once(lru->lock);
> +
> + if (obj->lru)
> + lru_remove(obj);

The obj->lru also needs to be locked if lru != obj->lru, isn't it? And
then we should add lockdep_assert_held_once(obj->lru->lock).

-- 
Best regards,
Dmitry


Re: [RFC PATCH] drm/edid: Make 144 Hz not preferred on Sharp LQ140M1JW46

2022-07-29 Thread Doug Anderson
Hi,

On Fri, Jul 29, 2022 at 12:51 AM Maxime Ripard  wrote:
>
> On Thu, Jul 28, 2022 at 02:18:38PM -0700, Doug Anderson wrote:
> > Hi,
> >
> > On Thu, Jul 28, 2022 at 10:34 AM Abhinav Kumar
> >  wrote:
> > >
> > > Hi Rob and Doug
> > >
> > > On 7/22/2022 10:36 AM, Rob Clark wrote:
> > > > On Fri, Jul 22, 2022 at 9:48 AM Doug Anderson  
> > > > wrote:
> > > >>
> > > >> Hi,
> > > >>
> > > >> On Fri, Jul 22, 2022 at 9:37 AM Abhinav Kumar 
> > > >>  wrote:
> > > >>>
> > > >>> + sankeerth
> > > >>>
> > > >>> Hi Doug
> > > >>>
> > > >>> On 7/21/2022 3:23 PM, Douglas Anderson wrote:
> > >  The Sharp LQ140M1JW46 panel is on the Qualcomm sc7280 CRD reference
> > >  board. This panel supports 144 Hz and 60 Hz. In the EDID, the 144 Hz
> > >  mode is listed first and thus is marked preferred. The EDID decode I
> > >  ran says:
> > > 
> > >  First detailed timing includes the native pixel format and 
> > >  preferred
> > >  refresh rate.
> > > 
> > >  ...
> > > 
> > >  Detailed Timing Descriptors:
> > >    DTD 1:  1920x1080  143.981 Hz  16:9   166.587 kHz  346.500 MHz
> > > Hfront   48 Hsync  32 Hback  80 Hpol N
> > > Vfront3 Vsync   5 Vback  69 Vpol N
> > >    DTD 2:  1920x1080   59.990 Hz  16:969.409 kHz  144.370 MHz
> > > Hfront   48 Hsync  32 Hback  80 Hpol N
> > > Vfront3 Vsync   5 Vback  69 Vpol N
> > > 
> > >  I'm proposing here that the above is actually a bug and that the 60 
> > >  Hz
> > >  mode really should be considered preferred by Linux.
> > >
> > > Its a bit tricky to say that this is a bug but I think we can certainly
> > > add here that for an internal display we would have ideally had the
> > > lower resolution first to indicate it as default.
> >
> > Yeah, it gets into the vagueness of the EDID spec in general. As far
> > as I can find it's really up to the monitor to decide by what means it
> > chooses the "preferred" refresh rate if the monitor can support many.
> > Some displays may decide that the normal rate is "preferred" and some
> > may decide that the high refresh rate is "preferred". Neither display
> > is "wrong" per say, but it's nice to have some consistency here and to
> > make it so that otherwise "dumb" userspace will get something
> > reasonable by default. I'll change it to say:
> >
> > While the EDID spec appears to allow a display to use any criteria for
> > picking which refresh mode is "preferred" or "optimal", that vagueness
> > is a bit annoying. From Linux's point of view let's choose the 60 Hz
> > one as the default.
>
> And if we start making that decision, it should be for all panels with a
> similar constraint, so most likely handled by the core, and the new
> policy properly documented.
>
> Doing that just for a single panel is weird.

Yeah, though having a "general policy" in the core can be problematic.

In general I think panel EDIDs are only trustworthy as far as you can
throw them. They are notorious for having wrong and incorrect
information, which is why the EDID quirk list exists to begin with.
Trying to change how we're going to interpret all EDIDs, even all
EDIDs for eDP panels, seems like it will break someone somewhere.
Maybe there are EDIDs out there that were only ever validated at the
higher refresh rate and they don't work / flicker / cause digitizer
noise at the lower refresh rate. Heck, we've seen eDP panel vendors
that can't even get their checksum correct, so I'm not sure I want to
make a global assertion that all panels validated their "secondary"
display mode.

In this particular case, we have validated that this particular Sharp
panel works fine at the lower refresh rate.

I would also note that, as far as I understand it, ODMs actually can
request different EDIDs from the panel vendors. In the past we have
been able to get panel vendors to change EDIDs. Thus for most panels
I'd expect that we would discover this early, change the EDID default,
and be done with it. The case here is a little unusual in that by the
time we got involved and started digging into this panel too many were
created and nobody wants to throw away those old panels. This is why
I'm treating it as a quirk/bug. Really: we should have updated the
EDID of the panel but we're unable to in this case.

-Doug


[PATCH v6 1/2] drm/panfrost: Add specific register offset macros for JS and MMU AS

2022-07-29 Thread Adrián Larumbe
Each Panfrost job has its own job slot and MMU address space set of
registers, which are selected with a job-specific index.

Turn the shift and stride used for selection of the right register set base
into a define rather than using magic numbers.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/panfrost/panfrost_regs.h | 42 ++--
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
b/drivers/gpu/drm/panfrost/panfrost_regs.h
index accb4fa3adb8..919f44ac853d 100644
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h
+++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
@@ -226,23 +226,25 @@
 #define JOB_INT_MASK_DONE(j)   BIT(j)
 
 #define JS_BASE0x1800
-#define JS_HEAD_LO(n)  (JS_BASE + ((n) * 0x80) + 0x00)
-#define JS_HEAD_HI(n)  (JS_BASE + ((n) * 0x80) + 0x04)
-#define JS_TAIL_LO(n)  (JS_BASE + ((n) * 0x80) + 0x08)
-#define JS_TAIL_HI(n)  (JS_BASE + ((n) * 0x80) + 0x0c)
-#define JS_AFFINITY_LO(n)  (JS_BASE + ((n) * 0x80) + 0x10)
-#define JS_AFFINITY_HI(n)  (JS_BASE + ((n) * 0x80) + 0x14)
-#define JS_CONFIG(n)   (JS_BASE + ((n) * 0x80) + 0x18)
-#define JS_XAFFINITY(n)(JS_BASE + ((n) * 0x80) + 0x1c)
-#define JS_COMMAND(n)  (JS_BASE + ((n) * 0x80) + 0x20)
-#define JS_STATUS(n)   (JS_BASE + ((n) * 0x80) + 0x24)
-#define JS_HEAD_NEXT_LO(n) (JS_BASE + ((n) * 0x80) + 0x40)
-#define JS_HEAD_NEXT_HI(n) (JS_BASE + ((n) * 0x80) + 0x44)
-#define JS_AFFINITY_NEXT_LO(n) (JS_BASE + ((n) * 0x80) + 0x50)
-#define JS_AFFINITY_NEXT_HI(n) (JS_BASE + ((n) * 0x80) + 0x54)
-#define JS_CONFIG_NEXT(n)  (JS_BASE + ((n) * 0x80) + 0x58)
-#define JS_COMMAND_NEXT(n) (JS_BASE + ((n) * 0x80) + 0x60)
-#define JS_FLUSH_ID_NEXT(n)(JS_BASE + ((n) * 0x80) + 0x70)
+#define JS_SLOT_STRIDE 0x80
+
+#define JS_HEAD_LO(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x00)
+#define JS_HEAD_HI(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x04)
+#define JS_TAIL_LO(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x08)
+#define JS_TAIL_HI(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x0c)
+#define JS_AFFINITY_LO(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x10)
+#define JS_AFFINITY_HI(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x14)
+#define JS_CONFIG(n)   (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x18)
+#define JS_XAFFINITY(n)(JS_BASE + ((n) * 
JS_SLOT_STRIDE) + 0x1c)
+#define JS_COMMAND(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x20)
+#define JS_STATUS(n)   (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x24)
+#define JS_HEAD_NEXT_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x40)
+#define JS_HEAD_NEXT_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x44)
+#define JS_AFFINITY_NEXT_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x50)
+#define JS_AFFINITY_NEXT_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x54)
+#define JS_CONFIG_NEXT(n)  (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x58)
+#define JS_COMMAND_NEXT(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x60)
+#define JS_FLUSH_ID_NEXT(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + 
0x70)
 
 /* Possible values of JS_CONFIG and JS_CONFIG_NEXT registers */
 #define JS_CONFIG_START_FLUSH_CLEANBIT(8)
@@ -281,7 +283,9 @@
 #define AS_COMMAND_FLUSH_MEM   0x05/* Wait for memory accesses to 
complete, flush all the L1s cache then
   flush all L2 caches then 
issue a flush region command to all MMUs */
 
-#define MMU_AS(as) (0x2400 + ((as) << 6))
+#define MMU_BASE   0x2400
+#define MMU_AS_SHIFT   0x06
+#define MMU_AS(as) (MMU_BASE + ((as) << MMU_AS_SHIFT))
 
 #define AS_TRANSTAB_LO(as) (MMU_AS(as) + 0x00) /* (RW) Translation 
Table Base Address for address space n, low word */
 #define AS_TRANSTAB_HI(as) (MMU_AS(as) + 0x04) /* (RW) Translation 
Table Base Address for address space n, high word */
@@ -300,6 +304,8 @@
 #define AS_FAULTEXTRA_LO(as)   (MMU_AS(as) + 0x38) /* (RO) Secondary 
fault address for address space n, low word */
 #define AS_FAULTEXTRA_HI(as)   (MMU_AS(as) + 0x3C) /* (RO) Secondary 
fault address for address space n, high word */
 
+#define MMU_AS_STRIDE  (1 << MMU_AS_SHIFT)
+
 /*
  * Begin LPAE MMU TRANSTAB register values
  */
-- 
2.37.0



[PATCH v6 0/2] devcoredump support for Panfrost GPU driver

2022-07-29 Thread Adrián Larumbe
This is v6 for a previous patch series being discussed at:

https://lore.kernel.org/dri-devel/20220718172418.584231-1-adrian.laru...@collabora.com/j

Mesa MR under review can be found at:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14034

Changes with respect to v5 of the same patch:

 - Expressed MMU_AS_STRIDE as a bitshift to avoid yet another magic number and
   removed misleading comment on the same line.

Adrián Larumbe (2):
  drm/panfrost: Add specific register offset macros for JS and MMU AS
  drm/panfrost: Add support for devcoredump

 drivers/gpu/drm/panfrost/Kconfig |   1 +
 drivers/gpu/drm/panfrost/Makefile|   3 +-
 drivers/gpu/drm/panfrost/panfrost_dump.c | 249 +++
 drivers/gpu/drm/panfrost/panfrost_dump.h |  12 ++
 drivers/gpu/drm/panfrost/panfrost_job.c  |   3 +
 drivers/gpu/drm/panfrost/panfrost_regs.h |  42 ++--
 include/uapi/drm/panfrost_drm.h  |  47 +
 7 files changed, 338 insertions(+), 19 deletions(-)
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_dump.c
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_dump.h

-- 
2.37.0



[PATCH v6 2/2] drm/panfrost: Add support for devcoredump

2022-07-29 Thread Adrián Larumbe
In the event of a job timeout, debug dump information will be written into
/sys/class/devcoredump.

Inspired by etnaviv's similar feature.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/panfrost/Kconfig |   1 +
 drivers/gpu/drm/panfrost/Makefile|   3 +-
 drivers/gpu/drm/panfrost/panfrost_dump.c | 249 +++
 drivers/gpu/drm/panfrost/panfrost_dump.h |  12 ++
 drivers/gpu/drm/panfrost/panfrost_job.c  |   3 +
 include/uapi/drm/panfrost_drm.h  |  47 +
 6 files changed, 314 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_dump.c
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_dump.h

diff --git a/drivers/gpu/drm/panfrost/Kconfig b/drivers/gpu/drm/panfrost/Kconfig
index 86cdc0ce79e6..079600328be1 100644
--- a/drivers/gpu/drm/panfrost/Kconfig
+++ b/drivers/gpu/drm/panfrost/Kconfig
@@ -11,6 +11,7 @@ config DRM_PANFROST
select DRM_GEM_SHMEM_HELPER
select PM_DEVFREQ
select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   select WANT_DEV_COREDUMP
help
  DRM driver for ARM Mali Midgard (T6xx, T7xx, T8xx) and
  Bifrost (G3x, G5x, G7x) GPUs.
diff --git a/drivers/gpu/drm/panfrost/Makefile 
b/drivers/gpu/drm/panfrost/Makefile
index b71935862417..7da2b3f02ed9 100644
--- a/drivers/gpu/drm/panfrost/Makefile
+++ b/drivers/gpu/drm/panfrost/Makefile
@@ -9,6 +9,7 @@ panfrost-y := \
panfrost_gpu.o \
panfrost_job.o \
panfrost_mmu.o \
-   panfrost_perfcnt.o
+   panfrost_perfcnt.o \
+   panfrost_dump.o
 
 obj-$(CONFIG_DRM_PANFROST) += panfrost.o
diff --git a/drivers/gpu/drm/panfrost/panfrost_dump.c 
b/drivers/gpu/drm/panfrost/panfrost_dump.c
new file mode 100644
index ..72458a6cc197
--- /dev/null
+++ b/drivers/gpu/drm/panfrost/panfrost_dump.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright 2021 Collabora ltd. */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "panfrost_job.h"
+#include "panfrost_gem.h"
+#include "panfrost_regs.h"
+#include "panfrost_dump.h"
+#include "panfrost_device.h"
+
+static bool panfrost_dump_core = true;
+module_param_named(dump_core, panfrost_dump_core, bool, 0600);
+
+struct panfrost_dump_iterator {
+   void *start;
+   struct panfrost_dump_object_header *hdr;
+   void *data;
+};
+
+static const unsigned short panfrost_dump_registers[] = {
+   SHADER_READY_LO,
+   SHADER_READY_HI,
+   TILER_READY_LO,
+   TILER_READY_HI,
+   L2_READY_LO,
+   L2_READY_HI,
+   JOB_INT_MASK,
+   JOB_INT_STAT,
+   JS_HEAD_LO(0),
+   JS_HEAD_HI(0),
+   JS_TAIL_LO(0),
+   JS_TAIL_HI(0),
+   JS_AFFINITY_LO(0),
+   JS_AFFINITY_HI(0),
+   JS_CONFIG(0),
+   JS_STATUS(0),
+   JS_HEAD_NEXT_LO(0),
+   JS_HEAD_NEXT_HI(0),
+   JS_AFFINITY_NEXT_LO(0),
+   JS_AFFINITY_NEXT_HI(0),
+   JS_CONFIG_NEXT(0),
+   MMU_INT_MASK,
+   MMU_INT_STAT,
+   AS_TRANSTAB_LO(0),
+   AS_TRANSTAB_HI(0),
+   AS_MEMATTR_LO(0),
+   AS_MEMATTR_HI(0),
+   AS_FAULTSTATUS(0),
+   AS_FAULTADDRESS_LO(0),
+   AS_FAULTADDRESS_HI(0),
+   AS_STATUS(0),
+};
+
+static void panfrost_core_dump_header(struct panfrost_dump_iterator *iter,
+   u32 type, void *data_end)
+{
+   struct panfrost_dump_object_header *hdr = iter->hdr;
+
+   hdr->magic = cpu_to_le32(PANFROSTDUMP_MAGIC);
+   hdr->type = cpu_to_le32(type);
+   hdr->file_offset = cpu_to_le32(iter->data - iter->start);
+   hdr->file_size = cpu_to_le32(data_end - iter->data);
+
+   iter->hdr++;
+   iter->data += le32_to_cpu(hdr->file_size);
+}
+
+static void
+panfrost_core_dump_registers(struct panfrost_dump_iterator *iter,
+struct panfrost_device *pfdev,
+u32 as_nr, int slot)
+{
+   struct panfrost_dump_registers *dumpreg = iter->data;
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(panfrost_dump_registers); i++, dumpreg++) {
+   unsigned int js_as_offset = 0;
+   unsigned int reg;
+
+   if (panfrost_dump_registers[i] >= JS_BASE &&
+   panfrost_dump_registers[i] <= JS_BASE + JS_SLOT_STRIDE)
+   js_as_offset = slot * JS_SLOT_STRIDE;
+   else if (panfrost_dump_registers[i] >= MMU_BASE &&
+panfrost_dump_registers[i] <= MMU_BASE + MMU_AS_STRIDE)
+   js_as_offset = (as_nr << MMU_AS_SHIFT);
+
+   reg = panfrost_dump_registers[i] + js_as_offset;
+
+   dumpreg->reg = cpu_to_le32(reg);
+   dumpreg->value = cpu_to_le32(gpu_read(pfdev, reg));
+   }
+
+   panfrost_core_dump_header(iter, PANFROSTDUMP_BUF_REG, dumpreg);
+}
+
+void panfrost_core_dump(struct panfrost_job *job)
+{
+   struct panfrost_device *pfdev = job->pfdev;
+   struct panfrost_dump_iterator iter;
+   struct drm_gem_object 

Re: [PATCH] drm/kmb: fix dereference before NULL check in kmb_plane_atomic_update()

2022-07-29 Thread Thomas Zimmermann

Hi

Am 29.07.22 um 16:23 schrieb Thomas Zimmermann:

Hi

Am 29.07.22 um 05:07 schrieb Zeng Jingxiang:

From: Zeng Jingxiang 

The "plane" pointer was access before checking if it was NULL.

The drm_atomic_get_old_plane_state() function will dereference
the pointer "plane".
345    struct drm_plane_state *old_plane_state =
    drm_atomic_get_old_plane_state(state, plane);
346    struct drm_plane_state *new_plane_state =
    drm_atomic_get_new_plane_state(state, plane);

A NULL check for "plane" indicates that it may be NULL
363    if (!plane || !new_plane_state || !old_plane_state)


Is this an actual bug that happens?

All planes should always have a state. Therefore the tests for 
!new_plane_state and !old_plane_state can be removed, I'd say.


Just to clarify: moving the test for !plane before using one of the 
get_plane_state functions is a correct bugfix.


Best regards
Thomas



Best regards
Thomas



Fixes: 977697e20b3d ("drm/atomic: Pass the full state to planes atomic 
disable and update")
Fixes: 37418bf14c13 ("drm: Use state helper instead of the plane state 
pointer")

Signed-off-by: Zeng Jingxiang 
---
  drivers/gpu/drm/kmb/kmb_plane.c | 13 -
  1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/kmb/kmb_plane.c 
b/drivers/gpu/drm/kmb/kmb_plane.c

index 2735b8eb3537..d2bc998b65ce 100644
--- a/drivers/gpu/drm/kmb/kmb_plane.c
+++ b/drivers/gpu/drm/kmb/kmb_plane.c
@@ -342,10 +342,7 @@ static void kmb_plane_set_alpha(struct 
kmb_drm_private *kmb,

  static void kmb_plane_atomic_update(struct drm_plane *plane,
  struct drm_atomic_state *state)
  {
-    struct drm_plane_state *old_plane_state = 
drm_atomic_get_old_plane_state(state,

- plane);
-    struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(state,

- plane);
+    struct drm_plane_state *old_plane_state, *new_plane_state;
  struct drm_framebuffer *fb;
  struct kmb_drm_private *kmb;
  unsigned int width;
@@ -360,7 +357,13 @@ static void kmb_plane_atomic_update(struct 
drm_plane *plane,

  static dma_addr_t addr[MAX_SUB_PLANES];
  struct disp_cfg *init_disp_cfg;
-    if (!plane || !new_plane_state || !old_plane_state)
+    if (!plane)
+    return;
+
+    old_plane_state = drm_atomic_get_old_plane_state(state, plane);
+    new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+
+    if (!new_plane_state || !old_plane_state)
  return;
  fb = new_plane_state->fb;




--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] drm/kmb: fix dereference before NULL check in kmb_plane_atomic_update()

2022-07-29 Thread Thomas Zimmermann

Hi

Am 29.07.22 um 05:07 schrieb Zeng Jingxiang:

From: Zeng Jingxiang 

The "plane" pointer was access before checking if it was NULL.

The drm_atomic_get_old_plane_state() function will dereference
the pointer "plane".
345 struct drm_plane_state *old_plane_state =
drm_atomic_get_old_plane_state(state, plane);
346 struct drm_plane_state *new_plane_state =
drm_atomic_get_new_plane_state(state, plane);

A NULL check for "plane" indicates that it may be NULL
363 if (!plane || !new_plane_state || !old_plane_state)


Is this an actual bug that happens?

All planes should always have a state. Therefore the tests for 
!new_plane_state and !old_plane_state can be removed, I'd say.


Best regards
Thomas



Fixes: 977697e20b3d ("drm/atomic: Pass the full state to planes atomic disable and 
update")
Fixes: 37418bf14c13 ("drm: Use state helper instead of the plane state pointer")
Signed-off-by: Zeng Jingxiang 
---
  drivers/gpu/drm/kmb/kmb_plane.c | 13 -
  1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/kmb/kmb_plane.c b/drivers/gpu/drm/kmb/kmb_plane.c
index 2735b8eb3537..d2bc998b65ce 100644
--- a/drivers/gpu/drm/kmb/kmb_plane.c
+++ b/drivers/gpu/drm/kmb/kmb_plane.c
@@ -342,10 +342,7 @@ static void kmb_plane_set_alpha(struct kmb_drm_private 
*kmb,
  static void kmb_plane_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
  {
-   struct drm_plane_state *old_plane_state = 
drm_atomic_get_old_plane_state(state,
-   
 plane);
-   struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(state,
-   
 plane);
+   struct drm_plane_state *old_plane_state, *new_plane_state;
struct drm_framebuffer *fb;
struct kmb_drm_private *kmb;
unsigned int width;
@@ -360,7 +357,13 @@ static void kmb_plane_atomic_update(struct drm_plane 
*plane,
static dma_addr_t addr[MAX_SUB_PLANES];
struct disp_cfg *init_disp_cfg;
  
-	if (!plane || !new_plane_state || !old_plane_state)

+   if (!plane)
+   return;
+
+   old_plane_state = drm_atomic_get_old_plane_state(state, plane);
+   new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+
+   if (!new_plane_state || !old_plane_state)
return;
  
  	fb = new_plane_state->fb;


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v16 0/3] eDP/DP Phy vdda realted function

2022-07-29 Thread Mark Brown
On Fri, Jul 29, 2022 at 03:35:33PM +0200, Johan Hovold wrote:

> I guess we just need to drop all those regulator-allow-set-load
> properties for now even if using DT for power-management configuration
> this way does seem to run against the whole DT-as-hardware-description
> idea (e.g. we may want to add them back when/if active- and idle loads
> are specified by the corresponding Linux drivers).

Well, there's also a question of if the hardware can usefully make use
of the facility - is there any non-suspend state where the regulator
needs to be on but is drawing so little current that it's worth trying
to select a lower power mode?

> But that doesn't address the problem that was trying to highlight here,
> and that you had noticed years ago, namely that using set_load only
> works reliably if *all* consumers use it.

> Shouldn't an enabled regulator from a consumer that didn't specify a
> load somehow result in HPM always being selected (e.g. count as INT_MAX
> load as Doug suggested some years ago)?

Possibly, but note that as well as the consumers with software drivers
you also have to consider any passive consumers on the board which may
not have any representation in DT so the actual numbers may well be off
even if every consumer is trying to keep things up to date.  You also
come back to the "let's just shove a random number in here" problem.

For ultimate saftey we probably want a command line option to gate the
feature which people can set to say they've audited their full
software/hardware integration stack.

> At some point in the discussion I thought Mark suggested removing
> set_load from drivers that don't actually manage active and idle loads.
> That would also work, at least until the day one of the drivers adds
> support for idle loads.

Yes, if the driver isn't actively managing loads it's probably not doing
anything useful.

The difficulties with this sort of system integration question is an
unfortunate consequence of DT, having to describe what's safe for an
unknown software stack is fundamentally hard.  I do question how much
effort it's worth putting into enabling this, especially in cases where
the regulator is shared - how much power is actually saved in the grand
scheme of things given that this is only taking effect when the system
is out of suspend and we tend to be talking about some percentage of the
power being drawn on something which is presumably already consuming
very little power for this to be at all relevant?


signature.asc
Description: PGP signature


Re: [PATCH v16 0/3] eDP/DP Phy vdda realted function

2022-07-29 Thread Johan Hovold
Sorry about the late follow-up on this. Has been one of those
constant-preemption weeks.

And thanks Doug and Mark for the insightful comments in this and the
dt-load RFC thread.

On Thu, Jul 21, 2022 at 07:49:55AM -0700, Doug Anderson wrote:
> Hi,
> 
> On Thu, Jul 21, 2022 at 6:25 AM Dmitry Baryshkov
>  wrote:
> >
> > > This series breaks USB and PCIe for some SC8280XP and SA540P machines
> > > where the DP PHY regulators are shared with other PHYs whose drivers do
> > > not request a load.
> >
> > I'm trying to understand, why does this series cause the regression.
> > Previously it would be the DP controller voting on the regulators
> > load, now it has been moved to the DP/eDP PHYs.
> 
> I think in the past not many device trees actually hooked up the
> regulators to the DP/eDP but did hook up the regulators to the PHYs?
> That means they didn't used to get a regulator_set_load() on them and
> now they do?

This was the case for us, but this could probably also partly be blamed
on the DP stuff being work-in-progress and the regulators were only ever
specified in the PHY nodes.

> It should also be noted that we're now setting the load for a bunch of
> USB PHYs that we didn't used to set a load on...

That was my concern. But after skimming the mainline dts it seems that
no users of these drivers are currently allowing the regulator mode to
be changed for those particular regulators.

Well, except for the sc8280xp (derivate) machines in -next that I'm
working on and that regressed of course.

I guess we just need to drop all those regulator-allow-set-load
properties for now even if using DT for power-management configuration
this way does seem to run against the whole DT-as-hardware-description
idea (e.g. we may want to add them back when/if active- and idle loads
are specified by the corresponding Linux drivers).

> > > It seems quite likely that changes like this one affects other systems
> > > too, and the effects may be hard to debug. So a more general solution
> > > than playing whack-a-mole using DT would be good to have.
> >
> > I think enabling a regulator which supports set_load() and without
> > load being set should cause a warning, at least with
> > CONFIG_REGULATOR_DEBUG. WDYT?
> 
> I'm not a total fan. I'd love to see evidence to the contrary, but I'm
> a believer that the amount of extra cruft involved with all these
> regulator_set_load() calls is overkill for most cases. All the extra
> code / per-SoC tables added to drivers isn't ideal.
> 
> Every single LDO on Qualcomm's PMICs seems to be able to be set in
> "high power mode" and "low power mode", but I think the majority of
> clients only really care about two things: on and in high power mode
> vs. off. I think the amount of stuff peripherals can do in low power
> mode is super limited, so you have to be _really_ sure that the
> peripheral won't draw too much current without you having a chance to
> reconfigure the regulator.
> 
> Of course, if the load could be easily specified in the device tree
> and we could get rid of all the cruft in the drivers then maybe that
> would be OK.

It seems a decision was made against this (which I tend to agree with),
and that instead it is now easier for drivers to specify loads using
your updated bulk-regulator implementation.

But that doesn't address the problem that was trying to highlight here,
and that you had noticed years ago, namely that using set_load only
works reliably if *all* consumers use it.

Otherwise we may end up with a couple of drivers adding some 10 mA each to
the load, while other driver do not specify a load so that while the
actual load is really above the 30 mA HPM threshold, we still end up in
LPM.

Shouldn't an enabled regulator from a consumer that didn't specify a
load somehow result in HPM always being selected (e.g. count as INT_MAX
load as Doug suggested some years ago)?

Note that LPM may be ok until that last consumer that didn't specify a
load pushes it over the HPM threshold (so specifying a regulator base
load in DT would also prevent ever selecting LPM).

This case of mixing consumers that specify and don't specify loads might
at least warrant a warning otherwise to avoid ending up in a
hard-to-debug situation with failing USB and PCIe due to a seemingly
unrelated DP PHY update.

At some point in the discussion I thought Mark suggested removing
set_load from drivers that don't actually manage active and idle loads.
That would also work, at least until the day one of the drivers adds
support for idle loads.

Johan


Re: [PATCH v3 1/4] video: fbdev: offb: Include missing linux/platform_device.h

2022-07-29 Thread Michael Ellerman
On Fri, 8 Jul 2022 09:11:05 +0200, Christophe Leroy wrote:
> A lot of drivers were getting platform and of headers
> indirectly via headers like asm/pci.h or asm/prom.h
> 
> Most of them were fixed during 5.19 cycle but a newissue was
> introduced by commit 52b1b46c39ae ("of: Create platform devices
> for OF framebuffers")
> 
> [...]

Applied to powerpc/next.

[1/4] video: fbdev: offb: Include missing linux/platform_device.h
  https://git.kernel.org/powerpc/c/ebef8abc963b9e537c0a0d619dd8faf1b8f2b183
[2/4] scsi: cxlflash: Include missing linux/irqdomain.h
  https://git.kernel.org/powerpc/c/61657dcd528b75cd196adaf56890124c13953c8d
[3/4] powerpc: Remove asm/prom.h from asm/mpc52xx.h and asm/pci.h
  https://git.kernel.org/powerpc/c/4d5c5bad51935482437528f7fa4dffdcb3330d8b
[4/4] powerpc: Finally remove unnecessary headers from asm/prom.h
  https://git.kernel.org/powerpc/c/36afe68714d45edf34430d28e3dc787425ad8b22

cheers


[PATCH v2] drm/tests: Split up test cases in igt_check_drm_format_min_pitch

2022-07-29 Thread Maíra Canal
The igt_check_drm_format_min_pitch() function had a lot of
KUNIT_EXPECT_* calls, all of which ended up allocating and initializing
various test assertion structures on the stack.

This behavior was producing -Wframe-larger-than warnings on PowerPC, i386,
and MIPS architectures, such as:

drivers/gpu/drm/tests/drm_format_test.c: In function 
'igt_check_drm_format_min_pitch':
drivers/gpu/drm/tests/drm_format_test.c:271:1: error: the frame size of
3712 bytes is larger than 2048 bytes

So, the igt_check_drm_format_min_pitch() test case was split into three
smaller functions: one testing single plane formats, one testing
multi-planar formats, and the other testing tiled formats.

Fixes: 0421bb0baa84 ("drm: selftest: convert drm_format selftest to KUnit")
Reported-by: kernel test robot 
Reported-by: Guenter Roeck 
Signed-off-by: Maíra Canal 
Tested-by: Guenter Roeck 
Reviewed-by: André Almeida 
---
v1 -> v2:
- Add Guenter's Tested-by tag.
- Add André's Reviewed-by tag.
- Replace "multiple planes" for "multi-planar" (André Almeida).
- Add Fixes tag (Melissa Wen).
---
 drivers/gpu/drm/tests/drm_format_test.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_format_test.c 
b/drivers/gpu/drm/tests/drm_format_test.c
index 056cb8599d6d..afb4bca72187 100644
--- a/drivers/gpu/drm/tests/drm_format_test.c
+++ b/drivers/gpu/drm/tests/drm_format_test.c
@@ -91,7 +91,7 @@ static void igt_check_drm_format_block_height(struct kunit 
*test)
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
 }
 
-static void igt_check_drm_format_min_pitch(struct kunit *test)
+static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit *test)
 {
const struct drm_format_info *info = NULL;
 
@@ -175,6 +175,11 @@ static void igt_check_drm_format_min_pitch(struct kunit 
*test)
(uint64_t)UINT_MAX * 4);
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 
1)),
(uint64_t)(UINT_MAX - 1) * 4);
+}
+
+static void igt_check_drm_format_min_pitch_for_multi_planar(struct kunit *test)
+{
+   const struct drm_format_info *info = NULL;
 
/* Test 2 planes format */
info = drm_format_info(DRM_FORMAT_NV12);
@@ -249,6 +254,11 @@ static void igt_check_drm_format_min_pitch(struct kunit 
*test)
(uint64_t)(UINT_MAX - 1) / 2);
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) 
/ 2),
(uint64_t)(UINT_MAX - 1) / 2);
+}
+
+static void igt_check_drm_format_min_pitch_for_tiled_format(struct kunit *test)
+{
+   const struct drm_format_info *info = NULL;
 
/* Test tiled format */
info = drm_format_info(DRM_FORMAT_X0L2);
@@ -273,7 +283,9 @@ static void igt_check_drm_format_min_pitch(struct kunit 
*test)
 static struct kunit_case drm_format_tests[] = {
KUNIT_CASE(igt_check_drm_format_block_width),
KUNIT_CASE(igt_check_drm_format_block_height),
-   KUNIT_CASE(igt_check_drm_format_min_pitch),
+   KUNIT_CASE(igt_check_drm_format_min_pitch_for_single_plane),
+   KUNIT_CASE(igt_check_drm_format_min_pitch_for_multi_planar),
+   KUNIT_CASE(igt_check_drm_format_min_pitch_for_tiled_format),
{ }
 };
 
-- 
2.37.1



[RESUBMIT][PATCH 2/2] drm/i915/gem: Perform active shrinking from a background thread

2022-07-29 Thread Janusz Krzysztofik
From: Chris Wilson 

i915 is very greedy and will retain system pages for as long as the user
requires them; once acquired they will be only returned when the object
is freed. In order to respond to system memory pressure, i915 hooks into
the shrinker subsystem, designed to prune the filesystem caches, to
unbind and return system pages. However, we can only do so if the device
is active at that moment, as we cannot resume the device from inside
direct reclaim to unbind pages from the GPU, nor do we want to delay
random processes with unbound waits trying to reclaim active pages. To
workaround that quandary, what we avoided in direct reclaim we
delegated to kswapd, as that is run from process context outside of
direct reclaim and able to sleep and resume the device.

In practice, kswapd also uses fs_reclaim_acquire() around its
shrink_slab calls, prohibiting runtime resume. If we cannot wake the
device from idle, we will retain system memory indefinitely.

As we cannot take advantage of kswapd's decoupled process context to
perform an active reclaim of bound pages, spawn our own kthread to wait
under our wakeref. Similar to kswapd, there is no direct dependency on
the background task to direct reclaim (other than failure to promptly
return pages will implicitly result in oom), as such the task itself does
not inherit the fs-reclaim context. A page reclaimed by i915 will
typically not immediately be available for re-use, as it will require
writeback, and so only a future allocation attempt may benefit.
Concurrent page allocation attempts do not wait for either kswapd or our
own swapper task.

We mark our kthread as a memallocator (allowed to dip into memory
reserves, but not allowed to trigger direct reclaim) and mark up
the call to the shrinker with a fs_reclaim critical section. This
should prevent us from accidentally abusing the background swapper task,
and so the swapper kthread behaves like kswapd with the exception of
being allowed to wake the device up, and being decoupled from the
shrinker_rwsem.

Reported-by: Thomas Hellström 
Bug: https://gitlab.freedesktop.org/drm/intel/-/issues/6449
Fixes: 178a30c90ac7 ("drm/i915: Unbind objects in shrinker only if device is 
runtime active")
Signed-off-by: Chris Wilson 
Cc: Thomas Hellström 
Cc: Matthew Auld 
Cc: Tvrtko Ursulin 
Cc: sta...@vger.kernel.org # v4.8+
Signed-off-by: Janusz Krzysztofik 
---
Resubmit reason: drop RFC label.

 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 134 +--
 drivers/gpu/drm/i915/i915_drv.h  |  15 +++
 2 files changed, 135 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 1030053571a2..bc6c1978e64a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -310,6 +310,113 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct 
shrink_control *sc)
return count;
 }
 
+static unsigned long run_swapper(struct drm_i915_private *i915,
+unsigned long target,
+unsigned long *nr_scanned)
+{
+   return i915_gem_shrink(NULL, i915,
+  target, nr_scanned,
+  I915_SHRINK_ACTIVE |
+  I915_SHRINK_BOUND |
+  I915_SHRINK_UNBOUND |
+  I915_SHRINK_WRITEBACK);
+}
+
+static int swapper(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   atomic_long_t *target = &i915->mm.swapper.target;
+   unsigned int noreclaim_state;
+
+   /*
+* For us to be running the swapper implies that the system is under
+* enough memory pressure to be swapping. At that point, we both want
+* to ensure we make forward progress in order to reclaim pages from
+* the device and not contribute further to direct reclaim pressure. We
+* mark ourselves as a memalloc task in order to not trigger direct
+* reclaim ourselves, but dip into the system memory reserves for
+* shrinkers.
+*/
+   noreclaim_state = memalloc_noreclaim_save();
+
+   do {
+   intel_wakeref_t wakeref;
+
+   ___wait_var_event(target,
+ atomic_long_read(target) ||
+ kthread_should_stop(),
+ TASK_IDLE, 0, 0, schedule());
+   if (kthread_should_stop())
+   break;
+
+   with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
+   unsigned long nr_scan = atomic_long_xchg(target, 0);
+
+   /*
+* Now that we have woken up the device hierarchy,
+* act as a normal shrinker. Our shrinker is primarily
+* focussed on supporting direct reclaim (low latency,
+ 

[RESUBMIT][PATCH 1/2] drm/i915/gem: Avoid taking runtime-pm under the shrinker

2022-07-29 Thread Janusz Krzysztofik
From: Chris Wilson 

Inside the shrinker, we cannot wake the device as that may cause
recursion into fs-reclaim, so instead we only unbind vma if the device
is currently awake. (In order to provide reclaim while asleep, we do
wake the device up during kswapd -- we probably want to limit that wake
up if we have anything to shrink though!)

To avoid the same fs_reclaim recursion potential during
i915_gem_object_unbind, we acquire a wakeref there, see commit
3e817471a34c ("drm/i915/gem: Take runtime-pm wakeref prior to unbinding").
However, we use i915_gem_object_unbind from the shrinker path to make the
object available for shrinking and so we must make the wakeref acquisition
here conditional.

<4> [437.542172] ==
<4> [437.542174] WARNING: possible circular locking dependency detected
<4> [437.542176] 5.19.0-rc6-CI_DRM_11876-g2305e0d00665+ #1 Tainted: G U
<4> [437.542179] --
<4> [437.542181] kswapd0/93 is trying to acquire lock:
<4> [437.542183] 827a7608 (acpi_wakeup_lock){+.+.}-{3:3}, at: 
acpi_device_wakeup_disable+0x12/0x50
<4> [437.542191]
but task is already holding lock:
<4> [437.542194] 8275d360 (fs_reclaim){+.+.}-{0:0}, at: 
balance_pgdat+0x91/0x5c0
<4> [437.542199]
which lock already depends on the new lock.
<4> [437.542202]
the existing dependency chain (in reverse order) is:
<4> [437.542204]
-> #2 (fs_reclaim){+.+.}-{0:0}:
<4> [437.542207]fs_reclaim_acquire+0x9d/0xd0
<4> [437.542211]kmem_cache_alloc_trace+0x2a/0x250
<4> [437.542214]__acpi_device_add+0x263/0x3a0
<4> [437.542217]acpi_add_single_object+0x3ea/0x710
<4> [437.542220]acpi_bus_check_add+0xf7/0x240
<4> [437.54]acpi_bus_scan+0x34/0xf0
<4> [437.542224]acpi_scan_init+0xf5/0x241
<4> [437.542228]acpi_init+0x449/0x4aa
<4> [437.542230]do_one_initcall+0x53/0x2e0
<4> [437.542233]kernel_init_freeable+0x18f/0x1dd
<4> [437.542236]kernel_init+0x11/0x110
<4> [437.542239]ret_from_fork+0x1f/0x30
<4> [437.542241]
-> #1 (acpi_device_lock){+.+.}-{3:3}:
<4> [437.542245]__mutex_lock+0x97/0xf20
<4> [437.542246]acpi_enable_wakeup_device_power+0x30/0xf0
<4> [437.542249]__acpi_device_wakeup_enable+0x31/0x110
<4> [437.542252]acpi_pm_set_device_wakeup+0x55/0x100
<4> [437.542254]__pci_enable_wake+0x5e/0xa0
<4> [437.542257]pci_finish_runtime_suspend+0x32/0x70
<4> [437.542259]pci_pm_runtime_suspend+0xa3/0x160
<4> [437.542262]__rpm_callback+0x3d/0x110
<4> [437.542265]rpm_callback+0x54/0x60
<4> [437.542268]rpm_suspend.part.10+0x105/0x5a0
<4> [437.542270]pm_runtime_work+0x7d/0x1e0
<4> [437.542273]process_one_work+0x272/0x5c0
<4> [437.542276]worker_thread+0x37/0x370
<4> [437.542278]kthread+0xed/0x120
<4> [437.542280]ret_from_fork+0x1f/0x30
<4> [437.542282]
-> #0 (acpi_wakeup_lock){+.+.}-{3:3}:
<4> [437.542285]__lock_acquire+0x15ad/0x2940
<4> [437.542288]lock_acquire+0xd3/0x310
<4> [437.542291]__mutex_lock+0x97/0xf20
<4> [437.542293]acpi_device_wakeup_disable+0x12/0x50
<4> [437.542295]acpi_pm_set_device_wakeup+0x6e/0x100
<4> [437.542297]__pci_enable_wake+0x73/0xa0
<4> [437.542300]pci_pm_runtime_resume+0x45/0x90
<4> [437.542302]__rpm_callback+0x3d/0x110
<4> [437.542304]rpm_callback+0x54/0x60
<4> [437.542307]rpm_resume+0x54f/0x750
<4> [437.542309]__pm_runtime_resume+0x42/0x80
<4> [437.542311]__intel_runtime_pm_get+0x19/0x80 [i915]
<4> [437.542386]i915_gem_object_unbind+0x8f/0x3b0 [i915]
<4> [437.542487]i915_gem_shrink+0x634/0x850 [i915]
<4> [437.542584]i915_gem_shrinker_scan+0x3a/0xc0 [i915]
<4> [437.542679]shrink_slab.constprop.97+0x1a4/0x4f0
<4> [437.542684]shrink_node+0x21e/0x420
<4> [437.542687]balance_pgdat+0x241/0x5c0
<4> [437.542690]kswapd+0x229/0x4f0
<4> [437.542694]kthread+0xed/0x120
<4> [437.542697]ret_from_fork+0x1f/0x30
<4> [437.542701]
other info that might help us debug this:
<4> [437.542705] Chain exists of:
  acpi_wakeup_lock --> acpi_device_lock --> fs_reclaim
<4> [437.542713]  Possible unsafe locking scenario:
<4> [437.542716]CPU0CPU1
<4> [437.542719]
<4> [437.542721]   lock(fs_reclaim);
<4> [437.542725]lock(acpi_device_lock);
<4> [437.542728]lock(fs_reclaim);
<4> [437.542732]   lock(acpi_wakeup_lock);
<4> [437.542736]
 *** DEADLOCK ***

Bug: https://gitlab.freedesktop.org/drm/intel/-/issues/6449
Fixes: 3e817471a34c ("drm/i915/gem: Take runtime-pm wakeref prior to unbinding")
Signed-off-by: Chris Wilson 
Cc: Matthew Auld 
Cc:  # v5.6+
Signed-off-by: Janusz Krzysztofik 
Reviewed-by: Matthew Auld 
---
Resubmit reason: keep in serie

Re: [PATCH 1/2] drivers: serial: earlycon: Pass device-tree node

2022-07-29 Thread Andy Shevchenko
On Fri, Jul 29, 2022 at 9:57 AM Greg Kroah-Hartman
 wrote:
> On Thu, Jul 28, 2022 at 11:04:24PM +0200, Andy Shevchenko wrote:
> > On Thu, Jul 28, 2022 at 4:41 PM Greg Kroah-Hartman
> >  wrote:
> > > On Thu, Jul 28, 2022 at 05:28:18PM +0300, Markuss Broks wrote:

...

> > > > + unsigned long node;
> > >
> > > That should not be an unsigned long, but rather an 'int'.  Something got
> > > messed up, of_setup_earlycon() should be changed to reflect this before
> > > propagating the error to other places in the kernel.
> >
> > It's a pointer, but what puzzles me, why it can't be declared as a such:
> >
> >  struct device_node *node;
> >
> > ?
>
> It should not be a pointer, trace things backwards, it comes from a call
> to of_setup_earlycon() from early_init_dt_scan_chosen_stdout() which has
> offset declared as an int, and then does:
> if (of_setup_earlycon(match, offset, options) == 0)
>
> So why would it be a node?

This is a very good question.

> > > And it's not really a "node" but an "offset", right?
> >
> > Seems no.
>
> Really?  What am I missing here?

It's me who is missing something here, thanks for your elaboration!
After it it becomes clear that your first question should be
addressed.

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v6 12/13] leds: flash: mt6370: Add MediaTek MT6370 flashlight support

2022-07-29 Thread Andy Shevchenko
On Fri, Jul 29, 2022 at 8:17 AM szuni chen  wrote:
> Andy Shevchenko  於 2022年7月25日 週一 下午4:51寫道:
> > On Fri, Jul 22, 2022 at 12:25 PM ChiaEn Wu  wrote:
> > >
> > > From: Alice Chen 

...

> > > Signed-off-by: Alice Chen 
> >
> > This SoB chain is wrong. Prioritize and read Submitting Patches!
>
> After reading the Submitted Patches,
> ChiaEn Wu wasn't involved in the development but he submitted the patch,
> So, ChiaEn Wu  should be the last SoB, right?

Right. Submitter's SoB is the last SoB in the chain.

> I will revise SoB to
>
> Signed-off-by: SzuNi Chen 

Not sure I understand the SzuNi <--> Alice transformation...

> Signed-off-by: ChiaEn Wu 
>
> If there is anything else I need to fix, please let me know. Thank you.

-- 
With Best Regards,
Andy Shevchenko


[PULL] drm-misc-fixes

2022-07-29 Thread Maxime Ripard
Hi Dave, Daniel,

Here's this week drm-misc-fixes PR

It's a partial resend from yesterday that only had the simpledrm but the mail 
somehow got lost.

Maxime

drm-misc-fixes-2022-07-29:
One fix to fix simpledrm mode_valid return value, and one for page
migration in nouveau
The following changes since commit 02c87df2480ac855d88ee308ce3fa857d9bd55a8:

  drm/imx/dcss: Add missing of_node_put() in fail path (2022-07-20 10:12:15 
+0300)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2022-07-29

for you to fetch changes up to 66cee9097e2b74ff3c8cc040ce5717c521a0c3fa:

  nouveau/svm: Fix to migrate all requested pages (2022-07-28 16:43:31 -0400)


One fix to fix simpledrm mode_valid return value, and one for page
migration in nouveau


Alistair Popple (1):
  nouveau/svm: Fix to migrate all requested pages

Nathan Chancellor (1):
  drm/simpledrm: Fix return type of 
simpledrm_simple_display_pipe_mode_valid()

 drivers/gpu/drm/nouveau/nouveau_dmem.c | 6 +-
 drivers/gpu/drm/tiny/simpledrm.c   | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)


signature.asc
Description: PGP signature


[PATCH] drm/via: Add new condition to via_dma_cleanup()

2022-07-29 Thread Alisa Khabibrakhmanova
Pointer dev_priv->mmio, which was checked for NULL at via_do_init_map(),
is passed to via_do_cleanup_map() and is dereferenced there without check.

The patch adds the condition in via_dma_cleanup() which prevents potential NULL
pointer dereference.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 22f579c621e2 ("drm: Add via unichrome support")
Signed-off-by: Alisa Khabibrakhmanova 
---
 drivers/gpu/drm/via/via_dri1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/via/via_dri1.c b/drivers/gpu/drm/via/via_dri1.c
index d695d9291ece..691e3ceb0062 100644
--- a/drivers/gpu/drm/via/via_dri1.c
+++ b/drivers/gpu/drm/via/via_dri1.c
@@ -2961,7 +2961,7 @@ int via_dma_cleanup(struct drm_device *dev)
drm_via_private_t *dev_priv =
(drm_via_private_t *) dev->dev_private;
 
-   if (dev_priv->ring.virtual_start) {
+   if (dev_priv->ring.virtual_start && dev_priv->mmio) {
via_cmdbuf_reset(dev_priv);
 
drm_legacy_ioremapfree(&dev_priv->ring.map, dev);
-- 
2.34.1



Re: [PATCH 1/2] drm/i915/gem: Avoid taking runtime-pm under the shrinker

2022-07-29 Thread Janusz Krzysztofik
Hi Matthew,

Thanks for review.

On Tuesday, 26 July 2022 20:14:05 CEST Matthew Auld wrote:
> On 20/07/2022 11:16, Janusz Krzysztofik wrote:
> > From: Chris Wilson 
> > 
> > Inside the shrinker, we cannot wake the device as that may cause
> > recursion into fs-reclaim, so instead we only unbind vma if the device
> > is currently awake. (In order to provide reclaim while asleep, we do
> > wake the device up during kswapd -- we probably want to limit that wake
> > up if we have anything to shrink though!)
> > 
> > To avoid the same fs_reclaim recursion potential during
> > i915_gem_object_unbind, we acquire a wakeref there, see commit
> > 3e817471a34c ("drm/i915/gem: Take runtime-pm wakeref prior to unbinding").
> > However, we use i915_gem_object_unbind from the shrinker path to make the
> > object available for shrinking and so we must make the wakeref acquisition
> > here conditional.
> > 
> > <4> [437.542172] ==
> > <4> [437.542174] WARNING: possible circular locking dependency detected
> > <4> [437.542176] 5.19.0-rc6-CI_DRM_11876-g2305e0d00665+ #1 Tainted: G U
> > <4> [437.542179] --
> > <4> [437.542181] kswapd0/93 is trying to acquire lock:
> > <4> [437.542183] 827a7608 (acpi_wakeup_lock){+.+.}-{3:3}, at: 
> > acpi_device_wakeup_disable+0x12/0x50
> > <4> [437.542191]
> > but task is already holding lock:
> > <4> [437.542194] 8275d360 (fs_reclaim){+.+.}-{0:0}, at: 
> > balance_pgdat+0x91/0x5c0
> > <4> [437.542199]
> > which lock already depends on the new lock.
> > <4> [437.542202]
> > the existing dependency chain (in reverse order) is:
> > <4> [437.542204]
> > -> #2 (fs_reclaim){+.+.}-{0:0}:
> > <4> [437.542207]fs_reclaim_acquire+0x9d/0xd0
> > <4> [437.542211]kmem_cache_alloc_trace+0x2a/0x250
> > <4> [437.542214]__acpi_device_add+0x263/0x3a0
> > <4> [437.542217]acpi_add_single_object+0x3ea/0x710
> > <4> [437.542220]acpi_bus_check_add+0xf7/0x240
> > <4> [437.54]acpi_bus_scan+0x34/0xf0
> > <4> [437.542224]acpi_scan_init+0xf5/0x241
> > <4> [437.542228]acpi_init+0x449/0x4aa
> > <4> [437.542230]do_one_initcall+0x53/0x2e0
> > <4> [437.542233]kernel_init_freeable+0x18f/0x1dd
> > <4> [437.542236]kernel_init+0x11/0x110
> > <4> [437.542239]ret_from_fork+0x1f/0x30
> > <4> [437.542241]
> > -> #1 (acpi_device_lock){+.+.}-{3:3}:
> > <4> [437.542245]__mutex_lock+0x97/0xf20
> > <4> [437.542246]acpi_enable_wakeup_device_power+0x30/0xf0
> > <4> [437.542249]__acpi_device_wakeup_enable+0x31/0x110
> > <4> [437.542252]acpi_pm_set_device_wakeup+0x55/0x100
> > <4> [437.542254]__pci_enable_wake+0x5e/0xa0
> > <4> [437.542257]pci_finish_runtime_suspend+0x32/0x70
> > <4> [437.542259]pci_pm_runtime_suspend+0xa3/0x160
> > <4> [437.542262]__rpm_callback+0x3d/0x110
> > <4> [437.542265]rpm_callback+0x54/0x60
> > <4> [437.542268]rpm_suspend.part.10+0x105/0x5a0
> > <4> [437.542270]pm_runtime_work+0x7d/0x1e0
> > <4> [437.542273]process_one_work+0x272/0x5c0
> > <4> [437.542276]worker_thread+0x37/0x370
> > <4> [437.542278]kthread+0xed/0x120
> > <4> [437.542280]ret_from_fork+0x1f/0x30
> > <4> [437.542282]
> > -> #0 (acpi_wakeup_lock){+.+.}-{3:3}:
> > <4> [437.542285]__lock_acquire+0x15ad/0x2940
> > <4> [437.542288]lock_acquire+0xd3/0x310
> > <4> [437.542291]__mutex_lock+0x97/0xf20
> > <4> [437.542293]acpi_device_wakeup_disable+0x12/0x50
> > <4> [437.542295]acpi_pm_set_device_wakeup+0x6e/0x100
> > <4> [437.542297]__pci_enable_wake+0x73/0xa0
> > <4> [437.542300]pci_pm_runtime_resume+0x45/0x90
> > <4> [437.542302]__rpm_callback+0x3d/0x110
> > <4> [437.542304]rpm_callback+0x54/0x60
> > <4> [437.542307]rpm_resume+0x54f/0x750
> > <4> [437.542309]__pm_runtime_resume+0x42/0x80
> > <4> [437.542311]__intel_runtime_pm_get+0x19/0x80 [i915]
> > <4> [437.542386]i915_gem_object_unbind+0x8f/0x3b0 [i915]
> > <4> [437.542487]i915_gem_shrink+0x634/0x850 [i915]
> > <4> [437.542584]i915_gem_shrinker_scan+0x3a/0xc0 [i915]
> > <4> [437.542679]shrink_slab.constprop.97+0x1a4/0x4f0
> > <4> [437.542684]shrink_node+0x21e/0x420
> > <4> [437.542687]balance_pgdat+0x241/0x5c0
> > <4> [437.542690]kswapd+0x229/0x4f0
> > <4> [437.542694]kthread+0xed/0x120
> > <4> [437.542697]ret_from_fork+0x1f/0x30
> > <4> [437.542701]
> > other info that might help us debug this:
> > <4> [437.542705] Chain exists of:
> >acpi_wakeup_lock --> acpi_device_lock --> fs_reclaim
> > <4> [437.542713]  Possible unsafe locking scenario:
> > <4> [437.542716]CPU0CPU1
> > <4> [437.542719]
> > <4> [437.542721]   lock(fs_reclaim);
> > 

Re: [PATCH 7/8] drm/tidss: Fix clock request value for OLDI videoports

2022-07-29 Thread Tomi Valkeinen

On 29/07/2022 06:56, Aradhya Bhatia wrote:


On 28-Jul-22 15:35, Tomi Valkeinen wrote:

On 19/07/2022 11:08, Aradhya Bhatia wrote:

The OLDI TX(es) require a serial clock which is 7 times the pixel clock
of the display panel. When the OLDI is enabled in DSS, the pixel clock
input of the corresponding videoport gets a divided-by 7 value of the
requested clock.

For the am625-dss, the requested clock needs to be 7 times the value.

Update the clock frequency by requesting 7 times the value.

Signed-off-by: Aradhya Bhatia 
---
  drivers/gpu/drm/tidss/tidss_dispc.c | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
b/drivers/gpu/drm/tidss/tidss_dispc.c

index c4a5f808648f..0b9689453ee8 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -1326,6 +1326,16 @@ int dispc_vp_set_clk_rate(struct dispc_device 
*dispc, u32 hw_videoport,

  int r;
  unsigned long new_rate;
+    /*
+ * For AM625 OLDI video ports, the requested pixel clock needs 
to take into account the
+ * serial clock required for the serialization of DPI signals 
into LVDS signals. The
+ * incoming pixel clock on the OLDI video port gets divided by 7 
whenever OLDI enable bit

+ * gets set.
+ */
+    if (dispc->feat->vp_bus_type[hw_videoport] == DISPC_VP_OLDI &&
+    dispc->feat->subrev == DISPC_AM625)
+    rate *= 7;
+
  r = clk_set_rate(dispc->vp_clk[hw_videoport], rate);
  if (r) {
  dev_err(dispc->dev, "vp%d: failed to set clk rate to %lu\n",


The AM625 TRM seems to be missing the "DSS integration" section, even 
if it's referred to in three places in the TRM. Supposedly that has 
details about the clocking.


Shouldn't the source clock be 3.5x when dual-link mode is used?

There should not be.

Whenever OLDI is enabled, the clock generated from the PLL is 7 times
the required pixel clock.

For the OLDI TXes, the clock passes through a /2 divider. This divider
only gets activated when the dual mode has been enabled in the OLDI
configuration. Thus the OLDI TXes get 3.5x the pixel clock in dual mode.

When the OLDI has been configured for a single mode,
the PLL clock passes through the /2 divider without any change.



While I don't know the details, this doesn't feel correct. We're 
supposed to be setting the VP pixel clock here, and the serial clock 
would be derived from that as it's done on AM65x. Is the DT clock tree

wrong for AM625?

Ideally, yes, its the pixel frequency that we are supposed to set here.

The same PLL clock (7 times the pixel frequency) passes through a /7
clock divider. This clock divider only gets active when OLDI is enabled.
Thus, the DSS VP clock input, only gets the actual pixel frequency that
it needs.

Since, the /7 divider is controlled by a signal from the DSS, the driver
needs to request 7 times more the pixel clock to accommodate for the
divider.

In AM65X, the system FW is able to model the 7 times requirement because
the divider is not controlled by the DSS signal. DSS signal controls a
multiplexer which receives both PLL Clock and PLL / 7 clock.


Could you ping the TI TRM team to add the DSS integration chapter? The 
clock tree is quite important part of the TRM.


I really don't like this one much. The dispc->vp_clk[0] here is actually 
not VP clock, but a parent clock of the VP clock, so, afaics, the driver 
gets "wrong" clock from DT data and then fixes things by manually 
multiplying the requested rate. If we have to go with a driver hack like 
this, I think it needs to be clarified more with comments, in the DT 
data also.


On AM625, the first videoport is always connected to OLDI(s), and never 
goes through as DPI, right? I.e. you cannot bypass OLDI?


If so, the /7 is, in practice, always enabled, as OLDI is the only use 
case. So why not add /7 node to the DT clock data, which would allow us 
to get rid of this code?


 Tomi


Re: [PATCH 1/2] drivers: serial: earlycon: Pass device-tree node

2022-07-29 Thread Greg Kroah-Hartman
On Thu, Jul 28, 2022 at 11:04:24PM +0200, Andy Shevchenko wrote:
> On Thu, Jul 28, 2022 at 4:41 PM Greg Kroah-Hartman
>  wrote:
> > On Thu, Jul 28, 2022 at 05:28:18PM +0300, Markuss Broks wrote:
> > > Pass a pointer to device-tree node in case the driver probed from
> > > OF. This makes early console drivers able to fetch options from
> > > device-tree node properties.
> 
> ...
> 
> > > + unsigned long node;
> >
> > That should not be an unsigned long, but rather an 'int'.  Something got
> > messed up, of_setup_earlycon() should be changed to reflect this before
> > propagating the error to other places in the kernel.
> 
> It's a pointer, but what puzzles me, why it can't be declared as a such:
> 
>  struct device_node *node;
> 
> ?

It should not be a pointer, trace things backwards, it comes from a call
to of_setup_earlycon() from early_init_dt_scan_chosen_stdout() which has
offset declared as an int, and then does:
if (of_setup_earlycon(match, offset, options) == 0)

So why would it be a node?

> > And it's not really a "node" but an "offset", right?
> 
> Seems no.

Really?  What am I missing here?

confused,

greg k-h


Re: [RFC PATCH] drm/edid: Make 144 Hz not preferred on Sharp LQ140M1JW46

2022-07-29 Thread Maxime Ripard
On Thu, Jul 28, 2022 at 02:18:38PM -0700, Doug Anderson wrote:
> Hi,
> 
> On Thu, Jul 28, 2022 at 10:34 AM Abhinav Kumar
>  wrote:
> >
> > Hi Rob and Doug
> >
> > On 7/22/2022 10:36 AM, Rob Clark wrote:
> > > On Fri, Jul 22, 2022 at 9:48 AM Doug Anderson  
> > > wrote:
> > >>
> > >> Hi,
> > >>
> > >> On Fri, Jul 22, 2022 at 9:37 AM Abhinav Kumar 
> > >>  wrote:
> > >>>
> > >>> + sankeerth
> > >>>
> > >>> Hi Doug
> > >>>
> > >>> On 7/21/2022 3:23 PM, Douglas Anderson wrote:
> >  The Sharp LQ140M1JW46 panel is on the Qualcomm sc7280 CRD reference
> >  board. This panel supports 144 Hz and 60 Hz. In the EDID, the 144 Hz
> >  mode is listed first and thus is marked preferred. The EDID decode I
> >  ran says:
> > 
> >  First detailed timing includes the native pixel format and 
> >  preferred
> >  refresh rate.
> > 
> >  ...
> > 
> >  Detailed Timing Descriptors:
> >    DTD 1:  1920x1080  143.981 Hz  16:9   166.587 kHz  346.500 MHz
> > Hfront   48 Hsync  32 Hback  80 Hpol N
> > Vfront3 Vsync   5 Vback  69 Vpol N
> >    DTD 2:  1920x1080   59.990 Hz  16:969.409 kHz  144.370 MHz
> > Hfront   48 Hsync  32 Hback  80 Hpol N
> > Vfront3 Vsync   5 Vback  69 Vpol N
> > 
> >  I'm proposing here that the above is actually a bug and that the 60 Hz
> >  mode really should be considered preferred by Linux.
> >
> > Its a bit tricky to say that this is a bug but I think we can certainly
> > add here that for an internal display we would have ideally had the
> > lower resolution first to indicate it as default.
> 
> Yeah, it gets into the vagueness of the EDID spec in general. As far
> as I can find it's really up to the monitor to decide by what means it
> chooses the "preferred" refresh rate if the monitor can support many.
> Some displays may decide that the normal rate is "preferred" and some
> may decide that the high refresh rate is "preferred". Neither display
> is "wrong" per say, but it's nice to have some consistency here and to
> make it so that otherwise "dumb" userspace will get something
> reasonable by default. I'll change it to say:
> 
> While the EDID spec appears to allow a display to use any criteria for
> picking which refresh mode is "preferred" or "optimal", that vagueness
> is a bit annoying. From Linux's point of view let's choose the 60 Hz
> one as the default.

And if we start making that decision, it should be for all panels with a
similar constraint, so most likely handled by the core, and the new
policy properly documented.

Doing that just for a single panel is weird.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v3 07/14] drm/mgag200: Replace simple-KMS with regular atomic helpers

2022-07-29 Thread Jocelyn Falempe

On 28/07/2022 20:31, Thomas Zimmermann wrote:

Hi Jocelyn

Am 28.07.22 um 17:09 schrieb Jocelyn Falempe:

On 28/07/2022 14:40, Thomas Zimmermann wrote:

Drop simple-KMS in favor of regular atomic helpers. Makes the code
more modular and hence better to adapt to per-model requirements.

The simple-KMS helpers provide few extra features, so the patch is
mostly about open-coding what simple-KMS does. The simple-KMS helpers
do mix up plane and CRTC state. Changing to regular atomic helpers
requires to split some of the simple-pipe functions into per-plane
and per-CRTC code

No functional changes.

v3:
* always run drm_atomic_helper_check_plane_state()
* clean up style

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Jocelyn Falempe 
Tested-by: Jocelyn Falempe 
Acked-by: Sam Ravnborg 
---
  drivers/gpu/drm/mgag200/mgag200_drv.h  |   8 +-
  drivers/gpu/drm/mgag200/mgag200_mode.c | 382 +++--
  2 files changed, 233 insertions(+), 157 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h

index bf6a01ff9719..b0433985ec0d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -15,11 +15,13 @@
  #include 
+#include 
+#include 
  #include 
  #include 
  #include 
  #include 
-#include 
+#include 
  #include "mgag200_reg.h"
@@ -276,9 +278,11 @@ struct mga_device {
  enum mga_type    type;
  struct mgag200_pll pixpll;
+    struct drm_plane primary_plane;
+    struct drm_crtc crtc;
+    struct drm_encoder encoder;
  struct mga_i2c_chan i2c;
  struct drm_connector connector;
-    struct drm_simple_display_pipe display_pipe;
  };
  static inline struct mga_device *to_mga_device(struct drm_device *dev)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c 
b/drivers/gpu/drm/mgag200/mgag200_mode.c

index 67795135d4dd..b524c1c5f032 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -23,7 +23,6 @@
  #include 
  #include 
  #include 
-#include 
  #include "mgag200_drv.h"
@@ -614,25 +613,106 @@ static void mgag200_handle_damage(struct 
mga_device *mdev, const struct iosys_ma

  }
  /*
- * Simple Display Pipe
+ * Primary plane
   */
-static const uint32_t mgag200_simple_display_pipe_formats[] = {
+static const uint32_t mgag200_primary_plane_formats[] = {
  DRM_FORMAT_XRGB,
  DRM_FORMAT_RGB565,
  DRM_FORMAT_RGB888,
  };
-static const uint64_t mgag200_simple_display_pipe_fmtmods[] = {
+static const uint64_t mgag200_primary_plane_fmtmods[] = {
  DRM_FORMAT_MOD_LINEAR,
  DRM_FORMAT_MOD_INVALID
  };
-static enum drm_mode_status
-mgag200_simple_display_pipe_mode_valid(struct 
drm_simple_display_pipe *pipe,

-   const struct drm_display_mode *mode)
+static int mgag200_primary_plane_helper_atomic_check(struct 
drm_plane *plane,

+ struct drm_atomic_state *new_state)
  {
-    struct mga_device *mdev = to_mga_device(pipe->crtc.dev);
+    struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(new_state, plane);

+    struct drm_framebuffer *new_fb = new_plane_state->fb;
+    struct drm_framebuffer *fb = NULL;
+    struct drm_crtc *new_crtc = new_plane_state->crtc;
+    struct drm_crtc_state *new_crtc_state = NULL;
+    struct mgag200_crtc_state *new_mgag200_crtc_state;
+    int ret;
+
+    if (new_crtc)
+    new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
new_crtc);


If new_crtc is NULL, then new_crtc_state will be NULL too, and it's 
dereferenced in drm_atomic_helper_check_plane_state() and later in 
this function.
So either there is a garantee that new_crtc is never NULL when calling 
this function, or it should return before trying to access it.


That's a good observation. Luckily it's not a problem in practice. The 
logic in the DRM code is confusing, however.


Near the top of the function, drm_atomic_check_planes_state() will only 
deref crtc_state if the plane has a CRTC set, [1] so we're safe here.


That will work because every CRTC/plane/connector/encoder always has an 
associated state; even if it's disabled. Hence if the plane has a crtc, 
that crtc will have a state. Or else, both will be NULL.


Further down, drm_atomic_helper_check_plane_state() first tests for 
!plane->fb [2] and then for !plane->crtc. [3] In both cases, 
drm_atomic_helper_check_plane_state() clears the visibility field to 0 
and returns 0.  Our code in mgag200_primary_plane_helper_atomic_check() 
will return early for invisible planes before deref'ing new_crtc_state, 
so we're safe here as well.


Best regards
Thomas

[1] 
https://elixir.bootlin.com/linux/v5.18.14/source/drivers/gpu/drm/drm_atomic_helper.c#L814 

[2] 
https://elixir.bootlin.com/linux/v5.18.14/source/drivers/gpu/drm/drm_atomic_helper.c#L819 

[3] 
https://elixir.bootlin.com/linux/v5.18.14/source/drivers/gpu/drm/drm_atomic_helper.c#L825 





Thanks a lot for the detailed explanation, I agree tha

[PATCH] drm/kmb: fix dereference before NULL check in kmb_plane_atomic_update()

2022-07-29 Thread Zeng Jingxiang
From: Zeng Jingxiang 

The "plane" pointer was access before checking if it was NULL.

The drm_atomic_get_old_plane_state() function will dereference
the pointer "plane".
345 struct drm_plane_state *old_plane_state =
drm_atomic_get_old_plane_state(state, plane);
346 struct drm_plane_state *new_plane_state =
drm_atomic_get_new_plane_state(state, plane);

A NULL check for "plane" indicates that it may be NULL
363 if (!plane || !new_plane_state || !old_plane_state)

Fixes: 977697e20b3d ("drm/atomic: Pass the full state to planes atomic disable 
and update")
Fixes: 37418bf14c13 ("drm: Use state helper instead of the plane state pointer")
Signed-off-by: Zeng Jingxiang 
---
 drivers/gpu/drm/kmb/kmb_plane.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/kmb/kmb_plane.c b/drivers/gpu/drm/kmb/kmb_plane.c
index 2735b8eb3537..d2bc998b65ce 100644
--- a/drivers/gpu/drm/kmb/kmb_plane.c
+++ b/drivers/gpu/drm/kmb/kmb_plane.c
@@ -342,10 +342,7 @@ static void kmb_plane_set_alpha(struct kmb_drm_private 
*kmb,
 static void kmb_plane_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
 {
-   struct drm_plane_state *old_plane_state = 
drm_atomic_get_old_plane_state(state,
-   
 plane);
-   struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(state,
-   
 plane);
+   struct drm_plane_state *old_plane_state, *new_plane_state;
struct drm_framebuffer *fb;
struct kmb_drm_private *kmb;
unsigned int width;
@@ -360,7 +357,13 @@ static void kmb_plane_atomic_update(struct drm_plane 
*plane,
static dma_addr_t addr[MAX_SUB_PLANES];
struct disp_cfg *init_disp_cfg;
 
-   if (!plane || !new_plane_state || !old_plane_state)
+   if (!plane)
+   return;
+
+   old_plane_state = drm_atomic_get_old_plane_state(state, plane);
+   new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+
+   if (!new_plane_state || !old_plane_state)
return;
 
fb = new_plane_state->fb;
-- 
2.27.0



Re: [syzbot] KASAN: vmalloc-out-of-bounds Write in imageblit (2)

2022-07-29 Thread Khalid Masum
Here is a simplified reproducer for the issue:

https://gist.githubusercontent.com/Labnann/923d6b9b3a19848fc129637b839b8a55/raw/a68271fcc724569735fe27f80817e561b3ff629a/reproducer.c




  1   2   >