Re: [PATCH] drm: xlnx: remove defined but not used 'scaling_factors_666'

2020-09-11 Thread Hyun Kwon
On Fri, Sep 11, 2020 at 09:27:08AM -0700, Hyun Kwon wrote:
> Hi Daniel,
> 
> On Fri, Sep 11, 2020 at 01:15:19AM -0700, Daniel Vetter wrote:
> > On Thu, Sep 10, 2020 at 11:14:18AM -0700, Hyun Kwon wrote:
> > > Hi Jason,
> > > 
> > > On Thu, Sep 10, 2020 at 07:06:30AM -0700, Jason Yan wrote:
> > > > This addresses the following gcc warning with "make W=1":
> > > > 
> > > > drivers/gpu/drm/xlnx/zynqmp_disp.c:245:18: warning:
> > > > ‘scaling_factors_666’ defined but not used [-Wunused-const-variable=]
> > > >   245 | static const u32 scaling_factors_666[] = {
> > > >   |  ^~~
> > > > 
> > > > Reported-by: Hulk Robot 
> > > > Signed-off-by: Jason Yan 
> > > 
> > > Reviewed-by: Hyun Kwon 
> > 
> > I think you're the maintainer, so please also push patches to
> > drm-misc-next. Otherwise they'll just get lost, or at least it's very
> > confusing when a maintainer reviews a patch but there's no indication what
> > will happen with the patch.
> 
> Right. I wanted to give it some time before pushing. I'll clearly state going
> forward.
> 

Pushed to drm-misc/drm-misc-next.

Thanks,
-hyun

> Thanks,
> -hyun
> 
> > -Daniel
> > 
> > > 
> > > Thanks!
> > > 
> > > -hyun
> > > 
> > > > ---
> > > >  drivers/gpu/drm/xlnx/zynqmp_disp.c | 6 --
> > > >  1 file changed, 6 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c 
> > > > b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > > > index a455cfc1bee5..98bd48f13fd1 100644
> > > > --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > > > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > > > @@ -242,12 +242,6 @@ static const u32 scaling_factors_565[] = {
> > > > ZYNQMP_DISP_AV_BUF_5BIT_SF,
> > > >  };
> > > >  
> > > > -static const u32 scaling_factors_666[] = {
> > > > -   ZYNQMP_DISP_AV_BUF_6BIT_SF,
> > > > -   ZYNQMP_DISP_AV_BUF_6BIT_SF,
> > > > -   ZYNQMP_DISP_AV_BUF_6BIT_SF,
> > > > -};
> > > > -
> > > >  static const u32 scaling_factors_888[] = {
> > > > ZYNQMP_DISP_AV_BUF_8BIT_SF,
> > > > ZYNQMP_DISP_AV_BUF_8BIT_SF,
> > > > -- 
> > > > 2.25.4
> > > > 
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: backend-drm and scanning really large resolutions

2020-09-11 Thread Xiaowen Wu

On 2020-02-13 05:16, Daniel Vetter wrote:

On Thu, Feb 13, 2020 at 11:37:40AM +0200, Pekka Paalanen wrote:

Adding Rob back in CC, I don't know if he is subscribed to
wayland-devel@. You forgot to CC dri-devel@ too.


On Tue, 11 Feb 2020 17:18:52 -0500
Xiaowen Wu  wrote:

> Hi Rob,
>
> If the vendor driver doesn't have the hwpipe sub-object and kms plane is
> one-to-one mapped to hwpipe (sspp),
> do you think if below approach is acceptable if we still want to
> virtualize the kms plane to support 4K/8K scanout?
>
> 1. At kms atomic check before calling drm_atomic_helper_check, depending
> on scanout width of plane A in state, add idle planes B (C,D,...)
> into the same atomic state, backup and then modify
> src_x/src_w/crtc_x/crtc_w of plane A and the affected planes B (C,D,...)
> to meet scanout
> width limits, and set crtc/fb of the affected planes B (C,D,...) same as
> plane A.
>
> 2. At plane's state duplicate function, check if plane's
> src_x/src_w/crtc_x/crtc_w are updated at step 1), if so revert the
> change to
> plane A's backup value to allow plane A's scanout to update again. These
> value will again be updated in step 1) so nothing really changes
> if plane A continues updating.
>
> 3. If plane A's scanout is updated or detached from crtc, detach
> affected planes B (C,D,...) in the same atomic state in step 1) and then
> run step 1) again.
>
> 4. If user want to commit plane B (C,D,...), the commit/test will fail
> if planes are already used as sister plane of plane A. This failure is
> same
> as insufficient hwpipe from plane B (C,D,...).
>
> With above change, any downstream driver can support virtualized plane.
> Also as the above approach is generic and not h/w specific, we can make
> it a helper function and it's up to vendor to choose if they want to use
> or not, if they don't have logic like drm/msm/disp/mdp5/mdp5_plane in
> their downstream driver.
>
> Conceptional above changes didn't borrow hwpipe resources from other
> plane but borrow planes themselves directly, however from user point of
> view
> they should not feel any difference.
>
> What do you think?


The trouble with modifying the real plane states (instead of a 2nd 
layer

of hw objects) is that changes the userspace visible state. Which could
confuse the heck out of userspace. That's why in all these cases where 
the
hw needs 2 things in gang mode (we have other examples where you need 
to

double up clocks or crtcs or whatever in other drivers/hw) we've made a
driver specific layer - that way you can store the stuff you exactly 
need,

and not something generic.

Maybe there is some room for generic helpers, but you'd need to prove 
your

case by converting a few drivers over to this model. There's a lot
already which virtualize planes in one way or another, but they're all
slightly different. Thus far simply rolling your own in each driver
proved to be quicker.
-Daniel


>
> BR,
> Xiaowen Wu
>
>
> On Tue Jan 21, 2020 at 4:12 PM Rob Clark  wrote:
> > On Fri, Jan 17, 2020 at 8:52 AM Matt Hoosier  > gmail.com> wrote:
> >>
> >> Hi all,
> >>
> >> I'm confronting a situation where the hardware with which I work is
> >> capable of driving connectors at 4K or 8K, but doing so requires
> >> bonding the scanning of multiple planes together.
> >>
> >> The scenario is that you'd have a big primary framebuffer whose size
> >> is too large for an individual hardware scanning pipeline on the
> >> display controller to traverse within its maximum allowed clock rate.
> >>
> >> The hardware supplier's approach is to assign multiple planes, which
> >> in the KMS driver map to hardware scanning pipelines, to each be
> >> responsible for scanning a smaller section of the framebuffer. The
> >> planes are all assigned to the same CRTC, and in concert with each
> >> other they cover the whole area of the framebuffer and CRTC.
> >>
> >> This sounds a little bit wild to me. I hadn't been aware it's even
> >> legal to have more than one plane treated a the source of scanout for
> >> a single framebuffer. Maybe that distinction isn't really relevant
> >> nowadays with universal plane support.
> >>
> >
> > fwiw, have a look at drm/msm/disp/mdp5/mdp5_plane, which will allocate
> > one or two hwpipe's from the devices global atomic state, depending on
> > scanout width.. the hwpipe (sspp) is the physical resource behind a
> > plane, so essentially the kms planes are virtualized.  At some point
> > if you have too many wide layers, the atomic test step will fail due
> > to insufficient hwpipe's.  But this sort of scenario is the reason for
> > the test step.
> >
> > BR,
> > -R
> >
> >> I'm wondering if anybody here knows whether this a legit approach for
> >> a compositor's DRM backend to take?
> >>
> ___
> wayland-devel mailing list
> wayland-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel






___
wayland-devel mail

Re: [RFC PATCH v2 10/17] WIP: gpu: host1x: Add no-recovery mode

2020-09-11 Thread Mikko Perttunen

On 9/11/20 7:40 PM, Dmitry Osipenko wrote:

05.09.2020 13:34, Mikko Perttunen пишет:

+   } else {
+   struct host1x_job *failed_job = job;
+
+   host1x_job_dump(dev, job);
+
+   host1x_syncpt_set_locked(job->syncpt);
+   failed_job->cancelled = true;
+
+   list_for_each_entry_continue(job, &cdma->sync_queue, list) {
+   unsigned int i;
+
+   if (job->syncpt != failed_job->syncpt)
+   continue;
+
+   for (i = 0; i < job->num_slots; i++) {
+   unsigned int slot = (job->first_get/8 + i) %
+   HOST1X_PUSHBUFFER_SLOTS;
+   u32 *mapped = cdma->push_buffer.mapped;
+
+   mapped[2*slot+0] = 0x1bad;
+   mapped[2*slot+1] = 0x1bad;


The 0x1bad is a valid memory address on Tegra20.

The 0x6000 is invalid phys address for all hardware generations.
It's used by grate-kernel [1] and VDE driver [2]. Note that the 0x6 <<
28 is also invalid Host1x opcode, while 0x1 should break CDMA parser
during of PB debug-dumping.

[1]
https://github.com/grate-driver/linux/blob/master/drivers/gpu/drm/tegra/gem.h#L16

[2]
https://elixir.bootlin.com/linux/v5.9-rc4/source/drivers/staging/media/tegra-vde/iommu.c#L99

The VDE driver reserves the trapping IOVA addresses, I assume the Host1x
driver should do the same.



The 0x1bad's are not intended to be memory addresses, they are NOOP 
opcodes (INCR of 0 words to offset 0xbad). I'll fix this to use proper 
functions to construct the opcodes and add some comments. These need to 
be NOOP opcodes so the command parser skips over these "cancelled" jobs 
when the channel is resumed.


BTW, 0x6000 is valid on Tegra194 and later.

Mikko
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/msm/adreno: fix probe without iommu

2020-09-11 Thread Jordan Crouse
On Fri, Sep 11, 2020 at 06:08:53PM +0200, Luca Weiss wrote:
> The function iommu_domain_alloc returns NULL on platforms without IOMMU
> such as msm8974. This resulted in PTR_ERR(-ENODEV) being assigned to
> gpu->aspace so the correct code path wasn't taken.
> 
> Fixes: ccac7ce373c1 ("drm/msm: Refactor address space initialization")
> Signed-off-by: Luca Weiss 

Reviewed-by: Jordan Crouse 

> ---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index 862dd35b27d3..6e8bef1a9ea2 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -189,10 +189,16 @@ struct msm_gem_address_space *
>  adreno_iommu_create_address_space(struct msm_gpu *gpu,
>   struct platform_device *pdev)
>  {
> - struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
> - struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu);
> + struct iommu_domain *iommu;
> + struct msm_mmu *mmu;
>   struct msm_gem_address_space *aspace;
>  
> + iommu = iommu_domain_alloc(&platform_bus_type);
> + if (!iommu)
> + return NULL;
> +
> + mmu = msm_iommu_new(&pdev->dev, iommu);
> +
>   aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
>   0x - SZ_16M);
>  
> -- 
> 2.28.0
> 

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


RE: [PATCH v7 2/4] drm/kmb: Add support for KeemBay Display

2020-09-11 Thread Chrisanthus, Anitha
Hi Neil,
Thanks for your review. Is a device tree binding document like this one enough? 
Entries for kmb-drm are similar to this.
https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/gpu/brcm%2Cbcm-v3d.txt

How do I submit it once I have it ready?

Thanks,
Anitha

> -Original Message-
> From: Neil Armstrong 
> Sent: Thursday, September 10, 2020 2:33 AM
> To: Chrisanthus, Anitha ; dri-
> de...@lists.freedesktop.org; Paauwe, Bob J ;
> Dea, Edmund J 
> Cc: Vetter, Daniel 
> Subject: Re: [PATCH v7 2/4] drm/kmb: Add support for KeemBay Display
> 
> On 31/08/2020 22:02, Anitha Chrisanthus wrote:
> > This is a basic KMS atomic modesetting display driver for KeemBay family
> of
> > SOCs. Driver has no 2D or 3D graphics.It calls into the ADV bridge
> > driver at the connector level.
> >
> > Single CRTC with LCD controller->mipi DSI-> ADV bridge
> >
> > Only 1080p resolution and single plane is supported at this time.
> >
> > v2: moved extern to .h, removed license text
> > use drm_dev_init, upclassed dev_private, removed HAVE_IRQ.(Sam)
> >
> > v3: Squashed all 59 commits to one
> >
> > v4: review changes from Sam Ravnborg
> > renamed dev_p to kmb
> > moved clocks under kmb_clock, consolidated clk initializations
> > use drmm functions
> > use DRM_GEM_CMA_DRIVER_OPS_VMAP
> >
> > v5: corrected spellings
> > v6: corrected checkpatch warnings
> > v7: review changes Sam Ravnborg and Thomas Zimmerman
> > removed kmb_crtc.h kmb_crtc_cleanup (Thomas)
> > renamed mode_set, kmb_load, inlined unload (Thomas)
> > moved remaining logging to drm_*(Thomas)
> > re-orged driver initialization (Thomas)
> > moved plane_status to drm_private (Sam)
> > removed unnecessary logs and defines and ifdef codes (Sam)
> > call helper_check in plane_atomic_check (Sam)
> > renamed set to get for bpp and format functions(Sam)
> > use drm helper functions for reset, duplicate/destroy state instead
> > of kmb functions (Sam)
> > removed kmb_priv from kmb_plane and removed kmb_plane_state
> (Sam)
> >
> > Cc: Sam Ravnborg 
> > Signed-off-by: Anitha Chrisanthus 
> > Reviewed-by: Bob Paauwe 
> > ---
> >  drivers/gpu/drm/kmb/kmb_crtc.c  | 224 +
> >  drivers/gpu/drm/kmb/kmb_drv.c   | 676
> 
> >  drivers/gpu/drm/kmb/kmb_drv.h   | 170 ++
> >  drivers/gpu/drm/kmb/kmb_plane.c | 480
> 
> >  drivers/gpu/drm/kmb/kmb_plane.h | 110 +++
> >  5 files changed, 1660 insertions(+)
> >  create mode 100644 drivers/gpu/drm/kmb/kmb_crtc.c
> >  create mode 100644 drivers/gpu/drm/kmb/kmb_drv.c
> >  create mode 100644 drivers/gpu/drm/kmb/kmb_drv.h
> >  create mode 100644 drivers/gpu/drm/kmb/kmb_plane.c
> >  create mode 100644 drivers/gpu/drm/kmb/kmb_plane.h
> >
> 
> [...]
> 
> > +
> > +static const struct of_device_id kmb_of_match[] = {
> > +   {.compatible = "intel,kmb_display"},
> > +   {},
> > +};
> 
> As I already commented on v1, a proper YAML bindings files
> is mandatory here, to check if the bindings are correct and if
> the drivers uses them correctly (port/endpoints, etc..)
> 
> Neil
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/1] drm/amdgpu: Convert to using devm_drm_dev_alloc()

2020-09-11 Thread Luben Tuikov
On 2020-09-08 16:09, Luben Tuikov wrote:
> On 2020-09-07 04:07, Daniel Vetter wrote:
>> On Mon, Sep 07, 2020 at 10:06:08AM +0200, Daniel Vetter wrote:
>>> On Sat, Sep 05, 2020 at 11:50:05AM -0400, Alex Deucher wrote:
 On Thu, Sep 3, 2020 at 9:22 PM Luben Tuikov  wrote:
>
> Convert to using devm_drm_dev_alloc(),
> as drm_dev_init() is going away.
>
> Signed-off-by: Luben Tuikov 

 I think we can drop the final drm_put in the error case?  I think the
 unwinding in current devm code should take care of it.
>>>
>>> Same applies for the pci remove hook too.
>>
>> KASAN run with unload should have caught this. 
> 
> But it didn't? Why?
> Could it be that drm_dev_put() actually got
> the kref to 0 and then drm_dev_release()
> was called which did a kfree()?
> 
> Could you try that same unload KASAN run but
> with your suggestion of removing drm_dev_put() from
> amdgpu_pci_remove()? What do you get then?

Hi Daniel,

Have you had a chance to run this unload KASAN run with
your suggestion of removing drm_dev_put() from
the PCI release hook?

If it "should have caught this", but it didn't,
perhaps it did catch it when you removed the drm_dev_put()
hook from the PCI release hook, when you did a KASAN unload run?
Showing that drm_dev_put() is still necessary, since,
1) we're still using kref,
2) kref is kref-init-ed under devm_drm_dev_alloc() as I pointed
   out in my reply to Alex in this thread.

I believe KASAN (and logic) show this patch to be solid.

> 
>> I strongly recommend doing
>> that for any changes to the unload code, it's way to easy to mix up
>> something and release it in the wrong order or from the wrong callback or
>> with the wrong managed (devm_ vs drmm_) functions.
> 
> Sorry, I don't understand what you mean by "doing that"? Do
> you mean "not calling drm_dev_put()"? Sure, but what
> are we supposed to call instead?
> 
> I also don't understand what you mean by "easy to mix up something
> and release it in wrong order or from the wrong callback..." etc.
> 
> If you want things to happen in certain order,
> you can either put the correct-order-sequence
> behind the non-zero-->0 transition of kref, say in
> drm_dev_release() as it is right now,
> 
> static void drm_dev_release(struct kref *ref)
> {
> struct drm_device *dev = container_of(ref, struct drm_device, ref);
> 
> if (dev->driver->release)
> dev->driver->release(dev);
> 
> drm_managed_release(dev);
> 
> kfree(dev->managed.final_kfree);
> }
> 
> Or you can remove kref from DRM dev (which I do not
> recommend), and stipulate the release sequence
> as I asked in Message-ID: <165961bb-3b5b-cedc-2fc0-838b7999d...@amd.com>,
> "Re: [PATCH] drm/managed: Cleanup of unused functions and polishing docs".
> 
> Then we can follow that and submit patches to conform.

Eagerly awaiting your response on this so that we can conform
to the direction you're setting forth.

Are you removing kref (release() cb) from DRM and if so,
what function should we call in order to do the "final"
(although without kref, the notion of "final" is obviated)
free, OR kref stays in and this patch, which conforms
to using devm_drm_dev_alloc(), as postulated by you,
can go in.

Regards,
Luben

> 
> Regards,
> Luben
> 
> 
> 
>> -Daniel
>>
>>> -Daniel

 Alex

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 11 +++
>  1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 146a85c8df1c..06d994187c24 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -1142,18 +1142,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
> if (ret)
> return ret;
>
> -   adev = kzalloc(sizeof(*adev), GFP_KERNEL);
> -   if (!adev)
> -   return -ENOMEM;
> +   adev = devm_drm_dev_alloc(&pdev->dev, &kms_driver, typeof(*adev), 
> ddev);
> +   if (IS_ERR(adev))
> +   return PTR_ERR(adev);
>
> adev->dev  = &pdev->dev;
> adev->pdev = pdev;
> ddev = adev_to_drm(adev);
> -   ret = drm_dev_init(ddev, &kms_driver, &pdev->dev);
> -   if (ret)
> -   goto err_free;
> -
> -   drmm_add_final_kfree(ddev, adev);
>
> if (!supports_atomic)
> ddev->driver_features &= ~DRIVER_ATOMIC;
> --
> 2.28.0.394.ge197136389
>
> ___
> amd-gfx mailing list
> amd-...@lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=02%7C01%7Cluben.tuikov%40amd.com%7C0c811cf4c16d4f79bc0d08d853051125%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637350628521258815&sdata=k

Re: [PATCH v2 3/4] drm/amd/display: Add pipe_state tracepoint

2020-09-11 Thread Rodrigo Siqueira
On 09/11, Kazlauskas, Nicholas wrote:
> On 2020-09-11 10:59 a.m., Rodrigo Siqueira wrote:
> > This commit introduces a trace mechanism for struct pipe_ctx by adding a
> > middle layer struct in the amdgpu_dm_trace.h for capturing the most
> > important data from struct pipe_ctx and showing its data via tracepoint.
> > This tracepoint was added to dc.c and dcn10_hw_sequencer, however, it
> > can be added to other DCN architecture.
> > 
> > Co-developed-by: Nicholas Kazlauskas 
> > Signed-off-by: Nicholas Kazlauskas 
> > Signed-off-by: Rodrigo Siqueira 
> 
> 
> This patch, while very useful, unfortunately pulls in a lot of DM code into
> DC so I would prefer to hold off on this one for now.

Hi Nicholas, first of all, thanks for your feedback.

By "pulls in a lot of DM code into DC" do you mean all references to
plane_state and plane_res? Or the data inserted in the struct?
 
> It would be better if this had a proper DC interface for tracing/logging
> these states. If the API was more like how we handle tracing register
> reads/writes this would be cleaner.

Could you elaborate a little bit more about  "a proper DC interface"?
What is your view of this sort of interface?

Also, how about Patch 04? Same problems?

Best Regards
Rodrigo Siqueira

> Regards,
> Nicholas Kazlauskas
> 
> > ---
> >   .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 172 ++
> >   drivers/gpu/drm/amd/display/dc/core/dc.c  |  11 ++
> >   .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  17 +-
> >   3 files changed, 195 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
> > index 5fb4c4a5c349..53f62506e17c 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
> > @@ -376,6 +376,178 @@ TRACE_EVENT(amdgpu_dm_atomic_check_finish,
> >   __entry->async_update, __entry->allow_modeset)
> >   );
> > +#ifndef _AMDGPU_DM_TRACE_STRUCTS_DEFINED_
> > +#define _AMDGPU_DM_TRACE_STRUCTS_DEFINED_
> > +
> > +struct amdgpu_dm_trace_pipe_state {
> > +   int pipe_idx;
> > +   const void *stream;
> > +   int stream_w;
> > +   int stream_h;
> > +   int dst_x;
> > +   int dst_y;
> > +   int dst_w;
> > +   int dst_h;
> > +   int src_x;
> > +   int src_y;
> > +   int src_w;
> > +   int src_h;
> > +   int clip_x;
> > +   int clip_y;
> > +   int clip_w;
> > +   int clip_h;
> > +   int recout_x;
> > +   int recout_y;
> > +   int recout_w;
> > +   int recout_h;
> > +   int viewport_x;
> > +   int viewport_y;
> > +   int viewport_w;
> > +   int viewport_h;
> > +   int flip_immediate;
> > +   int surface_pitch;
> > +   int format;
> > +   int swizzle;
> > +   unsigned int update_flags;
> > +};
> > +
> > +#define fill_out_trace_pipe_state(trace_pipe_state, pipe_ctx) \
> > +   do { \
> > +   trace_pipe_state.pipe_idx   = (pipe_ctx)->pipe_idx; \
> > +   trace_pipe_state.stream = (pipe_ctx)->stream; \
> > +   trace_pipe_state.stream_w   = 
> > (pipe_ctx)->stream->timing.h_addressable; \
> > +   trace_pipe_state.stream_h   = 
> > (pipe_ctx)->stream->timing.v_addressable; \
> > +   trace_pipe_state.dst_x  = 
> > (pipe_ctx)->plane_state->dst_rect.x; \
> > +   trace_pipe_state.dst_y  = 
> > (pipe_ctx)->plane_state->dst_rect.y; \
> > +   trace_pipe_state.dst_w  = 
> > (pipe_ctx)->plane_state->dst_rect.width; \
> > +   trace_pipe_state.dst_h  = 
> > (pipe_ctx)->plane_state->dst_rect.height; \
> > +   trace_pipe_state.src_x  = 
> > (pipe_ctx)->plane_state->src_rect.x; \
> > +   trace_pipe_state.src_y  = 
> > (pipe_ctx)->plane_state->src_rect.y; \
> > +   trace_pipe_state.src_w  = 
> > (pipe_ctx)->plane_state->src_rect.width; \
> > +   trace_pipe_state.src_h  = 
> > (pipe_ctx)->plane_state->src_rect.height; \
> > +   trace_pipe_state.clip_x = 
> > (pipe_ctx)->plane_state->clip_rect.x; \
> > +   trace_pipe_state.clip_y = 
> > (pipe_ctx)->plane_state->clip_rect.y; \
> > +   trace_pipe_state.clip_w = 
> > (pipe_ctx)->plane_state->clip_rect.width; \
> > +   trace_pipe_state.clip_h = 
> > (pipe_ctx)->plane_state->clip_rect.height; \
> > +   trace_pipe_state.recout_x   = 
> > (pipe_ctx)->plane_res.scl_data.recout.x; \
> > +   trace_pipe_state.recout_y   = 
> > (pipe_ctx)->plane_res.scl_data.recout.y; \
> > +   trace_pipe_state.recout_w   = 
> > (pipe_ctx)->plane_res.scl_data.recout.width; \
> > +   trace_pipe_state.recout_h   = 
> > (pipe_ctx)->plane_res.scl_data.recout.height; \
> > +   trace_pipe_state.viewport_x = 
> > (pipe_ctx)->plane_res.scl_data.viewport.x; \
> > +   trace_pipe_state.viewport_y = 
> > (pipe_ctx)->plane_res.scl_data.vie

Re: [git pull] drm fixes for 5.9-rc5

2020-09-11 Thread pr-tracker-bot
The pull request you sent on Fri, 11 Sep 2020 17:20:15 +1000:

> git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2020-09-11

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

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/4] drm/amd/display: Rework registers tracepoint

2020-09-11 Thread Rodrigo Siqueira
On 09/11, Kazlauskas, Nicholas wrote:
> On 2020-09-11 10:59 a.m., Rodrigo Siqueira wrote:
> > amdgpu_dc_rreg and amdgpu_dc_wreg are very similar, for this reason,
> > this commits abstract these two events by using DECLARE_EVENT_CLASS and
> > create an instance of it for each one of these events.
> > 
> > Signed-off-by: Rodrigo Siqueira 
> 
> This looks reasonable to me. Does this still show up as
> amdpgu_dc_rrreg/amdgpu_dc_wreg in the captured trace log?
> 
> As long as we can still tell this apart you can consider this patch:
> 
> Reviewed-by: Nicholas Kazlauskas 

Yes, this change does not change anything from the user perspective.

Thanks
 
> Regards,
> Nicholas Kazlauskas
> 
> > ---
> >   .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 55 ---
> >   1 file changed, 24 insertions(+), 31 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
> > index d898981684d5..dd34e11b1079 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
> > @@ -31,40 +31,33 @@
> >   #include 
> > -TRACE_EVENT(amdgpu_dc_rreg,
> > -   TP_PROTO(unsigned long *read_count, uint32_t reg, uint32_t value),
> > -   TP_ARGS(read_count, reg, value),
> > -   TP_STRUCT__entry(
> > -   __field(uint32_t, reg)
> > -   __field(uint32_t, value)
> > -   ),
> > -   TP_fast_assign(
> > -   __entry->reg = reg;
> > -   __entry->value = value;
> > -   *read_count = *read_count + 1;
> > -   ),
> > -   TP_printk("reg=0x%08lx, value=0x%08lx",
> > -   (unsigned long)__entry->reg,
> > -   (unsigned long)__entry->value)
> > -);
> > +DECLARE_EVENT_CLASS(amdgpu_dc_reg_template,
> > +   TP_PROTO(unsigned long *count, uint32_t reg, uint32_t 
> > value),
> > +   TP_ARGS(count, reg, value),
> > -TRACE_EVENT(amdgpu_dc_wreg,
> > -   TP_PROTO(unsigned long *write_count, uint32_t reg, uint32_t value),
> > -   TP_ARGS(write_count, reg, value),
> > -   TP_STRUCT__entry(
> > -   __field(uint32_t, reg)
> > -   __field(uint32_t, value)
> > -   ),
> > -   TP_fast_assign(
> > -   __entry->reg = reg;
> > -   __entry->value = value;
> > -   *write_count = *write_count + 1;
> > -   ),
> > -   TP_printk("reg=0x%08lx, value=0x%08lx",
> > -   (unsigned long)__entry->reg,
> > -   (unsigned long)__entry->value)
> > +   TP_STRUCT__entry(
> > +__field(uint32_t, reg)
> > +__field(uint32_t, value)
> > +   ),
> > +
> > +   TP_fast_assign(
> > +  __entry->reg = reg;
> > +  __entry->value = value;
> > +  *count = *count + 1;
> > +   ),
> > +
> > +   TP_printk("reg=0x%08lx, value=0x%08lx",
> > + (unsigned long)__entry->reg,
> > + (unsigned long)__entry->value)
> >   );
> > +DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_rreg,
> > +TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value),
> > +TP_ARGS(count, reg, value));
> > +
> > +DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_wreg,
> > +TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value),
> > +TP_ARGS(count, reg, value));
> >   TRACE_EVENT(amdgpu_dc_performance,
> > TP_PROTO(unsigned long read_count, unsigned long write_count,
> > 
> 

-- 
Rodrigo Siqueira
https://siqueira.tech


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/4] drm/amd/display: Rework registers tracepoint

2020-09-11 Thread Kazlauskas, Nicholas

On 2020-09-11 10:59 a.m., Rodrigo Siqueira wrote:

amdgpu_dc_rreg and amdgpu_dc_wreg are very similar, for this reason,
this commits abstract these two events by using DECLARE_EVENT_CLASS and
create an instance of it for each one of these events.

Signed-off-by: Rodrigo Siqueira 


This looks reasonable to me. Does this still show up as 
amdpgu_dc_rrreg/amdgpu_dc_wreg in the captured trace log?


As long as we can still tell this apart you can consider this patch:

Reviewed-by: Nicholas Kazlauskas 

Regards,
Nicholas Kazlauskas


---
  .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 55 ---
  1 file changed, 24 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index d898981684d5..dd34e11b1079 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -31,40 +31,33 @@
  
  #include 
  
-TRACE_EVENT(amdgpu_dc_rreg,

-   TP_PROTO(unsigned long *read_count, uint32_t reg, uint32_t value),
-   TP_ARGS(read_count, reg, value),
-   TP_STRUCT__entry(
-   __field(uint32_t, reg)
-   __field(uint32_t, value)
-   ),
-   TP_fast_assign(
-   __entry->reg = reg;
-   __entry->value = value;
-   *read_count = *read_count + 1;
-   ),
-   TP_printk("reg=0x%08lx, value=0x%08lx",
-   (unsigned long)__entry->reg,
-   (unsigned long)__entry->value)
-);
+DECLARE_EVENT_CLASS(amdgpu_dc_reg_template,
+   TP_PROTO(unsigned long *count, uint32_t reg, uint32_t 
value),
+   TP_ARGS(count, reg, value),
  
-TRACE_EVENT(amdgpu_dc_wreg,

-   TP_PROTO(unsigned long *write_count, uint32_t reg, uint32_t value),
-   TP_ARGS(write_count, reg, value),
-   TP_STRUCT__entry(
-   __field(uint32_t, reg)
-   __field(uint32_t, value)
-   ),
-   TP_fast_assign(
-   __entry->reg = reg;
-   __entry->value = value;
-   *write_count = *write_count + 1;
-   ),
-   TP_printk("reg=0x%08lx, value=0x%08lx",
-   (unsigned long)__entry->reg,
-   (unsigned long)__entry->value)
+   TP_STRUCT__entry(
+__field(uint32_t, reg)
+__field(uint32_t, value)
+   ),
+
+   TP_fast_assign(
+  __entry->reg = reg;
+  __entry->value = value;
+  *count = *count + 1;
+   ),
+
+   TP_printk("reg=0x%08lx, value=0x%08lx",
+ (unsigned long)__entry->reg,
+ (unsigned long)__entry->value)
  );
  
+DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_rreg,

+TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value),
+TP_ARGS(count, reg, value));
+
+DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_wreg,
+TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value),
+TP_ARGS(count, reg, value));
  
  TRACE_EVENT(amdgpu_dc_performance,

TP_PROTO(unsigned long read_count, unsigned long write_count,



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 3/4] drm/amd/display: Add pipe_state tracepoint

2020-09-11 Thread Kazlauskas, Nicholas

On 2020-09-11 10:59 a.m., Rodrigo Siqueira wrote:

This commit introduces a trace mechanism for struct pipe_ctx by adding a
middle layer struct in the amdgpu_dm_trace.h for capturing the most
important data from struct pipe_ctx and showing its data via tracepoint.
This tracepoint was added to dc.c and dcn10_hw_sequencer, however, it
can be added to other DCN architecture.

Co-developed-by: Nicholas Kazlauskas 
Signed-off-by: Nicholas Kazlauskas 
Signed-off-by: Rodrigo Siqueira 



This patch, while very useful, unfortunately pulls in a lot of DM code 
into DC so I would prefer to hold off on this one for now.


It would be better if this had a proper DC interface for tracing/logging 
these states. If the API was more like how we handle tracing register 
reads/writes this would be cleaner.


Regards,
Nicholas Kazlauskas


---
  .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 172 ++
  drivers/gpu/drm/amd/display/dc/core/dc.c  |  11 ++
  .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  17 +-
  3 files changed, 195 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index 5fb4c4a5c349..53f62506e17c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -376,6 +376,178 @@ TRACE_EVENT(amdgpu_dm_atomic_check_finish,
  __entry->async_update, __entry->allow_modeset)
  );
  
+#ifndef _AMDGPU_DM_TRACE_STRUCTS_DEFINED_

+#define _AMDGPU_DM_TRACE_STRUCTS_DEFINED_
+
+struct amdgpu_dm_trace_pipe_state {
+   int pipe_idx;
+   const void *stream;
+   int stream_w;
+   int stream_h;
+   int dst_x;
+   int dst_y;
+   int dst_w;
+   int dst_h;
+   int src_x;
+   int src_y;
+   int src_w;
+   int src_h;
+   int clip_x;
+   int clip_y;
+   int clip_w;
+   int clip_h;
+   int recout_x;
+   int recout_y;
+   int recout_w;
+   int recout_h;
+   int viewport_x;
+   int viewport_y;
+   int viewport_w;
+   int viewport_h;
+   int flip_immediate;
+   int surface_pitch;
+   int format;
+   int swizzle;
+   unsigned int update_flags;
+};
+
+#define fill_out_trace_pipe_state(trace_pipe_state, pipe_ctx) \
+   do { \
+   trace_pipe_state.pipe_idx   = (pipe_ctx)->pipe_idx; \
+   trace_pipe_state.stream = (pipe_ctx)->stream; \
+   trace_pipe_state.stream_w   = 
(pipe_ctx)->stream->timing.h_addressable; \
+   trace_pipe_state.stream_h   = 
(pipe_ctx)->stream->timing.v_addressable; \
+   trace_pipe_state.dst_x  = 
(pipe_ctx)->plane_state->dst_rect.x; \
+   trace_pipe_state.dst_y  = 
(pipe_ctx)->plane_state->dst_rect.y; \
+   trace_pipe_state.dst_w  = 
(pipe_ctx)->plane_state->dst_rect.width; \
+   trace_pipe_state.dst_h  = 
(pipe_ctx)->plane_state->dst_rect.height; \
+   trace_pipe_state.src_x  = 
(pipe_ctx)->plane_state->src_rect.x; \
+   trace_pipe_state.src_y  = 
(pipe_ctx)->plane_state->src_rect.y; \
+   trace_pipe_state.src_w  = 
(pipe_ctx)->plane_state->src_rect.width; \
+   trace_pipe_state.src_h  = 
(pipe_ctx)->plane_state->src_rect.height; \
+   trace_pipe_state.clip_x = 
(pipe_ctx)->plane_state->clip_rect.x; \
+   trace_pipe_state.clip_y = 
(pipe_ctx)->plane_state->clip_rect.y; \
+   trace_pipe_state.clip_w = 
(pipe_ctx)->plane_state->clip_rect.width; \
+   trace_pipe_state.clip_h = 
(pipe_ctx)->plane_state->clip_rect.height; \
+   trace_pipe_state.recout_x   = 
(pipe_ctx)->plane_res.scl_data.recout.x; \
+   trace_pipe_state.recout_y   = 
(pipe_ctx)->plane_res.scl_data.recout.y; \
+   trace_pipe_state.recout_w   = 
(pipe_ctx)->plane_res.scl_data.recout.width; \
+   trace_pipe_state.recout_h   = 
(pipe_ctx)->plane_res.scl_data.recout.height; \
+   trace_pipe_state.viewport_x = 
(pipe_ctx)->plane_res.scl_data.viewport.x; \
+   trace_pipe_state.viewport_y = 
(pipe_ctx)->plane_res.scl_data.viewport.y; \
+   trace_pipe_state.viewport_w = 
(pipe_ctx)->plane_res.scl_data.viewport.width; \
+   trace_pipe_state.viewport_h = 
(pipe_ctx)->plane_res.scl_data.viewport.height; \
+   trace_pipe_state.flip_immediate = 
(pipe_ctx)->plane_state->flip_immediate; \
+   trace_pipe_state.surface_pitch  = 
(pipe_ctx)->plane_state->plane_size.surface_pitch; \
+   trace_pipe_state.format = 
(pipe_ctx)->plane_state->format; \
+   trace_pipe_state.swizzle= 
(pipe_ctx)->plane_state->tiling_info.gfx9.swizzle; \
+   trac

Re: [PATCHv4 6/6] iommu: arm-smmu-impl: Remove unwanted extra blank lines

2020-09-11 Thread Robin Murphy

On 2020-09-11 17:21, Sai Prakash Ranjan wrote:

On 2020-09-11 21:37, Will Deacon wrote:

On Fri, Sep 11, 2020 at 05:03:06PM +0100, Robin Murphy wrote:
BTW am I supposed to have received 3 copies of everything? Because I 
did...


Yeah, this seems to be happening for all of Sai's emails :/



Sorry, I am not sure what went wrong as I only sent this once
and there are no recent changes to any of my configs, I'll
check it further.


Actually on closer inspection it appears to be "correct" behaviour. I'm 
still subscribed to LAKML and the IOMMU list on this account, but 
normally Office 365 deduplicates so aggressively that I have rules set 
up to copy list mails that I'm cc'ed on back to my inbox, in case they 
arrive first and cause the direct copy to get eaten - apparently there's 
something unique about your email setup that manages to defeat the 
deduplicator and make it deliver all 3 copies intact... :/


Robin.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm: xlnx: remove defined but not used 'scaling_factors_666'

2020-09-11 Thread Hyun Kwon
Hi Daniel,

On Fri, Sep 11, 2020 at 01:15:19AM -0700, Daniel Vetter wrote:
> On Thu, Sep 10, 2020 at 11:14:18AM -0700, Hyun Kwon wrote:
> > Hi Jason,
> > 
> > On Thu, Sep 10, 2020 at 07:06:30AM -0700, Jason Yan wrote:
> > > This addresses the following gcc warning with "make W=1":
> > > 
> > > drivers/gpu/drm/xlnx/zynqmp_disp.c:245:18: warning:
> > > ‘scaling_factors_666’ defined but not used [-Wunused-const-variable=]
> > >   245 | static const u32 scaling_factors_666[] = {
> > >   |  ^~~
> > > 
> > > Reported-by: Hulk Robot 
> > > Signed-off-by: Jason Yan 
> > 
> > Reviewed-by: Hyun Kwon 
> 
> I think you're the maintainer, so please also push patches to
> drm-misc-next. Otherwise they'll just get lost, or at least it's very
> confusing when a maintainer reviews a patch but there's no indication what
> will happen with the patch.

Right. I wanted to give it some time before pushing. I'll clearly state going
forward.

Thanks,
-hyun

> -Daniel
> 
> > 
> > Thanks!
> > 
> > -hyun
> > 
> > > ---
> > >  drivers/gpu/drm/xlnx/zynqmp_disp.c | 6 --
> > >  1 file changed, 6 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c 
> > > b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > > index a455cfc1bee5..98bd48f13fd1 100644
> > > --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > > @@ -242,12 +242,6 @@ static const u32 scaling_factors_565[] = {
> > >   ZYNQMP_DISP_AV_BUF_5BIT_SF,
> > >  };
> > >  
> > > -static const u32 scaling_factors_666[] = {
> > > - ZYNQMP_DISP_AV_BUF_6BIT_SF,
> > > - ZYNQMP_DISP_AV_BUF_6BIT_SF,
> > > - ZYNQMP_DISP_AV_BUF_6BIT_SF,
> > > -};
> > > -
> > >  static const u32 scaling_factors_888[] = {
> > >   ZYNQMP_DISP_AV_BUF_8BIT_SF,
> > >   ZYNQMP_DISP_AV_BUF_8BIT_SF,
> > > -- 
> > > 2.25.4
> > > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCHv4 6/6] iommu: arm-smmu-impl: Remove unwanted extra blank lines

2020-09-11 Thread Will Deacon
On Fri, Sep 11, 2020 at 05:03:06PM +0100, Robin Murphy wrote:
> BTW am I supposed to have received 3 copies of everything? Because I did...

Yeah, this seems to be happening for all of Sai's emails :/

Will
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCHv4 6/6] iommu: arm-smmu-impl: Remove unwanted extra blank lines

2020-09-11 Thread Robin Murphy

On 2020-09-11 15:28, Sai Prakash Ranjan wrote:

There are few places in arm-smmu-impl where there are
extra blank lines, remove them


FWIW those were deliberate - sometimes I like a bit of subtle space to 
visually delineate distinct groups of definitions. I suppose it won't be 
to everyone's taste :/



and while at it fix the
checkpatch warning for space required before the open
parenthesis.


That one, however, was not ;)

BTW am I supposed to have received 3 copies of everything? Because I did...

Robin.


Signed-off-by: Sai Prakash Ranjan 
---
  drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 5 +
  1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
index ce78295cfa78..f5b5218cbe5b 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -19,7 +19,7 @@ static const struct of_device_id __maybe_unused 
qcom_smmu_impl_of_match[] = {
  
  static int arm_smmu_gr0_ns(int offset)

  {
-   switch(offset) {
+   switch (offset) {
case ARM_SMMU_GR0_sCR0:
case ARM_SMMU_GR0_sACR:
case ARM_SMMU_GR0_sGFSR:
@@ -54,7 +54,6 @@ static const struct arm_smmu_impl calxeda_impl = {
.write_reg = arm_smmu_write_ns,
  };
  
-

  struct cavium_smmu {
struct arm_smmu_device smmu;
u32 id_base;
@@ -110,7 +109,6 @@ static struct arm_smmu_device *cavium_smmu_impl_init(struct 
arm_smmu_device *smm
return &cs->smmu;
  }
  
-

  #define ARM_MMU500_ACTLR_CPRE (1 << 1)
  
  #define ARM_MMU500_ACR_CACHE_LOCK	(1 << 26)

@@ -197,7 +195,6 @@ static const struct arm_smmu_impl mrvl_mmu500_impl = {
.reset = arm_mmu500_reset,
  };
  
-

  struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
  {
const struct device_node *np = smmu->dev->of_node;


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] drm/nouveau: explicitly specify caching to use

2020-09-11 Thread Christian König
Instead of letting TTM masking the caching bits
specify directly what the driver needs.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c  | 28 +--
 drivers/gpu/drm/nouveau/nouveau_ttm.c | 19 +++---
 2 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 97e1908eada0..b062ea8afffd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -340,18 +340,33 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int 
align,
 }
 
 static void
-set_placement_list(struct ttm_place *pl, unsigned *n, uint32_t domain,
-  uint32_t flags)
+set_placement_list(struct nouveau_drm *drm, struct ttm_place *pl, unsigned *n,
+  uint32_t domain, uint32_t flags)
 {
*n = 0;
 
if (domain & NOUVEAU_GEM_DOMAIN_VRAM) {
+   struct nvif_mmu *mmu = &drm->client.mmu;
+   const u8 type = mmu->type[drm->ttm.type_vram].type;
+
pl[*n].mem_type = TTM_PL_VRAM;
-   pl[(*n)++].flags = flags;
+   pl[*n].flags = flags & ~TTM_PL_FLAG_CACHED;
+
+   /* Some BARs do not support being ioremapped WC */
+   if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA &&
+   type & NVIF_MEM_UNCACHED)
+   pl[*n].flags &= ~TTM_PL_FLAG_WC;
+
+   (*n)++;
}
if (domain & NOUVEAU_GEM_DOMAIN_GART) {
pl[*n].mem_type = TTM_PL_TT;
-   pl[(*n)++].flags = flags;
+   pl[*n].flags = flags;
+
+   if (drm->agp.bridge)
+   pl[*n].flags &= ~TTM_PL_FLAG_CACHED;
+
+   (*n)++;
}
if (domain & NOUVEAU_GEM_DOMAIN_CPU) {
pl[*n].mem_type = TTM_PL_SYSTEM;
@@ -397,17 +412,18 @@ void
 nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t domain,
 uint32_t busy)
 {
+   struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct ttm_placement *pl = &nvbo->placement;
uint32_t flags = (nvbo->force_coherent ? TTM_PL_FLAG_UNCACHED :
 TTM_PL_MASK_CACHING) |
 (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0);
 
pl->placement = nvbo->placements;
-   set_placement_list(nvbo->placements, &pl->num_placement,
+   set_placement_list(drm, nvbo->placements, &pl->num_placement,
   domain, flags);
 
pl->busy_placement = nvbo->busy_placements;
-   set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
+   set_placement_list(drm, nvbo->busy_placements, &pl->num_busy_placement,
   domain | busy, flags);
 
set_placement_range(nvbo, domain);
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c 
b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index cf18f75cd0f1..1b00f32b3849 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -194,19 +194,13 @@ nouveau_ttm_init_host(struct nouveau_drm *drm, u8 kind)
 static int
 nouveau_ttm_init_vram(struct nouveau_drm *drm)
 {
-   struct nvif_mmu *mmu = &drm->client.mmu;
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
-   /* Some BARs do not support being ioremapped WC */
-   const u8 type = mmu->type[drm->ttm.type_vram].type;
struct ttm_resource_manager *man = kzalloc(sizeof(*man), 
GFP_KERNEL);
+
if (!man)
return -ENOMEM;
 
man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-
-   if (type & NVIF_MEM_UNCACHED)
-   man->available_caching = TTM_PL_FLAG_UNCACHED;
-
man->func = &nouveau_vram_manager;
 
ttm_resource_manager_init(man,
@@ -243,13 +237,6 @@ nouveau_ttm_init_gtt(struct nouveau_drm *drm)
struct ttm_resource_manager *man;
unsigned long size_pages = drm->gem.gart_available >> PAGE_SHIFT;
const struct ttm_resource_manager_func *func = NULL;
-   unsigned available_caching;
-
-   if (drm->agp.bridge)
-   available_caching = TTM_PL_FLAG_UNCACHED |
-   TTM_PL_FLAG_WC;
-   else
-   available_caching = TTM_PL_MASK_CACHING;
 
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA)
func = &nouveau_gart_manager;
@@ -257,7 +244,7 @@ nouveau_ttm_init_gtt(struct nouveau_drm *drm)
func = &nv04_gart_manager;
else
return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_TT,
- available_caching, true,
+ TTM_PL_MASK_CACHING, true,
  size_pages);
 
man = kzalloc(sizeof(*man),

[PATCH 2/2] drm/ttm: remove available_caching

2020-09-11 Thread Christian König
Instead of letting TTM make an educated guess based on
some mask all drivers should just specify what caching
they want for their CPU mappings.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c   |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  |  2 --
 drivers/gpu/drm/drm_gem_vram_helper.c |  1 -
 drivers/gpu/drm/nouveau/nouveau_ttm.c |  9 ++---
 drivers/gpu/drm/qxl/qxl_ttm.c |  3 +--
 drivers/gpu/drm/radeon/radeon_ttm.c   |  2 --
 drivers/gpu/drm/ttm/ttm_bo.c  |  8 ++--
 drivers/gpu/drm/ttm/ttm_range_manager.c   |  5 +
 drivers/gpu/drm/ttm/ttm_resource.c|  1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |  5 +
 drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c |  1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_thp.c   | 10 +++---
 include/drm/ttm/ttm_bo_driver.h   |  5 +
 include/drm/ttm/ttm_resource.h|  3 ---
 15 files changed, 11 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index b2ca693b8285..73fd2335e468 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -93,7 +93,6 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t 
gtt_size)
 
man->use_tt = true;
man->func = &amdgpu_gtt_mgr_func;
-   man->available_caching = TTM_PL_MASK_CACHING;
 
ttm_resource_manager_init(man, gtt_size >> PAGE_SHIFT);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 96aa8fcb9115..a761cc9cf422 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -68,7 +68,6 @@ static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev,
uint64_t size)
 {
return ttm_range_man_init(&adev->mman.bdev, type,
- TTM_PL_FLAG_UNCACHED,
  false, size >> PAGE_SHIFT);
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 8b4a9ab66586..76f1d8db0c85 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -177,8 +177,6 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
struct ttm_resource_manager *man = &mgr->manager;
int ret;
 
-   man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-
ttm_resource_manager_init(man, adev->gmc.real_vram_size >> PAGE_SHIFT);
 
man->func = &amdgpu_vram_mgr_func;
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index 34dc665eb891..e42cc361fe90 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -1105,7 +1105,6 @@ static int drm_vram_mm_init(struct drm_vram_mm *vmm, 
struct drm_device *dev,
return ret;
 
ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM,
-TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
 false, vram_size >> PAGE_SHIFT);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c 
b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 1b00f32b3849..427341753441 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -200,7 +200,6 @@ nouveau_ttm_init_vram(struct nouveau_drm *drm)
if (!man)
return -ENOMEM;
 
-   man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
man->func = &nouveau_vram_manager;
 
ttm_resource_manager_init(man,
@@ -209,9 +208,7 @@ nouveau_ttm_init_vram(struct nouveau_drm *drm)
ttm_resource_manager_set_used(man, true);
return 0;
} else {
-   return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_VRAM,
- TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
- false,
+   return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_VRAM, false,
  drm->gem.vram_available >> 
PAGE_SHIFT);
}
 }
@@ -243,8 +240,7 @@ nouveau_ttm_init_gtt(struct nouveau_drm *drm)
else if (!drm->agp.bridge)
func = &nv04_gart_manager;
else
-   return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_TT,
- TTM_PL_MASK_CACHING, true,
+   return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_TT, true,
  size_pages);
 
man = kzalloc(sizeof(*man), GFP_KERNEL);
@@ -252,7 +248,6 @@ nouveau_ttm_init_gtt(struct nouveau_drm *drm)
return -ENOMEM;

[PATCH v2 3/4] drm/amd/display: Add pipe_state tracepoint

2020-09-11 Thread Rodrigo Siqueira
This commit introduces a trace mechanism for struct pipe_ctx by adding a
middle layer struct in the amdgpu_dm_trace.h for capturing the most
important data from struct pipe_ctx and showing its data via tracepoint.
This tracepoint was added to dc.c and dcn10_hw_sequencer, however, it
can be added to other DCN architecture.

Co-developed-by: Nicholas Kazlauskas 
Signed-off-by: Nicholas Kazlauskas 
Signed-off-by: Rodrigo Siqueira 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 172 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  11 ++
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  17 +-
 3 files changed, 195 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index 5fb4c4a5c349..53f62506e17c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -376,6 +376,178 @@ TRACE_EVENT(amdgpu_dm_atomic_check_finish,
  __entry->async_update, __entry->allow_modeset)
 );
 
+#ifndef _AMDGPU_DM_TRACE_STRUCTS_DEFINED_
+#define _AMDGPU_DM_TRACE_STRUCTS_DEFINED_
+
+struct amdgpu_dm_trace_pipe_state {
+   int pipe_idx;
+   const void *stream;
+   int stream_w;
+   int stream_h;
+   int dst_x;
+   int dst_y;
+   int dst_w;
+   int dst_h;
+   int src_x;
+   int src_y;
+   int src_w;
+   int src_h;
+   int clip_x;
+   int clip_y;
+   int clip_w;
+   int clip_h;
+   int recout_x;
+   int recout_y;
+   int recout_w;
+   int recout_h;
+   int viewport_x;
+   int viewport_y;
+   int viewport_w;
+   int viewport_h;
+   int flip_immediate;
+   int surface_pitch;
+   int format;
+   int swizzle;
+   unsigned int update_flags;
+};
+
+#define fill_out_trace_pipe_state(trace_pipe_state, pipe_ctx) \
+   do { \
+   trace_pipe_state.pipe_idx   = (pipe_ctx)->pipe_idx; \
+   trace_pipe_state.stream = (pipe_ctx)->stream; \
+   trace_pipe_state.stream_w   = 
(pipe_ctx)->stream->timing.h_addressable; \
+   trace_pipe_state.stream_h   = 
(pipe_ctx)->stream->timing.v_addressable; \
+   trace_pipe_state.dst_x  = 
(pipe_ctx)->plane_state->dst_rect.x; \
+   trace_pipe_state.dst_y  = 
(pipe_ctx)->plane_state->dst_rect.y; \
+   trace_pipe_state.dst_w  = 
(pipe_ctx)->plane_state->dst_rect.width; \
+   trace_pipe_state.dst_h  = 
(pipe_ctx)->plane_state->dst_rect.height; \
+   trace_pipe_state.src_x  = 
(pipe_ctx)->plane_state->src_rect.x; \
+   trace_pipe_state.src_y  = 
(pipe_ctx)->plane_state->src_rect.y; \
+   trace_pipe_state.src_w  = 
(pipe_ctx)->plane_state->src_rect.width; \
+   trace_pipe_state.src_h  = 
(pipe_ctx)->plane_state->src_rect.height; \
+   trace_pipe_state.clip_x = 
(pipe_ctx)->plane_state->clip_rect.x; \
+   trace_pipe_state.clip_y = 
(pipe_ctx)->plane_state->clip_rect.y; \
+   trace_pipe_state.clip_w = 
(pipe_ctx)->plane_state->clip_rect.width; \
+   trace_pipe_state.clip_h = 
(pipe_ctx)->plane_state->clip_rect.height; \
+   trace_pipe_state.recout_x   = 
(pipe_ctx)->plane_res.scl_data.recout.x; \
+   trace_pipe_state.recout_y   = 
(pipe_ctx)->plane_res.scl_data.recout.y; \
+   trace_pipe_state.recout_w   = 
(pipe_ctx)->plane_res.scl_data.recout.width; \
+   trace_pipe_state.recout_h   = 
(pipe_ctx)->plane_res.scl_data.recout.height; \
+   trace_pipe_state.viewport_x = 
(pipe_ctx)->plane_res.scl_data.viewport.x; \
+   trace_pipe_state.viewport_y = 
(pipe_ctx)->plane_res.scl_data.viewport.y; \
+   trace_pipe_state.viewport_w = 
(pipe_ctx)->plane_res.scl_data.viewport.width; \
+   trace_pipe_state.viewport_h = 
(pipe_ctx)->plane_res.scl_data.viewport.height; \
+   trace_pipe_state.flip_immediate = 
(pipe_ctx)->plane_state->flip_immediate; \
+   trace_pipe_state.surface_pitch  = 
(pipe_ctx)->plane_state->plane_size.surface_pitch; \
+   trace_pipe_state.format = 
(pipe_ctx)->plane_state->format; \
+   trace_pipe_state.swizzle= 
(pipe_ctx)->plane_state->tiling_info.gfx9.swizzle; \
+   trace_pipe_state.update_flags   = (pipe_ctx)->update_flags.raw; 
\
+   } while (0)
+
+#endif /* _AMDGPU_DM_TRACE_STRUCTS_DEFINED_ */
+
+TRACE_EVENT(amdgpu_dm_dc_pipe_state,
+   TP_PROTO(const struct amdgpu_dm_trace_pipe_state *pipe_state),
+   TP_ARGS(pipe_state),
+   TP_STRUCT__entry(
+__field(int, pipe_idx)
+__field(const voi

[PATCH v2 2/4] drm/amd/display: Add tracepoint for amdgpu_dm

2020-09-11 Thread Rodrigo Siqueira
Debug amdgpu_dm could be a complicated task, therefore, this commit adds
tracepoints in some convenient functions such as plane and connector
check inside amdgpu_dm.

Co-developed-by: Nicholas Kazlauskas 
Signed-off-by: Nicholas Kazlauskas 
Signed-off-by: Rodrigo Siqueira 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  17 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 287 ++
 2 files changed, 304 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index cb624ee70545..552ca67c2a71 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5424,6 +5424,8 @@ amdgpu_dm_connector_atomic_check(struct drm_connector 
*conn,
struct drm_crtc_state *new_crtc_state;
int ret;
 
+   trace_amdgpu_dm_connector_atomic_check(new_con_state);
+
if (!crtc)
return 0;
 
@@ -5542,6 +5544,8 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc 
*crtc,
struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(state);
int ret = -EINVAL;
 
+   trace_amdgpu_dm_crtc_atomic_check(state);
+
dm_update_crtc_active_planes(crtc, state);
 
if (unlikely(!dm_crtc_state->stream &&
@@ -5916,6 +5920,8 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
struct drm_crtc_state *new_crtc_state;
int ret;
 
+   trace_amdgpu_dm_plane_atomic_check(state);
+
dm_plane_state = to_dm_plane_state(state);
 
if (!dm_plane_state->dc_state)
@@ -5956,6 +5962,8 @@ static void dm_plane_atomic_async_update(struct drm_plane 
*plane,
struct drm_plane_state *old_state =
drm_atomic_get_old_plane_state(new_state->state, plane);
 
+   trace_amdgpu_dm_atomic_update_cursor(new_state);
+
swap(plane->state->fb, new_state->fb);
 
plane->state->src_x = new_state->src_x;
@@ -7546,6 +7554,8 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
int crtc_disable_count = 0;
bool mode_set_reset_required = false;
 
+   trace_amdgpu_dm_atomic_commit_tail_begin(state);
+
drm_atomic_helper_update_legacy_modeset_state(dev, state);
 
dm_state = dm_atomic_get_new_state(state);
@@ -8616,6 +8626,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
int ret, i;
bool lock_and_validation_needed = false;
 
+   trace_amdgpu_dm_atomic_check_begin(state);
+
ret = drm_atomic_helper_check_modeset(dev, state);
if (ret)
goto fail;
@@ -8912,6 +8924,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 
/* Must be success */
WARN_ON(ret);
+
+   trace_amdgpu_dm_atomic_check_finish(state, ret);
+
return ret;
 
 fail:
@@ -8922,6 +8937,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
else
DRM_DEBUG_DRIVER("Atomic check failed with err: %d \n", ret);
 
+   trace_amdgpu_dm_atomic_check_finish(state, ret);
+
return ret;
 }
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index dd34e11b1079..5fb4c4a5c349 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -30,6 +30,12 @@
 #define _AMDGPU_DM_TRACE_H_
 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 DECLARE_EVENT_CLASS(amdgpu_dc_reg_template,
TP_PROTO(unsigned long *count, uint32_t reg, uint32_t 
value),
@@ -89,6 +95,287 @@ TRACE_EVENT(amdgpu_dc_performance,
(unsigned long)__entry->write_delta,
(unsigned long)__entry->writes)
 );
+
+TRACE_EVENT(amdgpu_dm_connector_atomic_check,
+   TP_PROTO(const struct drm_connector_state *state),
+   TP_ARGS(state),
+
+   TP_STRUCT__entry(
+__field(uint32_t, conn_id)
+__field(const struct drm_connector_state *, 
conn_state)
+__field(const struct drm_atomic_state *, state)
+__field(const struct drm_crtc_commit *, commit)
+__field(uint32_t, crtc_id)
+__field(uint32_t, best_encoder_id)
+__field(enum drm_link_status, link_status)
+__field(bool, self_refresh_aware)
+__field(enum hdmi_picture_aspect, 
picture_aspect_ratio)
+__field(unsigned int, content_type)
+__field(unsigned int, hdcp_content_type)
+__field(unsigned int, content_protection)
+__field(unsigned int, scaling_mode)
+__field(u32, colorspace)
+   

[PATCH v2 4/4] drm/amd/display: Add tracepoint for capturing clocks state

2020-09-11 Thread Rodrigo Siqueira
The clock state update is the source of many problems, and capturing
this sort of information helps debug. This commit introduces tracepoints
for capturing clock values and also add traces in DCE, DCN1, DCN2x, and
DCN3.

Co-developed-by: Nicholas Kazlauskas 
Signed-off-by: Nicholas Kazlauskas 
Signed-off-by: Rodrigo Siqueira 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 198 ++
 .../dc/clk_mgr/dce112/dce112_clk_mgr.c|   5 +
 .../display/dc/clk_mgr/dcn10/rv1_clk_mgr.c|   4 +
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  |   4 +
 .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c |   4 +
 .../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c  |   4 +
 .../gpu/drm/amd/display/dc/dce/dce_clk_mgr.c  |   5 +
 7 files changed, 224 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index 53f62506e17c..fb22b233224a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -411,6 +411,42 @@ struct amdgpu_dm_trace_pipe_state {
unsigned int update_flags;
 };
 
+struct amdgpu_dm_trace_dc_clocks_state {
+   int dispclk_khz;
+   int dppclk_khz;
+   int disp_dpp_voltage_level_khz;
+   int dcfclk_khz;
+   int socclk_khz;
+   int dcfclk_deep_sleep_khz;
+   int fclk_khz;
+   int phyclk_khz;
+   int dramclk_khz;
+   bool p_state_change_support;
+   int pwr_state;
+   bool prev_p_state_change_support;
+   int dtm_level;
+   int max_supported_dppclk_khz;
+   int max_supported_dispclk_khz;
+   int bw_dppclk_khz;
+   int bw_dispclk_khz;
+   int safe_to_lower;
+};
+
+struct amdgpu_dm_trace_dce_clocks_state {
+   bool cpuc_state_change_enable;
+   bool cpup_state_change_enable;
+   bool stutter_mode_enable;
+   bool nbp_state_change_enable;
+   bool all_displays_in_sync;
+   int sclk_khz;
+   int sclk_deep_sleep_khz;
+   int yclk_khz;
+   int dispclk_khz;
+   int blackout_recovery_time_us;
+   int patched_disp_clk;
+   int safe_to_lower;
+};
+
 #define fill_out_trace_pipe_state(trace_pipe_state, pipe_ctx) \
do { \
trace_pipe_state.pipe_idx   = (pipe_ctx)->pipe_idx; \
@@ -444,6 +480,44 @@ struct amdgpu_dm_trace_pipe_state {
trace_pipe_state.update_flags   = (pipe_ctx)->update_flags.raw; 
\
} while (0)
 
+#define fill_out_trace_clock_state(trace_clock_state, clocks, safe_to_lower) \
+   do { \
+   trace_clock_state.dispclk_khz = (clocks)->dispclk_khz; \
+   trace_clock_state.dppclk_khz = (clocks)->dppclk_khz; \
+   trace_clock_state.disp_dpp_voltage_level_khz = 
(clocks)->disp_dpp_voltage_level_khz; \
+   trace_clock_state.dcfclk_khz = (clocks)->dcfclk_khz; \
+   trace_clock_state.socclk_khz = (clocks)->socclk_khz; \
+   trace_clock_state.dcfclk_deep_sleep_khz = 
(clocks)->dcfclk_deep_sleep_khz; \
+   trace_clock_state.fclk_khz = (clocks)->fclk_khz; \
+   trace_clock_state.phyclk_khz = (clocks)->phyclk_khz; \
+   trace_clock_state.dramclk_khz = (clocks)->dramclk_khz; \
+   trace_clock_state.p_state_change_support = 
(clocks)->p_state_change_support; \
+   trace_clock_state.pwr_state = (clocks)->pwr_state; \
+   trace_clock_state.prev_p_state_change_support = 
(clocks)->prev_p_state_change_support; \
+   trace_clock_state.dtm_level = (clocks)->dtm_level; \
+   trace_clock_state.max_supported_dppclk_khz = 
(clocks)->max_supported_dppclk_khz; \
+   trace_clock_state.max_supported_dispclk_khz = 
(clocks)->max_supported_dispclk_khz; \
+   trace_clock_state.bw_dppclk_khz = (clocks)->bw_dppclk_khz; \
+   trace_clock_state.bw_dispclk_khz = (clocks)->bw_dispclk_khz; \
+   trace_clock_state.safe_to_lower = safe_to_lower; \
+   } while (0)
+
+#define fill_out_trace_dce_clock_state(trace_clock_state, clocks, 
patched_disp_clk, safe_to_lower) \
+   do { \
+   trace_clock_state.cpuc_state_change_enable = 
(clocks)->cpuc_state_change_enable; \
+   trace_clock_state.cpup_state_change_enable = 
(clocks)->cpup_state_change_enable; \
+   trace_clock_state.stutter_mode_enable = 
(clocks)->stutter_mode_enable; \
+   trace_clock_state.nbp_state_change_enable = 
(clocks)->nbp_state_change_enable; \
+   trace_clock_state.all_displays_in_sync = 
(clocks)->all_displays_in_sync; \
+   trace_clock_state.sclk_khz = (clocks)->sclk_khz; \
+   trace_clock_state.sclk_deep_sleep_khz = 
(clocks)->sclk_deep_sleep_khz; \
+   trace_clock_state.yclk_khz = (clocks)->yclk_khz; \
+   trace_clock_state.dispclk_khz = (clocks)->dispclk_khz; \
+   trace_clock_state.blackout_

[PATCH v2 1/4] drm/amd/display: Rework registers tracepoint

2020-09-11 Thread Rodrigo Siqueira
amdgpu_dc_rreg and amdgpu_dc_wreg are very similar, for this reason,
this commits abstract these two events by using DECLARE_EVENT_CLASS and
create an instance of it for each one of these events.

Signed-off-by: Rodrigo Siqueira 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 55 ---
 1 file changed, 24 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index d898981684d5..dd34e11b1079 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -31,40 +31,33 @@
 
 #include 
 
-TRACE_EVENT(amdgpu_dc_rreg,
-   TP_PROTO(unsigned long *read_count, uint32_t reg, uint32_t value),
-   TP_ARGS(read_count, reg, value),
-   TP_STRUCT__entry(
-   __field(uint32_t, reg)
-   __field(uint32_t, value)
-   ),
-   TP_fast_assign(
-   __entry->reg = reg;
-   __entry->value = value;
-   *read_count = *read_count + 1;
-   ),
-   TP_printk("reg=0x%08lx, value=0x%08lx",
-   (unsigned long)__entry->reg,
-   (unsigned long)__entry->value)
-);
+DECLARE_EVENT_CLASS(amdgpu_dc_reg_template,
+   TP_PROTO(unsigned long *count, uint32_t reg, uint32_t 
value),
+   TP_ARGS(count, reg, value),
 
-TRACE_EVENT(amdgpu_dc_wreg,
-   TP_PROTO(unsigned long *write_count, uint32_t reg, uint32_t value),
-   TP_ARGS(write_count, reg, value),
-   TP_STRUCT__entry(
-   __field(uint32_t, reg)
-   __field(uint32_t, value)
-   ),
-   TP_fast_assign(
-   __entry->reg = reg;
-   __entry->value = value;
-   *write_count = *write_count + 1;
-   ),
-   TP_printk("reg=0x%08lx, value=0x%08lx",
-   (unsigned long)__entry->reg,
-   (unsigned long)__entry->value)
+   TP_STRUCT__entry(
+__field(uint32_t, reg)
+__field(uint32_t, value)
+   ),
+
+   TP_fast_assign(
+  __entry->reg = reg;
+  __entry->value = value;
+  *count = *count + 1;
+   ),
+
+   TP_printk("reg=0x%08lx, value=0x%08lx",
+ (unsigned long)__entry->reg,
+ (unsigned long)__entry->value)
 );
 
+DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_rreg,
+TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value),
+TP_ARGS(count, reg, value));
+
+DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_wreg,
+TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value),
+TP_ARGS(count, reg, value));
 
 TRACE_EVENT(amdgpu_dc_performance,
TP_PROTO(unsigned long read_count, unsigned long write_count,
-- 
2.28.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 0/4] Enlarge tracepoints in the display component

2020-09-11 Thread Rodrigo Siqueira
Debug issues related to display can be a challenge due to the complexity
around this topic and different source of information might help in this
process. We already have support for tracepoints inside the display
component, i.e., we have the basic functionalities available and we just
need to expand it in order to make it more valuable for debugging. For
this reason, this patchset reworks part of the current tracepoint
options and add different sets of tracing inside amdgpu_dm, display
core, and DCN10. The first patch of this series just rework part of the
current tracepoints and the last set of patches introduces new
tracepoints.

This first patchset version is functional. Please, let me know what I
can improve in the current version but also let me know what kind of
tracepoint I can add for the next version. 

Finally, I want to highlight that this work is based on a set of patches
originally made by Nicholas Kazlauskas.

Change in V2:
- I added another patch for capturing the clock state for different display
  architecture.

Rodrigo Siqueira (4):
  drm/amd/display: Rework registers tracepoint
  drm/amd/display: Add tracepoint for amdgpu_dm
  drm/amd/display: Add pipe_state tracepoint
  drm/amd/display: Add tracepoint for capturing clocks state

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  17 +
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 712 +-
 .../dc/clk_mgr/dce112/dce112_clk_mgr.c|   5 +
 .../display/dc/clk_mgr/dcn10/rv1_clk_mgr.c|   4 +
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  |   4 +
 .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c |   4 +
 .../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c  |   4 +
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  11 +
 .../gpu/drm/amd/display/dc/dce/dce_clk_mgr.c  |   5 +
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  17 +-
 10 files changed, 747 insertions(+), 36 deletions(-)

-- 
2.28.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/vboxvideo: Use drm_gem_vram_vmap() interfaces

2020-09-11 Thread Hans de Goede

Hi,

On 9/11/20 9:59 AM, Thomas Zimmermann wrote:

VRAM helpers support ref counting for pin and vmap operations, no need
to avoid these operations, by employing the internal kmap interface. Just
use drm_gem_vram_vmap() and let it handle the details.

Also unexport the kmap interfaces from VRAM helpers. Vboxvideo was the
last user of these internal functions.

Signed-off-by: Thomas Zimmermann 


Nice cleanup.

I've given this a test-run in an actual VirtualBox vm, focussing on
cursor sprite changes and I don't see any regressions, so:

Tested-by: Hans de Goede 

Thomas, I assume that you will push this upstream yourself?

Regards,

Hans



---
  drivers/gpu/drm/drm_gem_vram_helper.c | 56 +--
  drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +++--
  include/drm/drm_gem_vram_helper.h |  3 --
  3 files changed, 8 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index 07447abb4134..0e3cdc40379c 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -97,8 +97,8 @@ static const struct drm_gem_object_funcs 
drm_gem_vram_object_funcs;
   * hardware's draing engine.
   *
   * To access a buffer object's memory from the DRM driver, call
- * drm_gem_vram_kmap(). It (optionally) maps the buffer into kernel address
- * space and returns the memory address. Use drm_gem_vram_kunmap() to
+ * drm_gem_vram_vmap(). It maps the buffer into kernel address
+ * space and returns the memory address. Use drm_gem_vram_vunmap() to
   * release the mapping.
   */
  
@@ -436,39 +436,6 @@ static void *drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,

return kmap->virtual;
  }
  
-/**

- * drm_gem_vram_kmap() - Maps a GEM VRAM object into kernel address space
- * @gbo:   the GEM VRAM object
- * @map:   establish a mapping if necessary
- * @is_iomem:  returns true if the mapped memory is I/O memory, or false \
-   otherwise; can be NULL
- *
- * This function maps the buffer object into the kernel's address space
- * or returns the current mapping. If the parameter map is false, the
- * function only queries the current mapping, but does not establish a
- * new one.
- *
- * Returns:
- * The buffers virtual address if mapped, or
- * NULL if not mapped, or
- * an ERR_PTR()-encoded error code otherwise.
- */
-void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
-   bool *is_iomem)
-{
-   int ret;
-   void *virtual;
-
-   ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
-   if (ret)
-   return ERR_PTR(ret);
-   virtual = drm_gem_vram_kmap_locked(gbo, map, is_iomem);
-   ttm_bo_unreserve(&gbo->bo);
-
-   return virtual;
-}
-EXPORT_SYMBOL(drm_gem_vram_kmap);
-
  static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
  {
if (WARN_ON_ONCE(!gbo->kmap_use_count))
@@ -484,22 +451,6 @@ static void drm_gem_vram_kunmap_locked(struct 
drm_gem_vram_object *gbo)
 */
  }
  
-/**

- * drm_gem_vram_kunmap() - Unmaps a GEM VRAM object
- * @gbo:   the GEM VRAM object
- */
-void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo)
-{
-   int ret;
-
-   ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
-   if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
-   return;
-   drm_gem_vram_kunmap_locked(gbo);
-   ttm_bo_unreserve(&gbo->bo);
-}
-EXPORT_SYMBOL(drm_gem_vram_kunmap);
-
  /**
   * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
   *   space
@@ -511,9 +462,6 @@ EXPORT_SYMBOL(drm_gem_vram_kunmap);
   * permanently. Call drm_gem_vram_vunmap() with the returned address to
   * unmap and unpin the GEM VRAM object.
   *
- * If you have special requirements for the pinning or mapping operations,
- * call drm_gem_vram_pin() and drm_gem_vram_kmap() directly.
- *
   * Returns:
   * The buffer's virtual address on success, or
   * an ERR_PTR()-encoded error code otherwise.
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c 
b/drivers/gpu/drm/vboxvideo/vbox_mode.c
index d9a5af62af89..4fcc0a542b8a 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_mode.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c
@@ -397,11 +397,13 @@ static void vbox_cursor_atomic_update(struct drm_plane 
*plane,
  
  	vbox_crtc->cursor_enabled = true;
  
-	/* pinning is done in prepare/cleanup framebuffer */

-   src = drm_gem_vram_kmap(gbo, true, NULL);
+   src = drm_gem_vram_vmap(gbo);
if (IS_ERR(src)) {
+   /*
+* BUG: we should have pinned the BO in prepare_fb().
+*/
mutex_unlock(&vbox->hw_mutex);
-   DRM_WARN("Could not kmap cursor bo, skipping update\n");
+   DRM_WARN("Could not map cursor bo, skipping update\n");
return;
}
  
@@ -414,7 +416,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,

 

[PATCH v3 1/7] drm: add drmm_encoder_alloc()

2020-09-11 Thread Philipp Zabel
Add an alternative to drm_encoder_init() that allocates and initializes
an encoder and registers drm_encoder_cleanup() with
drmm_add_action_or_reset().

Signed-off-by: Philipp Zabel 
---
Changes since v2:
 - call va_start() / va_end() unconditionally
---
 drivers/gpu/drm/drm_encoder.c | 101 ++
 include/drm/drm_encoder.h |  30 ++
 2 files changed, 108 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index e555281f43d4..f5414705f9ad 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "drm_crtc_internal.h"
 
@@ -91,25 +92,11 @@ void drm_encoder_unregister_all(struct drm_device *dev)
}
 }
 
-/**
- * drm_encoder_init - Init a preallocated encoder
- * @dev: drm device
- * @encoder: the encoder to init
- * @funcs: callbacks for this encoder
- * @encoder_type: user visible type of the encoder
- * @name: printf style format string for the encoder name, or NULL for default 
name
- *
- * Initialises a preallocated encoder. Encoder should be subclassed as part of
- * driver encoder objects. At driver unload time drm_encoder_cleanup() should 
be
- * called from the driver's &drm_encoder_funcs.destroy hook.
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_encoder_init(struct drm_device *dev,
-struct drm_encoder *encoder,
-const struct drm_encoder_funcs *funcs,
-int encoder_type, const char *name, ...)
+__printf(5, 0)
+static int __drm_encoder_init(struct drm_device *dev,
+ struct drm_encoder *encoder,
+ const struct drm_encoder_funcs *funcs,
+ int encoder_type, const char *name, va_list ap)
 {
int ret;
 
@@ -125,11 +112,7 @@ int drm_encoder_init(struct drm_device *dev,
encoder->encoder_type = encoder_type;
encoder->funcs = funcs;
if (name) {
-   va_list ap;
-
-   va_start(ap, name);
encoder->name = kvasprintf(GFP_KERNEL, name, ap);
-   va_end(ap);
} else {
encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
  
drm_encoder_enum_list[encoder_type].name,
@@ -150,6 +133,36 @@ int drm_encoder_init(struct drm_device *dev,
 
return ret;
 }
+
+/**
+ * drm_encoder_init - Init a preallocated encoder
+ * @dev: drm device
+ * @encoder: the encoder to init
+ * @funcs: callbacks for this encoder
+ * @encoder_type: user visible type of the encoder
+ * @name: printf style format string for the encoder name, or NULL for default 
name
+ *
+ * Initializes a preallocated encoder. Encoder should be subclassed as part of
+ * driver encoder objects. At driver unload time drm_encoder_cleanup() should 
be
+ * called from the driver's &drm_encoder_funcs.destroy hook.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_encoder_init(struct drm_device *dev,
+struct drm_encoder *encoder,
+const struct drm_encoder_funcs *funcs,
+int encoder_type, const char *name, ...)
+{
+   va_list ap;
+   int ret;
+
+   va_start(ap, name);
+   ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, name, ap);
+   va_end(ap);
+
+   return ret;
+}
 EXPORT_SYMBOL(drm_encoder_init);
 
 /**
@@ -181,6 +194,48 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+static void drmm_encoder_alloc_release(struct drm_device *dev, void *ptr)
+{
+   struct drm_encoder *encoder = ptr;
+
+   if (WARN_ON(!encoder->dev))
+   return;
+
+   drm_encoder_cleanup(encoder);
+}
+
+void *__drmm_encoder_alloc(struct drm_device *dev, size_t size, size_t offset,
+  const struct drm_encoder_funcs *funcs,
+  int encoder_type, const char *name, ...)
+{
+   void *container;
+   struct drm_encoder *encoder;
+   va_list ap;
+   int ret;
+
+   if (WARN_ON(!funcs || funcs->destroy))
+   return ERR_PTR(-EINVAL);
+
+   container = drmm_kzalloc(dev, size, GFP_KERNEL);
+   if (!container)
+   return ERR_PTR(-EINVAL);
+
+   encoder = container + offset;
+
+   va_start(ap, name);
+   ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, name, ap);
+   va_end(ap);
+   if (ret)
+   return ERR_PTR(ret);
+
+   ret = drmm_add_action_or_reset(dev, drmm_encoder_alloc_release, 
encoder);
+   if (ret)
+   return ERR_PTR(ret);
+
+   return container;
+}
+EXPORT_SYMBOL(__drmm_encoder_alloc);
+
 static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
 {
struct drm_connector *connector;
diff --git a/include/drm/drm_encoder.h b/include/

[PATCH v3 4/7] drm/crtc: add drmm_crtc_alloc_with_planes()

2020-09-11 Thread Philipp Zabel
Add an alternative to drm_crtc_init_with_planes() that allocates
and initializes a crtc and registers drm_crtc_cleanup() with
drmm_add_action_or_reset().

Signed-off-by: Philipp Zabel 
---
Changes since v2:
 - call va_start() / va_end() unconditionally
---
 drivers/gpu/drm/drm_crtc.c | 116 -
 include/drm/drm_crtc.h |  33 +++
 2 files changed, 121 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index aecdd7ea26dc..b9e7c11a76b7 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -231,30 +232,12 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc 
*crtc)
  * Setting MODE_ID to 0 will release reserved resources for the CRTC.
  */
 
-/**
- * drm_crtc_init_with_planes - Initialise a new CRTC object with
- *specified primary and cursor planes.
- * @dev: DRM device
- * @crtc: CRTC object to init
- * @primary: Primary plane for CRTC
- * @cursor: Cursor plane for CRTC
- * @funcs: callbacks for the new CRTC
- * @name: printf style format string for the CRTC name, or NULL for default 
name
- *
- * Inits a new object created as base part of a driver crtc object. Drivers
- * should use this function instead of drm_crtc_init(), which is only provided
- * for backwards compatibility with drivers which do not yet support universal
- * planes). For really simple hardware which has only 1 plane look at
- * drm_simple_display_pipe_init() instead.
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
- struct drm_plane *primary,
- struct drm_plane *cursor,
- const struct drm_crtc_funcs *funcs,
- const char *name, ...)
+__printf(6, 0)
+static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc 
*crtc,
+  struct drm_plane *primary,
+  struct drm_plane *cursor,
+  const struct drm_crtc_funcs *funcs,
+  const char *name, va_list ap)
 {
struct drm_mode_config *config = &dev->mode_config;
int ret;
@@ -282,11 +265,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
return ret;
 
if (name) {
-   va_list ap;
-
-   va_start(ap, name);
crtc->name = kvasprintf(GFP_KERNEL, name, ap);
-   va_end(ap);
} else {
crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
   drm_num_crtcs(dev));
@@ -330,8 +309,89 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
 
return 0;
 }
+
+/**
+ * drm_crtc_init_with_planes - Initialise a new CRTC object with
+ *specified primary and cursor planes.
+ * @dev: DRM device
+ * @crtc: CRTC object to init
+ * @primary: Primary plane for CRTC
+ * @cursor: Cursor plane for CRTC
+ * @funcs: callbacks for the new CRTC
+ * @name: printf style format string for the CRTC name, or NULL for default 
name
+ *
+ * Inits a new object created as base part of a driver crtc object. Drivers
+ * should use this function instead of drm_crtc_init(), which is only provided
+ * for backwards compatibility with drivers which do not yet support universal
+ * planes). For really simple hardware which has only 1 plane look at
+ * drm_simple_display_pipe_init() instead.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
+ struct drm_plane *primary,
+ struct drm_plane *cursor,
+ const struct drm_crtc_funcs *funcs,
+ const char *name, ...)
+{
+   va_list ap;
+   int ret;
+
+   va_start(ap, name);
+   ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
+ name, ap);
+   va_end(ap);
+
+   return ret;
+}
 EXPORT_SYMBOL(drm_crtc_init_with_planes);
 
+static void drmm_crtc_alloc_with_planes_cleanup(struct drm_device *dev,
+   void *ptr)
+{
+   struct drm_crtc *crtc = ptr;
+
+   drm_crtc_cleanup(crtc);
+}
+
+void *__drmm_crtc_alloc_with_planes(struct drm_device *dev,
+   size_t size, size_t offset,
+   struct drm_plane *primary,
+   struct drm_plane *cursor,
+   const struct drm_crtc_funcs *funcs,
+   const char *name, ...)
+{
+   void *container;
+   

[PATCH v3 2/7] drm/simple_kms_helper: add drmm_simple_encoder_alloc()

2020-09-11 Thread Philipp Zabel
Add an alternative to drm_simple_encoder_init() that allocates and
initializes a simple encoder and registers drm_encoder_cleanup() with
drmm_add_action_or_reset().

Signed-off-by: Philipp Zabel 
---
 drivers/gpu/drm/drm_simple_kms_helper.c | 12 
 include/drm/drm_simple_kms_helper.h | 24 
 2 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c 
b/drivers/gpu/drm/drm_simple_kms_helper.c
index 74946690aba4..3cbbfb0f9b51 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -71,6 +72,17 @@ int drm_simple_encoder_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_simple_encoder_init);
 
+static const struct drm_encoder_funcs drmm_simple_encoder_funcs_empty = { };
+
+void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size,
+ size_t offset, int encoder_type)
+{
+   return __drmm_encoder_alloc(dev, size, offset,
+   &drmm_simple_encoder_funcs_empty,
+   encoder_type, NULL);
+}
+EXPORT_SYMBOL(__drmm_simple_encoder_alloc);
+
 static enum drm_mode_status
 drm_simple_kms_crtc_mode_valid(struct drm_crtc *crtc,
   const struct drm_display_mode *mode)
diff --git a/include/drm/drm_simple_kms_helper.h 
b/include/drm/drm_simple_kms_helper.h
index a026375464ff..e6dbf3161c2f 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -185,4 +185,28 @@ int drm_simple_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder,
int encoder_type);
 
+void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size,
+ size_t offset, int encoder_type);
+
+/**
+ * drmm_simple_encoder_alloc - Allocate and initialize an encoder with basic
+ * functionality.
+ * @dev: drm device
+ * @type: the type of the struct which contains struct &drm_encoder
+ * @member: the name of the &drm_encoder within @type.
+ * @encoder_type: user visible type of the encoder
+ *
+ * Allocates and initializes an encoder that has no further functionality.
+ * Settings for possible CRTC and clones are left to their initial values.
+ * Cleanup is automatically handled through registering drm_encoder_cleanup()
+ * with drmm_add_action().
+ *
+ * Returns:
+ * Pointer to new encoder, or ERR_PTR on failure.
+ */
+#define drmm_simple_encoder_alloc(dev, type, member, encoder_type) \
+   ((type *)__drmm_simple_encoder_alloc(dev, sizeof(type), \
+offsetof(type, member), \
+encoder_type))
+
 #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 7/7] drm/imx: ipuv3-crtc: use drmm_crtc_alloc_with_planes()

2020-09-11 Thread Philipp Zabel
Merge ipu_crtc_init into ipu_drm_bind and use
drmm_crtc_alloc_with_planes().
This allows to drop the custom drm_crtc_cleanup action.

Signed-off-by: Philipp Zabel 
---
New in v3, example conversion of drm_crtc_init_with_planes() user.
---
 drivers/gpu/drm/imx/ipuv3-crtc.c | 71 
 1 file changed, 26 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index f284e4ea6d5f..982ef79653ae 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -349,47 +349,43 @@ static int ipu_get_resources(struct drm_device *dev, 
struct ipu_crtc *ipu_crtc,
return 0;
 }
 
-static void ipu_crtc_cleanup(struct drm_device *drm, void *ptr)
-{
-   struct drm_crtc *crtc = ptr;
-
-   drm_crtc_cleanup(crtc);
-}
-
-static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
-   struct ipu_client_platformdata *pdata, struct drm_device *drm)
+static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
 {
-   struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
-   struct drm_crtc *crtc = &ipu_crtc->base;
+   struct ipu_client_platformdata *pdata = dev->platform_data;
+   struct ipu_soc *ipu = dev_get_drvdata(dev->parent);
+   struct drm_device *drm = data;
+   struct ipu_plane *primary_plane;
+   struct ipu_crtc *ipu_crtc;
+   struct drm_crtc *crtc;
int dp = -EINVAL;
int ret;
 
-   ret = ipu_get_resources(drm, ipu_crtc, pdata);
-   if (ret) {
-   dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
-   ret);
-   return ret;
-   }
-
if (pdata->dp >= 0)
dp = IPU_DP_FLOW_SYNC_BG;
-   ipu_crtc->plane[0] = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0,
-   DRM_PLANE_TYPE_PRIMARY);
-   if (IS_ERR(ipu_crtc->plane[0])) {
-   ret = PTR_ERR(ipu_crtc->plane[0]);
-   return ret;
-   }
+   primary_plane = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0,
+  DRM_PLANE_TYPE_PRIMARY);
+   if (IS_ERR(primary_plane))
+   return PTR_ERR(primary_plane);
 
+   ipu_crtc = drmm_crtc_alloc_with_planes(drm, struct ipu_crtc, base,
+  &primary_plane->base, NULL,
+  &ipu_crtc_funcs, NULL);
+   if (IS_ERR(ipu_crtc))
+   return PTR_ERR(ipu_crtc);
+
+   ipu_crtc->dev = dev;
+   ipu_crtc->plane[0] = primary_plane;
+
+   crtc = &ipu_crtc->base;
crtc->port = pdata->of_node;
drm_crtc_helper_add(crtc, &ipu_helper_funcs);
-   ret = drm_crtc_init_with_planes(drm, crtc, &ipu_crtc->plane[0]->base,
-   NULL, &ipu_crtc_funcs, NULL);
-   if (ret)
-   return ret;
 
-   ret = drmm_add_action_or_reset(drm, ipu_crtc_cleanup, crtc);
-   if (ret)
+   ret = ipu_get_resources(drm, ipu_crtc, pdata);
+   if (ret) {
+   dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
+   ret);
return ret;
+   }
 
/* If this crtc is using the DP, add an overlay plane */
if (pdata->dp >= 0 && pdata->dma[1] > 0) {
@@ -414,21 +410,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
return 0;
 }
 
-static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
-{
-   struct ipu_client_platformdata *pdata = dev->platform_data;
-   struct drm_device *drm = data;
-   struct ipu_crtc *ipu_crtc;
-
-   ipu_crtc = drmm_kzalloc(drm, sizeof(*ipu_crtc), GFP_KERNEL);
-   if (!ipu_crtc)
-   return -ENOMEM;
-
-   ipu_crtc->dev = dev;
-
-   return ipu_crtc_init(ipu_crtc, pdata, drm);
-}
-
 static const struct component_ops ipu_crtc_ops = {
.bind = ipu_drm_bind,
 };
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 3/7] drm/plane: add drmm_universal_plane_alloc()

2020-09-11 Thread Philipp Zabel
Add an alternative to drm_universal_plane_init() that allocates
and initializes a plane and registers drm_plane_cleanup() with
drmm_add_action_or_reset().

Signed-off-by: Philipp Zabel 
---
Changes since v2:
 - call va_start() / va_end() unconditionally
---
 drivers/gpu/drm/drm_plane.c | 126 +++-
 include/drm/drm_plane.h |  42 
 2 files changed, 139 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index affe1cfed009..0081f6bb76b2 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "drm_crtc_internal.h"
@@ -152,31 +153,16 @@ static int create_in_format_blob(struct drm_device *dev, 
struct drm_plane *plane
return 0;
 }
 
-/**
- * drm_universal_plane_init - Initialize a new universal plane object
- * @dev: DRM device
- * @plane: plane object to init
- * @possible_crtcs: bitmask of possible CRTCs
- * @funcs: callbacks for the new plane
- * @formats: array of supported formats (DRM_FORMAT\_\*)
- * @format_count: number of elements in @formats
- * @format_modifiers: array of struct drm_format modifiers terminated by
- *DRM_FORMAT_MOD_INVALID
- * @type: type of plane (overlay, primary, cursor)
- * @name: printf style format string for the plane name, or NULL for default 
name
- *
- * Initializes a plane object of type @type.
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
-uint32_t possible_crtcs,
-const struct drm_plane_funcs *funcs,
-const uint32_t *formats, unsigned int format_count,
-const uint64_t *format_modifiers,
-enum drm_plane_type type,
-const char *name, ...)
+__printf(9, 0)
+static int __drm_universal_plane_init(struct drm_device *dev,
+ struct drm_plane *plane,
+ uint32_t possible_crtcs,
+ const struct drm_plane_funcs *funcs,
+ const uint32_t *formats,
+ unsigned int format_count,
+ const uint64_t *format_modifiers,
+ enum drm_plane_type type,
+ const char *name, va_list ap)
 {
struct drm_mode_config *config = &dev->mode_config;
unsigned int format_modifier_count = 0;
@@ -237,11 +223,7 @@ int drm_universal_plane_init(struct drm_device *dev, 
struct drm_plane *plane,
}
 
if (name) {
-   va_list ap;
-
-   va_start(ap, name);
plane->name = kvasprintf(GFP_KERNEL, name, ap);
-   va_end(ap);
} else {
plane->name = kasprintf(GFP_KERNEL, "plane-%d",
drm_num_planes(dev));
@@ -286,8 +268,94 @@ int drm_universal_plane_init(struct drm_device *dev, 
struct drm_plane *plane,
 
return 0;
 }
+
+/**
+ * drm_universal_plane_init - Initialize a new universal plane object
+ * @dev: DRM device
+ * @plane: plane object to init
+ * @possible_crtcs: bitmask of possible CRTCs
+ * @funcs: callbacks for the new plane
+ * @formats: array of supported formats (DRM_FORMAT\_\*)
+ * @format_count: number of elements in @formats
+ * @format_modifiers: array of struct drm_format modifiers terminated by
+ *DRM_FORMAT_MOD_INVALID
+ * @type: type of plane (overlay, primary, cursor)
+ * @name: printf style format string for the plane name, or NULL for default 
name
+ *
+ * Initializes a plane object of type @type.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
+uint32_t possible_crtcs,
+const struct drm_plane_funcs *funcs,
+const uint32_t *formats, unsigned int format_count,
+const uint64_t *format_modifiers,
+enum drm_plane_type type,
+const char *name, ...)
+{
+   va_list ap;
+   int ret;
+
+   va_start(ap, name);
+   ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
+formats, format_count, 
format_modifiers,
+type, name, ap);
+   va_end(ap);
+   return ret;
+}
 EXPORT_SYMBOL(drm_universal_plane_init);
 
+static void drmm_universal_plane_alloc_release(struct drm_device *dev, void 
*ptr)
+{
+   struct drm_plane *plane = ptr;
+
+   if (WARN_ON(!plane->dev))
+   return;
+
+   drm_plane

[PATCH v3 5/7] drm/imx: use drmm_simple_encoder_alloc()

2020-09-11 Thread Philipp Zabel
This allows to drop the custom drm_encoder_cleanup() actions.

Signed-off-by: Philipp Zabel 
---
New in v3, example conversion of drm_simple_encoder_init() users.

This and the following patches depend on the drm/imx conversion to use managed
resources [1].

[1] 
https://lore.kernel.org/dri-devel/20200911133855.29801-3-p.za...@pengutronix.de/T/#m335a28c5c26ab14bccc998d4dc0aed6850e9bc36
---
 drivers/gpu/drm/imx/dw_hdmi-imx.c  | 19 ---
 drivers/gpu/drm/imx/imx-ldb.c  | 20 
 drivers/gpu/drm/imx/imx-tve.c  | 22 --
 drivers/gpu/drm/imx/parallel-display.c | 22 --
 4 files changed, 16 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 16be8bd92653..87428fb23d9f 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -188,13 +188,6 @@ static const struct of_device_id dw_hdmi_imx_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids);
 
-static void dw_hdmi_imx_encoder_cleanup(struct drm_device *drm, void *data)
-{
-   struct drm_encoder *encoder = data;
-
-   drm_encoder_cleanup(encoder);
-}
-
 static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
void *data)
 {
@@ -203,9 +196,10 @@ static int dw_hdmi_imx_bind(struct device *dev, struct 
device *master,
struct drm_encoder *encoder;
int ret;
 
-   hdmi_encoder = drmm_kzalloc(drm, sizeof(*hdmi_encoder), GFP_KERNEL);
-   if (!hdmi_encoder)
-   return -ENOMEM;
+   hdmi_encoder = drmm_simple_encoder_alloc(drm, struct imx_hdmi_encoder,
+encoder, 
DRM_MODE_ENCODER_TMDS);
+   if (IS_ERR(hdmi_encoder))
+   return PTR_ERR(hdmi_encoder);
 
hdmi_encoder->hdmi = dev_get_drvdata(dev);
encoder = &hdmi_encoder->encoder;
@@ -215,11 +209,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct 
device *master,
return ret;
 
drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
-   drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
-
-   ret = drmm_add_action_or_reset(drm, dw_hdmi_imx_encoder_cleanup, 
encoder);
-   if (ret)
-   return ret;
 
return drm_bridge_attach(encoder, hdmi_encoder->hdmi->bridge, NULL, 0);
 }
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index d4beb58f509d..dbfe39e2f7f6 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -414,13 +414,6 @@ static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno)
return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]);
 }
 
-static void imx_ldb_encoder_cleanup(struct drm_device *drm, void *data)
-{
-   struct drm_encoder *encoder = data;
-
-   drm_encoder_cleanup(encoder);
-}
-
 static int imx_ldb_register(struct drm_device *drm,
struct imx_ldb_channel *imx_ldb_ch)
 {
@@ -430,20 +423,15 @@ static int imx_ldb_register(struct drm_device *drm,
struct drm_encoder *encoder;
int ret;
 
-   ldb_encoder = drmm_kzalloc(drm, sizeof(*ldb_encoder), GFP_KERNEL);
-   if (!ldb_encoder)
-   return -ENOMEM;
+   ldb_encoder = drmm_simple_encoder_alloc(drm, struct imx_ldb_encoder,
+   encoder, DRM_MODE_ENCODER_LVDS);
+   if (IS_ERR(ldb_encoder))
+   return PTR_ERR(ldb_encoder);
 
ldb_encoder->channel = imx_ldb_ch;
connector = &ldb_encoder->connector;
encoder = &ldb_encoder->encoder;
 
-   drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_LVDS);
-
-   ret = drmm_add_action_or_reset(drm, imx_ldb_encoder_cleanup, encoder);
-   if (ret)
-   return ret;
-
ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index bac025eafa1f..0746f0b425df 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -433,13 +433,6 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem 
*base)
return 0;
 }
 
-static void imx_tve_encoder_cleanup(struct drm_device *drm, void *ptr)
-{
-   struct drm_encoder *encoder = ptr;
-
-   drm_encoder_cleanup(encoder);
-}
-
 static void imx_tve_disable_regulator(void *data)
 {
struct imx_tve *tve = data;
@@ -498,22 +491,15 @@ static int imx_tve_bind(struct device *dev, struct device 
*master, void *data)
encoder_type = tve->mode == TVE_MODE_VGA ?
   DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
 
-   tvee = drmm_kzalloc(drm, sizeof(*tvee), GFP_KERNEL);
-   if (!tvee)
-   return -ENOMEM;
+   tvee = drmm_simple_encoder_alloc(drm, struct imx_tve_encoder, encoder,
+encoder_type);
+ 

[PATCH v3 6/7] drm/imx: use drmm_universal_plane_alloc()

2020-09-11 Thread Philipp Zabel
This allows to drop the custom drm_plane_cleanup action.

Signed-off-by: Philipp Zabel 
---
New in v3, example conversion of drm_universal_plane_init() user.
---
 drivers/gpu/drm/imx/ipuv3-plane.c | 34 ---
 1 file changed, 9 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index 38b959aa3564..075508051b5f 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -815,13 +815,6 @@ int ipu_planes_assign_pre(struct drm_device *dev,
 }
 EXPORT_SYMBOL_GPL(ipu_planes_assign_pre);
 
-static void ipu_plane_cleanup(struct drm_device *dev, void *data)
-{
-   struct ipu_plane *ipu_plane = data;
-
-   drm_plane_cleanup(&ipu_plane->base);
-}
-
 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
 int dma, int dp, unsigned int possible_crtcs,
 enum drm_plane_type type)
@@ -834,10 +827,15 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, 
struct ipu_soc *ipu,
DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
  dma, dp, possible_crtcs);
 
-   ipu_plane = drmm_kzalloc(dev, sizeof(*ipu_plane), GFP_KERNEL);
-   if (!ipu_plane) {
-   DRM_ERROR("failed to allocate plane\n");
-   return ERR_PTR(-ENOMEM);
+   ipu_plane = drmm_universal_plane_alloc(dev, struct ipu_plane, base,
+  possible_crtcs, &ipu_plane_funcs,
+  ipu_plane_formats,
+  ARRAY_SIZE(ipu_plane_formats),
+  modifiers, type, NULL);
+   if (IS_ERR(ipu_plane)) {
+   DRM_ERROR("failed to allocate and initialize %s plane\n",
+ zpos ? "overlay" : "primary");
+   return ipu_plane;
}
 
ipu_plane->ipu = ipu;
@@ -847,20 +845,6 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, 
struct ipu_soc *ipu,
if (ipu_prg_present(ipu))
modifiers = pre_format_modifiers;
 
-   ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
-  &ipu_plane_funcs, ipu_plane_formats,
-  ARRAY_SIZE(ipu_plane_formats),
-  modifiers, type, NULL);
-   if (ret) {
-   DRM_ERROR("failed to initialize %s plane\n",
- zpos ? "overlay" : "primary");
-   return ERR_PTR(ret);
-   }
-
-   ret = drmm_add_action_or_reset(dev, ipu_plane_cleanup, ipu_plane);
-   if (ret)
-   return ERR_PTR(ret);
-
drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs);
 
if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG)
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/imx/dcss: fix 64-bit divisions

2020-09-11 Thread Ville Syrjälä
On Fri, Sep 11, 2020 at 04:48:27PM +0300, Laurentiu Palcu wrote:
> Use div_s64() for the 64-bit divisions. This would allow the driver to compile
> on 32-bit architectures, if needed.
> 
> Signed-off-by: Laurentiu Palcu 
> ---
>  drivers/gpu/drm/imx/dcss/dcss-scaler.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-scaler.c 
> b/drivers/gpu/drm/imx/dcss/dcss-scaler.c
> index cd21905de580..7c1e0e461244 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-scaler.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-scaler.c
> @@ -134,7 +134,7 @@ static int div_q(int A, int B)
>   else
>   temp -= B / 2;
>  
> - result = (int)(temp / B);
> + result = (int)(div_s64(temp, B));
>   return result;
>  }
>  
> @@ -237,7 +237,7 @@ static void dcss_scaler_gaussian_filter(int fc_q, bool 
> use_5_taps,
>   ll_temp = coef[phase][i];
>   ll_temp <<= PSC_COEFF_PRECISION;
>   ll_temp += sum >> 1;
> - ll_temp /= sum;

That looks like hand rolled DIV_ROUND_CLOSEST_ULL()

> + ll_temp = div_s64(ll_temp, sum);
>   coef[phase][i] = (int)ll_temp;
>   }
>   }
> -- 
> 2.17.1
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 12/16] drm/exynos: configure mode on drm bridge

2020-09-11 Thread Michael Tretter
The driver uses the encoder to get the mode that shall be configured.
This is not possible, if the driver is used as a bridge, because the
encoder might not be used.

Use the mode_set function to set the display mode.

Signed-off-by: Michael Tretter 
---
v2: none
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index a4f17d50d1d8..988447812333 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -288,6 +288,8 @@ struct exynos_dsi {
u32 mode_flags;
u32 format;
 
+   struct drm_display_mode mode;
+
int state;
struct drm_property *brightness;
struct completion completed;
@@ -961,7 +963,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 
 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 {
-   struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
+   struct drm_display_mode *m = &dsi->mode;
unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
u32 reg;
 
@@ -1659,11 +1661,22 @@ static void exynos_dsi_bridge_disable(struct drm_bridge 
*bridge)
exynos_dsi_disable(dsi);
 }
 
+static void exynos_dsi_bridge_mode_set(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode,
+  const struct drm_display_mode 
*adjusted_mode)
+{
+   struct exynos_dsi *dsi = bridge->driver_private;
+
+   /* The mode is set when actually enabling the device. */
+   drm_mode_copy(&dsi->mode, adjusted_mode);
+}
+
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
.attach = exynos_dsi_bridge_attach,
.detach = exynos_dsi_bridge_detach,
.enable = exynos_dsi_bridge_enable,
.disable = exynos_dsi_bridge_disable,
+   .mode_set = exynos_dsi_bridge_mode_set,
 };
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 15/16] drm/exynos: split out platform specific code

2020-09-11 Thread Michael Tretter
Split the driver into the drm bridge driver and the exynos platform
specific driver.

Signed-off-by: Michael Tretter 
---
v2: none
---
 drivers/gpu/drm/exynos/Makefile   |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c   | 372 +-
 drivers/gpu/drm/exynos/exynos_drm_dsi.h   |  64 +++
 drivers/gpu/drm/exynos/exynos_drm_dsi_pltfm.c | 333 
 4 files changed, 405 insertions(+), 366 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_dsi.h
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_dsi_pltfm.c

diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 2fd2f3ee4fcf..add70b336935 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -11,7 +11,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)   += exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON)   += exynos5433_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON)  += exynos7_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o
-exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o 
exynos_drm_dsi_pltfm.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DP)  += exynos_dp.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER)   += exynos_mixer.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index ad70f5ce81ad..e8aea9d90c34 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -32,8 +32,7 @@
 #include 
 #include 
 
-#include "exynos_drm_crtc.h"
-#include "exynos_drm_drv.h"
+#include "exynos_drm_dsi.h"
 
 /* returns true iff both arguments logically differs */
 #define NEQV(a, b) (!(a) ^ !(b))
@@ -44,10 +43,6 @@
 #define DSIM_TX_READY_HS_CLK   (1 << 10)
 #define DSIM_PLL_STABLE(1 << 31)
 
-/* DSIM_SWRST */
-#define DSIM_FUNCRST   (1 << 16)
-#define DSIM_SWRST (1 << 0)
-
 /* DSIM_TIMEOUT */
 #define DSIM_LPDR_TIMEOUT(x)   ((x) << 0)
 #define DSIM_BTA_TIMEOUT(x)((x) << 16)
@@ -239,31 +234,6 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_CMD_LPM BIT(2)
 #define DSIM_STATE_VIDOUT_AVAILABLEBIT(3)
 
-struct exynos_dsi;
-struct exynos_dsi_host_ops {
-   int (*attach)(struct device *dev, struct mipi_dsi_device *device);
-   int (*detach)(struct device *dev, struct mipi_dsi_device *device);
-   void (*te_handler)(struct device *dev);
-};
-
-enum exynos_reg_offset {
-   EXYNOS_REG_OFS,
-   EXYNOS5433_REG_OFS
-};
-
-struct exynos_dsi_driver_data {
-   enum exynos_reg_offset reg_ofs;
-   unsigned int plltmr_reg;
-   unsigned int has_freqband:1;
-   unsigned int has_clklane_stop:1;
-   unsigned int num_clks;
-   unsigned int max_freq;
-   unsigned int wait_for_reset;
-   unsigned int num_bits_resol;
-   const unsigned int *reg_values;
-   const struct exynos_dsi_host_ops *host_ops;
-};
-
 struct exynos_dsi {
struct drm_bridge bridge;
struct mipi_dsi_host dsi_host;
@@ -400,201 +370,6 @@ static inline u32 exynos_dsi_read(struct exynos_dsi *dsi, 
enum reg_idx idx)
return readl(dsi->reg_base + reg_ofs[idx]);
 }
 
-enum reg_value_idx {
-   RESET_TYPE,
-   PLL_TIMER,
-   STOP_STATE_CNT,
-   PHYCTRL_ULPS_EXIT,
-   PHYCTRL_VREG_LP,
-   PHYCTRL_SLEW_UP,
-   PHYTIMING_LPX,
-   PHYTIMING_HS_EXIT,
-   PHYTIMING_CLK_PREPARE,
-   PHYTIMING_CLK_ZERO,
-   PHYTIMING_CLK_POST,
-   PHYTIMING_CLK_TRAIL,
-   PHYTIMING_HS_PREPARE,
-   PHYTIMING_HS_ZERO,
-   PHYTIMING_HS_TRAIL
-};
-
-struct exynos_dsi_pltfm {
-   struct exynos_dsi *dsi;
-   struct drm_encoder encoder;
-};
-
-static const unsigned int reg_values[] = {
-   [RESET_TYPE] = DSIM_SWRST,
-   [PLL_TIMER] = 500,
-   [STOP_STATE_CNT] = 0xf,
-   [PHYCTRL_ULPS_EXIT] = 0x0af,
-   [PHYCTRL_VREG_LP] = 0,
-   [PHYCTRL_SLEW_UP] = 0,
-   [PHYTIMING_LPX] = 0x06,
-   [PHYTIMING_HS_EXIT] = 0x0b,
-   [PHYTIMING_CLK_PREPARE] = 0x07,
-   [PHYTIMING_CLK_ZERO] = 0x27,
-   [PHYTIMING_CLK_POST] = 0x0d,
-   [PHYTIMING_CLK_TRAIL] = 0x08,
-   [PHYTIMING_HS_PREPARE] = 0x09,
-   [PHYTIMING_HS_ZERO] = 0x0d,
-   [PHYTIMING_HS_TRAIL] = 0x0b,
-};
-
-static const unsigned int exynos5422_reg_values[] = {
-   [RESET_TYPE] = DSIM_SWRST,
-   [PLL_TIMER] = 500,
-   [STOP_STATE_CNT] = 0xf,
-   [PHYCTRL_ULPS_EXIT] = 0xaf,
-   [PHYCTRL_VREG_LP] = 0,
-   [PHYCTRL_SLEW_UP] = 0,
-   [PHYTIMING_LPX] = 0x08,
-   [PHYTIMING_HS_EXIT] = 0x0d,
-   [PHYTIMING_CLK_PREPARE] = 0x09,
-   [PHYTIMING_CLK_ZERO] = 0x30,
-   [PHYTIMING_CLK_POST] = 0x0e,
-   [PHYTIMING_CLK_TRAIL] = 0x0a,
-   [PHYTIMING_HS_PREPARE] = 0x0c,
-   [PHYTIMING_HS_ZERO] = 0x11,
-   [PHYTIMING_HS_TRAIL] = 0x0d,

[PATCH v2 08/16] drm/exynos: add host_ops callback for platform drivers

2020-09-11 Thread Michael Tretter
Platform drivers need to be aware if a mipi dsi device attaches or
detaches. Add host_ops to the driver_data for attach and detach
callbacks and move the i80 mode selection and the hotplug handling into
the callback, because these depend on the drm driver.

Signed-off-by: Michael Tretter 
---
v2:
- new patch
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 64 -
 1 file changed, 53 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 1a15ae71205d..684a2fbef08a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -239,6 +239,12 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_CMD_LPM BIT(2)
 #define DSIM_STATE_VIDOUT_AVAILABLEBIT(3)
 
+struct exynos_dsi;
+struct exynos_dsi_host_ops {
+   int (*attach)(struct device *dev, struct mipi_dsi_device *device);
+   int (*detach)(struct device *dev, struct mipi_dsi_device *device);
+};
+
 enum exynos_reg_offset {
EXYNOS_REG_OFS,
EXYNOS5433_REG_OFS
@@ -254,6 +260,7 @@ struct exynos_dsi_driver_data {
unsigned int wait_for_reset;
unsigned int num_bits_resol;
const unsigned int *reg_values;
+   const struct exynos_dsi_host_ops *host_ops;
 };
 
 struct exynos_dsi {
@@ -467,6 +474,41 @@ static const unsigned int exynos5433_reg_values[] = {
[PHYTIMING_HS_TRAIL] = 0x0c,
 };
 
+static int __exynos_dsi_host_attach(struct device *dev,
+   struct mipi_dsi_device *device)
+{
+   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct drm_device *drm = dsi->encoder.dev;
+   struct exynos_drm_crtc *crtc;
+
+   mutex_lock(&drm->mode_config.mutex);
+   crtc = exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD);
+   crtc->i80_mode = !(device->mode_flags & MIPI_DSI_MODE_VIDEO);
+   mutex_unlock(&drm->mode_config.mutex);
+
+   if (drm->mode_config.poll_enabled)
+   drm_kms_helper_hotplug_event(drm);
+
+   return 0;
+}
+
+static int __exynos_dsi_host_detach(struct device *dev,
+struct mipi_dsi_device *device)
+{
+   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct drm_device *drm = dsi->encoder.dev;
+
+   if (drm->mode_config.poll_enabled)
+   drm_kms_helper_hotplug_event(drm);
+
+   return 0;
+}
+
+static const struct exynos_dsi_host_ops exynos_dsi_host_ops = {
+   .attach = __exynos_dsi_host_attach,
+   .detach = __exynos_dsi_host_detach,
+};
+
 static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
.reg_ofs = EXYNOS_REG_OFS,
.plltmr_reg = 0x50,
@@ -477,6 +519,7 @@ static const struct exynos_dsi_driver_data 
exynos3_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
+   .host_ops = &exynos_dsi_host_ops,
 };
 
 static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
@@ -489,6 +532,7 @@ static const struct exynos_dsi_driver_data 
exynos4_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
+   .host_ops = &exynos_dsi_host_ops,
 };
 
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
@@ -499,6 +543,7 @@ static const struct exynos_dsi_driver_data 
exynos5_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
+   .host_ops = &exynos_dsi_host_ops,
 };
 
 static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
@@ -510,6 +555,7 @@ static const struct exynos_dsi_driver_data 
exynos5433_dsi_driver_data = {
.wait_for_reset = 0,
.num_bits_resol = 12,
.reg_values = exynos5433_reg_values,
+   .host_ops = &exynos_dsi_host_ops,
 };
 
 static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
@@ -521,6 +567,7 @@ static const struct exynos_dsi_driver_data 
exynos5422_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 12,
.reg_values = exynos5422_reg_values,
+   .host_ops = &exynos_dsi_host_ops,
 };
 
 static const struct of_device_id exynos_dsi_of_match[] = {
@@ -1551,8 +1598,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
  struct mipi_dsi_device *device)
 {
struct exynos_dsi *dsi = host_to_dsi(host);
+   const struct exynos_dsi_host_ops *ops = dsi->driver_data->host_ops;
struct drm_encoder *encoder = &dsi->encoder;
-   struct drm_device *drm = encoder->dev;
struct drm_bridge *out_bridge;
 
out_bridge  = of_drm_find_bridge(device->dev.of_node);
@@ -1590,18 +1637,12 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
return ret;
}
 
-   mutex_lock(&drm->mode_config.mutex);
-
dsi->lanes = device->lanes;
d

[PATCH v2 06/16] drm/exynos: shift register values to fields on write

2020-09-11 Thread Michael Tretter
The phy timings are already shifted to the field position. If the driver
is reused on multiple platforms, this exposes the field positions to the
platform code.

Store only the timing values in the platform data and shift the value to
the field when writing the fields to the registers.

Signed-off-by: Michael Tretter 
---
v2: none
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 88 +
 1 file changed, 46 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 41000214a5fe..0f2cac7ed944 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -399,54 +399,54 @@ static const unsigned int reg_values[] = {
[RESET_TYPE] = DSIM_SWRST,
[PLL_TIMER] = 500,
[STOP_STATE_CNT] = 0xf,
-   [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x0af),
+   [PHYCTRL_ULPS_EXIT] = 0x0af,
[PHYCTRL_VREG_LP] = 0,
[PHYCTRL_SLEW_UP] = 0,
-   [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),
-   [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),
-   [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),
-   [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x27),
-   [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),
-   [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),
-   [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x09),
-   [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),
-   [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
+   [PHYTIMING_LPX] = 0x06,
+   [PHYTIMING_HS_EXIT] = 0x0b,
+   [PHYTIMING_CLK_PREPARE] = 0x07,
+   [PHYTIMING_CLK_ZERO] = 0x27,
+   [PHYTIMING_CLK_POST] = 0x0d,
+   [PHYTIMING_CLK_TRAIL] = 0x08,
+   [PHYTIMING_HS_PREPARE] = 0x09,
+   [PHYTIMING_HS_ZERO] = 0x0d,
+   [PHYTIMING_HS_TRAIL] = 0x0b,
 };
 
 static const unsigned int exynos5422_reg_values[] = {
[RESET_TYPE] = DSIM_SWRST,
[PLL_TIMER] = 500,
[STOP_STATE_CNT] = 0xf,
-   [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),
+   [PHYCTRL_ULPS_EXIT] = 0xaf,
[PHYCTRL_VREG_LP] = 0,
[PHYCTRL_SLEW_UP] = 0,
-   [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x08),
-   [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0d),
-   [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),
-   [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x30),
-   [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),
-   [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x0a),
-   [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0c),
-   [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x11),
-   [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0d),
+   [PHYTIMING_LPX] = 0x08,
+   [PHYTIMING_HS_EXIT] = 0x0d,
+   [PHYTIMING_CLK_PREPARE] = 0x09,
+   [PHYTIMING_CLK_ZERO] = 0x30,
+   [PHYTIMING_CLK_POST] = 0x0e,
+   [PHYTIMING_CLK_TRAIL] = 0x0a,
+   [PHYTIMING_HS_PREPARE] = 0x0c,
+   [PHYTIMING_HS_ZERO] = 0x11,
+   [PHYTIMING_HS_TRAIL] = 0x0d,
 };
 
 static const unsigned int exynos5433_reg_values[] = {
[RESET_TYPE] = DSIM_FUNCRST,
[PLL_TIMER] = 22200,
[STOP_STATE_CNT] = 0xa,
-   [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x190),
-   [PHYCTRL_VREG_LP] = DSIM_PHYCTRL_B_DPHYCTL_VREG_LP,
-   [PHYCTRL_SLEW_UP] = DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP,
-   [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x07),
-   [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0c),
-   [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),
-   [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x2d),
-   [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),
-   [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x09),
-   [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0b),
-   [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x10),
-   [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
+   [PHYCTRL_ULPS_EXIT] = 0x190,
+   [PHYCTRL_VREG_LP] = 1,
+   [PHYCTRL_SLEW_UP] = 1,
+   [PHYTIMING_LPX] = 0x07,
+   [PHYTIMING_HS_EXIT] = 0x0c,
+   [PHYTIMING_CLK_PREPARE] = 0x09,
+   [PHYTIMING_CLK_ZERO] = 0x2d,
+   [PHYTIMING_CLK_POST] = 0x0e,
+   [PHYTIMING_CLK_TRAIL] = 0x09,
+   [PHYTIMING_HS_PREPARE] = 0x0b,
+   [PHYTIMING_HS_ZERO] = 0x10,
+   [PHYTIMING_HS_TRAIL] = 0x0c,
 };
 
 static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
@@ -698,8 +698,11 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
return;
 
/* B D-PHY: D-PHY Master & Slave Analog Block control */
-   reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |
-   reg_values[PHYCTRL_SLEW_UP];
+   reg = DSIM_PHYCTRL_ULPS_EXIT(reg_values[PHYCTRL_ULPS_EXIT]);
+   if (reg_values[PHYCTRL_VREG_LP])
+   reg |= DSIM_PHYCTRL_B_DPHYCTL_VREG_LP;
+   if (reg_va

[PATCH v2 03/16] drm/exynos: use exynos_dsi as drvdata

2020-09-11 Thread Michael Tretter
Use the exynos_dsi as drvdata instead of the encoder to further decouple
the driver from the encoder.

Signed-off-by: Michael Tretter 
---
v2: drop removal of encoder_to_dsi
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 29f941b02210..ed04064afbb2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1689,8 +1689,8 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
 static int exynos_dsi_bind(struct device *dev, struct device *master,
void *data)
 {
-   struct drm_encoder *encoder = dev_get_drvdata(dev);
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct drm_encoder *encoder = &dsi->encoder;
struct drm_device *drm_dev = data;
struct device_node *in_bridge_node;
struct drm_bridge *in_bridge;
@@ -1718,8 +1718,8 @@ static int exynos_dsi_bind(struct device *dev, struct 
device *master,
 static void exynos_dsi_unbind(struct device *dev, struct device *master,
void *data)
 {
-   struct drm_encoder *encoder = dev_get_drvdata(dev);
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct drm_encoder *encoder = &dsi->encoder;
 
exynos_dsi_disable(encoder);
 
@@ -1818,7 +1818,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   platform_set_drvdata(pdev, &dsi->encoder);
+   platform_set_drvdata(pdev, dsi);
 
pm_runtime_enable(dev);
 
@@ -1845,8 +1845,7 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 
 static int __maybe_unused exynos_dsi_suspend(struct device *dev)
 {
-   struct drm_encoder *encoder = dev_get_drvdata(dev);
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+   struct exynos_dsi *dsi = dev_get_drvdata(dev);
const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
int ret, i;
 
@@ -1876,8 +1875,7 @@ static int __maybe_unused exynos_dsi_suspend(struct 
device *dev)
 
 static int __maybe_unused exynos_dsi_resume(struct device *dev)
 {
-   struct drm_encoder *encoder = dev_get_drvdata(dev);
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+   struct exynos_dsi *dsi = dev_get_drvdata(dev);
const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
int ret, i;
 
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 02/16] drm/exynos: remove in_bridge_node from exynos_dsi

2020-09-11 Thread Michael Tretter
We do not need to keep a reference to the in_bridge_node, but we can
simply drop it, once we found and attached the previous bridge.

Signed-off-by: Michael Tretter 
---
v2: none
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 1a1a2853a842..29f941b02210 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -282,7 +282,6 @@ struct exynos_dsi {
struct list_head transfer_list;
 
const struct exynos_dsi_driver_data *driver_data;
-   struct device_node *in_bridge_node;
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
@@ -1684,8 +1683,6 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
if (ret < 0)
return ret;
 
-   dsi->in_bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0);
-
return 0;
 }
 
@@ -1695,6 +1692,7 @@ static int exynos_dsi_bind(struct device *dev, struct 
device *master,
struct drm_encoder *encoder = dev_get_drvdata(dev);
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
struct drm_device *drm_dev = data;
+   struct device_node *in_bridge_node;
struct drm_bridge *in_bridge;
int ret;
 
@@ -1706,10 +1704,12 @@ static int exynos_dsi_bind(struct device *dev, struct 
device *master,
if (ret < 0)
return ret;
 
-   if (dsi->in_bridge_node) {
-   in_bridge = of_drm_find_bridge(dsi->in_bridge_node);
+   in_bridge_node = of_graph_get_remote_node(dev->of_node, DSI_PORT_IN, 0);
+   if (in_bridge_node) {
+   in_bridge = of_drm_find_bridge(in_bridge_node);
if (in_bridge)
drm_bridge_attach(encoder, in_bridge, NULL, 0);
+   of_node_put(in_bridge_node);
}
 
return mipi_dsi_host_register(&dsi->dsi_host);
@@ -1830,17 +1830,12 @@ static int exynos_dsi_probe(struct platform_device 
*pdev)
 
 err_disable_runtime:
pm_runtime_disable(dev);
-   of_node_put(dsi->in_bridge_node);
 
return ret;
 }
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
-   struct exynos_dsi *dsi = platform_get_drvdata(pdev);
-
-   of_node_put(dsi->in_bridge_node);
-
pm_runtime_disable(&pdev->dev);
 
component_del(&pdev->dev, &exynos_dsi_component_ops);
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 04/16] drm/exynos: extract helper functions for probe

2020-09-11 Thread Michael Tretter
As the driver shall be usable with drivers that use the component
framework and drivers that don't, split the common probing code into a
separate function that can be called from different locations.

Signed-off-by: Michael Tretter 
---
v2:
- move pm_runtime_enable from helper to calling function
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 40 ++---
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index ed04064afbb2..f8e64b74a6dd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1731,7 +1731,7 @@ static const struct component_ops 
exynos_dsi_component_ops = {
.unbind = exynos_dsi_unbind,
 };
 
-static int exynos_dsi_probe(struct platform_device *pdev)
+static struct exynos_dsi *__exynos_dsi_probe(struct platform_device *pdev)
 {
struct device *dev = &pdev->dev;
struct resource *res;
@@ -1740,7 +1740,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
-   return -ENOMEM;
+   return ERR_PTR(-ENOMEM);
 
/* To be checked as invalid one */
dsi->te_gpio = -ENOENT;
@@ -1763,14 +1763,14 @@ static int exynos_dsi_probe(struct platform_device 
*pdev)
if (ret) {
if (ret != -EPROBE_DEFER)
dev_info(dev, "failed to get regulators: %d\n", ret);
-   return ret;
+   return ERR_PTR(ret);
}
 
dsi->clks = devm_kcalloc(dev,
dsi->driver_data->num_clks, sizeof(*dsi->clks),
GFP_KERNEL);
if (!dsi->clks)
-   return -ENOMEM;
+   return ERR_PTR(-ENOMEM);
 
for (i = 0; i < dsi->driver_data->num_clks; i++) {
dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
@@ -1784,7 +1784,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
dev_info(dev, "failed to get the clock: %s\n",
clk_names[i]);
-   return PTR_ERR(dsi->clks[i]);
+   return ERR_PTR(PTR_ERR(dsi->clks[i]));
}
}
 
@@ -1792,18 +1792,18 @@ static int exynos_dsi_probe(struct platform_device 
*pdev)
dsi->reg_base = devm_ioremap_resource(dev, res);
if (IS_ERR(dsi->reg_base)) {
dev_err(dev, "failed to remap io region\n");
-   return PTR_ERR(dsi->reg_base);
+   return dsi->reg_base;
}
 
dsi->phy = devm_phy_get(dev, "dsim");
if (IS_ERR(dsi->phy)) {
dev_info(dev, "failed to get dsim phy\n");
-   return PTR_ERR(dsi->phy);
+   return ERR_PTR(PTR_ERR(dsi->phy));
}
 
dsi->irq = platform_get_irq(pdev, 0);
if (dsi->irq < 0)
-   return dsi->irq;
+   return ERR_PTR(dsi->irq);
 
irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
ret = devm_request_threaded_irq(dev, dsi->irq, NULL,
@@ -1811,13 +1811,29 @@ static int exynos_dsi_probe(struct platform_device 
*pdev)
dev_name(dev), dsi);
if (ret) {
dev_err(dev, "failed to request dsi irq\n");
-   return ret;
+   return ERR_PTR(ret);
}
 
ret = exynos_dsi_parse_dt(dsi);
if (ret)
-   return ret;
+   return ERR_PTR(ret);
+
+   return dsi;
+}
+
+static void __exynos_dsi_remove(struct exynos_dsi *dsi)
+{
+}
 
+static int exynos_dsi_probe(struct platform_device *pdev)
+{
+   struct exynos_dsi *dsi;
+   struct device *dev = &pdev->dev;
+   int ret;
+
+   dsi = __exynos_dsi_probe(pdev);
+   if (IS_ERR(dsi))
+   return PTR_ERR(dsi);
platform_set_drvdata(pdev, dsi);
 
pm_runtime_enable(dev);
@@ -1836,8 +1852,12 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
+   struct exynos_dsi *dsi = platform_get_drvdata(pdev);
+
pm_runtime_disable(&pdev->dev);
 
+   __exynos_dsi_remove(dsi);
+
component_del(&pdev->dev, &exynos_dsi_component_ops);
 
return 0;
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 07/16] drm/exynos: use identifier instead of register offsets

2020-09-11 Thread Michael Tretter
Different revisions of the MIPI-DSI PHY have slightly different register
layouts. Currently, the register layout was stored per platform, which
makes it necessary to define the layout for each new platform.

Keep the register layout in the driver and use identifiers to specify
which register layout shall be used on a platform.

Signed-off-by: Michael Tretter 
---
v2: none
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 54 -
 1 file changed, 36 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0f2cac7ed944..1a15ae71205d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -239,8 +239,13 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_CMD_LPM BIT(2)
 #define DSIM_STATE_VIDOUT_AVAILABLEBIT(3)
 
+enum exynos_reg_offset {
+   EXYNOS_REG_OFS,
+   EXYNOS5433_REG_OFS
+};
+
 struct exynos_dsi_driver_data {
-   const unsigned int *reg_ofs;
+   enum exynos_reg_offset reg_ofs;
unsigned int plltmr_reg;
unsigned int has_freqband:1;
unsigned int has_clklane_stop:1;
@@ -317,18 +322,6 @@ enum reg_idx {
NUM_REGS
 };
 
-static inline void exynos_dsi_write(struct exynos_dsi *dsi, enum reg_idx idx,
-   u32 val)
-{
-
-   writel(val, dsi->reg_base + dsi->driver_data->reg_ofs[idx]);
-}
-
-static inline u32 exynos_dsi_read(struct exynos_dsi *dsi, enum reg_idx idx)
-{
-   return readl(dsi->reg_base + dsi->driver_data->reg_ofs[idx]);
-}
-
 static const unsigned int exynos_reg_ofs[] = {
[DSIM_STATUS_REG] =  0x00,
[DSIM_SWRST_REG] =  0x04,
@@ -377,6 +370,31 @@ static const unsigned int exynos5433_reg_ofs[] = {
[DSIM_PHYTIMING2_REG] = 0xBC,
 };
 
+static inline void exynos_dsi_write(struct exynos_dsi *dsi, enum reg_idx idx,
+   u32 val)
+{
+   const unsigned int *reg_ofs;
+
+   if (dsi->driver_data->reg_ofs == EXYNOS5433_REG_OFS)
+   reg_ofs = exynos5433_reg_ofs;
+   else
+   reg_ofs = exynos_reg_ofs;
+
+   writel(val, dsi->reg_base + reg_ofs[idx]);
+}
+
+static inline u32 exynos_dsi_read(struct exynos_dsi *dsi, enum reg_idx idx)
+{
+   const unsigned int *reg_ofs;
+
+   if (dsi->driver_data->reg_ofs == EXYNOS5433_REG_OFS)
+   reg_ofs = exynos5433_reg_ofs;
+   else
+   reg_ofs = exynos_reg_ofs;
+
+   return readl(dsi->reg_base + reg_ofs[idx]);
+}
+
 enum reg_value_idx {
RESET_TYPE,
PLL_TIMER,
@@ -450,7 +468,7 @@ static const unsigned int exynos5433_reg_values[] = {
 };
 
 static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
-   .reg_ofs = exynos_reg_ofs,
+   .reg_ofs = EXYNOS_REG_OFS,
.plltmr_reg = 0x50,
.has_freqband = 1,
.has_clklane_stop = 1,
@@ -462,7 +480,7 @@ static const struct exynos_dsi_driver_data 
exynos3_dsi_driver_data = {
 };
 
 static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
-   .reg_ofs = exynos_reg_ofs,
+   .reg_ofs = EXYNOS_REG_OFS,
.plltmr_reg = 0x50,
.has_freqband = 1,
.has_clklane_stop = 1,
@@ -474,7 +492,7 @@ static const struct exynos_dsi_driver_data 
exynos4_dsi_driver_data = {
 };
 
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
-   .reg_ofs = exynos_reg_ofs,
+   .reg_ofs = EXYNOS_REG_OFS,
.plltmr_reg = 0x58,
.num_clks = 2,
.max_freq = 1000,
@@ -484,7 +502,7 @@ static const struct exynos_dsi_driver_data 
exynos5_dsi_driver_data = {
 };
 
 static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
-   .reg_ofs = exynos5433_reg_ofs,
+   .reg_ofs = EXYNOS5433_REG_OFS,
.plltmr_reg = 0xa0,
.has_clklane_stop = 1,
.num_clks = 5,
@@ -495,7 +513,7 @@ static const struct exynos_dsi_driver_data 
exynos5433_dsi_driver_data = {
 };
 
 static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
-   .reg_ofs = exynos5433_reg_ofs,
+   .reg_ofs = EXYNOS5433_REG_OFS,
.plltmr_reg = 0xa0,
.has_clklane_stop = 1,
.num_clks = 2,
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 10/16] drm/exynos: implement a drm bridge

2020-09-11 Thread Michael Tretter
Make the exynos_dsi driver a full drm bridge that can be found and used
from other drivers.

Other drivers can only attach to the bridge, if a mipi dsi device
already attached to the bridge. This allows to defer the probe of the
display pipe until the downstream bridges are available, too.

Signed-off-by: Michael Tretter 
---
v2:
- move attach of out_bridge to bridge_attach
- add bridge_detach
- don't cleanup encoder if create_connector failed
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 103 +---
 1 file changed, 75 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 2d75f9877dc0..5e7c1a99a3ee 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -266,6 +266,7 @@ struct exynos_dsi_driver_data {
 
 struct exynos_dsi {
struct drm_encoder encoder;
+   struct drm_bridge bridge;
struct mipi_dsi_host dsi_host;
struct drm_connector connector;
struct drm_panel *panel;
@@ -1602,6 +1603,60 @@ static const struct drm_encoder_helper_funcs 
exynos_dsi_encoder_helper_funcs = {
.disable = exynos_dsi_disable,
 };
 
+static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
+   enum drm_bridge_attach_flags flags)
+{
+   struct exynos_dsi *dsi = bridge->driver_private;
+   struct drm_encoder *encoder = bridge->encoder;
+   int ret;
+
+   if (!dsi->out_bridge && !dsi->panel)
+   return -EPROBE_DEFER;
+
+   if (dsi->out_bridge) {
+   ret = drm_bridge_attach(encoder, dsi->out_bridge,
+   bridge, flags);
+   if (ret)
+   return ret;
+   list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
+   } else {
+   ret = exynos_dsi_create_connector(encoder);
+   if (ret)
+   return ret;
+
+   if (dsi->panel) {
+   dsi->connector.status = connector_status_connected;
+   }
+   }
+
+   return 0;
+}
+
+static void exynos_dsi_bridge_detach(struct drm_bridge *bridge)
+{
+   struct exynos_dsi *dsi = bridge->driver_private;
+   struct drm_encoder *encoder = bridge->encoder;
+   struct drm_device *drm = encoder->dev;
+
+   if (dsi->panel) {
+   mutex_lock(&drm->mode_config.mutex);
+   exynos_dsi_disable(&dsi->encoder);
+   dsi->panel = NULL;
+   dsi->connector.status = connector_status_disconnected;
+   mutex_unlock(&drm->mode_config.mutex);
+   } else {
+   if (dsi->out_bridge->funcs->detach)
+   dsi->out_bridge->funcs->detach(dsi->out_bridge);
+   dsi->out_bridge = NULL;
+   INIT_LIST_HEAD(&dsi->bridge_chain);
+   }
+}
+
+static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
+   .attach = exynos_dsi_bridge_attach,
+   .detach = exynos_dsi_bridge_detach,
+};
+
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
 
 static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
@@ -1609,25 +1664,12 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
 {
struct exynos_dsi *dsi = host_to_dsi(host);
const struct exynos_dsi_host_ops *ops = dsi->driver_data->host_ops;
-   struct drm_encoder *encoder = &dsi->encoder;
struct drm_bridge *out_bridge;
 
-   out_bridge  = of_drm_find_bridge(device->dev.of_node);
+   out_bridge = of_drm_find_bridge(device->dev.of_node);
if (out_bridge) {
-   drm_bridge_attach(encoder, out_bridge, NULL, 0);
dsi->out_bridge = out_bridge;
-   list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
} else {
-   int ret = exynos_dsi_create_connector(encoder);
-
-   if (ret) {
-   DRM_DEV_ERROR(dsi->dev,
- "failed to create connector ret = %d\n",
- ret);
-   drm_encoder_cleanup(encoder);
-   return ret;
-   }
-
dsi->panel = of_drm_find_panel(device->dev.of_node);
if (IS_ERR(dsi->panel))
dsi->panel = NULL;
@@ -1662,20 +1704,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host 
*host,
 {
struct exynos_dsi *dsi = host_to_dsi(host);
const struct exynos_dsi_host_ops *ops = dsi->driver_data->host_ops;
-   struct drm_device *drm = dsi->encoder.dev;
-
-   if (dsi->panel) {
-   mutex_lock(&drm->mode_config.mutex);
-   exynos_dsi_disable(&dsi->encoder);
-   dsi->panel = NULL;
-   dsi->connector.status = connector_status_disconnected;
-   mutex_unlock(&drm->mode_config.mutex);
-   } else {
-   if (dsi-

[PATCH v2 05/16] drm/exynos: move dsi host registration to probe

2020-09-11 Thread Michael Tretter
Once the driver implements a drm_bridge, the bridge will be attached
during bind. The driver has to register the mipi dsi host before making
the driver available at the component framework, because the bridge is
only initialized when a mipi dsi device attaches.

Signed-off-by: Michael Tretter 
---
v2: none
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index f8e64b74a6dd..41000214a5fe 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1712,7 +1712,7 @@ static int exynos_dsi_bind(struct device *dev, struct 
device *master,
of_node_put(in_bridge_node);
}
 
-   return mipi_dsi_host_register(&dsi->dsi_host);
+   return 0;
 }
 
 static void exynos_dsi_unbind(struct device *dev, struct device *master,
@@ -1722,8 +1722,6 @@ static void exynos_dsi_unbind(struct device *dev, struct 
device *master,
struct drm_encoder *encoder = &dsi->encoder;
 
exynos_dsi_disable(encoder);
-
-   mipi_dsi_host_unregister(&dsi->dsi_host);
 }
 
 static const struct component_ops exynos_dsi_component_ops = {
@@ -1818,11 +1816,16 @@ static struct exynos_dsi *__exynos_dsi_probe(struct 
platform_device *pdev)
if (ret)
return ERR_PTR(ret);
 
+   ret = mipi_dsi_host_register(&dsi->dsi_host);
+   if (ret)
+   return ERR_PTR(ret);
+
return dsi;
 }
 
 static void __exynos_dsi_remove(struct exynos_dsi *dsi)
 {
+   mipi_dsi_host_unregister(&dsi->dsi_host);
 }
 
 static int exynos_dsi_probe(struct platform_device *pdev)
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 11/16] drm/exynos: convert encoder functions to bridge function

2020-09-11 Thread Michael Tretter
If other drivers use the exynos_dsi driver as a bridge, they might bring
their own encoder. Enable and disable the MIPI-DSI bridge using the
bridge functions instead of the encoder functions.

Signed-off-by: Michael Tretter 
---
v2: none
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 33 +++--
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 5e7c1a99a3ee..a4f17d50d1d8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1455,9 +1455,8 @@ static void exynos_dsi_unregister_te_irq(struct 
exynos_dsi *dsi)
}
 }
 
-static void exynos_dsi_enable(struct drm_encoder *encoder)
+static void exynos_dsi_enable(struct exynos_dsi *dsi)
 {
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
struct drm_bridge *iter;
int ret;
 
@@ -1505,9 +1504,8 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
pm_runtime_put(dsi->dev);
 }
 
-static void exynos_dsi_disable(struct drm_encoder *encoder)
+static void exynos_dsi_disable(struct exynos_dsi *dsi)
 {
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
struct drm_bridge *iter;
 
if (!(dsi->state & DSIM_STATE_ENABLED))
@@ -1598,11 +1596,6 @@ static int exynos_dsi_create_connector(struct 
drm_encoder *encoder)
return 0;
 }
 
-static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = 
{
-   .enable = exynos_dsi_enable,
-   .disable = exynos_dsi_disable,
-};
-
 static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
 {
@@ -1640,7 +1633,7 @@ static void exynos_dsi_bridge_detach(struct drm_bridge 
*bridge)
 
if (dsi->panel) {
mutex_lock(&drm->mode_config.mutex);
-   exynos_dsi_disable(&dsi->encoder);
+   exynos_dsi_disable(dsi);
dsi->panel = NULL;
dsi->connector.status = connector_status_disconnected;
mutex_unlock(&drm->mode_config.mutex);
@@ -1652,9 +1645,25 @@ static void exynos_dsi_bridge_detach(struct drm_bridge 
*bridge)
}
 }
 
+static void exynos_dsi_bridge_enable(struct drm_bridge *bridge)
+{
+   struct exynos_dsi *dsi = bridge->driver_private;
+
+   exynos_dsi_enable(dsi);
+}
+
+static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
+{
+   struct exynos_dsi *dsi = bridge->driver_private;
+
+   exynos_dsi_disable(dsi);
+}
+
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
.attach = exynos_dsi_bridge_attach,
.detach = exynos_dsi_bridge_detach,
+   .enable = exynos_dsi_bridge_enable,
+   .disable = exynos_dsi_bridge_disable,
 };
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
@@ -1800,8 +1809,6 @@ static int exynos_dsi_bind(struct device *dev, struct 
device *master,
 
drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
-   drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
-
ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
if (ret < 0)
return ret;
@@ -1831,7 +1838,7 @@ static void exynos_dsi_unbind(struct device *dev, struct 
device *master,
struct exynos_dsi *dsi = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dsi->encoder;
 
-   exynos_dsi_disable(encoder);
+   exynos_dsi_disable(dsi);
 
drm_encoder_cleanup(encoder);
 }
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 00/16] drm/exynos: Convert driver to drm bridge

2020-09-11 Thread Michael Tretter
This is v2 of the series to convert the Exynos MIPI DSI driver into a drm
bridge and make it usable with other drivers. Although the driver is
converted, it still supports the component framework API to stay compliant
with the Exynos DRM driver.

The Exynos MIPI DSI Phy is also found on the i.MX8M Mini. However, on the
i.MX8M Mini, the bridge is driven by an LCDIF display controller instead of
the Exynos Decon. The driver for the LCDIF does not use the component
framework, but uses drm bridges.

I don't have any Exynos SoC to actually test the series. I build a dummy to
test the bridge with a component driver, to make sure that at least the
initialization is working. Furthermore, tested the driver as a bridge with a
few additional unfinished patches on the i.MX8M Mini EVK. However, somebody
should verify that the driver is still working on Exynos hardware.

I also changed the order of the patches to first make the driver more platform
independent (patches 2 to 8), then convert to a drm bridge driver (patches 10
to 13) and finally expose the API, split the code and move the platform
independent driver to the bridges (patches 14 - 16). Hopefully this simplifies
testing/bisecting and helps me to understand potential error reports.

Also I added host_ops for attach/detach and the tearing effect handler to make
the calls into the platform code more visible.

Furthermore, the series should now apply to linux-next and correctly build the
exynos_defconfig.

Thanks,

Michael

Changelog:

v2:
- rebase on linux-next
- verify with exynos_defconfig
- fix crashes reported by Marek Szyprowski Exynos3250-based Rinato
- reorder patches
- add host_ops for platform specific code
- roughly test component framework integration with dummy

Michael Tretter (16):
  drm/encoder: remove obsolete documentation of bridge
  drm/exynos: remove in_bridge_node from exynos_dsi
  drm/exynos: use exynos_dsi as drvdata
  drm/exynos: extract helper functions for probe
  drm/exynos: move dsi host registration to probe
  drm/exynos: shift register values to fields on write
  drm/exynos: use identifier instead of register offsets
  drm/exynos: add host_ops callback for platform drivers
  drm/exynos: add callback for tearing effect handler
  drm/exynos: implement a drm bridge
  drm/exynos: convert encoder functions to bridge function
  drm/exynos: configure mode on drm bridge
  drm/exynos: get encoder from bridge whenever possible
  drm/exynos: add API functions for platform drivers
  drm/exynos: split out platform specific code
  drm/exynos: move bridge driver to bridges

 drivers/gpu/drm/bridge/Kconfig  |9 +
 drivers/gpu/drm/bridge/Makefile |1 +
 drivers/gpu/drm/bridge/samsung-dsim.c   | 1790 +
 drivers/gpu/drm/exynos/Kconfig  |5 +-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 1927 ++-
 include/drm/bridge/samsung-dsim.h   |   64 +
 include/drm/drm_encoder.h   |1 -
 7 files changed, 2027 insertions(+), 1770 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/samsung-dsim.c
 create mode 100644 include/drm/bridge/samsung-dsim.h

-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 01/16] drm/encoder: remove obsolete documentation of bridge

2020-09-11 Thread Michael Tretter
In commit 05193dc38197 ("drm/bridge: Make the bridge chain a
double-linked list") the bridge has been removed and replaced by a
private field. Remove the leftover documentation of the removed field.

Signed-off-by: Michael Tretter 
Reviewed-by: Laurent Pinchart 
---
v2: none
---
 include/drm/drm_encoder.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index a60f5f1555ac..5dfa5f7a80a7 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -89,7 +89,6 @@ struct drm_encoder_funcs {
  * @head: list management
  * @base: base KMS object
  * @name: human readable name, can be overwritten by the driver
- * @bridge: bridge associated to the encoder
  * @funcs: control functions
  * @helper_private: mid-layer private data
  *
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 13/16] drm/exynos: get encoder from bridge whenever possible

2020-09-11 Thread Michael Tretter
The bridge will not necessarily use the encoder of struct exynos_dsi,
but might use another encoder from another drm driver. Therefore, the
driver has to use the encoder from the bridge instead of the one from
exynos_dsi.

In the future, the struct exynos_dsi will not have an encoder at all.

Signed-off-by: Michael Tretter 
---
v2:
- add removal of encoder_to_dsi
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 988447812333..b9216785b2d7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -303,11 +303,6 @@ struct exynos_dsi {
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
-static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
-{
-   return container_of(e, struct exynos_dsi, encoder);
-}
-
 enum reg_idx {
DSIM_STATUS_REG,/* Status register */
DSIM_SWRST_REG, /* Software reset register */
@@ -1570,11 +1565,10 @@ static const struct drm_connector_helper_funcs 
exynos_dsi_connector_helper_funcs
.get_modes = exynos_dsi_get_modes,
 };
 
-static int exynos_dsi_create_connector(struct drm_encoder *encoder)
+static int exynos_dsi_create_connector(struct exynos_dsi *dsi)
 {
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
struct drm_connector *connector = &dsi->connector;
-   struct drm_device *drm = encoder->dev;
+   struct drm_device *drm = dsi->bridge.dev;
int ret;
 
connector->polled = DRM_CONNECTOR_POLL_HPD;
@@ -1589,7 +1583,7 @@ static int exynos_dsi_create_connector(struct drm_encoder 
*encoder)
 
connector->status = connector_status_disconnected;
drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
-   drm_connector_attach_encoder(connector, encoder);
+   drm_connector_attach_encoder(connector, dsi->bridge.encoder);
if (!drm->registered)
return 0;
 
@@ -1615,7 +1609,7 @@ static int exynos_dsi_bridge_attach(struct drm_bridge 
*bridge,
return ret;
list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
} else {
-   ret = exynos_dsi_create_connector(encoder);
+   ret = exynos_dsi_create_connector(dsi);
if (ret)
return ret;
 
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 14/16] drm/exynos: add API functions for platform drivers

2020-09-11 Thread Michael Tretter
Add new functions for the probe/remove API, the bind/unbind API and
resume/suspend calls. Move everything exynos drm specific into separate
functions, which can easily be moved to other files.

Also split struct exynos_dsi into a generic and a platform specific
struct.

Signed-off-by: Michael Tretter 
---
v2:
- new patch
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 114 +---
 1 file changed, 82 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index b9216785b2d7..ad70f5ce81ad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -265,7 +265,6 @@ struct exynos_dsi_driver_data {
 };
 
 struct exynos_dsi {
-   struct drm_encoder encoder;
struct drm_bridge bridge;
struct mipi_dsi_host dsi_host;
struct drm_connector connector;
@@ -419,6 +418,11 @@ enum reg_value_idx {
PHYTIMING_HS_TRAIL
 };
 
+struct exynos_dsi_pltfm {
+   struct exynos_dsi *dsi;
+   struct drm_encoder encoder;
+};
+
 static const unsigned int reg_values[] = {
[RESET_TYPE] = DSIM_SWRST,
[PLL_TIMER] = 500,
@@ -476,7 +480,7 @@ static const unsigned int exynos5433_reg_values[] = {
 static int __exynos_dsi_host_attach(struct device *dev,
struct mipi_dsi_device *device)
 {
-   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_device *drm = dsi->encoder.dev;
struct exynos_drm_crtc *crtc;
 
@@ -494,7 +498,7 @@ static int __exynos_dsi_host_attach(struct device *dev,
 static int __exynos_dsi_host_detach(struct device *dev,
 struct mipi_dsi_device *device)
 {
-   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_device *drm = dsi->encoder.dev;
 
if (drm->mode_config.poll_enabled)
@@ -505,7 +509,7 @@ static int __exynos_dsi_host_detach(struct device *dev,
 
 static void __exynos_dsi_te_handler(struct device *dev)
 {
-   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
 
exynos_drm_crtc_te_handler(dsi->encoder.crtc);
 }
@@ -1804,10 +1808,12 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
return 0;
 }
 
-static int exynos_dsi_bind(struct device *dev, struct device *master,
-   void *data)
+static int exynos_dsi_bind(struct exynos_dsi *dsi, struct drm_encoder 
*encoder);
+static void exynos_dsi_unbind(struct exynos_dsi *dsi);
+
+static int exynos_dsi_pltfm_bind(struct device *dev, struct device *master, 
void *data)
 {
-   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dsi->encoder;
struct drm_device *drm_dev = data;
struct device_node *in_bridge_node;
@@ -1828,7 +1834,7 @@ static int exynos_dsi_bind(struct device *dev, struct 
device *master,
of_node_put(in_bridge_node);
}
 
-   ret = drm_bridge_attach(encoder, &dsi->bridge, in_bridge, 0);
+   ret = exynos_dsi_bind(dsi->dsi, encoder);
if (ret)
goto err;
 
@@ -1839,20 +1845,20 @@ static int exynos_dsi_bind(struct device *dev, struct 
device *master,
return ret;
 }
 
-static void exynos_dsi_unbind(struct device *dev, struct device *master,
-   void *data)
+static void exynos_dsi_pltfm_unbind(struct device *dev, struct device *master,
+   void *data)
 {
-   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+   struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dsi->encoder;
 
-   exynos_dsi_disable(dsi);
+   exynos_dsi_unbind(dsi->dsi);
 
drm_encoder_cleanup(encoder);
 }
 
-static const struct component_ops exynos_dsi_component_ops = {
-   .bind   = exynos_dsi_bind,
-   .unbind = exynos_dsi_unbind,
+static const struct component_ops exynos_dsi_pltfm_component_ops = {
+   .bind   = exynos_dsi_pltfm_bind,
+   .unbind = exynos_dsi_pltfm_unbind,
 };
 
 static struct exynos_dsi *__exynos_dsi_probe(struct platform_device *pdev)
@@ -1963,20 +1969,52 @@ static void __exynos_dsi_remove(struct exynos_dsi *dsi)
mipi_dsi_host_unregister(&dsi->dsi_host);
 }
 
-static int exynos_dsi_probe(struct platform_device *pdev)
+/*
+ * Probe/remove API, used from platforms based on the DRM bridge API.
+ */
+static struct exynos_dsi *exynos_dsi_probe(struct platform_device *pdev)
 {
-   struct exynos_dsi *dsi;
+   return __exynos_dsi_probe(pdev);
+}
+
+static void exynos_dsi_remove(struct exynos_dsi *dsi)
+{
+   return __exynos_dsi_remove(dsi);
+}
+
+/*
+ * Bind/unbind API, used from platforms based on the component framework.
+ */
+sta

[PATCH v2 16/16] drm/exynos: move bridge driver to bridges

2020-09-11 Thread Michael Tretter
As the driver is not platform dependent anymore, move it to the drm
bridge driver directory.

Signed-off-by: Michael Tretter 
---
v2:
- select DRM_SAMSUNG_DSIM from DRM_EXYNOS_DSI
- add removal of depends on !FB_S3C
---
 drivers/gpu/drm/bridge/Kconfig|9 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/samsung-dsim.c | 1790 
 drivers/gpu/drm/exynos/Kconfig|5 +-
 drivers/gpu/drm/exynos/Makefile   |2 +-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c   | 1896 ++---
 drivers/gpu/drm/exynos/exynos_drm_dsi_pltfm.c |  333 ---
 .../drm/bridge/samsung-dsim.h |   20 +-
 8 files changed, 2037 insertions(+), 2019 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/samsung-dsim.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_dsi_pltfm.c
 rename drivers/gpu/drm/exynos/exynos_drm_dsi.h => 
include/drm/bridge/samsung-dsim.h (69%)

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 3e11af4e9f63..55ab5030c6cf 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -125,6 +125,15 @@ config DRM_PARADE_PS8640
  The PS8640 is a high-performance and low-power
  MIPI DSI to eDP converter
 
+config DRM_SAMSUNG_DSIM
+   tristate "Samsung MIPI DSI bridge"
+   depends on OF
+   select DRM_KMS_HELPER
+   select DRM_MIPI_DSI
+   select DRM_PANEL
+   help
+ Samsung MIPI DSI bridge driver.
+
 config DRM_SIL_SII8620
tristate "Silicon Image SII8620 HDMI/MHL bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index c589a6a7cbe1..5ac7a5c413dc 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
megachips-stdp-ge-b850v
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
+obj-$(CONFIG_DRM_SAMSUNG_DSIM) += samsung-dsim.o
 obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
 obj-$(CONFIG_DRM_SII902X) += sii902x.o
 obj-$(CONFIG_DRM_SII9234) += sii9234.o
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
new file mode 100644
index ..6d2d8dc027de
--- /dev/null
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -0,0 +1,1790 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Samsung SoC MIPI DSI Master driver.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *
+ * Contacts: Tomasz Figa 
+*/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* returns true iff both arguments logically differs */
+#define NEQV(a, b) (!(a) ^ !(b))
+
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK(1 << 8)
+#define DSIM_TX_READY_HS_CLK   (1 << 10)
+#define DSIM_PLL_STABLE(1 << 31)
+
+/* DSIM_TIMEOUT */
+#define DSIM_LPDR_TIMEOUT(x)   ((x) << 0)
+#define DSIM_BTA_TIMEOUT(x)((x) << 16)
+
+/* DSIM_CLKCTRL */
+#define DSIM_ESC_PRESCALER(x)  (((x) & 0x) << 0)
+#define DSIM_ESC_PRESCALER_MASK(0x << 0)
+#define DSIM_LANE_ESC_CLK_EN_CLK   (1 << 19)
+#define DSIM_LANE_ESC_CLK_EN_DATA(x)   (((x) & 0xf) << 20)
+#define DSIM_LANE_ESC_CLK_EN_DATA_MASK (0xf << 20)
+#define DSIM_BYTE_CLKEN(1 << 24)
+#define DSIM_BYTE_CLK_SRC(x)   (((x) & 0x3) << 25)
+#define DSIM_BYTE_CLK_SRC_MASK (0x3 << 25)
+#define DSIM_PLL_BYPASS(1 << 27)
+#define DSIM_ESC_CLKEN (1 << 28)
+#define DSIM_TX_REQUEST_HSCLK  (1 << 31)
+
+/* DSIM_CONFIG */
+#define DSIM_LANE_EN_CLK   (1 << 0)
+#define DSIM_LANE_EN(x)(((x) & 0xf) << 1)
+#define DSIM_NUM_OF_DATA_LANE(x)   (((x) & 0x3) << 5)
+#define DSIM_SUB_PIX_FORMAT(x) (((x) & 0x7) << 8)
+#define DSIM_MAIN_PIX_FORMAT_MASK  (0x7 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB888(0x7 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB666(0x6 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB666_P  (0x5 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB565(0x4 << 12)
+#define DSIM_SUB_VC(((x) & 0x3) << 16)
+#define DSIM_MAIN_VC   (((x) & 0x3) << 18)
+#define DSIM_HSA_MODE  (1 << 20)
+#define DSIM_HBP_MODE  (1 << 21)
+#define DSIM_HFP_MODE  (1 << 22)
+#define DSIM_HSE_MODE  (1 << 23)
+#define DSIM_AUTO_MODE (1 << 24)
+#define DSIM_VIDEO_MODE(1 << 25)
+#define DSIM_BURST_MODE(1

[PATCH v2 09/16] drm/exynos: add callback for tearing effect handler

2020-09-11 Thread Michael Tretter
The tearing effect interrupts are not handled by the MIPI DSI bridge
driver, but the display controller driver.

Allow platforms to register a callback for the tearing effect interrupt.

Signed-off-by: Michael Tretter 
---
v2:
- add handler as callback in host_ops
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 684a2fbef08a..2d75f9877dc0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -243,6 +243,7 @@ struct exynos_dsi;
 struct exynos_dsi_host_ops {
int (*attach)(struct device *dev, struct mipi_dsi_device *device);
int (*detach)(struct device *dev, struct mipi_dsi_device *device);
+   void (*te_handler)(struct device *dev);
 };
 
 enum exynos_reg_offset {
@@ -504,9 +505,17 @@ static int __exynos_dsi_host_detach(struct device *dev,
return 0;
 }
 
+static void __exynos_dsi_te_handler(struct device *dev)
+{
+   struct exynos_dsi *dsi = dev_get_drvdata(dev);
+
+   exynos_drm_crtc_te_handler(dsi->encoder.crtc);
+}
+
 static const struct exynos_dsi_host_ops exynos_dsi_host_ops = {
.attach = __exynos_dsi_host_attach,
.detach = __exynos_dsi_host_detach,
+   .te_handler = __exynos_dsi_te_handler,
 };
 
 static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
@@ -1354,11 +1363,12 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 
 static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
 {
-   struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
-   struct drm_encoder *encoder = &dsi->encoder;
+   struct exynos_dsi *dsi = dev_id;
+   const struct exynos_dsi_host_ops *ops = dsi->driver_data->host_ops;
 
-   if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
-   exynos_drm_crtc_te_handler(encoder->crtc);
+   if (ops && ops->te_handler &&
+   (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE))
+   ops->te_handler(dsi->dsi_host.dev);
 
return IRQ_HANDLED;
 }
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [trivial PATCH] treewide: Convert switch/case fallthrough; to break;

2020-09-11 Thread Nicolas.Ferre
Joe,

Please drop this chunk: it's a successive controller version number 
which are all backward compatible with "fallthrough" on each case so 
removing from this last one makes it inconsistent.

In sort: NACK for atmel-mci.

Best regards,
   Nicolas


On 09/09/2020 at 22:06, Joe Perches wrote:
> diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
> index 444bd3a0a922..8324312e4f42 100644
> --- a/drivers/mmc/host/atmel-mci.c
> +++ b/drivers/mmc/host/atmel-mci.c
> @@ -2435,7 +2435,7 @@ static void atmci_get_cap(struct atmel_mci *host)
>  case 0x100:
>  host->caps.has_bad_data_ordering = 0;
>  host->caps.need_reset_after_xfer = 0;
> -   fallthrough;
> +   break;
>  case 0x0:
>  break;
>  default:


-- 
Nicolas Ferre
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/imx/dcss: fix 64-bit divisions

2020-09-11 Thread Laurentiu Palcu
Use div_s64() for the 64-bit divisions. This would allow the driver to compile
on 32-bit architectures, if needed.

Signed-off-by: Laurentiu Palcu 
---
 drivers/gpu/drm/imx/dcss/dcss-scaler.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/imx/dcss/dcss-scaler.c 
b/drivers/gpu/drm/imx/dcss/dcss-scaler.c
index cd21905de580..7c1e0e461244 100644
--- a/drivers/gpu/drm/imx/dcss/dcss-scaler.c
+++ b/drivers/gpu/drm/imx/dcss/dcss-scaler.c
@@ -134,7 +134,7 @@ static int div_q(int A, int B)
else
temp -= B / 2;
 
-   result = (int)(temp / B);
+   result = (int)(div_s64(temp, B));
return result;
 }
 
@@ -237,7 +237,7 @@ static void dcss_scaler_gaussian_filter(int fc_q, bool 
use_5_taps,
ll_temp = coef[phase][i];
ll_temp <<= PSC_COEFF_PRECISION;
ll_temp += sum >> 1;
-   ll_temp /= sum;
+   ll_temp = div_s64(ll_temp, sum);
coef[phase][i] = (int)ll_temp;
}
}
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 18/21] drm/imx: parallel-display: use drm managed resources

2020-09-11 Thread Philipp Zabel
Move device tree parsing into probe(). Use drmm_kzalloc() to align
encoder memory lifetime with the drm device, and use
drmm_add_action_or_reset() to make sure drm_encoder_cleanup() is
called before the memory is freed.

Signed-off-by: Philipp Zabel 
Acked-by: Daniel Vetter 
---
Changes since v1:
 - Split some changes into previous patches, rebased.
---
 drivers/gpu/drm/imx/parallel-display.c | 76 --
 1 file changed, 47 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c 
b/drivers/gpu/drm/imx/parallel-display.c
index 42b44dbf45f5..2b2160387cbf 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -22,10 +23,14 @@
 
 #include "imx-drm.h"
 
-struct imx_parallel_display {
+struct imx_parallel_display_encoder {
struct drm_connector connector;
struct drm_encoder encoder;
struct drm_bridge bridge;
+   struct imx_parallel_display *pd;
+};
+
+struct imx_parallel_display {
struct device *dev;
void *edid;
u32 bus_format;
@@ -37,12 +42,12 @@ struct imx_parallel_display {
 
 static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector 
*c)
 {
-   return container_of(c, struct imx_parallel_display, connector);
+   return container_of(c, struct imx_parallel_display_encoder, 
connector)->pd;
 }
 
 static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge 
*b)
 {
-   return container_of(b, struct imx_parallel_display, bridge);
+   return container_of(b, struct imx_parallel_display_encoder, bridge)->pd;
 }
 
 static int imx_pd_connector_get_modes(struct drm_connector *connector)
@@ -253,17 +258,39 @@ static const struct drm_bridge_funcs imx_pd_bridge_funcs 
= {
.atomic_get_output_bus_fmts = imx_pd_bridge_atomic_get_output_bus_fmts,
 };
 
-static int imx_pd_register(struct drm_device *drm,
-   struct imx_parallel_display *imxpd)
+static void imx_pd_encoder_cleanup(struct drm_device *drm, void *ptr)
+{
+   struct drm_encoder *encoder = ptr;
+
+   drm_encoder_cleanup(encoder);
+}
+
+static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 {
-   struct drm_connector *connector = &imxpd->connector;
-   struct drm_encoder *encoder = &imxpd->encoder;
-   struct drm_bridge *bridge = &imxpd->bridge;
+   struct drm_device *drm = data;
+   struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
+   struct imx_parallel_display_encoder *imxpd_encoder;
+   struct drm_connector *connector;
+   struct drm_encoder *encoder;
+   struct drm_bridge *bridge;
int ret;
 
-   memset(connector, 0, sizeof(*connector));
-   memset(encoder, 0, sizeof(*encoder));
-   memset(bridge, 0, sizeof(*bridge));
+   imxpd_encoder = drmm_kzalloc(drm, sizeof(*imxpd_encoder), GFP_KERNEL);
+   if (!imxpd_encoder)
+   return -ENOMEM;
+
+   imxpd_encoder->pd = imxpd;
+   connector = &imxpd_encoder->connector;
+   encoder = &imxpd_encoder->encoder;
+   bridge = &imxpd_encoder->bridge;
+
+   ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
+   if (ret)
+   return ret;
+
+   ret = drmm_add_action_or_reset(drm, imx_pd_encoder_cleanup, encoder);
+   if (ret)
+   return ret;
 
ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
if (ret)
@@ -276,18 +303,9 @@ static int imx_pd_register(struct drm_device *drm,
 */
connector->dpms = DRM_MODE_DPMS_OFF;
 
-   drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
-
bridge->funcs = &imx_pd_bridge_funcs;
drm_bridge_attach(encoder, bridge, NULL, 0);
 
-   if (!imxpd->next_bridge) {
-   drm_connector_helper_add(connector,
-&imx_pd_connector_helper_funcs);
-   drm_connector_init(drm, connector, &imx_pd_connector_funcs,
-  DRM_MODE_CONNECTOR_DPI);
-   }
-
if (imxpd->next_bridge) {
ret = drm_bridge_attach(encoder, imxpd->next_bridge, bridge, 0);
if (ret < 0) {
@@ -296,20 +314,17 @@ static int imx_pd_register(struct drm_device *drm,
return ret;
}
} else {
+   drm_connector_helper_add(connector,
+&imx_pd_connector_helper_funcs);
+   drm_connector_init(drm, connector, &imx_pd_connector_funcs,
+  DRM_MODE_CONNECTOR_DPI);
+
drm_connector_attach_encoder(connector, encoder);
}
 
return 0;
 }
 
-static int imx_pd_bind(struct device *dev, struct device *master, void *data)
-{
-   struct drm_device *drm = data;
-   struct imx_parallel_display *imxpd = dev_get_drvd

[PATCH v2 08/21] drm/imx: imx-tve: use local encoder and connector variables

2020-09-11 Thread Philipp Zabel
Introduce local variables for encoder and connector.
This simplifies the following commits.

Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/imx-tve.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index ef3c25d87d87..aa2f140527e9 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -430,27 +430,28 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem 
*base)
 
 static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
 {
+   struct drm_encoder *encoder = &tve->encoder;
+   struct drm_connector *connector = &tve->connector;
int encoder_type;
int ret;
 
encoder_type = tve->mode == TVE_MODE_VGA ?
DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
 
-   ret = imx_drm_encoder_parse_of(drm, &tve->encoder, tve->dev->of_node);
+   ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node);
if (ret)
return ret;
 
-   drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs);
-   drm_simple_encoder_init(drm, &tve->encoder, encoder_type);
+   drm_encoder_helper_add(encoder, &imx_tve_encoder_helper_funcs);
+   drm_simple_encoder_init(drm, encoder, encoder_type);
 
-   drm_connector_helper_add(&tve->connector,
-   &imx_tve_connector_helper_funcs);
-   drm_connector_init_with_ddc(drm, &tve->connector,
+   drm_connector_helper_add(connector, &imx_tve_connector_helper_funcs);
+   drm_connector_init_with_ddc(drm, connector,
&imx_tve_connector_funcs,
DRM_MODE_CONNECTOR_VGA,
tve->ddc);
 
-   drm_connector_attach_encoder(&tve->connector, &tve->encoder);
+   drm_connector_attach_encoder(connector, encoder);
 
return 0;
 }
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 16/21] drm/imx: parallel-display: use local encoder and connector variables

2020-09-11 Thread Philipp Zabel
Use local variables for encoder, bridge, and connector.
This simplifies the following commits.

Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/parallel-display.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c 
b/drivers/gpu/drm/imx/parallel-display.c
index 2eb8df4697df..16e576f8ee83 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -256,7 +256,9 @@ static const struct drm_bridge_funcs imx_pd_bridge_funcs = {
 static int imx_pd_register(struct drm_device *drm,
struct imx_parallel_display *imxpd)
 {
+   struct drm_connector *connector = &imxpd->connector;
struct drm_encoder *encoder = &imxpd->encoder;
+   struct drm_bridge *bridge = &imxpd->bridge;
int ret;
 
ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
@@ -268,31 +270,29 @@ static int imx_pd_register(struct drm_device *drm,
 * immediately since the current state is ON
 * at this point.
 */
-   imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
+   connector->dpms = DRM_MODE_DPMS_OFF;
 
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
 
-   imxpd->bridge.funcs = &imx_pd_bridge_funcs;
-   drm_bridge_attach(encoder, &imxpd->bridge, NULL, 0);
+   bridge->funcs = &imx_pd_bridge_funcs;
+   drm_bridge_attach(encoder, bridge, NULL, 0);
 
if (!imxpd->next_bridge) {
-   drm_connector_helper_add(&imxpd->connector,
-   &imx_pd_connector_helper_funcs);
-   drm_connector_init(drm, &imxpd->connector,
-  &imx_pd_connector_funcs,
+   drm_connector_helper_add(connector,
+&imx_pd_connector_helper_funcs);
+   drm_connector_init(drm, connector, &imx_pd_connector_funcs,
   DRM_MODE_CONNECTOR_DPI);
}
 
if (imxpd->next_bridge) {
-   ret = drm_bridge_attach(encoder, imxpd->next_bridge,
-   &imxpd->bridge, 0);
+   ret = drm_bridge_attach(encoder, imxpd->next_bridge, bridge, 0);
if (ret < 0) {
dev_err(imxpd->dev, "failed to attach bridge: %d\n",
ret);
return ret;
}
} else {
-   drm_connector_attach_encoder(&imxpd->connector, encoder);
+   drm_connector_attach_encoder(connector, encoder);
}
 
return 0;
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 09/21] drm/imx: imx-tve: move initialization into probe

2020-09-11 Thread Philipp Zabel
The parts of the initialization that do not require the drm device can
be done once during probe instead of possibly multiple times during
bind. The bind function only creates the encoder.

Signed-off-by: Philipp Zabel 
---
Changes since v1:
 - Split from patch "drm/imx: imx-tve: use drm managed resources".
---
 drivers/gpu/drm/imx/imx-tve.c | 42 ---
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index aa2f140527e9..2011e9085095 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -438,6 +438,9 @@ static int imx_tve_register(struct drm_device *drm, struct 
imx_tve *tve)
encoder_type = tve->mode == TVE_MODE_VGA ?
DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
 
+   memset(connector, 0, sizeof(*connector));
+   memset(encoder, 0, sizeof(*encoder));
+
ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node);
if (ret)
return ret;
@@ -503,8 +506,19 @@ static const int of_get_tve_mode(struct device_node *np)
 
 static int imx_tve_bind(struct device *dev, struct device *master, void *data)
 {
-   struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = data;
+   struct imx_tve *tve = dev_get_drvdata(dev);
+
+   return imx_tve_register(drm, tve);
+}
+
+static const struct component_ops imx_tve_ops = {
+   .bind   = imx_tve_bind,
+};
+
+static int imx_tve_probe(struct platform_device *pdev)
+{
+   struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct device_node *ddc_node;
struct imx_tve *tve;
@@ -514,8 +528,9 @@ static int imx_tve_bind(struct device *dev, struct device 
*master, void *data)
int irq;
int ret;
 
-   tve = dev_get_drvdata(dev);
-   memset(tve, 0, sizeof(*tve));
+   tve = devm_kzalloc(dev, sizeof(*tve), GFP_KERNEL);
+   if (!tve)
+   return -ENOMEM;
 
tve->dev = dev;
 
@@ -622,28 +637,9 @@ static int imx_tve_bind(struct device *dev, struct device 
*master, void *data)
if (ret)
return ret;
 
-   ret = imx_tve_register(drm, tve);
-   if (ret)
-   return ret;
-
-   return 0;
-}
-
-static const struct component_ops imx_tve_ops = {
-   .bind   = imx_tve_bind,
-};
-
-static int imx_tve_probe(struct platform_device *pdev)
-{
-   struct imx_tve *tve;
-
-   tve = devm_kzalloc(&pdev->dev, sizeof(*tve), GFP_KERNEL);
-   if (!tve)
-   return -ENOMEM;
-
platform_set_drvdata(pdev, tve);
 
-   return component_add(&pdev->dev, &imx_tve_ops);
+   return component_add(dev, &imx_tve_ops);
 }
 
 static int imx_tve_remove(struct platform_device *pdev)
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 01/21] drm/imx: dw_hdmi-imx: remove empty encoder_disable callback

2020-09-11 Thread Philipp Zabel
This has not been required since commit 75229eca569f ("drm: Make
drm_encoder_helper_funcs optional").

Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/dw_hdmi-imx.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 6debe87cc160..d07b39b8afd2 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -111,10 +111,6 @@ static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi)
return 0;
 }
 
-static void dw_hdmi_imx_encoder_disable(struct drm_encoder *encoder)
-{
-}
-
 static void dw_hdmi_imx_encoder_enable(struct drm_encoder *encoder)
 {
struct imx_hdmi *hdmi = enc_to_imx_hdmi(encoder);
@@ -140,7 +136,6 @@ static int dw_hdmi_imx_atomic_check(struct drm_encoder 
*encoder,
 
 static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs 
= {
.enable = dw_hdmi_imx_encoder_enable,
-   .disable= dw_hdmi_imx_encoder_disable,
.atomic_check = dw_hdmi_imx_atomic_check,
 };
 
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 03/21] drm/imx: dw_hdmi-imx: use drm managed resources

2020-09-11 Thread Philipp Zabel
Use drmm_kzalloc() to align encoder memory lifetime with the drm device,
and use drmm_add_action_or_reset() to make sure drm_encoder_cleanup() is
called before the memory is freed.

Signed-off-by: Philipp Zabel 
Acked-by: Daniel Vetter 
---
Changes since v1:
 - Split from patch "drm/imx: dw_hdmi-imx: use drm managed resources, switch to
   dw_hdmi_probe"
---
 drivers/gpu/drm/imx/dw_hdmi-imx.c | 34 ---
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index bbd0a0cd7c3d..16be8bd92653 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -18,14 +18,21 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #include "imx-drm.h"
 
+struct imx_hdmi;
+
+struct imx_hdmi_encoder {
+   struct drm_encoder encoder;
+   struct imx_hdmi *hdmi;
+};
+
 struct imx_hdmi {
struct device *dev;
-   struct drm_encoder encoder;
struct drm_bridge *bridge;
struct dw_hdmi *hdmi;
struct regmap *regmap;
@@ -33,7 +40,7 @@ struct imx_hdmi {
 
 static inline struct imx_hdmi *enc_to_imx_hdmi(struct drm_encoder *e)
 {
-   return container_of(e, struct imx_hdmi, encoder);
+   return container_of(e, struct imx_hdmi_encoder, encoder)->hdmi;
 }
 
 static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = {
@@ -181,18 +188,27 @@ static const struct of_device_id dw_hdmi_imx_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids);
 
+static void dw_hdmi_imx_encoder_cleanup(struct drm_device *drm, void *data)
+{
+   struct drm_encoder *encoder = data;
+
+   drm_encoder_cleanup(encoder);
+}
+
 static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
void *data)
 {
struct drm_device *drm = data;
+   struct imx_hdmi_encoder *hdmi_encoder;
struct drm_encoder *encoder;
-   struct imx_hdmi *hdmi;
int ret;
 
-   hdmi = dev_get_drvdata(dev);
-   memset(&hdmi->encoder, 0, sizeof(hdmi->encoder));
+   hdmi_encoder = drmm_kzalloc(drm, sizeof(*hdmi_encoder), GFP_KERNEL);
+   if (!hdmi_encoder)
+   return -ENOMEM;
 
-   encoder = &hdmi->encoder;
+   hdmi_encoder->hdmi = dev_get_drvdata(dev);
+   encoder = &hdmi_encoder->encoder;
 
ret = imx_drm_encoder_parse_of(drm, encoder, dev->of_node);
if (ret)
@@ -201,7 +217,11 @@ static int dw_hdmi_imx_bind(struct device *dev, struct 
device *master,
drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
-   return drm_bridge_attach(encoder, hdmi->bridge, NULL, 0);
+   ret = drmm_add_action_or_reset(drm, dw_hdmi_imx_encoder_cleanup, 
encoder);
+   if (ret)
+   return ret;
+
+   return drm_bridge_attach(encoder, hdmi_encoder->hdmi->bridge, NULL, 0);
 }
 
 static const struct component_ops dw_hdmi_imx_ops = {
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 17/21] drm/imx: parallel-display: move initialization into probe

2020-09-11 Thread Philipp Zabel
The parts of the initialization do not require the drm device can be
done once during probe instead of possibly multiple times during bind.
The bind function only creates the encoder.

Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/parallel-display.c | 42 --
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c 
b/drivers/gpu/drm/imx/parallel-display.c
index 16e576f8ee83..42b44dbf45f5 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -261,6 +261,10 @@ static int imx_pd_register(struct drm_device *drm,
struct drm_bridge *bridge = &imxpd->bridge;
int ret;
 
+   memset(connector, 0, sizeof(*connector));
+   memset(encoder, 0, sizeof(*encoder));
+   memset(bridge, 0, sizeof(*bridge));
+
ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
if (ret)
return ret;
@@ -301,6 +305,18 @@ static int imx_pd_register(struct drm_device *drm,
 static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 {
struct drm_device *drm = data;
+   struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
+
+   return imx_pd_register(drm, imxpd);
+}
+
+static const struct component_ops imx_pd_ops = {
+   .bind   = imx_pd_bind,
+};
+
+static int imx_pd_probe(struct platform_device *pdev)
+{
+   struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
const u8 *edidp;
struct imx_parallel_display *imxpd;
@@ -309,8 +325,9 @@ static int imx_pd_bind(struct device *dev, struct device 
*master, void *data)
u32 bus_format = 0;
const char *fmt;
 
-   imxpd = dev_get_drvdata(dev);
-   memset(imxpd, 0, sizeof(*imxpd));
+   imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
+   if (!imxpd)
+   return -ENOMEM;
 
/* port@1 is the output port */
ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel,
@@ -337,28 +354,9 @@ static int imx_pd_bind(struct device *dev, struct device 
*master, void *data)
 
imxpd->dev = dev;
 
-   ret = imx_pd_register(drm, imxpd);
-   if (ret)
-   return ret;
-
-   return 0;
-}
-
-static const struct component_ops imx_pd_ops = {
-   .bind   = imx_pd_bind,
-};
-
-static int imx_pd_probe(struct platform_device *pdev)
-{
-   struct imx_parallel_display *imxpd;
-
-   imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL);
-   if (!imxpd)
-   return -ENOMEM;
-
platform_set_drvdata(pdev, imxpd);
 
-   return component_add(&pdev->dev, &imx_pd_ops);
+   return component_add(dev, &imx_pd_ops);
 }
 
 static int imx_pd_remove(struct platform_device *pdev)
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 15/21] drm/imx: parallel-display: reduce scope of edid_len

2020-09-11 Thread Philipp Zabel
The edid_len variable is never used again. Use a local variable instead
of storing it in the device structure.

Signed-off-by: Philipp Zabel 
---
Changes since v1:
 - Split patch from "drm/imx: parallel-display: use drm managed resources".
---
 drivers/gpu/drm/imx/parallel-display.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c 
b/drivers/gpu/drm/imx/parallel-display.c
index 726f6cc6fa25..2eb8df4697df 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -28,7 +28,6 @@ struct imx_parallel_display {
struct drm_bridge bridge;
struct device *dev;
void *edid;
-   int edid_len;
u32 bus_format;
u32 bus_flags;
struct drm_display_mode mode;
@@ -305,6 +304,7 @@ static int imx_pd_bind(struct device *dev, struct device 
*master, void *data)
struct device_node *np = dev->of_node;
const u8 *edidp;
struct imx_parallel_display *imxpd;
+   int edid_len;
int ret;
u32 bus_format = 0;
const char *fmt;
@@ -318,10 +318,9 @@ static int imx_pd_bind(struct device *dev, struct device 
*master, void *data)
if (ret && ret != -ENODEV)
return ret;
 
-   edidp = of_get_property(np, "edid", &imxpd->edid_len);
+   edidp = of_get_property(np, "edid", &edid_len);
if (edidp)
-   imxpd->edid = devm_kmemdup(dev, edidp, imxpd->edid_len,
-  GFP_KERNEL);
+   imxpd->edid = devm_kmemdup(dev, edidp, edid_len, GFP_KERNEL);
 
ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
if (!ret) {
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 11/21] drm/imx: imx-tve: fold imx_tve_register into imx_tve_bind

2020-09-11 Thread Philipp Zabel
imx_tve_bind() doesn't do anything more than calling imx_tve_register().
Merge the two functions into one.

Signed-off-by: Philipp Zabel 
---
Changes since v1:
 - Split from patch "drm/imx: imx-tve: use drm managed resources".
---
 drivers/gpu/drm/imx/imx-tve.c | 58 ---
 1 file changed, 26 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 044730b95120..aa1c2ab34170 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -428,37 +428,6 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem 
*base)
return 0;
 }
 
-static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
-{
-   struct drm_encoder *encoder = &tve->encoder;
-   struct drm_connector *connector = &tve->connector;
-   int encoder_type;
-   int ret;
-
-   encoder_type = tve->mode == TVE_MODE_VGA ?
-   DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
-
-   memset(connector, 0, sizeof(*connector));
-   memset(encoder, 0, sizeof(*encoder));
-
-   ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node);
-   if (ret)
-   return ret;
-
-   drm_encoder_helper_add(encoder, &imx_tve_encoder_helper_funcs);
-   drm_simple_encoder_init(drm, encoder, encoder_type);
-
-   drm_connector_helper_add(connector, &imx_tve_connector_helper_funcs);
-   drm_connector_init_with_ddc(drm, connector,
-   &imx_tve_connector_funcs,
-   DRM_MODE_CONNECTOR_VGA,
-   tve->ddc);
-
-   drm_connector_attach_encoder(connector, encoder);
-
-   return 0;
-}
-
 static void imx_tve_disable_regulator(void *data)
 {
struct imx_tve *tve = data;
@@ -508,8 +477,33 @@ static int imx_tve_bind(struct device *dev, struct device 
*master, void *data)
 {
struct drm_device *drm = data;
struct imx_tve *tve = dev_get_drvdata(dev);
+   struct drm_encoder *encoder = &tve->encoder;
+   struct drm_connector *connector = &tve->connector;
+   int encoder_type;
+   int ret;
+
+   encoder_type = tve->mode == TVE_MODE_VGA ?
+  DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
+
+   memset(connector, 0, sizeof(*connector));
+   memset(encoder, 0, sizeof(*encoder));
 
-   return imx_tve_register(drm, tve);
+   ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node);
+   if (ret)
+   return ret;
+
+   drm_encoder_helper_add(encoder, &imx_tve_encoder_helper_funcs);
+   drm_simple_encoder_init(drm, encoder, encoder_type);
+
+   drm_connector_helper_add(connector, &imx_tve_connector_helper_funcs);
+   drm_connector_init_with_ddc(drm, connector,
+   &imx_tve_connector_funcs,
+   DRM_MODE_CONNECTOR_VGA,
+   tve->ddc);
+
+   drm_connector_attach_encoder(connector, encoder);
+
+   return 0;
 }
 
 static const struct component_ops imx_tve_ops = {
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 06/21] drm/imx: imx-ldb: move initialization into probe

2020-09-11 Thread Philipp Zabel
The parts of the initialization that do not require the drm device can
be done once during probe instead of possibly multiple times during
bind. The bind function only creates the encoders.

Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/imx-ldb.c | 72 ++-
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 288a81f134fe..c3639cc32ddf 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -415,6 +415,9 @@ static int imx_ldb_register(struct drm_device *drm,
struct drm_encoder *encoder = &imx_ldb_ch->encoder;
int ret;
 
+   memset(connector, 0, sizeof(*connector));
+   memset(encoder, 0, sizeof(*encoder));
+
ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child);
if (ret)
return ret;
@@ -559,17 +562,42 @@ static int imx_ldb_panel_ddc(struct device *dev,
 static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
 {
struct drm_device *drm = data;
+   struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
+   int ret;
+   int i;
+
+   for (i = 0; i < 2; i++) {
+   struct imx_ldb_channel *channel = &imx_ldb->channel[i];
+
+   if (!channel->ldb)
+   break;
+
+   ret = imx_ldb_register(drm, channel);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static const struct component_ops imx_ldb_ops = {
+   .bind   = imx_ldb_bind,
+};
+
+static int imx_ldb_probe(struct platform_device *pdev)
+{
+   struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
-   const struct of_device_id *of_id =
-   of_match_device(imx_ldb_dt_ids, dev);
+   const struct of_device_id *of_id = of_match_device(imx_ldb_dt_ids, dev);
struct device_node *child;
struct imx_ldb *imx_ldb;
int dual;
int ret;
int i;
 
-   imx_ldb = dev_get_drvdata(dev);
-   memset(imx_ldb, 0, sizeof(*imx_ldb));
+   imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL);
+   if (!imx_ldb)
+   return -ENOMEM;
 
imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
if (IS_ERR(imx_ldb->regmap)) {
@@ -669,25 +697,20 @@ static int imx_ldb_bind(struct device *dev, struct device 
*master, void *data)
}
channel->bus_format = bus_format;
channel->child = child;
-
-   ret = imx_ldb_register(drm, channel);
-   if (ret) {
-   channel->child = NULL;
-   goto free_child;
-   }
}
 
-   return 0;
+   platform_set_drvdata(pdev, imx_ldb);
+
+   return component_add(&pdev->dev, &imx_ldb_ops);
 
 free_child:
of_node_put(child);
return ret;
 }
 
-static void imx_ldb_unbind(struct device *dev, struct device *master,
-   void *data)
+static int imx_ldb_remove(struct platform_device *pdev)
 {
-   struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
+   struct imx_ldb *imx_ldb = platform_get_drvdata(pdev);
int i;
 
for (i = 0; i < 2; i++) {
@@ -696,28 +719,7 @@ static void imx_ldb_unbind(struct device *dev, struct 
device *master,
kfree(channel->edid);
i2c_put_adapter(channel->ddc);
}
-}
-
-static const struct component_ops imx_ldb_ops = {
-   .bind   = imx_ldb_bind,
-   .unbind = imx_ldb_unbind,
-};
 
-static int imx_ldb_probe(struct platform_device *pdev)
-{
-   struct imx_ldb *imx_ldb;
-
-   imx_ldb = devm_kzalloc(&pdev->dev, sizeof(*imx_ldb), GFP_KERNEL);
-   if (!imx_ldb)
-   return -ENOMEM;
-
-   platform_set_drvdata(pdev, imx_ldb);
-
-   return component_add(&pdev->dev, &imx_ldb_ops);
-}
-
-static int imx_ldb_remove(struct platform_device *pdev)
-{
component_del(&pdev->dev, &imx_ldb_ops);
return 0;
 }
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 20/21] drm/imx: move call to ipu_plane_get_resources() into ipu_plane_init()

2020-09-11 Thread Philipp Zabel
Use drm managed resources to get and put IPU resources automatically.

Signed-off-by: Philipp Zabel 
Acked-by: Daniel Vetter 
---
Changes since v1:
 - Dropped a remaining use of the removed err_put_plane1_res label, that was
   fixed in the following patch in v1.
---
 drivers/gpu/drm/imx/ipuv3-crtc.c  | 27 ++-
 drivers/gpu/drm/imx/ipuv3-plane.c | 29 -
 drivers/gpu/drm/imx/ipuv3-plane.h |  3 ---
 3 files changed, 22 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index d412fc265395..8076ab272637 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -380,29 +380,14 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
drm_crtc_init_with_planes(drm, crtc, &ipu_crtc->plane[0]->base, NULL,
  &ipu_crtc_funcs, NULL);
 
-   ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
-   if (ret) {
-   dev_err(ipu_crtc->dev, "getting plane 0 resources failed with 
%d.\n",
-   ret);
-   goto err_put_resources;
-   }
-
/* If this crtc is using the DP, add an overlay plane */
if (pdata->dp >= 0 && pdata->dma[1] > 0) {
ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1],
IPU_DP_FLOW_SYNC_FG,
drm_crtc_mask(&ipu_crtc->base),
DRM_PLANE_TYPE_OVERLAY);
-   if (IS_ERR(ipu_crtc->plane[1])) {
+   if (IS_ERR(ipu_crtc->plane[1]))
ipu_crtc->plane[1] = NULL;
-   } else {
-   ret = ipu_plane_get_resources(ipu_crtc->plane[1]);
-   if (ret) {
-   dev_err(ipu_crtc->dev, "getting plane 1 "
-   "resources failed with %d.\n", ret);
-   goto err_put_plane0_res;
-   }
-   }
}
 
ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
@@ -410,18 +395,13 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
"imx_drm", ipu_crtc);
if (ret < 0) {
dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
-   goto err_put_plane1_res;
+   goto err_put_resources;
}
/* Only enable IRQ when we actually need it to trigger work. */
disable_irq(ipu_crtc->irq);
 
return 0;
 
-err_put_plane1_res:
-   if (ipu_crtc->plane[1])
-   ipu_plane_put_resources(ipu_crtc->plane[1]);
-err_put_plane0_res:
-   ipu_plane_put_resources(ipu_crtc->plane[0]);
 err_put_resources:
ipu_put_resources(ipu_crtc);
 
@@ -448,9 +428,6 @@ static void ipu_drm_unbind(struct device *dev, struct 
device *master,
struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev);
 
ipu_put_resources(ipu_crtc);
-   if (ipu_crtc->plane[1])
-   ipu_plane_put_resources(ipu_crtc->plane[1]);
-   ipu_plane_put_resources(ipu_crtc->plane[0]);
 }
 
 static const struct component_ops ipu_crtc_ops = {
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index d3e6c37bf0fb..38b959aa3564 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -143,8 +143,10 @@ drm_plane_state_to_vbo(struct drm_plane_state *state)
   fb->format->cpp[2] * x - eba;
 }
 
-void ipu_plane_put_resources(struct ipu_plane *ipu_plane)
+static void ipu_plane_put_resources(struct drm_device *dev, void *ptr)
 {
+   struct ipu_plane *ipu_plane = ptr;
+
if (!IS_ERR_OR_NULL(ipu_plane->dp))
ipu_dp_put(ipu_plane->dp);
if (!IS_ERR_OR_NULL(ipu_plane->dmfc))
@@ -155,7 +157,8 @@ void ipu_plane_put_resources(struct ipu_plane *ipu_plane)
ipu_idmac_put(ipu_plane->alpha_ch);
 }
 
-int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
+static int ipu_plane_get_resources(struct drm_device *dev,
+  struct ipu_plane *ipu_plane)
 {
int ret;
int alpha_ch;
@@ -167,6 +170,10 @@ int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
return ret;
}
 
+   ret = drmm_add_action_or_reset(dev, ipu_plane_put_resources, ipu_plane);
+   if (ret)
+   return ret;
+
alpha_ch = ipu_channel_alpha_channel(ipu_plane->dma);
if (alpha_ch >= 0) {
ipu_plane->alpha_ch = ipu_idmac_get(ipu_plane->ipu, alpha_ch);
@@ -182,7 +189,7 @@ int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
if (IS_ERR(ipu_plane->dmfc)) {
ret = PTR_ERR(ipu_plane->dmfc);
DRM_ERROR("failed to get dmfc: ret %d\n", ret);
-   goto err_out;
+   return ret;
}
 
if (ipu_plane-

[PATCH v2 07/21] drm/imx: imx-ldb: use drm managed resources

2020-09-11 Thread Philipp Zabel
Use drmm_kzalloc() to align encoder memory lifetime with the drm device,
and use drmm_add_action_or_reset() to make sure drm_encoder_cleanup() is
called before the memory is freed.

Signed-off-by: Philipp Zabel 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/imx/imx-ldb.c | 43 +++
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index c3639cc32ddf..d4beb58f509d 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -47,12 +48,18 @@
 #define LDB_DI1_VS_POL_ACT_LOW (1 << 10)
 #define LDB_BGREF_RMODE_INT(1 << 15)
 
+struct imx_ldb_channel;
+
+struct imx_ldb_encoder {
+   struct drm_connector connector;
+   struct drm_encoder encoder;
+   struct imx_ldb_channel *channel;
+};
+
 struct imx_ldb;
 
 struct imx_ldb_channel {
struct imx_ldb *ldb;
-   struct drm_connector connector;
-   struct drm_encoder encoder;
 
/* Defines what is connected to the ldb, only one at a time */
struct drm_panel *panel;
@@ -70,12 +77,12 @@ struct imx_ldb_channel {
 
 static inline struct imx_ldb_channel *con_to_imx_ldb_ch(struct drm_connector 
*c)
 {
-   return container_of(c, struct imx_ldb_channel, connector);
+   return container_of(c, struct imx_ldb_encoder, connector)->channel;
 }
 
 static inline struct imx_ldb_channel *enc_to_imx_ldb_ch(struct drm_encoder *e)
 {
-   return container_of(e, struct imx_ldb_channel, encoder);
+   return container_of(e, struct imx_ldb_encoder, encoder)->channel;
 }
 
 struct bus_mux {
@@ -407,16 +414,35 @@ static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno)
return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]);
 }
 
+static void imx_ldb_encoder_cleanup(struct drm_device *drm, void *data)
+{
+   struct drm_encoder *encoder = data;
+
+   drm_encoder_cleanup(encoder);
+}
+
 static int imx_ldb_register(struct drm_device *drm,
struct imx_ldb_channel *imx_ldb_ch)
 {
struct imx_ldb *ldb = imx_ldb_ch->ldb;
-   struct drm_connector *connector = &imx_ldb_ch->connector;
-   struct drm_encoder *encoder = &imx_ldb_ch->encoder;
+   struct imx_ldb_encoder *ldb_encoder;
+   struct drm_connector *connector;
+   struct drm_encoder *encoder;
int ret;
 
-   memset(connector, 0, sizeof(*connector));
-   memset(encoder, 0, sizeof(*encoder));
+   ldb_encoder = drmm_kzalloc(drm, sizeof(*ldb_encoder), GFP_KERNEL);
+   if (!ldb_encoder)
+   return -ENOMEM;
+
+   ldb_encoder->channel = imx_ldb_ch;
+   connector = &ldb_encoder->connector;
+   encoder = &ldb_encoder->encoder;
+
+   drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_LVDS);
+
+   ret = drmm_add_action_or_reset(drm, imx_ldb_encoder_cleanup, encoder);
+   if (ret)
+   return ret;
 
ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child);
if (ret)
@@ -433,7 +459,6 @@ static int imx_ldb_register(struct drm_device *drm,
}
 
drm_encoder_helper_add(encoder, &imx_ldb_encoder_helper_funcs);
-   drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_LVDS);
 
if (imx_ldb_ch->bridge) {
ret = drm_bridge_attach(encoder, imx_ldb_ch->bridge, NULL, 0);
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 05/21] drm/imx: imx-ldb: use local encoder and connector variables

2020-09-11 Thread Philipp Zabel
Use local variables for encoder and connector.
This simplifies the following commits.

Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/imx-ldb.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 41e2978cb1eb..288a81f134fe 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -411,6 +411,7 @@ static int imx_ldb_register(struct drm_device *drm,
struct imx_ldb_channel *imx_ldb_ch)
 {
struct imx_ldb *ldb = imx_ldb_ch->ldb;
+   struct drm_connector *connector = &imx_ldb_ch->connector;
struct drm_encoder *encoder = &imx_ldb_ch->encoder;
int ret;
 
@@ -432,8 +433,7 @@ static int imx_ldb_register(struct drm_device *drm,
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_LVDS);
 
if (imx_ldb_ch->bridge) {
-   ret = drm_bridge_attach(&imx_ldb_ch->encoder,
-   imx_ldb_ch->bridge, NULL, 0);
+   ret = drm_bridge_attach(encoder, imx_ldb_ch->bridge, NULL, 0);
if (ret) {
DRM_ERROR("Failed to initialize bridge with drm\n");
return ret;
@@ -445,13 +445,13 @@ static int imx_ldb_register(struct drm_device *drm,
 * historical reasons, the ldb driver can also work without
 * a panel.
 */
-   drm_connector_helper_add(&imx_ldb_ch->connector,
-   &imx_ldb_connector_helper_funcs);
-   drm_connector_init_with_ddc(drm, &imx_ldb_ch->connector,
+   drm_connector_helper_add(connector,
+&imx_ldb_connector_helper_funcs);
+   drm_connector_init_with_ddc(drm, connector,
&imx_ldb_connector_funcs,
DRM_MODE_CONNECTOR_LVDS,
imx_ldb_ch->ddc);
-   drm_connector_attach_encoder(&imx_ldb_ch->connector, encoder);
+   drm_connector_attach_encoder(connector, encoder);
}
 
return 0;
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 19/21] drm/imx: ipuv3-plane: use drm managed resources

2020-09-11 Thread Philipp Zabel
Use drmm_kzalloc() to align plane memory lifetime with the drm device,
and use drmm_add_action_or_reset() to make sure drm_plane_cleanup() is
called before the memory is freed. Also handle error return values of
the plane property creation functions.

Signed-off-by: Philipp Zabel 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/imx/ipuv3-plane.c | 34 +--
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index 8a4235d9d9f1..d3e6c37bf0fb 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -262,16 +263,6 @@ void ipu_plane_disable_deferred(struct drm_plane *plane)
 }
 EXPORT_SYMBOL_GPL(ipu_plane_disable_deferred);
 
-static void ipu_plane_destroy(struct drm_plane *plane)
-{
-   struct ipu_plane *ipu_plane = to_ipu_plane(plane);
-
-   DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
-   drm_plane_cleanup(plane);
-   kfree(ipu_plane);
-}
-
 static void ipu_plane_state_reset(struct drm_plane *plane)
 {
unsigned int zpos = (plane->type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1;
@@ -336,7 +327,6 @@ static bool ipu_plane_format_mod_supported(struct drm_plane 
*plane,
 static const struct drm_plane_funcs ipu_plane_funcs = {
.update_plane   = drm_atomic_helper_update_plane,
.disable_plane  = drm_atomic_helper_disable_plane,
-   .destroy= ipu_plane_destroy,
.reset  = ipu_plane_state_reset,
.atomic_duplicate_state = ipu_plane_duplicate_state,
.atomic_destroy_state   = ipu_plane_destroy_state,
@@ -822,6 +812,13 @@ int ipu_planes_assign_pre(struct drm_device *dev,
 }
 EXPORT_SYMBOL_GPL(ipu_planes_assign_pre);
 
+static void ipu_plane_cleanup(struct drm_device *dev, void *data)
+{
+   struct ipu_plane *ipu_plane = data;
+
+   drm_plane_cleanup(&ipu_plane->base);
+}
+
 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
 int dma, int dp, unsigned int possible_crtcs,
 enum drm_plane_type type)
@@ -834,7 +831,7 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, 
struct ipu_soc *ipu,
DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
  dma, dp, possible_crtcs);
 
-   ipu_plane = kzalloc(sizeof(*ipu_plane), GFP_KERNEL);
+   ipu_plane = drmm_kzalloc(dev, sizeof(*ipu_plane), GFP_KERNEL);
if (!ipu_plane) {
DRM_ERROR("failed to allocate plane\n");
return ERR_PTR(-ENOMEM);
@@ -853,16 +850,23 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, 
struct ipu_soc *ipu,
   modifiers, type, NULL);
if (ret) {
DRM_ERROR("failed to initialize plane\n");
-   kfree(ipu_plane);
return ERR_PTR(ret);
}
 
+   ret = drmm_add_action_or_reset(dev, ipu_plane_cleanup, ipu_plane);
+   if (ret)
+   return ERR_PTR(ret);
+
drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs);
 
if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG)
-   drm_plane_create_zpos_property(&ipu_plane->base, zpos, 0, 1);
+   ret = drm_plane_create_zpos_property(&ipu_plane->base, zpos, 0,
+1);
else
-   drm_plane_create_zpos_immutable_property(&ipu_plane->base, 0);
+   ret = drm_plane_create_zpos_immutable_property(&ipu_plane->base,
+  0);
+   if (ret)
+   return ERR_PTR(ret);
 
return ipu_plane;
 }
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 10/21] drm/imx: imx-tve: use devm_clk_register

2020-09-11 Thread Philipp Zabel
Avoid leaking the clock provider when the driver is unbound.

Signed-off-by: Philipp Zabel 
---
Changes since v1:
 - Split from patch "drm/imx: imx-tve: use drm managed resources".
---
 drivers/gpu/drm/imx/imx-tve.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 2011e9085095..044730b95120 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -418,7 +418,7 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem 
*base)
init.parent_names = (const char **)&tve_di_parent;
 
tve->clk_hw_di.init = &init;
-   tve->di_clk = clk_register(tve->dev, &tve->clk_hw_di);
+   tve->di_clk = devm_clk_register(tve->dev, &tve->clk_hw_di);
if (IS_ERR(tve->di_clk)) {
dev_err(tve->dev, "failed to register TVE output clock: %ld\n",
PTR_ERR(tve->di_clk));
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 04/21] drm/imx: imx-ldb: reduce scope of edid_len

2020-09-11 Thread Philipp Zabel
The edid_len variable is never used again. Use a local variable instead
of storing it in the device structure.

Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/imx-ldb.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index af757d1e21fe..41e2978cb1eb 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -62,7 +62,6 @@ struct imx_ldb_channel {
struct i2c_adapter *ddc;
int chno;
void *edid;
-   int edid_len;
struct drm_display_mode mode;
int mode_valid;
u32 bus_format;
@@ -536,15 +535,14 @@ static int imx_ldb_panel_ddc(struct device *dev,
}
 
if (!channel->ddc) {
+   int edid_len;
+
/* if no DDC available, fallback to hardcoded EDID */
dev_dbg(dev, "no ddc available\n");
 
-   edidp = of_get_property(child, "edid",
-   &channel->edid_len);
+   edidp = of_get_property(child, "edid", &edid_len);
if (edidp) {
-   channel->edid = kmemdup(edidp,
-   channel->edid_len,
-   GFP_KERNEL);
+   channel->edid = kmemdup(edidp, edid_len, GFP_KERNEL);
} else if (!channel->panel) {
/* fallback to display-timings node */
ret = of_get_drm_display_mode(child,
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 14/21] drm/imx: parallel-display: remove unused function enc_to_imxpd()

2020-09-11 Thread Philipp Zabel
Remove leftover container_of helper, it has been replaced by
bridge_to_imxpd().

Fixes: fe141cedc433 ("drm/imx: pd: Use bus format/flags provided by the bridge 
when available")
Signed-off-by: Philipp Zabel 
---
New in v2.
---
 drivers/gpu/drm/imx/parallel-display.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c 
b/drivers/gpu/drm/imx/parallel-display.c
index ecf49f2ce268..726f6cc6fa25 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -41,11 +41,6 @@ static inline struct imx_parallel_display 
*con_to_imxpd(struct drm_connector *c)
return container_of(c, struct imx_parallel_display, connector);
 }
 
-static inline struct imx_parallel_display *enc_to_imxpd(struct drm_encoder *e)
-{
-   return container_of(e, struct imx_parallel_display, encoder);
-}
-
 static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge 
*b)
 {
return container_of(b, struct imx_parallel_display, bridge);
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 12/21] drm/imx: imx-tve: use drm managed resources

2020-09-11 Thread Philipp Zabel
Use drmm_kzalloc() to align encoder memory lifetime with the drm device,
and use drmm_add_action_or_reset() to make sure drm_encoder_cleanup() is
called before the memory is freed.

Signed-off-by: Philipp Zabel 
Acked-by: Daniel Vetter 
---
Changes since v1:
 - Split some changes out into previous patches.
---
 drivers/gpu/drm/imx/imx-tve.c | 54 +--
 1 file changed, 39 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index aa1c2ab34170..bac025eafa1f 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -19,6 +19,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -99,9 +100,13 @@ enum {
TVE_MODE_VGA,
 };
 
-struct imx_tve {
+struct imx_tve_encoder {
struct drm_connector connector;
struct drm_encoder encoder;
+   struct imx_tve *tve;
+};
+
+struct imx_tve {
struct device *dev;
int mode;
int di_hsync_pin;
@@ -118,12 +123,12 @@ struct imx_tve {
 
 static inline struct imx_tve *con_to_tve(struct drm_connector *c)
 {
-   return container_of(c, struct imx_tve, connector);
+   return container_of(c, struct imx_tve_encoder, connector)->tve;
 }
 
 static inline struct imx_tve *enc_to_tve(struct drm_encoder *e)
 {
-   return container_of(e, struct imx_tve, encoder);
+   return container_of(e, struct imx_tve_encoder, encoder)->tve;
 }
 
 static void tve_enable(struct imx_tve *tve)
@@ -428,6 +433,13 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem 
*base)
return 0;
 }
 
+static void imx_tve_encoder_cleanup(struct drm_device *drm, void *ptr)
+{
+   struct drm_encoder *encoder = ptr;
+
+   drm_encoder_cleanup(encoder);
+}
+
 static void imx_tve_disable_regulator(void *data)
 {
struct imx_tve *tve = data;
@@ -477,33 +489,45 @@ static int imx_tve_bind(struct device *dev, struct device 
*master, void *data)
 {
struct drm_device *drm = data;
struct imx_tve *tve = dev_get_drvdata(dev);
-   struct drm_encoder *encoder = &tve->encoder;
-   struct drm_connector *connector = &tve->connector;
+   struct imx_tve_encoder *tvee;
+   struct drm_encoder *encoder;
+   struct drm_connector *connector;
int encoder_type;
int ret;
 
encoder_type = tve->mode == TVE_MODE_VGA ?
   DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
 
-   memset(connector, 0, sizeof(*connector));
-   memset(encoder, 0, sizeof(*encoder));
+   tvee = drmm_kzalloc(drm, sizeof(*tvee), GFP_KERNEL);
+   if (!tvee)
+   return -ENOMEM;
+
+   tvee->tve = tve;
+   encoder = &tvee->encoder;
+   connector = &tvee->connector;
+
+   ret = drm_simple_encoder_init(drm, encoder, encoder_type);
+   if (ret)
+   return ret;
+
+   ret = drmm_add_action_or_reset(drm, imx_tve_encoder_cleanup, encoder);
+   if (ret)
+   return ret;
 
ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node);
if (ret)
return ret;
 
drm_encoder_helper_add(encoder, &imx_tve_encoder_helper_funcs);
-   drm_simple_encoder_init(drm, encoder, encoder_type);
 
drm_connector_helper_add(connector, &imx_tve_connector_helper_funcs);
-   drm_connector_init_with_ddc(drm, connector,
-   &imx_tve_connector_funcs,
-   DRM_MODE_CONNECTOR_VGA,
-   tve->ddc);
-
-   drm_connector_attach_encoder(connector, encoder);
+   ret = drm_connector_init_with_ddc(drm, connector,
+ &imx_tve_connector_funcs,
+ DRM_MODE_CONNECTOR_VGA, tve->ddc);
+   if (ret)
+   return ret;
 
-   return 0;
+   return drm_connector_attach_encoder(connector, encoder);
 }
 
 static const struct component_ops imx_tve_ops = {
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 02/21] drm/imx: dw_hdmi-imx: move initialization into probe

2020-09-11 Thread Philipp Zabel
The parts of the initialization do not require the drm device can be
done once during probe instead of possibly multiple times during bind.
The bind function only creates the encoder and attaches the bridge.

Signed-off-by: Philipp Zabel 
---
Changes since v1:
 - Split from patch "drm/imx: dw_hdmi-imx: use drm managed resources, switch to
   dw_hdmi_probe"
---
 drivers/gpu/drm/imx/dw_hdmi-imx.c | 74 +++
 1 file changed, 26 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index d07b39b8afd2..bbd0a0cd7c3d 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -15,6 +15,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,6 +26,7 @@
 struct imx_hdmi {
struct device *dev;
struct drm_encoder encoder;
+   struct drm_bridge *bridge;
struct dw_hdmi *hdmi;
struct regmap *regmap;
 };
@@ -98,19 +100,6 @@ static const struct dw_hdmi_phy_config imx_phy_config[] = {
{ ~0UL,  0x, 0x, 0x}
 };
 
-static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi)
-{
-   struct device_node *np = hdmi->dev->of_node;
-
-   hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
-   if (IS_ERR(hdmi->regmap)) {
-   dev_err(hdmi->dev, "Unable to get gpr\n");
-   return PTR_ERR(hdmi->regmap);
-   }
-
-   return 0;
-}
-
 static void dw_hdmi_imx_encoder_enable(struct drm_encoder *encoder)
 {
struct imx_hdmi *hdmi = enc_to_imx_hdmi(encoder);
@@ -195,65 +184,34 @@ MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids);
 static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
void *data)
 {
-   struct platform_device *pdev = to_platform_device(dev);
-   const struct dw_hdmi_plat_data *plat_data;
-   const struct of_device_id *match;
struct drm_device *drm = data;
struct drm_encoder *encoder;
struct imx_hdmi *hdmi;
int ret;
 
-   if (!pdev->dev.of_node)
-   return -ENODEV;
-
hdmi = dev_get_drvdata(dev);
-   memset(hdmi, 0, sizeof(*hdmi));
+   memset(&hdmi->encoder, 0, sizeof(hdmi->encoder));
 
-   match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node);
-   plat_data = match->data;
-   hdmi->dev = &pdev->dev;
encoder = &hdmi->encoder;
 
ret = imx_drm_encoder_parse_of(drm, encoder, dev->of_node);
if (ret)
return ret;
 
-   ret = dw_hdmi_imx_parse_dt(hdmi);
-   if (ret < 0)
-   return ret;
-
drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
-   hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
-
-   /*
-* If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
-* which would have called the encoder cleanup.  Do it manually.
-*/
-   if (IS_ERR(hdmi->hdmi)) {
-   ret = PTR_ERR(hdmi->hdmi);
-   drm_encoder_cleanup(encoder);
-   }
-
-   return ret;
-}
-
-static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
-  void *data)
-{
-   struct imx_hdmi *hdmi = dev_get_drvdata(dev);
-
-   dw_hdmi_unbind(hdmi->hdmi);
+   return drm_bridge_attach(encoder, hdmi->bridge, NULL, 0);
 }
 
 static const struct component_ops dw_hdmi_imx_ops = {
.bind   = dw_hdmi_imx_bind,
-   .unbind = dw_hdmi_imx_unbind,
 };
 
 static int dw_hdmi_imx_probe(struct platform_device *pdev)
 {
+   struct device_node *np = pdev->dev.of_node;
+   const struct of_device_id *match = of_match_node(dw_hdmi_imx_dt_ids, 
np);
struct imx_hdmi *hdmi;
 
hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
@@ -261,13 +219,33 @@ static int dw_hdmi_imx_probe(struct platform_device *pdev)
return -ENOMEM;
 
platform_set_drvdata(pdev, hdmi);
+   hdmi->dev = &pdev->dev;
+
+   hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+   if (IS_ERR(hdmi->regmap)) {
+   dev_err(hdmi->dev, "Unable to get gpr\n");
+   return PTR_ERR(hdmi->regmap);
+   }
+
+   hdmi->hdmi = dw_hdmi_probe(pdev, match->data);
+   if (IS_ERR(hdmi->hdmi))
+   return PTR_ERR(hdmi->hdmi);
+
+   hdmi->bridge = of_drm_find_bridge(np);
+   if (!hdmi->bridge) {
+   dev_err(hdmi->dev, "Unable to find bridge\n");
+   return -ENODEV;
+   }
 
return component_add(&pdev->dev, &dw_hdmi_imx_ops);
 }
 
 static int dw_hdmi_imx_remove(struct platform_device *pdev)
 {
+   struct imx_hdmi *hdmi = platform_get_drvdata(pdev);
+
component_del(&pdev->dev, &dw_hdmi_imx_ops);
+   dw_hdmi_remove(hdmi->hdmi);
 
return 0;
 }
-- 
2.20.1

___
dri-devel m

[PATCH v2 13/21] drm/imx: parallel-display: fix edid memory leak

2020-09-11 Thread Philipp Zabel
From: Marco Felsch 

The edid memory is only freed if the component.unbind() is called. This
is okay if the parallel-display was bound but if the bind() fails we
leak the memory.

Signed-off-by: Marco Felsch 
[p.za...@pengutronix.de: rebased, dropped now empty unbind()]
Signed-off-by: Philipp Zabel 
---
 drivers/gpu/drm/imx/parallel-display.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c 
b/drivers/gpu/drm/imx/parallel-display.c
index 8232f512b9ed..ecf49f2ce268 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -325,7 +325,8 @@ static int imx_pd_bind(struct device *dev, struct device 
*master, void *data)
 
edidp = of_get_property(np, "edid", &imxpd->edid_len);
if (edidp)
-   imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL);
+   imxpd->edid = devm_kmemdup(dev, edidp, imxpd->edid_len,
+  GFP_KERNEL);
 
ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
if (!ret) {
@@ -349,17 +350,8 @@ static int imx_pd_bind(struct device *dev, struct device 
*master, void *data)
return 0;
 }
 
-static void imx_pd_unbind(struct device *dev, struct device *master,
-   void *data)
-{
-   struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
-
-   kfree(imxpd->edid);
-}
-
 static const struct component_ops imx_pd_ops = {
.bind   = imx_pd_bind,
-   .unbind = imx_pd_unbind,
 };
 
 static int imx_pd_probe(struct platform_device *pdev)
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 21/21] drm/imx: ipuv3-crtc: use drm managed resources

2020-09-11 Thread Philipp Zabel
Use drmm_kzalloc() to align crtc memory lifetime with the drm device,
and use drmm_add_action_or_reset() to make sure IPU resources are
released and drm_crtc_cleanup() is called before the memory is freed.

Signed-off-by: Philipp Zabel 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/imx/ipuv3-crtc.c | 77 ++--
 1 file changed, 34 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 8076ab272637..f284e4ea6d5f 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -161,7 +162,6 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
 
 static const struct drm_crtc_funcs ipu_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
-   .destroy = drm_crtc_cleanup,
.page_flip = drm_atomic_helper_page_flip,
.reset = imx_drm_crtc_reset,
.atomic_duplicate_state = imx_drm_crtc_duplicate_state,
@@ -318,37 +318,42 @@ static const struct drm_crtc_helper_funcs 
ipu_helper_funcs = {
.atomic_enable = ipu_crtc_atomic_enable,
 };
 
-static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
+static void ipu_put_resources(struct drm_device *dev, void *ptr)
 {
+   struct ipu_crtc *ipu_crtc = ptr;
+
if (!IS_ERR_OR_NULL(ipu_crtc->dc))
ipu_dc_put(ipu_crtc->dc);
if (!IS_ERR_OR_NULL(ipu_crtc->di))
ipu_di_put(ipu_crtc->di);
 }
 
-static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
-   struct ipu_client_platformdata *pdata)
+static int ipu_get_resources(struct drm_device *dev, struct ipu_crtc *ipu_crtc,
+struct ipu_client_platformdata *pdata)
 {
struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
int ret;
 
ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
-   if (IS_ERR(ipu_crtc->dc)) {
-   ret = PTR_ERR(ipu_crtc->dc);
-   goto err_out;
-   }
+   if (IS_ERR(ipu_crtc->dc))
+   return PTR_ERR(ipu_crtc->dc);
+
+   ret = drmm_add_action_or_reset(dev, ipu_put_resources, ipu_crtc);
+   if (ret)
+   return ret;
 
ipu_crtc->di = ipu_di_get(ipu, pdata->di);
-   if (IS_ERR(ipu_crtc->di)) {
-   ret = PTR_ERR(ipu_crtc->di);
-   goto err_out;
-   }
+   if (IS_ERR(ipu_crtc->di))
+   return PTR_ERR(ipu_crtc->di);
 
return 0;
-err_out:
-   ipu_put_resources(ipu_crtc);
+}
 
-   return ret;
+static void ipu_crtc_cleanup(struct drm_device *drm, void *ptr)
+{
+   struct drm_crtc *crtc = ptr;
+
+   drm_crtc_cleanup(crtc);
 }
 
 static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
@@ -359,7 +364,7 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
int dp = -EINVAL;
int ret;
 
-   ret = ipu_get_resources(ipu_crtc, pdata);
+   ret = ipu_get_resources(drm, ipu_crtc, pdata);
if (ret) {
dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
ret);
@@ -372,13 +377,19 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
DRM_PLANE_TYPE_PRIMARY);
if (IS_ERR(ipu_crtc->plane[0])) {
ret = PTR_ERR(ipu_crtc->plane[0]);
-   goto err_put_resources;
+   return ret;
}
 
crtc->port = pdata->of_node;
drm_crtc_helper_add(crtc, &ipu_helper_funcs);
-   drm_crtc_init_with_planes(drm, crtc, &ipu_crtc->plane[0]->base, NULL,
- &ipu_crtc_funcs, NULL);
+   ret = drm_crtc_init_with_planes(drm, crtc, &ipu_crtc->plane[0]->base,
+   NULL, &ipu_crtc_funcs, NULL);
+   if (ret)
+   return ret;
+
+   ret = drmm_add_action_or_reset(drm, ipu_crtc_cleanup, crtc);
+   if (ret)
+   return ret;
 
/* If this crtc is using the DP, add an overlay plane */
if (pdata->dp >= 0 && pdata->dma[1] > 0) {
@@ -395,17 +406,12 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
"imx_drm", ipu_crtc);
if (ret < 0) {
dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
-   goto err_put_resources;
+   return ret;
}
/* Only enable IRQ when we actually need it to trigger work. */
disable_irq(ipu_crtc->irq);
 
return 0;
-
-err_put_resources:
-   ipu_put_resources(ipu_crtc);
-
-   return ret;
 }
 
 static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
@@ -414,31 +420,22 @@ static int ipu_drm_bind(struct device *dev, struct device 
*master, void *data)
struct drm_device *drm = data;
struct ipu_crtc *ipu_crtc;
 
-   ipu_crtc = dev_get_drvdata(dev);
-   memset(ipu_crtc, 0, sizeof(*ipu_crtc));
+   ipu

[PATCH] drm/ttm: remove default caching

2020-09-11 Thread Christian König
As far as I can tell this was never used either and we just
always fallback to the order cached > wc > uncached anyway.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c   |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  |  1 -
 drivers/gpu/drm/drm_gem_vram_helper.c |  3 +--
 drivers/gpu/drm/nouveau/nouveau_ttm.c | 21 +++
 drivers/gpu/drm/qxl/qxl_ttm.c |  2 +-
 drivers/gpu/drm/radeon/radeon_ttm.c   |  6 ++
 drivers/gpu/drm/ttm/ttm_bo.c  |  3 ---
 drivers/gpu/drm/ttm/ttm_range_manager.c   |  2 --
 drivers/gpu/drm/ttm/ttm_resource.c|  1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |  4 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c |  1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_thp.c   |  1 -
 include/drm/ttm/ttm_bo_driver.h   |  2 --
 include/drm/ttm/ttm_resource.h|  3 ---
 15 files changed, 14 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index 697bc2c6fdb2..b2ca693b8285 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -94,7 +94,6 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t 
gtt_size)
man->use_tt = true;
man->func = &amdgpu_gtt_mgr_func;
man->available_caching = TTM_PL_MASK_CACHING;
-   man->default_caching = TTM_PL_FLAG_CACHED;
 
ttm_resource_manager_init(man, gtt_size >> PAGE_SHIFT);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 651365183e75..96aa8fcb9115 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -68,7 +68,7 @@ static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev,
uint64_t size)
 {
return ttm_range_man_init(&adev->mman.bdev, type,
- TTM_PL_FLAG_UNCACHED, TTM_PL_FLAG_UNCACHED,
+ TTM_PL_FLAG_UNCACHED,
  false, size >> PAGE_SHIFT);
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 7574be6cd7a0..8b4a9ab66586 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -178,7 +178,6 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
int ret;
 
man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-   man->default_caching = TTM_PL_FLAG_WC;
 
ttm_resource_manager_init(man, adev->gmc.real_vram_size >> PAGE_SHIFT);
 
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index 5f10aa7aa099..34dc665eb891 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -1106,8 +1106,7 @@ static int drm_vram_mm_init(struct drm_vram_mm *vmm, 
struct drm_device *dev,
 
ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM,
 TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
-TTM_PL_FLAG_WC, false,
-vram_size >> PAGE_SHIFT);
+false, vram_size >> PAGE_SHIFT);
if (ret)
return ret;
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c 
b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index a62f37b1131c..cf18f75cd0f1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -203,12 +203,9 @@ nouveau_ttm_init_vram(struct nouveau_drm *drm)
return -ENOMEM;
 
man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-   man->default_caching = TTM_PL_FLAG_WC;
 
-   if (type & NVIF_MEM_UNCACHED) {
+   if (type & NVIF_MEM_UNCACHED)
man->available_caching = TTM_PL_FLAG_UNCACHED;
-   man->default_caching = TTM_PL_FLAG_UNCACHED;
-   }
 
man->func = &nouveau_vram_manager;
 
@@ -220,7 +217,7 @@ nouveau_ttm_init_vram(struct nouveau_drm *drm)
} else {
return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_VRAM,
  TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
- TTM_PL_FLAG_WC, false,
+ false,
  drm->gem.vram_available >> 
PAGE_SHIFT);
}
 }
@@ -245,16 +242,14 @@ nouveau_ttm_init_gtt(struct nouveau_drm *drm)
 {
struct ttm_resource_manager *man;
unsigned long size_pages = drm->gem.gart_available >> PAGE_SHIFT;
-   unsigned available_caching, default_caching;
const struct ttm_resource_manager_func *func = NULL;

Re: [PATCH] drm/bridge: dw-mipi-dsi: permit configuring the escape clock rate

2020-09-11 Thread Neil Armstrong
On 11/09/2020 10:29, Philippe CORNU wrote:
> 
> 
> On 9/4/20 2:55 PM, Neil Armstrong wrote:
>> The Amlogic D-PHY in the Amlogic AXG SoC Family does support a frequency
>> higher than 10MHz for the TX Escape Clock, thus make the target rate
>> configurable.
>>
>> Signed-off-by: Neil Armstrong 
>> ---
>>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 25 +++
>>   include/drm/bridge/dw_mipi_dsi.h  |  1 +
>>   2 files changed, 21 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
>> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
>> index d580b2aa4ce9..31fc965c66fd 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
>> @@ -562,15 +562,30 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi 
>> *dsi)
>>   
>>   static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
>>   {
>> +const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
>> +unsigned int esc_rate; /* in MHz */
>> +u32 esc_clk_division;
>> +int ret;
>> +
>>  /*
>>   * The maximum permitted escape clock is 20MHz and it is derived from
>> - * lanebyteclk, which is running at "lane_mbps / 8".  Thus we want:
>> - *
>> - * (lane_mbps >> 3) / esc_clk_division < 20
>> + * lanebyteclk, which is running at "lane_mbps / 8".
>> + */
>> +if (phy_ops->get_esc_clk_rate) {
>> +ret = phy_ops->get_esc_clk_rate(dsi->plat_data->priv_data,
>> +&esc_rate);
>> +if (ret)
>> +DRM_DEBUG_DRIVER("Phy get_esc_clk_rate() failed\n");
>> +} else
>> +esc_rate = 20; /* Default to 20MHz */
>> +
>> +/*
>> + * We want :
>> + * (lane_mbps >> 3) / esc_clk_division < X
>>   * which is:
>> - * (lane_mbps >> 3) / 20 > esc_clk_division
>> + * (lane_mbps >> 3) / X > esc_clk_division
>>   */
>> -u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
>> +esc_clk_division = (dsi->lane_mbps >> 3) / esc_rate + 1;
>>   
>>  dsi_write(dsi, DSI_PWR_UP, RESET);
>>   
>> diff --git a/include/drm/bridge/dw_mipi_dsi.h 
>> b/include/drm/bridge/dw_mipi_dsi.h
>> index b0e390b3288e..bda8aa7c2280 100644
>> --- a/include/drm/bridge/dw_mipi_dsi.h
>> +++ b/include/drm/bridge/dw_mipi_dsi.h
>> @@ -36,6 +36,7 @@ struct dw_mipi_dsi_phy_ops {
>>   unsigned int *lane_mbps);
>>  int (*get_timing)(void *priv_data, unsigned int lane_mbps,
>>struct dw_mipi_dsi_dphy_timing *timing);
>> +int (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate);
>>   };
>>   
>>   struct dw_mipi_dsi_host_ops {
>>
> 
> Hi Neil,
> Thank you for the patch
> 
> Reviewed-by: Philippe Cornu 
> 
> Philippe :-)
> 

Thanks !

Applying to drm-misc-next

Neil
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: per-plane LUTs and CSCs?

2020-09-11 Thread Pekka Paalanen
On Thu, 10 Sep 2020 15:39:07 -0400
Vitaly Prosyak  wrote:

> On 2020-09-10 2:07 p.m., Vitaly Prosyak wrote:
> >
> >
> > On 2020-09-10 1:51 p.m., Laurent Pinchart wrote:  
> >> Hi Vitaly,
> >>
> >> On Thu, Sep 10, 2020 at 01:09:03PM -0400, Vitaly Prosyak wrote:  
> >>> On 2020-09-10 6:56 a.m., Laurent Pinchart wrote:  
>  On Thu, Sep 10, 2020 at 01:28:03PM +0300, Pekka Paalanen wrote:  
> > On Thu, 10 Sep 2020 12:30:09 +0300 Laurentiu Palcu wrote:  
> >> On Thu, Sep 10, 2020 at 11:50:26AM +0300, Pekka Paalanen wrote:  
> >>> On Thu, 10 Sep 2020 09:52:26 +0200 Daniel Vetter wrote:  
>  On Thu, Sep 10, 2020 at 10:25:43AM +0300, Pekka Paalanen wrote:  
> > On Wed, 9 Sep 2020 13:57:28 +0300 Laurentiu Palcu wrote:
> > 
> >> Hi all,
> >>
> >> I was wondering whether you could give me an advise on how to 
> >> proceed further
> >> with the following issue as I'm preparing to upstream the next set 
> >> of patches
> >> for the iMX8MQ display controller(DCSS). The display controller 
> >> has 3 planes,
> >> each with 2 CSCs and one degamma LUT. The CSCs are in front and 
> >> after the LUT
> >> respectively. Then the output from those 3 pipes is blended 
> >> together and then
> >> gamma correction is applied using a linear-to-nonlinear LUT and 
> >> another CSC, if
> >> needed.  
> >>> Hi,
> >>>
> >>> hmm, so FB -> CSC -> LUT -> CSC -> blending?
> >>>
> >>> Is it then
> >>>   blending -> LUT -> CSC -> encoder
> >>> or
> >>>   blending -> CSC -> LUT -> encoder?  
> >> The DCSS pipeline topology is this:
> >>
> >> FB1->CSC_A->LUT->CSC_B-\
> >> FB2->CSC_A->LUT->CSC_B-|-blender->LUT->CSC_O->encoder
> >> FB3->CSC_A->LUT->CSC_B-/
> >>
> >> Basically, CSC_A is used to convert to a common colorspace if needed
> >> (YUV->RGB) as well as to perform pixel range conversions: 
> >> limited->full.
> >> CSC_B is for gamut conversions(like 709->2020). The CSC_O is used to
> >> convert to the colorspace used by the output (like RGB->YUV).  
> > I didn't realize that it would be correct to do RGB-YUV conversion in
> > non-linear space, but yeah, that's what most software do too I guess.
> >  
> >>> Are all these LUTs per-channel 1D LUTs or something else?  
> >> LUTs are 3D, per pixel component.  
> > Sorry, which one?
> >
> > An example of a 3D LUT is 32x32x32 entries with each entry being a
> > triplet, while a 1D LUT could be 1024 entries with each entry being a
> > scalar. 1D LUTs are used per-channel so you need three of them, 3D LUTs
> > you need just one for the color value triplet mapping.
> >
> > A 3D LUT can express much more than a 4x4 CTM. A 1D LUT cannot do the
> > channel mixing that a CTM can.
> >
> > So if you truly have 3D LUTs everywhere, I wonder why the CSC matrix
> > blocks exist...  
>  Possibly because the 3D LUT uses interpolation (it's a 17x17x17 LUT in
>  R-Car), having a separate CSC can give more precision (as well as
>  allowing the two problems to be decoupled, at a relatively low hardware
>  cost).  
> >>> If you put nonlinear signal to 3DLUT then your
> >>> precision would be improved.
> >>> How many bits each color value has in 3DLUT ?  
> >> The whole display pipeline uses 8 bits per component.  
> > It is pretty low , please, use always nonlinear signal in the pipe and it 
> > allows you to compress and 'win' about 2 bits.  

The DRM driver is not in control of that, though. Userspace controls it
through what values it happens to upload to the LUTs and matrices.

This raises a good point: userspace must be aware of both LUT
size and precision to decide if and how to use it.

> Do you have alpha and de-alpha blocks in your pipeline?
> You can do CSC and blending in nonlinear mode, it is less accurate than in 
> linear, but it is viable way.

It may be viable in some cases and not others. That too is a userspace
decision.

> Also alpha should be removed (if it is applied) before CSC.

Right.


Thanks,
pq


pgp2pIusqPQAL.pgp
Description: OpenPGP digital signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/bridge: dw-mipi-dsi: Use kmemdup cf. kmalloc+memcpy

2020-09-11 Thread Neil Armstrong
On 09/09/2020 21:02, Alex Dewar wrote:
> kmemdup can be used instead of kmalloc+memcpy. Replace an occurrence of
> this pattern.
> 
> Issue identified with Coccinelle.
> 
> Signed-off-by: Alex Dewar 
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 52f5c5a2ed64..7e9a62ad56e8 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -1049,12 +1049,10 @@ static void debugfs_create_files(void *data)
>   };
>   int i;
>  
> - dsi->debugfs_vpg = kmalloc(sizeof(debugfs), GFP_KERNEL);
> + dsi->debugfs_vpg = kmemdup(debugfs, sizeof(debugfs), GFP_KERNEL);
>   if (!dsi->debugfs_vpg)
>   return;
>  
> - memcpy(dsi->debugfs_vpg, debugfs, sizeof(debugfs));
> -
>   for (i = 0; i < ARRAY_SIZE(debugfs); i++)
>   debugfs_create_file(dsi->debugfs_vpg[i].name, 0644,
>   dsi->debugfs, &dsi->debugfs_vpg[i],
> 

Acked-by: Neil Armstrong 

Thanks,
Neil
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC PATCH 2/3] drm/atomic-helper: add REQUIRE_MATCHING_FB flag

2020-09-11 Thread Ville Syrjälä
On Thu, Sep 10, 2020 at 11:24:24AM +0200, Stefan Agner wrote:
> Add flag which checks that the framebuffer size matches the plane size
> exactly. This is useful for display controller which can't handle
> framebuffers other than the plane/CRTC size.
> 
> Signed-off-by: Stefan Agner 
> ---
>  drivers/gpu/drm/drm_atomic_helper.c   | 7 +++
>  drivers/gpu/drm/selftests/test-drm_plane_helper.c | 9 +
>  include/drm/drm_atomic_helper.h   | 1 +
>  3 files changed, 17 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index 755572a37f3f..8bc7f8c2e566 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -802,6 +802,7 @@ int drm_atomic_helper_check_plane_state(struct 
> drm_plane_state *plane_state,
>   int hscale, vscale;
>   bool can_position = flags & DRM_PLANE_CAN_POSITION;
>   bool can_update_disabled = flags & DRM_PLANE_CAN_UPDATE_DISABLED;
> + bool require_matching_fb = flags & DRM_PLANE_REQUIRE_MATCHING_FB;
>  
>   WARN_ON(plane_state->crtc && plane_state->crtc != crtc_state->crtc);
>  
> @@ -860,6 +861,12 @@ int drm_atomic_helper_check_plane_state(struct 
> drm_plane_state *plane_state,
>   return -EINVAL;
>   }
>  
> + if (require_matching_fb && (drm_rect_width(src) != fb->width ||
> + drm_rect_height(src) != fb->height)) {

src rect is .16 fixed point vs. fb dimensions are integers

Still not a fan of these swiss army knife functions but meh.

> + DRM_DEBUG_KMS("Framebuffer size must match plane size.\n");
> + return -EINVAL;
> + }
> +
>   return 0;
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_check_plane_state);
> diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c 
> b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> index 01e95b2d572f..2c81bbef830e 100644
> --- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> +++ b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> @@ -139,6 +139,15 @@ int igt_check_plane_state(void *ignored)
>   FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1023 << 16, 767 << 16));
>   FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1023, 767));
>  
> + /* Check whether requiring same size framebuffer works correctly. */
> + set_src(&plane_state, 0, 0, 1024 << 16, 768 << 16);
> + set_crtc(&plane_state, 0, 0, 1024, 768);
> + ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
> +   DRM_PLANE_HELPER_NO_SCALING,
> +   DRM_PLANE_HELPER_NO_SCALING,
> +   
> DRM_PLANE_REQUIRE_MATCHING_FB);
> + FAIL(!ret, "Should not be able to use different size framebuffer with 
> REQUIRE_MATCHING_FB\n");
> +
>   /* Simple scaling tests. */
>   set_src(&plane_state, 0, 0, 512 << 16, 384 << 16);
>   set_crtc(&plane_state, 0, 0, 1024, 768);
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index bb9957b4f91b..244b730e84d3 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -43,6 +43,7 @@ int drm_atomic_helper_check_modeset(struct drm_device *dev,
>  
>  #define DRM_PLANE_CAN_POSITION   BIT(0)
>  #define DRM_PLANE_CAN_UPDATE_DISABLEDBIT(1)
> +#define DRM_PLANE_REQUIRE_MATCHING_FBBIT(2)
>  
>  int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
>   const struct drm_crtc_state *crtc_state,
> -- 
> 2.28.0
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC PATCH v2 17/17] WIP: drm/tegra: Implement new UAPI

2020-09-11 Thread Mikko Perttunen

On 9/11/20 12:57 AM, Dmitry Osipenko wrote:

09.09.2020 11:36, Mikko Perttunen пишет:
...


Does it make sense to have timeout in microseconds?



Not sure, but better have it a bit more fine-grained rather than
coarse-grained. This still gives a maximum timeout of 71 minutes so I
don't think it has any negatives compared to milliseconds.


If there is no good reason to use microseconds right now, then should be
better to default to milliseconds, IMO. It shouldn't be a problem to
extend the IOCLT with a microseconds entry, if ever be needed.

{
__u32 timeout_ms;
...
__u32 timeout_us;
}

timeout = timeout_ms + 1000 * timeout_us;

There shouldn't be a need for a long timeouts, since a job that takes
over 100ms is probably too unpractical. It also should be possible to
detect a progressing job and then defer timeout in the driver. At least
this is what other drivers do, like etnaviv driver for example:

https://elixir.bootlin.com/linux/v5.9-rc4/source/drivers/gpu/drm/etnaviv/etnaviv_sched.c#L107



I still don't quite understand why it's better to default to 
milliseconds? As you say, there is no need to have a long timeout, and 
if we go microseconds now, then there wouldn't be a need to extend in 
the future.


Mikko
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: DRM_TEGRA_SUBMIT_BUF_WRITE_RELOC

2020-09-11 Thread Mikko Perttunen

On 9/11/20 1:15 AM, Dmitry Osipenko wrote:

09.09.2020 11:10, Mikko Perttunen пишет:

On 9/9/20 2:45 AM, Dmitry Osipenko wrote:

05.09.2020 13:34, Mikko Perttunen пишет:
...

+/* Submission */
+
+/** Patch address of the specified mapping in the submitted gather. */
+#define DRM_TEGRA_SUBMIT_BUF_WRITE_RELOC    (1<<0)


Shouldn't the kernel driver be aware about what relocations need to be
patched? Could you please explain the purpose of this flag?



Sure, the kernel knows if it returned the IOVA to the user or not, so we
could remove this flag and determine it implicitly. I don't think there
is much harm in it though; if we have the flag an application can decide
to ignore the iova field and just pass WRITE_RELOC always, and it's not
really any extra code on kernel side.


Sounds like there is no real practical use for this flag other than for
testing purposes, correct?



Patching depending just on if the MAP IOCTL returned an IOVA or not 
seems a bit "spooky action at a distance"-ish to me, but maybe it's not 
so bad.. I'll consider removing it.


Mikko
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv1] gpu: ipu-v3: Add 8 pixel alignment fix

2020-09-11 Thread Sebastian Reichel
Some standard (but unusual) resolutions like 1366x768 do not work
properly with i.MX6 SoCs, since the horizontal resolution needs to
be aligned to 8 pixels (so 1360x768 or 1368x768 work).

This patch allocates framebuffers allocated to 8 pixels. The extra
time required to send the additional pixels is removed from the blank
time. In order to expose the correct display size to userspace, the
stride is increased without increasing the width.

Without this patch, system hangs on an imx6dl board with 1366x768
panel connected via LVDS (and will be rebooted by watchdog). Last
message printed by a kernel at default loglevel is:

[1.876609] [drm] Initialized imx-drm 1.0.0 20120507 for display-subsystem 
on minor 1

After this patch the system boots fine and it is possible to start
X.org and Weston from Debian testing.

Suggested-by: Boris Brezillon 
Signed-off-by: Sebastian Reichel 
---
Hi,

I could not find much about the 8 pixel requirement in the datasheets,
but the problem is real and the NXP kernel has an alignment fix for
this. I think this was not yet detected because resolutions with width
not being a multiply of 8 are not that common.

PS: I'm on vacation for two weeks, so take your time reviewing this
and don't expect timely replies from me :)

-- Sebastian
---
 drivers/gpu/drm/imx/imx-drm-core.c | 26 +-
 drivers/gpu/drm/imx/ipuv3-crtc.c   | 11 ++-
 drivers/gpu/drm/imx/ipuv3-plane.c  | 18 ++
 drivers/gpu/ipu-v3/ipu-dc.c|  5 +
 drivers/gpu/ipu-v3/ipu-di.c|  7 +++
 5 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-drm-core.c 
b/drivers/gpu/drm/imx/imx-drm-core.c
index 7d00c49fd5a5..c4d904ecb517 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -144,9 +144,33 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
/* none so far */
 };
 
+static int imx_drm_dumb_create(struct drm_file *file_priv,
+  struct drm_device *drm,
+  struct drm_mode_create_dumb *args)
+{
+   u32 width = args->width;
+   int ret;
+
+   /*
+* Width must be multiple of 8 pixels or system will hang. This
+* generates a big enough buffer, so that we can send a few 'dead'
+* pixels to satisfy this requirement. Userspace is supposed to
+* see 'correct' panel resolution instead, so that it does not
+* render content into non-visible pixels.
+*/
+   args->width = ALIGN(width, 8);
+
+   ret = drm_gem_cma_dumb_create(file_priv, drm, args);
+   if (ret)
+   return ret;
+
+   args->width = width;
+   return ret;
+}
+
 static struct drm_driver imx_drm_driver = {
.driver_features= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
-   DRM_GEM_CMA_DRIVER_OPS,
+   DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(imx_drm_dumb_create),
.ioctls = imx_drm_ioctls,
.num_ioctls = ARRAY_SIZE(imx_drm_ioctls),
.fops   = &imx_drm_driver_fops,
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index d412fc265395..87a408e77694 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -301,10 +301,19 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
sig_cfg.vsync_pin = imx_crtc_state->di_vsync_pin;
 
drm_display_mode_to_videomode(mode, &sig_cfg.mode);
+   if (!IS_ALIGNED(sig_cfg.mode.hactive, 8)) {
+   unsigned int new_hactive = ALIGN(sig_cfg.mode.hactive, 8);
+
+   dev_info(ipu_crtc->dev, "8-pixel alignment change hactive %d -> 
%d\n",
+sig_cfg.mode.hactive, new_hactive);
+
+   sig_cfg.mode.hfront_porch = new_hactive - sig_cfg.mode.hactive;
+   sig_cfg.mode.hactive = new_hactive;
+   }
 
ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
 mode->flags & DRM_MODE_FLAG_INTERLACE,
-imx_crtc_state->bus_format, mode->hdisplay);
+imx_crtc_state->bus_format, sig_cfg.mode.hactive);
ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
 }
 
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index 6776ebb3246d..3e33dc59f454 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -29,6 +29,11 @@ to_ipu_plane_state(struct drm_plane_state *p)
return container_of(p, struct ipu_plane_state, base);
 }
 
+static unsigned int ipu_src_rect_width(const struct drm_plane_state *state)
+{
+   return ALIGN(drm_rect_width(&state->src) >> 16, 8);
+}
+
 static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p)
 {
return container_of(p, struct ipu_plane, base);
@@ -418,6 +423,11 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
if (old_fb && fb->pitches[

Re: [RFC PATCH v2 09/17] gpu: host1x: DMA fences and userspace fence creation

2020-09-11 Thread Dmitry Osipenko
05.09.2020 13:34, Mikko Perttunen пишет:
...
>  
> +static void action_signal_fence(struct host1x_waitlist *waiter)
> +{
> + struct host1x_syncpt_fence *f = waiter->data;
> +
> + host1x_fence_signal(f);
> +}
> +
>  typedef void (*action_handler)(struct host1x_waitlist *waiter);
>  
>  static const action_handler action_handlers[HOST1X_INTR_ACTION_COUNT] = {
>   action_submit_complete,
>   action_wakeup,
>   action_wakeup_interruptible,
> + action_signal_fence,
>  };

My expectation is that we should remove the host1x-waiter entirely. It
comes from 2011/2012 era of the host1x driver and now duplicates
functionality provided by the dma-fence and drm-scheduler. Perhaps it
could be okay to re-use existing code for the starter, but this is
something to keep in mind that it may be better not to put much effort
into the older code.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3] drm/dp_mst: Retrieve extended DPCD caps for topology manager

2020-09-11 Thread Koba Ko
As per DP-1.3, First check DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT.
If DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is 1, read the DP_DP13_DPCD_REV to
get the faster capability.
If DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is 0, read DP_DPCD_REV.

Signed-off-by: Koba Ko 
Reviewed-by: Lyude Paul 
---
Changelog:
1. Adjust the commit message.
2. use drm_dbg_kms instead and print the return code.
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 7753c718ddf9..63f8809b9aa4 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3671,8 +3671,6 @@ EXPORT_SYMBOL(drm_dp_read_mst_cap);
 int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool 
mst_state)
 {
int ret = 0;
-   u8 dpcd_ext = 0;
-   unsigned int dpcd_offset = 0;
struct drm_dp_mst_branch *mstb = NULL;
 
mutex_lock(&mgr->payload_lock);
@@ -3686,17 +3684,11 @@ int drm_dp_mst_topology_mgr_set_mst(struct 
drm_dp_mst_topology_mgr *mgr, bool ms
struct drm_dp_payload reset_pay;
 
WARN_ON(mgr->mst_primary);
-   drm_dp_dpcd_read(mgr->aux,
-DP_TRAINING_AUX_RD_INTERVAL,
-&dpcd_ext, sizeof(dpcd_ext));
-
-   dpcd_offset =
-   ((dpcd_ext & DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT) ?  
DP_DP13_DPCD_REV : DP_DPCD_REV);
 
/* get dpcd info */
-   ret = drm_dp_dpcd_read(mgr->aux, dpcd_offset, mgr->dpcd, 
DP_RECEIVER_CAP_SIZE);
-   if (ret != DP_RECEIVER_CAP_SIZE) {
-   DRM_DEBUG_KMS("failed to read DPCD\n");
+   ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
+   if (ret < 0) {
+   drm_dbg_kms(mgr->dev, "failed to read DPCD, ret %d\n", 
ret);
goto out_unlock;
}
 
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/vc4: Fix bitwise OR versus ternary operator in vc4_plane_mode_set

2020-09-11 Thread Nathan Chancellor
Clang warns:

drivers/gpu/drm/vc4/vc4_plane.c:901:27: warning: operator '?:' has lower
precedence than '|'; '|' will be evaluated first
[-Wbitwise-conditional-parentheses]
fb->format->has_alpha ?
~ ^
drivers/gpu/drm/vc4/vc4_plane.c:901:27: note: place parentheses around
the '|' expression to silence this warning
fb->format->has_alpha ?
~ ^
drivers/gpu/drm/vc4/vc4_plane.c:901:27: note: place parentheses around
the '?:' expression to evaluate it first
fb->format->has_alpha ?
~~^
1 warning generated.

Add the parentheses as that was clearly intended, otherwise
SCALER5_CTL2_ALPHA_PREMULT won't be added to the list.

Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5")
Link: https://github.com/ClangBuiltLinux/linux/issues/1150
Signed-off-by: Nathan Chancellor 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 24d7e6db6fdd..89543fa8ca4d 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -898,8 +898,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
vc4_dlist_write(vc4_state,
VC4_SET_FIELD(state->alpha >> 4,
  SCALER5_CTL2_ALPHA) |
-   fb->format->has_alpha ?
-   SCALER5_CTL2_ALPHA_PREMULT : 0 |
+   (fb->format->has_alpha ?
+   SCALER5_CTL2_ALPHA_PREMULT : 0) |
(mix_plane_alpha ?
SCALER5_CTL2_ALPHA_MIX : 0) |
VC4_SET_FIELD(fb->format->has_alpha ?

base-commit: 8c3c818c23a5bbce6ff180dd2ee04415241df77c
-- 
2.28.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 04/23] virtio: Add get_shm_region method

2020-09-11 Thread Miklos Szeredi
On Thu, Sep 10, 2020 at 2:28 AM Gurchetan Singh
 wrote:

> That sounds like an excellent plan !
>
> I will send out blob v3 (incorporating kraxel@'s feedback) once the topic 
> pull request (it seems Miklos will do this?) for the shm region patches has 
> been merged into drm-misc-next.

I split out the three patches into:

  git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#virtio-shm

Thanks,
Miklos
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 0/8] Convert the intel iommu driver to the dma-iommu api

2020-09-11 Thread Tom Murphy
On Wed, 9 Sep 2020 at 13:56, Tvrtko Ursulin
 wrote:
>
>
> On 09/09/2020 10:16, Tvrtko Ursulin wrote:
> > On 08/09/2020 23:43, Tom Murphy wrote:
> >> On Tue, 8 Sep 2020 at 16:56, Tvrtko Ursulin
> >>  wrote:
> >>> On 08/09/2020 16:44, Logan Gunthorpe wrote:
>  On 2020-09-08 9:28 a.m., Tvrtko Ursulin wrote:
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_scatterlist.h
> >> b/drivers/gpu/drm/i915/i915
> >> index b7b59328cb76..9367ac801f0c 100644
> >> --- a/drivers/gpu/drm/i915/i915_scatterlist.h
> >> +++ b/drivers/gpu/drm/i915/i915_scatterlist.h
> >> @@ -27,13 +27,19 @@ static __always_inline struct sgt_iter {
> >> } __sgt_iter(struct scatterlist *sgl, bool dma) {
> >>struct sgt_iter s = { .sgp = sgl };
> >>
> >> +   if (sgl && !sg_dma_len(s.sgp))
> >
> > I'd extend the condition to be, just to be safe:
> >   if (dma && sgl && !sg_dma_len(s.sgp))
> >
> 
>  Right, good catch, that's definitely necessary.
> 
> >> +   s.sgp = NULL;
> >> +
> >>if (s.sgp) {
> >>s.max = s.curr = s.sgp->offset;
> >> -   s.max += s.sgp->length;
> >> -   if (dma)
> >> +
> >> +   if (dma) {
> >> +   s.max += sg_dma_len(s.sgp);
> >>s.dma = sg_dma_address(s.sgp);
> >> -   else
> >> +   } else {
> >> +   s.max += s.sgp->length;
> >>s.pfn = page_to_pfn(sg_page(s.sgp));
> >> +   }
> >
> > Otherwise has this been tested or alternatively how to test it?
> > (How to
> > repro the issue.)
> 
>  It has not been tested. To test it, you need Tom's patch set without
>  the
>  last "DO NOT MERGE" patch:
> 
>  https://lkml.kernel.org/lkml/20200907070035.ga25...@infradead.org/T/
> >>>
> >>> Tom, do you have a branch somewhere I could pull from? (Just being lazy
> >>> about downloading a bunch of messages from the archives.)
> >>
> >> I don't unfortunately. I'm working locally with poor internet.
> >>
> >>>
> >>> What GPU is in your Lenovo x1 carbon 5th generation and what
> >>> graphical/desktop setup I need to repro?
> >>
> >>
> >> Is this enough info?:
> >>
> >> $ lspci -vnn | grep VGA -A 12
> >> 00:02.0 VGA compatible controller [0300]: Intel Corporation HD
> >> Graphics 620 [8086:5916] (rev 02) (prog-if 00 [VGA controller])
> >>  Subsystem: Lenovo ThinkPad X1 Carbon 5th Gen [17aa:224f]
> >>  Flags: bus master, fast devsel, latency 0, IRQ 148
> >>  Memory at eb00 (64-bit, non-prefetchable) [size=16M]
> >>  Memory at 6000 (64-bit, prefetchable) [size=256M]
> >>  I/O ports at e000 [size=64]
> >>  [virtual] Expansion ROM at 000c [disabled] [size=128K]
> >>  Capabilities: [40] Vendor Specific Information: Len=0c 
> >>  Capabilities: [70] Express Root Complex Integrated Endpoint, MSI 00
> >>  Capabilities: [ac] MSI: Enable+ Count=1/1 Maskable- 64bit-
> >>  Capabilities: [d0] Power Management version 2
> >>  Capabilities: [100] Process Address Space ID (PASID)
> >>  Capabilities: [200] Address Translation Service (ATS)
> >
> > Works for a start. What about the steps to repro? Any desktop
> > environment and it is just visual corruption, no hangs/stalls or such?
> >
> > I've submitted a series consisting of what I understood are the patches
> > needed to repro the issue to our automated CI here:
> >
> > https://patchwork.freedesktop.org/series/81489/
> >
> > So will see if it will catch something, or more targeted testing will be
> > required. Hopefully it does trip over in which case I can add the patch
> > suggested by Logan on top and see if that fixes it. Or I'll need to
> > write a new test case.
> >
> > If you could glance over my series to check I identified the patches
> > correctly it would be appreciated.
>
> Our CI was more than capable at catching the breakage so I've copied you
> on a patch (https://patchwork.freedesktop.org/series/81497/) which has a
> good potential to fix this. (Or improve the robustness of our sg walks,
> depends how you look at it.)
>
> Would you be able to test it in your environment by any chance? If it
> works I understand it unblocks your IOMMU work, right?

I tested your latest patch set ([PATCH 1/2] drm/i915: Fix DMA mapped
scatterlist walks) and it fixes the issue. great work!

>
> Regards,
>
> Tvrtko
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 -next] drm/amdkfd: Fix -Wunused-const-variable warning

2020-09-11 Thread YueHaibing
If KFD_SUPPORT_IOMMU_V2 is not set, gcc warns:

drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_device.c:121:37: warning: 
‘raven_device_info’ defined but not used [-Wunused-const-variable=]
 static const struct kfd_device_info raven_device_info = {
 ^

As Huang Rui suggested, Raven already has the fallback path,
so it should be out of IOMMU v2 flag.

Suggested-by: Huang Rui 
Signed-off-by: YueHaibing 
---
 drivers/gpu/drm/amd/amdkfd/kfd_device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 0e71a0543f98..e3fc6ed7b79c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -503,8 +503,8 @@ static const struct kfd_device_info 
*kfd_supported_devices[][2] = {
 #ifdef KFD_SUPPORT_IOMMU_V2
[CHIP_KAVERI] = {&kaveri_device_info, NULL},
[CHIP_CARRIZO] = {&carrizo_device_info, NULL},
-   [CHIP_RAVEN] = {&raven_device_info, NULL},
 #endif
+   [CHIP_RAVEN] = {&raven_device_info, NULL},
[CHIP_HAWAII] = {&hawaii_device_info, NULL},
[CHIP_TONGA] = {&tonga_device_info, NULL},
[CHIP_FIJI] = {&fiji_device_info, &fiji_vf_device_info},
-- 
2.17.1


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/3] arm64: dts: sc7180: add bus clock to mdp node for sc7180 target

2020-09-11 Thread Bjorn Andersson
On Thu 16 Jul 11:35 UTC 2020, Kalyan Thota wrote:

> From: Krishna Manikandan 
> 
> Move the bus clock to mdp device node,in order
> to facilitate bus band width scaling on sc7180
> target.
> 
> The parent device MDSS will not vote for bus bw,
> instead the vote will be triggered by mdp device
> node. Since a minimum vote is required to turn
> on bus clock, move the clock node to mdp device
> from where the votes are requested.
> 
> This patch has dependency on the below series
> https://patchwork.kernel.org/patch/11468783/
> 

Isn't this dependency on an old revision of patch 3/3 in this series?

Regardless, I don't see either the linked patch or patch 3 merged in
linux-next, so I presume I should not merge this?

Regards,
Bjorn

> Signed-off-by: Krishna Manikandan 
> ---
>  arch/arm64/boot/dts/qcom/sc7180.dtsi | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi 
> b/arch/arm64/boot/dts/qcom/sc7180.dtsi
> index 4f2c0d1..31fed6d 100644
> --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
> @@ -1510,10 +1510,9 @@
>   power-domains = <&dispcc MDSS_GDSC>;
>  
>   clocks = <&gcc GCC_DISP_AHB_CLK>,
> -  <&gcc GCC_DISP_HF_AXI_CLK>,
><&dispcc DISP_CC_MDSS_AHB_CLK>,
><&dispcc DISP_CC_MDSS_MDP_CLK>;
> - clock-names = "iface", "bus", "ahb", "core";
> + clock-names = "iface", "ahb", "core";
>  
>   assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>;
>   assigned-clock-rates = <3>;
> @@ -1539,12 +1538,13 @@
> <0 0x0aeb 0 0x2008>;
>   reg-names = "mdp", "vbif";
>  
> - clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
> + clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
> +  <&dispcc DISP_CC_MDSS_AHB_CLK>,
><&dispcc DISP_CC_MDSS_ROT_CLK>,
><&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
><&dispcc DISP_CC_MDSS_MDP_CLK>,
><&dispcc DISP_CC_MDSS_VSYNC_CLK>;
> - clock-names = "iface", "rot", "lut", "core",
> + clock-names = "bus", "iface", "rot", "lut", 
> "core",
> "vsync";
>   assigned-clocks = <&dispcc 
> DISP_CC_MDSS_MDP_CLK>,
> <&dispcc 
> DISP_CC_MDSS_VSYNC_CLK>;
> -- 
> 1.9.1
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] video: fbdev: sis: remove unneeded semicolon

2020-09-11 Thread Jason Yan
Eliminate the following coccicheck warning:

drivers/video/fbdev/sis/sis_accel.h:143:72-73: Unneeded semicolon
drivers/video/fbdev/sis/sis_accel.h:144:72-73: Unneeded semicolon
drivers/video/fbdev/sis/sis_accel.h:145:72-73: Unneeded semicolon
drivers/video/fbdev/sis/sis_accel.h:273:75-76: Unneeded semicolon
drivers/video/fbdev/sis/sis_accel.h:274:75-76: Unneeded semicolon
drivers/video/fbdev/sis/sis_accel.h:275:73-74: Unneeded semicolon
drivers/video/fbdev/sis/sis_accel.h:276:75-76: Unneeded semicolon

Reported-by: Hulk Robot 
Signed-off-by: Jason Yan 
---
 drivers/video/fbdev/sis/sis_accel.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/sis/sis_accel.h 
b/drivers/video/fbdev/sis/sis_accel.h
index c3dfd2a20cf9..98d209658662 100644
--- a/drivers/video/fbdev/sis/sis_accel.h
+++ b/drivers/video/fbdev/sis/sis_accel.h
@@ -140,9 +140,9 @@
 
 #define SiS300Idle \
   { \
-   while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
-   while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
-   while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+   while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){} \
+   while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){} \
+   while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){} \
CmdQueLen = MMIO_IN16(ivideo->mmio_vbase, 0x8240); \
   }
 /* (do three times, because 2D engine seems quite unsure about whether or not 
it's idle) */
@@ -270,10 +270,10 @@
 
 #define SiS310Idle \
   { \
-   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){}; \
-   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){}; \
-   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){}; \
-   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){}; \
+   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){} \
+   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){} \
+   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){} \
+   while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 
0x8000){} \
CmdQueLen = 0; \
   }
 
-- 
2.25.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC PATCH v2 17/17] WIP: drm/tegra: Implement new UAPI

2020-09-11 Thread Dmitry Osipenko
09.09.2020 11:36, Mikko Perttunen пишет:
...
>>
>> Does it make sense to have timeout in microseconds?
>>
> 
> Not sure, but better have it a bit more fine-grained rather than
> coarse-grained. This still gives a maximum timeout of 71 minutes so I
> don't think it has any negatives compared to milliseconds.

If there is no good reason to use microseconds right now, then should be
better to default to milliseconds, IMO. It shouldn't be a problem to
extend the IOCLT with a microseconds entry, if ever be needed.

{
__u32 timeout_ms;
...
__u32 timeout_us;
}

timeout = timeout_ms + 1000 * timeout_us;

There shouldn't be a need for a long timeouts, since a job that takes
over 100ms is probably too unpractical. It also should be possible to
detect a progressing job and then defer timeout in the driver. At least
this is what other drivers do, like etnaviv driver for example:

https://elixir.bootlin.com/linux/v5.9-rc4/source/drivers/gpu/drm/etnaviv/etnaviv_sched.c#L107
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: xlnx: remove defined but not used 'scaling_factors_666'

2020-09-11 Thread Jason Yan
This addresses the following gcc warning with "make W=1":

drivers/gpu/drm/xlnx/zynqmp_disp.c:245:18: warning:
‘scaling_factors_666’ defined but not used [-Wunused-const-variable=]
  245 | static const u32 scaling_factors_666[] = {
  |  ^~~

Reported-by: Hulk Robot 
Signed-off-by: Jason Yan 
---
 drivers/gpu/drm/xlnx/zynqmp_disp.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c 
b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index a455cfc1bee5..98bd48f13fd1 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -242,12 +242,6 @@ static const u32 scaling_factors_565[] = {
ZYNQMP_DISP_AV_BUF_5BIT_SF,
 };
 
-static const u32 scaling_factors_666[] = {
-   ZYNQMP_DISP_AV_BUF_6BIT_SF,
-   ZYNQMP_DISP_AV_BUF_6BIT_SF,
-   ZYNQMP_DISP_AV_BUF_6BIT_SF,
-};
-
 static const u32 scaling_factors_888[] = {
ZYNQMP_DISP_AV_BUF_8BIT_SF,
ZYNQMP_DISP_AV_BUF_8BIT_SF,
-- 
2.25.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] video: fbdev: fsl-diu-fb: remove unneeded variable 'res'

2020-09-11 Thread Jason Yan
Eliminate the following coccicheck warning:

drivers/video/fbdev/fsl-diu-fb.c:1428:5-8: Unneeded variable: "res".
Return "0" on line 1450

Reported-by: Hulk Robot 
Signed-off-by: Jason Yan 
---
 drivers/video/fbdev/fsl-diu-fb.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c
index a547c21c7e92..e332017c6af6 100644
--- a/drivers/video/fbdev/fsl-diu-fb.c
+++ b/drivers/video/fbdev/fsl-diu-fb.c
@@ -1425,7 +1425,6 @@ static int fsl_diu_open(struct fb_info *info, int user)
 static int fsl_diu_release(struct fb_info *info, int user)
 {
struct mfb_info *mfbi = info->par;
-   int res = 0;
 
spin_lock(&diu_lock);
mfbi->count--;
@@ -1447,7 +1446,7 @@ static int fsl_diu_release(struct fb_info *info, int user)
}
 
spin_unlock(&diu_lock);
-   return res;
+   return 0;
 }
 
 static const struct fb_ops fsl_diu_ops = {
-- 
2.25.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/i810: make i810_flush_queue() return void

2020-09-11 Thread Jason Yan
This function always return '0' and no callers use the return value. So
make it a void function.

This eliminates the following coccicheck warning:

drivers/gpu/drm/i810/i810_dma.c:860:8-11: Unneeded variable: "ret".
Return "0" on line 885

Reported-by: Hulk Robot 
Signed-off-by: Jason Yan 
---
 drivers/gpu/drm/i810/i810_dma.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 303c2d483c6e..88250860f8e4 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -853,11 +853,11 @@ static void i810_dma_quiescent(struct drm_device *dev)
i810_wait_ring(dev, dev_priv->ring.Size - 8);
 }
 
-static int i810_flush_queue(struct drm_device *dev)
+static void i810_flush_queue(struct drm_device *dev)
 {
drm_i810_private_t *dev_priv = dev->dev_private;
struct drm_device_dma *dma = dev->dma;
-   int i, ret = 0;
+   int i;
RING_LOCALS;
 
i810_kernel_lost_context(dev);
@@ -882,7 +882,7 @@ static int i810_flush_queue(struct drm_device *dev)
DRM_DEBUG("still on client\n");
}
 
-   return ret;
+   return;
 }
 
 /* Must be called with the lock held */
-- 
2.25.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/vc4: hdmi: Fix NULL vs IS_ERR() checks in vc5_hdmi_init_resources()

2020-09-11 Thread Maxime Ripard
On Thu, Sep 10, 2020 at 01:08:25PM +0300, Dan Carpenter wrote:
> The devm_ioremap() function never returns error pointers, it returns
> NULL.
> 
> Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers")
> Signed-off-by: Dan Carpenter 

Applied, thanks!
Maxime


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: DRM_TEGRA_SUBMIT_BUF_WRITE_RELOC

2020-09-11 Thread Dmitry Osipenko
09.09.2020 11:10, Mikko Perttunen пишет:
> On 9/9/20 2:45 AM, Dmitry Osipenko wrote:
>> 05.09.2020 13:34, Mikko Perttunen пишет:
>> ...
>>> +/* Submission */
>>> +
>>> +/** Patch address of the specified mapping in the submitted gather. */
>>> +#define DRM_TEGRA_SUBMIT_BUF_WRITE_RELOC    (1<<0)
>>
>> Shouldn't the kernel driver be aware about what relocations need to be
>> patched? Could you please explain the purpose of this flag?
>>
> 
> Sure, the kernel knows if it returned the IOVA to the user or not, so we
> could remove this flag and determine it implicitly. I don't think there
> is much harm in it though; if we have the flag an application can decide
> to ignore the iova field and just pass WRITE_RELOC always, and it's not
> really any extra code on kernel side.

Sounds like there is no real practical use for this flag other than for
testing purposes, correct?
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC PATCH v2 17/17] WIP: drm/tegra: Implement new UAPI

2020-09-11 Thread Dmitry Osipenko
09.09.2020 11:19, Mikko Perttunen пишет:
...
>>> +    if (!job_data->used_mappings)
>>> +    return -ENOMEM;
>>> +
>>> +    for (i = 0; i < args->num_bufs; i++) {
>>> +    copy_err = copy_from_user(&buf, user_bufs_ptr+i, sizeof(buf));
>>
>> Whole array always should be copied at once. Please keep in mind that
>> each copy_from_user() has a cpu-time cost, there should maximum up to 2
>> copyings per job.
>>
> 
> OK. BTW, do you have some reference/numbers for this or is it based on
> grate-driver experience?

I had numbers about 2 years ago while was profiling job submission
latency using host1x-tests and for a simple jobs there was a visible
difference caused by each copy_from_user(), kmalloc() and having
firewall functions uninlined.

Of course it wasn't critical, but it's also not difficult to optimize
such things.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] fbcon: Fix user font detection test at fbcon_resize().

2020-09-11 Thread Tetsuo Handa
syzbot is reporting OOB read at fbcon_resize() [1], for
commit 39b3cffb8cf31117 ("fbcon: prevent user font height or width change
 from causing potential out-of-bounds access") is by error using
registered_fb[con2fb_map[vc->vc_num]]->fbcon_par->p->userfont (which was
set to non-zero) instead of fb_display[vc->vc_num].userfont (which remains
zero for that display).

We could remove tricky userfont flag [2], for we can determine it by
comparing address of the font data and addresses of built-in font data.
But since that commit is failing to fix the original OOB read [3], this
patch keeps the change minimal in case we decide to revert altogether.

[1] 
https://syzkaller.appspot.com/bug?id=ebcbbb6576958a496500fee9cf7aa83ea00b5920
[2] https://syzkaller.appspot.com/text?tag=Patch&x=1403085390
[3] 
https://syzkaller.appspot.com/bug?id=6fba8c186d97cf1011ab17660e633b1cc4e080c9

Reported-by: syzbot 
Signed-off-by: Tetsuo Handa 
Fixes: 39b3cffb8cf31117 ("fbcon: prevent user font height or width change from 
causing potential out-of-bounds access")
Cc: George Kennedy 
---
 drivers/video/fbdev/core/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 66167830fefd..dae7ae7f225a 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -2203,7 +2203,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int 
width,
struct fb_var_screeninfo var = info->var;
int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
 
-   if (ops->p && ops->p->userfont && FNTSIZE(vc->vc_font.data)) {
+   if (p->userfont && FNTSIZE(vc->vc_font.data)) {
int size;
int pitch = PITCH(vc->vc_font.width);
 
-- 
2.18.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PULL] drm-misc-next

2020-09-11 Thread Maxime Ripard
Hi Dave, Daniel,

Here is this week PR for drm-misc-next

Thanks!
Maxime

drm-misc-next-2020-09-10:
drm-misc-next for 5.10:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
  - fbdev: Various cleanups, conversion to PM helpers
  - ttm: More reworks

Driver Changes:
  - imx: Support for the i.MX8MQ DCSS
  - vc4: Support for the BCM2711/RPi4
  - panel: Support DSI for s6e63m0
The following changes since commit bfacb84993eb173c0ab53ca4dd6180f76f4dc176:

  drm: virtio: fix kconfig dependency warning (2020-08-31 08:55:02 +0200)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2020-09-10

for you to fetch changes up to 13138ab2dacd0076a93f74b49ea8fe806e49c3f5:

  drm/panel: s6e63m0: Add missing MODULE_LICENSE (2020-09-10 08:53:06 +0200)


drm-misc-next for 5.10:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
  - fbdev: Various cleanups, conversion to PM helpers
  - ttm: More reworks

Driver Changes:
  - imx: Support for the i.MX8MQ DCSS
  - vc4: Support for the BCM2711/RPi4
  - panel: Support DSI for s6e63m0


Alex Dewar (1):
  video: fbdev: sstfb: replace spurious snprintf() with sprintf()

Angelo Ribeiro (1):
  drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs

Antonio Borneo (3):
  drm/bridge/synopsys: dsi: allow LP commands in video mode
  drm/bridge/synopsys: dsi: allow sending longer LP commands
  drm/bridge/synopsys: dsi: add support for non-continuous HS clock

Bernard Zhao (1):
  gpu/drm: cleanup coding style a bit

Bilal Wasim (1):
  docs: fb: Correcting the location of FRAMEBUFFER_CONSOLE option.

Christian König (5):
  drm/ttm: make sure that we always zero init mem.bus v2
  drm/nouveau: move io_reserve_lru handling into the driver v5
  drm/ttm: remove io_reserve_lru handling v3
  drm/qxl: don't touch mem.bus.offset
  drm/ttm: merge offset and base in ttm_bus_placement

Colin Ian King (2):
  video: fbdev: vga16fb: fix setting of pixclock because a pass-by-value 
error
  omapfb: fix spelling mistake "propert" -> "property"

Daniel Vetter (1):
  drm/managed: Cleanup of unused functions and polishing docs

Dave Airlie (14):
  drm/ttm: remove bdev from ttm_tt
  drm/ttm: introduce ttm_bo_move_null
  drm/ttm: add optional bind/unbind via driver.
  drm/qxl: move bind/unbind/destroy to the driver function table.
  drm/ttm/agp: export bind/unbind/destroy for drivers to use.
  drm/radeon/ttm: move to driver binding/destroy functions. (v2)
  drm/nouveau/ttm: use driver bind/unbind/destroy functions.
  drm/vmwgfx: move to driver binding functions
  drm/amdgpu/ttm: move to driver backend binding funcs
  drm/gem_vram/ttm: move to driver backend destroy function.
  drm/ttm/agp: drop back end bindings from agp
  drm/ttm: get rid of agp specific populate/unpopulate paths.
  drm/ttm/agp: remove bdev from agp helpers
  drm/ttm: drop the tt backend function paths.

Dave Stevenson (7):
  drm/vc4: Add support for the BCM2711 HVS5
  drm/vc4: plane: Change LBM alignment constraint on LBM
  drm/vc4: plane: Optimize the LBM allocation size
  drm/vc4: hdmi: Use reg-names to retrieve the HDMI audio registers
  drm/vc4: hdmi: Reset audio infoframe on encoder_enable if previously 
streaming
  drm/vc4: hdmi: Set the b-frame marker to the match ALSA's default.
  drm/vc4: hdmi: Add audio-related callbacks

Dinghao Liu (2):
  drm/crc-debugfs: Fix memleak in crc_control_write
  video: fbdev: radeon: Fix memleak in radeonfb_pci_register

Doug Horn (1):
  Fix use after free in get_capset_info callback.

Evgeny Novikov (1):
  fbdev: sm712fb: handle ioremap() errors in probe

George Kennedy (1):
  fbmem: add margin check to fb_check_caps()

Gerd Hoffmann (3):
  drm/virtio: fix unblank
  drm/virtio: drop virtio_gpu_output->enabled
  drm: allow limiting the scatter list size.

Gurchetan Singh (2):
  drm/virtio: fix uninitialized variable
  drm/virtio: report uuid in debugfs

Hoegeun Kwon (1):
  drm/vc4: hdmi: Add pixel BVB clock control

Jason Yan (2):
  video: fbdev: kyro: remove set but not used 'ulBestVCO'
  video: fbdev: kyro: remove set but not used 'ulCoreClock'

Joe Perches (1):
  video: fbdev: tgafb: Avoid comma separated statements

Kristian H. Kristensen (1):
  udmabuf: Add missing compact_ioctl

Laurentiu Palcu (5):
  drm/imx: compile imx directory by default
  drm/imx: Add initial support for DCSS on iMX8MQ
  drm/imx/dcss: use drm_bridge_connector API
  MAINTAINERS: Add entry for i.MX 8MQ DCSS driver
  dt-bindings: display: imx: add bindings for DCSS

Linus Walleij (6):
  drm/panel: s6e63m0: Break out SPI transport
  drm/panel: s6e63m0: Add DSI transport
  drm/panel: s6e63m0: Add read

Re: [PATCH] drm/vc4: hdmi: Fix off by ones in vc4_hdmi_read/write()

2020-09-11 Thread Maxime Ripard
On Thu, Sep 10, 2020 at 01:07:48PM +0300, Dan Carpenter wrote:
> The variant->registers[] has ->num_registers elements so the >
> comparison needs to be changes to >= to prevent an out of bounds
> access.
> 
> Fixes: 311e305fdb4e ("drm/vc4: hdmi: Implement a register layout abstraction")
> Signed-off-by: Dan Carpenter 

Applied, thanks!
Maxime


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: rcar-du: add missing put_device() call in rcar_du_vsp_init()

2020-09-11 Thread Yu Kuai
if of_find_device_by_node() succeed, rcar_du_vsp_init() doesn't have
a corresponding put_device(). Thus add a jump target to fix the exception
handling for this function implementation.

Fixes: 6d62ef3ac30b ("drm: rcar-du: Expose the VSP1 compositor through KMS 
planes")
Signed-off-by: Yu Kuai 
---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index f1a81c9b184d..172ee3f3b21c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -352,14 +352,16 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct 
device_node *np,
 
/* Find the VSP device and initialize it. */
pdev = of_find_device_by_node(np);
-   if (!pdev)
-   return -ENXIO;
+   if (!pdev) {
+   ret = -ENXIO;
+   goto put_device;
+   }
 
vsp->vsp = &pdev->dev;
 
ret = vsp1_du_init(vsp->vsp);
if (ret < 0)
-   return ret;
+   goto put_device;
 
 /*
  * The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
@@ -369,8 +371,10 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct 
device_node *np,
 
vsp->planes = devm_kcalloc(rcdu->dev, vsp->num_planes,
   sizeof(*vsp->planes), GFP_KERNEL);
-   if (!vsp->planes)
-   return -ENOMEM;
+   if (!vsp->planes) {
+   ret = -ENOMEM;
+   goto put_device;
+   }
 
for (i = 0; i < vsp->num_planes; ++i) {
enum drm_plane_type type = i < num_crtcs
@@ -387,7 +391,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct 
device_node *np,
   ARRAY_SIZE(rcar_du_vsp_formats),
   NULL, type, NULL);
if (ret < 0)
-   return ret;
+   goto put_device;
 
drm_plane_helper_add(&plane->plane,
 &rcar_du_vsp_plane_helper_funcs);
@@ -403,4 +407,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct 
device_node *np,
}
 
return 0;
+put_device:
+   put_device(&pdev->dev);
+   return ret;
 }
-- 
2.25.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC PATCH v2 00/17] Host1x/TegraDRM UAPI

2020-09-11 Thread Dmitry Osipenko
09.09.2020 11:40, Mikko Perttunen пишет:
> On 9/9/20 2:36 AM, Dmitry Osipenko wrote:
>> 05.09.2020 13:34, Mikko Perttunen пишет:
>>> Hi all,
>>>
>>> here's a second revision of the Host1x/TegraDRM UAPI proposal,
>>> hopefully with most issues from v1 resolved, and also with
>>> an implementation. There are still open issues with the
>>> implementation:
>> Could you please clarify the current status of the DMA heaps. Are we
>> still going to use DMA heaps?
>>
> 
> Sorry, should have mentioned the status in the cover letter. I sent an
> email to dri-devel about how DMA heaps should be used -- I believe the
> conclusion was that it's not entirely clear, but dma-bufs should only be
> used for buffers shared between engines. So for the time being, we
> should still implement GEM for intra-TegraDRM buffers. There seems to be
> some planning ongoing to see if the different subsystem allocators can
> be unified (see dma-buf heaps talk from linux plumbers conference), but
> for now we should go for GEM.

Thanks!
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/mm: prevent a potential null-pointer dereference

2020-09-11 Thread Jing Xiangfeng



On 2020/9/10 16:58, Christian König wrote:

Am 10.09.20 um 04:38 schrieb Jing Xiangfeng:

The macro 'DECLARE_NEXT_HOLE_ADDR' may hit a potential null-pointer
dereference. So use 'entry' after checking it.


I don't see a potential null-pointer dereference here.

Where should that be?


In current code,the "entry" pointer is checked after entry->rb_hole_addr.
Thanks


Christian.



Fixes: 5fad79fd66ff ("drm/mm: cleanup and improve next_hole_*_addr()")
Signed-off-by: Jing Xiangfeng 
---
  drivers/gpu/drm/drm_mm.c | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index a4a04d246135..6fcf70f71962 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -392,11 +392,14 @@ first_hole(struct drm_mm *mm,
  #define DECLARE_NEXT_HOLE_ADDR(name, first, last)\
  static struct drm_mm_node *name(struct drm_mm_node *entry, u64
size)\
  {\
-struct rb_node *parent, *node = &entry->rb_hole_addr;\
+struct rb_node *parent, *node;\
  \
-if (!entry || RB_EMPTY_NODE(node))\
+if (!entry)\
  return NULL;\
  \
+node = &entry->rb_hole_addr;\
+if (RB_EMPTY_NODE(node))\
+return NULL;\
  if (usable_hole_addr(node->first, size)) {\
  node = node->first;\
  while (usable_hole_addr(node->last, size))\


.


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


  1   2   >