Re: [RFC PATCH 00/16] drm/rockchip: Rockchip EBC ("E-Book Controller") display driver

2022-04-20 Thread Andreas Kemnade
On Wed, 13 Apr 2022 17:19:00 -0500
Samuel Holland  wrote:

[...]
> Waveform Selection From Userspace
> =
> EPDs use different waveforms for different purposes: high-quality
> grayscale vs. monochrome text vs. dithered monochrome video. How can
> userspace select which waveform to use? Should this be a plane property?
> 
Or does userspace rather select a QoS, like low-latency vs. high
quality. Or this will not change for a longer time: like doing full
refreshes.

> It is also likely that userspace will want to use different waveforms at
> the same time for different parts of the screen, for example a fast
> monochrome waveform for the drawing area of a note-taking app, but a
> grayscale waveform for surrounding UI and window manager.
> 

> I believe the i.MX6 EPDC supports multiple planes, each with their own
> waveform choice. That seems like a good abstraction, but the EBC only
> supports one plane in hardware. So using this abstraction with the EBC
> would require blending pixels and doing waveform lookups in software.
> 
The iMX6 EPDC has one working buffer containing the old+new state of
the pixel. That is 16bpp. Then for each update you can specify a
rectangle in an independant 8bpp buffer as a source. For now I am just
using a single buffer. But yes, that construction could be used to do
some multi plane stuff.

> Blitting/Blending in Software
> =
> There are multiple layers to this topic (pun slightly intended):
>  1) Today's userspace does not expect a grayscale framebuffer.
> Currently, the driver advertises XRGB and converts to Y4
> in software. This seems to match other drivers (e.g. repaper).
> 
>  2) Ignoring what userspace "wants", the closest existing format is
> DRM_FORMAT_R8. Geert sent a series[4] adding DRM_FORMAT_R1 through
> DRM_FORMAT_R4 (patch 9), which I believe are the "correct" formats
> to use.
>
hmm R=red? That sounds strange. I am unsure whether doing things with
lower bit depths actually really helps. 

>  3) The RK356x SoCs have an "RGA" hardware block that can do the
> RGB-to-grayscale conversion, and also RGB-to-dithered-monochrome
> which is needed for animation/video. Currently this is exposed with
> a V4L2 platform driver. Can this be inserted into the pipeline in a
> way that is transparent to userspace? Or must some userspace library
> be responsible for setting up the RGA => EBC pipeline?

hmm, we have other drivers with some hardware block doing rotation, but
in that cases it is not exposed as v4l2 mem2mem device.

On IMX6 there is also the PXP doing RGB-to-grayscale and rotation but
exposed as v4l2 device. But it can also be used to do undocumented
stuff writing to the 16bpp working buffer. So basically it is similar.
But I would do thoso things in a second step and just have the basic
stuff upstreamed

Regards,
Andreas


Re: [PULL v2] gvt-next

2022-04-20 Thread Joonas Lahtinen
+ Tvrtko

Quoting Christoph Hellwig (2022-04-21 08:47:38)
> On Thu, Apr 21, 2022 at 04:57:34AM +, Wang, Zhi A wrote:
> > Is it possible that I can send two different pull based on the same branch?
> > I was thinking I can remove this line in the original patch and then add a
> > small patch to add this line back on the top. Then make two different tags
> > before and after that small patch, send one pull with tag that includes that
> > small patch to i915 and the other pull with tag that doesn't includes it to
> > VFIO?
> 
> Yes, you can do that as long as the small fixup commit is the very last
> one.


Re: [PATCH 05/34] drm/i915/gvt: cleanup the Makefile

2022-04-20 Thread Joonas Lahtinen
+ Tvrtko

Quoting Jason Gunthorpe (2022-04-13 17:45:48)
> On Wed, Apr 13, 2022 at 02:26:23PM +, Wang, Zhi A wrote:
> > On 4/13/22 1:43 PM, Jason Gunthorpe wrote:
> > > On Wed, Apr 13, 2022 at 01:39:35PM +, Wang, Zhi A wrote:
> > > 
> > >> It seems Jani's makefile clean patch has already included this one, I can
> > >> just simply drop this one so that Christoph won't need to re-send 
> > >> everything.
> > >>
> > >> For the branch to move on, I am merging the patches and will re-generate 
> > >> the
> > >> gvt-staging branch, which combines the newest drm-tip vfio-upstream and 
> > >> other
> > >> gvt branches.
> > >>
> > >> If you are in a rush of re-basing the patches of non-GVT-g stuff, you 
> > >> can use
> > >> gvt-staging branch until my pull request landed in drm-intel-next.
> > >>
> > >> Also our QA will test gvt-staging-branch before the pull request. I 
> > >> suppose
> > >> it will take one or two days.
> > > 
> > > When you are wrangling the branches it would be great if Christoph's
> > > series and it's minimal dependencies could be on a single branch that
> > > could reasonably be pulled to the VFIO tree too, thanks
> > > 
> > > Jason
> > > 
> > 
> > Hi Jason:
> > 
> > I am thinking about the process of merging process. Here are the dependence:
> > 
> > 1) My patches depend on one patch in drm-intel/drm-intel-next. So it has to
> > go through drm.
> > My patches of GVT-g will go through drm-intel-next -> drm -> upstream. 
> > 
> > 2) Christoph's patches depends on my patches, but part of them are for VFIO.
> > 
> > a. If they are fully going through VFIO repo, they might have to wait my
> > patches to get landed first.
> > 
> > b. If only the GVT-g parts goes through GVT repo, and rest of them goes
> > through VFIO, the rest part still needs to wait.
> > 
> > What would be a better process?
> 
> You should organize everything onto one simple branch based on a rc to
> make this all work.
> 
> Make your #1 patch as a single patch PR based on rc to drm-intel so it
> gets to the right tree
> 
> Make your MMIO series as PR on the branch above that first PR and merge to
> the gvt tree
> 
> Make Christoph's series as a PR on the branch above the second PR's
> MMIO series and merge to the gvt tree
> 
> Merge the gvt toward DRM in the normal way - ie the main merge path for
> this should be through DRM.
> 
> Then ask Alex to merge the 3rd PR as well.
> 
> I don't see any intel-next stuff in linux-next yet so hopefully it is
> early enough to get #1 OK.
> 
> Jason


Re: [Intel-gfx] [PATCH] drm/i915: Fix race in __i915_vma_remove_closed

2022-04-20 Thread kernel test robot
Hi Karol,

I love your patch! Yet something to improve:

[auto build test ERROR on drm-tip/drm-tip]
[also build test ERROR on linus/master v5.18-rc3 next-20220420]
[cannot apply to drm-intel/for-linux-next linux/master]
[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]

url:
https://github.com/intel-lab-lkp/linux/commits/Karol-Herbst/drm-i915-Fix-race-in-__i915_vma_remove_closed/20220420-074525
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-c002 
(https://download.01.org/0day-ci/archive/20220420/202204201854.2r6j6wjr-...@intel.com/config)
compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
reproduce (this is a W=1 build):
# 
https://github.com/intel-lab-lkp/linux/commit/50a17180127b7d2527ee9a8f5c9e8207e158afb6
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Karol-Herbst/drm-i915-Fix-race-in-__i915_vma_remove_closed/20220420-074525
git checkout 50a17180127b7d2527ee9a8f5c9e8207e158afb6
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpu/drm/i915/

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

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/i915_vma.c: In function 'release_references':
>> drivers/gpu/drm/i915/i915_vma.c:1654:9: error: ISO C90 forbids mixed 
>> declarations and code [-Werror=declaration-after-statement]
1654 | struct intel_gt *gt = vma->vm->gt;
 | ^~
   cc1: all warnings being treated as errors


vim +1654 drivers/gpu/drm/i915/i915_vma.c

  1640  
  1641  static void release_references(struct i915_vma *vma, bool vm_ddestroy)
  1642  {
  1643  struct drm_i915_gem_object *obj = vma->obj;
  1644  
  1645  GEM_BUG_ON(i915_vma_is_active(vma));
  1646  
  1647  spin_lock(&obj->vma.lock);
  1648  list_del(&vma->obj_link);
  1649  if (!RB_EMPTY_NODE(&vma->obj_node))
  1650  rb_erase(&vma->obj_node, &obj->vma.tree);
  1651  
  1652  spin_unlock(&obj->vma.lock);
  1653  
> 1654  struct intel_gt *gt = vma->vm->gt;
  1655  
  1656  spin_lock_irq(>->closed_lock);
  1657  __i915_vma_remove_closed(vma);
  1658  spin_unlock_irq(>->closed_lock);
  1659  
  1660  if (vm_ddestroy)
  1661  i915_vm_resv_put(vma->vm);
  1662  
  1663  i915_active_fini(&vma->active);
  1664  GEM_WARN_ON(vma->resource);
  1665  i915_vma_free(vma);
  1666  }
  1667  

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


Re: [PATCH 24/41] ARM: omap: un-merge plat/sram.c

2022-04-20 Thread Tony Lindgren
* Arnd Bergmann  [220419 13:37]:
> From: Arnd Bergmann 
> 
> The sram initialization code is the only shared omap1/2 code that
> is not a standalone driver, but it is very short. Having two copies
> of this code means some duplication of the sources, but actually
> saves object code size as it can be inlined better.

FYI, the sram code should eventually be updated to use drivers/misc/sram.c,
I recall there being some issues to deal with for PM related code though.
Probably the PM related save and restore could be now handled with cpu_pm.

Regards,

Tony



Re: [PATCH 00/41] OMAP1 full multiplatform conversion

2022-04-20 Thread Tony Lindgren
* Ulf Hansson  [220419 14:12]:
> On Tue, 19 Apr 2022 at 15:37, Arnd Bergmann  wrote:
> >
> > From: Arnd Bergmann 
> >
> > This is the full series for converting OMAP1 to multiplatform, rebased
> > from my 2019 attempt to do the same thing. The soc tree contains simpler
> > patches to do the same for iop32x, ixp4xx, ep93xx and s3c24xx, which
> > means we are getting closer to completing this for all ARMv5 platforms
> > (I have patches for PXA, which is the last one remaining).
> >
> > Janusz already tested the branch separately and did the missing work
> > for the common-clk conversion after my previous approach was broken.
> >
> > The fbdev, mmc and ASoC portion of Janusz' work already went into the
> > corresponding maintainer tree, but I include them here for reference.
> > Unless there are any objections, I would add the entire series to the
> > for-next branch of the soc tree, but only send the first 36 patches early
> > in the merge window. After everything else has made it in, I would rebase
> > the last two patches and send them separately, which may or may not make
> > it in the merge window.
> 
> Sounds like a good plan to me. I usually send the MMC pull-request on
> Mondays, the first day of the merge window.

Sounds good to me. I tested the current omap1-multiplatform-5.18 branch
from mach-omap2 point of view, and things seem to work just fine for me.
I don't currently have any omap1 hardware online to test with.

For the patches, please feel free to add:

Acked-by: Tony Lindgren 


Re: [PATCH] drm/ttm: fix ttm tt init fail when size exceeds kmalloc limit

2022-04-20 Thread Christian König

Am 21.04.22 um 04:15 schrieb Wang, Yang(Kevin):


[AMD Official Use Only]





*From:* Kuehling, Felix 
*Sent:* Thursday, April 21, 2022 5:21 AM
*To:* Lazar, Lijo ; Koenig, Christian 
; Wang, Yang(Kevin) 
; Christian König 
; dri-devel@lists.freedesktop.org 
; amd-...@lists.freedesktop.org 

*Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size exceeds 
kmalloc limit


On 2022-04-20 09:23, Lazar, Lijo wrote:
>
>
> On 4/20/2022 6:26 PM, Christian König wrote:
>> Am 20.04.22 um 14:54 schrieb Wang, Yang(Kevin):
>>>
>>> [AMD Official Use Only]
>>>
>>>
>>> Hi Chris,
>>>
>>> 1) Change the test case to use something larger than 1TiB.
>>> sure, we can increase the size of BO and make test pass,
>>> but if user really want to allocate 1TB GTT BO, we have no reason to
>>> let it fail? right?
>>
>> No, the reason is the underlying core kernel doesn't allow kvmalloc
>> allocations with GFP_ZERO which are large enough to hold the array of
>> allocated pages for this.
>>
>> We are working on top of the core Linux kernel and should *NEVER*
>> ever add workarounds like what was suggested here. >
>
> AFAIU, for the purpose of ttm use, fallback to vmalloc is fine.
>
>  * Please note that any use of gfp flags outside of GFP_KERNEL is
> careful to not
>  * fall back to vmalloc.
>  *

That's weird, because kvcalloc does the same thing. If that were not
able to fall back to vmalloc, it would be pretty useless.

    static inline __alloc_size(1, 2) void *kvcalloc(size_t n, size_t 
size, gfp_t flags)

    {
 return kvmalloc_array(n, size, flags | __GFP_ZERO);
    }

Maybe kvcalloc is the function we TTM should be using here anyway,
instead of open-coding the kvmalloc_array call with an extra GFP flag.

Regards,
   Felix

Yes, I agree with your point, and in amdkfd driver code, we have the 
same risk in svm_range_dma_map_dev().


Yes, sounds like a good idea to me as well to change that.

Regards,
Christian.



Best Regards,
Kevin

>
> Actually the current implementation documents the behavior, but it is
> deep inside the implementation to be noticeable - at least not obvious
> while using kvmalloc_array.
>
> Thanks,
> Lijo
>
>> Regards,
>> Christian.
>>
>>> the system availed memory about 2T, but it will still fail.
>>>
>>> 2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc
>>> fallback path.
>>>     the 5.18 kernel will add this patch to fix this issue .
>>>
>>> Best Regards,
>>> Kevin
>>> 


>>>
>>> *From:* Koenig, Christian 
>>> *Sent:* Wednesday, April 20, 2022 8:42 PM
>>> *To:* Wang, Yang(Kevin) ; Christian König
>>> ; dri-devel@lists.freedesktop.org
>>> ; amd-...@lists.freedesktop.org
>>> 
>>> *Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size
>>> exceeds kmalloc limit
>>> Hi Kevin,
>>>
>>> yes and that is perfectly valid and expected behavior. There is
>>> absolutely no need to change anything in TTM here.
>>>
>>> What we could do is:
>>> 1) Change the test case to use something larger than 1TiB.
>>> 2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc
>>> fallback path.
>>>
>>> Regards,
>>> Christian.
>>>
>>> Am 20.04.22 um 14:39 schrieb Wang, Yang(Kevin):

 [AMD Official Use Only]


 Hi Chirs,

 yes, right, the amdgpu drive rwill use amdgpu_bo_validate_size()
 function to verify bo size,
 but when driver try to allocate VRAM domain bo fail, the amdgpu
 driver will fall back to allocate domain = (GTT | VRAM)  bo.
 please check following code, it will cause the 2nd time to allocate
 bo fail during allocate 256Mb buffer to store dma address (via
 kvmalloc()).

 initial_domain = (u32)(0x & args->in.domains);
 retry:
         r = amdgpu_gem_object_create(adev, size, args->in.alignment,
                    initial_domain,
                    flags, ttm_bo_type_device, resv, &gobj);
         if (r && r != -ERESTARTSYS) {
                 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
       flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
       goto retry;
                 }

                 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
       initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
       goto retry;
                 }
 DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n",
               size, initial_domain, args->in.alignment, r);
         }

 Best Regards,
 Kevin

 



 *From:* Christian König 
 >

 *Sent:* Wednesday, April 20, 2022 7:55 PM
 *To:* Wang, Yang(Kevin) 
 >; 
Koenig, Christian
  

Re: [PATCH 40/41] [TO BE REBASED] ARM: OMAP1: clock: Convert to CCF

2022-04-20 Thread Tony Lindgren
* Arnd Bergmann  [220419 13:39]:
> From: Janusz Krzysztofik 
> + /* protect clk->enable_reg from concurrent access via clk_set_rate() */
> + if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
> + spin_lock_irqsave(&arm_ckctl_lock, flags);
> + else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
> + spin_lock_irqsave(&arm_idlect2_lock, flags);
> + else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
> + spin_lock_irqsave(&mod_conf_ctrl_0_lock, flags);
> + else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
> + spin_lock_irqsave(&mod_conf_ctrl_1_lock, flags);
> + else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
> + spin_lock_irqsave(&swd_clk_div_ctrl_sel_lock, flags);
> +

Eventually there should be just separate clock controller instances for
the clock registers banks, and then this should all disappear as the
lock is instance specific. Anyways, that's probably best done as a separate
changes later on.

Regards,

Tony


Re: [PATCH 17/41] ARM: omap1: move 32k counter from plat-omap to mach-omap1

2022-04-20 Thread Tony Lindgren
* Arnd Bergmann  [220419 13:36]:
> From: Arnd Bergmann 
> 
> omap2 stopped using this code with commit 8d39ff3d1696 ("ARM: OMAP2+:
> Remove unused legacy code for timer"), so just move it to mach-omap1 now,
> along with the other half of that driver.

BTW, if omap1 gains devicetree support, chances are that the
drivers/clocksource/timer-ti-32k.c will be usable with minor
modifications.

Regards,

Tony


Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Paul Menzel

Dear Richard,


Am 21.04.22 um 03:12 schrieb Gong, Richard:


On 4/20/2022 3:29 PM, Paul Menzel wrote:



Am 19.04.22 um 23:46 schrieb Gong, Richard:


On 4/14/2022 2:52 AM, Paul Menzel wrote:

[Cc: -kernel test robot ]


[…]


Am 13.04.22 um 15:00 schrieb Alex Deucher:

On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:



Thank you for sending out v4.

Am 12.04.22 um 23:50 schrieb Richard Gong:
Active State Power Management (ASPM) feature is enabled since 
kernel 5.14.
There are some AMD GFX cards (such as WX3200 and RX640) that 
won't work
with ASPM-enabled Intel Alder Lake based systems. Using these GFX 
cards as
video/display output, Intel Alder Lake based systems will hang 
during

suspend/resume.


[Your email program wraps lines in cited text for some reason, making 
the citation harder to read.]


Not sure why, I am using Mozila Thunderbird for email. I am not using MS 
Outlook for upstream email.


Strange. No idea if there were bugs in Mozilla Thunderbird 91.2.0, 
released over half year ago. The current version is 91.8.1. [1]


I am still not clear, what “hang during suspend/resume” means. I 
guess
suspending works fine? During resume (S3 or S0ix?), where does it 
hang?

The system is functional, but there are only display problems?

System freeze after suspend/resume.


But you see certain messages still? At what point does it freeze 
exactly? In the bug report you posted Linux messages.


No, the system freeze then users have to recycle power to recover.


Then I misread the issue? Did you capture the messages over serial log then?

The issue was initially reported on one system (Dell Precision 
3660 with
BIOS version 0.14.81), but was later confirmed to affect at least 
4 Alder

Lake based systems.

Add extra check to disable ASPM on Intel Alder Lake based systems.

Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
Link: 
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=05%7C01%7Crichard.gong%40amd.com%7Cce01de048c61456174ff08da230c750d%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637860833680922036%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=vqhh3dTc%2FgBt7GrP9hKppWlrFy2F7DaivkNEuGekl0g%3D&reserved=0 



Thank you Microsoft Outlook for keeping us safe. :(

I am not using MS Outlook for the email exchanges.


I guess, it’s not the client but the Microsoft email service (Exchange?) 
no idea adding these protection links. (Making it even harder for users 
to actually verify domain. No idea who comes up with these ideas, and 
customers actually accepting those.)




Reported-by: kernel test robot 


This tag is a little confusing. Maybe clarify that it was for an 
issue

in a previous patch iteration?


I did describe in change-list version 3 below, which corrected the 
build error with W=1 option.


It is not good idea to add the description for that to the commit 
message, this is why I add descriptions on change-list version 3.


Do as you wish, but the current style is confusing, and readers of the 
commit are going to think, the kernel test robot reported the problem 
with AMD VI ASICs and Intel Alder Lake systems.





Signed-off-by: Richard Gong 
---
v4: s/CONFIG_X86_64/CONFIG_X86
  enhanced check logic
v3: s/intel_core_asom_chk/aspm_support_quirk_check
  correct build error with W=1 option
v2: correct commit description
  move the check from chip family to problematic platform
---
   drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
   1 file changed, 16 insertions(+), 1 deletion(-)

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

index 039b90cdc3bc..b33e0a9bee65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -81,6 +81,10 @@
   #include "mxgpu_vi.h"
   #include "amdgpu_dm.h"

+#if IS_ENABLED(CONFIG_X86)
+#include 
+#endif
+
   #define ixPCIE_LC_L1_PM_SUBSTATE    0x100100C6
   #define 
PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 0x0001L
   #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 
0x0002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct 
amdgpu_device *adev)

   WREG32_PCIE(ixPCIE_LC_CNTL, data);
   }

+static bool aspm_support_quirk_check(void)
+{
+ if (IS_ENABLED(CONFIG_X86)) {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+ return !(c->x86 == 6 && c->x86_model == 
INTEL_FAM6_ALDERLAKE);

+ }
+
+ return true;
+}
+
   static void vi_program_aspm(struct amdgpu_device *adev)
   {
   u32 data, data1, orig;
   bool bL1SS = false;
   bool bClkReqSupport = true;

- if (!amdgpu_device_should_use_aspm(adev))
+ if (!amdgpu_device_should_use_aspm(adev) || 
!aspm_support_quirk_check())

   return;


Can users still forcefully enable ASPM with the parameter 
`amdgpu.aspm`?


As Mario mentioned in a separate reply, we can't forcefully 

Re: [RFC PATCH v2 04/10] KVM: x86: mmu: tweak fast path for emulation of access to nested NPT pages

2022-04-20 Thread Maxim Levitsky
On Thu, 2022-04-21 at 08:12 +0300, Maxim Levitsky wrote:
> ---
>  arch/x86/kvm/mmu/mmu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 23f895d439cf5..b63398dfdac3b 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -5315,8 +5315,8 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t 
> cr2_or_gpa, u64 error_code,
>*/
>   if (vcpu->arch.mmu->root_role.direct &&
>   (error_code & PFERR_NESTED_GUEST_PAGE) == PFERR_NESTED_GUEST_PAGE) {
> - kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(cr2_or_gpa));
> - return 1;
> + if (kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(cr2_or_gpa)))
> + return 1;
>   }
>  
>   /*

I forgot to add commit description here:

If non leaf mmu page is write tracked externally for some reason,
which can in theory happen if it was used for nested avic physid page
before, then this code will enter an endless loop of page faults because
unprotecting the page will not remove write tracking, nor will the
write tracker callback be called.

Fix this by only invoking the fast patch if we succeeded in zapping the
mmu page.

Fixes: 147277540bbc5 ("kvm: svm: Add support for additional SVM NPF error 
codes")
Signed-off-by: Maxim Levitsky 

--

In theory, KVMGT also does external write tracking so in theory this issue can 
happen today,
but it is highly unlikely.

Best regards,
Maxim Levitsk



Re: [PATCH 26/41] ARM: omap1: relocate static I/O mapping

2022-04-20 Thread Tony Lindgren
* Arnd Bergmann  [220420 19:18]:
> On Wed, Apr 20, 2022 at 3:46 PM Aaro Koskinen  wrote:
> >
> > Hi,
> >
> > On Tue, Apr 19, 2022 at 03:37:08PM +0200, Arnd Bergmann wrote:
> > > From: Arnd Bergmann 
> > >
> > > The address range 0xfee0-0xfeff is used for PCI and
> > > PCMCIA I/O port mappings, but OMAP1 has its static mappings
> > > there as well.
> > >
> > > Move the OMAP1 addresses a little higher to avoid crashing
> > > at boot.
> >
> > This has the same problem I reported in 2019, with earlyprintk the
> > system no longer boots:
> >
> > https://marc.info/?t=15653001425&r=1&w=2
> >
> > Tested on OSK and SX1/qemu.
> 
> Thanks a lot for testing!
> 
> I managed to get to the bottom of this after just a few hours, and
> it turned out to be a simple math error on my end, as I got
> the alignment wrong, the offset has to be 0x00f0
> instead of 0x00fb be section aligned. I made sure the
> kernel boots up (to the point of missing a rootfs) and uploaded
> the fixed branch.

Good to hear this got sorted out :)

Regards,

Tony


[RFC PATCH v2 10/10] KVM: SVM: allow to avoid not needed updates to is_running

2022-04-20 Thread Maxim Levitsky
Allow optionally to make KVM not update is_running unless it is
functionally needed which is only when a vCPU halts,
or is in the guest mode.

This means security wise that if a vCPU is scheduled out,
other vCPUs could still send doorbell messages to the
last physical CPU where this vCPU was last running.

If a malicious guest tries to do it can slow down
the victim CPU by about 40% in my testing, so this
should only be enabled if physical CPUs are not shared
among guests.

The option is avic_doorbell_strict and is true by
default, setting it to false allows this relaxed
non strict mode.

Signed-off-by: Maxim Levitsky 
---
 arch/x86/kvm/svm/avic.c | 19 ---
 arch/x86/kvm/svm/svm.c  | 19 ++-
 arch/x86/kvm/svm/svm.h  |  1 +
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 9176c35662ada..1bfe58ee961b2 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -1641,7 +1641,7 @@ avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, 
int cpu, bool r)
 
 void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
-   u64 entry;
+   u64 old_entry, new_entry;
int h_physical_id = kvm_cpu_get_apicid(cpu);
struct vcpu_svm *svm = to_svm(vcpu);
 
@@ -1660,14 +1660,16 @@ void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (kvm_vcpu_is_blocking(vcpu))
return;
 
-   entry = READ_ONCE(*(svm->avic_physical_id_cache));
-   WARN_ON(entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK);
+   old_entry = READ_ONCE(*(svm->avic_physical_id_cache));
+   new_entry = old_entry;
 
-   entry &= ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK;
-   entry |= (h_physical_id & AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK);
-   entry |= AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK;
+   new_entry &= ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK;
+   new_entry |= (h_physical_id & 
AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK);
+   new_entry |= AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK;
+
+   if (old_entry != new_entry)
+   WRITE_ONCE(*(svm->avic_physical_id_cache), new_entry);
 
-   WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, true);
 }
 
@@ -1777,6 +1779,9 @@ void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
 
 void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
 {
+   if (!avic_doorbell_strict)
+   __nested_avic_put(vcpu);
+
if (!kvm_vcpu_apicv_active(vcpu))
return;
 
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 3d9ab1e7b2b52..7e79fefc81650 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -190,6 +190,10 @@ module_param(avic, bool, 0444);
 static bool force_avic;
 module_param_unsafe(force_avic, bool, 0444);
 
+bool avic_doorbell_strict = true;
+module_param(avic_doorbell_strict, bool, 0444);
+
+
 bool __read_mostly dump_invalid_vmcb;
 module_param(dump_invalid_vmcb, bool, 0644);
 
@@ -1395,16 +1399,21 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int 
cpu)
 
if (kvm_vcpu_apicv_active(vcpu))
__avic_vcpu_load(vcpu, cpu);
-
__nested_avic_load(vcpu, cpu);
 }
 
 static void svm_vcpu_put(struct kvm_vcpu *vcpu)
 {
-   if (kvm_vcpu_apicv_active(vcpu))
-   __avic_vcpu_put(vcpu);
-
-   __nested_avic_put(vcpu);
+   /*
+* Forbid AVIC's peers to send interrupts
+* to this CPU unless we are in non strict mode,
+* in which case, we will do so only when this vCPU blocks
+*/
+   if (avic_doorbell_strict) {
+   if (kvm_vcpu_apicv_active(vcpu))
+   __avic_vcpu_put(vcpu);
+   __nested_avic_put(vcpu);
+   }
 
svm_prepare_host_switch(vcpu);
 
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 7d1a5028750e6..7139bbb534f9e 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -36,6 +36,7 @@ extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
 extern bool npt_enabled;
 extern int vgif;
 extern bool intercept_smi;
+extern bool avic_doorbell_strict;
 
 /*
  * Clean bits in VMCB.
-- 
2.26.3



[RFC PATCH v2 09/10] KVM: nSVM: implement support for nested AVIC

2022-04-20 Thread Maxim Levitsky
This implements initial support of using the AVIC in a nested guest

Signed-off-by: Maxim Levitsky 
---
 arch/x86/kvm/svm/avic.c   | 850 +-
 arch/x86/kvm/svm/nested.c | 131 +-
 arch/x86/kvm/svm/svm.c|  18 +
 arch/x86/kvm/svm/svm.h| 150 +++
 arch/x86/kvm/trace.h  | 140 ++-
 arch/x86/kvm/x86.c|  11 +
 6 files changed, 1282 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 87756237c646d..9176c35662ada 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -51,6 +51,526 @@ static u32 next_vm_id = 0;
 static bool next_vm_id_wrapped = 0;
 static DEFINE_SPINLOCK(svm_vm_data_hash_lock);
 
+static u32 nested_avic_get_reg(struct kvm_vcpu *vcpu, int reg_off)
+{
+   struct vcpu_svm *svm = to_svm(vcpu);
+
+   void *nested_apic_regs = svm->nested.l2_apic_access_page.hva;
+
+   if (WARN_ON_ONCE(!nested_apic_regs))
+   return 0;
+
+   return *((u32 *) (nested_apic_regs + reg_off));
+}
+
+static inline struct kvm_vcpu *avic_vcpu_by_l1_apicid(struct kvm *kvm,
+ int l1_apicid)
+{
+   WARN_ON(l1_apicid == -1);
+   return kvm_get_vcpu_by_id(kvm, l1_apicid);
+}
+
+static void avic_physid_shadow_entry_set_vcpu(struct kvm *kvm,
+ struct avic_physid_table *t,
+ int n,
+ int new_l1_apicid)
+{
+   struct avic_physid_entry_descr *e = &t->entries[n];
+   u64 sentry = READ_ONCE(*e->sentry);
+   u64 old_sentry = sentry;
+   struct kvm_svm *kvm_svm = to_kvm_svm(kvm);
+   struct kvm_vcpu *new_vcpu = NULL;
+   int l0_apicid = -1;
+   unsigned long flags;
+
+   raw_spin_lock_irqsave(&kvm_svm->avic.table_entries_lock, flags);
+
+   WARN_ON(!test_bit(n, t->valid_entires));
+
+   if (!list_empty(&e->link))
+   list_del_init(&e->link);
+
+   if (new_l1_apicid != -1)
+   new_vcpu = avic_vcpu_by_l1_apicid(kvm, new_l1_apicid);
+
+   if (new_vcpu)
+   list_add_tail(&e->link, 
&to_svm(new_vcpu)->nested.physid_ref_entries);
+
+   if (new_vcpu && to_svm(new_vcpu)->nested_avic_active)
+   l0_apicid = kvm_cpu_get_apicid(new_vcpu->cpu);
+
+   physid_entry_set_apicid(&sentry, l0_apicid);
+
+   if (sentry != old_sentry)
+   WRITE_ONCE(*e->sentry, sentry);
+
+   raw_spin_unlock_irqrestore(&kvm_svm->avic.table_entries_lock, flags);
+}
+
+static void avic_physid_shadow_entry_create(struct kvm *kvm,
+   struct avic_physid_table *t,
+   int n,
+   u64 gentry)
+{
+   struct avic_physid_entry_descr *e = &t->entries[n];
+   struct page *backing_page;
+   u64 backing_page_gpa = physid_entry_get_backing_table(gentry);
+   int l1_apic_id = physid_entry_get_apicid(gentry);
+   hpa_t backing_page_hpa;
+   u64 sentry = 0;
+
+
+   if (backing_page_gpa == INVALID_BACKING_PAGE)
+   return;
+
+   /* Pin the APIC backing page */
+   backing_page = gfn_to_page(kvm, gpa_to_gfn(backing_page_gpa));
+
+   if (is_error_page(backing_page))
+   /* Invalid GPA in the guest entry - point to a dummy entry */
+   backing_page_hpa = t->dummy_page_hpa;
+   else
+   backing_page_hpa = page_to_phys(backing_page);
+
+   physid_entry_set_backing_table(&sentry, backing_page_hpa);
+
+   e->gentry = gentry;
+   *e->sentry = sentry;
+
+   if (test_and_set_bit(n, t->valid_entires))
+   WARN_ON(1);
+
+   if (backing_page_hpa != t->dummy_page_hpa)
+   avic_physid_shadow_entry_set_vcpu(kvm, t, n, l1_apic_id);
+}
+
+static void avic_physid_shadow_entry_remove(struct kvm *kvm,
+  struct avic_physid_table *t,
+  int n)
+{
+   struct avic_physid_entry_descr *e = &t->entries[n];
+   struct kvm_svm *kvm_svm = to_kvm_svm(kvm);
+   hpa_t backing_page_hpa;
+   unsigned long flags;
+
+   raw_spin_lock_irqsave(&kvm_svm->avic.table_entries_lock, flags);
+
+   if (!test_and_clear_bit(n, t->valid_entires))
+   WARN_ON(1);
+
+   /* Release the APIC backing page */
+   backing_page_hpa = physid_entry_get_backing_table(*e->sentry);
+
+   if (backing_page_hpa != t->dummy_page_hpa)
+   kvm_release_pfn_dirty(backing_page_hpa >> PAGE_SHIFT);
+
+   if (!list_empty(&e->link))
+   list_del_init(&e->link);
+
+   e->gentry = 0;
+   *e->sentry = 0;
+
+   raw_spin_unlock_irqrestore(&kvm_svm->avic.table_entries_lock, flags);
+}
+
+static void avic_update_peer_physid_entries(struct kvm_vcpu *vcpu, int cpu)
+{
+   /*
+* Update all sha

[RFC PATCH v2 08/10] KVM: x86: rename .set_apic_access_page_addr to reload_apic_access_page

2022-04-20 Thread Maxim Levitsky
This will be used on SVM to reload shadow page of the AVIC physid table

No functional change intended

Signed-off-by: Maxim Levitsky 
---
 arch/x86/include/asm/kvm-x86-ops.h | 2 +-
 arch/x86/include/asm/kvm_host.h| 3 +--
 arch/x86/kvm/vmx/vmx.c | 8 
 arch/x86/kvm/x86.c | 6 +++---
 4 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/kvm-x86-ops.h 
b/arch/x86/include/asm/kvm-x86-ops.h
index 96e4e9842dfc6..997edb7453ac2 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -82,7 +82,7 @@ KVM_X86_OP_OPTIONAL(hwapic_isr_update)
 KVM_X86_OP_OPTIONAL_RET0(guest_apic_has_interrupt)
 KVM_X86_OP_OPTIONAL(load_eoi_exitmap)
 KVM_X86_OP_OPTIONAL(set_virtual_apic_mode)
-KVM_X86_OP_OPTIONAL(set_apic_access_page_addr)
+KVM_X86_OP_OPTIONAL(reload_apic_pages)
 KVM_X86_OP(deliver_interrupt)
 KVM_X86_OP_OPTIONAL(sync_pir_to_irr)
 KVM_X86_OP_OPTIONAL_RET0(set_tss_addr)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index ae41d2df69fe9..f83cfcd7dd74c 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1415,7 +1415,7 @@ struct kvm_x86_ops {
bool (*guest_apic_has_interrupt)(struct kvm_vcpu *vcpu);
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
-   void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu);
+   void (*reload_apic_pages)(struct kvm_vcpu *vcpu);
void (*deliver_interrupt)(struct kvm_lapic *apic, int delivery_mode,
  int trig_mode, int vector);
int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);
@@ -1888,7 +1888,6 @@ int kvm_cpu_has_extint(struct kvm_vcpu *v);
 int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
-
 int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
unsigned long ipi_bitmap_high, u32 min,
unsigned long icr, int op_64_bit);
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index cf8581978bce3..7defd31703c61 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6339,7 +6339,7 @@ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
vmx_update_msr_bitmap_x2apic(vcpu);
 }
 
-static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu)
+static void vmx_reload_apic_access_page(struct kvm_vcpu *vcpu)
 {
struct page *page;
 
@@ -,7 +,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.enable_irq_window = vmx_enable_irq_window,
.update_cr8_intercept = vmx_update_cr8_intercept,
.set_virtual_apic_mode = vmx_set_virtual_apic_mode,
-   .set_apic_access_page_addr = vmx_set_apic_access_page_addr,
+   .reload_apic_pages = vmx_reload_apic_access_page,
.refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
.load_eoi_exitmap = vmx_load_eoi_exitmap,
.apicv_post_state_restore = vmx_apicv_post_state_restore,
@@ -7940,12 +7940,12 @@ static __init int hardware_setup(void)
enable_vnmi = 0;
 
/*
-* set_apic_access_page_addr() is used to reload apic access
+* kvm_vcpu_reload_apic_pages() is used to reload apic access
 * page upon invalidation.  No need to do anything if not
 * using the APIC_ACCESS_ADDR VMCS field.
 */
if (!flexpriority_enabled)
-   vmx_x86_ops.set_apic_access_page_addr = NULL;
+   vmx_x86_ops.reload_apic_pages = NULL;
 
if (!cpu_has_vmx_tpr_shadow())
vmx_x86_ops.update_cr8_intercept = NULL;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ab336f7c82e4b..3ac2d0134271b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9949,12 +9949,12 @@ void kvm_arch_mmu_notifier_invalidate_range(struct kvm 
*kvm,
kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD);
 }
 
-static void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
+static void kvm_vcpu_reload_apic_pages(struct kvm_vcpu *vcpu)
 {
if (!lapic_in_kernel(vcpu))
return;
 
-   static_call_cond(kvm_x86_set_apic_access_page_addr)(vcpu);
+   static_call_cond(kvm_x86_reload_apic_pages)(vcpu);
 }
 
 void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
@@ -10071,7 +10071,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (kvm_check_request(KVM_REQ_LOAD_EOI_EXITMAP, vcpu))
vcpu_load_eoi_exitmap(vcpu);
if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
-   kvm_vcpu_reload_apic_access_page(vcpu);
+   kvm_vcpu_reload_apic_pages(vcpu);
if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) {
vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVE

[RFC PATCH v2 07/10] KVM: x86: SVM: move avic state to separate struct

2022-04-20 Thread Maxim Levitsky
This will make the code a bit easier to read when nested AVIC support
is added.

No functional change intended.

Signed-off-by: Maxim Levitsky 
---
 arch/x86/kvm/svm/avic.c | 49 +++--
 arch/x86/kvm/svm/svm.h  | 14 +++-
 2 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index f375ca1d6518e..87756237c646d 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -69,6 +69,8 @@ int avic_ga_log_notifier(u32 ga_tag)
unsigned long flags;
struct kvm_svm *kvm_svm;
struct kvm_vcpu *vcpu = NULL;
+   struct kvm_svm_avic *avic;
+
u32 vm_id = AVIC_GATAG_TO_VMID(ga_tag);
u32 vcpu_id = AVIC_GATAG_TO_VCPUID(ga_tag);
 
@@ -76,9 +78,13 @@ int avic_ga_log_notifier(u32 ga_tag)
trace_kvm_avic_ga_log(vm_id, vcpu_id);
 
spin_lock_irqsave(&svm_vm_data_hash_lock, flags);
-   hash_for_each_possible(svm_vm_data_hash, kvm_svm, hnode, vm_id) {
-   if (kvm_svm->avic_vm_id != vm_id)
+   hash_for_each_possible(svm_vm_data_hash, avic, hnode, vm_id) {
+
+
+   if (avic->vm_id != vm_id)
continue;
+
+   kvm_svm = container_of(avic, struct kvm_svm, avic);
vcpu = kvm_get_vcpu_by_id(&kvm_svm->kvm, vcpu_id);
break;
}
@@ -98,18 +104,18 @@ int avic_ga_log_notifier(u32 ga_tag)
 void avic_vm_destroy(struct kvm *kvm)
 {
unsigned long flags;
-   struct kvm_svm *kvm_svm = to_kvm_svm(kvm);
+   struct kvm_svm_avic *avic = &to_kvm_svm(kvm)->avic;
 
if (!enable_apicv)
return;
 
-   if (kvm_svm->avic_logical_id_table_page)
-   __free_page(kvm_svm->avic_logical_id_table_page);
-   if (kvm_svm->avic_physical_id_table_page)
-   __free_page(kvm_svm->avic_physical_id_table_page);
+   if (avic->logical_id_table_page)
+   __free_page(avic->logical_id_table_page);
+   if (avic->physical_id_table_page)
+   __free_page(avic->physical_id_table_page);
 
spin_lock_irqsave(&svm_vm_data_hash_lock, flags);
-   hash_del(&kvm_svm->hnode);
+   hash_del(&avic->hnode);
spin_unlock_irqrestore(&svm_vm_data_hash_lock, flags);
 }
 
@@ -117,10 +123,9 @@ int avic_vm_init(struct kvm *kvm)
 {
unsigned long flags;
int err = -ENOMEM;
-   struct kvm_svm *kvm_svm = to_kvm_svm(kvm);
-   struct kvm_svm *k2;
struct page *p_page;
struct page *l_page;
+   struct kvm_svm_avic *avic = &to_kvm_svm(kvm)->avic;
u32 vm_id;
 
if (!enable_apicv)
@@ -131,14 +136,14 @@ int avic_vm_init(struct kvm *kvm)
if (!p_page)
goto free_avic;
 
-   kvm_svm->avic_physical_id_table_page = p_page;
+   avic->physical_id_table_page = p_page;
 
/* Allocating logical APIC ID table (4KB) */
l_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
if (!l_page)
goto free_avic;
 
-   kvm_svm->avic_logical_id_table_page = l_page;
+   avic->logical_id_table_page = l_page;
 
spin_lock_irqsave(&svm_vm_data_hash_lock, flags);
  again:
@@ -149,13 +154,15 @@ int avic_vm_init(struct kvm *kvm)
}
/* Is it still in use? Only possible if wrapped at least once */
if (next_vm_id_wrapped) {
-   hash_for_each_possible(svm_vm_data_hash, k2, hnode, vm_id) {
-   if (k2->avic_vm_id == vm_id)
+   struct kvm_svm_avic *avic2;
+
+   hash_for_each_possible(svm_vm_data_hash, avic2, hnode, vm_id) {
+   if (avic2->vm_id == vm_id)
goto again;
}
}
-   kvm_svm->avic_vm_id = vm_id;
-   hash_add(svm_vm_data_hash, &kvm_svm->hnode, kvm_svm->avic_vm_id);
+   avic->vm_id = vm_id;
+   hash_add(svm_vm_data_hash, &avic->hnode, avic->vm_id);
spin_unlock_irqrestore(&svm_vm_data_hash_lock, flags);
 
return 0;
@@ -169,8 +176,8 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb)
 {
struct kvm_svm *kvm_svm = to_kvm_svm(svm->vcpu.kvm);
phys_addr_t bpa = __sme_set(page_to_phys(svm->avic_backing_page));
-   phys_addr_t lpa = 
__sme_set(page_to_phys(kvm_svm->avic_logical_id_table_page));
-   phys_addr_t ppa = 
__sme_set(page_to_phys(kvm_svm->avic_physical_id_table_page));
+   phys_addr_t lpa = 
__sme_set(page_to_phys(kvm_svm->avic.logical_id_table_page));
+   phys_addr_t ppa = 
__sme_set(page_to_phys(kvm_svm->avic.physical_id_table_page));
 
vmcb->control.avic_backing_page = bpa & AVIC_HPA_MASK;
vmcb->control.avic_logical_id = lpa & AVIC_HPA_MASK;
@@ -193,7 +200,7 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu 
*vcpu,
if (index >= AVIC_MAX_PHYSICAL_ID_COUNT)
return NULL;
 
-   avic_physical_id_table = 
page_address(kvm_svm->avic_physical_id_tab

[RFC PATCH v2 06/10] KVM: x86: SVM: remove avic's broken code that updated APIC ID

2022-04-20 Thread Maxim Levitsky
Now that KVM doesn't allow to change APIC ID in case AVIC is
enabled, remove buggy AVIC code that tried to do so.

Signed-off-by: Maxim Levitsky 
---
 arch/x86/kvm/svm/avic.c | 35 ---
 1 file changed, 35 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 9b859218af59c..f375ca1d6518e 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -442,35 +442,6 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu)
return ret;
 }
 
-static int avic_handle_apic_id_update(struct kvm_vcpu *vcpu)
-{
-   u64 *old, *new;
-   struct vcpu_svm *svm = to_svm(vcpu);
-   u32 id = kvm_xapic_id(vcpu->arch.apic);
-
-   if (vcpu->vcpu_id == id)
-   return 0;
-
-   old = avic_get_physical_id_entry(vcpu, vcpu->vcpu_id);
-   new = avic_get_physical_id_entry(vcpu, id);
-   if (!new || !old)
-   return 1;
-
-   /* We need to move physical_id_entry to new offset */
-   *new = *old;
-   *old = 0ULL;
-   to_svm(vcpu)->avic_physical_id_cache = new;
-
-   /*
-* Also update the guest physical APIC ID in the logical
-* APIC ID table entry if already setup the LDR.
-*/
-   if (svm->ldr_reg)
-   avic_handle_ldr_update(vcpu);
-
-   return 0;
-}
-
 static void avic_handle_dfr_update(struct kvm_vcpu *vcpu)
 {
struct vcpu_svm *svm = to_svm(vcpu);
@@ -489,10 +460,6 @@ static int avic_unaccel_trap_write(struct kvm_vcpu *vcpu)
AVIC_UNACCEL_ACCESS_OFFSET_MASK;
 
switch (offset) {
-   case APIC_ID:
-   if (avic_handle_apic_id_update(vcpu))
-   return 0;
-   break;
case APIC_LDR:
if (avic_handle_ldr_update(vcpu))
return 0;
@@ -584,8 +551,6 @@ int avic_init_vcpu(struct vcpu_svm *svm)
 
 void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
 {
-   if (avic_handle_apic_id_update(vcpu) != 0)
-   return;
avic_handle_dfr_update(vcpu);
avic_handle_ldr_update(vcpu);
 }
-- 
2.26.3



[RFC PATCH v2 05/10] KVM: x86: lapic: don't allow to change APIC ID when apic acceleration is enabled

2022-04-20 Thread Maxim Levitsky
No normal guest has any reason to change physical APIC IDs, and
allowing this introduces bugs into APIC acceleration code.

Signed-off-by: Maxim Levitsky 
---
 arch/x86/kvm/lapic.c | 28 +++-
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 66b0eb0bda94e..56996aeca9881 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -2046,10 +2046,20 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, 
u32 reg, u32 val)
 
switch (reg) {
case APIC_ID:   /* Local APIC ID */
-   if (!apic_x2apic_mode(apic))
-   kvm_apic_set_xapic_id(apic, val >> 24);
-   else
+   if (apic_x2apic_mode(apic)) {
ret = 1;
+   break;
+   }
+   /*
+* Don't allow setting APIC ID with any APIC acceleration
+* enabled to avoid unexpected issues
+*/
+   if (enable_apicv && ((val >> 24) != apic->vcpu->vcpu_id)) {
+   kvm_vm_bugged(apic->vcpu->kvm);
+   break;
+   }
+
+   kvm_apic_set_xapic_id(apic, val >> 24);
break;
 
case APIC_TASKPRI:
@@ -2617,8 +2627,16 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
 static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s, bool set)
 {
-   if (apic_x2apic_mode(vcpu->arch.apic)) {
-   u32 *id = (u32 *)(s->regs + APIC_ID);
+   u32 *id = (u32 *)(s->regs + APIC_ID);
+
+   if (!apic_x2apic_mode(vcpu->arch.apic)) {
+   /* Don't allow setting APIC ID with any APIC acceleration
+* enabled to avoid unexpected issues
+*/
+   if (enable_apicv && (*id >> 24) != vcpu->vcpu_id)
+   return -EINVAL;
+   } else {
+
u32 *ldr = (u32 *)(s->regs + APIC_LDR);
u64 icr;
 
-- 
2.26.3



[RFC PATCH v2 04/10] KVM: x86: mmu: tweak fast path for emulation of access to nested NPT pages

2022-04-20 Thread Maxim Levitsky
---
 arch/x86/kvm/mmu/mmu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 23f895d439cf5..b63398dfdac3b 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -5315,8 +5315,8 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t 
cr2_or_gpa, u64 error_code,
 */
if (vcpu->arch.mmu->root_role.direct &&
(error_code & PFERR_NESTED_GUEST_PAGE) == PFERR_NESTED_GUEST_PAGE) {
-   kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(cr2_or_gpa));
-   return 1;
+   if (kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(cr2_or_gpa)))
+   return 1;
}
 
/*
-- 
2.26.3



[RFC PATCH v2 03/10] KVM: x86: mmu: add gfn_in_memslot helper

2022-04-20 Thread Maxim Levitsky
This is a tiny refactoring, and can be useful to check
if a GPA/GFN is within a memslot a bit more cleanly.

Signed-off-by: Maxim Levitsky 
---
 include/linux/kvm_host.h | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 252ee4a61b58b..12e261559070b 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1580,6 +1580,13 @@ int kvm_request_irq_source_id(struct kvm *kvm);
 void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
 bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args);
 
+
+static inline bool gfn_in_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+   return (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages);
+}
+
+
 /*
  * Returns a pointer to the memslot if it contains gfn.
  * Otherwise returns NULL.
@@ -1590,12 +1597,13 @@ try_get_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
if (!slot)
return NULL;
 
-   if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages)
+   if (gfn_in_memslot(slot, gfn))
return slot;
else
return NULL;
 }
 
+
 /*
  * Returns a pointer to the memslot that contains gfn. Otherwise returns NULL.
  *
-- 
2.26.3



[RFC PATCH v2 02/10] x86: KVMGT: use kvm_page_track_write_tracking_enable

2022-04-20 Thread Maxim Levitsky
This allows to enable the write tracking only when KVMGT is
actually used and doesn't carry any penalty otherwise.

Tested by booting a VM with a kvmgt mdev device.

Signed-off-by: Maxim Levitsky 
---
 arch/x86/kvm/Kconfig | 3 ---
 arch/x86/kvm/mmu/mmu.c   | 2 +-
 drivers/gpu/drm/i915/Kconfig | 1 -
 drivers/gpu/drm/i915/gvt/kvmgt.c | 5 +
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index e3cbd77061364..41341905d3734 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -126,7 +126,4 @@ config KVM_XEN
 
  If in doubt, say "N".
 
-config KVM_EXTERNAL_WRITE_TRACKING
-   bool
-
 endif # VIRTUALIZATION
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 2c4edae4b026d..23f895d439cf5 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -5727,7 +5727,7 @@ int kvm_mmu_init_vm(struct kvm *kvm)
node->track_flush_slot = kvm_mmu_invalidate_zap_pages_in_memslot;
kvm_page_track_register_notifier(kvm, node);
 
-   if (IS_ENABLED(CONFIG_KVM_EXTERNAL_WRITE_TRACKING) || !tdp_enabled)
+   if (!tdp_enabled)
mmu_enable_write_tracking(kvm);
 
return 0;
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 98c5450b8eacc..7d8346f4bae11 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -130,7 +130,6 @@ config DRM_I915_GVT_KVMGT
depends on DRM_I915_GVT
depends on KVM
depends on VFIO_MDEV
-   select KVM_EXTERNAL_WRITE_TRACKING
default n
help
  Choose this option if you want to enable KVMGT support for
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 057ec44901045..4c62ab3ef245d 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1933,6 +1933,7 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
struct intel_vgpu *vgpu;
struct kvmgt_vdev *vdev;
struct kvm *kvm;
+   int ret;
 
vgpu = mdev_get_drvdata(mdev);
if (handle_valid(vgpu->handle))
@@ -1948,6 +1949,10 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
if (__kvmgt_vgpu_exist(vgpu, kvm))
return -EEXIST;
 
+   ret = kvm_page_track_write_tracking_enable(kvm);
+   if (ret)
+   return ret;
+
info = vzalloc(sizeof(struct kvmgt_guest_info));
if (!info)
return -ENOMEM;
-- 
2.26.3



[RFC PATCH v2 01/10] KVM: x86: mmu: allow to enable write tracking externally

2022-04-20 Thread Maxim Levitsky
This will be used to enable write tracking from nested AVIC code
and can also be used to enable write tracking in GVT-g module
when it actually uses it as opposed to always enabling it,
when the module is compiled in the kernel.

No functional change intended.

Signed-off-by: Maxim Levitsky 
---
 arch/x86/include/asm/kvm_host.h   |  2 +-
 arch/x86/include/asm/kvm_page_track.h |  1 +
 arch/x86/kvm/mmu.h|  8 +---
 arch/x86/kvm/mmu/mmu.c| 17 ++---
 arch/x86/kvm/mmu/page_track.c | 10 --
 5 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2c20f715f0094..ae41d2df69fe9 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1234,7 +1234,7 @@ struct kvm_arch {
 * is used as one input when determining whether certain memslot
 * related allocations are necessary.
 */
-   bool shadow_root_allocated;
+   bool mmu_page_tracking_enabled;
 
 #if IS_ENABLED(CONFIG_HYPERV)
hpa_t   hv_root_tdp;
diff --git a/arch/x86/include/asm/kvm_page_track.h 
b/arch/x86/include/asm/kvm_page_track.h
index eb186bc57f6a9..955a5ae07b10e 100644
--- a/arch/x86/include/asm/kvm_page_track.h
+++ b/arch/x86/include/asm/kvm_page_track.h
@@ -50,6 +50,7 @@ int kvm_page_track_init(struct kvm *kvm);
 void kvm_page_track_cleanup(struct kvm *kvm);
 
 bool kvm_page_track_write_tracking_enabled(struct kvm *kvm);
+int kvm_page_track_write_tracking_enable(struct kvm *kvm);
 int kvm_page_track_write_tracking_alloc(struct kvm_memory_slot *slot);
 
 void kvm_page_track_free_memslot(struct kvm_memory_slot *slot);
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 671cfeccf04e9..44d15551f7156 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -269,7 +269,7 @@ int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu);
 int kvm_mmu_post_init_vm(struct kvm *kvm);
 void kvm_mmu_pre_destroy_vm(struct kvm *kvm);
 
-static inline bool kvm_shadow_root_allocated(struct kvm *kvm)
+static inline bool mmu_page_tracking_enabled(struct kvm *kvm)
 {
/*
 * Read shadow_root_allocated before related pointers. Hence, threads
@@ -277,9 +277,11 @@ static inline bool kvm_shadow_root_allocated(struct kvm 
*kvm)
 * see the pointers. Pairs with smp_store_release in
 * mmu_first_shadow_root_alloc.
 */
-   return smp_load_acquire(&kvm->arch.shadow_root_allocated);
+   return smp_load_acquire(&kvm->arch.mmu_page_tracking_enabled);
 }
 
+int mmu_enable_write_tracking(struct kvm *kvm);
+
 #ifdef CONFIG_X86_64
 static inline bool is_tdp_mmu_enabled(struct kvm *kvm) { return 
kvm->arch.tdp_mmu_enabled; }
 #else
@@ -288,7 +290,7 @@ static inline bool is_tdp_mmu_enabled(struct kvm *kvm) { 
return false; }
 
 static inline bool kvm_memslots_have_rmaps(struct kvm *kvm)
 {
-   return !is_tdp_mmu_enabled(kvm) || kvm_shadow_root_allocated(kvm);
+   return !is_tdp_mmu_enabled(kvm) || mmu_page_tracking_enabled(kvm);
 }
 
 static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 69a30d6d1e2b9..2c4edae4b026d 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3368,7 +3368,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
return r;
 }
 
-static int mmu_first_shadow_root_alloc(struct kvm *kvm)
+int mmu_enable_write_tracking(struct kvm *kvm)
 {
struct kvm_memslots *slots;
struct kvm_memory_slot *slot;
@@ -3378,21 +3378,20 @@ static int mmu_first_shadow_root_alloc(struct kvm *kvm)
 * Check if this is the first shadow root being allocated before
 * taking the lock.
 */
-   if (kvm_shadow_root_allocated(kvm))
+   if (mmu_page_tracking_enabled(kvm))
return 0;
 
mutex_lock(&kvm->slots_arch_lock);
 
/* Recheck, under the lock, whether this is the first shadow root. */
-   if (kvm_shadow_root_allocated(kvm))
+   if (mmu_page_tracking_enabled(kvm))
goto out_unlock;
 
/*
 * Check if anything actually needs to be allocated, e.g. all metadata
 * will be allocated upfront if TDP is disabled.
 */
-   if (kvm_memslots_have_rmaps(kvm) &&
-   kvm_page_track_write_tracking_enabled(kvm))
+   if (kvm_memslots_have_rmaps(kvm) && mmu_page_tracking_enabled(kvm))
goto out_success;
 
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
@@ -3422,7 +3421,7 @@ static int mmu_first_shadow_root_alloc(struct kvm *kvm)
 * all the related pointers are set.
 */
 out_success:
-   smp_store_release(&kvm->arch.shadow_root_allocated, true);
+   smp_store_release(&kvm->arch.mmu_page_tracking_enabled, true);
 
 out_unlock:
mutex_unlock(&kvm->slots_arch_lock);
@@ -3459,7 +3458,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
  

[RFC PATCH v2 00/10] RFCv2: nested AVIC

2022-04-20 Thread Maxim Levitsky
This patch series implement everything that is needed to
use AMD's AVIC while a nested guest is running including
ability of the nested guest to use it, and brings feature
parity vs APICv.

Compared to v1 of the series, there are lot of fixes,
and refactoring.

This version still use unconditional read-only apic id,
which will be addressed in the next version.

For the last patch, which allows to avoid cleaning is_running
bit in physid pages as long as it is possible, I measured
what would happen in a worst case:

- A malicious guest runs with 2 vCPUs pinned,
its first vCPU pounds on ICR sending IPIs to the 2nd vCPU

and 2nd vCPU scheduled out forever and not halted
(something that should not happen with Qemu though)

- A normal guest with single vCPU is pinned to run
on the same CPU as the 2nd vCPU of the first guest.

The normal guest continued to run, but was observed to run
about 40% slower.

Therefore AVIC doorbel is strict by default but if the admin
policy is to pin guests and not allow them to share a physical
cpu, then strict doorbel can be set to false and that does
improves the nested (and not nested as well) AVIC perf futher.

Suggestions, comments are welcome.

Best regards,
Maxim Levitsky

Maxim Levitsky (10):
  KVM: x86: mmu: allow to enable write tracking externally
  x86: KVMGT: use kvm_page_track_write_tracking_enable
  KVM: x86: mmu: add gfn_in_memslot helper
  KVM: x86: mmu: tweak fast path for emulation of access to nested NPT
pages
  KVM: x86: lapic: don't allow to change APIC ID when apic acceleration
is enabled
  KVM: x86: SVM: remove avic's broken code that updated APIC ID
  KVM: x86: SVM: move avic state to separate struct
  KVM: x86: rename .set_apic_access_page_addr to reload_apic_access_page
  KVM: nSVM: implement support for nested AVIC
  KVM: SVM: allow to avoid not needed updates to is_running

 arch/x86/include/asm/kvm-x86-ops.h|   2 +-
 arch/x86/include/asm/kvm_host.h   |   5 +-
 arch/x86/include/asm/kvm_page_track.h |   1 +
 arch/x86/kvm/Kconfig  |   3 -
 arch/x86/kvm/lapic.c  |  28 +-
 arch/x86/kvm/mmu.h|   8 +-
 arch/x86/kvm/mmu/mmu.c|  21 +-
 arch/x86/kvm/mmu/page_track.c |  10 +-
 arch/x86/kvm/svm/avic.c   | 949 --
 arch/x86/kvm/svm/nested.c | 131 +++-
 arch/x86/kvm/svm/svm.c|  31 +-
 arch/x86/kvm/svm/svm.h| 165 -
 arch/x86/kvm/trace.h  | 140 +++-
 arch/x86/kvm/vmx/vmx.c|   8 +-
 arch/x86/kvm/x86.c|  17 +-
 drivers/gpu/drm/i915/Kconfig  |   1 -
 drivers/gpu/drm/i915/gvt/kvmgt.c  |   5 +
 include/linux/kvm_host.h  |  10 +-
 18 files changed, 1413 insertions(+), 122 deletions(-)

-- 
2.26.3




[RFC PATCH 3/3] drm/i915: Enabling WD Transcoder

2022-04-20 Thread Suraj Kandpal
Adding support for writeback transcoder to start capturing frames using
interrupt mechanism

Signed-off-by: Suraj Kandpal 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/display/intel_acpi.c |   1 +
 drivers/gpu/drm/i915/display/intel_display.c  |  89 +-
 drivers/gpu/drm/i915/display/intel_display.h  |   9 +
 .../drm/i915/display/intel_display_types.h|  13 +
 drivers/gpu/drm/i915/display/intel_dpll.c |   3 +
 drivers/gpu/drm/i915/display/intel_opregion.c |   3 +
 drivers/gpu/drm/i915/display/intel_wd.c   | 978 ++
 drivers/gpu/drm/i915/display/intel_wd.h   |  82 ++
 drivers/gpu/drm/i915/i915_drv.h   |   2 +
 drivers/gpu/drm/i915/i915_irq.c   |   8 +-
 drivers/gpu/drm/i915/i915_pci.c   |   7 +-
 drivers/gpu/drm/i915/i915_reg.h   | 137 +++
 13 files changed, 1330 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_wd.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_wd.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 087bd9d1b397..5ee32513a945 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -287,6 +287,7 @@ i915-y += \
display/intel_vdsc.o \
display/intel_vrr.o \
display/intel_wb_connector.o\
+   display/intel_wd.o\
display/vlv_dsi.o \
display/vlv_dsi_pll.o
 
diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c 
b/drivers/gpu/drm/i915/display/intel_acpi.c
index e78430001f07..ae08db164f73 100644
--- a/drivers/gpu/drm/i915/display/intel_acpi.c
+++ b/drivers/gpu/drm/i915/display/intel_acpi.c
@@ -247,6 +247,7 @@ static u32 acpi_display_type(struct intel_connector 
*connector)
case DRM_MODE_CONNECTOR_LVDS:
case DRM_MODE_CONNECTOR_eDP:
case DRM_MODE_CONNECTOR_DSI:
+   case DRM_MODE_CONNECTOR_WRITEBACK:
display_type = ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL;
break;
case DRM_MODE_CONNECTOR_Unknown:
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index eb49973621f0..6dedc7921f54 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -111,6 +111,7 @@
 #include "intel_sprite.h"
 #include "intel_tc.h"
 #include "intel_vga.h"
+#include "intel_wd.h"
 #include "i9xx_plane.h"
 #include "skl_scaler.h"
 #include "skl_universal_plane.h"
@@ -1544,6 +1545,72 @@ static void intel_encoders_update_complete(struct 
intel_atomic_state *state)
}
 }
 
+static void intel_queue_writeback_job(struct intel_atomic_state *state,
+   struct intel_crtc *intel_crtc, struct intel_crtc_state 
*crtc_state)
+{
+   struct drm_connector_state *new_conn_state;
+   struct drm_connector *connector;
+   struct drm_i915_private *i915 = to_i915(intel_crtc->base.dev);
+   struct intel_wd *intel_wd;
+   struct intel_connector *intel_connector;
+   struct intel_digital_connector_state *intel_conn_state;
+   struct intel_encoder *encoder;
+   int i;
+
+   for_each_intel_encoder_with_wd(&i915->drm, encoder) {
+   intel_wd = enc_to_intel_wd(encoder);
+
+   if (intel_wd->wd_crtc != intel_crtc)
+   return;
+
+   }
+
+   for_each_new_connector_in_state(&state->base, connector, new_conn_state,
+   i) {
+   intel_conn_state = 
to_intel_digital_connector_state(new_conn_state);
+   if (!intel_conn_state->job)
+   continue;
+   intel_connector = to_intel_connector(connector);
+   intel_writeback_queue_job(&intel_connector->wb_conn, 
new_conn_state);
+   drm_dbg_kms(&i915->drm, "queueing writeback job\n");
+   }
+}
+
+static void intel_find_writeback_connector(struct intel_atomic_state *state,
+   struct intel_crtc *intel_crtc, struct intel_crtc_state 
*crtc_state)
+{
+   struct drm_connector_state *new_conn_state;
+   struct drm_connector *connector;
+   struct drm_i915_private *i915 = to_i915(intel_crtc->base.dev);
+   struct intel_wd *intel_wd;
+   struct intel_encoder *encoder;
+   int i;
+
+   for_each_intel_encoder_with_wd(&i915->drm, encoder) {
+   intel_wd = enc_to_intel_wd(encoder);
+
+   if (intel_wd->wd_crtc != intel_crtc)
+   return;
+
+   }
+
+   for_each_new_connector_in_state(&state->base, connector, new_conn_state,
+   i) {
+   struct intel_connector *intel_connector;
+
+   intel_connector = to_intel_connector(connector);
+   drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]: status: %s\n",
+   connector->base.id, connector->name,
+   
drm_get_connector_status_name(connector->statu

[RFC PATCH 2/3] drm/i915: Define WD trancoder for i915

2022-04-20 Thread Suraj Kandpal
Adding WD Types, WD transcoder to enum list and WD Transcoder offsets

Signed-off-by: Suraj Kandpal 
---
 drivers/gpu/drm/i915/display/intel_display.h   | 6 ++
 drivers/gpu/drm/i915/display/intel_display_types.h | 1 +
 drivers/gpu/drm/i915/i915_reg.h| 2 ++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.h 
b/drivers/gpu/drm/i915/display/intel_display.h
index 8513703086b7..8c93a5de8e07 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -119,6 +119,8 @@ enum transcoder {
TRANSCODER_DSI_1,
TRANSCODER_DSI_A = TRANSCODER_DSI_0,/* legacy DSI */
TRANSCODER_DSI_C = TRANSCODER_DSI_1,/* legacy DSI */
+   TRANSCODER_WD_0,
+   TRANSCODER_WD_1,
 
I915_MAX_TRANSCODERS
 };
@@ -140,6 +142,10 @@ static inline const char *transcoder_name(enum transcoder 
transcoder)
return "DSI A";
case TRANSCODER_DSI_C:
return "DSI C";
+   case TRANSCODER_WD_0:
+   return "WD 0";
+   case TRANSCODER_WD_1:
+   return "WD 1";
default:
return "";
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 7a96ecba73c0..dcb4ad43cf88 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -79,6 +79,7 @@ enum intel_output_type {
INTEL_OUTPUT_DSI = 9,
INTEL_OUTPUT_DDI = 10,
INTEL_OUTPUT_DP_MST = 11,
+   INTEL_OUTPUT_WD = 12,
 };
 
 enum hdmi_force_audio {
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ddbc7a685a50..6396afd77209 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2023,6 +2023,8 @@
 #define TRANSCODER_EDP_OFFSET 0x6f000
 #define TRANSCODER_DSI0_OFFSET 0x6b000
 #define TRANSCODER_DSI1_OFFSET 0x6b800
+#define TRANSCODER_WD0_OFFSET  0x6e000
+#define TRANSCODER_WD1_OFFSET  0x6e800
 
 #define HTOTAL(trans)  _MMIO_TRANS2(trans, _HTOTAL_A)
 #define HBLANK(trans)  _MMIO_TRANS2(trans, _HBLANK_A)
-- 
2.35.1



[RFC PATCH 1/3] drm/i915: Creating writeback pipeline to bypass drm_writeback framework

2022-04-20 Thread Suraj Kandpal
Changes to create a i915 private pipeline to enable the WD transcoder
without relying on the current drm_writeback framework.

Signed-off-by: Suraj Kandpal 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../drm/i915/display/intel_display_types.h|   4 +
 .../gpu/drm/i915/display/intel_wb_connector.c | 296 ++
 .../gpu/drm/i915/display/intel_wb_connector.h |  99 ++
 drivers/gpu/drm/i915/i915_drv.h   |   3 +
 5 files changed, 403 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/display/intel_wb_connector.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_wb_connector.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1a771ee5b1d0..087bd9d1b397 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -286,6 +286,7 @@ i915-y += \
display/intel_tv.o \
display/intel_vdsc.o \
display/intel_vrr.o \
+   display/intel_wb_connector.o\
display/vlv_dsi.o \
display/vlv_dsi_pll.o
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index d84e82f3eab9..7a96ecba73c0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -52,6 +52,7 @@
 #include "intel_display_power.h"
 #include "intel_dpll_mgr.h"
 #include "intel_pm_types.h"
+#include "intel_wb_connector.h"
 
 struct drm_printer;
 struct __intel_global_objs_state;
@@ -537,11 +538,14 @@ struct intel_connector {
struct work_struct modeset_retry_work;
 
struct intel_hdcp hdcp;
+
+   struct intel_writeback_connector wb_conn;
 };
 
 struct intel_digital_connector_state {
struct drm_connector_state base;
 
+   struct intel_writeback_job *job;
enum hdmi_force_audio force_audio;
int broadcast_rgb;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_wb_connector.c 
b/drivers/gpu/drm/i915/display/intel_wb_connector.c
new file mode 100644
index ..65f4abef53d0
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_wb_connector.c
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2022 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Suraj Kandpal 
+ * Arun Murthy 
+ *
+ */
+
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "intel_wb_connector.h"
+#include "intel_display_types.h"
+
+#define fence_to_wb_connector(x) container_of(x->lock, \
+ struct intel_writeback_connector, 
\
+ fence_lock)
+
+static const char *intel_writeback_fence_get_driver_name(struct dma_fence 
*fence)
+{
+   struct intel_writeback_connector *wb_connector =
+   fence_to_wb_connector(fence);
+
+   return wb_connector->base->dev->driver->name;
+}
+
+static const char *
+intel_writeback_fence_get_timeline_name(struct dma_fence *fence)
+{
+   struct intel_writeback_connector *wb_connector =
+   fence_to_wb_connector(fence);
+
+   return wb_connector->timeline_name;
+}
+
+static bool intel_writeback_fence_enable_signaling(struct dma_fence *fence)
+{
+   return true;
+}
+
+static const struct dma_fence_ops intel_writeback_fence_ops = {
+   .get_driver_name = intel_writeback_fence_get_driver_name,
+   .get_timeline_name = intel_writeback_fence_get_timeline_name,
+   .enable_signaling = intel_writeback_fence_enable_signaling,
+};
+
+static int intel_create_writeback_properties(struct drm_device *dev)
+{
+   struct drm_property *prop;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (!i915->wb_fb_id_property) {
+   prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
+  

[RFC PATCH 0/3] i915 writeback private framework

2022-04-20 Thread Suraj Kandpal
A patch series was floated in the drm mailing list which aimed to change
the drm_connector and drm_encoder fields to pointer in the
drm_connector_writeback structure, this received a huge pushback from
the community but since i915 expects each connector present in the
drm_device list to be a intel_connector but drm_writeback framework.
[1] 
https://patchwork.kernel.org/project/dri-devel/patch/20220202081702.22119-1-suraj.kand...@intel.com/
[2] 
https://patchwork.kernel.org/project/dri-devel/patch/20220202085429.22261-6-suraj.kand...@intel.com/
This forces us to use a drm_connector which is not embedded in
intel_connector the current drm_writeback framework becomes very
unfeasible to us as it would mean a lot of checks at a lot of places
to take into account the above issue.Since no one had an issue with
encoder field being changed into a pointer it was decided to break the
connector and encoder pointer changes into two different series.The
encoder field changes is currently being worked upon by Abhinav Kumar
[3]https://patchwork.kernel.org/project/dri-devel/list/?series=633565
In the meantime for i915 to start using the writeback functionality we
came up with a interim solution to own writeback pipeline bypassing one
provided by drm which is what these patches do.
Note: these are temp patches till we figure out how we can either change
drm core writeback to work with our intel_connector structure or find a
different solution which allows us to work with the current
drm_writeback framework

Suraj Kandpal (3):
  drm/i915: Creating writeback pipeline to bypass drm_writeback
framework
  drm/i915: Define WD trancoder for i915
  drm/i915: Enabling WD Transcoder

 drivers/gpu/drm/i915/Makefile |   2 +
 drivers/gpu/drm/i915/display/intel_acpi.c |   1 +
 drivers/gpu/drm/i915/display/intel_display.c  |  89 +-
 drivers/gpu/drm/i915/display/intel_display.h  |  15 +
 .../drm/i915/display/intel_display_types.h|  18 +
 drivers/gpu/drm/i915/display/intel_dpll.c |   3 +
 drivers/gpu/drm/i915/display/intel_opregion.c |   3 +
 .../gpu/drm/i915/display/intel_wb_connector.c | 296 ++
 .../gpu/drm/i915/display/intel_wb_connector.h |  99 ++
 drivers/gpu/drm/i915/display/intel_wd.c   | 978 ++
 drivers/gpu/drm/i915/display/intel_wd.h   |  82 ++
 drivers/gpu/drm/i915/i915_drv.h   |   5 +
 drivers/gpu/drm/i915/i915_irq.c   |   8 +-
 drivers/gpu/drm/i915/i915_pci.c   |   7 +-
 drivers/gpu/drm/i915/i915_reg.h   | 139 +++
 15 files changed, 1742 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_wb_connector.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_wb_connector.h
 create mode 100644 drivers/gpu/drm/i915/display/intel_wd.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_wd.h

-- 
2.35.1



Re: [PULL v2] gvt-next

2022-04-20 Thread Wang, Zhi A
On 4/20/22 8:00 PM, Jason Gunthorpe wrote:
> On Wed, Apr 20, 2022 at 02:46:00PM -0300, Jason Gunthorpe wrote:
>> On Wed, Apr 20, 2022 at 11:40:33AM -0600, Alex Williamson wrote:
>>> On Wed, 20 Apr 2022 13:43:51 -0300
>>> Jason Gunthorpe  wrote:
>>>
 On Wed, Apr 20, 2022 at 04:34:47PM +, Wang, Zhi A wrote:
> Hi folks:
>
> Here is the PR of gvt-next. Thanks so much for the patience.
>
> Mostly it includes the patch bundle of GVT-g re-factor patches for 
> adapting the GVT-g with the
> new MDEV interfaces:
>
> - Separating the MMIO table from GVT-g. (Zhi)
> - GVT-g re-factor. (Christoph)
> - GVT-g mdev API cleanup. (Jason)
> - GVT-g trace/makefile cleanup. (Jani)
>
> Thanks so much for making this happen.
>
> This PR has been tested as following and no problem shows up:
>
> $dim update-branches
> $dim apply-pull drm-intel-next < this_email.eml
>
> The following changes since commit 
> 3123109284176b1532874591f7c81f3837bbdc17:
>
>   Linux 5.18-rc1 (2022-04-03 14:08:21 -0700)
>
> are available in the Git repository at:
>
>   https://github.com/intel/gvt-linux 
> tags/gvt-next-2022-04-20-for-christoph
>
> for you to fetch changes up to ae7875879b7c838bffb42ed6db4658e5c504032e:
>
>   vfio/mdev: Remove mdev drvdata (2022-04-20 03:15:58 -0400)  

 This looks well constructed now! thanks

 Alex you can pull this for VFIO after Jani&co grab it

 I'll respin my vfio_group series on top of this branch
>>>
>>> Sure, so just to confirm tags/gvt-next-2022-04-20-for-christoph is
>>> pruned down to exactly the commits we're looking for now?  Thanks,
>>
>> Yes, the above is correct and the tag points to commit
>> ae7875879b7c838bffb42ed6db4658e5c504032e
>>
>> It is the bare minimum series
> 
> Actually this topic branch doesn't compile:
> 
> ../drivers/gpu/drm/i915/intel_gvt_mmio_table.c:7:10: fatal error: 
> 'display/intel_dmc_regs.h' file not found
> #include "display/intel_dmc_regs.h"
>  ^~
> 1 error generated.
> 
> :( :(
> 
> This is the merge conflict that was mentioned. This topic branch needs
> to delete the above intel_dmc_regs.h include file
> 
> When drm-intel-next merges this PR then need to add it back as part of
> the merge resolution - so explain this in the PR text above and
> include a diff that does it when you send it again. (or do the merge
> yourself as I showed before, it depends on what drm-intel-next wants)
> 
Hi Jason:

Is it possible that I can send two different pull based on the same branch?
I was thinking I can remove this line in the original patch and then add a
small patch to add this line back on the top. Then make two different tags
before and after that small patch, send one pull with tag that includes that
small patch to i915 and the other pull with tag that doesn't includes it to
VFIO?

Thanks,
Zhi.

> Jason
> 



[PATCH v4 2/2] drm/msm/dpu: Issue MDSS reset during initialization

2022-04-20 Thread Bjorn Andersson
It's typical for the bootloader to bring up the display for showing a
boot splash or efi framebuffer. But in some cases the kernel driver ends
up only partially configuring (in particular) the DPU, which might
result in e.g. that two different data paths attempts to push data to
the interface - with resulting graphical artifacts.

Naturally the end goal would be to inherit the bootloader's
configuration and provide the user with a glitch free handover from the
boot configuration to a running DPU.

But as implementing seamless transition from the bootloader
configuration to the running OS will be a considerable effort, start by
simply resetting the entire MDSS to its power-on state, to avoid the
partial configuration.

Signed-off-by: Bjorn Andersson 
---

Changes since v3:
- Rebased upon the mdss dpu/mdp restructuring 
(https://patchwork.freedesktop.org/series/98525/)

 drivers/gpu/drm/msm/msm_mdss.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index f6f0d0fa5ab2..20f154dda9cf 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -4,11 +4,13 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "msm_drv.h"
 #include "msm_kms.h"
@@ -193,6 +195,32 @@ static void msm_mdss_destroy(struct msm_mdss *msm_mdss)
irq_set_chained_handler_and_data(irq, NULL, NULL);
 }
 
+static int msm_mdss_reset(struct device *dev)
+{
+   struct reset_control *reset;
+
+   reset = reset_control_get_optional_exclusive(dev, NULL);
+   if (!reset) {
+   /* Optional reset not specified */
+   return 0;
+   } else if (IS_ERR(reset)) {
+   return dev_err_probe(dev, PTR_ERR(reset),
+"failed to acquire mdss reset\n");
+   }
+
+   reset_control_assert(reset);
+   /*
+* Tests indicate that reset has to be held for some period of time,
+* make it one frame in a typical system
+*/
+   msleep(20);
+   reset_control_deassert(reset);
+
+   reset_control_put(reset);
+
+   return 0;
+}
+
 /*
  * MDP5 MDSS uses at most three specified clocks.
  */
@@ -229,6 +257,10 @@ static struct msm_mdss *msm_mdss_init(struct 
platform_device *pdev, bool is_mdp5
int ret;
int irq;
 
+   ret = msm_mdss_reset(&pdev->dev);
+   if (ret)
+   return ERR_PTR(ret);
+
msm_mdss = devm_kzalloc(&pdev->dev, sizeof(*msm_mdss), GFP_KERNEL);
if (!msm_mdss)
return ERR_PTR(-ENOMEM);
-- 
2.35.1



[PATCH v4 1/2] dt-bindings: display: msm: Add optional resets

2022-04-20 Thread Bjorn Andersson
Add an optional reference to the MDSS_CORE reset, which when specified
can be used by the implementation to reset the hardware blocks.

Reviewed-by: Dmitry Baryshkov 
Acked-by: Krzysztof Kozlowski 
Signed-off-by: Bjorn Andersson 
---

Changes since v3:
- None

 .../devicetree/bindings/display/msm/dpu-qcm2290.yaml  | 4 
 Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml | 4 
 Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml | 4 
 Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml | 4 
 4 files changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml 
b/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml
index 6fb7e321f011..734d14de966d 100644
--- a/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml
@@ -66,6 +66,10 @@ properties:
   interconnect-names:
 const: mdp0-mem
 
+  resets:
+items:
+  - description: MDSS_CORE reset
+
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml 
b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml
index 12a86b1ec1bc..b41991eaa454 100644
--- a/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml
@@ -65,6 +65,10 @@ properties:
   interconnect-names:
 const: mdp0-mem
 
+  resets:
+items:
+  - description: MDSS_CORE reset
+
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml 
b/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
index fbeb931a026e..6e417d06fc79 100644
--- a/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
@@ -64,6 +64,10 @@ properties:
   interconnect-names:
 const: mdp0-mem
 
+  resets:
+items:
+  - description: MDSS_CORE reset
+
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml 
b/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml
index 0dca4b3d66e4..1a42491efdbc 100644
--- a/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml
@@ -57,6 +57,10 @@ properties:
 
   ranges: true
 
+  resets:
+items:
+  - description: MDSS_CORE reset
+
 patternProperties:
   "^display-controller@[0-9a-f]+$":
 type: object
-- 
2.35.1



Re: [PATCH] drm/ttm: fix ttm tt init fail when size exceeds kmalloc limit

2022-04-20 Thread Wang, Yang(Kevin)
[AMD Official Use Only]




From: Kuehling, Felix 
Sent: Thursday, April 21, 2022 5:21 AM
To: Lazar, Lijo ; Koenig, Christian 
; Wang, Yang(Kevin) ; 
Christian König ; 
dri-devel@lists.freedesktop.org ; 
amd-...@lists.freedesktop.org 
Subject: Re: [PATCH] drm/ttm: fix ttm tt init fail when size exceeds kmalloc 
limit


On 2022-04-20 09:23, Lazar, Lijo wrote:
>
>
> On 4/20/2022 6:26 PM, Christian König wrote:
>> Am 20.04.22 um 14:54 schrieb Wang, Yang(Kevin):
>>>
>>> [AMD Official Use Only]
>>>
>>>
>>> Hi Chris,
>>>
>>> 1) Change the test case to use something larger than 1TiB.
>>> sure, we can increase the size of BO and make test pass,
>>> but if user really want to allocate 1TB GTT BO, we have no reason to
>>> let it fail? right?
>>
>> No, the reason is the underlying core kernel doesn't allow kvmalloc
>> allocations with GFP_ZERO which are large enough to hold the array of
>> allocated pages for this.
>>
>> We are working on top of the core Linux kernel and should *NEVER*
>> ever add workarounds like what was suggested here. >
>
> AFAIU, for the purpose of ttm use, fallback to vmalloc is fine.
>
>  * Please note that any use of gfp flags outside of GFP_KERNEL is
> careful to not
>  * fall back to vmalloc.
>  *

That's weird, because kvcalloc does the same thing. If that were not
able to fall back to vmalloc, it would be pretty useless.

static inline __alloc_size(1, 2) void *kvcalloc(size_t n, size_t size, 
gfp_t flags)
{
 return kvmalloc_array(n, size, flags | __GFP_ZERO);
}

Maybe kvcalloc is the function we TTM should be using here anyway,
instead of open-coding the kvmalloc_array call with an extra GFP flag.

Regards,
   Felix

Yes, I agree with your point, and in amdkfd driver code, we have the same risk 
in svm_range_dma_map_dev().

Best Regards,
Kevin

>
> Actually the current implementation documents the behavior, but it is
> deep inside the implementation to be noticeable - at least not obvious
> while using kvmalloc_array.
>
> Thanks,
> Lijo
>
>> Regards,
>> Christian.
>>
>>> the system availed memory about 2T, but it will still fail.
>>>
>>> 2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc
>>> fallback path.
>>> the 5.18 kernel will add this patch to fix this issue .
>>>
>>> Best Regards,
>>> Kevin
>>> 
>>>
>>> *From:* Koenig, Christian 
>>> *Sent:* Wednesday, April 20, 2022 8:42 PM
>>> *To:* Wang, Yang(Kevin) ; Christian König
>>> ; dri-devel@lists.freedesktop.org
>>> ; amd-...@lists.freedesktop.org
>>> 
>>> *Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size
>>> exceeds kmalloc limit
>>> Hi Kevin,
>>>
>>> yes and that is perfectly valid and expected behavior. There is
>>> absolutely no need to change anything in TTM here.
>>>
>>> What we could do is:
>>> 1) Change the test case to use something larger than 1TiB.
>>> 2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc
>>> fallback path.
>>>
>>> Regards,
>>> Christian.
>>>
>>> Am 20.04.22 um 14:39 schrieb Wang, Yang(Kevin):

 [AMD Official Use Only]


 Hi Chirs,

 yes, right, the amdgpu drive rwill use amdgpu_bo_validate_size()
 function to verify bo size,
 but when driver try to allocate VRAM domain bo fail, the amdgpu
 driver will fall back to allocate domain = (GTT | VRAM)  bo.
 please check following code, it will cause the 2nd time to allocate
 bo fail during allocate 256Mb buffer to store dma address (via
 kvmalloc()).

 initial_domain = (u32)(0x & args->in.domains);
 retry:
 r = amdgpu_gem_object_create(adev, size, args->in.alignment,
initial_domain,
flags, ttm_bo_type_device, resv, &gobj);
 if (r && r != -ERESTARTSYS) {
 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
   flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
   goto retry;
 }

 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
   initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
   goto retry;
 }
 DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n",
   size, initial_domain, args->in.alignment, r);
 }

 Best Regards,
 Kevin

 

 *From:* Christian König 
 
 *Sent:* Wednesday, April 20, 2022 7:55 PM
 *To:* Wang, Yang(Kevin) 
 ; Koenig, Christian
  ;
 dri-devel@lists.freedesktop.org
 
 
 ;
 amd-...@lists.freedesktop.org
 
  

Re: [RFC v2 1/2] drm/doc/rfc: VM_BIND feature design document

2022-04-20 Thread Niranjana Vishwanathapura

On Wed, Mar 09, 2022 at 10:58:09AM -0500, Alex Deucher wrote:

On Mon, Mar 7, 2022 at 3:30 PM Niranjana Vishwanathapura
 wrote:


VM_BIND design document with description of intended use cases.

Signed-off-by: Niranjana Vishwanathapura 
---
 Documentation/gpu/rfc/i915_vm_bind.rst | 210 +
 Documentation/gpu/rfc/index.rst|   4 +
 2 files changed, 214 insertions(+)
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.rst

diff --git a/Documentation/gpu/rfc/i915_vm_bind.rst 
b/Documentation/gpu/rfc/i915_vm_bind.rst
new file mode 100644
index ..cdc6bb25b942
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.rst
@@ -0,0 +1,210 @@
+==
+I915 VM_BIND feature design and use cases
+==
+
+VM_BIND feature
+
+DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
+objects (BOs) or sections of a BOs at specified GPU virtual addresses on
+a specified address space (VM).
+
+These mappings (also referred to as persistent mappings) will be persistent
+across multiple GPU submissions (execbuff) issued by the UMD, without user
+having to provide a list of all required mappings during each submission
+(as required by older execbuff mode).
+
+VM_BIND ioctl deferes binding the mappings until next execbuff submission
+where it will be required, or immediately if I915_GEM_VM_BIND_IMMEDIATE
+flag is set (useful if mapping is required for an active context).
+
+VM_BIND feature is advertised to user via I915_PARAM_HAS_VM_BIND.
+User has to opt-in for VM_BIND mode of binding for an address space (VM)
+during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension.
+A VM in VM_BIND mode will not support older execbuff mode of binding.
+
+UMDs can still send BOs of these persistent mappings in execlist of execbuff
+for specifying BO dependencies (implicit fencing) and to use BO as a batch,
+but those BOs should be mapped ahead via vm_bind ioctl.
+
+VM_BIND features include,
+- Multiple Virtual Address (VA) mappings can map to the same physical pages
+  of an object (aliasing).
+- VA mapping can map to a partial section of the BO (partial binding).
+- Support capture of persistent mappings in the dump upon GPU error.
+- TLB is flushed upon unbind completion. Batching of TLB flushes in some
+  usecases will be helpful.
+- Asynchronous vm_bind and vm_unbind support.
+- VM_BIND uses user/memory fence mechanism for signaling bind completion
+  and for signaling batch completion in long running contexts (explained
+  below).
+
+VM_PRIVATE objects
+--
+By default, BOs can be mapped on multiple VMs and can also be dma-buf
+exported. Hence these BOs are referred to as Shared BOs.
+During each execbuff submission, the request fence must be added to the
+dma-resv fence list of all shared BOs mapped on the VM.
+
+VM_BIND feature introduces an optimization where user can create BO which
+is private to a specified VM via I915_GEM_CREATE_EXT_VM_PRIVATE flag during
+BO creation. Unlike Shared BOs, these VM private BOs can only be mapped on
+the VM they are private to and can't be dma-buf exported.
+All private BOs of a VM share the dma-resv object. Hence during each execbuff
+submission, they need only one dma-resv fence list updated. Thus the fast
+path (where required mappings are already bound) submission latency is O(1)
+w.r.t the number of VM private BOs.
+
+VM_BIND locking hirarchy
+-
+VM_BIND locking order is as below.
+
+1) A vm_bind mutex will protect vm_bind lists. This lock is taken in vm_bind/
+   vm_unbind ioctl calls, in the execbuff path and while releasing the mapping.
+
+   In future, when GPU page faults are supported, we can potentially use a
+   rwsem instead, so that multiple pagefault handlers can take the read side
+   lock to lookup the mapping and hence can run in parallel.
+
+2) The BO's dma-resv lock will protect i915_vma state and needs to be held
+   while binding a vma and while updating dma-resv fence list of a BO.
+   The private BOs of a VM will all share a dma-resv object.
+
+   This lock is held in vm_bind call for immediate binding, during vm_unbind
+   call for unbinding and during execbuff path for binding the mapping and
+   updating the dma-resv fence list of the BO.
+
+3) Spinlock/s to protect some of the VM's lists.
+
+We will also need support for bluk LRU movement of persistent mapping to
+avoid additional latencies in execbuff path.
+
+GPU page faults
+
+Both older execbuff mode and the newer VM_BIND mode of binding will require
+using dma-fence to ensure residency.
+In future when GPU page faults are supported, no dma-fence usage is required
+as residency is purely managed by installing and removing/invalidating ptes.
+
+
+User/Memory Fence
+==
+The idea is to take a user specified virtual address and install an interrupt
+handler to wake up the current task when the m

Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Gong, Richard

Hi Paul,

On 4/20/2022 3:29 PM, Paul Menzel wrote:

Dear Richard,


Am 19.04.22 um 23:46 schrieb Gong, Richard:


On 4/14/2022 2:52 AM, Paul Menzel wrote:

[Cc: -kernel test robot ]


[…]


Am 13.04.22 um 15:00 schrieb Alex Deucher:

On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:



Thank you for sending out v4.

Am 12.04.22 um 23:50 schrieb Richard Gong:
Active State Power Management (ASPM) feature is enabled since 
kernel 5.14.
There are some AMD GFX cards (such as WX3200 and RX640) that 
won't work
with ASPM-enabled Intel Alder Lake based systems. Using these GFX 
cards as
video/display output, Intel Alder Lake based systems will hang 
during

suspend/resume.


[Your email program wraps lines in cited text for some reason, making 
the citation harder to read.]


Not sure why, I am using Mozila Thunderbird for email. I am not using MS 
Outlook for upstream email.


I am still not clear, what “hang during suspend/resume” means. I 
guess
suspending works fine? During resume (S3 or S0ix?), where does it 
hang?

The system is functional, but there are only display problems?

System freeze after suspend/resume.


But you see certain messages still? At what point does it freeze 
exactly? In the bug report you posted Linux messages.


No, the system freeze then users have to recycle power to recover.



The issue was initially reported on one system (Dell Precision 
3660 with
BIOS version 0.14.81), but was later confirmed to affect at least 
4 Alder

Lake based systems.

Add extra check to disable ASPM on Intel Alder Lake based systems.

Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
Link: 
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=05%7C01%7Crichard.gong%40amd.com%7Cce01de048c61456174ff08da230c750d%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637860833680922036%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=vqhh3dTc%2FgBt7GrP9hKppWlrFy2F7DaivkNEuGekl0g%3D&reserved=0


Thank you Microsoft Outlook for keeping us safe. :(

I am not using MS Outlook for the email exchanges.




Reported-by: kernel test robot 


This tag is a little confusing. Maybe clarify that it was for an 
issue

in a previous patch iteration?


I did describe in change-list version 3 below, which corrected the 
build error with W=1 option.


It is not good idea to add the description for that to the commit 
message, this is why I add descriptions on change-list version 3.


Do as you wish, but the current style is confusing, and readers of the 
commit are going to think, the kernel test robot reported the problem 
with AMD VI ASICs and Intel Alder Lake systems.





Signed-off-by: Richard Gong 
---
v4: s/CONFIG_X86_64/CONFIG_X86
  enhanced check logic
v3: s/intel_core_asom_chk/aspm_support_quirk_check
  correct build error with W=1 option
v2: correct commit description
  move the check from chip family to problematic platform
---
   drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
   1 file changed, 16 insertions(+), 1 deletion(-)

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

index 039b90cdc3bc..b33e0a9bee65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -81,6 +81,10 @@
   #include "mxgpu_vi.h"
   #include "amdgpu_dm.h"

+#if IS_ENABLED(CONFIG_X86)
+#include 
+#endif
+
   #define ixPCIE_LC_L1_PM_SUBSTATE    0x100100C6
   #define 
PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 0x0001L
   #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 
0x0002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct 
amdgpu_device *adev)

   WREG32_PCIE(ixPCIE_LC_CNTL, data);
   }

+static bool aspm_support_quirk_check(void)
+{
+ if (IS_ENABLED(CONFIG_X86)) {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+ return !(c->x86 == 6 && c->x86_model == 
INTEL_FAM6_ALDERLAKE);

+ }
+
+ return true;
+}
+
   static void vi_program_aspm(struct amdgpu_device *adev)
   {
   u32 data, data1, orig;
   bool bL1SS = false;
   bool bClkReqSupport = true;

- if (!amdgpu_device_should_use_aspm(adev))
+ if (!amdgpu_device_should_use_aspm(adev) || 
!aspm_support_quirk_check())

   return;


Can users still forcefully enable ASPM with the parameter 
`amdgpu.aspm`?


As Mario mentioned in a separate reply, we can't forcefully enable 
ASPM with the parameter 'amdgpu.aspm'.


That would be a regression on systems where ASPM used to work. Hmm. I 
guess, you could say, there are no such systems.




   if (adev->flags & AMD_IS_APU ||


If I remember correctly, there were also newer cards, where ASPM 
worked
with Intel Alder Lake, right? Can only the problematic generations 
for

WX3200 and RX640 be excluded from ASPM?


This patch only disables it for the generatioaon that was problematic.


Could that please be made clear i

Re: [PATCH v2] drm/msm/dp: enhance both connect and disconnect pending_timeout handle

2022-04-20 Thread Kuogee Hsieh



On 4/20/2022 3:58 PM, Stephen Boyd wrote:

Quoting Kuogee Hsieh (2022-04-15 17:06:48)

On 4/14/2022 4:34 PM, Dmitry Baryshkov wrote:

I'm not sure how should the driver react if the client doesn't disable
the output, but then the sink gets reattached?

I do not know that either.

But it should not happen as long as framework response to uevent.

In talking with seanpaul@ it sounds like we can update the link status
to BAD with drm_connector_set_link_status_property() and then put it
back to GOOD when the link is re-established. This way userspace will
know it needs to retry the modeset. Does that help here?


To setup connection, dp driver have to enable phy and do link training 
then transfer dp controller to video ready state.


After that, dp driver signal framework to set up frame buffer 
fetching/layer mixer and start timing engine at final step to have video 
stream start transmitting to panel.


Do opposite way to tear down connection since dp driver can not reset dp 
controller and disable phy before timing engine has been stopped. 
Otherwise vsync timeout or buffer underrun/overrun may happen.


this means user space framework need to stop timing engine (stop frame 
buffer fetching/layer mixer) first and then stop video ready state of dp 
controller and then disable phy. (note, there may have something else at 
drm stack need to be teared down but i do not know details)


In this case, since framework is not response to uevent to stop timing 
engine,  dp controller still in video ready state and phy still enabled 
even dongle had been removed already.


At this point, I am not sure what dp driver should do if dongle re 
plugged back in.


Tear down dp mainlink while timing engine is still running and re setup 
dp mainlink?


However, I think this scenario most likely will not happen since if 
framework responses uevent to setup connection earlier it should be 
there to response uevent to tear down connection.








[PATCH v3 12/18] drm/msm/dpu: add encoder operations to prepare/cleanup wb job

2022-04-20 Thread Abhinav Kumar
add dpu encoder APIs to prepare and cleanup writeback job
for the writeback encoder. These shall be invoked from the
prepare_wb_job/cleanup_wb_job hooks of the drm_writeback
framework.

changes in v3:
- none

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  | 34 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h  | 16 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  5 
 3 files changed, 55 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index ec93962..86bdd1a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -912,6 +912,40 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
return 0;
 }
 
+void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc,
+   struct drm_writeback_job *job)
+{
+   struct dpu_encoder_virt *dpu_enc;
+   int i;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+   if (phys->ops.prepare_wb_job)
+   phys->ops.prepare_wb_job(phys, job);
+
+   }
+}
+
+void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc,
+   struct drm_writeback_job *job)
+{
+   struct dpu_encoder_virt *dpu_enc;
+   int i;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+   if (phys->ops.cleanup_wb_job)
+   phys->ops.cleanup_wb_job(phys, job);
+
+   }
+}
+
 static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
 struct drm_crtc_state *crtc_state,
 struct drm_connector_state 
*conn_state)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 2903e65..6ceec1d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -180,4 +180,20 @@ bool dpu_encoder_is_widebus_enabled(const struct 
drm_encoder *drm_enc);
  */
 bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc);
 
+/**
+ * dpu_encoder_prepare_wb_job - prepare writeback job for the encoder.
+ * @drm_enc:Pointer to previously created drm encoder structure
+ * @job:Pointer to the current drm writeback job
+ */
+void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc,
+   struct drm_writeback_job *job);
+
+/**
+ * dpu_encoder_cleanup_wb_job - cleanup writeback job for the encoder.
+ * @drm_enc:Pointer to previously created drm encoder structure
+ * @job:Pointer to the current drm writeback job
+ */
+void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc,
+   struct drm_writeback_job *job);
+
 #endif /* __DPU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 0b80af4..00951f3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -7,6 +7,7 @@
 #ifndef __DPU_ENCODER_PHYS_H__
 #define __DPU_ENCODER_PHYS_H__
 
+#include 
 #include 
 
 #include "dpu_kms.h"
@@ -137,6 +138,10 @@ struct dpu_encoder_phys_ops {
void (*restore)(struct dpu_encoder_phys *phys);
int (*get_line_count)(struct dpu_encoder_phys *phys);
int (*get_frame_count)(struct dpu_encoder_phys *phys);
+   void (*prepare_wb_job)(struct dpu_encoder_phys *phys_enc,
+   struct drm_writeback_job *job);
+   void (*cleanup_wb_job)(struct dpu_encoder_phys *phys_enc,
+   struct drm_writeback_job *job);
 };
 
 /**
-- 
2.7.4



[PATCH v3 17/18] drm/msm/dpu: gracefully handle null fb commits for writeback

2022-04-20 Thread Abhinav Kumar
kms_writeback test cases also verify with a null fb for the
writeback connector job. In addition there are also other
commit paths which can result in kickoffs without a valid
framebuffer like while closing the fb which results in the
callback to drm_atomic_helper_dirtyfb() which internally
triggers a commit.

Add protection in the dpu driver to ensure that commits for
writeback encoders without a valid fb are gracefully skipped.

changes in v2:
- rename dpu_encoder_has_valid_fb to dpu_encoder_is_valid_for_commit

changes in v3:
- none

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|  9 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 21 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  6 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h|  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 12 
 5 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 7763558..d65e124 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -869,6 +869,13 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
 
DPU_ATRACE_BEGIN("crtc_commit");
 
+   drm_for_each_encoder_mask(encoder, crtc->dev,
+   crtc->state->encoder_mask) {
+   if (!dpu_encoder_is_valid_for_commit(encoder)) {
+   DRM_DEBUG_ATOMIC("invalid FB not kicking off crtc\n");
+   goto end;
+   }
+   }
/*
 * Encoder will flush/start now, unless it has a tx pending. If so, it
 * may delay and flush at an irq event (e.g. ppdone)
@@ -891,6 +898,8 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
dpu_encoder_kickoff(encoder);
 
reinit_completion(&dpu_crtc->frame_done_comp);
+
+end:
DPU_ATRACE_END("crtc_commit");
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 65e44af..9c12841 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1850,6 +1850,27 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder 
*drm_enc)
dpu_encoder_prep_dsc(dpu_enc, dpu_enc->dsc);
 }
 
+bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc;
+   unsigned int i;
+   struct dpu_encoder_phys *phys;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_VIRTUAL) {
+   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+   phys = dpu_enc->phys_encs[i];
+   if (phys->ops.is_valid_for_commit && 
!phys->ops.is_valid_for_commit(phys)) {
+   DPU_DEBUG("invalid FB not kicking off\n");
+   return false;
+   }
+   }
+   }
+
+   return true;
+}
+
 void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
 {
struct dpu_encoder_virt *dpu_enc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 6ceec1d..781d41c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -196,4 +196,10 @@ void dpu_encoder_prepare_wb_job(struct drm_encoder 
*drm_enc,
 void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc,
struct drm_writeback_job *job);
 
+/**
+ * dpu_encoder_is_valid_for_commit - check if encode has valid parameters for 
commit.
+ * @drm_enc:Pointer to drm encoder structure
+ */
+bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc);
+
 #endif /* __DPU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 5452f98..04d037e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -142,6 +142,7 @@ struct dpu_encoder_phys_ops {
struct drm_writeback_job *job);
void (*cleanup_wb_job)(struct dpu_encoder_phys *phys_enc,
struct drm_writeback_job *job);
+   bool (*is_valid_for_commit)(struct dpu_encoder_phys *phys_enc);
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 3261437..563ca08 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -667,6 +667,16 @@ static void dpu_encoder_phys_wb_cleanup_wb_job(struct 
dpu_encoder_phys *phys_enc
wb_enc->wb_conn = NULL;
 }
 
+static bool dpu_encoder_phys_wb_is_valid_for_commit(struct dpu_encoder_phys 
*phys_enc)
+{
+   struct dpu

[PATCH v3 18/18] drm/msm/dpu: add writeback blocks to the display snapshot

2022-04-20 Thread Abhinav Kumar
Add writeback block information while capturing the display
snapshot.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 0a50509..86c98db 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -944,6 +944,11 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state 
*disp_state, struct msm_k
msm_disp_snapshot_add_block(disp_state, cat->mixer[i].len,
dpu_kms->mmio + cat->mixer[i].base, "lm_%d", i);
 
+   /* dump WB sub-blocks HW regs info */
+   for (i = 0; i < cat->wb_count; i++)
+   msm_disp_snapshot_add_block(disp_state, cat->wb[i].len,
+   dpu_kms->mmio + cat->wb[i].base, "wb_%d", i);
+
msm_disp_snapshot_add_block(disp_state, top->hw.length,
dpu_kms->mmio + top->hw.blk_off, "top");
 
-- 
2.7.4



[PATCH v3 11/18] drm/msm/dpu: make changes to dpu_encoder to support virtual encoder

2022-04-20 Thread Abhinav Kumar
Make changes to dpu_encoder to support virtual encoder needed
to support writeback for dpu.

changes in v3:
- fix a debug print statement
- leave a FIXME comment to separate intf_idx and wb_idx
- leave a TODO to improve the dpu_encoder_helper_phys_cleanup()

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0e31ad3..ec93962 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -928,6 +928,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
int num_lm, num_ctl, num_pp, num_dsc;
unsigned int dsc_mask = 0;
+   enum dpu_hw_blk_type blk_type;
int i;
 
if (!drm_enc) {
@@ -1009,12 +1010,21 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
phys->hw_pp = dpu_enc->hw_pp[i];
phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
 
-   if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX)
-   phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, 
phys->intf_idx);
+   if (dpu_encoder_get_intf_mode(&dpu_enc->base) == 
INTF_MODE_WB_LINE)
+   blk_type = DPU_HW_BLK_WB;
+   else
+   blk_type = DPU_HW_BLK_INTF;
+
+   if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) {
+   if (blk_type == DPU_HW_BLK_INTF)
+   phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, 
phys->intf_idx);
+   else if (blk_type == DPU_HW_BLK_WB)
+   phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, 
phys->intf_idx);
+   }
 
-   if (!phys->hw_intf) {
+   if (!phys->hw_intf && !phys->hw_wb) {
DPU_ERROR_ENC(dpu_enc,
- "no intf block assigned at idx: %d\n", i);
+ "no intf or wb block assigned at idx: 
%d\n", i);
return;
}
 
@@ -1157,15 +1167,22 @@ static void dpu_encoder_virt_disable(struct drm_encoder 
*drm_enc)
mutex_unlock(&dpu_enc->enc_lock);
 }
 
-static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg *catalog,
+static enum dpu_intf dpu_encoder_get_intf_or_wb(struct dpu_mdss_cfg *catalog,
enum dpu_intf_type type, u32 controller_id)
 {
int i = 0;
 
-   for (i = 0; i < catalog->intf_count; i++) {
-   if (catalog->intf[i].type == type
-   && catalog->intf[i].controller_id == controller_id) {
-   return catalog->intf[i].id;
+   if (type != INTF_WB) {
+   for (i = 0; i < catalog->intf_count; i++) {
+   if (catalog->intf[i].type == type
+   && catalog->intf[i].controller_id == 
controller_id) {
+   return catalog->intf[i].id;
+   }
+   }
+   } else {
+   for (i = 0; i < catalog->wb_count; i++) {
+   if (catalog->wb[i].id == controller_id)
+   return catalog->wb[i].id;
}
}
 
@@ -1886,16 +1903,32 @@ void dpu_encoder_helper_phys_cleanup(struct 
dpu_encoder_phys *phys_enc)
 
dpu_encoder_helper_reset_mixers(phys_enc);
 
-   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
-   if (dpu_enc->phys_encs[i] && 
phys_enc->hw_intf->ops.bind_pingpong_blk)
-   phys_enc->hw_intf->ops.bind_pingpong_blk(
-   dpu_enc->phys_encs[i]->hw_intf, false,
-   dpu_enc->phys_encs[i]->hw_pp->idx);
-
-   /* mark INTF flush as pending */
-   if (phys_enc->hw_ctl->ops.update_pending_flush_intf)
-   
phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl,
-   dpu_enc->phys_encs[i]->hw_intf->idx);
+   /*
+* TODO: move the once-only operation like CTL flush/trigger
+* into dpu_encoder_virt_disable() and all operations which need
+* to be done per phys encoder into the phys_disable() op.
+*/
+   if (phys_enc->hw_wb) {
+   /* disable the PP block */
+   if (phys_enc->hw_wb->ops.bind_pingpong_blk)
+   phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, 
false,
+   phys_enc->hw_pp->idx);
+
+   /* mark WB flush as pending */
+   if (phys_enc->hw_ctl->ops.update_pending_flush_

[PATCH v3 05/18] drm/msm/dpu: add reset_intf_cfg operation for dpu_hw_ctl

2022-04-20 Thread Abhinav Kumar
Add a reset_intf_cfg operation for dpu_hw_ctl to reset the
entire CTL path by disabling each component namely layer mixer,
3d-merge and interface blocks.

changes in v3:
- none

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 32 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h |  8 
 2 files changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index dc27579..524f024 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -563,6 +563,37 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
DPU_REG_WRITE(c, CTL_TOP, intf_cfg);
 }
 
+static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
+   struct dpu_hw_intf_cfg *cfg)
+{
+   struct dpu_hw_blk_reg_map *c = &ctx->hw;
+   u32 intf_active = 0;
+   u32 merge3d_active = 0;
+
+   /*
+* This API resets each portion of the CTL path namely,
+* clearing the sspps staged on the lm, merge_3d block,
+* interfaces etc to ensure clean teardown of the pipeline.
+* This will be used for writeback to begin with to have a
+* proper teardown of the writeback session but upon further
+* validation, this can be extended to all interfaces.
+*/
+   if (cfg->merge_3d) {
+   merge3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE);
+   merge3d_active &= ~BIT(cfg->merge_3d - MERGE_3D_0);
+   DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
+   merge3d_active);
+   }
+
+   dpu_hw_ctl_clear_all_blendstages(ctx);
+
+   if (cfg->intf) {
+   intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
+   intf_active &= ~BIT(cfg->intf - INTF_0);
+   DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
+   }
+}
+
 static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx,
unsigned long *fetch_active)
 {
@@ -586,6 +617,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
if (cap & BIT(DPU_CTL_ACTIVE_CFG)) {
ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1;
+   ops->reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1;
ops->update_pending_flush_intf =
dpu_hw_ctl_update_pending_flush_intf_v1;
ops->update_pending_flush_merge_3d =
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 97f326d..c61a8fd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -140,6 +140,14 @@ struct dpu_hw_ctl_ops {
void (*setup_intf_cfg)(struct dpu_hw_ctl *ctx,
struct dpu_hw_intf_cfg *cfg);
 
+   /**
+* reset ctl_path interface config
+* @ctx: ctl path ctx pointer
+* @cfg: interface config structure pointer
+*/
+   void (*reset_intf_cfg)(struct dpu_hw_ctl *ctx,
+   struct dpu_hw_intf_cfg *cfg);
+
int (*reset)(struct dpu_hw_ctl *c);
 
/*
-- 
2.7.4



[PATCH v3 13/18] drm/msm/dpu: move _dpu_plane_get_qos_lut to dpu_hw_util file

2022-04-20 Thread Abhinav Kumar
_dpu_plane_get_qos_lut() is not specific to just dpu_plane.
It can take any fill level and return the LUT matching it.
This can be used even for other modules like dpu_writeback.

Move _dpu_plane_get_qos_lut() to the common dpu_hw_util file
and rename it to _dpu_hw_get_qos_lut().

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 25 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h |  4 
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 27 +--
 3 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
index aad8511..512316f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
@@ -422,3 +422,28 @@ void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
DPU_REG_WRITE(c, csc_reg_off + 0x3c, data->csc_post_bv[1]);
DPU_REG_WRITE(c, csc_reg_off + 0x40, data->csc_post_bv[2]);
 }
+
+/**
+ * _dpu_hw_get_qos_lut - get LUT mapping based on fill level
+ * @tbl:   Pointer to LUT table
+ * @total_fl:  fill level
+ * Return: LUT setting corresponding to the fill level
+ */
+u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
+   u32 total_fl)
+{
+   int i;
+
+   if (!tbl || !tbl->nentry || !tbl->entries)
+   return 0;
+
+   for (i = 0; i < tbl->nentry; i++)
+   if (total_fl <= tbl->entries[i].fl)
+   return tbl->entries[i].lut;
+
+   /* if last fl is zero, use as default */
+   if (!tbl->entries[i-1].fl)
+   return tbl->entries[i-1].lut;
+
+   return 0;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
index a200df1..e4a65eb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include "dpu_hw_mdss.h"
+#include "dpu_hw_catalog.h"
 
 #define REG_MASK(n) ((BIT(n)) - 1)
 
@@ -339,4 +340,7 @@ void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map  *c,
u32 csc_reg_off,
const struct dpu_csc_cfg *data, bool csc10);
 
+u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
+   u32 total_fl);
+
 #endif /* _DPU_HW_UTIL_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 08b8c64..9d2f036 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -280,31 +280,6 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
 }
 
 /**
- * _dpu_plane_get_qos_lut - get LUT mapping based on fill level
- * @tbl:   Pointer to LUT table
- * @total_fl:  fill level
- * Return: LUT setting corresponding to the fill level
- */
-static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
-   u32 total_fl)
-{
-   int i;
-
-   if (!tbl || !tbl->nentry || !tbl->entries)
-   return 0;
-
-   for (i = 0; i < tbl->nentry; i++)
-   if (total_fl <= tbl->entries[i].fl)
-   return tbl->entries[i].lut;
-
-   /* if last fl is zero, use as default */
-   if (!tbl->entries[i-1].fl)
-   return tbl->entries[i-1].lut;
-
-   return 0;
-}
-
-/**
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane: Pointer to drm plane
  * @fb:Pointer to framebuffer associated with the 
given plane
@@ -333,7 +308,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
lut_usage = DPU_QOS_LUT_USAGE_MACROTILE;
}
 
-   qos_lut = _dpu_plane_get_qos_lut(
+   qos_lut = _dpu_hw_get_qos_lut(
&pdpu->catalog->perf.qos_lut_tbl[lut_usage], total_fl);
 
trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0,
-- 
2.7.4



[PATCH v3 16/18] drm/msm/dpu: initialize dpu encoder and connector for writeback

2022-04-20 Thread Abhinav Kumar
Initialize dpu encoder and connector for writeback if the
target supports it in the catalog.

changes in v2:
- start initialing the encoder for writeback since we
have migrated to using drm_writeback_connector_init_with_encoder()
- instead of checking for WB_2 inside _dpu_kms_initialize_writeback
call it only when its WB_2
- rebase on tip of msm-next and remove usage of priv->encoders

changes in v3:
- none

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 27 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 58 +
 2 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 86bdd1a..65e44af 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2090,7 +2090,7 @@ static void dpu_encoder_early_unregister(struct 
drm_encoder *encoder)
 }
 
 static int dpu_encoder_virt_add_phys_encs(
-   u32 display_caps,
+   struct msm_display_info *disp_info,
struct dpu_encoder_virt *dpu_enc,
struct dpu_enc_phys_init_params *params)
 {
@@ -2109,7 +2109,7 @@ static int dpu_encoder_virt_add_phys_encs(
return -EINVAL;
}
 
-   if (display_caps & MSM_DISPLAY_CAP_VID_MODE) {
+   if (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE) {
enc = dpu_encoder_phys_vid_init(params);
 
if (IS_ERR_OR_NULL(enc)) {
@@ -2122,7 +2122,7 @@ static int dpu_encoder_virt_add_phys_encs(
++dpu_enc->num_phys_encs;
}
 
-   if (display_caps & MSM_DISPLAY_CAP_CMD_MODE) {
+   if (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) {
enc = dpu_encoder_phys_cmd_init(params);
 
if (IS_ERR_OR_NULL(enc)) {
@@ -2135,6 +2135,19 @@ static int dpu_encoder_virt_add_phys_encs(
++dpu_enc->num_phys_encs;
}
 
+   if (disp_info->intf_type == DRM_MODE_ENCODER_VIRTUAL) {
+   enc = dpu_encoder_phys_wb_init(params);
+
+   if (IS_ERR_OR_NULL(enc)) {
+   DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n",
+   PTR_ERR(enc));
+   return enc == NULL ? -EINVAL : PTR_ERR(enc);
+   }
+
+   dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
+   ++dpu_enc->num_phys_encs;
+   }
+
if (params->split_role == ENC_ROLE_SLAVE)
dpu_enc->cur_slave = enc;
else
@@ -2233,9 +2246,8 @@ static int dpu_encoder_setup_display(struct 
dpu_encoder_virt *dpu_enc,
}
 
if (!ret) {
-   ret = 
dpu_encoder_virt_add_phys_encs(disp_info->capabilities,
-   
 dpu_enc,
-   
 &phys_params);
+   ret = dpu_encoder_virt_add_phys_encs(disp_info,
+   dpu_enc, &phys_params);
if (ret)
DPU_ERROR_ENC(dpu_enc, "failed to add phys 
encs\n");
}
@@ -2352,8 +2364,9 @@ struct drm_encoder *dpu_encoder_init(struct drm_device 
*dev,
if (!dpu_enc)
return ERR_PTR(-ENOMEM);
 
+
rc = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs,
-   drm_enc_mode, NULL);
+ drm_enc_mode, NULL);
if (rc) {
devm_kfree(dev->dev, dpu_enc);
return ERR_PTR(rc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index c683cab..0a50509 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark 
@@ -15,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "msm_drv.h"
 #include "msm_mmu.h"
@@ -29,6 +31,7 @@
 #include "dpu_kms.h"
 #include "dpu_plane.h"
 #include "dpu_vbif.h"
+#include "dpu_writeback.h"
 
 #define CREATE_TRACE_POINTS
 #include "dpu_trace.h"
@@ -648,6 +651,45 @@ static int _dpu_kms_initialize_displayport(struct 
drm_device *dev,
return 0;
 }
 
+static int _dpu_kms_initialize_writeback(struct drm_device *dev,
+   struct msm_drm_private *priv, struct dpu_kms *dpu_kms,
+   const u32 *wb_formats, int n_formats)
+{
+   struct drm_encoder *encoder = NULL;
+   struct msm

[PATCH v3 09/18] drm/msm/dpu: add changes to support writeback in hw_ctl

2022-04-20 Thread Abhinav Kumar
Add changes to support writeback module in the dpu_hw_ctl
interface.

changes in v3:
- read the intf_active and wb_active before writing
  to preserve existing bits
- add the update_pending_flush_wb for non-v1 targets

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 54 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 15 -
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 524f024..67522ab 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
  */
 
 #include 
@@ -23,10 +24,12 @@
 #define   CTL_SW_RESET  0x030
 #define   CTL_LAYER_EXTN_OFFSET 0x40
 #define   CTL_MERGE_3D_ACTIVE   0x0E4
+#define   CTL_WB_ACTIVE 0x0EC
 #define   CTL_INTF_ACTIVE   0x0F4
 #define   CTL_MERGE_3D_FLUSH0x100
 #define   CTL_DSC_ACTIVE0x0E8
 #define   CTL_DSC_FLUSH0x104
+#define   CTL_WB_FLUSH  0x108
 #define   CTL_INTF_FLUSH0x110
 #define   CTL_INTF_MASTER   0x134
 #define   CTL_FETCH_PIPE_ACTIVE 0x0FC
@@ -38,6 +41,7 @@
 #define  MERGE_3D_IDX   23
 #define  DSC_IDX22
 #define  INTF_IDX   31
+#define WB_IDX  16
 #define CTL_INVALID_BIT 0x
 #define CTL_DEFAULT_GROUP_ID   0xf
 
@@ -135,6 +139,9 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct 
dpu_hw_ctl *ctx)
if (ctx->pending_flush_mask & BIT(INTF_IDX))
DPU_REG_WRITE(&ctx->hw, CTL_INTF_FLUSH,
ctx->pending_intf_flush_mask);
+   if (ctx->pending_flush_mask & BIT(WB_IDX))
+   DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
+   ctx->pending_wb_flush_mask);
 
DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
 }
@@ -255,6 +262,26 @@ static void dpu_hw_ctl_update_pending_flush_intf(struct 
dpu_hw_ctl *ctx,
}
 }
 
+static void dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl *ctx,
+   enum dpu_wb wb)
+{
+   switch (wb) {
+   case WB_0:
+   case WB_1:
+   case WB_2:
+   ctx->pending_flush_mask |= BIT(WB_IDX);
+   default:
+   break;
+   }
+}
+
+static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
+   enum dpu_wb wb)
+{
+   ctx->pending_wb_flush_mask |= BIT(wb - WB_0);
+   ctx->pending_flush_mask |= BIT(WB_IDX);
+}
+
 static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx,
enum dpu_intf intf)
 {
@@ -504,6 +531,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
 {
struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 intf_active = 0;
+   u32 wb_active = 0;
u32 mode_sel = 0;
 
/* CTL_TOP[31:28] carries group_id to collate CTL paths
@@ -520,10 +548,18 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
mode_sel |= BIT(17);
 
intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
-   intf_active |= BIT(cfg->intf - INTF_0);
+   wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
+
+   if (cfg->intf)
+   intf_active |= BIT(cfg->intf - INTF_0);
+
+   if (cfg->wb)
+   wb_active |= BIT(cfg->wb - WB_0);
 
DPU_REG_WRITE(c, CTL_TOP, mode_sel);
DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
+   DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
+
if (cfg->merge_3d)
DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
  BIT(cfg->merge_3d - MERGE_3D_0));
@@ -546,6 +582,9 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
intf_cfg |= (cfg->mode_3d - 0x1) << 20;
}
 
+   if (cfg->wb)
+   intf_cfg |= (cfg->wb & 0x3) + 2;
+
switch (cfg->intf_mode_sel) {
case DPU_CTL_MODE_SEL_VID:
intf_cfg &= ~BIT(17);
@@ -568,12 +607,13 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct 
dpu_hw_ctl *ctx,
 {
struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 intf_active = 0;
+   u32 wb_active = 0;
u32 merge3d_active = 0;
 
/*
 * This API resets each portion of the CTL path namely,
 * clearing the sspps staged on the lm, merge_3d block,
-* interfaces etc to ensure clean teardown of the pipeline.
+* interfaces , writeback etc to ensure clean teardown of the pipeline.
 * This will be used for writeback to begin with to have a
 * proper teardown of th

[PATCH v3 15/18] drm/msm/dpu: add the writeback connector layer

2022-04-20 Thread Abhinav Kumar
Introduce the dpu_writeback module which serves as the
interface between dpu operations and the drm_writeback.

This module manages the connector related operations for
dpu writeback.

changes in v2:
- start using drm_writeback_connector_init_with_encoder()
- drop unnecessary arguments from dpu_writeback_init()
- rebase on msm-next tip and remove usage of priv->connectors

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/Makefile  |  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c | 68 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h | 25 ++
 3 files changed, 94 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 0387f22..66395ee 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -80,6 +80,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_plane.o \
disp/dpu1/dpu_rm.o \
disp/dpu1/dpu_vbif.o \
+   disp/dpu1/dpu_writeback.o
 
 msm-$(CONFIG_DRM_MSM_MDSS) += \
msm_mdss.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
new file mode 100644
index 000..526d884
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "dpu_writeback.h"
+
+static int dpu_wb_conn_get_modes(struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+
+   return drm_add_modes_noedid(connector, dev->mode_config.max_width,
+   dev->mode_config.max_height);
+}
+
+static const struct drm_connector_funcs dpu_wb_conn_funcs = {
+   .reset = drm_atomic_helper_connector_reset,
+   .fill_modes = drm_helper_probe_single_connector_modes,
+   .destroy = drm_connector_cleanup,
+   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int dpu_wb_conn_prepare_job(struct drm_writeback_connector *connector,
+   struct drm_writeback_job *job)
+{
+   if (!job->fb)
+   return 0;
+
+   dpu_encoder_prepare_wb_job(connector->encoder, job);
+
+   return 0;
+}
+
+static void dpu_wb_conn_cleanup_job(struct drm_writeback_connector *connector,
+   struct drm_writeback_job *job)
+{
+   if (!job->fb)
+   return;
+
+   dpu_encoder_cleanup_wb_job(connector->encoder, job);
+}
+
+static const struct drm_connector_helper_funcs dpu_wb_conn_helper_funcs = {
+   .get_modes = dpu_wb_conn_get_modes,
+   .prepare_writeback_job = dpu_wb_conn_prepare_job,
+   .cleanup_writeback_job = dpu_wb_conn_cleanup_job,
+};
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+   const u32 *format_list, u32 num_formats)
+{
+   struct dpu_wb_connector *dpu_wb_conn;
+   int rc = 0;
+
+   dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL);
+
+   drm_connector_helper_add(&dpu_wb_conn->base.base, 
&dpu_wb_conn_helper_funcs);
+
+   /* DPU initializes the encoder and sets it up completely for writeback
+* cases and hence should use the new API 
drm_writeback_connector_init_with_encoder
+* to initialize the writeback connector
+*/
+   rc = drm_writeback_connector_init_with_encoder(dev, &dpu_wb_conn->base, 
enc,
+   &dpu_wb_conn_funcs, format_list, num_formats);
+
+   return rc;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
new file mode 100644
index 000..05aff05
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DPU_WRITEBACK_H
+#define _DPU_WRITEBACK_H
+
+#include 
+#include 
+#include 
+#include 
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_encoder_phys.h"
+
+struct dpu_wb_connector {
+   struct drm_writeback_connector base;
+};
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+   const u32 *format_list, u32 num_formats);
+
+#endif /*_DPU_WRITEBACK_H */
-- 
2.7.4



[PATCH v3 07/18] drm/msm/dpu: add dpu_hw_wb abstraction for writeback blocks

2022-04-20 Thread Abhinav Kumar
Add the dpu_hw_wb abstraction to program registers related to the
writeback block. These will be invoked once all the configuration
is set and ready to be programmed to the registers.

changes in v3:
- start using the common struct dpu_hw_cdp_cfg
- leave a comment about DPU non-DPU_WB_QOS_8LVL chipsets

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/Makefile  |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 279 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 115 
 3 files changed, 395 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index d5ca2e6..ca779c1 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -74,6 +74,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_hw_top.o \
disp/dpu1/dpu_hw_util.o \
disp/dpu1/dpu_hw_vbif.o \
+   disp/dpu1/dpu_hw_wb.o \
disp/dpu1/dpu_kms.o \
disp/dpu1/dpu_plane.o \
disp/dpu1/dpu_rm.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
new file mode 100644
index 000..be2
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0-only
+ /*
+  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved
+  */
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_wb.h"
+#include "dpu_formats.h"
+#include "dpu_kms.h"
+
+#define WB_DST_FORMAT 0x000
+#define WB_DST_OP_MODE0x004
+#define WB_DST_PACK_PATTERN   0x008
+#define WB_DST0_ADDR  0x00C
+#define WB_DST1_ADDR  0x010
+#define WB_DST2_ADDR  0x014
+#define WB_DST3_ADDR  0x018
+#define WB_DST_YSTRIDE0   0x01C
+#define WB_DST_YSTRIDE1   0x020
+#define WB_DST_YSTRIDE1   0x020
+#define WB_DST_DITHER_BITDEPTH0x024
+#define WB_DST_MATRIX_ROW00x030
+#define WB_DST_MATRIX_ROW10x034
+#define WB_DST_MATRIX_ROW20x038
+#define WB_DST_MATRIX_ROW30x03C
+#define WB_DST_WRITE_CONFIG   0x048
+#define WB_ROTATION_DNSCALER  0x050
+#define WB_ROTATOR_PIPE_DOWNSCALER0x054
+#define WB_N16_INIT_PHASE_X_C03   0x060
+#define WB_N16_INIT_PHASE_X_C12   0x064
+#define WB_N16_INIT_PHASE_Y_C03   0x068
+#define WB_N16_INIT_PHASE_Y_C12   0x06C
+#define WB_OUT_SIZE   0x074
+#define WB_ALPHA_X_VALUE  0x078
+#define WB_DANGER_LUT 0x084
+#define WB_SAFE_LUT   0x088
+#define WB_QOS_CTRL   0x090
+#define WB_CREQ_LUT_0 0x098
+#define WB_CREQ_LUT_1 0x09C
+#define WB_UBWC_STATIC_CTRL   0x144
+#define WB_MUX0x150
+#define WB_CROP_CTRL  0x154
+#define WB_CROP_OFFSET0x158
+#define WB_CSC_BASE   0x260
+#define WB_DST_ADDR_SW_STATUS 0x2B0
+#define WB_CDP_CNTL   0x2B4
+#define WB_OUT_IMAGE_SIZE 0x2C0
+#define WB_OUT_XY 0x2C4
+
+/* WB_QOS_CTRL */
+#define WB_QOS_CTRL_DANGER_SAFE_ENBIT(0)
+
+static const struct dpu_wb_cfg *_wb_offset(enum dpu_wb wb,
+   const struct dpu_mdss_cfg *m, void __iomem *addr,
+   struct dpu_hw_blk_reg_map *b)
+{
+   int i;
+
+   for (i = 0; i < m->wb_count; i++) {
+   if (wb == m->wb[i].id) {
+   b->base_off = addr;
+   b->blk_off = m->wb[i].base;
+   b->length = m->wb[i].len;
+   b->hwversion = m->hwversion;
+   return &m->wb[i];
+   }
+   }
+   return ERR_PTR(-EINVAL);
+}
+
+static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx,
+   struct dpu_hw_wb_cfg *data)
+{
+   struct dpu_hw_blk_reg_map *c = &ctx->hw;
+
+   DPU_REG_WRITE(c, WB_DST0_ADDR, data->dest.plane_addr[0]);
+   DPU_REG_WRITE(c, WB_DST1_ADDR, data->dest.plane_addr[1]);
+   DPU_REG_WRITE(c, WB_DST2_ADDR, data->dest.plane_addr[2]);
+   DPU_REG_WRITE(c, WB_DST3_ADDR, data->dest.plane_addr[3]);
+}
+
+static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx,
+   struct dpu_hw_wb_cfg *data)
+{
+   struct dpu_hw_blk_reg_map *c = &ctx->hw;
+   const struct dpu_format *fmt = data->

[PATCH v3 10/18] drm/msm/dpu: add an API to reset the encoder related hw blocks

2022-04-20 Thread Abhinav Kumar
Add an API to reset the encoder related hw blocks to ensure
a proper teardown of the pipeline. At the moment this is being
used only for the writeback encoder but eventually we can start
using this for all interfaces.

changes in v3:
- none

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  | 82 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  7 ++
 2 files changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 4523693..0e31ad3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights 
reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark 
@@ -22,6 +23,7 @@
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_dspp.h"
 #include "dpu_hw_dsc.h"
+#include "dpu_hw_merge3d.h"
 #include "dpu_formats.h"
 #include "dpu_encoder_phys.h"
 #include "dpu_crtc.h"
@@ -1838,6 +1840,86 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
DPU_ATRACE_END("encoder_kickoff");
 }
 
+static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
+{
+   struct dpu_hw_mixer_cfg mixer;
+   int i, num_lm;
+   u32 flush_mask = 0;
+   struct dpu_global_state *global_state;
+   struct dpu_hw_blk *hw_lm[2];
+   struct dpu_hw_mixer *hw_mixer[2];
+   struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+
+   memset(&mixer, 0, sizeof(mixer));
+
+   /* reset all mixers for this encoder */
+   if (phys_enc->hw_ctl->ops.clear_all_blendstages)
+   phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl);
+
+   global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms);
+
+   num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, 
global_state,
+   phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, 
ARRAY_SIZE(hw_lm));
+
+   for (i = 0; i < num_lm; i++) {
+   hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]);
+   flush_mask = phys_enc->hw_ctl->ops.get_bitmask_mixer(ctl, 
hw_mixer[i]->idx);
+   if (phys_enc->hw_ctl->ops.update_pending_flush)
+   phys_enc->hw_ctl->ops.update_pending_flush(ctl, 
flush_mask);
+
+   /* clear all blendstages */
+   if (phys_enc->hw_ctl->ops.setup_blendstage)
+   phys_enc->hw_ctl->ops.setup_blendstage(ctl, 
hw_mixer[i]->idx, NULL);
+   }
+}
+
+void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
+{
+   struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+   struct dpu_hw_intf_cfg intf_cfg = { 0 };
+   int i;
+   struct dpu_encoder_virt *dpu_enc;
+
+   dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
+
+   phys_enc->hw_ctl->ops.reset(ctl);
+
+   dpu_encoder_helper_reset_mixers(phys_enc);
+
+   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+   if (dpu_enc->phys_encs[i] && 
phys_enc->hw_intf->ops.bind_pingpong_blk)
+   phys_enc->hw_intf->ops.bind_pingpong_blk(
+   dpu_enc->phys_encs[i]->hw_intf, false,
+   dpu_enc->phys_encs[i]->hw_pp->idx);
+
+   /* mark INTF flush as pending */
+   if (phys_enc->hw_ctl->ops.update_pending_flush_intf)
+   
phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl,
+   dpu_enc->phys_encs[i]->hw_intf->idx);
+   }
+
+   /* reset the merge 3D HW block */
+   if (phys_enc->hw_pp->merge_3d) {
+   
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
+   BLEND_3D_NONE);
+   if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d)
+   phys_enc->hw_ctl->ops.update_pending_flush_merge_3d(ctl,
+   phys_enc->hw_pp->merge_3d->idx);
+   }
+
+   intf_cfg.stream_sel = 0; /* Don't care value for video mode */
+   intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+   if (phys_enc->hw_pp->merge_3d)
+   intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
+
+   if (ctl->ops.reset_intf_cfg)
+   ctl->ops.reset_intf_cfg(ctl, &intf_cfg);
+
+   ctl->ops.trigger_flush(ctl);
+   ctl->ops.trigger_start(ctl);
+   ctl->ops.clear_pending_flush(ctl);
+}
+
 void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc)
 {
struct dpu_encoder_virt *dpu_enc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 706b566..544a9a4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_enc

[PATCH v3 08/18] drm/msm/dpu: add writeback blocks to DPU RM

2022-04-20 Thread Abhinav Kumar
Add writeback blocks to DPU resource manager so that
the encoders can directly request them through RM.

changes in v3:
- use IS_ERR() instead of IS_ERR_OR_NULL()

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 0e6634b..06f03e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -9,6 +9,7 @@
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_pingpong.h"
 #include "dpu_hw_intf.h"
+#include "dpu_hw_wb.h"
 #include "dpu_hw_dspp.h"
 #include "dpu_hw_merge3d.h"
 #include "dpu_hw_dsc.h"
@@ -87,6 +88,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
}
}
 
+   for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
+   dpu_hw_wb_destroy(rm->hw_wb[i]);
+
return 0;
 }
 
@@ -186,6 +190,24 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->hw_intf[intf->id - INTF_0] = hw;
}
 
+   for (i = 0; i < cat->wb_count; i++) {
+   struct dpu_hw_wb *hw;
+   const struct dpu_wb_cfg *wb = &cat->wb[i];
+
+   if (wb->id < WB_0 || wb->id >= WB_MAX) {
+   DPU_ERROR("skip intf %d with invalid id\n", wb->id);
+   continue;
+   }
+
+   hw = dpu_hw_wb_init(wb->id, mmio, cat);
+   if (IS_ERR(hw)) {
+   rc = PTR_ERR(hw);
+   DPU_ERROR("failed wb object creation: err %d\n", rc);
+   goto fail;
+   }
+   rm->hw_wb[wb->id - WB_0] = hw;
+   }
+
for (i = 0; i < cat->ctl_count; i++) {
struct dpu_hw_ctl *hw;
const struct dpu_ctl_cfg *ctl = &cat->ctl[i];
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 32e0d8a..ba82e54 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -19,6 +19,7 @@ struct dpu_global_state;
  * @mixer_blks: array of layer mixer hardware resources
  * @ctl_blks: array of ctl hardware resources
  * @hw_intf: array of intf hardware resources
+ * @hw_wb: array of wb hardware resources
  * @dspp_blks: array of dspp hardware resources
  */
 struct dpu_rm {
@@ -26,6 +27,7 @@ struct dpu_rm {
struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0];
struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
struct dpu_hw_intf *hw_intf[INTF_MAX - INTF_0];
+   struct dpu_hw_wb *hw_wb[WB_MAX - WB_0];
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
@@ -96,5 +98,15 @@ static inline struct dpu_hw_intf *dpu_rm_get_intf(struct 
dpu_rm *rm, enum dpu_in
return rm->hw_intf[intf_idx - INTF_0];
 }
 
+/**
+ * dpu_rm_get_wb - Return a struct dpu_hw_wb instance given it's index.
+ * @rm: DPU Resource Manager handle
+ * @wb_idx: WB index
+ */
+static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_intf 
wb_idx)
+{
+   return rm->hw_wb[wb_idx - WB_0];
+}
+
 #endif /* __DPU_RM_H__ */
 
-- 
2.7.4



[PATCH v3 06/18] drm/msm/dpu: rename dpu_hw_pipe_cdp_cfg to dpu_hw_cdp_cfg

2022-04-20 Thread Abhinav Kumar
Rename dpu_hw_pipe_cdp_cfg to dpu_hw_cdp_cfg and move it
to dpu_hw_utils file so that other modules in addition to
SSPP such as writeback can use it as all the fields can
be used by writeback as well.

Suggested-by: Dmitry Baryshkov 
Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 18 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 15 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  4 ++--
 4 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 09cdc35..0a0864d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -627,7 +627,7 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe 
*ctx,
 }
 
 static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cdp_cfg *cfg,
+   struct dpu_hw_cdp_cfg *cfg,
enum dpu_sspp_multirect_index index)
 {
u32 idx;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 92b071b..a81e166 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -193,22 +193,6 @@ enum {
 };
 
 /**
- * struct dpu_hw_pipe_cdp_cfg : CDP configuration
- * @enable: true to enable CDP
- * @ubwc_meta_enable: true to enable ubwc metadata preload
- * @tile_amortize_enable: true to enable amortization control for tile format
- * @preload_ahead: number of request to preload ahead
- * DPU_SSPP_CDP_PRELOAD_AHEAD_32,
- * DPU_SSPP_CDP_PRELOAD_AHEAD_64
- */
-struct dpu_hw_pipe_cdp_cfg {
-   bool enable;
-   bool ubwc_meta_enable;
-   bool tile_amortize_enable;
-   u32 preload_ahead;
-};
-
-/**
  * struct dpu_hw_pipe_ts_cfg - traffic shaper configuration
  * @size: size to prefill in bytes, or zero to disable
  * @time: time to prefill in usec, or zero to disable
@@ -359,7 +343,7 @@ struct dpu_hw_sspp_ops {
 * @index: rectangle index in multirect
 */
void (*setup_cdp)(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cdp_cfg *cfg,
+   struct dpu_hw_cdp_cfg *cfg,
enum dpu_sspp_multirect_index index);
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
index 3913475..a200df1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
@@ -298,6 +298,21 @@ struct dpu_drm_scaler_v2 {
struct dpu_drm_de_v1 de;
 };
 
+/**
+ * struct dpu_hw_cdp_cfg : CDP configuration
+ * @enable: true to enable CDP
+ * @ubwc_meta_enable: true to enable ubwc metadata preload
+ * @tile_amortize_enable: true to enable amortization control for tile format
+ * @preload_ahead: number of request to preload ahead
+ * DPU_*_CDP_PRELOAD_AHEAD_32,
+ * DPU_*_CDP_PRELOAD_AHEAD_64
+ */
+struct dpu_hw_cdp_cfg {
+   bool enable;
+   bool ubwc_meta_enable;
+   bool tile_amortize_enable;
+   u32 preload_ahead;
+};
 
 u32 *dpu_hw_util_get_log_mask_ptr(void);
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c77c3d9d..08b8c64 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1246,9 +1246,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
pstate->multirect_index);
 
if (pdpu->pipe_hw->ops.setup_cdp) {
-   struct dpu_hw_pipe_cdp_cfg cdp_cfg;
+   struct dpu_hw_cdp_cfg cdp_cfg;
 
-   memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
+   memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg));
 
cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg
[DPU_PERF_CDP_USAGE_RT].rd_enable;
-- 
2.7.4



[PATCH v3 14/18] drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback

2022-04-20 Thread Abhinav Kumar
Introduce the dpu_encoder_phys_* for the writeback interface
to handle writeback specific hardware programming.

changes in v3:
- start using the now generic struct dpu_hw_cdp_cfg

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/Makefile   |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |  30 +
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 751 +
 3 files changed, 782 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index ca779c1..0387f22 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -60,6 +60,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_encoder.o \
disp/dpu1/dpu_encoder_phys_cmd.o \
disp/dpu1/dpu_encoder_phys_vid.o \
+   disp/dpu1/dpu_encoder_phys_wb.o \
disp/dpu1/dpu_formats.o \
disp/dpu1/dpu_hw_catalog.o \
disp/dpu1/dpu_hw_ctl.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 00951f3..5452f98 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -150,6 +150,7 @@ struct dpu_encoder_phys_ops {
  * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
  * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
  * @INTR_IDX_RDPTR:Readpointer done unterrupt for cmd mode panel
+ * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
  */
 enum dpu_intr_idx {
INTR_IDX_VSYNC,
@@ -157,6 +158,7 @@ enum dpu_intr_idx {
INTR_IDX_UNDERRUN,
INTR_IDX_CTL_START,
INTR_IDX_RDPTR,
+   INTR_IDX_WB_DONE,
INTR_IDX_MAX,
 };
 
@@ -224,6 +226,27 @@ static inline int dpu_encoder_phys_inc_pending(struct 
dpu_encoder_phys *phys)
 }
 
 /**
+ * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to handle command
+ * mode specific operations
+ * @base:  Baseclass physical encoder structure
+ * @wbirq_refcount: Reference count of writeback interrupt
+ * @wb_done_timeout_cnt: number of wb done irq timeout errors
+ * @wb_cfg:  writeback block config to store fb related details
+ * @wb_conn: backpointer to writeback connector
+ * @wb_job: backpointer to current writeback job
+ * @dest:   dpu buffer layout for current writeback output buffer
+ */
+struct dpu_encoder_phys_wb {
+   struct dpu_encoder_phys base;
+   atomic_t wbirq_refcount;
+   int wb_done_timeout_cnt;
+   struct dpu_hw_wb_cfg wb_cfg;
+   struct drm_writeback_connector *wb_conn;
+   struct drm_writeback_job *wb_job;
+   struct dpu_hw_fmt_layout dest;
+};
+
+/**
  * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle 
command
  * mode specific operations
  * @base:  Baseclass physical encoder structure
@@ -291,6 +314,13 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
struct dpu_enc_phys_init_params *p);
 
 /**
+ * dpu_encoder_phys_wb_init - initialize writeback encoder
+ * @init:  Pointer to init info structure with initialization params
+ */
+struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
+   struct dpu_enc_phys_init_params *p);
+
+/**
  * dpu_encoder_helper_trigger_start - control start helper function
  * This helper function may be optionally specified by physical
  * encoders if they require ctl_start triggering.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
new file mode 100644
index 000..3261437
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -0,0 +1,751 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include 
+
+#include "dpu_encoder_phys.h"
+#include "dpu_formats.h"
+#include "dpu_hw_top.h"
+#include "dpu_hw_wb.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_blk.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_core_irq.h"
+#include "dpu_vbif.h"
+#include "dpu_crtc.h"
+#include "disp/msm_disp_snapshot.h"
+
+#define DEFAULT_MAX_WRITEBACK_WIDTH 2048
+
+#define to_dpu_encoder_phys_wb(x) \
+   container_of(x, struct dpu_encoder_phys_wb, base)
+
+/**
+ * dpu_encoder_phys_wb_is_master - report wb always as master encoder
+ */
+static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc)
+{
+   /* there is only one physical enc for dpu_writeback */
+   return true;
+}
+
+/**
+ * dpu_encoder_phys_wb_set_ot_limit - set OT limit for writeback interface
+ * @phys_enc:  Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_set_ot_limit(
+   struct dpu_encoder_phys *phys_enc)
+{
+   struct dpu_hw_wb *hw_w

[PATCH v3 04/18] drm/msm/dpu: add writeback blocks to the sm8250 DPU catalog

2022-04-20 Thread Abhinav Kumar
Add writeback blocks to the sm8250 DPU hardware catalog. Other
chipsets support writeback too but add it to sm8250 to prototype
the feature so that it can be easily extended to other chipsets.

changes in v3:
- none

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 74 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 66 ++-
 2 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index b0a0ef7..bcb5273 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
  */
 
 #define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__
@@ -120,6 +121,16 @@
  BIT(MDP_AD4_0_INTR) | \
  BIT(MDP_AD4_1_INTR))
 
+#define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \
+BIT(DPU_WB_UBWC) | \
+BIT(DPU_WB_YUV_CONFIG) | \
+BIT(DPU_WB_PIPE_ALPHA) | \
+BIT(DPU_WB_XY_ROI_OFFSET) | \
+BIT(DPU_WB_QOS) | \
+BIT(DPU_WB_QOS_8LVL) | \
+BIT(DPU_WB_CDP) | \
+BIT(DPU_WB_INPUT_CTRL))
+
 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
 #define DEFAULT_DPU_LINE_WIDTH 2048
 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH  2560
@@ -211,6 +222,40 @@ static const u32 rotation_v2_formats[] = {
/* TODO add formats after validation */
 };
 
+static const uint32_t wb2_formats[] = {
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_BGR565,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_RGBA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGBX,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_RGBA5551,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_RGBX5551,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_RGBA,
+   DRM_FORMAT_RGBX,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_BGR565,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_ABGR1555,
+   DRM_FORMAT_BGRA5551,
+   DRM_FORMAT_XBGR1555,
+   DRM_FORMAT_BGRX5551,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_XBGR,
+};
+
 /*
  * DPU sub blocks config
  */
@@ -448,6 +493,8 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = {
.reg_off = 0x2C4, .bit_off = 8},
.clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
.reg_off = 0x2BC, .bit_off = 20},
+   .clk_ctrls[DPU_CLK_CTRL_WB2] = {
+   .reg_off = 0x3B8, .bit_off = 24},
},
 };
 
@@ -1235,6 +1282,29 @@ static const struct dpu_intf_cfg qcm2290_intf[] = {
 };
 
 /*
+ * Writeback blocks config
+ */
+#define WB_BLK(_name, _id, _base, _features, _clk_ctrl, \
+   __xin_id, vbif_id, _reg, _wb_done_bit) \
+   { \
+   .name = _name, .id = _id, \
+   .base = _base, .len = 0x2c8, \
+   .features = _features, \
+   .format_list = wb2_formats, \
+   .num_formats = ARRAY_SIZE(wb2_formats), \
+   .clk_ctrl = _clk_ctrl, \
+   .xin_id = __xin_id, \
+   .vbif_idx = vbif_id, \
+   .maxlinewidth = DEFAULT_DPU_LINE_WIDTH, \
+   .intr_wb_done = DPU_IRQ_IDX(_reg, _wb_done_bit) \
+   }
+
+static const struct dpu_wb_cfg sm8250_wb[] = {
+   WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6,
+   VBIF_RT, MDP_SSPP_TOP0_INTR, 4),
+};
+
+/*
  * VBIF sub blocks config
  */
 /* VBIF QOS remap */
@@ -1832,6 +1902,8 @@ static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
.intf = sm8150_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
+   .wb_count = ARRAY_SIZE(sm8250_wb),
+   .wb = sm8250_wb,
.reg_dma_count = 1,
.dma_cfg = sm8250_regdma,
.perf = sm8250_perf_data,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp

[PATCH v3 02/18] drm: introduce drm_writeback_connector_init_with_encoder() API

2022-04-20 Thread Abhinav Kumar
For vendors drivers which pass an already allocated and
initialized encoder especially for cases where the encoder
hardware is shared OR the writeback encoder shares the resources
with the rest of the display pipeline introduce a new API,
drm_writeback_connector_init_with_encoder() which expects
an initialized encoder as a parameter and only sets up the
writeback connector.

changes in v4:
- removed the possible_crtcs part

changes in v5:
- reorder this change to come before in the series
  to avoid incorrect functionality in subsequent changes
- continue using struct drm_encoder instead of
  struct drm_encoder * and switch it in next change

changes in v6:
- remove drm_writeback_connector_setup() and instead
  directly call drm_writeback_connector_init_with_encoder()
- fix a drm_writeback_connector typo and function doc which
  incorrectly shows that the function accepts enc_helper_funcs
- pass encoder as a parameter explicitly to the new API
  for better readability

changes in v7:
- fix the function doc slightly as suggested by Liviu

Reviewed-by: Liviu Dudau 
Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/drm_writeback.c | 72 +
 include/drm/drm_writeback.h |  6 
 2 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index 9e0b845..92658ad 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -178,6 +178,62 @@ int drm_writeback_connector_init(struct drm_device *dev,
 const u32 *formats, int n_formats,
 u32 possible_crtcs)
 {
+   int ret = 0;
+
+   drm_encoder_helper_add(&wb_connector->encoder, enc_helper_funcs);
+
+   wb_connector->encoder.possible_crtcs = possible_crtcs;
+
+   ret = drm_encoder_init(dev, &wb_connector->encoder,
+  &drm_writeback_encoder_funcs,
+  DRM_MODE_ENCODER_VIRTUAL, NULL);
+   if (ret)
+   return ret;
+
+   ret = drm_writeback_connector_init_with_encoder(dev, wb_connector, 
&wb_connector->encoder,
+   con_funcs, formats, n_formats);
+
+   if (ret)
+   drm_encoder_cleanup(&wb_connector->encoder);
+
+   return ret;
+}
+EXPORT_SYMBOL(drm_writeback_connector_init);
+
+/**
+ * drm_writeback_connector_init_with_encoder - Initialize a writeback 
connector and its properties
+ * using the encoder which already assigned and initialized
+ *
+ * @dev: DRM device
+ * @wb_connector: Writeback connector to initialize
+ * @enc: handle to the already initialized drm encoder
+ * @con_funcs: Connector funcs vtable
+ * @formats: Array of supported pixel formats for the writeback engine
+ * @n_formats: Length of the formats array
+ *
+ * This function creates the writeback-connector-specific properties if they
+ * have not been already created, initializes the connector as
+ * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property
+ * values.
+ *
+ * This function assumes that the drm_writeback_connector's encoder has 
already been
+ * created and initialized before invoking this function.
+ *
+ * In addition, this function also assumes that callers of this API will manage
+ * assigning the encoder helper functions, possible_crtcs and any other encoder
+ * specific operation.
+ *
+ * Drivers should always use this function instead of drm_connector_init() to
+ * set up writeback connectors if they want to manage themselves the lifetime 
of the
+ * associated encoder.
+ *
+ * Returns: 0 on success, or a negative error code
+ */
+int drm_writeback_connector_init_with_encoder(struct drm_device *dev,
+   struct drm_writeback_connector *wb_connector, struct 
drm_encoder *enc,
+   const struct drm_connector_funcs *con_funcs, const u32 *formats,
+   int n_formats)
+{
struct drm_property_blob *blob;
struct drm_connector *connector = &wb_connector->base;
struct drm_mode_config *config = &dev->mode_config;
@@ -191,15 +247,6 @@ int drm_writeback_connector_init(struct drm_device *dev,
if (IS_ERR(blob))
return PTR_ERR(blob);
 
-   drm_encoder_helper_add(&wb_connector->encoder, enc_helper_funcs);
-
-   wb_connector->encoder.possible_crtcs = possible_crtcs;
-
-   ret = drm_encoder_init(dev, &wb_connector->encoder,
-  &drm_writeback_encoder_funcs,
-  DRM_MODE_ENCODER_VIRTUAL, NULL);
-   if (ret)
-   goto fail;
 
connector->interlace_allowed = 0;
 
@@ -208,8 +255,7 @@ int drm_writeback_connector_init(struct drm_device *dev,
if (ret)
goto connector_fail;
 
-   ret = drm_connector_attach_encoder(connector,
-  

[PATCH v3 03/18] drm: allow real encoder to be passed for drm_writeback_connector

2022-04-20 Thread Abhinav Kumar
For some vendor driver implementations, display hardware can
be shared between the encoder used for writeback and the physical
display.

In addition resources such as clocks and interrupts can
also be shared between writeback and the real encoder.

To accommodate such vendor drivers and hardware, allow
real encoder to be passed for drm_writeback_connector.

For existing clients, drm_writeback_connector_init() will use
an internal_encoder under the hood and hence no changes will
be needed.

changes in v7:
- move this change before the vc4 change in the series
  to minimize the changes to vendor drivers in drm core
  changes

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/drm_writeback.c | 18 --
 drivers/gpu/drm/vc4/vc4_txp.c   |  4 ++--
 include/drm/drm_writeback.h | 22 --
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index 92658ad..0538674 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -180,21 +180,21 @@ int drm_writeback_connector_init(struct drm_device *dev,
 {
int ret = 0;
 
-   drm_encoder_helper_add(&wb_connector->encoder, enc_helper_funcs);
+   drm_encoder_helper_add(&wb_connector->internal_encoder, 
enc_helper_funcs);
 
-   wb_connector->encoder.possible_crtcs = possible_crtcs;
+   wb_connector->internal_encoder.possible_crtcs = possible_crtcs;
 
-   ret = drm_encoder_init(dev, &wb_connector->encoder,
+   ret = drm_encoder_init(dev, &wb_connector->internal_encoder,
   &drm_writeback_encoder_funcs,
   DRM_MODE_ENCODER_VIRTUAL, NULL);
if (ret)
return ret;
 
-   ret = drm_writeback_connector_init_with_encoder(dev, wb_connector, 
&wb_connector->encoder,
-   con_funcs, formats, n_formats);
+   ret = drm_writeback_connector_init_with_encoder(dev, wb_connector,
+   &wb_connector->internal_encoder, con_funcs, formats, 
n_formats);
 
if (ret)
-   drm_encoder_cleanup(&wb_connector->encoder);
+   drm_encoder_cleanup(&wb_connector->internal_encoder);
 
return ret;
 }
@@ -239,6 +239,12 @@ int drm_writeback_connector_init_with_encoder(struct 
drm_device *dev,
struct drm_mode_config *config = &dev->mode_config;
int ret = create_writeback_properties(dev);
 
+   /*
+* Assign the encoder passed to this API to the wb_connector's encoder.
+* For drm_writeback_connector_init(), this shall be the 
internal_encoder
+*/
+   wb_connector->encoder = enc;
+
if (ret != 0)
return ret;
 
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index 3447eb6..7e063a9 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -159,7 +159,7 @@ struct vc4_txp {
 
 static inline struct vc4_txp *encoder_to_vc4_txp(struct drm_encoder *encoder)
 {
-   return container_of(encoder, struct vc4_txp, connector.encoder);
+   return container_of(encoder, struct vc4_txp, 
connector.internal_encoder);
 }
 
 static inline struct vc4_txp *connector_to_vc4_txp(struct drm_connector *conn)
@@ -507,7 +507,7 @@ static int vc4_txp_bind(struct device *dev, struct device 
*master, void *data)
if (ret)
return ret;
 
-   encoder = &txp->connector.encoder;
+   encoder = txp->connector.encoder;
encoder->possible_crtcs = drm_crtc_mask(crtc);
 
ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0,
diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
index bb306fa..3fbae9d 100644
--- a/include/drm/drm_writeback.h
+++ b/include/drm/drm_writeback.h
@@ -25,13 +25,31 @@ struct drm_writeback_connector {
struct drm_connector base;
 
/**
-* @encoder: Internal encoder used by the connector to fulfill
+* @encoder: handle to drm_encoder used by the connector to fulfill
 * the DRM framework requirements. The users of the
 * @drm_writeback_connector control the behaviour of the @encoder
 * by passing the @enc_funcs parameter to drm_writeback_connector_init()
 * function.
+*
+* For some vendor drivers, the hardware resources are shared between
+* writeback encoder and rest of the display pipeline.
+* To accommodate such cases, encoder is a handle to the real encoder
+* hardware.
+*
+* For current existing writeback users, this shall continue to be the
+* embedded encoder for the writeback connector.
+*/
+   struct drm_encoder *encoder;
+
+   /**
+* @internal_encoder: internal encoder used by writeback when
+* drm_writeback_connector_init() is used.
+* @encoder will be assigned to this for those cases
+

[PATCH v3 00/18] Add writeback block support for DPU

2022-04-20 Thread Abhinav Kumar
This series adds support for writeback block on DPU. Writeback
block is extremely useful to validate boards having no physical displays
in addition to many other use-cases where we want to get the output
of the display pipeline to examine whether issue is with the display
pipeline or with the panel.

These changes have been validated on SM8250 RB5 boards with IGT KMS
writeback test-suite thereby further increasing the IGT test coverage
for DPU. I am sharing the test results below.

root@linaro-developer:~/igt_repo/igt-gpu-tools/build/tests# ./kms_writeback
[   35.066157] Console: switching to colour dummy device 80x25
[   35.071964] [IGT] kms_writeback: executing
IGT-Version: 1.26-gae2eb9e1 (aarch64) (Linux: 5.16.0-rc2-62171-g132577e2697b 
aarch64)
[   35.611418] [IGT] kms_writeback: starting subtest writeback-pixel-formats
Starting subtest: writeback-pixel-formats
[   35.618528] [IGT] kms_writeback: starting subtest 
writeback-invalid-parameters
Subtest writeback-pixel-formats: SUCCESS (0.000s)
Starting subtest: writeback-invalid-parameters
Subtest writeback-invalid-parameters: SUCCESS (0.028s)   35.657437] [IGT] 
kms_writeback: starting subtest writeback-fb-id
Starting subtest: writeback-fb-id
Subtest writeback-fb-id: SUCCESS (0.030s)
[   35.698957] [IGT] kms_writeback: starting subtest writeback-check-output
Starting subtest: writeback-check-output
[   35.852834] [IGT] kms_writeback: exiting, ret=0
Subtest writeback-check-output: SUCCESS (0.142s)
[   35.861291] Console: switching to colour frame buffer device 240x67
root@linaro-developer:~/igt_repo/igt-gpu-tools/build/tests# 

The changes can easily be extended to support any other chipset using
the DPU driver by adding the support in the catalog.

Writeback block supports various formats and features. The support
for all of them can be incrementally added on top of this framework when
validation is improved and the test frameworks are extended to validate
them.

changes in v3:
- unify plane and wb struct
- leave fixme and to-do comments for pending changes

Abhinav Kumar (18):
  drm: allow passing possible_crtcs to drm_writeback_connector_init()
  drm: introduce drm_writeback_connector_init_with_encoder() API
  drm: allow real encoder to be passed for drm_writeback_connector
  drm/msm/dpu: add writeback blocks to the sm8250 DPU catalog
  drm/msm/dpu: add reset_intf_cfg operation for dpu_hw_ctl
  drm/msm/dpu: rename dpu_hw_pipe_cdp_cfg to dpu_hw_cdp_cfg
  drm/msm/dpu: add dpu_hw_wb abstraction for writeback blocks
  drm/msm/dpu: add writeback blocks to DPU RM
  drm/msm/dpu: add changes to support writeback in hw_ctl
  drm/msm/dpu: add an API to reset the encoder related hw blocks
  drm/msm/dpu: make changes to dpu_encoder to support virtual encoder
  drm/msm/dpu: add encoder operations to prepare/cleanup wb job
  drm/msm/dpu: move _dpu_plane_get_qos_lut to dpu_hw_util file
  drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback
  drm/msm/dpu: add the writeback connector layer
  drm/msm/dpu: initialize dpu encoder and connector for writeback
  drm/msm/dpu: gracefully handle null fb commits for writeback
  drm/msm/dpu: add writeback blocks to the display snapshot

 .../drm/arm/display/komeda/komeda_wb_connector.c   |   4 +-
 drivers/gpu/drm/arm/malidp_mw.c|   4 +-
 drivers/gpu/drm/drm_writeback.c|  79 ++-
 drivers/gpu/drm/msm/Makefile   |   3 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   |   9 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 230 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h|  22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |  46 ++
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 763 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  74 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  66 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c |  84 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h |  23 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c|   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h|  18 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c|  25 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h|  19 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c  | 279 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h  | 115 
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|  63 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  |  31 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c |  22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  12 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c  |  68 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h  |  25 +
 drivers/gpu/drm/rcar-du/rcar_du_writeback.c|   4 +-
 drivers/gpu/drm/vc4/vc4_txp.c  |   7 +-
 drivers/gpu/drm/vkms/vkms_writeback.c  |   4 +-
 include/drm/drm_writeback.h|  31 +-
 29 files

[PATCH v3 01/18] drm: allow passing possible_crtcs to drm_writeback_connector_init()

2022-04-20 Thread Abhinav Kumar
Clients of drm_writeback_connector_init() initialize the
possible_crtcs and then invoke the call to this API.

To simplify things, allow passing possible_crtcs as a parameter
to drm_writeback_connector_init() and make changes to the
other drm drivers to make them compatible with this change.

changes in v2:
- split the changes according to their functionality

changes in v3:
- allow passing possible_crtcs for existing users of
  drm_writeback_connector_init()
- squash the vendor changes into the same commit so
  that each patch in the series can compile individually

changes in v4:
- keep only changes related to possible_crtcs
- add line breaks after ARRAY_SIZE
- stop using temporary variables for possible_crtcs

changes in v5:
- None

changes in v6:
- None

changes in v7:
- wrap long lines to match the coding style of existing drivers
- Fix indentation and remove parenthesis where not needed
- use u32 instead of uint32_t for possible_crtcs

Signed-off-by: Abhinav Kumar 
Acked-by: Liviu Dudau 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c | 4 ++--
 drivers/gpu/drm/arm/malidp_mw.c  | 4 ++--
 drivers/gpu/drm/drm_writeback.c  | 7 ++-
 drivers/gpu/drm/rcar-du/rcar_du_writeback.c  | 4 ++--
 drivers/gpu/drm/vc4/vc4_txp.c| 3 ++-
 drivers/gpu/drm/vkms/vkms_writeback.c| 4 ++--
 include/drm/drm_writeback.h  | 3 ++-
 7 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index e465cc4..ce4b760 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -155,7 +155,6 @@ static int komeda_wb_connector_add(struct komeda_kms_dev 
*kms,
kwb_conn->wb_layer = kcrtc->master->wb_layer;
 
wb_conn = &kwb_conn->base;
-   wb_conn->encoder.possible_crtcs = BIT(drm_crtc_index(&kcrtc->base));
 
formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,
   kwb_conn->wb_layer->layer_type,
@@ -164,7 +163,8 @@ static int komeda_wb_connector_add(struct komeda_kms_dev 
*kms,
err = drm_writeback_connector_init(&kms->base, wb_conn,
   &komeda_wb_connector_funcs,
   &komeda_wb_encoder_helper_funcs,
-  formats, n_formats);
+  formats, n_formats,
+  BIT(drm_crtc_index(&kcrtc->base)));
komeda_put_fourcc_list(formats);
if (err) {
kfree(kwb_conn);
diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index f5847a7..204c869 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -212,7 +212,6 @@ int malidp_mw_connector_init(struct drm_device *drm)
if (!malidp->dev->hw->enable_memwrite)
return 0;
 
-   malidp->mw_connector.encoder.possible_crtcs = 1 << 
drm_crtc_index(&malidp->crtc);
drm_connector_helper_add(&malidp->mw_connector.base,
 &malidp_mw_connector_helper_funcs);
 
@@ -223,7 +222,8 @@ int malidp_mw_connector_init(struct drm_device *drm)
ret = drm_writeback_connector_init(drm, &malidp->mw_connector,
   &malidp_mw_connector_funcs,
   &malidp_mw_encoder_helper_funcs,
-  formats, n_formats);
+  formats, n_formats,
+  1 << drm_crtc_index(&malidp->crtc));
kfree(formats);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index dccf4504..9e0b845 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -157,6 +157,7 @@ static const struct drm_encoder_funcs 
drm_writeback_encoder_funcs = {
  * @enc_helper_funcs: Encoder helper funcs vtable to be used by the internal 
encoder
  * @formats: Array of supported pixel formats for the writeback engine
  * @n_formats: Length of the formats array
+ * @possible_crtcs: possible crtcs for the internal writeback encoder
  *
  * This function creates the writeback-connector-specific properties if they
  * have not been already created, initializes the connector as
@@ -174,7 +175,8 @@ int drm_writeback_connector_init(struct drm_device *dev,
 struct drm_writeback_connector *wb_connector,
 const struct drm_connector_funcs *con_funcs,
  

Re: [PATCH 1/2] Revert "drm: of: Properly try all possible cases for bridge/panel detection"

2022-04-20 Thread Bjorn Andersson
On Wed 20 Apr 16:12 PDT 2022, Bjorn Andersson wrote:

Sorry, I missed Jagan and Linus, author and reviewer of the reverted
patch 2, among the recipients.

Regards,
Bjorn

> Commit '80253168dbfd ("drm: of: Lookup if child node has panel or
> bridge")' introduced the ability to describe a panel under a display
> controller without having to use a graph to connect the controller to
> its single child panel (or bridge).
> 
> The implementation of this would find the first non-graph node and
> attempt to acquire the related panel or bridge. This prevents cases
> where any other child node, such as a aux bus for a DisplayPort
> controller, or an opp-table to find the referenced panel.
> 
> Commit '67bae5f28c89 ("drm: of: Properly try all possible cases for
> bridge/panel detection")' attempted to solve this problem by not
> bypassing the graph reference lookup before attempting to find the panel
> or bridge.
> 
> While this does solve the case where a proper graph reference is
> present, it does not allow the caller to distinguish between a
> yet-to-be-probed panel or bridge and the absence of a reference to a
> panel.
> 
> One such case is a DisplayPort controller that on some boards have an
> explicitly described reference to a panel, but on others have a
> discoverable DisplayPort display attached (which doesn't need to be
> expressed in DeviceTree).
> 
> This reverts commit '67bae5f28c89 ("drm: of: Properly try all possible
> cases for bridge/panel detection")', as a step towards reverting commit
> '80253168dbfd ("drm: of: Lookup if child node has panel or bridge")'.
> 
> Signed-off-by: Bjorn Andersson 
> ---
>  drivers/gpu/drm/drm_of.c | 99 
>  1 file changed, 49 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index f4df344509a8..026e4e29a0f3 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -214,29 +214,6 @@ int drm_of_encoder_active_endpoint(struct device_node 
> *node,
>  }
>  EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
>  
> -static int find_panel_or_bridge(struct device_node *node,
> - struct drm_panel **panel,
> - struct drm_bridge **bridge)
> -{
> - if (panel) {
> - *panel = of_drm_find_panel(node);
> - if (!IS_ERR(*panel))
> - return 0;
> -
> - /* Clear the panel pointer in case of error. */
> - *panel = NULL;
> - }
> -
> - /* No panel found yet, check for a bridge next. */
> - if (bridge) {
> - *bridge = of_drm_find_bridge(node);
> - if (*bridge)
> - return 0;
> - }
> -
> - return -EPROBE_DEFER;
> -}
> -
>  /**
>   * drm_of_find_panel_or_bridge - return connected panel or bridge device
>   * @np: device tree node containing encoder output ports
> @@ -259,44 +236,66 @@ int drm_of_find_panel_or_bridge(const struct 
> device_node *np,
>   struct drm_panel **panel,
>   struct drm_bridge **bridge)
>  {
> - struct device_node *node;
> - int ret;
> + int ret = -EPROBE_DEFER;
> + struct device_node *remote;
>  
>   if (!panel && !bridge)
>   return -EINVAL;
> -
>   if (panel)
>   *panel = NULL;
> - if (bridge)
> - *bridge = NULL;
> -
> - /* Check for a graph on the device node first. */
> - if (of_graph_is_present(np)) {
> - node = of_graph_get_remote_node(np, port, endpoint);
> - if (node) {
> - ret = find_panel_or_bridge(node, panel, bridge);
> - of_node_put(node);
> -
> - if (!ret)
> - return 0;
> - }
> - }
>  
> - /* Otherwise check for any child node other than port/ports. */
> - for_each_available_child_of_node(np, node) {
> - if (of_node_name_eq(node, "port") ||
> - of_node_name_eq(node, "ports"))
> + /**
> +  * Devices can also be child nodes when we also control that device
> +  * through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).
> +  *
> +  * Lookup for a child node of the given parent that isn't either port
> +  * or ports.
> +  */
> + for_each_available_child_of_node(np, remote) {
> + if (of_node_name_eq(remote, "port") ||
> + of_node_name_eq(remote, "ports"))
>   continue;
>  
> - ret = find_panel_or_bridge(node, panel, bridge);
> - of_node_put(node);
> + goto of_find_panel_or_bridge;
> + }
> +
> + /*
> +  * of_graph_get_remote_node() produces a noisy error message if port
> +  * node isn't found and the absence of the port is a legit case here,
> +  * so at first we silently check whether graph presents in the
> +  * device-tree node.
> 

[PATCH 2/2] Revert "drm: of: Lookup if child node has panel or bridge"

2022-04-20 Thread Bjorn Andersson
Commit '80253168dbfd ("drm: of: Lookup if child node has panel or
bridge")' attempted to simplify the case of expressing a simple panel
under a DSI controller, by assuming that the first non-graph child node
was a panel or bridge.

Unfortunately for non-trivial cases the first child node might not be a
panel or bridge.  Examples of this can be a aux-bus in the case of
DisplayPort, or an opp-table represented before the panel node.

In these cases the reverted commit prevents the caller from ever finding
a reference to the panel.

This reverts commit '80253168dbfd ("drm: of: Lookup if child node has
panel or bridge")', in favor of using an explicit graph reference to the
panel in the trivial case as well.

Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/drm_of.c | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 026e4e29a0f3..9a2cfab3a177 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -244,21 +244,6 @@ int drm_of_find_panel_or_bridge(const struct device_node 
*np,
if (panel)
*panel = NULL;
 
-   /**
-* Devices can also be child nodes when we also control that device
-* through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).
-*
-* Lookup for a child node of the given parent that isn't either port
-* or ports.
-*/
-   for_each_available_child_of_node(np, remote) {
-   if (of_node_name_eq(remote, "port") ||
-   of_node_name_eq(remote, "ports"))
-   continue;
-
-   goto of_find_panel_or_bridge;
-   }
-
/*
 * of_graph_get_remote_node() produces a noisy error message if port
 * node isn't found and the absence of the port is a legit case here,
@@ -269,8 +254,6 @@ int drm_of_find_panel_or_bridge(const struct device_node 
*np,
return -ENODEV;
 
remote = of_graph_get_remote_node(np, port, endpoint);
-
-of_find_panel_or_bridge:
if (!remote)
return -ENODEV;
 
-- 
2.35.1



[PATCH 1/2] Revert "drm: of: Properly try all possible cases for bridge/panel detection"

2022-04-20 Thread Bjorn Andersson
Commit '80253168dbfd ("drm: of: Lookup if child node has panel or
bridge")' introduced the ability to describe a panel under a display
controller without having to use a graph to connect the controller to
its single child panel (or bridge).

The implementation of this would find the first non-graph node and
attempt to acquire the related panel or bridge. This prevents cases
where any other child node, such as a aux bus for a DisplayPort
controller, or an opp-table to find the referenced panel.

Commit '67bae5f28c89 ("drm: of: Properly try all possible cases for
bridge/panel detection")' attempted to solve this problem by not
bypassing the graph reference lookup before attempting to find the panel
or bridge.

While this does solve the case where a proper graph reference is
present, it does not allow the caller to distinguish between a
yet-to-be-probed panel or bridge and the absence of a reference to a
panel.

One such case is a DisplayPort controller that on some boards have an
explicitly described reference to a panel, but on others have a
discoverable DisplayPort display attached (which doesn't need to be
expressed in DeviceTree).

This reverts commit '67bae5f28c89 ("drm: of: Properly try all possible
cases for bridge/panel detection")', as a step towards reverting commit
'80253168dbfd ("drm: of: Lookup if child node has panel or bridge")'.

Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/drm_of.c | 99 
 1 file changed, 49 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index f4df344509a8..026e4e29a0f3 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -214,29 +214,6 @@ int drm_of_encoder_active_endpoint(struct device_node 
*node,
 }
 EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
 
-static int find_panel_or_bridge(struct device_node *node,
-   struct drm_panel **panel,
-   struct drm_bridge **bridge)
-{
-   if (panel) {
-   *panel = of_drm_find_panel(node);
-   if (!IS_ERR(*panel))
-   return 0;
-
-   /* Clear the panel pointer in case of error. */
-   *panel = NULL;
-   }
-
-   /* No panel found yet, check for a bridge next. */
-   if (bridge) {
-   *bridge = of_drm_find_bridge(node);
-   if (*bridge)
-   return 0;
-   }
-
-   return -EPROBE_DEFER;
-}
-
 /**
  * drm_of_find_panel_or_bridge - return connected panel or bridge device
  * @np: device tree node containing encoder output ports
@@ -259,44 +236,66 @@ int drm_of_find_panel_or_bridge(const struct device_node 
*np,
struct drm_panel **panel,
struct drm_bridge **bridge)
 {
-   struct device_node *node;
-   int ret;
+   int ret = -EPROBE_DEFER;
+   struct device_node *remote;
 
if (!panel && !bridge)
return -EINVAL;
-
if (panel)
*panel = NULL;
-   if (bridge)
-   *bridge = NULL;
-
-   /* Check for a graph on the device node first. */
-   if (of_graph_is_present(np)) {
-   node = of_graph_get_remote_node(np, port, endpoint);
-   if (node) {
-   ret = find_panel_or_bridge(node, panel, bridge);
-   of_node_put(node);
-
-   if (!ret)
-   return 0;
-   }
-   }
 
-   /* Otherwise check for any child node other than port/ports. */
-   for_each_available_child_of_node(np, node) {
-   if (of_node_name_eq(node, "port") ||
-   of_node_name_eq(node, "ports"))
+   /**
+* Devices can also be child nodes when we also control that device
+* through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).
+*
+* Lookup for a child node of the given parent that isn't either port
+* or ports.
+*/
+   for_each_available_child_of_node(np, remote) {
+   if (of_node_name_eq(remote, "port") ||
+   of_node_name_eq(remote, "ports"))
continue;
 
-   ret = find_panel_or_bridge(node, panel, bridge);
-   of_node_put(node);
+   goto of_find_panel_or_bridge;
+   }
+
+   /*
+* of_graph_get_remote_node() produces a noisy error message if port
+* node isn't found and the absence of the port is a legit case here,
+* so at first we silently check whether graph presents in the
+* device-tree node.
+*/
+   if (!of_graph_is_present(np))
+   return -ENODEV;
+
+   remote = of_graph_get_remote_node(np, port, endpoint);
+
+of_find_panel_or_bridge:
+   if (!remote)
+   return -ENODEV;
+
+   if (panel) {
+   *panel = of_drm_find_panel(remot

Re: [PATCH] WIP: drm/dp_mst: Add support for dumping topology ref histories from debugfs

2022-04-20 Thread Lyude Paul
Hey! Figured I'd check if there's been any status updates here since it's been
a while, just to make sure I haven't dropped this issue from my radar. No
problem if you're busy :)

On Wed, 2022-03-16 at 10:46 +, Lin, Wayne wrote:
> [Public]
> 
> > -Original Message-
> > From: Lyude Paul 
> > Sent: Wednesday, March 16, 2022 8:48 AM
> > To: Lin, Wayne 
> > Cc: dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org
> > Subject: Re: [PATCH] WIP: drm/dp_mst: Add support for dumping topology ref
> > histories from debugfs
> > 
> > (Adding this back to the dri-devel mailing list since I didn't notice it
> > got
> > dropped from there)
> > 
> > Hm, some comments on this issue down below. Sorry for the delayed
> > response, I
> > was going to try this right after I finished the MST legacy removal but
> > that's
> > ending up taking longer than I hoped.
> > 
> > On Tue, 2022-03-08 at 01:46 +, Lin, Wayne wrote:
> > > [AMD Official Use Only]
> > > 
> > > Oops...
> > > I didn't notice that I replied to wrong mail previously : P
> > > Sorry for the confusion and reply to the correct thread.
> > > 
> > > Good day!
> > > I probably know why you can't reproduce the issue there. Please refer to
> > > the
> > > attached
> > > patch file which makes me easier to explain this.
> > > 
> > > In dm_dp_mst_get_modes(), we will create a new dc_sink by calling
> > > dc_link_add_remote_sink() and add that dc_sink into the array dc_link-
> > > > remote_sinks[].
> > > However, if we find that aconnector->dc_sink is not null, then we won't
> > > create a new
> > > dc_sink for that aconnector and won't add the sink to the array dc_link-
> > > > remote_sinks[].
> > > 
> > > When the issue that I mentioned before occurs, we won't be able to
> > > release
> > > the dc_sink
> > > for the aconnector when we unplug the sst monitor. Hence, we can't
> > > create
> > > new dc_sink
> > > for the latter on connected new stream sink of that port. Which leads to
> > > two
> > > issues
> > > 1. Unplug monitor and plug in another monitor "to the same port"
> > > =>  Since we use the same dc_sink to reflect the capability of the new
> > > connected stream
> > > sink, we might send out inappropriate stream to the new connected sink.
> > > 2. Because we can't release dc_sink in the array dc_link-
> > > >remote_sinks[],
> > > when we
> > > plug/unplug sst monitor to more than 4 different mst port, we will break
> > > the
> > > criteria
> > > "dc_link->sink_count >= MAX_SINKS_PER_LINK" in
> > > link_add_remote_sink_helper().
> > 
> > Ok, a lot of this seems to be happening in amdgpu which certainly explains
> > why
> > I had so much trouble following along with this originally (also, having
> > learned a bit more about how DC works definitely has helped a bit). I
> > already
> > see a bunch of issues though with how this code is structured that would
> > definitely break things, though note I haven't sat down and tried this on
> > a
> > real machine yet - will try tomorrow.
> > 
> > So - it seems like dc_sink == a bunch of hotplugging state for a dm
> > connector,
> > which actually tells me for one that this is definitely the wrong spot for
> > this code. get_modes() really should just handle filling out DRM modes and
> > pretty much nothing else, because callers from DRM aren't going to expect
> > side-effects like this when get_modes() is called - which could
> > potentially
> > lead to all sorts of weirdness down the line if the DRM call paths that
> > use
> > this ever change. i915 and nouveau have good examples of what these
> > functions
> > should typically look like, and amdgpu actually seems to mostly follow
> > this
> > advice for it's other get_modes() callback.
> > 
> > Note there's also another problem here: the assumption "no EDID ==
> > disconnected" isn't correct. It's totally possible to run into EDID-less
> > displays if the display is some ancient pre-historic relic, or if the ROM
> > (or
> > EEPROM? can't remember what type of chip computer displays tend to use...)
> > chip
> > in the monitor containing the EDID has died. Note that the second
> > situation is
> > suprisingly more common then one might think! I ran into a 140Hz 4k ASUS
> > display where this happened, and I know another friend of mine who had the
> > ROM
> > in their display die randomly as well.
> > 
> > So with this being said: I, think the solution here is actually just to
> > add/remove dc_sink from dm_dp_mst_detect() based on the CSN, and drop the
> > calls from get_modes()? detect() should always be called before the
> > connector
> > has been removed, and we could use the return status from
> > drm_dp_mst_detect_port() in order to tell whether or not we should
> > add/remove
> > the dc_sink.
> 
> Thank you Lyude for guiding me through! After your elaboration, I think I
> roughly
> know the idea from drm perspective now. Let me get through this and will get
> back
> to you.
> 
> > 
> > If you don't get to it first tomorrow, I'll see if I can 

Re: [PATCH v2] drm/msm/dp: enhance both connect and disconnect pending_timeout handle

2022-04-20 Thread Stephen Boyd
Quoting Kuogee Hsieh (2022-04-15 17:06:48)
>
> On 4/14/2022 4:34 PM, Dmitry Baryshkov wrote:
> >
> > I'm not sure how should the driver react if the client doesn't disable
> > the output, but then the sink gets reattached?
>
> I do not know that either.
>
> But it should not happen as long as framework response to uevent.

In talking with seanpaul@ it sounds like we can update the link status
to BAD with drm_connector_set_link_status_property() and then put it
back to GOOD when the link is re-established. This way userspace will
know it needs to retry the modeset. Does that help here?


Re: [RFC v2 1/2] drm/doc/rfc: VM_BIND feature design document

2022-04-20 Thread Niranjana Vishwanathapura

On Thu, Mar 31, 2022 at 01:37:08PM +0200, Daniel Vetter wrote:

One thing I've forgotten, since it's only hinted at here: If/when we
switch tlb flushing from the current dumb&synchronous implementation
we now have in i915 in upstream to one with batching using dma_fence,
then I think that should be something which is done with a small
helper library of shared code too. The batching is somewhat tricky,
and you need to make sure you put the fence into the right
dma_resv_usage slot, and the trick with replace the vm fence with a
tlb flush fence is also a good reason to share the code so we only
have it one.

Christian's recent work also has some prep work for this already with
the fence replacing trick.


Sure, but this optimization is not required for initial vm_bind support
to land right? We can look at it soon after that. Is that ok?
I have made a reference to this TLB flush batching work in the rst file.

Niranjana


-Daniel

On Thu, 31 Mar 2022 at 10:28, Daniel Vetter  wrote:

Adding a pile of people who've expressed interest in vm_bind for their
drivers.

Also note to the intel folks: This is largely written with me having my
subsystem co-maintainer hat on, i.e. what I think is the right thing to do
here for the subsystem at large. There is substantial rework involved
here, but it's not any different from i915 adopting ttm or i915 adpoting
drm/sched, and I do think this stuff needs to happen in one form or
another.

On Mon, Mar 07, 2022 at 12:31:45PM -0800, Niranjana Vishwanathapura wrote:
> VM_BIND design document with description of intended use cases.
>
> Signed-off-by: Niranjana Vishwanathapura 
> ---
>  Documentation/gpu/rfc/i915_vm_bind.rst | 210 +
>  Documentation/gpu/rfc/index.rst|   4 +
>  2 files changed, 214 insertions(+)
>  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.rst
>
> diff --git a/Documentation/gpu/rfc/i915_vm_bind.rst 
b/Documentation/gpu/rfc/i915_vm_bind.rst
> new file mode 100644
> index ..cdc6bb25b942
> --- /dev/null
> +++ b/Documentation/gpu/rfc/i915_vm_bind.rst
> @@ -0,0 +1,210 @@
> +==
> +I915 VM_BIND feature design and use cases
> +==
> +
> +VM_BIND feature
> +
> +DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
> +objects (BOs) or sections of a BOs at specified GPU virtual addresses on
> +a specified address space (VM).
> +
> +These mappings (also referred to as persistent mappings) will be persistent
> +across multiple GPU submissions (execbuff) issued by the UMD, without user
> +having to provide a list of all required mappings during each submission
> +(as required by older execbuff mode).
> +
> +VM_BIND ioctl deferes binding the mappings until next execbuff submission
> +where it will be required, or immediately if I915_GEM_VM_BIND_IMMEDIATE
> +flag is set (useful if mapping is required for an active context).

So this is a screw-up I've done, and for upstream I think we need to fix
it: Implicit sync is bad, and it's also still a bad idea for vm_bind, and
I was wrong suggesting we should do this a few years back when we kicked
this off internally :-(

What I think we need is just always VM_BIND_IMMEDIATE mode, and then a few
things on top:
- in and out fences, like with execbuf, to allow userspace to sync with
  execbuf as needed
- for compute-mode context this means userspace memory fences
- for legacy context this means a timeline syncobj in drm_syncobj

No sync_file or anything else like this at all. This means a bunch of
work, but also it'll have benefits because it means we should be able to
use exactly the same code paths and logic for both compute and for legacy
context, because drm_syncobj support future fence semantics.

Also on the implementation side we still need to install dma_fence to the
various dma_resv, and for this we need the new dma_resv_usage series from
Christian König first. vm_bind fences can then use the USAGE_BOOKKEEPING
flag to make sure they never result in an oversync issue with execbuf. I
don't think trying to land vm_bind without that prep work in
dma_resv_usage makes sense.

Also as soon as dma_resv_usage has landed there's a few cleanups we should
do in i915:
- ttm bo moving code should probably simplify a bit (and maybe more of the
  code should be pushed as helpers into ttm)
- clflush code should be moved over to using USAGE_KERNEL and the various
  hacks and special cases should be ditched. See df94fd05e69e ("drm/i915:
  expand on the kernel-doc for cache_dirty") for a bit more context

This is still not yet enough, since if a vm_bind races with an eviction we
might stall on the new buffers being readied first before the context can
continue. This needs some care to make sure that vma which aren't fully
bound yet are on a separate list, and vma which are marked for unbinding
are removed from the main working set list as soon as possible.

All of these things are rel

Re: [RFC v2 1/2] drm/doc/rfc: VM_BIND feature design document

2022-04-20 Thread Niranjana Vishwanathapura

On Thu, Mar 31, 2022 at 10:28:48AM +0200, Daniel Vetter wrote:

Adding a pile of people who've expressed interest in vm_bind for their
drivers.

Also note to the intel folks: This is largely written with me having my
subsystem co-maintainer hat on, i.e. what I think is the right thing to do
here for the subsystem at large. There is substantial rework involved
here, but it's not any different from i915 adopting ttm or i915 adpoting
drm/sched, and I do think this stuff needs to happen in one form or
another.

On Mon, Mar 07, 2022 at 12:31:45PM -0800, Niranjana Vishwanathapura wrote:

VM_BIND design document with description of intended use cases.

Signed-off-by: Niranjana Vishwanathapura 
---
 Documentation/gpu/rfc/i915_vm_bind.rst | 210 +
 Documentation/gpu/rfc/index.rst|   4 +
 2 files changed, 214 insertions(+)
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.rst

diff --git a/Documentation/gpu/rfc/i915_vm_bind.rst 
b/Documentation/gpu/rfc/i915_vm_bind.rst
new file mode 100644
index ..cdc6bb25b942
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.rst
@@ -0,0 +1,210 @@
+==
+I915 VM_BIND feature design and use cases
+==
+
+VM_BIND feature
+
+DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
+objects (BOs) or sections of a BOs at specified GPU virtual addresses on
+a specified address space (VM).
+
+These mappings (also referred to as persistent mappings) will be persistent
+across multiple GPU submissions (execbuff) issued by the UMD, without user
+having to provide a list of all required mappings during each submission
+(as required by older execbuff mode).
+
+VM_BIND ioctl deferes binding the mappings until next execbuff submission
+where it will be required, or immediately if I915_GEM_VM_BIND_IMMEDIATE
+flag is set (useful if mapping is required for an active context).


So this is a screw-up I've done, and for upstream I think we need to fix
it: Implicit sync is bad, and it's also still a bad idea for vm_bind, and
I was wrong suggesting we should do this a few years back when we kicked
this off internally :-(

What I think we need is just always VM_BIND_IMMEDIATE mode, and then a few
things on top:
- in and out fences, like with execbuf, to allow userspace to sync with
 execbuf as needed
- for compute-mode context this means userspace memory fences
- for legacy context this means a timeline syncobj in drm_syncobj

No sync_file or anything else like this at all. This means a bunch of
work, but also it'll have benefits because it means we should be able to
use exactly the same code paths and logic for both compute and for legacy
context, because drm_syncobj support future fence semantics.



Thanks Daniel,
Ok, will update


Also on the implementation side we still need to install dma_fence to the
various dma_resv, and for this we need the new dma_resv_usage series from
Christian König first. vm_bind fences can then use the USAGE_BOOKKEEPING
flag to make sure they never result in an oversync issue with execbuf. I
don't think trying to land vm_bind without that prep work in
dma_resv_usage makes sense.



Ok, but that is not a dependency for this VM_BIND design RFC patch right?
I will add this to the documentation here.


Also as soon as dma_resv_usage has landed there's a few cleanups we should
do in i915:
- ttm bo moving code should probably simplify a bit (and maybe more of the
 code should be pushed as helpers into ttm)
- clflush code should be moved over to using USAGE_KERNEL and the various
 hacks and special cases should be ditched. See df94fd05e69e ("drm/i915:
 expand on the kernel-doc for cache_dirty") for a bit more context

This is still not yet enough, since if a vm_bind races with an eviction we
might stall on the new buffers being readied first before the context can
continue. This needs some care to make sure that vma which aren't fully
bound yet are on a separate list, and vma which are marked for unbinding
are removed from the main working set list as soon as possible.

All of these things are relevant for the uapi semantics, which means
- they need to be documented in the uapi kerneldoc, ideally with example
 flows
- umd need to ack this



Ok


The other thing here is the async/nonblocking path. I think we still need
that one, but again it should not sync with anything going on in execbuf,
but simply execute the ioctl code in a kernel thread. The idea here is
that this works like a special gpu engine, so that compute and vk can
schedule bindings interleaved with rendering. This should be enough to get
a performant vk sparse binding/textures implementation.

But I'm not entirely sure on this one, so this definitely needs acks from
umds.


+VM_BIND feature is advertised to user via I915_PARAM_HAS_VM_BIND.
+User has to opt-in for VM_BIND mode of binding for an address space (VM)
+during VM creation time via I915_VM_CREATE

Re: [PATCH v2 09/17] drm/msm/dpu: add an API to reset the encoder related hw blocks

2022-04-20 Thread Dmitry Baryshkov

On 21/04/2022 00:28, Abhinav Kumar wrote:



On 4/20/2022 12:23 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Add an API to reset the encoder related hw blocks to ensure
a proper teardown of the pipeline. At the moment this is being
used only for the writeback encoder but eventually we can start
using this for all interfaces.

changes in v2:
- split the writeback part to another commit

Signed-off-by: Abhinav Kumar 


Reviewed-by: Dmitry Baryshkov 

A minor question: do we need to also reset the DSPP alongside 
resetting the LM?


So this function is mostly doing what the downstream equivalent of it 
does which is to disable all the sspp blend stages, the ping-pong 
binding and 3d-merge connection.


For DSPP, there is no ability to *bind* it or connect it. Its a 
hard-wired connection. Its just a question of whether to enable it or not.


When the CTL path connections are removed, there is no need to 
explicitly disable the DSPP.


Thats why even downstream doesnt do it today.


Ack, thanks.







---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  | 82 


  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  7 ++
  2 files changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 4523693..0e31ad3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1,5 +1,6 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.
   * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All 
rights reserved.

   * Copyright (C) 2013 Red Hat
   * Author: Rob Clark 
@@ -22,6 +23,7 @@
  #include "dpu_hw_ctl.h"
  #include "dpu_hw_dspp.h"
  #include "dpu_hw_dsc.h"
+#include "dpu_hw_merge3d.h"
  #include "dpu_formats.h"
  #include "dpu_encoder_phys.h"
  #include "dpu_crtc.h"
@@ -1838,6 +1840,86 @@ void dpu_encoder_kickoff(struct drm_encoder 
*drm_enc)

  DPU_ATRACE_END("encoder_kickoff");
  }
+static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys 
*phys_enc)

+{
+    struct dpu_hw_mixer_cfg mixer;
+    int i, num_lm;
+    u32 flush_mask = 0;
+    struct dpu_global_state *global_state;
+    struct dpu_hw_blk *hw_lm[2];
+    struct dpu_hw_mixer *hw_mixer[2];
+    struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+
+    memset(&mixer, 0, sizeof(mixer));
+
+    /* reset all mixers for this encoder */
+    if (phys_enc->hw_ctl->ops.clear_all_blendstages)
+    phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl);
+
+    global_state = 
dpu_kms_get_existing_global_state(phys_enc->dpu_kms);

+
+    num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, 
global_state,
+    phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, 
ARRAY_SIZE(hw_lm));

+
+    for (i = 0; i < num_lm; i++) {
+    hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]);
+    flush_mask = phys_enc->hw_ctl->ops.get_bitmask_mixer(ctl, 
hw_mixer[i]->idx);

+    if (phys_enc->hw_ctl->ops.update_pending_flush)
+    phys_enc->hw_ctl->ops.update_pending_flush(ctl, 
flush_mask);

+
+    /* clear all blendstages */
+    if (phys_enc->hw_ctl->ops.setup_blendstage)
+    phys_enc->hw_ctl->ops.setup_blendstage(ctl, 
hw_mixer[i]->idx, NULL);

+    }
+}
+
+void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
+{
+    struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+    struct dpu_hw_intf_cfg intf_cfg = { 0 };
+    int i;
+    struct dpu_encoder_virt *dpu_enc;
+
+    dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
+
+    phys_enc->hw_ctl->ops.reset(ctl);
+
+    dpu_encoder_helper_reset_mixers(phys_enc);
+
+    for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+    if (dpu_enc->phys_encs[i] && 
phys_enc->hw_intf->ops.bind_pingpong_blk)

+    phys_enc->hw_intf->ops.bind_pingpong_blk(
+    dpu_enc->phys_encs[i]->hw_intf, false,
+    dpu_enc->phys_encs[i]->hw_pp->idx);
+
+    /* mark INTF flush as pending */
+    if (phys_enc->hw_ctl->ops.update_pending_flush_intf)
+ phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl,
+    dpu_enc->phys_encs[i]->hw_intf->idx);
+    }
+
+    /* reset the merge 3D HW block */
+    if (phys_enc->hw_pp->merge_3d) {
+ 
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,

+    BLEND_3D_NONE);
+    if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d)
+    phys_enc->hw_ctl->ops.update_pending_flush_merge_3d(ctl,
+    phys_enc->hw_pp->merge_3d->idx);
+    }
+
+    intf_cfg.stream_sel = 0; /* Don't care value for video mode */
+    intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+    if (phys_enc->hw_pp->merge_3d)
+    intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
+
+    if (ctl->ops.reset_intf_cfg)
+    ctl->ops.reset_intf_cfg(ctl, &intf_cfg);
+
+    c

[PATCH 4/4] drm/amd/pm: use bitmap_{from,to}_arr32 where appropriate

2022-04-20 Thread Yury Norov
The smu_v1X_0_set_allowed_mask() uses bitmap_copy() to convert
bitmap to 32-bit array. This may be wrong due to endianness issues.
Fix it by switching to bitmap_{from,to}_arr32.

Signed-off-by: Yury Norov 
---
 drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
index b87f550af26b..5f8809f6990d 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
@@ -781,7 +781,7 @@ int smu_v11_0_set_allowed_mask(struct smu_context *smu)
goto failed;
}
 
-   bitmap_copy((unsigned long *)feature_mask, feature->allowed, 64);
+   bitmap_to_arr32(feature_mask, feature->allowed, 64);
 
ret = smu_cmn_send_smc_msg_with_param(smu, 
SMU_MSG_SetAllowedFeaturesMaskHigh,
  feature_mask[1], NULL);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
index cf09e30bdfe0..747430ce6394 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -730,7 +730,7 @@ int smu_v13_0_set_allowed_mask(struct smu_context *smu)
feature->feature_num < 64)
return -EINVAL;
 
-   bitmap_copy((unsigned long *)feature_mask, feature->allowed, 64);
+   bitmap_to_arr32(feature_mask, feature->allowed, 64);
 
ret = smu_cmn_send_smc_msg_with_param(smu, 
SMU_MSG_SetAllowedFeaturesMaskHigh,
  feature_mask[1], NULL);
-- 
2.32.0



Re: [Freedreno] [PATCH v2 10/17] drm/msm/dpu: make changes to dpu_encoder to support virtual encoder

2022-04-20 Thread Dmitry Baryshkov

On 21/04/2022 01:06, Abhinav Kumar wrote:

Hi Dmitry

On 4/20/2022 11:46 AM, Abhinav Kumar wrote:



On 4/20/2022 11:37 AM, Dmitry Baryshkov wrote:
On Wed, 20 Apr 2022 at 20:41, Abhinav Kumar 
 wrote:




On 4/20/2022 12:44 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Make changes to dpu_encoder to support virtual encoder needed
to support writeback for dpu.

changes in v2:
 - add the writeback parts to dpu_encoder_helper_phys_cleanup
 - rebase on tip of msm-next and fix related dependencies
 - get the writeback blocks directly from RM

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0e31ad3..06b8631 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -928,6 +928,7 @@ static void
dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
   struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
   int num_lm, num_ctl, num_pp, num_dsc;
   unsigned int dsc_mask = 0;
+    enum dpu_hw_blk_type blk_type;
   int i;
   if (!drm_enc) {
@@ -1009,12 +1010,21 @@ static void
dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
   phys->hw_pp = dpu_enc->hw_pp[i];
   phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
-    if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX)
-    phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm,
phys->intf_idx);
+    if (dpu_encoder_get_intf_mode(&dpu_enc->base) ==
INTF_MODE_WB_LINE)
+    blk_type = DPU_HW_BLK_WB;
+    else
+    blk_type = DPU_HW_BLK_INTF;
+
+    if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) {
+    if (blk_type == DPU_HW_BLK_INTF)
+    phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm,
phys->intf_idx);
+    else if (blk_type == DPU_HW_BLK_WB)
+    phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm,
phys->intf_idx);
+    }
-    if (!phys->hw_intf) {
+    if (!phys->hw_intf && !phys->hw_wb) {
   DPU_ERROR_ENC(dpu_enc,
-  "no intf block assigned at idx: %d\n", i);
+  "no intf ow wb block assigned at idx: 
%d\n", i);


or wb

ack



   return;
   }
@@ -1157,15 +1167,22 @@ static void dpu_encoder_virt_disable(struct
drm_encoder *drm_enc)
   mutex_unlock(&dpu_enc->enc_lock);
   }
-static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg 
*catalog,

+static enum dpu_intf dpu_encoder_get_intf_or_wb(struct dpu_mdss_cfg
*catalog,
   enum dpu_intf_type type, u32 controller_id)
   {
   int i = 0;
-    for (i = 0; i < catalog->intf_count; i++) {
-    if (catalog->intf[i].type == type
-    && catalog->intf[i].controller_id == controller_id) {
-    return catalog->intf[i].id;
+    if (type != INTF_WB) {
+    for (i = 0; i < catalog->intf_count; i++) {
+    if (catalog->intf[i].type == type
+    && catalog->intf[i].controller_id == 
controller_id) {

+    return catalog->intf[i].id;
+    }
+    }
+    } else {
+    for (i = 0; i < catalog->wb_count; i++) {
+    if (catalog->wb[i].id == controller_id)
+    return catalog->wb[i].id;
   }
   }
@@ -1886,16 +1903,27 @@ void dpu_encoder_helper_phys_cleanup(struct
dpu_encoder_phys *phys_enc)
   dpu_encoder_helper_reset_mixers(phys_enc);
-    for (i = 0; i < dpu_enc->num_phys_encs; i++) {
-    if (dpu_enc->phys_encs[i] &&
phys_enc->hw_intf->ops.bind_pingpong_blk)
-    phys_enc->hw_intf->ops.bind_pingpong_blk(
-    dpu_enc->phys_encs[i]->hw_intf, false,
-    dpu_enc->phys_encs[i]->hw_pp->idx);
+    if (phys_enc->hw_wb) {


I think this adds a hidden knowledge here. That there is always just a
single phys_enc for the WB encoder. I'd still do this cleanup in a 
loop

together with the INTF cleanup.

alright, I can make this change.


I dug into the history of dpu_encoder_helper_phys_cleanup() API more in 
downstream.


So this API seems to be a bit poorly designed in downstream too.

This gets called from phys->ops.disable() today which is anyway called 
from within a loop.


  for (i = 0; i < dpu_enc->num_phys_encs; i++) {
     struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];

     if (phys->ops.disable)
     phys->ops.disable(phys);
     }

So technically we dont need a loop even for the intf cases because of that.

But, while calling for interfaces, downstream makes sure to call this 
just once for the master and skip for the same.


Here the loop is needed just to set the flush bits even for the slave 
and let the master do the actual flush.


Since today, we are not calling thi

Re: [PATCH] drm/msm/dp: tear down main link at unplug handle immediately

2022-04-20 Thread Stephen Boyd
Quoting Kuogee Hsieh (2022-04-14 14:03:43)
> Two stages are required to setup up main link to be ready to transmit
> video stream.
> Stage 1: dp_hpd_plug_handle() perform link training to set up main link
> stage 2: user space framework (msm_dp_display_enable()) to enable pixel
> clock and transfer main link to video ready state.
>
> At current implementation, when dongle unplugged dp_hdp_unplug_handle()
> has to wait until stage 2 completed before it can send link down uevent
> to user space framework to disable pixel clock followed by tearing down
> main link.  This introduce unnecessary latency if dongle unplugged happen
> after stage 1 and before stage 2. It also has possibility leave main link
> stay at ready state after dongle unplugged if framework does not response
> to link down uevent notification. This will prevent next dongle plug in
> from working. This scenario could possibly happen when dongle unplug while
> system in the middle of suspending.
>
> This patch allow unplug handle to tear down main link and notify
> framework link down immediately if dongle unplugged happen after
> stage 1 and before stage 2. With this approach, dp driver is much
> more resilient to any different scenarios. Also redundant both
> dp_connect_pending_timeout() and dp_disconnect_pending_timeout()
> are removed to reduce logic complexity.
>
> Fixes: 8ede2ecc3e5e ("drm/msm/dp: Add DP compliance tests on Snapdragon 
> Chipsets")
> Signed-off-by: Kuogee Hsieh 

Reviewed-by: Stephen Boyd 

Some questions below but doesn't seem like it will hold up this patch.

> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 01453db..f5bd8f5 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -615,24 +598,21 @@ static int dp_hpd_unplug_handle(struct 
> dp_display_private *dp, u32 data)
> if (dp->link->sink_count == 0) {
> dp_display_host_phy_exit(dp);
> }
> +   dp_display_notify_disconnect(&dp->pdev->dev);
> mutex_unlock(&dp->event_mutex);
> return 0;
> -   }
> -
> -   if (state == ST_DISCONNECT_PENDING) {
> +   } else if (state == ST_DISCONNECT_PENDING) {
> mutex_unlock(&dp->event_mutex);
> return 0;
> -   }
> -
> -   if (state == ST_CONNECT_PENDING) {
> -   /* wait until CONNECTED */
> -   dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 1); /* delay = 1 */
> +   } else if (state == ST_CONNECT_PENDING) {

I take it that ST_CONNECT_PENDING is sort of like "userspace hasn't
handled the uevent yet and modeset hasn't been called but the link is
setup and now we want to tear it down". The state name may want to be
changed to something else.

> +   dp_ctrl_off_link(dp->ctrl);
> +   dp_display_host_phy_exit(dp);
> +   dp->hpd_state = ST_DISCONNECTED;
> +   dp_display_notify_disconnect(&dp->pdev->dev);
> mutex_unlock(&dp->event_mutex);
> return 0;
> }
>
> -   dp->hpd_state = ST_DISCONNECT_PENDING;
> -
> /* disable HPD plug interrupts */
> dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, 
> false);
>
> @@ -640,10 +620,13 @@ static int dp_hpd_unplug_handle(struct 
> dp_display_private *dp, u32 data)
>  * We don't need separate work for disconnect as
>  * connect/attention interrupts are disabled
>  */
> -   dp_display_usbpd_disconnect_cb(&dp->pdev->dev);
> +   dp_display_notify_disconnect(&dp->pdev->dev);
>
> -   /* start sentinel checking in case of missing uevent */
> -   dp_add_event(dp, EV_DISCONNECT_PENDING_TIMEOUT, 0, 
> DP_TIMEOUT_5_SECOND);
> +   if (state == ST_DISPLAY_OFF) {
> +   dp->hpd_state = ST_DISCONNECTED;
> +   } else {
> +   dp->hpd_state = ST_DISCONNECT_PENDING;
> +   }

Nitpick: No braces needed for single line if clauses.

>
> DRM_DEBUG_DP("hpd_state=%d\n", state);
> /* signal the disconnect event early to ensure proper teardown */
> @@ -1529,8 +1480,11 @@ int msm_dp_display_enable(struct msm_dp *dp, struct 
> drm_encoder *encoder)
>
> mutex_lock(&dp_display->event_mutex);
>
> -   /* stop sentinel checking */
> -   dp_del_event(dp_display, EV_CONNECT_PENDING_TIMEOUT);
> +   state = dp_display->hpd_state;
> +   if (state != ST_DISPLAY_OFF && state != ST_CONNECT_PENDING) {

Is this to guard against userspace doing an atomic commit when the
display isn't connected? Is that even possible?

> +   mutex_unlock(&dp_display->event_mutex);
> +   return rc;
> +   }
>
> rc = dp_display_set_mode(dp, &dp_display->dp_mode);
> if (rc) {


Re: [Freedreno] [PATCH v2 10/17] drm/msm/dpu: make changes to dpu_encoder to support virtual encoder

2022-04-20 Thread Abhinav Kumar

Hi Dmitry

On 4/20/2022 11:46 AM, Abhinav Kumar wrote:



On 4/20/2022 11:37 AM, Dmitry Baryshkov wrote:
On Wed, 20 Apr 2022 at 20:41, Abhinav Kumar 
 wrote:




On 4/20/2022 12:44 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Make changes to dpu_encoder to support virtual encoder needed
to support writeback for dpu.

changes in v2:
 - add the writeback parts to dpu_encoder_helper_phys_cleanup
 - rebase on tip of msm-next and fix related dependencies
 - get the writeback blocks directly from RM

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0e31ad3..06b8631 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -928,6 +928,7 @@ static void
dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
   struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
   int num_lm, num_ctl, num_pp, num_dsc;
   unsigned int dsc_mask = 0;
+    enum dpu_hw_blk_type blk_type;
   int i;
   if (!drm_enc) {
@@ -1009,12 +1010,21 @@ static void
dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
   phys->hw_pp = dpu_enc->hw_pp[i];
   phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
-    if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX)
-    phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm,
phys->intf_idx);
+    if (dpu_encoder_get_intf_mode(&dpu_enc->base) ==
INTF_MODE_WB_LINE)
+    blk_type = DPU_HW_BLK_WB;
+    else
+    blk_type = DPU_HW_BLK_INTF;
+
+    if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) {
+    if (blk_type == DPU_HW_BLK_INTF)
+    phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm,
phys->intf_idx);
+    else if (blk_type == DPU_HW_BLK_WB)
+    phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm,
phys->intf_idx);
+    }
-    if (!phys->hw_intf) {
+    if (!phys->hw_intf && !phys->hw_wb) {
   DPU_ERROR_ENC(dpu_enc,
-  "no intf block assigned at idx: %d\n", i);
+  "no intf ow wb block assigned at idx: %d\n", 
i);


or wb

ack



   return;
   }
@@ -1157,15 +1167,22 @@ static void dpu_encoder_virt_disable(struct
drm_encoder *drm_enc)
   mutex_unlock(&dpu_enc->enc_lock);
   }
-static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg 
*catalog,

+static enum dpu_intf dpu_encoder_get_intf_or_wb(struct dpu_mdss_cfg
*catalog,
   enum dpu_intf_type type, u32 controller_id)
   {
   int i = 0;
-    for (i = 0; i < catalog->intf_count; i++) {
-    if (catalog->intf[i].type == type
-    && catalog->intf[i].controller_id == controller_id) {
-    return catalog->intf[i].id;
+    if (type != INTF_WB) {
+    for (i = 0; i < catalog->intf_count; i++) {
+    if (catalog->intf[i].type == type
+    && catalog->intf[i].controller_id == controller_id) {
+    return catalog->intf[i].id;
+    }
+    }
+    } else {
+    for (i = 0; i < catalog->wb_count; i++) {
+    if (catalog->wb[i].id == controller_id)
+    return catalog->wb[i].id;
   }
   }
@@ -1886,16 +1903,27 @@ void dpu_encoder_helper_phys_cleanup(struct
dpu_encoder_phys *phys_enc)
   dpu_encoder_helper_reset_mixers(phys_enc);
-    for (i = 0; i < dpu_enc->num_phys_encs; i++) {
-    if (dpu_enc->phys_encs[i] &&
phys_enc->hw_intf->ops.bind_pingpong_blk)
-    phys_enc->hw_intf->ops.bind_pingpong_blk(
-    dpu_enc->phys_encs[i]->hw_intf, false,
-    dpu_enc->phys_encs[i]->hw_pp->idx);
+    if (phys_enc->hw_wb) {


I think this adds a hidden knowledge here. That there is always just a
single phys_enc for the WB encoder. I'd still do this cleanup in a loop
together with the INTF cleanup.

alright, I can make this change.


I dug into the history of dpu_encoder_helper_phys_cleanup() API more in 
downstream.


So this API seems to be a bit poorly designed in downstream too.

This gets called from phys->ops.disable() today which is anyway called 
from within a loop.


 for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];

if (phys->ops.disable)
phys->ops.disable(phys);
}

So technically we dont need a loop even for the intf cases because of that.

But, while calling for interfaces, downstream makes sure to call this 
just once for the master and skip for the same.


Here the loop is needed just to set the flush bits even for the slave 
and let the master do the actual flush.


Since today, we are not calling this for interface yet, I think i can 
get rid of the l

Re: [PATCH 1/2] dt-bindings: display: ti,am65x-dss: Add missing register & interrupt

2022-04-20 Thread Rob Herring
On Wed, Apr 20, 2022 at 10:05:34AM +0300, Tomi Valkeinen wrote:
> Hi,
> 
> On 19/04/2022 17:20, Rob Herring wrote:
> > On Tue, Apr 19, 2022 at 12:33:01PM +0530, Aradhya Bhatia wrote:
> > > The DSS IP on the ti-am65x soc supports an additional register space,
> > > named "common1". Further. the IP services a maximum number of 2
> > > interrupts.
> > > 
> > > Add the missing register space "common1" and the additional interrupt.
> > > 
> > > Signed-off-by: Aradhya Bhatia 
> > > ---
> > >   .../devicetree/bindings/display/ti/ti,am65x-dss.yaml   | 10 +++---
> > >   1 file changed, 7 insertions(+), 3 deletions(-)
> > > 
> > > diff --git 
> > > a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml 
> > > b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> > > index 5c7d2cbc4aac..102059e9e0d5 100644
> > > --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> > > +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> > > @@ -26,6 +26,7 @@ properties:
> > > Addresses to each DSS memory region described in the SoC's TRM.
> > >   items:
> > > - description: common DSS register area
> > > +  - description: common1 DSS register area
> > 
> > You've just broken the ABI.
> > 
> > New entries have to go on the end.
> 
> I'm curious, if the 'reg-names' is a required property, as it is here, does
> this still break the ABI?

Yes, the order is part of the ABI.

Sometimes we just give up with multiple optional entries or inherited 
any order allowed, but here there is no reason. Just add 'common1' to 
the end.

Rob


Re: [PATCH v2 09/17] drm/msm/dpu: add an API to reset the encoder related hw blocks

2022-04-20 Thread Abhinav Kumar




On 4/20/2022 12:23 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Add an API to reset the encoder related hw blocks to ensure
a proper teardown of the pipeline. At the moment this is being
used only for the writeback encoder but eventually we can start
using this for all interfaces.

changes in v2:
- split the writeback part to another commit

Signed-off-by: Abhinav Kumar 


Reviewed-by: Dmitry Baryshkov 

A minor question: do we need to also reset the DSPP alongside resetting 
the LM?


So this function is mostly doing what the downstream equivalent of it 
does which is to disable all the sspp blend stages, the ping-pong 
binding and 3d-merge connection.


For DSPP, there is no ability to *bind* it or connect it. Its a 
hard-wired connection. Its just a question of whether to enable it or not.


When the CTL path connections are removed, there is no need to 
explicitly disable the DSPP.


Thats why even downstream doesnt do it today.




---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  | 82 


  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  7 ++
  2 files changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 4523693..0e31ad3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1,5 +1,6 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.
   * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All 
rights reserved.

   * Copyright (C) 2013 Red Hat
   * Author: Rob Clark 
@@ -22,6 +23,7 @@
  #include "dpu_hw_ctl.h"
  #include "dpu_hw_dspp.h"
  #include "dpu_hw_dsc.h"
+#include "dpu_hw_merge3d.h"
  #include "dpu_formats.h"
  #include "dpu_encoder_phys.h"
  #include "dpu_crtc.h"
@@ -1838,6 +1840,86 @@ void dpu_encoder_kickoff(struct drm_encoder 
*drm_enc)

  DPU_ATRACE_END("encoder_kickoff");
  }
+static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys 
*phys_enc)

+{
+    struct dpu_hw_mixer_cfg mixer;
+    int i, num_lm;
+    u32 flush_mask = 0;
+    struct dpu_global_state *global_state;
+    struct dpu_hw_blk *hw_lm[2];
+    struct dpu_hw_mixer *hw_mixer[2];
+    struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+
+    memset(&mixer, 0, sizeof(mixer));
+
+    /* reset all mixers for this encoder */
+    if (phys_enc->hw_ctl->ops.clear_all_blendstages)
+    phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl);
+
+    global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms);
+
+    num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, 
global_state,
+    phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, 
ARRAY_SIZE(hw_lm));

+
+    for (i = 0; i < num_lm; i++) {
+    hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]);
+    flush_mask = phys_enc->hw_ctl->ops.get_bitmask_mixer(ctl, 
hw_mixer[i]->idx);

+    if (phys_enc->hw_ctl->ops.update_pending_flush)
+    phys_enc->hw_ctl->ops.update_pending_flush(ctl, flush_mask);
+
+    /* clear all blendstages */
+    if (phys_enc->hw_ctl->ops.setup_blendstage)
+    phys_enc->hw_ctl->ops.setup_blendstage(ctl, 
hw_mixer[i]->idx, NULL);

+    }
+}
+
+void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
+{
+    struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+    struct dpu_hw_intf_cfg intf_cfg = { 0 };
+    int i;
+    struct dpu_encoder_virt *dpu_enc;
+
+    dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
+
+    phys_enc->hw_ctl->ops.reset(ctl);
+
+    dpu_encoder_helper_reset_mixers(phys_enc);
+
+    for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+    if (dpu_enc->phys_encs[i] && 
phys_enc->hw_intf->ops.bind_pingpong_blk)

+    phys_enc->hw_intf->ops.bind_pingpong_blk(
+    dpu_enc->phys_encs[i]->hw_intf, false,
+    dpu_enc->phys_encs[i]->hw_pp->idx);
+
+    /* mark INTF flush as pending */
+    if (phys_enc->hw_ctl->ops.update_pending_flush_intf)
+
phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl,

+    dpu_enc->phys_encs[i]->hw_intf->idx);
+    }
+
+    /* reset the merge 3D HW block */
+    if (phys_enc->hw_pp->merge_3d) {
+
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,

+    BLEND_3D_NONE);
+    if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d)
+    phys_enc->hw_ctl->ops.update_pending_flush_merge_3d(ctl,
+    phys_enc->hw_pp->merge_3d->idx);
+    }
+
+    intf_cfg.stream_sel = 0; /* Don't care value for video mode */
+    intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+    if (phys_enc->hw_pp->merge_3d)
+    intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
+
+    if (ctl->ops.reset_intf_cfg)
+    ctl->ops.reset_intf_cfg(ctl, &intf_cfg);
+
+    ctl->ops.trigger_flush(ctl);
+    ctl->ops.tr

Re: [PATCH] drm/ttm: fix ttm tt init fail when size exceeds kmalloc limit

2022-04-20 Thread Felix Kuehling



On 2022-04-20 09:23, Lazar, Lijo wrote:



On 4/20/2022 6:26 PM, Christian König wrote:

Am 20.04.22 um 14:54 schrieb Wang, Yang(Kevin):


[AMD Official Use Only]


Hi Chris,

1) Change the test case to use something larger than 1TiB.
sure, we can increase the size of BO and make test pass,
but if user really want to allocate 1TB GTT BO, we have no reason to 
let it fail? right?


No, the reason is the underlying core kernel doesn't allow kvmalloc 
allocations with GFP_ZERO which are large enough to hold the array of 
allocated pages for this.


We are working on top of the core Linux kernel and should *NEVER* 
ever add workarounds like what was suggested here. >


AFAIU, for the purpose of ttm use, fallback to vmalloc is fine.

 * Please note that any use of gfp flags outside of GFP_KERNEL is 
careful to not

 * fall back to vmalloc.
 *


That's weird, because kvcalloc does the same thing. If that were not 
able to fall back to vmalloc, it would be pretty useless.


   static inline __alloc_size(1, 2) void *kvcalloc(size_t n, size_t size, gfp_t 
flags)
   {
return kvmalloc_array(n, size, flags | __GFP_ZERO);
   }

Maybe kvcalloc is the function we TTM should be using here anyway, 
instead of open-coding the kvmalloc_array call with an extra GFP flag.


Regards,
  Felix




Actually the current implementation documents the behavior, but it is 
deep inside the implementation to be noticeable - at least not obvious 
while using kvmalloc_array.


Thanks,
Lijo


Regards,
Christian.


the system availed memory about 2T, but it will still fail.

2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc 
fallback path.

    the 5.18 kernel will add this patch to fix this issue .

Best Regards,
Kevin
 


*From:* Koenig, Christian 
*Sent:* Wednesday, April 20, 2022 8:42 PM
*To:* Wang, Yang(Kevin) ; Christian König 
; dri-devel@lists.freedesktop.org 
; amd-...@lists.freedesktop.org 

*Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size 
exceeds kmalloc limit

Hi Kevin,

yes and that is perfectly valid and expected behavior. There is 
absolutely no need to change anything in TTM here.


What we could do is:
1) Change the test case to use something larger than 1TiB.
2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc 
fallback path.


Regards,
Christian.

Am 20.04.22 um 14:39 schrieb Wang, Yang(Kevin):


[AMD Official Use Only]


Hi Chirs,

yes, right, the amdgpu drive rwill use amdgpu_bo_validate_size() 
function to verify bo size,
but when driver try to allocate VRAM domain bo fail, the amdgpu 
driver will fall back to allocate domain = (GTT | VRAM)  bo.
please check following code, it will cause the 2nd time to allocate 
bo fail during allocate 256Mb buffer to store dma address (via 
kvmalloc()).


initial_domain = (u32)(0x & args->in.domains);
retry:
        r = amdgpu_gem_object_create(adev, size, args->in.alignment,
                   initial_domain,
                   flags, ttm_bo_type_device, resv, &gobj);
        if (r && r != -ERESTARTSYS) {
                if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
      flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
      goto retry;
                }

                if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
      initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
      goto retry;
                }
DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n",
              size, initial_domain, args->in.alignment, r);
        }

Best Regards,
Kevin

 

*From:* Christian König  


*Sent:* Wednesday, April 20, 2022 7:55 PM
*To:* Wang, Yang(Kevin)  
; Koenig, Christian 
 ; 
dri-devel@lists.freedesktop.org 
 
 
; 
amd-...@lists.freedesktop.org 
 
 
*Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size 
exceeds kmalloc limit

Hi Kevin,

no, the test case should already fail in amdgpu_bo_validate_size().

If we have a system with 2TiB of memory where the test case could 
succeed then we should increase the requested size to something 
larger.


And if the underlying core Linux kernel functions don't allow 
allocations as large as the requested one we should *NEVER* ever 
add workarounds like this.


It is perfectly expected that this test case is not able to fulfill 
the desired allocation. That it fails during kvmalloc is 
unfortunate, but not a show stopper.


Regards,
Christian.


Am 20.04.22 um 13:32 schrieb Wang, Yang(Kevin):


[AMD Official Use Only]


Hi Chris,

you misunderstood background about this case.

although we expect this test case to fail, it should fail at the 
location where the

RE: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Limonciello, Mario
[Public]



> -Original Message-
> From: Alex Deucher 
> Sent: Wednesday, April 20, 2022 16:14
> To: Paul Menzel 
> Cc: Gong, Richard ; Dave Airlie ;
> Pan, Xinhui ; LKML ;
> Maling list - DRI developers ; amd-gfx list
> ; Daniel Vetter ; Deucher,
> Alexander ; Koenig, Christian
> ; Limonciello, Mario
> 
> Subject: Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based
> systems
> 
> On Wed, Apr 20, 2022 at 5:02 PM Paul Menzel 
> wrote:
> >
> > Dear Richard,
> >
> >
> > Am 20.04.22 um 22:56 schrieb Gong, Richard:
> >
> > > On 4/20/2022 3:48 PM, Paul Menzel wrote:
> >
> > >> Am 20.04.22 um 22:40 schrieb Alex Deucher:
> > >>> On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel
> 
> > >>> wrote:
> > >>
> >  Am 19.04.22 um 23:46 schrieb Gong, Richard:
> > 
> > > On 4/14/2022 2:52 AM, Paul Menzel wrote:
> > >> [Cc: -kernel test robot ]
> > 
> >  [...]
> > 
> > >> Am 13.04.22 um 15:00 schrieb Alex Deucher:
> > >>> On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:
> > >>
> >  Thank you for sending out v4.
> > 
> >  Am 12.04.22 um 23:50 schrieb Richard Gong:
> > > Active State Power Management (ASPM) feature is enabled since
> > > kernel 5.14.
> > > There are some AMD GFX cards (such as WX3200 and RX640) that
> won't
> > > work
> > > with ASPM-enabled Intel Alder Lake based systems. Using these
> GFX
> > > cards as
> > > video/display output, Intel Alder Lake based systems will hang
> > > during
> > > suspend/resume.
> > 
> >  [Your email program wraps lines in cited text for some reason, making
> >  the citation harder to read.]
> > 
> > 
> >  I am still not clear, what "hang during suspend/resume" means. I
> >  guess
> >  suspending works fine? During resume (S3 or S0ix?), where does
> >  it hang?
> >  The system is functional, but there are only display problems?
> > > System freeze after suspend/resume.
> > 
> >  But you see certain messages still? At what point does it freeze
> >  exactly? In the bug report you posted Linux messages.
> > 
> > > The issue was initially reported on one system (Dell Precision
> > > 3660
> > > with
> > > BIOS version 0.14.81), but was later confirmed to affect at
> > > least 4
> > > Alder
> > > Lake based systems.
> > >
> > > Add extra check to disable ASPM on Intel Alder Lake based
> systems.
> > >
> > > Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
> > > Link:
> > >
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.fr
> eedesktop.org%2Fdrm%2Famd%2F-
> %2Fissues%2F1885&data=05%7C01%7Cmario.limonciello%40amd.com%7
> Ce74863210c324bc6fda608da2312b506%7C3dd8961fe4884e608e11a82d994e1
> 83d%7C0%7C0%7C637860860514174025%7CUnknown%7CTWFpbGZsb3d8eyJ
> WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C
> 3000%7C%7C%7C&sdata=NUGXlybuH3volccVuN%2BGQ0kXwsOfCqM%2F
> wqHL6%2F%2FGYUc%3D&reserved=0
> > >
> > 
> >  Thank you Microsoft Outlook for keeping us safe. :(
> > 
> > >
> > > Reported-by: kernel test robot 
> > 
> >  This tag is a little confusing. Maybe clarify that it was for an
> >  issue
> >  in a previous patch iteration?
> > >
> > > I did describe in change-list version 3 below, which corrected the
> > > build
> > > error with W=1 option.
> > >
> > > It is not good idea to add the description for that to the commit
> > > message, this is why I add descriptions on change-list version 3.
> > 
> >  Do as you wish, but the current style is confusing, and readers of the
> >  commit are going to think, the kernel test robot reported the problem
> >  with AMD VI ASICs and Intel Alder Lake systems.
> > 
> > 
> > > Signed-off-by: Richard Gong 
> > > ---
> > > v4: s/CONFIG_X86_64/CONFIG_X86
> > >enhanced check logic
> > > v3: s/intel_core_asom_chk/aspm_support_quirk_check
> > >correct build error with W=1 option
> > > v2: correct commit description
> > >move the check from chip family to problematic platform
> > > ---
> > > drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
> > > 1 file changed, 16 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
> > > b/drivers/gpu/drm/amd/amdgpu/vi.c
> > > index 039b90cdc3bc..b33e0a9bee65 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> > > @@ -81,6 +81,10 @@
> > > #include "mxgpu_vi.h"
> > > #include "amdgpu_dm.h"
> > >
> > > +#if IS_ENABLED(CONFIG_X86)

Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Alex Deucher
On Wed, Apr 20, 2022 at 5:13 PM Gong, Richard  wrote:
>
>
> On 4/20/2022 4:02 PM, Paul Menzel wrote:
> > Dear Richard,
> >
> >
> > Am 20.04.22 um 22:56 schrieb Gong, Richard:
> >
> >> On 4/20/2022 3:48 PM, Paul Menzel wrote:
> >
> >>> Am 20.04.22 um 22:40 schrieb Alex Deucher:
>  On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel 
>  wrote:
> >>>
> > Am 19.04.22 um 23:46 schrieb Gong, Richard:
> >
> >> On 4/14/2022 2:52 AM, Paul Menzel wrote:
> >>> [Cc: -kernel test robot ]
> >
> > […]
> >
> >>> Am 13.04.22 um 15:00 schrieb Alex Deucher:
>  On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:
> >>>
> > Thank you for sending out v4.
> >
> > Am 12.04.22 um 23:50 schrieb Richard Gong:
> >> Active State Power Management (ASPM) feature is enabled since
> >> kernel 5.14.
> >> There are some AMD GFX cards (such as WX3200 and RX640) that
> >> won't
> >> work
> >> with ASPM-enabled Intel Alder Lake based systems. Using these
> >> GFX
> >> cards as
> >> video/display output, Intel Alder Lake based systems will
> >> hang during
> >> suspend/resume.
> >
> > [Your email program wraps lines in cited text for some reason, making
> > the citation harder to read.]
> >
> >
> > I am still not clear, what “hang during suspend/resume” means.
> > I guess
> > suspending works fine? During resume (S3 or S0ix?), where does
> > it hang?
> > The system is functional, but there are only display problems?
> >> System freeze after suspend/resume.
> >
> > But you see certain messages still? At what point does it freeze
> > exactly? In the bug report you posted Linux messages.
> >
> >> The issue was initially reported on one system (Dell
> >> Precision 3660
> >> with
> >> BIOS version 0.14.81), but was later confirmed to affect at
> >> least 4
> >> Alder
> >> Lake based systems.
> >>
> >> Add extra check to disable ASPM on Intel Alder Lake based
> >> systems.
> >>
> >> Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
> >> Link:
> >> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=05%7C01%7Crichard.gong%40amd.com%7C509e0378edcf477605a708da231114f0%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637860853537880384%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=SoXDKGHUiiQN4rcL7FpCotouWFt0kkAbcHyO3esfNlE%3D&reserved=0
> >>
> >
> > Thank you Microsoft Outlook for keeping us safe. :(
> >
> >>
> >> Reported-by: kernel test robot 
> >
> > This tag is a little confusing. Maybe clarify that it was for
> > an issue
> > in a previous patch iteration?
> >>
> >> I did describe in change-list version 3 below, which corrected
> >> the build
> >> error with W=1 option.
> >>
> >> It is not good idea to add the description for that to the commit
> >> message, this is why I add descriptions on change-list version 3.
> >
> > Do as you wish, but the current style is confusing, and readers of
> > the
> > commit are going to think, the kernel test robot reported the problem
> > with AMD VI ASICs and Intel Alder Lake systems.
> >
> >
> >> Signed-off-by: Richard Gong 
> >> ---
> >> v4: s/CONFIG_X86_64/CONFIG_X86
> >>enhanced check logic
> >> v3: s/intel_core_asom_chk/aspm_support_quirk_check
> >>correct build error with W=1 option
> >> v2: correct commit description
> >>move the check from chip family to problematic platform
> >> ---
> >> drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
> >> 1 file changed, 16 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
> >> b/drivers/gpu/drm/amd/amdgpu/vi.c
> >> index 039b90cdc3bc..b33e0a9bee65 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> >> @@ -81,6 +81,10 @@
> >> #include "mxgpu_vi.h"
> >> #include "amdgpu_dm.h"
> >>
> >> +#if IS_ENABLED(CONFIG_X86)
> >> +#include 
> >> +#endif
> >> +
> >> #define ixPCIE_LC_L1_PM_SUBSTATE 0x100100C6
> >> #define
> >> PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK
> >> 0x0001L
> >> #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK
> >> 0x0002L
> >> @@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct
> >> amdgpu_device *adev)
> >>

Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Alex Deucher
On Wed, Apr 20, 2022 at 5:02 PM Paul Menzel  wrote:
>
> Dear Richard,
>
>
> Am 20.04.22 um 22:56 schrieb Gong, Richard:
>
> > On 4/20/2022 3:48 PM, Paul Menzel wrote:
>
> >> Am 20.04.22 um 22:40 schrieb Alex Deucher:
> >>> On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel 
> >>> wrote:
> >>
>  Am 19.04.22 um 23:46 schrieb Gong, Richard:
> 
> > On 4/14/2022 2:52 AM, Paul Menzel wrote:
> >> [Cc: -kernel test robot ]
> 
>  […]
> 
> >> Am 13.04.22 um 15:00 schrieb Alex Deucher:
> >>> On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:
> >>
>  Thank you for sending out v4.
> 
>  Am 12.04.22 um 23:50 schrieb Richard Gong:
> > Active State Power Management (ASPM) feature is enabled since
> > kernel 5.14.
> > There are some AMD GFX cards (such as WX3200 and RX640) that won't
> > work
> > with ASPM-enabled Intel Alder Lake based systems. Using these GFX
> > cards as
> > video/display output, Intel Alder Lake based systems will hang
> > during
> > suspend/resume.
> 
>  [Your email program wraps lines in cited text for some reason, making
>  the citation harder to read.]
> 
> 
>  I am still not clear, what “hang during suspend/resume” means. I
>  guess
>  suspending works fine? During resume (S3 or S0ix?), where does
>  it hang?
>  The system is functional, but there are only display problems?
> > System freeze after suspend/resume.
> 
>  But you see certain messages still? At what point does it freeze
>  exactly? In the bug report you posted Linux messages.
> 
> > The issue was initially reported on one system (Dell Precision
> > 3660
> > with
> > BIOS version 0.14.81), but was later confirmed to affect at
> > least 4
> > Alder
> > Lake based systems.
> >
> > Add extra check to disable ASPM on Intel Alder Lake based systems.
> >
> > Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
> > Link:
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=05%7C01%7Crichard.gong%40amd.com%7C487aaa63098b462e146a08da230f2319%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637860845178176835%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=3IVldn05qNa2XVp1Lu58SriS8k9mk4U9K9p3F3IYPe0%3D&reserved=0
> >
> 
>  Thank you Microsoft Outlook for keeping us safe. :(
> 
> >
> > Reported-by: kernel test robot 
> 
>  This tag is a little confusing. Maybe clarify that it was for an
>  issue
>  in a previous patch iteration?
> >
> > I did describe in change-list version 3 below, which corrected the
> > build
> > error with W=1 option.
> >
> > It is not good idea to add the description for that to the commit
> > message, this is why I add descriptions on change-list version 3.
> 
>  Do as you wish, but the current style is confusing, and readers of the
>  commit are going to think, the kernel test robot reported the problem
>  with AMD VI ASICs and Intel Alder Lake systems.
> 
> 
> > Signed-off-by: Richard Gong 
> > ---
> > v4: s/CONFIG_X86_64/CONFIG_X86
> >enhanced check logic
> > v3: s/intel_core_asom_chk/aspm_support_quirk_check
> >correct build error with W=1 option
> > v2: correct commit description
> >move the check from chip family to problematic platform
> > ---
> > drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
> > 1 file changed, 16 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
> > b/drivers/gpu/drm/amd/amdgpu/vi.c
> > index 039b90cdc3bc..b33e0a9bee65 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> > @@ -81,6 +81,10 @@
> > #include "mxgpu_vi.h"
> > #include "amdgpu_dm.h"
> >
> > +#if IS_ENABLED(CONFIG_X86)
> > +#include 
> > +#endif
> > +
> > #define ixPCIE_LC_L1_PM_SUBSTATE0x100100C6
> > #define
> > PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK
> > 0x0001L
> > #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK
> > 0x0002L
> > @@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct
> > amdgpu_device *adev)
> > WREG32_PCIE(ixPCIE_LC_CNTL, data);
> > }
> >
> > +static bool aspm_support_quirk_check(void)
> > +{
> > + if (IS_ENABLED(CONFIG_X86)) {
> > + 

Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Gong, Richard



On 4/20/2022 4:02 PM, Paul Menzel wrote:

Dear Richard,


Am 20.04.22 um 22:56 schrieb Gong, Richard:


On 4/20/2022 3:48 PM, Paul Menzel wrote:



Am 20.04.22 um 22:40 schrieb Alex Deucher:
On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel  
wrote:



Am 19.04.22 um 23:46 schrieb Gong, Richard:


On 4/14/2022 2:52 AM, Paul Menzel wrote:

[Cc: -kernel test robot ]


[…]


Am 13.04.22 um 15:00 schrieb Alex Deucher:

On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:



Thank you for sending out v4.

Am 12.04.22 um 23:50 schrieb Richard Gong:

Active State Power Management (ASPM) feature is enabled since
kernel 5.14.
There are some AMD GFX cards (such as WX3200 and RX640) that 
won't

work
with ASPM-enabled Intel Alder Lake based systems. Using these 
GFX

cards as
video/display output, Intel Alder Lake based systems will 
hang during

suspend/resume.


[Your email program wraps lines in cited text for some reason, making
the citation harder to read.]



I am still not clear, what “hang during suspend/resume” means. 
I guess
suspending works fine? During resume (S3 or S0ix?), where does 
it hang?

The system is functional, but there are only display problems?

System freeze after suspend/resume.


But you see certain messages still? At what point does it freeze
exactly? In the bug report you posted Linux messages.

The issue was initially reported on one system (Dell 
Precision 3660

with
BIOS version 0.14.81), but was later confirmed to affect at 
least 4

Alder
Lake based systems.

Add extra check to disable ASPM on Intel Alder Lake based 
systems.


Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
Link:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=05%7C01%7Crichard.gong%40amd.com%7C509e0378edcf477605a708da231114f0%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637860853537880384%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=SoXDKGHUiiQN4rcL7FpCotouWFt0kkAbcHyO3esfNlE%3D&reserved=0 



Thank you Microsoft Outlook for keeping us safe. :(



Reported-by: kernel test robot 


This tag is a little confusing. Maybe clarify that it was for 
an issue

in a previous patch iteration?


I did describe in change-list version 3 below, which corrected 
the build

error with W=1 option.

It is not good idea to add the description for that to the commit
message, this is why I add descriptions on change-list version 3.


Do as you wish, but the current style is confusing, and readers of 
the

commit are going to think, the kernel test robot reported the problem
with AMD VI ASICs and Intel Alder Lake systems.




Signed-off-by: Richard Gong 
---
v4: s/CONFIG_X86_64/CONFIG_X86
   enhanced check logic
v3: s/intel_core_asom_chk/aspm_support_quirk_check
   correct build error with W=1 option
v2: correct commit description
   move the check from chip family to problematic platform
---
    drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
    1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
b/drivers/gpu/drm/amd/amdgpu/vi.c
index 039b90cdc3bc..b33e0a9bee65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -81,6 +81,10 @@
    #include "mxgpu_vi.h"
    #include "amdgpu_dm.h"

+#if IS_ENABLED(CONFIG_X86)
+#include 
+#endif
+
    #define ixPCIE_LC_L1_PM_SUBSTATE 0x100100C6
    #define 
PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK

0x0001L
    #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK
0x0002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct
amdgpu_device *adev)
    WREG32_PCIE(ixPCIE_LC_CNTL, data);
    }

+static bool aspm_support_quirk_check(void)
+{
+ if (IS_ENABLED(CONFIG_X86)) {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+ return !(c->x86 == 6 && c->x86_model ==
INTEL_FAM6_ALDERLAKE);
+ }
+
+ return true;
+}
+
    static void vi_program_aspm(struct amdgpu_device *adev)
    {
    u32 data, data1, orig;
    bool bL1SS = false;
    bool bClkReqSupport = true;

- if (!amdgpu_device_should_use_aspm(adev))
+ if (!amdgpu_device_should_use_aspm(adev) ||
!aspm_support_quirk_check())
    return;


Can users still forcefully enable ASPM with the parameter
`amdgpu.aspm`?

As Mario mentioned in a separate reply, we can't forcefully 
enable ASPM

with the parameter 'amdgpu.aspm'.


That would be a regression on systems where ASPM used to work. Hmm. I
guess, you could say, there are no such systems.



    if (adev->flags & AMD_IS_APU ||


If I remember correctly, there were also newer cards, where 
ASPM worked
with Intel Alder Lake, right? Can only the problematic 
generations for

WX3200 and RX640 be excluded from ASPM?


This patch only disables it for the generatioaon that was 
problematic.


Could that please be made clear in the commit message summary, and
messag

[linux-next:master] BUILD REGRESSION f1244c81da13009dbf61cb807f45881501c44789

2022-04-20 Thread kernel test robot
tree/branch: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: f1244c81da13009dbf61cb807f45881501c44789  Add linux-next specific 
files for 20220420

Error/Warning reports:

https://lore.kernel.org/linux-mm/202204081656.6x4pfen4-...@intel.com
https://lore.kernel.org/linux-mm/202204140108.derahwen-...@intel.com
https://lore.kernel.org/linux-mm/202204202059.7tv9fkry-...@intel.com
https://lore.kernel.org/lkml/202204140043.tx7bibvi-...@intel.com
https://lore.kernel.org/llvm/202203241958.uw9bwfmd-...@intel.com

Error/Warning: (recently discovered and may have been fixed)

arch/arm/mach-versatile/integrator_ap.c:148:13: warning: no previous prototype 
for 'ap_init_early' [-Wmissing-prototypes]
drivers/bus/mhi/host/main.c:787:13: warning: parameter 'event_quota' set but 
not used [-Wunused-but-set-parameter]
drivers/ntb/hw/idt/ntb_hw_idt.c:1116:1: warning: the frame size of 1288 bytes 
is larger than 1280 bytes [-Wframe-larger-than=]

Unverified Error/Warning (likely false positive, please contact us if 
interested):

Makefile:684: arch/h8300/Makefile: No such file or directory
arch/Kconfig:10: can't open file "arch/h8300/Kconfig"
arch/s390/include/asm/spinlock.h:81:3: error: unexpected token in '.rept' 
directive
arch/s390/include/asm/spinlock.h:81:3: error: unknown directive
arch/s390/include/asm/spinlock.h:81:3: error: unmatched '.endr' directive
arch/s390/lib/spinlock.c:78:3: error: unexpected token in '.rept' directive
arch/s390/lib/spinlock.c:78:3: error: unknown directive
arch/s390/lib/spinlock.c:78:3: error: unmatched '.endr' directive
drivers/dma-buf/st-dma-fence-unwrap.c:125:13: warning: variable 'err' set but 
not used [-Wunused-but-set-variable]
drivers/edac/edac_device.c:79 edac_device_alloc_ctl_info() warn: Please 
consider using kcalloc instead
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubp.c:57:6: warning: no 
previous prototype for 'hubp31_program_extended_blank' [-Wmissing-prototypes]
kernel/bpf/syscall.c:4944:13: warning: no previous prototype for function 
'unpriv_ebpf_notify' [-Wmissing-prototypes]
make[1]: *** No rule to make target 'arch/h8300/Makefile'.
scripts/Makefile.clean:15: arch/h8300/Makefile: No such file or directory
sound/soc/codecs/wm8731.c:654:1: internal compiler error: Segmentation fault

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- alpha-allmodconfig
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- alpha-allyesconfig
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- alpha-randconfig-r024-20220420
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arc-allmodconfig
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arc-allyesconfig
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arc-randconfig-r002-20220420
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arc-randconfig-r043-20220420
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arm-allmodconfig
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arm-allyesconfig
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arm-integrator_defconfig
|   `-- 
arch-arm-mach-versatile-integrator_ap.c:warning:no-previous-prototype-for-ap_init_early
|-- arm-randconfig-c002-20220420
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arm64-allyesconfig
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- arm64-randconfig-c023-20220420
|   `-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|-- h8300-allyesconfig
|   |-- Makefile:arch-h8300-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-h8300-Kconfig
|   `-- make:No-rule-to-make-target-arch-h8300-Makefile-.
|-- h8300-randconfig-r003-20220420
|   `-- scripts-Makefile.clean:arch-h8300-Makefile:No-such-file-or-directory
|-- h8300-randconfig-r032-20220420
|   |-- Makefile:arch-h8300-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-h8300-Kconfig
|   `-- make:No-rule-to-make-target-arch-h8300-Makefile-.
|-- i386-allyesconfig
|   |-- 
drivers-dma-buf-st-dma-fence-unwrap.c:warning:variable-err-set-but-not-used
|   `-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-dcn31-dcn31_hubp.c:warning:no-previous-prototype-for-hubp31_program_extended_blank
|-- i386-randconfig-m021
|   `-- 
drivers-edac-edac_device.c-edac_device_alloc_ctl_info()-warn:Please-consider-using-kcalloc-instead
|-- i386-randconfig-s001
|   |-- fs-io_uring.c:sparse:sparse:marked-inline-but-without-a-definition
|   |-- 
mm-memory.c:sparse:sparse:incorrect

Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Paul Menzel

Dear Richard,


Am 20.04.22 um 22:56 schrieb Gong, Richard:


On 4/20/2022 3:48 PM, Paul Menzel wrote:



Am 20.04.22 um 22:40 schrieb Alex Deucher:
On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel  
wrote:



Am 19.04.22 um 23:46 schrieb Gong, Richard:


On 4/14/2022 2:52 AM, Paul Menzel wrote:

[Cc: -kernel test robot ]


[…]


Am 13.04.22 um 15:00 schrieb Alex Deucher:

On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:



Thank you for sending out v4.

Am 12.04.22 um 23:50 schrieb Richard Gong:

Active State Power Management (ASPM) feature is enabled since
kernel 5.14.
There are some AMD GFX cards (such as WX3200 and RX640) that won't
work
with ASPM-enabled Intel Alder Lake based systems. Using these GFX
cards as
video/display output, Intel Alder Lake based systems will hang 
during

suspend/resume.


[Your email program wraps lines in cited text for some reason, making
the citation harder to read.]



I am still not clear, what “hang during suspend/resume” means. I 
guess
suspending works fine? During resume (S3 or S0ix?), where does 
it hang?

The system is functional, but there are only display problems?

System freeze after suspend/resume.


But you see certain messages still? At what point does it freeze
exactly? In the bug report you posted Linux messages.

The issue was initially reported on one system (Dell Precision 
3660

with
BIOS version 0.14.81), but was later confirmed to affect at 
least 4

Alder
Lake based systems.

Add extra check to disable ASPM on Intel Alder Lake based systems.

Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
Link:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=05%7C01%7Crichard.gong%40amd.com%7C487aaa63098b462e146a08da230f2319%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637860845178176835%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=3IVldn05qNa2XVp1Lu58SriS8k9mk4U9K9p3F3IYPe0%3D&reserved=0 



Thank you Microsoft Outlook for keeping us safe. :(



Reported-by: kernel test robot 


This tag is a little confusing. Maybe clarify that it was for an 
issue

in a previous patch iteration?


I did describe in change-list version 3 below, which corrected the 
build

error with W=1 option.

It is not good idea to add the description for that to the commit
message, this is why I add descriptions on change-list version 3.


Do as you wish, but the current style is confusing, and readers of the
commit are going to think, the kernel test robot reported the problem
with AMD VI ASICs and Intel Alder Lake systems.




Signed-off-by: Richard Gong 
---
v4: s/CONFIG_X86_64/CONFIG_X86
   enhanced check logic
v3: s/intel_core_asom_chk/aspm_support_quirk_check
   correct build error with W=1 option
v2: correct commit description
   move the check from chip family to problematic platform
---
    drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
    1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
b/drivers/gpu/drm/amd/amdgpu/vi.c
index 039b90cdc3bc..b33e0a9bee65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -81,6 +81,10 @@
    #include "mxgpu_vi.h"
    #include "amdgpu_dm.h"

+#if IS_ENABLED(CONFIG_X86)
+#include 
+#endif
+
    #define ixPCIE_LC_L1_PM_SUBSTATE    0x100100C6
    #define 
PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK

0x0001L
    #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK
0x0002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct
amdgpu_device *adev)
    WREG32_PCIE(ixPCIE_LC_CNTL, data);
    }

+static bool aspm_support_quirk_check(void)
+{
+ if (IS_ENABLED(CONFIG_X86)) {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+ return !(c->x86 == 6 && c->x86_model ==
INTEL_FAM6_ALDERLAKE);
+ }
+
+ return true;
+}
+
    static void vi_program_aspm(struct amdgpu_device *adev)
    {
    u32 data, data1, orig;
    bool bL1SS = false;
    bool bClkReqSupport = true;

- if (!amdgpu_device_should_use_aspm(adev))
+ if (!amdgpu_device_should_use_aspm(adev) ||
!aspm_support_quirk_check())
    return;


Can users still forcefully enable ASPM with the parameter
`amdgpu.aspm`?

As Mario mentioned in a separate reply, we can't forcefully enable 
ASPM

with the parameter 'amdgpu.aspm'.


That would be a regression on systems where ASPM used to work. Hmm. I
guess, you could say, there are no such systems.



    if (adev->flags & AMD_IS_APU ||


If I remember correctly, there were also newer cards, where ASPM 
worked
with Intel Alder Lake, right? Can only the problematic 
generations for

WX3200 and RX640 be excluded from ASPM?


This patch only disables it for the generatioaon that was 
problematic.


Could that please be made clear in the commit message summary, and
message?


Are you ok with the commit messages below?


Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Gong, Richard

Hi Paul,

On 4/20/2022 3:48 PM, Paul Menzel wrote:

Dear Alex,


Am 20.04.22 um 22:40 schrieb Alex Deucher:
On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel  
wrote:



Am 19.04.22 um 23:46 schrieb Gong, Richard:


On 4/14/2022 2:52 AM, Paul Menzel wrote:

[Cc: -kernel test robot ]


[…]


Am 13.04.22 um 15:00 schrieb Alex Deucher:

On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:



Thank you for sending out v4.

Am 12.04.22 um 23:50 schrieb Richard Gong:

Active State Power Management (ASPM) feature is enabled since
kernel 5.14.
There are some AMD GFX cards (such as WX3200 and RX640) that won't
work
with ASPM-enabled Intel Alder Lake based systems. Using these GFX
cards as
video/display output, Intel Alder Lake based systems will hang 
during

suspend/resume.


[Your email program wraps lines in cited text for some reason, making
the citation harder to read.]



I am still not clear, what “hang during suspend/resume” means. I 
guess
suspending works fine? During resume (S3 or S0ix?), where does 
it hang?

The system is functional, but there are only display problems?

System freeze after suspend/resume.


But you see certain messages still? At what point does it freeze
exactly? In the bug report you posted Linux messages.

The issue was initially reported on one system (Dell Precision 
3660

with
BIOS version 0.14.81), but was later confirmed to affect at 
least 4

Alder
Lake based systems.

Add extra check to disable ASPM on Intel Alder Lake based systems.

Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
Link:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=05%7C01%7Crichard.gong%40amd.com%7C487aaa63098b462e146a08da230f2319%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637860845178176835%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=3IVldn05qNa2XVp1Lu58SriS8k9mk4U9K9p3F3IYPe0%3D&reserved=0 



Thank you Microsoft Outlook for keeping us safe. :(



Reported-by: kernel test robot 


This tag is a little confusing. Maybe clarify that it was for an 
issue

in a previous patch iteration?


I did describe in change-list version 3 below, which corrected the 
build

error with W=1 option.

It is not good idea to add the description for that to the commit
message, this is why I add descriptions on change-list version 3.


Do as you wish, but the current style is confusing, and readers of the
commit are going to think, the kernel test robot reported the problem
with AMD VI ASICs and Intel Alder Lake systems.




Signed-off-by: Richard Gong 
---
v4: s/CONFIG_X86_64/CONFIG_X86
   enhanced check logic
v3: s/intel_core_asom_chk/aspm_support_quirk_check
   correct build error with W=1 option
v2: correct commit description
   move the check from chip family to problematic platform
---
    drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
    1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
b/drivers/gpu/drm/amd/amdgpu/vi.c
index 039b90cdc3bc..b33e0a9bee65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -81,6 +81,10 @@
    #include "mxgpu_vi.h"
    #include "amdgpu_dm.h"

+#if IS_ENABLED(CONFIG_X86)
+#include 
+#endif
+
    #define ixPCIE_LC_L1_PM_SUBSTATE    0x100100C6
    #define 
PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK

0x0001L
    #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK
0x0002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct
amdgpu_device *adev)
    WREG32_PCIE(ixPCIE_LC_CNTL, data);
    }

+static bool aspm_support_quirk_check(void)
+{
+ if (IS_ENABLED(CONFIG_X86)) {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+ return !(c->x86 == 6 && c->x86_model ==
INTEL_FAM6_ALDERLAKE);
+ }
+
+ return true;
+}
+
    static void vi_program_aspm(struct amdgpu_device *adev)
    {
    u32 data, data1, orig;
    bool bL1SS = false;
    bool bClkReqSupport = true;

- if (!amdgpu_device_should_use_aspm(adev))
+ if (!amdgpu_device_should_use_aspm(adev) ||
!aspm_support_quirk_check())
    return;


Can users still forcefully enable ASPM with the parameter
`amdgpu.aspm`?

As Mario mentioned in a separate reply, we can't forcefully enable 
ASPM

with the parameter 'amdgpu.aspm'.


That would be a regression on systems where ASPM used to work. Hmm. I
guess, you could say, there are no such systems.



    if (adev->flags & AMD_IS_APU ||


If I remember correctly, there were also newer cards, where ASPM 
worked
with Intel Alder Lake, right? Can only the problematic 
generations for

WX3200 and RX640 be excluded from ASPM?


This patch only disables it for the generatioaon that was 
problematic.


Could that please be made clear in the commit message summary, and
message?


Are you ok with the commit messages below?


Please change the commit message summary

Re: [PATCH v3] drm: of: Properly try all possible cases for bridge/panel detection

2022-04-20 Thread Rob Clark
On Tue, Apr 5, 2022 at 10:01 AM Thierry Reding  wrote:
>
> On Fri, Apr 01, 2022 at 09:44:46AM +0200, Paul Kocialkowski wrote:
> > Hi Bjorn,
> >
> > On Thu 31 Mar 22, 20:16, Bjorn Andersson wrote:
> > > On Tue 29 Mar 06:27 PDT 2022, Paul Kocialkowski wrote:
> > >
> > > > While bridge/panel detection was initially relying on the usual
> > > > port/ports-based of graph detection, it was recently changed to
> > > > perform the lookup on any child node that is not port/ports
> > > > instead when such a node is available, with no fallback on the
> > > > usual way.
> > > >
> > > > This results in breaking detection when a child node is present
> > > > but does not contain any panel or bridge node, even when the
> > > > usual port/ports-based of graph is there.
> > > >
> > > > In order to support both situations properly, this commit reworks
> > > > the logic to try both options and not just one of the two: it will
> > > > only return -EPROBE_DEFER when both have failed.
> > > >
> > >
> > > Thanks for your patch Paul, it fixed a regression on a device where I
> > > have a eDP bridge with an of_graph and a aux-bus defined.
> > >
> > > But unfortunately it does not resolve the regression I have for the
> > > USB based DisplayPort setup described below.
> > >
> > >
> > > In the Qualcomm DisplayPort driver We're calling:
> > >
> > > devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
> > >
> > > and with the following DT snippet the behavior changed:
> > >
> > > displayport-controller@ae9 {
> > > compatible = "qcom,sc8180x-dp";
> > > ...
> > >
> > > operating-points-v2 = <&dp0_opp_table>;
> > >
> > > ports {
> > > #address-cells = <1>;
> > > #size-cells = <0>;
> > >
> > > port@0 {
> > > reg = <0>;
> > > dp0_in: endpoint {
> > > remote-endpoint = <&display_driver>;
> > > };
> > > };
> > > };
> > >
> > > dp0_opp_table: opp-table {
> > > ...;
> > > };
> > > };
> > >
> > > Prior to the introduction of 80253168dbfd ("drm: of: Lookup if child
> > > node has panel or bridge") this would return -ENODEV, so we could
> > > differentiate the case when we have a statically defined eDP panel from
> > > that of a dynamically attached (over USB) DP panel.
> > >
> > > Prior to your change, above case without the opp-table node would have
> > > still returned -ENODEV.
> > >
> > > But now this will just return -EPROBE_DEFER in both cases.
> >
> > Oh that's right, the -ENODEV case was just completely removed by my change.
> > Initially this would happen if !of_graph_is_present or if the remote node
> > doesn't exist.
> >
> > Now that we are also checking for child nodes, we can't just return -ENODEV
> > when the graph or remote node is missing: we must also check that there is 
> > no
> > child node that is a panel/bridge.
> >
> > For the graph remote case, we can reliabily return -EPROBE_DEFER when
> > of_graph_is_present and the remote exists and of_device_is_available.
> > Otherwise we can go for -ENODEV. I think getting -EPROBE_DEFER at this point
> > should stop the drm_of_find_panel_or_bridge process.
> >
> > On the other hand for the child panel/bridge node case, I don't see how we
> > can reliably distinguish between -EPROBE_DEFER and -ENODEV, because
> > of_drm_find_panel and of_drm_find_bridge will behave the same if the child
> > node is a not-yet-probed panel/bridge or a totally unrelated node.
> > So I think we should always return -EPROBE_DEFER in that case.
> >
> > As a result you can't get -ENODEV if using the of graph while having any
> > (unrelated) child node there, so your issue remains.
> >
> > Do you see any way we could make this work?
> >
> > > I thought the appropriate method of referencing the dsi panel was to
> > > actually reference that using the of_graph, even though it's a child of
> > > the dsi controller - that's at least how we've done it in e.g. [1].
> > > I find this to be much nicer than to just blindly define that all
> > > children of any sort of display controller must be a bridge or a panel.
> >
> > Yes I totally agree. Given that using the child node directly apparently
> > can't allow us to distinguish between -EPROBE_DEFER/-ENODEV I would be in
> > favor of dropping this mechanism and going with explicit of graph in any 
> > case
> > (even if it's a child node). I don't see any downside to this approach.
> >
> > What do yout think?
>
> This patch has recently starting causing failures on various Tegra
> devices that use drm_of_find_panel_or_bridge() for the case where the
> output might be connected to an eDP or LVDS panel. However, that same
> output could also be connected to an HDMI or DP monitor, in which case
> we obviously don't want a DT representation because it's all
> discoverable.
>
> If I understand correctly, that's similar to what Bjorn described. In my
> case I was able to fix the regression by return

Re: [RESEND v2 2/2] dt-bindings: display: Add STARRY 2081101QFH032011-53G

2022-04-20 Thread Linus Walleij
On Thu, Apr 14, 2022 at 10:19 AM xiazhengqiao
 wrote:

> Add dt-bindings for 10.1" TFT LCD module called STARRY 2081101
> QFH032011-53G.
>
> Signed-off-by: xiazhengqiao 
> Reviewed-by: Rob Herring 

(...)

> +  enable-gpios:
> +description: a GPIO spec for the enable pin

The way this is used in the code makes me suspect this should
be named reset-gpios. What is the name of the pin on the
panel?

It also appears you should tag this as active low so in that case
write that in the description "always tag with GPIO_ACTIVE_LOW"
(and alter the code in the driver to match the inversion)

> +  pp1800-supply:
> +description: core voltage supply

Hm the name of this supply makes me think the display controller is
actually named pp1800. Is this correct?

> +enable-gpios = <&pio 45 0>;

Don't use ordinal flags in examples.

examples:
  - |
#include 
(...)
reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>;

Yours,
Linus Walleij


Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Paul Menzel

Dear Alex,


Am 20.04.22 um 22:40 schrieb Alex Deucher:

On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel  wrote:



Am 19.04.22 um 23:46 schrieb Gong, Richard:


On 4/14/2022 2:52 AM, Paul Menzel wrote:

[Cc: -kernel test robot ]


[…]


Am 13.04.22 um 15:00 schrieb Alex Deucher:

On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:



Thank you for sending out v4.

Am 12.04.22 um 23:50 schrieb Richard Gong:

Active State Power Management (ASPM) feature is enabled since
kernel 5.14.
There are some AMD GFX cards (such as WX3200 and RX640) that won't
work
with ASPM-enabled Intel Alder Lake based systems. Using these GFX
cards as
video/display output, Intel Alder Lake based systems will hang during
suspend/resume.


[Your email program wraps lines in cited text for some reason, making
the citation harder to read.]



I am still not clear, what “hang during suspend/resume” means. I guess
suspending works fine? During resume (S3 or S0ix?), where does it hang?
The system is functional, but there are only display problems?

System freeze after suspend/resume.


But you see certain messages still? At what point does it freeze
exactly? In the bug report you posted Linux messages.


The issue was initially reported on one system (Dell Precision 3660
with
BIOS version 0.14.81), but was later confirmed to affect at least 4
Alder
Lake based systems.

Add extra check to disable ASPM on Intel Alder Lake based systems.

Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
Link:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=04%7C01%7Crichard.gong%40amd.com%7Ce7febed5d6a441c3a58008da1debb99c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637855195670542145%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=7cEnE%2BSM9e5IGFxSLloCLtCOxovBpaPz0Ns0Ta2vVlc%3D&reserved=0


Thank you Microsoft Outlook for keeping us safe. :(



Reported-by: kernel test robot 


This tag is a little confusing. Maybe clarify that it was for an issue
in a previous patch iteration?


I did describe in change-list version 3 below, which corrected the build
error with W=1 option.

It is not good idea to add the description for that to the commit
message, this is why I add descriptions on change-list version 3.


Do as you wish, but the current style is confusing, and readers of the
commit are going to think, the kernel test robot reported the problem
with AMD VI ASICs and Intel Alder Lake systems.




Signed-off-by: Richard Gong 
---
v4: s/CONFIG_X86_64/CONFIG_X86
   enhanced check logic
v3: s/intel_core_asom_chk/aspm_support_quirk_check
   correct build error with W=1 option
v2: correct commit description
   move the check from chip family to problematic platform
---
drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
b/drivers/gpu/drm/amd/amdgpu/vi.c
index 039b90cdc3bc..b33e0a9bee65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -81,6 +81,10 @@
#include "mxgpu_vi.h"
#include "amdgpu_dm.h"

+#if IS_ENABLED(CONFIG_X86)
+#include 
+#endif
+
#define ixPCIE_LC_L1_PM_SUBSTATE0x100100C6
#define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK
0x0001L
#define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK
0x0002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct
amdgpu_device *adev)
WREG32_PCIE(ixPCIE_LC_CNTL, data);
}

+static bool aspm_support_quirk_check(void)
+{
+ if (IS_ENABLED(CONFIG_X86)) {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+ return !(c->x86 == 6 && c->x86_model ==
INTEL_FAM6_ALDERLAKE);
+ }
+
+ return true;
+}
+
static void vi_program_aspm(struct amdgpu_device *adev)
{
u32 data, data1, orig;
bool bL1SS = false;
bool bClkReqSupport = true;

- if (!amdgpu_device_should_use_aspm(adev))
+ if (!amdgpu_device_should_use_aspm(adev) ||
!aspm_support_quirk_check())
return;


Can users still forcefully enable ASPM with the parameter
`amdgpu.aspm`?


As Mario mentioned in a separate reply, we can't forcefully enable ASPM
with the parameter 'amdgpu.aspm'.


That would be a regression on systems where ASPM used to work. Hmm. I
guess, you could say, there are no such systems.



if (adev->flags & AMD_IS_APU ||


If I remember correctly, there were also newer cards, where ASPM worked
with Intel Alder Lake, right? Can only the problematic generations for
WX3200 and RX640 be excluded from ASPM?


This patch only disables it for the generatioaon that was problematic.


Could that please be made clear in the commit message summary, and
message?


Are you ok with the commit messages below?


Please change the commit message summary. Maybe:

drm/amdgpu: VI: Disable ASPM on Intel Alder Lake based systems


Activ

Re: [RESEND v2 1/2] drm/panel: Add inx Himax8279d MIPI-DSI LCD panel driver

2022-04-20 Thread Linus Walleij
On Thu, Apr 14, 2022 at 10:19 AM xiazhengqiao
 wrote:

> Add STARRY 2081101QFH032011-53G 10.1" WUXGA TFT LCD panel
>
> Signed-off-by: xiazhengqiao 
> Tested-by: Hsin-Yi Wang 
> Reviewed-by: Hsin-Yi Wang 

OK cool... Do you know the name of the display controller
used in this panel? We tend to name the implementation, Kconfig
symbols etc after the display controller such as panel-ilitek-*
panel-truly-* panel-novatek-* etc. This would be panel-innolux-xyz.c
in that case. We already have:
panel-innolux-ej030na.c
panel-innolux-p079zca.c

> +struct panel_desc {

Name it after the panel. struct inx_config to reflect other code
in this subsystem.

> +   const struct drm_display_mode *modes;
> +   unsigned int bpc;
> +
> +   /**
> +* @width_mm: width of the panel's active display area
> +* @height_mm: height of the panel's active display area
> +*/
> +   struct {
> +   unsigned int width_mm;
> +   unsigned int height_mm;
> +   } size;

This seems a bit overdesigned, why not just put these two unsigned in the
strict as is without an anonymous struct in the struct?

> +   unsigned long mode_flags;
> +   enum mipi_dsi_pixel_format format;
> +   const struct panel_init_cmd *init_cmds;

OK so a sequence of commands per panel type I get it.

> +   unsigned int lanes;
> +   bool discharge_on_disable;
> +};
> +
> +struct inx_panel {
> +   struct drm_panel base;
> +   struct mipi_dsi_device *dsi;
> +
> +   const struct panel_desc *desc;
> +
> +   enum drm_panel_orientation orientation;
> +   struct regulator *pp1800;
> +   struct regulator *avee;
> +   struct regulator *avdd;

These match the pin names on the chip? (Just checking.)

> +   struct gpio_desc *enable_gpio;
> +
> +   bool prepared;
> +};
> +
> +enum dsi_cmd_type {
> +   INIT_DCS_CMD,
> +   DELAY_CMD,
> +};

I've seen this comand/delay sequencing before. Maybe something
we should generalize as it keeps popping up?

> +struct panel_init_cmd {
> +   enum dsi_cmd_type type;
> +   size_t len;
> +   const char *data;
> +};
> +
> +#define _INIT_DCS_CMD(...) { \
> +   .type = INIT_DCS_CMD, \
> +   .len = sizeof((char[]){__VA_ARGS__}), \
> +   .data = (char[]){__VA_ARGS__} }
> +
> +#define _INIT_DELAY_CMD(...) { \
> +   .type = DELAY_CMD,\
> +   .len = sizeof((char[]){__VA_ARGS__}), \
> +   .data = (char[]){__VA_ARGS__} }

These defines are massive overkill, especially .len, if you look
below it is clear that all of them have ... len = 2 and two that have
len = 1.

If these macros are just for this driver ... drop them, just do something
like:

struct inx_init_tuple {
u8 cmd;
u8 val;
};

static const struct inx_tuple inx_init_seq[] = {
{ .cmd = ..., .val = ...}
   ...
};

Then iterate over this array of structs until you reach
ARRAY_SIZE(inx_init_seq).

Just hardcode the delays etc in the end.

> +static const struct panel_init_cmd starry_qfh032011_53g_init_cmd[] = {
> +   _INIT_DCS_CMD(0xB0, 0x01),

All of these opaque 0xB0 etc, create a proper #define for that parameter
using the name in the datasheet. It's especially helpful if the datasheet is
not public which is usually the case, but I think that you have it?
It's really hard for the next system using this to alter things if they have no
idea what the different parameters are.

> +   _INIT_DCS_CMD(0xC3, 0x4F),
> +   _INIT_DCS_CMD(0xC4, 0x40),
> +   _INIT_DCS_CMD(0xC5, 0x40),
> +   _INIT_DCS_CMD(0xC6, 0x40),
> +   _INIT_DCS_CMD(0xC7, 0x40),
> +   _INIT_DCS_CMD(0xC8, 0x4D),
> +   _INIT_DCS_CMD(0xC9, 0x52),
> +   _INIT_DCS_CMD(0xCA, 0x51),
> +   _INIT_DCS_CMD(0xCD, 0x5D),
> +   _INIT_DCS_CMD(0xCE, 0x5B),
> +   _INIT_DCS_CMD(0xCF, 0x4B),
> +   _INIT_DCS_CMD(0xD0, 0x49),
> +   _INIT_DCS_CMD(0xD1, 0x47),
> +   _INIT_DCS_CMD(0xD2, 0x45),
> +   _INIT_DCS_CMD(0xD3, 0x41),
> +   _INIT_DCS_CMD(0xD7, 0x50),
> +   _INIT_DCS_CMD(0xD8, 0x40),
> +   _INIT_DCS_CMD(0xD9, 0x40),
> +   _INIT_DCS_CMD(0xDA, 0x40),
> +   _INIT_DCS_CMD(0xDB, 0x40),
> +   _INIT_DCS_CMD(0xDC, 0x4E),
> +   _INIT_DCS_CMD(0xDD, 0x52),
> +   _INIT_DCS_CMD(0xDE, 0x51),
> +   _INIT_DCS_CMD(0xE1, 0x5E),
> +   _INIT_DCS_CMD(0xE2, 0x5C),
> +   _INIT_DCS_CMD(0xE3, 0x4C),
> +   _INIT_DCS_CMD(0xE4, 0x4A),
> +   _INIT_DCS_CMD(0xE5, 0x48),
> +   _INIT_DCS_CMD(0xE6, 0x46),
> +   _INIT_DCS_CMD(0xE7, 0x42),
> +   _INIT_DCS_CMD(0xB0, 0x03),
> +   _INIT_DCS_CMD(0xBE, 0x03),
> +   _INIT_DCS_CMD(0xCC, 0x44),
> +   _INIT_DCS_CMD(0xC8, 0x07),
> +   _INIT_DCS_CMD(0xC9, 0x05),
> +   _INIT_DCS_CMD(0xCA, 0x42),
> +   _INIT_DCS_CMD(0xCD, 0x3E),
> +   _INIT_DCS_CMD(0xCF, 0x60),
> +   _INIT_DCS_CMD(0xD2, 0x04),
> +   _INIT_DCS_CMD(0xD3, 0x04),
> +   _INIT_DCS_CMD(0xD4, 0x01),
> +   _INIT_DCS_CMD(0xD5, 0x00),
> +   _INIT_DCS_CMD(0xD6,

Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Alex Deucher
On Wed, Apr 20, 2022 at 4:29 PM Paul Menzel  wrote:
>
> Dear Richard,
>
>
> Am 19.04.22 um 23:46 schrieb Gong, Richard:
>
> > On 4/14/2022 2:52 AM, Paul Menzel wrote:
> >> [Cc: -kernel test robot ]
>
> […]
>
> >> Am 13.04.22 um 15:00 schrieb Alex Deucher:
> >>> On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:
> >>
>  Thank you for sending out v4.
> 
>  Am 12.04.22 um 23:50 schrieb Richard Gong:
> > Active State Power Management (ASPM) feature is enabled since
> > kernel 5.14.
> > There are some AMD GFX cards (such as WX3200 and RX640) that won't
> > work
> > with ASPM-enabled Intel Alder Lake based systems. Using these GFX
> > cards as
> > video/display output, Intel Alder Lake based systems will hang during
> > suspend/resume.
>
> [Your email program wraps lines in cited text for some reason, making
> the citation harder to read.]
>
> 
>  I am still not clear, what “hang during suspend/resume” means. I guess
>  suspending works fine? During resume (S3 or S0ix?), where does it hang?
>  The system is functional, but there are only display problems?
> > System freeze after suspend/resume.
>
> But you see certain messages still? At what point does it freeze
> exactly? In the bug report you posted Linux messages.
>
> > The issue was initially reported on one system (Dell Precision 3660
> > with
> > BIOS version 0.14.81), but was later confirmed to affect at least 4
> > Alder
> > Lake based systems.
> >
> > Add extra check to disable ASPM on Intel Alder Lake based systems.
> >
> > Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
> > Link:
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=04%7C01%7Crichard.gong%40amd.com%7Ce7febed5d6a441c3a58008da1debb99c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637855195670542145%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=7cEnE%2BSM9e5IGFxSLloCLtCOxovBpaPz0Ns0Ta2vVlc%3D&reserved=0
>
> Thank you Microsoft Outlook for keeping us safe. :(
>
> >
> > Reported-by: kernel test robot 
> 
>  This tag is a little confusing. Maybe clarify that it was for an issue
>  in a previous patch iteration?
> >
> > I did describe in change-list version 3 below, which corrected the build
> > error with W=1 option.
> >
> > It is not good idea to add the description for that to the commit
> > message, this is why I add descriptions on change-list version 3.
>
> Do as you wish, but the current style is confusing, and readers of the
> commit are going to think, the kernel test robot reported the problem
> with AMD VI ASICs and Intel Alder Lake systems.
>
> 
> > Signed-off-by: Richard Gong 
> > ---
> > v4: s/CONFIG_X86_64/CONFIG_X86
> >   enhanced check logic
> > v3: s/intel_core_asom_chk/aspm_support_quirk_check
> >   correct build error with W=1 option
> > v2: correct commit description
> >   move the check from chip family to problematic platform
> > ---
> >drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
> >1 file changed, 16 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c
> > b/drivers/gpu/drm/amd/amdgpu/vi.c
> > index 039b90cdc3bc..b33e0a9bee65 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> > @@ -81,6 +81,10 @@
> >#include "mxgpu_vi.h"
> >#include "amdgpu_dm.h"
> >
> > +#if IS_ENABLED(CONFIG_X86)
> > +#include 
> > +#endif
> > +
> >#define ixPCIE_LC_L1_PM_SUBSTATE0x100100C6
> >#define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK
> > 0x0001L
> >#define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK
> > 0x0002L
> > @@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct
> > amdgpu_device *adev)
> >WREG32_PCIE(ixPCIE_LC_CNTL, data);
> >}
> >
> > +static bool aspm_support_quirk_check(void)
> > +{
> > + if (IS_ENABLED(CONFIG_X86)) {
> > + struct cpuinfo_x86 *c = &cpu_data(0);
> > +
> > + return !(c->x86 == 6 && c->x86_model ==
> > INTEL_FAM6_ALDERLAKE);
> > + }
> > +
> > + return true;
> > +}
> > +
> >static void vi_program_aspm(struct amdgpu_device *adev)
> >{
> >u32 data, data1, orig;
> >bool bL1SS = false;
> >bool bClkReqSupport = true;
> >
> > - if (!amdgpu_device_should_use_aspm(adev))
> > + if (!amdgpu_device_should_use_aspm(adev) ||
> > !aspm_support_quirk_check())
> >return;
> 
>  Can users still forcefully enable ASPM with the parameter
>  `amdgpu.aspm`?
> 
> > As Mario mentioned in a separate reply, we can't fo

Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems

2022-04-20 Thread Paul Menzel

Dear Richard,


Am 19.04.22 um 23:46 schrieb Gong, Richard:


On 4/14/2022 2:52 AM, Paul Menzel wrote:

[Cc: -kernel test robot ]


[…]


Am 13.04.22 um 15:00 schrieb Alex Deucher:

On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote:



Thank you for sending out v4.

Am 12.04.22 um 23:50 schrieb Richard Gong:
Active State Power Management (ASPM) feature is enabled since 
kernel 5.14.
There are some AMD GFX cards (such as WX3200 and RX640) that won't 
work
with ASPM-enabled Intel Alder Lake based systems. Using these GFX 
cards as

video/display output, Intel Alder Lake based systems will hang during
suspend/resume.


[Your email program wraps lines in cited text for some reason, making 
the citation harder to read.]




I am still not clear, what “hang during suspend/resume” means. I guess
suspending works fine? During resume (S3 or S0ix?), where does it hang?
The system is functional, but there are only display problems?

System freeze after suspend/resume.


But you see certain messages still? At what point does it freeze 
exactly? In the bug report you posted Linux messages.


The issue was initially reported on one system (Dell Precision 3660 
with
BIOS version 0.14.81), but was later confirmed to affect at least 4 
Alder

Lake based systems.

Add extra check to disable ASPM on Intel Alder Lake based systems.

Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default")
Link: 
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885&data=04%7C01%7Crichard.gong%40amd.com%7Ce7febed5d6a441c3a58008da1debb99c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637855195670542145%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=7cEnE%2BSM9e5IGFxSLloCLtCOxovBpaPz0Ns0Ta2vVlc%3D&reserved=0


Thank you Microsoft Outlook for keeping us safe. :(



Reported-by: kernel test robot 


This tag is a little confusing. Maybe clarify that it was for an issue
in a previous patch iteration?


I did describe in change-list version 3 below, which corrected the build 
error with W=1 option.


It is not good idea to add the description for that to the commit 
message, this is why I add descriptions on change-list version 3.


Do as you wish, but the current style is confusing, and readers of the 
commit are going to think, the kernel test robot reported the problem 
with AMD VI ASICs and Intel Alder Lake systems.





Signed-off-by: Richard Gong 
---
v4: s/CONFIG_X86_64/CONFIG_X86
  enhanced check logic
v3: s/intel_core_asom_chk/aspm_support_quirk_check
  correct build error with W=1 option
v2: correct commit description
  move the check from chip family to problematic platform
---
   drivers/gpu/drm/amd/amdgpu/vi.c | 17 -
   1 file changed, 16 insertions(+), 1 deletion(-)

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

index 039b90cdc3bc..b33e0a9bee65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -81,6 +81,10 @@
   #include "mxgpu_vi.h"
   #include "amdgpu_dm.h"

+#if IS_ENABLED(CONFIG_X86)
+#include 
+#endif
+
   #define ixPCIE_LC_L1_PM_SUBSTATE    0x100100C6
   #define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 
0x0001L
   #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 
0x0002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct 
amdgpu_device *adev)

   WREG32_PCIE(ixPCIE_LC_CNTL, data);
   }

+static bool aspm_support_quirk_check(void)
+{
+ if (IS_ENABLED(CONFIG_X86)) {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+ return !(c->x86 == 6 && c->x86_model == 
INTEL_FAM6_ALDERLAKE);

+ }
+
+ return true;
+}
+
   static void vi_program_aspm(struct amdgpu_device *adev)
   {
   u32 data, data1, orig;
   bool bL1SS = false;
   bool bClkReqSupport = true;

- if (!amdgpu_device_should_use_aspm(adev))
+ if (!amdgpu_device_should_use_aspm(adev) || 
!aspm_support_quirk_check())

   return;


Can users still forcefully enable ASPM with the parameter 
`amdgpu.aspm`?


As Mario mentioned in a separate reply, we can't forcefully enable ASPM 
with the parameter 'amdgpu.aspm'.


That would be a regression on systems where ASPM used to work. Hmm. I 
guess, you could say, there are no such systems.




   if (adev->flags & AMD_IS_APU ||


If I remember correctly, there were also newer cards, where ASPM worked
with Intel Alder Lake, right? Can only the problematic generations for
WX3200 and RX640 be excluded from ASPM?


This patch only disables it for the generatioaon that was problematic.


Could that please be made clear in the commit message summary, and 
message?


Are you ok with the commit messages below?


Please change the commit message summary. Maybe:

drm/amdgpu: VI: Disable ASPM on Intel Alder Lake based systems


Active State Power Management (ASPM) feature is enabled since kernel 5.14.

There are som

Re: [Intel-gfx] [RFC v2 2/2] drm/doc/rfc: VM_BIND uapi definition

2022-04-20 Thread Niranjana Vishwanathapura

On Wed, Mar 30, 2022 at 02:51:41PM +0200, Daniel Vetter wrote:

On Mon, Mar 07, 2022 at 12:31:46PM -0800, Niranjana Vishwanathapura wrote:

VM_BIND und related uapi definitions

Signed-off-by: Niranjana Vishwanathapura 
---
 Documentation/gpu/rfc/i915_vm_bind.h | 176 +++


Maybe as the top level comment: The point of documenting uapi isn't to
just spell out all the fields, but to define _how_ and _why_ things work.
This part is completely missing from these docs here.



Thanks Daniel,

Some of the documentation is in the rst file.
Ok, will add documentation here on _how and _why_.


 1 file changed, 176 insertions(+)
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h

diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h
new file mode 100644
index ..80f00ee6c8a1
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.h


You need to incldue this somewhere so it's rendered, see the previous
examples.


Looking at previous examples, my understanding is this is just a documentation
file at this point which goes into Documentation/gpu/rfc folder and will have to
remove it later once the actual uapi changes lands in 
include/uapi/drm/i915_drm.h.
Let me know if that is incorrect and needs change.




@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/* VM_BIND feature availability through drm_i915_getparam */
+#define I915_PARAM_HAS_VM_BIND 57


Needs to be kernel-docified, which means we need a prep patch that fixes
up the existing mess.



Ok on kernel-doc, but as mentioned above, I am not sure we need prep
patch that fixes up other existing fields at this point.


+
+/* VM_BIND related ioctls */
+#define DRM_I915_GEM_VM_BIND   0x3d
+#define DRM_I915_GEM_VM_UNBIND 0x3e
+#define DRM_I915_GEM_WAIT_USER_FENCE   0x3f
+
+#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_UNBIND   DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
+
+/**
+ * struct drm_i915_gem_vm_bind - VA to object/buffer mapping to [un]bind.


Both binding and unbinding need to specify in excruciating detail what
happens if there's overlaps (existing mappings, or unmapping a range which
has no mapping, or only partially full of maps or different objects) and
fun stuff like that.



Ok, will add those details.


+ */
+struct drm_i915_gem_vm_bind {
+   /** vm to [un]bind */
+   __u32 vm_id;
+
+   /**
+* BO handle or file descriptor.
+* 'fd' value of -1 is reserved for system pages (SVM)
+*/
+   union {
+   __u32 handle; /* For unbind, it is reserved and must be 0 */


I think it'd be a lot cleaner if we do a bind and an unbind struct for
these, instead of mixing it up.



Ok


Also I thought mesa requested to be able to unmap an object from a vm
without a range. Has that been dropped, and confirmed to not be needed.



Hmm...I think it was other way around. ie., to unmap with a range in vm
but without an object. We already support that.


+   __s32 fd;


If we don't need it right away then don't add it yet. If it's planned to
be used then it needs to be documented, but I kinda have no idea why you'd
need an fd for svm?



It is not required for SVM, it was intended for future expanstions and '-1'
was reserved for SVM.
Ok, will remove it for now.


+   }
+
+   /** VA start to [un]bind */
+   __u64 start;
+
+   /** Offset in object to [un]bind */
+   __u64 offset;
+
+   /** VA length to [un]bind */
+   __u64 length;
+
+   /** Flags */
+   __u64 flags;
+   /** Bind the mapping immediately instead of during next submission */


This aint kerneldoc.

Also this needs to specify in much more detail what exactly this means,
and also how it interacts with execbuf.



Ok


So the patch here probably needs to include the missing pieces on the
execbuf side of things. Like how does execbuf work when it's used with a
vm_bind managed vm? That means:
- document the pieces that are there
- then add a patch to document how that all changes with vm_bind


Hmm, I am bit confused. The current execbuff handling documentation is in
i915_gem_execbuffer.c. Not sure how to update it in this design RFC patch.
With VM_BIND support, we only support vm_bind vmas in the execbuff and
based on comments from other patch in this series, we probably should not
allow any execlist entries in vm_bind mode (no implicit syncing and use
an extension for the batch address). May be I can update the rst file
in this series for these information for now. Thoughts?



And do that for everything execbuf can do.


+#define I915_GEM_VM_BIND_IMMEDIATE   (1 

[pull] drm/msm: drm-msm-fixes-2022-04-20 for v5.18

2022-04-20 Thread Rob Clark
Hi Dave & Daniel,

One more fix for v5.18.. actually a revert to fix iommu breakage on
older devices

The following changes since commit 390d645877ffd6dcb55f162d618045b2779217b3:

  drm/msm/gpu: Avoid -Wunused-function with !CONFIG_PM_SLEEP
(2022-04-11 18:35:31 -0700)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/msm.git drm-msm-fixes-2022-04-20

for you to fetch changes up to 0371870b96907bf560ecf7dc3fadc238fadf7845:

  drm/msm: Revert "drm/msm: Stop using iommu_present()" (2022-04-19
10:33:07 -0700)


Dmitry Baryshkov (1):
  drm/msm: Revert "drm/msm: Stop using iommu_present()"

 drivers/gpu/drm/msm/msm_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


Re: [PULL v2] gvt-next

2022-04-20 Thread Jason Gunthorpe
On Wed, Apr 20, 2022 at 02:46:00PM -0300, Jason Gunthorpe wrote:
> On Wed, Apr 20, 2022 at 11:40:33AM -0600, Alex Williamson wrote:
> > On Wed, 20 Apr 2022 13:43:51 -0300
> > Jason Gunthorpe  wrote:
> > 
> > > On Wed, Apr 20, 2022 at 04:34:47PM +, Wang, Zhi A wrote:
> > > > Hi folks:
> > > > 
> > > > Here is the PR of gvt-next. Thanks so much for the patience.
> > > > 
> > > > Mostly it includes the patch bundle of GVT-g re-factor patches for 
> > > > adapting the GVT-g with the
> > > > new MDEV interfaces:
> > > > 
> > > > - Separating the MMIO table from GVT-g. (Zhi)
> > > > - GVT-g re-factor. (Christoph)
> > > > - GVT-g mdev API cleanup. (Jason)
> > > > - GVT-g trace/makefile cleanup. (Jani)
> > > > 
> > > > Thanks so much for making this happen.
> > > > 
> > > > This PR has been tested as following and no problem shows up:
> > > > 
> > > > $dim update-branches
> > > > $dim apply-pull drm-intel-next < this_email.eml
> > > > 
> > > > The following changes since commit 
> > > > 3123109284176b1532874591f7c81f3837bbdc17:
> > > > 
> > > >   Linux 5.18-rc1 (2022-04-03 14:08:21 -0700)
> > > > 
> > > > are available in the Git repository at:
> > > > 
> > > >   https://github.com/intel/gvt-linux 
> > > > tags/gvt-next-2022-04-20-for-christoph
> > > > 
> > > > for you to fetch changes up to ae7875879b7c838bffb42ed6db4658e5c504032e:
> > > > 
> > > >   vfio/mdev: Remove mdev drvdata (2022-04-20 03:15:58 -0400)  
> > > 
> > > This looks well constructed now! thanks
> > > 
> > > Alex you can pull this for VFIO after Jani&co grab it
> > > 
> > > I'll respin my vfio_group series on top of this branch
> > 
> > Sure, so just to confirm tags/gvt-next-2022-04-20-for-christoph is
> > pruned down to exactly the commits we're looking for now?  Thanks,
> 
> Yes, the above is correct and the tag points to commit
> ae7875879b7c838bffb42ed6db4658e5c504032e
> 
> It is the bare minimum series

Actually this topic branch doesn't compile:

../drivers/gpu/drm/i915/intel_gvt_mmio_table.c:7:10: fatal error: 
'display/intel_dmc_regs.h' file not found
#include "display/intel_dmc_regs.h"
 ^~
1 error generated.

:( :(

This is the merge conflict that was mentioned. This topic branch needs
to delete the above intel_dmc_regs.h include file

When drm-intel-next merges this PR then need to add it back as part of
the merge resolution - so explain this in the PR text above and
include a diff that does it when you send it again. (or do the merge
yourself as I showed before, it depends on what drm-intel-next wants)

Jason


Re: [PATCH 00/41] OMAP1 full multiplatform conversion

2022-04-20 Thread Arnd Bergmann
On Wed, Apr 20, 2022 at 7:08 PM Aaro Koskinen  wrote:
> On Tue, Apr 19, 2022 at 03:36:42PM +0200, Arnd Bergmann wrote:
> > From: Arnd Bergmann 
> >
> > This is the full series for converting OMAP1 to multiplatform, rebased
> > from my 2019 attempt to do the same thing. The soc tree contains simpler
> > patches to do the same for iop32x, ixp4xx, ep93xx and s3c24xx, which
> > means we are getting closer to completing this for all ARMv5 platforms
> > (I have patches for PXA, which is the last one remaining).
> >
> > Janusz already tested the branch separately and did the missing work
> > for the common-clk conversion after my previous approach was broken.
>
> I tested the full series on the following OMAP1 boards: ams-delta,
> nokia770, osk, palmte and sx1 (QEMU only).
>
> Apart from the earlyprintk breakage, everything seemed to work OK.

Nice, thanks a lot for testing!

> A minor note, zImage grows about 50 KB with a minimal kernel config. This
> is not yet critical, there's still about 7% headroom on 770 to the 2 MB
> bootloader limit on my setup. Also the decompression time is approaching
> the hardcoded watchdog timeout...

I suspect that most of this is for the added devicetree code, and some
more for the common-clk layer. For the omap1_defconfig, there is some
hope to get part of the overhead back eventually by replacing board files
with dts descriptions that are not part of the zImage itself, but it's unlikely
to ever get smaller than it was.

   Arnd


[PATCH v3 2/2] drm: rcar-du: Add RZ/G2L DSI driver

2022-04-20 Thread Biju Das
This driver supports the MIPI DSI encoder found in the RZ/G2L
SoC. It currently supports DSI mode only.

Signed-off-by: Biju Das 
---
v2->v3:
 * pass rzg2l_mipi_dsi pointer to {Link,Phy} register rd/wr function instead
   of the memory pointer
 * Fixed the comment in rzg2l_mipi_dsi_startup()
 * Removed unnecessary dbg message from rzg2l_mipi_dsi_start_video()
 * DRM bridge parameter initialization moved to probe
 * Replaced dev_dbg->dev_err in rzg2l_mipi_dsi_parse_dt()
 * Inserted the missing blank lane after return in probe()
 * Added missing MODULE_DEVICE_TABLE
 * Added include linux/bits.h in header file
 * Fixed various macros in header file.
 * Reorder the make file for DSI, so that it is no more dependent
   on RZ/G2L DU patch series.
v1->v2:
 * Rework based on dt-binding change (DSI + D-PHY) as single block
 * Replaced link_mmio and phy_mmio with mmio in struct rzg2l_mipi_dsi
 * Replaced rzg2l_mipi_phy_write with rzg2l_mipi_dsi_phy_write
   and rzg2l_mipi_dsi_link_write
 * Replaced rzg2l_mipi_phy_read->rzg2l_mipi_dsi_link_read
RFC->v1:
 * Added "depends on ARCH_RENESAS || COMPILE_TEST" on KCONFIG
   and dropped DRM as it is implied by DRM_BRIDGE
 * Used devm_reset_control_get_exclusive() for reset handle
 * Removed bool hsclkmode from struct rzg2l_mipi_dsi
 * Added error check for pm, using pm_runtime_resume_and_get() instead of
   pm_runtime_get_sync()
 * Added check for unsupported formats in rzg2l_mipi_dsi_host_attach()
 * Avoided read-modify-write stopping hsclock
 * Used devm_platform_ioremap_resource for resource allocation
 * Removed unnecessary assert call from probe and remove.
 * wrap the line after the PTR_ERR() in probe()
 * Updated reset failure messages in probe
 * Fixed the typo arstc->prstc
 * Made hex constants to lower case.
RFC:
 * 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-23-biju.das...@bp.renesas.com/
---
 drivers/gpu/drm/rcar-du/Kconfig   |   8 +
 drivers/gpu/drm/rcar-du/Makefile  |   2 +
 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c  | 690 ++
 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h | 151 
 4 files changed, 851 insertions(+)
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h

diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
index f6e6a6d5d987..3e59c7c213f5 100644
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ b/drivers/gpu/drm/rcar-du/Kconfig
@@ -51,6 +51,14 @@ config DRM_RCAR_MIPI_DSI
help
  Enable support for the R-Car Display Unit embedded MIPI DSI encoders.
 
+config DRM_RZG2L_MIPI_DSI
+   tristate "RZ/G2L MIPI DSI Encoder Support"
+   depends on DRM_BRIDGE && OF
+   depends on ARCH_RENESAS || COMPILE_TEST
+   select DRM_MIPI_DSI
+   help
+ Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders.
+
 config DRM_RCAR_VSP
bool "R-Car DU VSP Compositor Support" if ARM
default y if ARM64
diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile
index e7275b5e7ec8..14a3fa88cc0b 100644
--- a/drivers/gpu/drm/rcar-du/Makefile
+++ b/drivers/gpu/drm/rcar-du/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_DRM_RCAR_DW_HDMI)+= 
rcar_dw_hdmi.o
 obj-$(CONFIG_DRM_RCAR_LVDS)+= rcar_lvds.o
 obj-$(CONFIG_DRM_RCAR_MIPI_DSI)+= rcar_mipi_dsi.o
 
+obj-$(CONFIG_DRM_RZG2L_MIPI_DSI)   += rzg2l_mipi_dsi.o
+
 # 'remote-endpoint' is fixed up at run-time
 DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint
 DTC_FLAGS_rcar_du_of_lvds_r8a7791 += -Wno-graph_endpoint
diff --git a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c 
b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
new file mode 100644
index ..8c3a26bc9624
--- /dev/null
+++ b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/G2L MIPI DSI Encoder Driver
+ *
+ * Copyright (C) 2022 Renesas Electronics Corporation
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "rzg2l_mipi_dsi_regs.h"
+
+struct rzg2l_mipi_dsi {
+   struct device *dev;
+   void __iomem *mmio;
+
+   struct reset_control *rstc;
+   struct reset_control *arstc;
+   struct reset_control *prstc;
+
+   struct mipi_dsi_host host;
+   struct drm_bridge bridge;
+   struct drm_bridge *next_bridge;
+
+   struct clk *vclk;
+
+   enum mipi_dsi_pixel_format format;
+   unsigned int num_data_lanes;
+   unsigned int lanes;
+   unsigned long mode_flags;
+};
+
+static inline struct rzg2l_mipi_dsi *
+bridge_to_rzg2l_mipi_dsi(struct drm_bridge *bridge)
+{
+   return container_of(bridge, struct rzg2l_mipi_dsi, bridge);
+}
+
+static inline struct rzg2l_mipi_dsi *
+host_to_rzg2l_mipi_dsi(struc

[PATCH v3 1/2] dt-bindings: display: bridge: Document RZ/G2L MIPI DSI TX bindings

2022-04-20 Thread Biju Das
The RZ/G2L MIPI DSI TX is embedded in the Renesas RZ/G2L family SoC's. It
can operate in DSI mode, with up to four data lanes.

Signed-off-by: Biju Das 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Geert Uytterhoeven 
---
v2->v3:
 * Added Rb tag from Geert and Laurent
 * Fixed the typo "Receive" -> "transmit"
 * Added accepible values for data-lanes
 * Sorted Header file in the example
 * Added SoC specific compaible along with generic one.
v1->v2:
 * Added full path for dsi-controller.yaml
 * Modeled DSI + D-PHY as single block and updated reg property
 * Fixed typo D_PHY->D-PHY
 * Updated description
 * Added interrupts and interrupt-names and updated the example 
RFC->v1:
 * Added a ref to dsi-controller.yaml.
RFC:-
 * 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-22-biju.das...@bp.renesas.com/
---
 .../bindings/display/bridge/renesas,dsi.yaml  | 182 ++
 1 file changed, 182 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml 
b/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml
new file mode 100644
index ..131d5b63ec4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml
@@ -0,0 +1,182 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/renesas,dsi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/G2L MIPI DSI Encoder
+
+maintainers:
+  - Biju Das 
+
+description: |
+  This binding describes the MIPI DSI encoder embedded in the Renesas
+  RZ/G2L alike family of SoC's. The encoder can operate in DSI mode, with
+  up to four data lanes.
+
+allOf:
+  - $ref: /schemas/display/dsi-controller.yaml#
+
+properties:
+  compatible:
+items:
+  - enum:
+  - renesas,r9a07g044-mipi-dsi # RZ/G2{L,LC}
+  - const: renesas,rzg2l-mipi-dsi
+
+  reg:
+maxItems: 1
+
+  interrupts:
+items:
+  - description: Sequence operation channel 0 interrupt
+  - description: Sequence operation channel 1 interrupt
+  - description: Video-Input operation channel 1 interrupt
+  - description: DSI Packet Receive interrupt
+  - description: DSI Fatal Error interrupt
+  - description: DSI D-PHY PPI interrupt
+  - description: Debug interrupt
+
+  interrupt-names:
+items:
+  - const: seq0
+  - const: seq1
+  - const: vin1
+  - const: rcv
+  - const: ferr
+  - const: ppi
+  - const: debug
+
+  clocks:
+items:
+  - description: DSI D-PHY PLL multiplied clock
+  - description: DSI D-PHY system clock
+  - description: DSI AXI bus clock
+  - description: DSI Register access clock
+  - description: DSI Video clock
+  - description: DSI D-PHY Escape mode transmit clock
+
+  clock-names:
+items:
+  - const: pllclk
+  - const: sysclk
+  - const: aclk
+  - const: pclk
+  - const: vclk
+  - const: lpclk
+
+  resets:
+items:
+  - description: MIPI_DSI_CMN_RSTB
+  - description: MIPI_DSI_ARESET_N
+  - description: MIPI_DSI_PRESET_N
+
+  reset-names:
+items:
+  - const: rst
+  - const: arst
+  - const: prst
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Parallel input port
+
+  port@1:
+$ref: /schemas/graph.yaml#/$defs/port-base
+unevaluatedProperties: false
+description: DSI output port
+
+properties:
+  endpoint:
+$ref: /schemas/media/video-interfaces.yaml#
+unevaluatedProperties: false
+
+properties:
+  data-lanes:
+description: array of physical DSI data lane indexes.
+minItems: 1
+items:
+  - const: 1
+  - const: 2
+  - const: 3
+  - const: 4
+
+required:
+  - data-lanes
+
+required:
+  - port@0
+  - port@1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - power-domains
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dsi0: dsi@1085 {
+compatible = "renesas,r9a07g044-mipi-dsi", "renesas,rzg2l-mipi-dsi";
+reg = <0x1085 0x2>;
+interrupts = ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ;
+interrupt-names = "seq0", "seq1", "vin1", "rcv",
+  "ferr", "ppi", "debug";
+clocks = <&cpg CPG_MOD R9A07G044_MIPI_DSI_PLLCLK>,
+ 

[PATCH v3 0/2] Add RZ/G2L DSI driver

2022-04-20 Thread Biju Das
This patch series aims to support the MIPI DSI encoder found in the RZ/G2L
SoC. It currently supports DSI mode only.

This unit supports MIPI Alliance Specification for Display Serial Interface 
(DSI) Specification. This unit provides a
solution for transmitting MIPI DSI compliant digital video and packets. 
Normative References are below.
* MIPI Alliance Specification for Display Serial Interface Version 1.3.1
* MIPI Alliance Specification for D-PHY Version 2.1

The following are key features of this unit.

* 1 channel
* The number of Lane: 4-lane
* Support up to Full HD (1920 × 1080), 60 fps (RGB888)
* Maximum Bandwidth: 1.5 Gbps per lane
* Support Output Data Format: RGB666 / RGB888

v2->v3:
 * Added Rb tag from Geert and Laurent for the binding patch.
 * Fixed the typo "Receive" -> "transmit"
 * Added accepible values for data-lanes
 * Sorted Header file in the example
 * Added SoC specific compaible along with generic one.
 * pass rzg2l_mipi_dsi pointer to {Link,Phy} register rd/wr function instead
   of the memory pointer
 * Fixed the comment in rzg2l_mipi_dsi_startup()
 * Removed unnecessary dbg message from rzg2l_mipi_dsi_start_video()
 * DRM bridge parameter initialization moved to probe
 * Replaced dev_dbg->dev_err in rzg2l_mipi_dsi_parse_dt()
 * Inserted the missing blank lane after return in probe()
 * Added missing MODULE_DEVICE_TABLE
 * Added include linux/bits.h in header file
 * Fixed various macros in header file.
 * Reorder the make file for DSI, so that it is no more dependent
   on RZ/G2L DU patch series.
v1->v2:
 * Added full path for dsi-controller.yaml
 * Modeled DSI + D-PHY as single block and updated reg property
 * Fixed typo D_PHY->D-PHY
 * Updated description
 * Added interrupts and interrupt-names and updated the example 
 * Driver rework based on dt-binding changes (DSI + D-PHY) as single block
 * Replaced link_mmio and phy_mmio with mmio in struct rzg2l_mipi_dsi
 * Replaced rzg2l_mipi_phy_write with rzg2l_mipi_dsi_phy_write
   and rzg2l_mipi_dsi_link_write
 * Replaced rzg2l_mipi_phy_read->rzg2l_mipi_dsi_link_read
RFC->v1:
 * Added a ref to dsi-controller.yaml.
 * Added "depends on ARCH_RENESAS || COMPILE_TEST" on KCONFIG
   and dropped DRM as it is implied by DRM_BRIDGE
 * Used devm_reset_control_get_exclusive() for reset handle
 * Removed bool hsclkmode from struct rzg2l_mipi_dsi
 * Added error check for pm, using pm_runtime_resume_and_get() instead of
   pm_runtime_get_sync()
 * Added check for unsupported formats in rzg2l_mipi_dsi_host_attach()
 * Avoided read-modify-write stopping hsclock
 * Used devm_platform_ioremap_resource for resource allocation
 * Removed unnecessary assert call from probe and remove.
 * wrap the line after the PTR_ERR() in probe()
 * Updated reset failure messages in probe
 * Fixed the typo arstc->prstc
 * Made hex constants to lower case.
RFC:
 * 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-22-biju.das...@bp.renesas.com/
 * 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-23-biju.das...@bp.renesas.com/

Biju Das (2):
  dt-bindings: display: bridge: Document RZ/G2L MIPI DSI TX bindings
  drm: rcar-du: Add RZ/G2L DSI driver

 .../bindings/display/bridge/renesas,dsi.yaml  | 182 +
 drivers/gpu/drm/rcar-du/Kconfig   |   8 +
 drivers/gpu/drm/rcar-du/Makefile  |   2 +
 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c  | 690 ++
 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h | 151 
 5 files changed, 1033 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h

-- 
2.25.1



Re: [PATCH v2 13/17] drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback

2022-04-20 Thread Dmitry Baryshkov
On Wed, 20 Apr 2022 at 22:36, Abhinav Kumar  wrote:
>
>
>
> On 4/20/2022 12:26 PM, Dmitry Baryshkov wrote:
> > On 20/04/2022 21:17, Abhinav Kumar wrote:
> >>
> >>
> >> On 4/20/2022 12:49 AM, Dmitry Baryshkov wrote:
> >>> On 20/04/2022 04:46, Abhinav Kumar wrote:
>  Introduce the dpu_encoder_phys_* for the writeback interface
>  to handle writeback specific hardware programming.
> 
>  changes in v2:
>  - rebase on msm-next and fix related dependencies namely
>    the irq cleanup
>  - move cdp_cfg, aspace out of dpu_encoder_phys_wb
>  - leave a comment about wb master
>  - start using _dpu_hw_get_qos_lut from dpu_hw_util
>  - replace hw_pp->merge_3d check with DPU_CTL_ACTIVE_CFG
> 
>  Signed-off-by: Abhinav Kumar 
>  ---
>    drivers/gpu/drm/msm/Makefile   |   1 +
>    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |  30 +
>    .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 751
>  +
>    3 files changed, 782 insertions(+)
>    create mode 100644
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> 
>  diff --git a/drivers/gpu/drm/msm/Makefile
>  b/drivers/gpu/drm/msm/Makefile
>  index ca779c1..0387f22 100644
>  --- a/drivers/gpu/drm/msm/Makefile
>  +++ b/drivers/gpu/drm/msm/Makefile
>  @@ -60,6 +60,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
>    disp/dpu1/dpu_encoder.o \
>    disp/dpu1/dpu_encoder_phys_cmd.o \
>    disp/dpu1/dpu_encoder_phys_vid.o \
>  +disp/dpu1/dpu_encoder_phys_wb.o \
>    disp/dpu1/dpu_formats.o \
>    disp/dpu1/dpu_hw_catalog.o \
>    disp/dpu1/dpu_hw_ctl.o \
>  diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>  b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>  index 00951f3..5452f98 100644
>  --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>  +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>  @@ -150,6 +150,7 @@ struct dpu_encoder_phys_ops {
> * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
> * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode
>  panel
> * @INTR_IDX_RDPTR:Readpointer done unterrupt for cmd mode panel
>  + * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
> */
>    enum dpu_intr_idx {
>    INTR_IDX_VSYNC,
>  @@ -157,6 +158,7 @@ enum dpu_intr_idx {
>    INTR_IDX_UNDERRUN,
>    INTR_IDX_CTL_START,
>    INTR_IDX_RDPTR,
>  +INTR_IDX_WB_DONE,
>    INTR_IDX_MAX,
>    };
>  @@ -224,6 +226,27 @@ static inline int
>  dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
>    }
>    /**
>  + * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to
>  handle command
>  + *mode specific operations
>  + * @base:Baseclass physical encoder structure
>  + * @wbirq_refcount: Reference count of writeback interrupt
>  + * @wb_done_timeout_cnt: number of wb done irq timeout errors
>  + * @wb_cfg:  writeback block config to store fb related details
>  + * @wb_conn: backpointer to writeback connector
>  + * @wb_job: backpointer to current writeback job
>  + * @dest:   dpu buffer layout for current writeback output buffer
>  + */
>  +struct dpu_encoder_phys_wb {
>  +struct dpu_encoder_phys base;
>  +atomic_t wbirq_refcount;
>  +int wb_done_timeout_cnt;
>  +struct dpu_hw_wb_cfg wb_cfg;
>  +struct drm_writeback_connector *wb_conn;
>  +struct drm_writeback_job *wb_job;
>  +struct dpu_hw_fmt_layout dest;
>  +};
>  +
>  +/**
> * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to
>  handle command
> *mode specific operations
> * @base:Baseclass physical encoder structure
>  @@ -291,6 +314,13 @@ struct dpu_encoder_phys
>  *dpu_encoder_phys_cmd_init(
>    struct dpu_enc_phys_init_params *p);
>    /**
>  + * dpu_encoder_phys_wb_init - initialize writeback encoder
>  + * @init:Pointer to init info structure with initialization params
>  + */
>  +struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
>  +struct dpu_enc_phys_init_params *p);
>  +
>  +/**
> * dpu_encoder_helper_trigger_start - control start helper function
> *This helper function may be optionally specified by physical
> *encoders if they require ctl_start triggering.
>  diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>  b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>  new file mode 100644
>  index 000..128317fe
>  --- /dev/null
>  +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>  @@ -0,0 +1,751 @@
>  +// SPDX-License-Identifier: GPL-2.0-only

Re: [PATCH v2 13/17] drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback

2022-04-20 Thread Abhinav Kumar




On 4/20/2022 12:26 PM, Dmitry Baryshkov wrote:

On 20/04/2022 21:17, Abhinav Kumar wrote:



On 4/20/2022 12:49 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Introduce the dpu_encoder_phys_* for the writeback interface
to handle writeback specific hardware programming.

changes in v2:
- rebase on msm-next and fix related dependencies namely
  the irq cleanup
- move cdp_cfg, aspace out of dpu_encoder_phys_wb
- leave a comment about wb master
- start using _dpu_hw_get_qos_lut from dpu_hw_util
- replace hw_pp->merge_3d check with DPU_CTL_ACTIVE_CFG

Signed-off-by: Abhinav Kumar 
---
  drivers/gpu/drm/msm/Makefile   |   1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |  30 +
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c    | 751 
+

  3 files changed, 782 insertions(+)
  create mode 100644 
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c


diff --git a/drivers/gpu/drm/msm/Makefile 
b/drivers/gpu/drm/msm/Makefile

index ca779c1..0387f22 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -60,6 +60,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
  disp/dpu1/dpu_encoder.o \
  disp/dpu1/dpu_encoder_phys_cmd.o \
  disp/dpu1/dpu_encoder_phys_vid.o \
+    disp/dpu1/dpu_encoder_phys_wb.o \
  disp/dpu1/dpu_formats.o \
  disp/dpu1/dpu_hw_catalog.o \
  disp/dpu1/dpu_hw_ctl.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h

index 00951f3..5452f98 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -150,6 +150,7 @@ struct dpu_encoder_phys_ops {
   * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
   * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode 
panel

   * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
+ * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
   */
  enum dpu_intr_idx {
  INTR_IDX_VSYNC,
@@ -157,6 +158,7 @@ enum dpu_intr_idx {
  INTR_IDX_UNDERRUN,
  INTR_IDX_CTL_START,
  INTR_IDX_RDPTR,
+    INTR_IDX_WB_DONE,
  INTR_IDX_MAX,
  };
@@ -224,6 +226,27 @@ static inline int 
dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)

  }
  /**
+ * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to 
handle command

+ *    mode specific operations
+ * @base:    Baseclass physical encoder structure
+ * @wbirq_refcount: Reference count of writeback interrupt
+ * @wb_done_timeout_cnt: number of wb done irq timeout errors
+ * @wb_cfg:  writeback block config to store fb related details
+ * @wb_conn: backpointer to writeback connector
+ * @wb_job: backpointer to current writeback job
+ * @dest:   dpu buffer layout for current writeback output buffer
+ */
+struct dpu_encoder_phys_wb {
+    struct dpu_encoder_phys base;
+    atomic_t wbirq_refcount;
+    int wb_done_timeout_cnt;
+    struct dpu_hw_wb_cfg wb_cfg;
+    struct drm_writeback_connector *wb_conn;
+    struct drm_writeback_job *wb_job;
+    struct dpu_hw_fmt_layout dest;
+};
+
+/**
   * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to 
handle command

   *    mode specific operations
   * @base:    Baseclass physical encoder structure
@@ -291,6 +314,13 @@ struct dpu_encoder_phys 
*dpu_encoder_phys_cmd_init(

  struct dpu_enc_phys_init_params *p);
  /**
+ * dpu_encoder_phys_wb_init - initialize writeback encoder
+ * @init:    Pointer to init info structure with initialization params
+ */
+struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
+    struct dpu_enc_phys_init_params *p);
+
+/**
   * dpu_encoder_helper_trigger_start - control start helper function
   *    This helper function may be optionally specified by physical
   *    encoders if they require ctl_start triggering.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c

new file mode 100644
index 000..128317fe
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -0,0 +1,751 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.

+ */
+
+#define pr_fmt(fmt)    "[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include 
+
+#include "dpu_encoder_phys.h"
+#include "dpu_formats.h"
+#include "dpu_hw_top.h"
+#include "dpu_hw_wb.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_blk.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_core_irq.h"
+#include "dpu_vbif.h"
+#include "dpu_crtc.h"
+#include "disp/msm_disp_snapshot.h"
+
+#define DEFAULT_MAX_WRITEBACK_WIDTH 2048
+
+#define to_dpu_encoder_phys_wb(x) \
+    container_of(x, struct dpu_encoder_phys_wb, base)
+
+/**
+ * dpu_encoder_phys_wb_is_master - report wb always as master encoder
+ */
+static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys 
*phys_enc)

+{
+  

Re: [PATCH 03/15] dma-buf & drm/amdgpu: remove dma_resv workaround

2022-04-20 Thread Zack Rusin
On Wed, 2022-04-20 at 20:56 +0200, Christian König wrote:
> ⚠ External Email
> 
> Am 20.04.22 um 20:49 schrieb Christian König:
> > Am 20.04.22 um 20:41 schrieb Zack Rusin:
> > > On Wed, 2022-04-20 at 19:40 +0200, Christian König wrote:
> > > > Am 20.04.22 um 19:38 schrieb Zack Rusin:
> > > > > On Wed, 2022-04-20 at 09:37 +0200, Christian König wrote:
> > > > > > ⚠ External Email
> > > > > > 
> > > > > > Hi Zack,
> > > > > > 
> > > > > > Am 20.04.22 um 05:56 schrieb Zack Rusin:
> > > > > > > On Thu, 2022-04-07 at 10:59 +0200, Christian König wrote:
> > > > > > > > Rework the internals of the dma_resv object to allow
> > > > > > > > adding
> > > > > > > > more
> > > > > > > > than
> > > > > > > > one
> > > > > > > > write fence and remember for each fence what purpose it
> > > > > > > > had.
> > > > > > > > 
> > > > > > > > This allows removing the workaround from amdgpu which
> > > > > > > > used a
> > > > > > > > container
> > > > > > > > for
> > > > > > > > this instead.
> > > > > > > > 
> > > > > > > > Signed-off-by: Christian König
> > > > > > > > 
> > > > > > > > Reviewed-by: Daniel Vetter 
> > > > > > > > Cc: amd-...@lists.freedesktop.org
> > > > > > > afaict this change broke vmwgfx which now kernel oops
> > > > > > > right
> > > > > > > after
> > > > > > > boot.
> > > > > > > I haven't had the time to look into it yet, so I'm not
> > > > > > > sure
> > > > > > > what's
> > > > > > > the
> > > > > > > problem. I'll look at this tomorrow, but just in case you
> > > > > > > have
> > > > > > > some
> > > > > > > clues, the backtrace follows:
> > > > > > that's a known issue and should already be fixed with:
> > > > > > 
> > > > > > commit d72dcbe9fce505228dae43bef9da8f2b707d1b3d
> > > > > > Author: Christian König 
> > > > > > Date:   Mon Apr 11 15:21:59 2022 +0200
> > > > > Unfortunately that doesn't seem to be it. The backtrace is
> > > > > from the
> > > > > current (as of the time of sending of this email) drm-misc-
> > > > > next,
> > > > > which
> > > > > has this change, so it's something else.
> > > > Ok, that's strange. In this case I need to investigate further.
> > > > 
> > > > Maybe VMWGFX is adding more than one fence and we actually need
> > > > to
> > > > reserve multiple slots.
> > > This might be helper code issue with CONFIG_DEBUG_MUTEXES set. On
> > > that config
> > > dma_resv_reset_max_fences does:
> > >     fences->max_fences = fences->num_fences;
> > > For some objects num_fences is 0 and so after max_fences and
> > > num_fences are both 0.
> > > And then BUG_ON(num_fences >= max_fences) is triggered.
> > 
> > Yeah, but that's expected behavior.
> > 
> > What's not expected is that max_fences is still 0 (or equal to old
> > num_fences) when VMWGFX tries to add a new fence. The function
> > ttm_eu_reserve_buffers() should have reserved at least one fence
> > slot.
> > 
> > So the underlying problem is that either ttm_eu_reserve_buffers()
> > was
> > never called or VMWGFX tried to add more than one fence.
> 
> 
> To figure out what it is could you try the following code fragment:
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
> index f46891012be3..a36f89d3f36d 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
> @@ -288,7 +288,7 @@ int vmw_validation_add_bo(struct
> vmw_validation_context *ctx,
>  val_buf->bo = ttm_bo_get_unless_zero(&vbo->base);
>  if (!val_buf->bo)
>  return -ESRCH;
> -   val_buf->num_shared = 0;
> +   val_buf->num_shared = 16;
>  list_add_tail(&val_buf->head, &ctx->bo_list);
>  bo_node->as_mob = as_mob;
>  bo_node->cpu_blit = cpu_blit;

Fails the same BUG_ON with num_fences and max_fences == 0.

z


Re: [PATCH v2 14/17] drm/msm/dpu: add the writeback connector layer

2022-04-20 Thread Dmitry Baryshkov

On 20/04/2022 04:46, Abhinav Kumar wrote:

Introduce the dpu_writeback module which serves as the
interface between dpu operations and the drm_writeback.

This module manages the connector related operations for
dpu writeback.

changes in v2:
- start using drm_writeback_connector_init_with_encoder()
- drop unnecessary arguments from dpu_writeback_init()
- rebase on msm-next tip and remove usage of priv->connectors

Signed-off-by: Abhinav Kumar 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/Makefile  |  1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c | 68 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h | 25 ++
  3 files changed, 94 insertions(+)
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 0387f22..66395ee 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -80,6 +80,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_plane.o \
disp/dpu1/dpu_rm.o \
disp/dpu1/dpu_vbif.o \
+   disp/dpu1/dpu_writeback.o
  
  msm-$(CONFIG_DRM_MSM_MDSS) += \

msm_mdss.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
new file mode 100644
index 000..526d884
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "dpu_writeback.h"
+
+static int dpu_wb_conn_get_modes(struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+
+   return drm_add_modes_noedid(connector, dev->mode_config.max_width,
+   dev->mode_config.max_height);
+}
+
+static const struct drm_connector_funcs dpu_wb_conn_funcs = {
+   .reset = drm_atomic_helper_connector_reset,
+   .fill_modes = drm_helper_probe_single_connector_modes,
+   .destroy = drm_connector_cleanup,
+   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int dpu_wb_conn_prepare_job(struct drm_writeback_connector *connector,
+   struct drm_writeback_job *job)
+{
+   if (!job->fb)
+   return 0;
+
+   dpu_encoder_prepare_wb_job(connector->encoder, job);
+
+   return 0;
+}
+
+static void dpu_wb_conn_cleanup_job(struct drm_writeback_connector *connector,
+   struct drm_writeback_job *job)
+{
+   if (!job->fb)
+   return;
+
+   dpu_encoder_cleanup_wb_job(connector->encoder, job);
+}
+
+static const struct drm_connector_helper_funcs dpu_wb_conn_helper_funcs = {
+   .get_modes = dpu_wb_conn_get_modes,
+   .prepare_writeback_job = dpu_wb_conn_prepare_job,
+   .cleanup_writeback_job = dpu_wb_conn_cleanup_job,
+};
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+   const u32 *format_list, u32 num_formats)
+{
+   struct dpu_wb_connector *dpu_wb_conn;
+   int rc = 0;
+
+   dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL);
+
+   drm_connector_helper_add(&dpu_wb_conn->base.base, 
&dpu_wb_conn_helper_funcs);
+
+   /* DPU initializes the encoder and sets it up completely for writeback
+* cases and hence should use the new API 
drm_writeback_connector_init_with_encoder
+* to initialize the writeback connector
+*/
+   rc = drm_writeback_connector_init_with_encoder(dev, &dpu_wb_conn->base, 
enc,
+   &dpu_wb_conn_funcs, format_list, num_formats);
+
+   return rc;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
new file mode 100644
index 000..05aff05
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DPU_WRITEBACK_H
+#define _DPU_WRITEBACK_H
+
+#include 
+#include 
+#include 
+#include 
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_encoder_phys.h"
+
+struct dpu_wb_connector {
+   struct drm_writeback_connector base;
+};
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+   const u32 *format_list, u32 num_formats);
+
+#endif /*_DPU_WRITEBACK_H */



--
With best wishes
Dmitry


Re: [PATCH v2 14/17] drm/msm/dpu: add the writeback connector layer

2022-04-20 Thread Dmitry Baryshkov

On 20/04/2022 22:10, Abhinav Kumar wrote:



On 4/20/2022 12:52 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Introduce the dpu_writeback module which serves as the
interface between dpu operations and the drm_writeback.

This module manages the connector related operations for
dpu writeback.

changes in v2:
- start using drm_writeback_connector_init_with_encoder()
- drop unnecessary arguments from dpu_writeback_init()
- rebase on msm-next tip and remove usage of priv->connectors

Signed-off-by: Abhinav Kumar 
---
  drivers/gpu/drm/msm/Makefile  |  1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c | 68 
+++

  drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h | 25 ++
  3 files changed, 94 insertions(+)
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 0387f22..66395ee 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -80,6 +80,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
  disp/dpu1/dpu_plane.o \
  disp/dpu1/dpu_rm.o \
  disp/dpu1/dpu_vbif.o \
+    disp/dpu1/dpu_writeback.o
  msm-$(CONFIG_DRM_MSM_MDSS) += \
  msm_mdss.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c

new file mode 100644
index 000..526d884
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.

+ */
+
+#include "dpu_writeback.h"
+
+static int dpu_wb_conn_get_modes(struct drm_connector *connector)
+{
+    struct drm_device *dev = connector->dev;
+
+    return drm_add_modes_noedid(connector, dev->mode_config.max_width,
+    dev->mode_config.max_height);
+}
+
+static const struct drm_connector_funcs dpu_wb_conn_funcs = {
+    .reset = drm_atomic_helper_connector_reset,
+    .fill_modes = drm_helper_probe_single_connector_modes,
+    .destroy = drm_connector_cleanup,
+    .atomic_duplicate_state = 
drm_atomic_helper_connector_duplicate_state,

+    .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int dpu_wb_conn_prepare_job(struct drm_writeback_connector 
*connector,

+    struct drm_writeback_job *job)
+{
+    if (!job->fb)
+    return 0;
+
+    dpu_encoder_prepare_wb_job(connector->encoder, job);
+
+    return 0;
+}
+
+static void dpu_wb_conn_cleanup_job(struct drm_writeback_connector 
*connector,

+    struct drm_writeback_job *job)
+{
+    if (!job->fb)
+    return;
+
+    dpu_encoder_cleanup_wb_job(connector->encoder, job);
+}
+
+static const struct drm_connector_helper_funcs 
dpu_wb_conn_helper_funcs = {

+    .get_modes = dpu_wb_conn_get_modes,
+    .prepare_writeback_job = dpu_wb_conn_prepare_job,
+    .cleanup_writeback_job = dpu_wb_conn_cleanup_job,
+};
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+    const u32 *format_list, u32 num_formats)
+{
+    struct dpu_wb_connector *dpu_wb_conn;
+    int rc = 0;
+
+    dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), 
GFP_KERNEL);

+
+    drm_connector_helper_add(&dpu_wb_conn->base.base, 
&dpu_wb_conn_helper_funcs);

+
+    /* DPU initializes the encoder and sets it up completely for 
writeback
+ * cases and hence should use the new API 
drm_writeback_connector_init_with_encoder

+ * to initialize the writeback connector
+ */
+    rc = drm_writeback_connector_init_with_encoder(dev, 
&dpu_wb_conn->base, enc,

+    &dpu_wb_conn_funcs, format_list, num_formats);
+
+    return rc;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h

new file mode 100644
index 000..05aff05
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.

+ */
+
+#ifndef _DPU_WRITEBACK_H
+#define _DPU_WRITEBACK_H
+
+#include 
+#include 
+#include 
+#include 
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_encoder_phys.h"
+
+struct dpu_wb_connector {
+    struct drm_writeback_connector base;
+};


Do you plan to add more fields to this struct? If not, we can probably 
drop it and use struct drm_writeback_connector directly.


Glad you asked about it. I was expecting this question because it looks 
like a very "light" struct.


Yes, we do plan to expand this as we will keep adding writeback features 
sequentially now to make it ready for this to be absorbed downstream 
completely.


Then a separate struct is fine with me.






+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+    const u32 *format_list, u32 num_formats);
+
+#endif /*_DPU_WRITEBACK_H */




Re: [PATCH v2 13/17] drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback

2022-04-20 Thread Dmitry Baryshkov

On 20/04/2022 21:17, Abhinav Kumar wrote:



On 4/20/2022 12:49 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Introduce the dpu_encoder_phys_* for the writeback interface
to handle writeback specific hardware programming.

changes in v2:
- rebase on msm-next and fix related dependencies namely
  the irq cleanup
- move cdp_cfg, aspace out of dpu_encoder_phys_wb
- leave a comment about wb master
- start using _dpu_hw_get_qos_lut from dpu_hw_util
- replace hw_pp->merge_3d check with DPU_CTL_ACTIVE_CFG

Signed-off-by: Abhinav Kumar 
---
  drivers/gpu/drm/msm/Makefile   |   1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |  30 +
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c    | 751 
+

  3 files changed, 782 insertions(+)
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index ca779c1..0387f22 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -60,6 +60,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
  disp/dpu1/dpu_encoder.o \
  disp/dpu1/dpu_encoder_phys_cmd.o \
  disp/dpu1/dpu_encoder_phys_vid.o \
+    disp/dpu1/dpu_encoder_phys_wb.o \
  disp/dpu1/dpu_formats.o \
  disp/dpu1/dpu_hw_catalog.o \
  disp/dpu1/dpu_hw_ctl.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h

index 00951f3..5452f98 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -150,6 +150,7 @@ struct dpu_encoder_phys_ops {
   * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
   * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
   * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
+ * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
   */
  enum dpu_intr_idx {
  INTR_IDX_VSYNC,
@@ -157,6 +158,7 @@ enum dpu_intr_idx {
  INTR_IDX_UNDERRUN,
  INTR_IDX_CTL_START,
  INTR_IDX_RDPTR,
+    INTR_IDX_WB_DONE,
  INTR_IDX_MAX,
  };
@@ -224,6 +226,27 @@ static inline int 
dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)

  }
  /**
+ * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to 
handle command

+ *    mode specific operations
+ * @base:    Baseclass physical encoder structure
+ * @wbirq_refcount: Reference count of writeback interrupt
+ * @wb_done_timeout_cnt: number of wb done irq timeout errors
+ * @wb_cfg:  writeback block config to store fb related details
+ * @wb_conn: backpointer to writeback connector
+ * @wb_job: backpointer to current writeback job
+ * @dest:   dpu buffer layout for current writeback output buffer
+ */
+struct dpu_encoder_phys_wb {
+    struct dpu_encoder_phys base;
+    atomic_t wbirq_refcount;
+    int wb_done_timeout_cnt;
+    struct dpu_hw_wb_cfg wb_cfg;
+    struct drm_writeback_connector *wb_conn;
+    struct drm_writeback_job *wb_job;
+    struct dpu_hw_fmt_layout dest;
+};
+
+/**
   * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to 
handle command

   *    mode specific operations
   * @base:    Baseclass physical encoder structure
@@ -291,6 +314,13 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
  struct dpu_enc_phys_init_params *p);
  /**
+ * dpu_encoder_phys_wb_init - initialize writeback encoder
+ * @init:    Pointer to init info structure with initialization params
+ */
+struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
+    struct dpu_enc_phys_init_params *p);
+
+/**
   * dpu_encoder_helper_trigger_start - control start helper function
   *    This helper function may be optionally specified by physical
   *    encoders if they require ctl_start triggering.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c

new file mode 100644
index 000..128317fe
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -0,0 +1,751 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.

+ */
+
+#define pr_fmt(fmt)    "[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include 
+
+#include "dpu_encoder_phys.h"
+#include "dpu_formats.h"
+#include "dpu_hw_top.h"
+#include "dpu_hw_wb.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_blk.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_core_irq.h"
+#include "dpu_vbif.h"
+#include "dpu_crtc.h"
+#include "disp/msm_disp_snapshot.h"
+
+#define DEFAULT_MAX_WRITEBACK_WIDTH 2048
+
+#define to_dpu_encoder_phys_wb(x) \
+    container_of(x, struct dpu_encoder_phys_wb, base)
+
+/**
+ * dpu_encoder_phys_wb_is_master - report wb always as master encoder
+ */
+static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys 
*phys_enc)

+{
+    /* there is only one physical enc for dpu_writeback */
+ 

Re: [PATCH 26/41] ARM: omap1: relocate static I/O mapping

2022-04-20 Thread Arnd Bergmann
On Wed, Apr 20, 2022 at 3:46 PM Aaro Koskinen  wrote:
>
> Hi,
>
> On Tue, Apr 19, 2022 at 03:37:08PM +0200, Arnd Bergmann wrote:
> > From: Arnd Bergmann 
> >
> > The address range 0xfee0-0xfeff is used for PCI and
> > PCMCIA I/O port mappings, but OMAP1 has its static mappings
> > there as well.
> >
> > Move the OMAP1 addresses a little higher to avoid crashing
> > at boot.
>
> This has the same problem I reported in 2019, with earlyprintk the
> system no longer boots:
>
> https://marc.info/?t=15653001425&r=1&w=2
>
> Tested on OSK and SX1/qemu.

Thanks a lot for testing!

I managed to get to the bottom of this after just a few hours, and
it turned out to be a simple math error on my end, as I got
the alignment wrong, the offset has to be 0x00f0
instead of 0x00fb be section aligned. I made sure the
kernel boots up (to the point of missing a rootfs) and uploaded
the fixed branch.

  Arnd


Re: [PATCH v2 14/17] drm/msm/dpu: add the writeback connector layer

2022-04-20 Thread Abhinav Kumar




On 4/20/2022 12:52 AM, Dmitry Baryshkov wrote:

On 20/04/2022 04:46, Abhinav Kumar wrote:

Introduce the dpu_writeback module which serves as the
interface between dpu operations and the drm_writeback.

This module manages the connector related operations for
dpu writeback.

changes in v2:
- start using drm_writeback_connector_init_with_encoder()
- drop unnecessary arguments from dpu_writeback_init()
- rebase on msm-next tip and remove usage of priv->connectors

Signed-off-by: Abhinav Kumar 
---
  drivers/gpu/drm/msm/Makefile  |  1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c | 68 
+++

  drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h | 25 ++
  3 files changed, 94 insertions(+)
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 0387f22..66395ee 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -80,6 +80,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
  disp/dpu1/dpu_plane.o \
  disp/dpu1/dpu_rm.o \
  disp/dpu1/dpu_vbif.o \
+    disp/dpu1/dpu_writeback.o
  msm-$(CONFIG_DRM_MSM_MDSS) += \
  msm_mdss.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c

new file mode 100644
index 000..526d884
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.

+ */
+
+#include "dpu_writeback.h"
+
+static int dpu_wb_conn_get_modes(struct drm_connector *connector)
+{
+    struct drm_device *dev = connector->dev;
+
+    return drm_add_modes_noedid(connector, dev->mode_config.max_width,
+    dev->mode_config.max_height);
+}
+
+static const struct drm_connector_funcs dpu_wb_conn_funcs = {
+    .reset = drm_atomic_helper_connector_reset,
+    .fill_modes = drm_helper_probe_single_connector_modes,
+    .destroy = drm_connector_cleanup,
+    .atomic_duplicate_state = 
drm_atomic_helper_connector_duplicate_state,

+    .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int dpu_wb_conn_prepare_job(struct drm_writeback_connector 
*connector,

+    struct drm_writeback_job *job)
+{
+    if (!job->fb)
+    return 0;
+
+    dpu_encoder_prepare_wb_job(connector->encoder, job);
+
+    return 0;
+}
+
+static void dpu_wb_conn_cleanup_job(struct drm_writeback_connector 
*connector,

+    struct drm_writeback_job *job)
+{
+    if (!job->fb)
+    return;
+
+    dpu_encoder_cleanup_wb_job(connector->encoder, job);
+}
+
+static const struct drm_connector_helper_funcs 
dpu_wb_conn_helper_funcs = {

+    .get_modes = dpu_wb_conn_get_modes,
+    .prepare_writeback_job = dpu_wb_conn_prepare_job,
+    .cleanup_writeback_job = dpu_wb_conn_cleanup_job,
+};
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+    const u32 *format_list, u32 num_formats)
+{
+    struct dpu_wb_connector *dpu_wb_conn;
+    int rc = 0;
+
+    dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), 
GFP_KERNEL);

+
+    drm_connector_helper_add(&dpu_wb_conn->base.base, 
&dpu_wb_conn_helper_funcs);

+
+    /* DPU initializes the encoder and sets it up completely for 
writeback
+ * cases and hence should use the new API 
drm_writeback_connector_init_with_encoder

+ * to initialize the writeback connector
+ */
+    rc = drm_writeback_connector_init_with_encoder(dev, 
&dpu_wb_conn->base, enc,

+    &dpu_wb_conn_funcs, format_list, num_formats);
+
+    return rc;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h

new file mode 100644
index 000..05aff05
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights 
reserved.

+ */
+
+#ifndef _DPU_WRITEBACK_H
+#define _DPU_WRITEBACK_H
+
+#include 
+#include 
+#include 
+#include 
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_encoder_phys.h"
+
+struct dpu_wb_connector {
+    struct drm_writeback_connector base;
+};


Do you plan to add more fields to this struct? If not, we can probably 
drop it and use struct drm_writeback_connector directly.


Glad you asked about it. I was expecting this question because it looks 
like a very "light" struct.


Yes, we do plan to expand this as we will keep adding writeback features 
sequentially now to make it ready for this to be absorbed downstream 
completely.





+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+    const u32 *format_list, u32 num_formats);
+
+#endif /*_DPU_WRITEBACK_H */





Re: [PATCH 03/15] dma-buf & drm/amdgpu: remove dma_resv workaround

2022-04-20 Thread Christian König

Am 20.04.22 um 20:49 schrieb Christian König:

Am 20.04.22 um 20:41 schrieb Zack Rusin:

On Wed, 2022-04-20 at 19:40 +0200, Christian König wrote:

Am 20.04.22 um 19:38 schrieb Zack Rusin:

On Wed, 2022-04-20 at 09:37 +0200, Christian König wrote:

⚠ External Email

Hi Zack,

Am 20.04.22 um 05:56 schrieb Zack Rusin:

On Thu, 2022-04-07 at 10:59 +0200, Christian König wrote:

Rework the internals of the dma_resv object to allow adding
more
than
one
write fence and remember for each fence what purpose it had.

This allows removing the workaround from amdgpu which used a
container
for
this instead.

Signed-off-by: Christian König 
Reviewed-by: Daniel Vetter 
Cc: amd-...@lists.freedesktop.org

afaict this change broke vmwgfx which now kernel oops right
after
boot.
I haven't had the time to look into it yet, so I'm not sure
what's
the
problem. I'll look at this tomorrow, but just in case you have
some
clues, the backtrace follows:

that's a known issue and should already be fixed with:

commit d72dcbe9fce505228dae43bef9da8f2b707d1b3d
Author: Christian König 
Date:   Mon Apr 11 15:21:59 2022 +0200

Unfortunately that doesn't seem to be it. The backtrace is from the
current (as of the time of sending of this email) drm-misc-next,
which
has this change, so it's something else.

Ok, that's strange. In this case I need to investigate further.

Maybe VMWGFX is adding more than one fence and we actually need to
reserve multiple slots.
This might be helper code issue with CONFIG_DEBUG_MUTEXES set. On 
that config

dma_resv_reset_max_fences does:
    fences->max_fences = fences->num_fences;
For some objects num_fences is 0 and so after max_fences and 
num_fences are both 0.

And then BUG_ON(num_fences >= max_fences) is triggered.


Yeah, but that's expected behavior.

What's not expected is that max_fences is still 0 (or equal to old 
num_fences) when VMWGFX tries to add a new fence. The function 
ttm_eu_reserve_buffers() should have reserved at least one fence slot.


So the underlying problem is that either ttm_eu_reserve_buffers() was 
never called or VMWGFX tried to add more than one fence.



To figure out what it is could you try the following code fragment:

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c

index f46891012be3..a36f89d3f36d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
@@ -288,7 +288,7 @@ int vmw_validation_add_bo(struct 
vmw_validation_context *ctx,

    val_buf->bo = ttm_bo_get_unless_zero(&vbo->base);
    if (!val_buf->bo)
    return -ESRCH;
-   val_buf->num_shared = 0;
+   val_buf->num_shared = 16;
    list_add_tail(&val_buf->head, &ctx->bo_list);
    bo_node->as_mob = as_mob;
    bo_node->cpu_blit = cpu_blit;

Thanks,
Christian.



Regards,
Christian.



z







Re: [PATCH 03/15] dma-buf & drm/amdgpu: remove dma_resv workaround

2022-04-20 Thread Christian König

Am 20.04.22 um 20:41 schrieb Zack Rusin:

On Wed, 2022-04-20 at 19:40 +0200, Christian König wrote:

Am 20.04.22 um 19:38 schrieb Zack Rusin:

On Wed, 2022-04-20 at 09:37 +0200, Christian König wrote:

⚠ External Email

Hi Zack,

Am 20.04.22 um 05:56 schrieb Zack Rusin:

On Thu, 2022-04-07 at 10:59 +0200, Christian König wrote:

Rework the internals of the dma_resv object to allow adding
more
than
one
write fence and remember for each fence what purpose it had.

This allows removing the workaround from amdgpu which used a
container
for
this instead.

Signed-off-by: Christian König 
Reviewed-by: Daniel Vetter 
Cc: amd-...@lists.freedesktop.org

afaict this change broke vmwgfx which now kernel oops right
after
boot.
I haven't had the time to look into it yet, so I'm not sure
what's
the
problem. I'll look at this tomorrow, but just in case you have
some
clues, the backtrace follows:

that's a known issue and should already be fixed with:

commit d72dcbe9fce505228dae43bef9da8f2b707d1b3d
Author: Christian König 
Date:   Mon Apr 11 15:21:59 2022 +0200

Unfortunately that doesn't seem to be it. The backtrace is from the
current (as of the time of sending of this email) drm-misc-next,
which
has this change, so it's something else.

Ok, that's strange. In this case I need to investigate further.

Maybe VMWGFX is adding more than one fence and we actually need to
reserve multiple slots.

This might be helper code issue with CONFIG_DEBUG_MUTEXES set. On that config
dma_resv_reset_max_fences does:
fences->max_fences = fences->num_fences;
For some objects num_fences is 0 and so after max_fences and num_fences are 
both 0.
And then BUG_ON(num_fences >= max_fences) is triggered.


Yeah, but that's expected behavior.

What's not expected is that max_fences is still 0 (or equal to old 
num_fences) when VMWGFX tries to add a new fence. The function 
ttm_eu_reserve_buffers() should have reserved at least one fence slot.


So the underlying problem is that either ttm_eu_reserve_buffers() was 
never called or VMWGFX tried to add more than one fence.


Regards,
Christian.



z





Re: [PATCH v2 06/17] drm/msm/dpu: add dpu_hw_wb abstraction for writeback blocks

2022-04-20 Thread Dmitry Baryshkov
On Wed, 20 Apr 2022 at 21:11, Abhinav Kumar  wrote:
>
> Hi Dmitry
>
> Sorry, I missed answering one question.
>
> On 4/20/2022 10:49 AM, Dmitry Baryshkov wrote:
> > On Wed, 20 Apr 2022 at 20:01, Abhinav Kumar  
> > wrote:
> >>
> >>
> >>
> >> On 4/20/2022 12:20 AM, Dmitry Baryshkov wrote:
> >>> On 20/04/2022 04:45, Abhinav Kumar wrote:
>  Add the dpu_hw_wb abstraction to program registers related to the
>  writeback block. These will be invoked once all the configuration
>  is set and ready to be programmed to the registers.
> 
>  changes in v2:
>   - remove multiple empty lines at the end of the file
>   - change dpu_hw_wb_bind_pingpong_blk to preserve upper bits
> 
>  Signed-off-by: Abhinav Kumar 
>  Reviewed-by: Dmitry Baryshkov 
> >>>
> >>> It's still Reviewed-by, few nits below.
> >>>
>  ---
> drivers/gpu/drm/msm/Makefile  |   1 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 273
>  ++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 131 ++
> 3 files changed, 405 insertions(+)
> create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
> create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
> 
>  diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
>  index d5ca2e6..ca779c1 100644
>  --- a/drivers/gpu/drm/msm/Makefile
>  +++ b/drivers/gpu/drm/msm/Makefile
>  @@ -74,6 +74,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
> disp/dpu1/dpu_hw_top.o \
> disp/dpu1/dpu_hw_util.o \
> disp/dpu1/dpu_hw_vbif.o \
>  +disp/dpu1/dpu_hw_wb.o \
> disp/dpu1/dpu_kms.o \
> disp/dpu1/dpu_plane.o \
> disp/dpu1/dpu_rm.o \
>  diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
>  b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
>  new file mode 100644
>  index 000..afa8aab
>  --- /dev/null
>  +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
>  @@ -0,0 +1,273 @@
>  +// SPDX-License-Identifier: GPL-2.0-only
>  + /*
>  +  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights
>  reserved
>  +  */
>  +
>  +#include "dpu_hw_mdss.h"
>  +#include "dpu_hwio.h"
>  +#include "dpu_hw_catalog.h"
>  +#include "dpu_hw_wb.h"
>  +#include "dpu_formats.h"
>  +#include "dpu_kms.h"
>  +
>  +#define WB_DST_FORMAT 0x000
>  +#define WB_DST_OP_MODE0x004
>  +#define WB_DST_PACK_PATTERN   0x008
>  +#define WB_DST0_ADDR  0x00C
>  +#define WB_DST1_ADDR  0x010
>  +#define WB_DST2_ADDR  0x014
>  +#define WB_DST3_ADDR  0x018
>  +#define WB_DST_YSTRIDE0   0x01C
>  +#define WB_DST_YSTRIDE1   0x020
>  +#define WB_DST_YSTRIDE1   0x020
>  +#define WB_DST_DITHER_BITDEPTH0x024
>  +#define WB_DST_MATRIX_ROW00x030
>  +#define WB_DST_MATRIX_ROW10x034
>  +#define WB_DST_MATRIX_ROW20x038
>  +#define WB_DST_MATRIX_ROW30x03C
>  +#define WB_DST_WRITE_CONFIG   0x048
>  +#define WB_ROTATION_DNSCALER  0x050
>  +#define WB_ROTATOR_PIPE_DOWNSCALER0x054
>  +#define WB_N16_INIT_PHASE_X_C03   0x060
>  +#define WB_N16_INIT_PHASE_X_C12   0x064
>  +#define WB_N16_INIT_PHASE_Y_C03   0x068
>  +#define WB_N16_INIT_PHASE_Y_C12   0x06C
>  +#define WB_OUT_SIZE   0x074
>  +#define WB_ALPHA_X_VALUE  0x078
>  +#define WB_DANGER_LUT 0x084
>  +#define WB_SAFE_LUT   0x088
>  +#define WB_QOS_CTRL   0x090
>  +#define WB_CREQ_LUT_0 0x098
>  +#define WB_CREQ_LUT_1 0x09C
>  +#define WB_UBWC_STATIC_CTRL   0x144
>  +#define WB_MUX0x150
>  +#define WB_CROP_CTRL  0x154
>  +#define WB_CROP_OFFSET0x158
>  +#define WB_CSC_BASE   0x260
>  +#define WB_DST_ADDR_SW_STATUS 0x2B0
>  +#define WB_CDP_CNTL   0x2B4
>  +#define WB_OUT_IMAGE_SIZE 0x2C0
>  +#define WB_OUT_XY 0x2C4
>  +
>  +/* WB_QOS_CTRL */
>  +#define WB_QOS_CTRL_DANGER_SAFE_ENBIT(0)
>  +
>  +static const struct dpu_wb_cfg *_wb_offset(enum dpu_wb wb,
>  +const struct dpu_mdss_cfg *m, void __iomem *addr,
>  +struct dpu_hw_b

Re: [PATCH v2 08/17] drm/msm/dpu: add changes to support writeback in hw_ctl

2022-04-20 Thread Dmitry Baryshkov
On Wed, 20 Apr 2022 at 20:16, Abhinav Kumar  wrote:
>
>
>
> On 4/19/2022 11:59 PM, Dmitry Baryshkov wrote:
> > On 20/04/2022 04:46, Abhinav Kumar wrote:
> >> Add changes to support writeback module in the dpu_hw_ctl
> >> interface.
> >>
> >> changes in v2:
> >> - keep only the wb specific changes to reset_intf_cfg
> >> - use cfg->intf / cfg->wb to identify intf or wb
> >> - use bit-wise OR for the wb bits while programming
> >>
> >> Signed-off-by: Abhinav Kumar 
> >> ---
> >>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 43
> >> +++---
> >>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 15 ++-
> >>   2 files changed, 53 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> >> index 524f024..495a9cd 100644
> >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> >> @@ -1,5 +1,6 @@
> >>   // SPDX-License-Identifier: GPL-2.0-only
> >> -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
> >> +/* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights
> >> reserved.
> >> + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
> >>*/
> >>   #include 
> >> @@ -23,10 +24,12 @@
> >>   #define   CTL_SW_RESET  0x030
> >>   #define   CTL_LAYER_EXTN_OFFSET 0x40
> >>   #define   CTL_MERGE_3D_ACTIVE   0x0E4
> >> +#define   CTL_WB_ACTIVE 0x0EC
> >>   #define   CTL_INTF_ACTIVE   0x0F4
> >>   #define   CTL_MERGE_3D_FLUSH0x100
> >>   #define   CTL_DSC_ACTIVE0x0E8
> >>   #define   CTL_DSC_FLUSH0x104
> >> +#define   CTL_WB_FLUSH  0x108
> >>   #define   CTL_INTF_FLUSH0x110
> >>   #define   CTL_INTF_MASTER   0x134
> >>   #define   CTL_FETCH_PIPE_ACTIVE 0x0FC
> >> @@ -38,6 +41,7 @@
> >>   #define  MERGE_3D_IDX   23
> >>   #define  DSC_IDX22
> >>   #define  INTF_IDX   31
> >> +#define WB_IDX  16
> >>   #define CTL_INVALID_BIT 0x
> >>   #define CTL_DEFAULT_GROUP_ID0xf
> >> @@ -135,6 +139,9 @@ static inline void
> >> dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
> >>   if (ctx->pending_flush_mask & BIT(INTF_IDX))
> >>   DPU_REG_WRITE(&ctx->hw, CTL_INTF_FLUSH,
> >>   ctx->pending_intf_flush_mask);
> >> +if (ctx->pending_flush_mask & BIT(WB_IDX))
> >> +DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
> >> +ctx->pending_wb_flush_mask);
> >>   DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
> >>   }
> >> @@ -255,6 +262,13 @@ static void
> >> dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx,
> >>   }
> >>   }
> >> +static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl
> >> *ctx,
> >> +enum dpu_wb wb)
> >> +{
> >> +ctx->pending_wb_flush_mask |= BIT(wb - WB_0);
> >> +ctx->pending_flush_mask |= BIT(WB_IDX);
> >> +}
> >> +
> >>   static void dpu_hw_ctl_update_pending_flush_intf_v1(struct
> >> dpu_hw_ctl *ctx,
> >>   enum dpu_intf intf)
> >>   {
> >> @@ -504,6 +518,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct
> >> dpu_hw_ctl *ctx,
> >>   {
> >>   struct dpu_hw_blk_reg_map *c = &ctx->hw;
> >>   u32 intf_active = 0;
> >> +u32 wb_active = 0;
> >>   u32 mode_sel = 0;
> >>   /* CTL_TOP[31:28] carries group_id to collate CTL paths
> >> @@ -519,11 +534,20 @@ static void dpu_hw_ctl_intf_cfg_v1(struct
> >> dpu_hw_ctl *ctx,
> >>   if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
> >>   mode_sel |= BIT(17);
> >> -intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
> >> -intf_active |= BIT(cfg->intf - INTF_0);
> >> +if (cfg->intf) {
> >> +intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
> >> +intf_active |= BIT(cfg->intf - INTF_0);
> >> +}
> >> +
> >> +if (cfg->wb) {
> >> +wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
> >> +wb_active |= BIT(cfg->wb - WB_0);
> >> +}
> >>   DPU_REG_WRITE(c, CTL_TOP, mode_sel);
> >>   DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
> >> +DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
> >
> > This will not work as expected. If cfg->intf is not set, CTL_INTF_ACTIVE
> > will be reset to 0 (while it should have been retained). Please change
> > this to always read CTL_INTF_ACTIVE/CTL_WB_ACTIVE.
>
> ack, and thanks for catching this.
> Yes, i need to add the always read part back.
>
> >
> >> +
> >>   if (cfg->merge_3d)
> >>   DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
> >> BIT(cfg->merge_3d - MERGE_3D_0));
> >> @@ -546,6 +570,9 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl
> >> *ctx,
> >>   intf_cfg |= (cfg->mode_3d - 0x1) << 20;
> >>   }
> >> +if (cfg->wb)
> >> +intf_cfg |= (cfg->wb & 0x3) + 2;
> >> +
> >
> > Ugh. I see that we 

  1   2   3   >