Re: [PATCH v4] drm/omap: plane zpos/zorder management improvements
On 08/01/18 13:07, Laurent Pinchart wrote: >> Yes, this is a subject I have complained a few times: DRM keeping the >> state. I think that will be a problem with many other properties too. An >> app could change a platform specific property, which no other app is >> aware of, and after that no other app would work correctly. >> >> I believe each app has to know all the DRM properties and set them >> accordingly on startup, and/or each app has to reset the properties when >> exiting. Unfortunately I think both cases are not realistic. > > I agree with you. I'd prefer restoring a sane default state on last close. Is > there any reason not to do so ? I have to say I can't remember, but it probably was about fbdev, legacy, on PCs you don't usually encounter problems related to this, or things like that. -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 3/3] drm/sun4i: hdmi: Add missing rate halving check in sun4i_tmds_determine_rate
It was only checking the divider when determing the closest match if it could not match the requested rate exactly. For a projector connected to an Olimex A20-OLinuXino-LIME using HDMI with a native resolution of 1280x800 and pixel clock of 83.5 MHz, this resulted in 1280x800 mode not being available and the following in dmesg when the kernel is booted with drm.debug=0x3e: [drm:drm_mode_debug_printmodeline] Modeline 37:"1280x800" 60 83500 1280 1352 1480 1680 800 810 816 831 0x48 0x5 [drm:drm_mode_prune_invalid] Not using 1280x800 mode: NOCLOCK Fixes: 9c5681011a0c ("drm/sun4i: Add HDMI support") Signed-off-by: Jonathan Liu --- drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c index 88eeeaf34638..3ecffa52c814 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c @@ -102,9 +102,12 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw, goto out; } - if (!best_parent || abs(rate - rounded / i) < - abs(rate - best_parent / best_div)) { + if (!best_parent || + abs(rate - rounded / i / j) < + abs(rate - best_parent / best_half / + best_div)) { best_parent = rounded; + best_half = i; best_div = j; } } -- 2.15.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 1/3] drm/sun4i: hdmi: Check for unset best_parent in sun4i_tmds_determine_rate
It is possible that if there is no exact rate match and "rounded = clk_hw_round_rate(parent, ideal)" gives high enough values (e.g. if rounded is 2 * ideal) that the condition "abs(rate - rounded / i) < abs(rate - best_parent / best_div)" is never met and best_parent is never set. This results in req->rate and req->best_parent_rate being assigned 0. To avoid this, we set best_parent to the first calculated rate if it is unset. The sun4i_tmds_calc_divider function already has a similar check. Fixes: 9c5681011a0c ("drm/sun4i: Add HDMI support") Signed-off-by: Jonathan Liu --- drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c index dc332ea56f6c..4d235e5ea31c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c @@ -102,7 +102,7 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw, goto out; } - if (abs(rate - rounded / i) < + if (!best_parent || abs(rate - rounded / i) < abs(rate - best_parent / best_div)) { best_parent = rounded; best_div = i; -- 2.15.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL] drm/tegra: Changes for v4.16-rc1
On 08.01.2018 15:39, Thierry Reding wrote: > On Mon, Jan 08, 2018 at 08:42:50AM +0100, Thierry Reding wrote: >> On Fri, Jan 05, 2018 at 05:58:17PM +0300, Dmitry Osipenko wrote: >>> On 05.01.2018 17:17, Thierry Reding wrote: Hi Dave, The following changes since commit 9428088c90b6f7d5edd2a1b0d742c75339b36f6e: drm/qxl: reapply cursor after resetting primary (2017-12-08 13:37:02 +1000) are available in the Git repository at: git://anongit.freedesktop.org/tegra/linux tags/drm/tegra/for-4.16-rc1 for you to fetch changes up to ebae8d07435ae91314f4a28d69b530d09c625815: drm/tegra: dc: Implement legacy blending (2017-12-21 14:55:55 +0100) Thanks, Thierry drm/tegra: Changes for v4.16-rc1 The bulk of these changes are preparation work and addition of support for Tegra186. Currently only HDMI output (the primary output on Jetson TX2) is supported, but the hardware is also capable of doing DSI and DisplayPort. Tegra DRM now also uses the atomic commit helpers instead of the open- coded variant that was only doing half its job. As a bit of a byproduct of the Tegra186 support the driver also gained HDMI 2.0 as well as zpos property support. Along the way there are also a few patches to clean up a few things and fix minor issues. Arnd Bergmann (2): drm/tegra: Mark Tegra186 display hub PM functions __maybe_unused drm/tegra: Fix non-debugfs builds Dmitry Osipenko (3): drm/tegra: dc: Link DC1 to DC0 on Tegra20 drm/tegra: gem: Correct iommu_map_sg() error checking drm/tegra: Correct timeout in tegra_syncpt_wait Thierry Reding (43): drm/fourcc: Fix fourcc_mod_code() definition drm/tegra: Sanitize format modifiers gpu: host1x: Rewrite conditional for better readability gpu: host1x: Cleanup on initialization failure dt-bindings: display: tegra: Update SOR for Tegra186 drm/tegra: dc: Move register definitions into a table drm/tegra: dsi: Move register definitions into a table drm/tegra: hdmi: Move register definitions into a table drm/tegra: sor: Move register definitions into a table drm/tegra: dc: Reshuffle some code drm/tegra: dc: Register debugfs in ->late_register() drm/tegra: dsi: Register debugfs in ->late_register() drm/tegra: hdmi: Register debugfs in ->late_register() drm/tegra: sor: Root debugfs files at the connector drm/tegra: sor: Register debugfs in ->late_register() drm/tegra: Do not wrap lines unnecessarily drm/tegra: vic: Properly align arguments drm/tegra: dc: Support background color drm/tegra: Use atomic commit helpers drm/tegra: Remove custom page-flip handler drm/tegra: dc: Remove tegra_primary_plane_destroy() drm/tegra: dc: Remove duplicate plane funcs drm/tegra: dc: Remove tegra_overlay_plane_destroy() drm/tegra: dc: Remove duplicate plane funcs drm/tegra: dc: Move state definition to header drm/tegra: Move common plane code to separate file drm/tegra: Add Tegra186 display hub support drm/tegra: dc: Add Tegra186 support drm/tegra: Support ARGB and ABGR formats drm/tegra: sor: Parameterize register offsets drm/tegra: sor: Add Tegra186 support drm/tegra: sor: Support HDMI 2.0 modes drm/tegra: dpaux: Implement runtime PM drm/tegra: dpaux: Add Tegra186 support drm/tegra: fb: Force alpha formats drm/tegra: dc: Support more formats drm/tegra: dc: Use direct offset to plane registers drm/tegra: dc: Remove redundant spinlock drm/tegra: Implement zpos property gpu: host1x: Use IOMMU groups drm/tegra: Use IOMMU groups drm/tegra: dpaux: Keep reset defaults for hybrid pad parameters >>> >>> drm/tegra: dc: Implement legacy blending >>> >>> Please hold on this patch. First of all it doesn't work correctly, see my >>> last >>> reply to the patch. Secondly, it introduces bug that breaks YUV plane. >> >> I thought we had already concluded that this version doesn't cause any >> regressions. And since this is new functionality I'm not too worried if >> it doesn't work in all cases, we've got plenty of time to fix those up. >> >> As for the YUV plane bug, can you point me at a test case, or describe >> what exactly you're trying to do so that I can reproduce and fix it? >> >> I'd like to make forward progress on this rather than hold back on >> patches out of fear that
Re: [PATCH] drm/etnaviv: don't fail to build on arches without PHYS_OFFSET
It seems wrong to define PHYS_OFFSET here in a gpu driver. Is there an actual ARC system using vivante? The bit of code that uses PHYS_OFFSET looks pretty ARM specific. If not, then at least maybe +#if !define (PHYS_OFFSET) && defined (COMPILE_TEST) +#define PHY_OFFSET 0 +#endif would be more appropriate? Maybe the use of PHYS_OFFSET should be moved into an inline in a header where it can be defined differently for other arches On Sun, Jan 7, 2018 at 7:56 AM, Lucas Stach wrote: > Some architecture ports like ARC don't provide the PHYS_OFFSET symbol. > Define it to 0 in that case, which is the most conservative default in > the usage context of the etnaviv driver. > > Signed-off-by: Lucas Stach > --- > drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > index 935d99be748e..febbd1e5bbc7 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > @@ -31,6 +31,10 @@ > #include "state_hi.xml.h" > #include "cmdstream.xml.h" > > +#ifndef PHYS_OFFSET > +#define PHYS_OFFSET 0 > +#endif > + > static const struct platform_device_id gpu_ids[] = { > { .name = "etnaviv-gpu,2d" }, > { }, > -- > 2.11.0 > > ___ > etnaviv mailing list > etna...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/etnaviv > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL] drm/tegra: Changes for v4.16-rc1
On 08.01.2018 18:47, Thierry Reding wrote: > On Mon, Jan 08, 2018 at 04:47:32PM +0300, Dmitry Osipenko wrote: >> On 08.01.2018 10:42, Thierry Reding wrote: >>> On Fri, Jan 05, 2018 at 05:58:17PM +0300, Dmitry Osipenko wrote: On 05.01.2018 17:17, Thierry Reding wrote: > Hi Dave, > > The following changes since commit > 9428088c90b6f7d5edd2a1b0d742c75339b36f6e: > > drm/qxl: reapply cursor after resetting primary (2017-12-08 13:37:02 > +1000) > > are available in the Git repository at: > > git://anongit.freedesktop.org/tegra/linux tags/drm/tegra/for-4.16-rc1 > > for you to fetch changes up to ebae8d07435ae91314f4a28d69b530d09c625815: > > drm/tegra: dc: Implement legacy blending (2017-12-21 14:55:55 +0100) > > Thanks, > Thierry > > > drm/tegra: Changes for v4.16-rc1 > > The bulk of these changes are preparation work and addition of support > for Tegra186. Currently only HDMI output (the primary output on Jetson > TX2) is supported, but the hardware is also capable of doing DSI and > DisplayPort. > > Tegra DRM now also uses the atomic commit helpers instead of the open- > coded variant that was only doing half its job. As a bit of a byproduct > of the Tegra186 support the driver also gained HDMI 2.0 as well as zpos > property support. > > Along the way there are also a few patches to clean up a few things and > fix minor issues. > > > Arnd Bergmann (2): > drm/tegra: Mark Tegra186 display hub PM functions __maybe_unused > drm/tegra: Fix non-debugfs builds > > Dmitry Osipenko (3): > drm/tegra: dc: Link DC1 to DC0 on Tegra20 > drm/tegra: gem: Correct iommu_map_sg() error checking > drm/tegra: Correct timeout in tegra_syncpt_wait > > Thierry Reding (43): > drm/fourcc: Fix fourcc_mod_code() definition > drm/tegra: Sanitize format modifiers > gpu: host1x: Rewrite conditional for better readability > gpu: host1x: Cleanup on initialization failure > dt-bindings: display: tegra: Update SOR for Tegra186 > drm/tegra: dc: Move register definitions into a table > drm/tegra: dsi: Move register definitions into a table > drm/tegra: hdmi: Move register definitions into a table > drm/tegra: sor: Move register definitions into a table > drm/tegra: dc: Reshuffle some code > drm/tegra: dc: Register debugfs in ->late_register() > drm/tegra: dsi: Register debugfs in ->late_register() > drm/tegra: hdmi: Register debugfs in ->late_register() > drm/tegra: sor: Root debugfs files at the connector > drm/tegra: sor: Register debugfs in ->late_register() > drm/tegra: Do not wrap lines unnecessarily > drm/tegra: vic: Properly align arguments > drm/tegra: dc: Support background color > drm/tegra: Use atomic commit helpers > drm/tegra: Remove custom page-flip handler > drm/tegra: dc: Remove tegra_primary_plane_destroy() > drm/tegra: dc: Remove duplicate plane funcs > drm/tegra: dc: Remove tegra_overlay_plane_destroy() > drm/tegra: dc: Remove duplicate plane funcs > drm/tegra: dc: Move state definition to header > drm/tegra: Move common plane code to separate file > drm/tegra: Add Tegra186 display hub support > drm/tegra: dc: Add Tegra186 support > drm/tegra: Support ARGB and ABGR formats > drm/tegra: sor: Parameterize register offsets > drm/tegra: sor: Add Tegra186 support > drm/tegra: sor: Support HDMI 2.0 modes > drm/tegra: dpaux: Implement runtime PM > drm/tegra: dpaux: Add Tegra186 support > drm/tegra: fb: Force alpha formats > drm/tegra: dc: Support more formats > drm/tegra: dc: Use direct offset to plane registers > drm/tegra: dc: Remove redundant spinlock > drm/tegra: Implement zpos property > gpu: host1x: Use IOMMU groups > drm/tegra: Use IOMMU groups > drm/tegra: dpaux: Keep reset defaults for hybrid pad parameters > drm/tegra: dc: Implement legacy blending Please hold on this patch. First of all it doesn't work correctly, see my last reply to the patch. Secondly, it introduces bug that breaks YUV plane. >>> >>> I thought we had already concluded that this version doesn't cause any >>> regressions. And since this is new functionality I'm not too worried if >>> it doesn't work in all cases, we've got plenty of time to fix those up. >> >> My expectation was that you'll update the patch. I'm not sure why you'd want >> to >> go with s
Re: [GIT PULL] drm/tegra: Changes for v4.16-rc1
On 08.01.2018 10:42, Thierry Reding wrote: > On Fri, Jan 05, 2018 at 05:58:17PM +0300, Dmitry Osipenko wrote: >> On 05.01.2018 17:17, Thierry Reding wrote: >>> Hi Dave, >>> >>> The following changes since commit 9428088c90b6f7d5edd2a1b0d742c75339b36f6e: >>> >>> drm/qxl: reapply cursor after resetting primary (2017-12-08 13:37:02 >>> +1000) >>> >>> are available in the Git repository at: >>> >>> git://anongit.freedesktop.org/tegra/linux tags/drm/tegra/for-4.16-rc1 >>> >>> for you to fetch changes up to ebae8d07435ae91314f4a28d69b530d09c625815: >>> >>> drm/tegra: dc: Implement legacy blending (2017-12-21 14:55:55 +0100) >>> >>> Thanks, >>> Thierry >>> >>> >>> drm/tegra: Changes for v4.16-rc1 >>> >>> The bulk of these changes are preparation work and addition of support >>> for Tegra186. Currently only HDMI output (the primary output on Jetson >>> TX2) is supported, but the hardware is also capable of doing DSI and >>> DisplayPort. >>> >>> Tegra DRM now also uses the atomic commit helpers instead of the open- >>> coded variant that was only doing half its job. As a bit of a byproduct >>> of the Tegra186 support the driver also gained HDMI 2.0 as well as zpos >>> property support. >>> >>> Along the way there are also a few patches to clean up a few things and >>> fix minor issues. >>> >>> >>> Arnd Bergmann (2): >>> drm/tegra: Mark Tegra186 display hub PM functions __maybe_unused >>> drm/tegra: Fix non-debugfs builds >>> >>> Dmitry Osipenko (3): >>> drm/tegra: dc: Link DC1 to DC0 on Tegra20 >>> drm/tegra: gem: Correct iommu_map_sg() error checking >>> drm/tegra: Correct timeout in tegra_syncpt_wait >>> >>> Thierry Reding (43): >>> drm/fourcc: Fix fourcc_mod_code() definition >>> drm/tegra: Sanitize format modifiers >>> gpu: host1x: Rewrite conditional for better readability >>> gpu: host1x: Cleanup on initialization failure >>> dt-bindings: display: tegra: Update SOR for Tegra186 >>> drm/tegra: dc: Move register definitions into a table >>> drm/tegra: dsi: Move register definitions into a table >>> drm/tegra: hdmi: Move register definitions into a table >>> drm/tegra: sor: Move register definitions into a table >>> drm/tegra: dc: Reshuffle some code >>> drm/tegra: dc: Register debugfs in ->late_register() >>> drm/tegra: dsi: Register debugfs in ->late_register() >>> drm/tegra: hdmi: Register debugfs in ->late_register() >>> drm/tegra: sor: Root debugfs files at the connector >>> drm/tegra: sor: Register debugfs in ->late_register() >>> drm/tegra: Do not wrap lines unnecessarily >>> drm/tegra: vic: Properly align arguments >>> drm/tegra: dc: Support background color >>> drm/tegra: Use atomic commit helpers >>> drm/tegra: Remove custom page-flip handler >>> drm/tegra: dc: Remove tegra_primary_plane_destroy() >>> drm/tegra: dc: Remove duplicate plane funcs >>> drm/tegra: dc: Remove tegra_overlay_plane_destroy() >>> drm/tegra: dc: Remove duplicate plane funcs >>> drm/tegra: dc: Move state definition to header >>> drm/tegra: Move common plane code to separate file >>> drm/tegra: Add Tegra186 display hub support >>> drm/tegra: dc: Add Tegra186 support >>> drm/tegra: Support ARGB and ABGR formats >>> drm/tegra: sor: Parameterize register offsets >>> drm/tegra: sor: Add Tegra186 support >>> drm/tegra: sor: Support HDMI 2.0 modes >>> drm/tegra: dpaux: Implement runtime PM >>> drm/tegra: dpaux: Add Tegra186 support >>> drm/tegra: fb: Force alpha formats >>> drm/tegra: dc: Support more formats >>> drm/tegra: dc: Use direct offset to plane registers >>> drm/tegra: dc: Remove redundant spinlock >>> drm/tegra: Implement zpos property >>> gpu: host1x: Use IOMMU groups >>> drm/tegra: Use IOMMU groups >>> drm/tegra: dpaux: Keep reset defaults for hybrid pad parameters >> >> >>> drm/tegra: dc: Implement legacy blending >> >> Please hold on this patch. First of all it doesn't work correctly, see my >> last >> reply to the patch. Secondly, it introduces bug that breaks YUV plane. > > I thought we had already concluded that this version doesn't cause any > regressions. And since this is new functionality I'm not too worried if > it doesn't work in all cases, we've got plenty of time to fix those up. My expectation was that you'll update the patch. I'm not sure why you'd want to go with something half-working while there is already a version of the patch that works correctly (or at least better), but of course it's up to you to decide. If you'll decide to change your mind, feel free to cherry-pick and squash the patch-fix [0] which also contains the fix for the YUV and adds missed ARGB format. > As for the
[PATCH v3 2/3] drm/sun4i: hdmi: Fix incorrect assignment in sun4i_tmds_determine_rate
best_div is set to i which corresponds to rate halving when it should be set to j which corresponds to the divider. Fixes: 9c5681011a0c ("drm/sun4i: Add HDMI support") Signed-off-by: Jonathan Liu --- drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c index 4d235e5ea31c..88eeeaf34638 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c @@ -105,7 +105,7 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw, if (!best_parent || abs(rate - rounded / i) < abs(rate - best_parent / best_div)) { best_parent = rounded; - best_div = i; + best_div = j; } } } -- 2.15.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL] drm/tegra: Changes for v4.16-rc1
On 08.01.2018 18:49, Thierry Reding wrote: > On Mon, Jan 08, 2018 at 04:47:42PM +0300, Dmitry Osipenko wrote: >> On 08.01.2018 15:39, Thierry Reding wrote: >>> On Mon, Jan 08, 2018 at 08:42:50AM +0100, Thierry Reding wrote: On Fri, Jan 05, 2018 at 05:58:17PM +0300, Dmitry Osipenko wrote: > On 05.01.2018 17:17, Thierry Reding wrote: >> Hi Dave, >> >> The following changes since commit >> 9428088c90b6f7d5edd2a1b0d742c75339b36f6e: >> >> drm/qxl: reapply cursor after resetting primary (2017-12-08 13:37:02 >> +1000) >> >> are available in the Git repository at: >> >> git://anongit.freedesktop.org/tegra/linux tags/drm/tegra/for-4.16-rc1 >> >> for you to fetch changes up to ebae8d07435ae91314f4a28d69b530d09c625815: >> >> drm/tegra: dc: Implement legacy blending (2017-12-21 14:55:55 +0100) >> >> Thanks, >> Thierry >> >> >> drm/tegra: Changes for v4.16-rc1 >> >> The bulk of these changes are preparation work and addition of support >> for Tegra186. Currently only HDMI output (the primary output on Jetson >> TX2) is supported, but the hardware is also capable of doing DSI and >> DisplayPort. >> >> Tegra DRM now also uses the atomic commit helpers instead of the open- >> coded variant that was only doing half its job. As a bit of a byproduct >> of the Tegra186 support the driver also gained HDMI 2.0 as well as zpos >> property support. >> >> Along the way there are also a few patches to clean up a few things and >> fix minor issues. >> >> >> Arnd Bergmann (2): >> drm/tegra: Mark Tegra186 display hub PM functions __maybe_unused >> drm/tegra: Fix non-debugfs builds >> >> Dmitry Osipenko (3): >> drm/tegra: dc: Link DC1 to DC0 on Tegra20 >> drm/tegra: gem: Correct iommu_map_sg() error checking >> drm/tegra: Correct timeout in tegra_syncpt_wait >> >> Thierry Reding (43): >> drm/fourcc: Fix fourcc_mod_code() definition >> drm/tegra: Sanitize format modifiers >> gpu: host1x: Rewrite conditional for better readability >> gpu: host1x: Cleanup on initialization failure >> dt-bindings: display: tegra: Update SOR for Tegra186 >> drm/tegra: dc: Move register definitions into a table >> drm/tegra: dsi: Move register definitions into a table >> drm/tegra: hdmi: Move register definitions into a table >> drm/tegra: sor: Move register definitions into a table >> drm/tegra: dc: Reshuffle some code >> drm/tegra: dc: Register debugfs in ->late_register() >> drm/tegra: dsi: Register debugfs in ->late_register() >> drm/tegra: hdmi: Register debugfs in ->late_register() >> drm/tegra: sor: Root debugfs files at the connector >> drm/tegra: sor: Register debugfs in ->late_register() >> drm/tegra: Do not wrap lines unnecessarily >> drm/tegra: vic: Properly align arguments >> drm/tegra: dc: Support background color >> drm/tegra: Use atomic commit helpers >> drm/tegra: Remove custom page-flip handler >> drm/tegra: dc: Remove tegra_primary_plane_destroy() >> drm/tegra: dc: Remove duplicate plane funcs >> drm/tegra: dc: Remove tegra_overlay_plane_destroy() >> drm/tegra: dc: Remove duplicate plane funcs >> drm/tegra: dc: Move state definition to header >> drm/tegra: Move common plane code to separate file >> drm/tegra: Add Tegra186 display hub support >> drm/tegra: dc: Add Tegra186 support >> drm/tegra: Support ARGB and ABGR formats >> drm/tegra: sor: Parameterize register offsets >> drm/tegra: sor: Add Tegra186 support >> drm/tegra: sor: Support HDMI 2.0 modes >> drm/tegra: dpaux: Implement runtime PM >> drm/tegra: dpaux: Add Tegra186 support >> drm/tegra: fb: Force alpha formats >> drm/tegra: dc: Support more formats >> drm/tegra: dc: Use direct offset to plane registers >> drm/tegra: dc: Remove redundant spinlock >> drm/tegra: Implement zpos property >> gpu: host1x: Use IOMMU groups >> drm/tegra: Use IOMMU groups >> drm/tegra: dpaux: Keep reset defaults for hybrid pad parameters > > >> drm/tegra: dc: Implement legacy blending > > Please hold on this patch. First of all it doesn't work correctly, see my > last > reply to the patch. Secondly, it introduces bug that breaks YUV plane. I thought we had already concluded that this version doesn't cause any regressions. And since this is new functionality I'm not too worried if it do
Re: [PATCH v5 5/9] drm/i915: Add HDCP framework + base implementation
Sean, On Mon, Jan 8, 2018 at 4:50 PM, Sean Paul wrote: > This patch adds the framework required to add HDCP support to intel > connectors. It implements Aksv loading from fuse, and parts 1/2/3 > of the HDCP authentication scheme. > > Note that without shim implementations, this does not actually implement > HDCP. That will come in subsequent patches. > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_hdcp.c > @@ -0,0 +1,740 @@ > +/* > + * Copyright (C) 2017 Google, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. Would you mind using an SPDX tag instead of this fine but long legalese? See Thomas doc [1] for details. Thanks! [1] https://lkml.org/lkml/2017/12/28/323 -- Cordially Philippe Ombredanne ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 0/3] drm/sun4i: hdmi: Fix sun4i_tmds_determine_rate
This patchset fixes several issues in sun4i_tmds_determine_rate that I discovered while trying to get a projector connected to an Olimex A20-OLinuXino-LIME using HDMI with a native resolution of 1280x800 and pixel clock of 83.5 MHz to display at its native resolution. Changes for v3: - Improve commit message for unset best_parent Changes for v2: - Split into separate patches for each issue - Add details to commit message for reproducing issue Jonathan Liu (3): drm/sun4i: hdmi: Check for unset best_parent in sun4i_tmds_determine_rate drm/sun4i: hdmi: Fix incorrect assignment in sun4i_tmds_determine_rate drm/sun4i: hdmi: Add missing rate halving check in sun4i_tmds_determine_rate drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) -- 2.15.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/2] drm/omap: Normalize the zpos and use the normalized_zpos in runtime
On Fri, Dec 22, 2017 at 08:38:38AM +0200, Peter Ujfalusi wrote: > > > On 2017-12-21 15:17, Daniel Vetter wrote: > > On Thu, Dec 21, 2017 at 02:11:01PM +0200, Peter Ujfalusi wrote: > >> To avoid zpos collision, use the normalized_zpos when configuring the > >> zorder of the plane. > >> > >> Signed-off-by: Peter Ujfalusi > >> --- > >> drivers/gpu/drm/omapdrm/omap_drv.c | 26 +- > >> drivers/gpu/drm/omapdrm/omap_plane.c | 2 +- > >> 2 files changed, 26 insertions(+), 2 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c > >> b/drivers/gpu/drm/omapdrm/omap_drv.c > >> index 6bfc2d9ebb46..230df6d8edd1 100644 > >> --- a/drivers/gpu/drm/omapdrm/omap_drv.c > >> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c > >> @@ -21,6 +21,7 @@ > >> > >> #include > >> #include > >> +#include > >> #include > >> #include > >> > >> @@ -54,6 +55,29 @@ MODULE_PARM_DESC(displays, > >> * devices > >> */ > >> > >> +int omap_atomic_helper_check(struct drm_device *dev, > >> + struct drm_atomic_state *state) > >> +{ > >> + int ret; > >> + > >> + ret = drm_atomic_helper_check_modeset(dev, state); > >> + if (ret) > >> + return ret; > >> + > >> + ret = drm_atomic_normalize_zpos(dev, state); > >> + if (ret) > >> + return ret; > > > > Maybe we should call this by default from helpers instead of forcing > > everyone to reinvent this particular wheel? > > > exynos and sti have the exact same code as you do here, ans rcar could > > also reuse it. That feels like we should just fix up > > drm_atomic_helper_check instead of patching all the drivers. And as long > > as you never change zpos it shouldn't ever run. > > It used to be done within drm_atomic_helper_check_planes() which is > called from the drm_atomic_helper_check(), but commit > 38d868e41c4b9 drm: Don't force all planes to be added to the state due > to zpos > > removed it. Drivers need to do this by themselves if they want to use > the normalized_zpos. Oh right, I forgot about all that again. -Daniel > > > -Daniel > > > >> + > >> + ret = drm_atomic_helper_check_planes(dev, state); > >> + if (ret) > >> + return ret; > >> + > >> + if (state->legacy_cursor_update) > >> + state->async_update = !drm_atomic_helper_async_check(dev, > >> state); > >> + > >> + return ret; > >> +} > >> + > >> static void omap_atomic_wait_for_completion(struct drm_device *dev, > >>struct drm_atomic_state *old_state) > >> { > >> @@ -133,7 +157,7 @@ static const struct drm_mode_config_helper_funcs > >> omap_mode_config_helper_funcs = > >> static const struct drm_mode_config_funcs omap_mode_config_funcs = { > >>.fb_create = omap_framebuffer_create, > >>.output_poll_changed = drm_fb_helper_output_poll_changed, > >> - .atomic_check = drm_atomic_helper_check, > >> + .atomic_check = omap_atomic_helper_check, > >>.atomic_commit = drm_atomic_helper_commit, > >> }; > >> > >> diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c > >> b/drivers/gpu/drm/omapdrm/omap_plane.c > >> index bbbdd560e503..abd78b511e6d 100644 > >> --- a/drivers/gpu/drm/omapdrm/omap_plane.c > >> +++ b/drivers/gpu/drm/omapdrm/omap_plane.c > >> @@ -65,7 +65,7 @@ static void omap_plane_atomic_update(struct drm_plane > >> *plane, > >>info.rotation_type = OMAP_DSS_ROT_NONE; > >>info.rotation = DRM_MODE_ROTATE_0; > >>info.global_alpha = 0xff; > >> - info.zorder = state->zpos; > >> + info.zorder = state->normalized_zpos; > >> > >>/* update scanout: */ > >>omap_framebuffer_update_scanout(state->fb, state, &info); > >> -- > >> Peter > >> > >> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. > >> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki > >> > > > > - Péter > > Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. > Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki -- 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: [PATCH v1] drm/i915: Try EDID bitbanging on HDMI after failed read
On Sun, Dec 24, 2017 at 10:45:24PM +0100, Stefan Brüns wrote: > The ACK/NACK implementation as found in e.g. the G965 has the falling > clock edge and the release of the data line to ACK the received byte > happen at the same time. > > Some HDMI-to-VGA converters apparently read the ACK not in the middle of > the clock high phase, but at the rising clock edge, so instead of an ACK > sometimes a NACK is read and the slave (i.e. the EDID ROM) ends the > transfer. > > The bitbanging releases the data line for the ACK only 1/4 bit time after > the falling clock edge, so a slave will see the correct value no matter > if is samples at the rising or the falling clock edge or in the center. > > Fallback to bitbanging is already done for the CRT connector. > > Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92685 > > Signed-off-by: Stefan Brüns Applied with a Cc: stable so it gets backported. Thanks, Daniel > > --- > > drivers/gpu/drm/i915/intel_hdmi.c | 14 +++--- > 1 file changed, 11 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c > b/drivers/gpu/drm/i915/intel_hdmi.c > index 4dea833f9d1b..847cda4c017c 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1573,12 +1573,20 @@ intel_hdmi_set_edid(struct drm_connector *connector) > struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > struct edid *edid; > bool connected = false; > + struct i2c_adapter *i2c; > > intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > > - edid = drm_get_edid(connector, > - intel_gmbus_get_adapter(dev_priv, > - intel_hdmi->ddc_bus)); > + i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); > + > + edid = drm_get_edid(connector, i2c); > + > + if (!edid && !intel_gmbus_is_forced_bit(i2c)) { > + DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO > bit-banging\n"); > + intel_gmbus_force_bit(i2c, true); > + edid = drm_get_edid(connector, i2c); > + intel_gmbus_force_bit(i2c, false); > + } > > intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); > > -- > 2.15.1 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- 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: [RFC PATCH] drm: split up drm_ioctl to allow drivers to hook into "core" functions
On Sun, Dec 31, 2017 at 01:40:46PM -0500, Ilia Mirkin wrote: > On Sun, Dec 31, 2017 at 1:15 PM, Ilia Mirkin wrote: > > Currently there's no way to allow a driver to reimplement any ioctls > > from the drm core. This can be desirable to, e.g., override fixed format > > selection logic, without turning to a midlayer-like solution. > > > > Signed-off-by: Ilia Mirkin > > --- > > > > I want drm_mode_addfb to pick a different format for depth=30 than the > > one it currently selects. Flipping it for all drivers would break a > > bunch of existing ones, so this enables a driver to take control. > > > > Alternatively I can stash something into drm_device which specifies the > > preferred depth=30 fb format. However from my cursory observations of > > dri-devel discussions, midlayering is seen as a problem and not a > > solution. > > Ugh, of course this is turning into a disaster as well. > drm_mode_addfb2 isn't exported, so I have to copy all the > functionality into nouveau, or move it to drm_kms_helper or whatever. > The flag in drm_device approach is sounding a lot more palatable. Let > me know what the best way to proceed is. > > This is all to fix a regression, btw, since previous to nouveau > becoming atomic this all worked fine -- it just looked at the > 30bpp'ness of the fb and assumed. Now it actually cares about specific > formats, and we run into all these problems. Can you just submit the hack to the core addfb code so we know what exactly goes wrong? Overwriting core ioctls is imo not cool at all :-) -Daniel > > > > > drivers/gpu/drm/drm_ioctl.c | 36 > > include/drm/drm_ioctl.h | 2 ++ > > 2 files changed, 26 insertions(+), 12 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c > > index 4aafe4802099..698d69c6db0a 100644 > > --- a/drivers/gpu/drm/drm_ioctl.c > > +++ b/drivers/gpu/drm/drm_ioctl.c > > @@ -767,12 +767,7 @@ long drm_ioctl(struct file *filp, > > struct drm_file *file_priv = filp->private_data; > > struct drm_device *dev; > > const struct drm_ioctl_desc *ioctl = NULL; > > - drm_ioctl_t *func; > > unsigned int nr = DRM_IOCTL_NR(cmd); > > - int retcode = -EINVAL; > > - char stack_kdata[128]; > > - char *kdata = NULL; > > - unsigned int in_size, out_size, drv_size, ksize; > > bool is_driver_ioctl; > > > > dev = file_priv->minor->dev; > > @@ -784,16 +779,33 @@ long drm_ioctl(struct file *filp, > > > > if (is_driver_ioctl) { > > /* driver ioctl */ > > - if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls) > > - goto err_i1; > > - ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; > > + if (nr - DRM_COMMAND_BASE < dev->driver->num_ioctls) > > + ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; > > } else { > > /* core ioctl */ > > - if (nr >= DRM_CORE_IOCTL_COUNT) > > - goto err_i1; > > - ioctl = &drm_ioctls[nr]; > > + if (nr < DRM_CORE_IOCTL_COUNT) > > + ioctl = &drm_ioctls[nr]; > > } > > > > + return __drm_ioctl(filp, cmd, arg, ioctl); > > +} > > +EXPORT_SYMBOL(drm_ioctl); > > + > > +long __drm_ioctl(struct file *filp, > > +unsigned int cmd, unsigned long arg, > > +const struct drm_ioctl_desc *ioctl) > > +{ > > + struct drm_file *file_priv = filp->private_data; > > + drm_ioctl_t *func; > > + unsigned int nr = DRM_IOCTL_NR(cmd); > > + int retcode = -EINVAL; > > + char stack_kdata[128]; > > + char *kdata = NULL; > > + unsigned int in_size, out_size, drv_size, ksize; > > + > > + if (!ioctl) > > + goto err_i1; > > + > > drv_size = _IOC_SIZE(ioctl->cmd); > > out_size = in_size = _IOC_SIZE(cmd); > > if ((cmd & ioctl->cmd & IOC_IN) == 0) > > @@ -851,7 +863,7 @@ long drm_ioctl(struct file *filp, > > DRM_DEBUG("ret = %d\n", retcode); > > return retcode; > > } > > -EXPORT_SYMBOL(drm_ioctl); > > +EXPORT_SYMBOL(__drm_ioctl); > > > > /** > > * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags > > diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h > > index add42809642a..e08f8ea66f2a 100644 > > --- a/include/drm/drm_ioctl.h > > +++ b/include/drm/drm_ioctl.h > > @@ -172,6 +172,8 @@ struct drm_ioctl_desc { > > > > int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); > > long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); > > +long __drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, > > +const struct drm_ioctl_desc *ioctl); > > long drm_ioctl_kernel(struct file *, drm_ioctl_t, void *, u32); > > #ifdef CONFIG_COMPAT > > long drm_compat_ioctl(struct file *filp, unsigned
Re: [PATCH v2] drm/i915: Try EDID bitbanging on HDMI after failed read
On Sun, Dec 31, 2017 at 11:34:54PM +0100, Stefan Brüns wrote: > The ACK/NACK implementation as found in e.g. the G965 has the falling > clock edge and the release of the data line after the ACK for the received > byte happen at the same time. > > This is conformant with the I2C specification, which allows a zero hold > time, see footnote [3]: "A device must internally provide a hold time of > at least 300 ns for the SDA signal (with respect to the V IH(min) of the > SCL signal) to bridge the undefined region of the falling edge of SCL." > > Some HDMI-to-VGA converters apparently fail to adhere to this requirement > and latch SDA at the falling clock edge, so instead of an ACK > sometimes a NACK is read and the slave (i.e. the EDID ROM) ends the > transfer. > > The bitbanging releases the data line for the ACK only 1/4 bit time after > the falling clock edge, so a slave will see the correct value no matter > if it samples at the rising or the falling clock edge or in the center. > > Fallback to bitbanging is already done for the CRT connector. > > Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92685 > > Signed-off-by: Stefan Brüns > > --- > > Changes in v2: > - Fix/enhance commit message, no code changes Ok, found v2, merged this one instead. -Daniel > > drivers/gpu/drm/i915/intel_hdmi.c | 14 +++--- > 1 file changed, 11 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c > b/drivers/gpu/drm/i915/intel_hdmi.c > index 4dea833f9d1b..847cda4c017c 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1573,12 +1573,20 @@ intel_hdmi_set_edid(struct drm_connector *connector) > struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > struct edid *edid; > bool connected = false; > + struct i2c_adapter *i2c; > > intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > > - edid = drm_get_edid(connector, > - intel_gmbus_get_adapter(dev_priv, > - intel_hdmi->ddc_bus)); > + i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); > + > + edid = drm_get_edid(connector, i2c); > + > + if (!edid && !intel_gmbus_is_forced_bit(i2c)) { > + DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO > bit-banging\n"); > + intel_gmbus_force_bit(i2c, true); > + edid = drm_get_edid(connector, i2c); > + intel_gmbus_force_bit(i2c, false); > + } > > intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); > > -- > 2.15.1 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- 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: [PATCH v3 19/27] drm: replace devm_ioremap_nocache with devm_ioremap
2017-12-23 12:01 GMT+01:00 Yisheng Xie : > Default ioremap is ioremap_nocache, so devm_ioremap has the same > function with devm_ioremap_nocache, which can just be killed to > save the size of devres.o That looks true for arm and arm64 architectures but not, for exemple, for ia64: https://elixir.free-electrons.com/linux/v4.15-rc7/source/arch/ia64/mm/ioremap.c If there is still one architecture doing a difference between cached and uncached ioremap we can't remove devm_ioremap_nocache... This patch only concern arm chipsets so we can apply it but that will not help you to reduce devres size. > This patch is to use use devm_ioremap instead of devm_ioremap_nocache, > which should not have any function change but prepare for killing > devm_ioremap_nocache. > > Cc: Daniel Vetter > Cc: Jani Nikula > Cc: Sean Paul > Cc: David Airlie > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Yisheng Xie > --- > drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 2 +- > drivers/gpu/drm/msm/msm_drv.c | 2 +- > drivers/gpu/drm/sti/sti_dvo.c | 3 +-- > drivers/gpu/drm/sti/sti_hda.c | 4 ++-- > drivers/gpu/drm/sti/sti_hdmi.c | 2 +- > drivers/gpu/drm/sti/sti_tvout.c | 2 +- > drivers/gpu/drm/sti/sti_vtg.c | 2 +- > 7 files changed, 8 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c > b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c > index d4f6f1f..242e14f 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c > +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c > @@ -237,7 +237,7 @@ static int hibmc_hw_map(struct hibmc_drm_private *priv) > > ioaddr = pci_resource_start(pdev, 1); > iosize = pci_resource_len(pdev, 1); > - priv->mmio = devm_ioremap_nocache(dev->dev, ioaddr, iosize); > + priv->mmio = devm_ioremap(dev->dev, ioaddr, iosize); > if (!priv->mmio) { > DRM_ERROR("Cannot map mmio region\n"); > return -ENOMEM; > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c > index 0a3ea30..5622704 100644 > --- a/drivers/gpu/drm/msm/msm_drv.c > +++ b/drivers/gpu/drm/msm/msm_drv.c > @@ -122,7 +122,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, > const char *name, > > size = resource_size(res); > > - ptr = devm_ioremap_nocache(&pdev->dev, res->start, size); > + ptr = devm_ioremap(&pdev->dev, res->start, size); > if (!ptr) { > dev_err(&pdev->dev, "failed to ioremap: %s\n", name); > return ERR_PTR(-ENOMEM); > diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c > index 83314ae..81781c5 100644 > --- a/drivers/gpu/drm/sti/sti_dvo.c > +++ b/drivers/gpu/drm/sti/sti_dvo.c > @@ -532,8 +532,7 @@ static int sti_dvo_probe(struct platform_device *pdev) > DRM_ERROR("Invalid dvo resource\n"); > return -ENOMEM; > } > - dvo->regs = devm_ioremap_nocache(dev, res->start, > - resource_size(res)); > + dvo->regs = devm_ioremap(dev, res->start, resource_size(res)); > if (!dvo->regs) > return -ENOMEM; > > diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c > index cf65e32..a3b46c5 100644 > --- a/drivers/gpu/drm/sti/sti_hda.c > +++ b/drivers/gpu/drm/sti/sti_hda.c > @@ -755,14 +755,14 @@ static int sti_hda_probe(struct platform_device *pdev) > DRM_ERROR("Invalid hda resource\n"); > return -ENOMEM; > } > - hda->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); > + hda->regs = devm_ioremap(dev, res->start, resource_size(res)); > if (!hda->regs) > return -ENOMEM; > > res = platform_get_resource_byname(pdev, IORESOURCE_MEM, > "video-dacs-ctrl"); > if (res) { > - hda->video_dacs_ctrl = devm_ioremap_nocache(dev, res->start, > + hda->video_dacs_ctrl = devm_ioremap(dev, res->start, > resource_size(res)); > if (!hda->video_dacs_ctrl) > return -ENOMEM; > diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c > index 30f02d2..ca720b8 100644 > --- a/drivers/gpu/drm/sti/sti_hdmi.c > +++ b/drivers/gpu/drm/sti/sti_hdmi.c > @@ -1371,7 +1371,7 @@ static int sti_hdmi_probe(struct platform_device *pdev) > ret = -ENOMEM; > goto release_adapter; > } > - hdmi->regs = devm_ioremap_nocache(dev, res->start, > resource_size(res)); > + hdmi->regs = devm_ioremap(dev, res->start, resource_size(res)); > if (!hdmi->regs) { > ret = -ENOMEM; > goto release_adapter; > diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c > index 8959fcc..fa1c7a8 10064
Re: [PATCH 2/3] drm: export gem dmabuf_ops for drivers to reuse
On Fri, Jan 05, 2018 at 10:16:04AM +0100, Christian König wrote: > Am 04.01.2018 um 22:12 schrieb Samuel Li: > > Change-Id: I03c22a890d2305f3243d88019d1a28bddd4ddda7 > > Signed-off-by: Samuel Li > > Reviewed-by: Christian König Want to push to drm-misc or some other plan with this? -Daniel > > > --- > > drivers/gpu/drm/drm_prime.c | 53 > > ++--- > > include/drm/drm_prime.h | 22 +++ > > 2 files changed, 53 insertions(+), 22 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > > index 8de93a2..68a69e9 100644 > > --- a/drivers/gpu/drm/drm_prime.c > > +++ b/drivers/gpu/drm/drm_prime.c > > @@ -180,9 +180,8 @@ static int drm_prime_lookup_buf_handle(struct > > drm_prime_file_private *prime_fpri > > return -ENOENT; > > } > > -static int drm_gem_map_attach(struct dma_buf *dma_buf, > > - struct device *target_dev, > > - struct dma_buf_attachment *attach) > > +int drm_gem_map_attach(struct dma_buf *dma_buf, struct device *target_dev, > > + struct dma_buf_attachment *attach) > > { > > struct drm_prime_attachment *prime_attach; > > struct drm_gem_object *obj = dma_buf->priv; > > @@ -200,9 +199,10 @@ static int drm_gem_map_attach(struct dma_buf *dma_buf, > > return dev->driver->gem_prime_pin(obj); > > } > > +EXPORT_SYMBOL(drm_gem_map_attach); > > -static void drm_gem_map_detach(struct dma_buf *dma_buf, > > - struct dma_buf_attachment *attach) > > +void drm_gem_map_detach(struct dma_buf *dma_buf, > > + struct dma_buf_attachment *attach) > > { > > struct drm_prime_attachment *prime_attach = attach->priv; > > struct drm_gem_object *obj = dma_buf->priv; > > @@ -227,6 +227,7 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, > > kfree(prime_attach); > > attach->priv = NULL; > > } > > +EXPORT_SYMBOL(drm_gem_map_detach); > > void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private > > *prime_fpriv, > > struct dma_buf *dma_buf) > > @@ -253,8 +254,8 @@ void drm_prime_remove_buf_handle_locked(struct > > drm_prime_file_private *prime_fpr > > } > > } > > -static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment > > *attach, > > - enum dma_data_direction dir) > > +struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, > > +enum dma_data_direction dir) > > { > > struct drm_prime_attachment *prime_attach = attach->priv; > > struct drm_gem_object *obj = attach->dmabuf->priv; > > @@ -289,13 +290,15 @@ static struct sg_table *drm_gem_map_dma_buf(struct > > dma_buf_attachment *attach, > > return sgt; > > } > > +EXPORT_SYMBOL(drm_gem_map_dma_buf); > > -static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, > > - struct sg_table *sgt, > > - enum dma_data_direction dir) > > +void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, > > + struct sg_table *sgt, > > + enum dma_data_direction dir) > > { > > /* nothing to be done here */ > > } > > +EXPORT_SYMBOL(drm_gem_unmap_dma_buf); > > /** > >* drm_gem_dmabuf_export - dma_buf export implementation for GEM > > @@ -346,47 +349,52 @@ void drm_gem_dmabuf_release(struct dma_buf *dma_buf) > > } > > EXPORT_SYMBOL(drm_gem_dmabuf_release); > > -static void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf) > > +void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf) > > { > > struct drm_gem_object *obj = dma_buf->priv; > > struct drm_device *dev = obj->dev; > > return dev->driver->gem_prime_vmap(obj); > > } > > +EXPORT_SYMBOL(drm_gem_dmabuf_vmap); > > -static void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) > > +void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) > > { > > struct drm_gem_object *obj = dma_buf->priv; > > struct drm_device *dev = obj->dev; > > dev->driver->gem_prime_vunmap(obj, vaddr); > > } > > +EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); > > -static void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, > > - unsigned long page_num) > > +void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, > > +unsigned long page_num) > > { > > return NULL; > > } > > +EXPORT_SYMBOL(drm_gem_dmabuf_kmap_atomic); > > -static void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, > > -unsigned long page_num, void *addr) > > +void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, > > + unsigned long page_num, void *addr) > > { > > } > > -static void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf, > > -unsigned l
Re: [PATCH 03/10] drm: xlnx: Add xlnx fb of Xilinx DRM KMS
On Thu, Jan 04, 2018 at 06:05:52PM -0800, Hyun Kwon wrote: > Helpers for framebuffers backed by cma allocator. > > Signed-off-by: Hyun Kwon Please take a look at the very new drm_gem_framebuffer_helper.c file. There's lots of helpers in there that you can use to remove almost the entire file here :-) You might even want to entirely drop this if it becomes too small. -Daniel > --- > drivers/gpu/drm/xlnx/xlnx_fb.c | 467 > + > drivers/gpu/drm/xlnx/xlnx_fb.h | 30 +++ > 2 files changed, 497 insertions(+) > create mode 100644 drivers/gpu/drm/xlnx/xlnx_fb.c > create mode 100644 drivers/gpu/drm/xlnx/xlnx_fb.h > > diff --git a/drivers/gpu/drm/xlnx/xlnx_fb.c b/drivers/gpu/drm/xlnx/xlnx_fb.c > new file mode 100644 > index 000..dbe9fbf > --- /dev/null > +++ b/drivers/gpu/drm/xlnx/xlnx_fb.c > @@ -0,0 +1,467 @@ > +/* > + * Xilinx DRM KMS Framebuffer helper > + * > + * Copyright (C) 2015 - 2018 Xilinx, Inc. > + * > + * Author: Hyun Woo Kwon > + * > + * Based on drm_fb_cma_helper.c > + * > + * Copyright (C) 2012 Analog Device Inc. > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include "xlnx_fb.h" > + > +#define XLNX_MAX_PLANES 4 > + > +struct xlnx_fb { > + struct drm_framebuffer base; > + struct drm_gem_cma_object *obj[XLNX_MAX_PLANES]; > +}; > + > +struct xlnx_fbdev { > + struct drm_fb_helper fb_helper; > + struct xlnx_fb *fb; > + unsigned int align; > + unsigned int vres_mult; > +}; > + > +static inline struct xlnx_fbdev *to_fbdev(struct drm_fb_helper *fb_helper) > +{ > + return container_of(fb_helper, struct xlnx_fbdev, fb_helper); > +} > + > +static inline struct xlnx_fb *to_fb(struct drm_framebuffer *base_fb) > +{ > + return container_of(base_fb, struct xlnx_fb, base); > +} > + > +static void xlnx_fb_destroy(struct drm_framebuffer *base_fb) > +{ > + struct xlnx_fb *fb = to_fb(base_fb); > + int i; > + > + for (i = 0; i < XLNX_MAX_PLANES; i++) > + if (fb->obj[i]) > + drm_gem_object_unreference_unlocked(&fb->obj[i]->base); > + > + drm_framebuffer_cleanup(base_fb); > + kfree(fb); > +} > + > +static int xlnx_fb_create_handle(struct drm_framebuffer *base_fb, > + struct drm_file *file_priv, > + unsigned int *handle) > +{ > + struct xlnx_fb *fb = to_fb(base_fb); > + > + return drm_gem_handle_create(file_priv, &fb->obj[0]->base, handle); > +} > + > +static struct drm_framebuffer_funcs xlnx_fb_funcs = { > + .destroy= xlnx_fb_destroy, > + .create_handle = xlnx_fb_create_handle, > +}; > + > +/** > + * xlnx_fb_alloc - Allocate a xlnx_fb > + * @drm: DRM object > + * @mode_cmd: drm_mode_fb_cmd2 struct > + * @obj: pointers for returned drm_gem_cma_objects > + * @num_planes: number of planes to be allocated > + * > + * This function is based on drm_fb_cma_alloc(). > + * > + * Return: a xlnx_fb object, or ERR_PTR. > + */ > +static struct xlnx_fb * > +xlnx_fb_alloc(struct drm_device *drm, > + const struct drm_mode_fb_cmd2 *mode_cmd, > + struct drm_gem_cma_object **obj, unsigned int num_planes) > +{ > + struct xlnx_fb *fb; > + int ret; > + int i; > + > + fb = kzalloc(sizeof(*fb), GFP_KERNEL); > + if (!fb) > + return ERR_PTR(-ENOMEM); > + > + drm_helper_mode_fill_fb_struct(drm, &fb->base, mode_cmd); > + > + for (i = 0; i < num_planes; i++) > + fb->obj[i] = obj[i]; > + > + ret = drm_framebuffer_init(drm, &fb->base, &xlnx_fb_funcs); > + if (ret) { > + dev_err(drm->dev, "Failed to initialize fb: %d\n", ret); > + kfree(fb); > + return ERR_PTR(ret); > + } > + > + return fb; > +} > + > +/** > + * xlnx_fb_get_paddr - Get physycal address of framebuffer > + * @base_fb: the framebuffer > + * @plane: which plane > + * > + * This function is based on drm_fb_cma_get_gem_obj(). > + * > + * Return: a physical address of the plane, or 0 > + */ > +dma_addr_t > +xlnx_fb_get_paddr(struct drm_framebuffer *base_fb, unsigned int plane) > +{ > + struct xlnx_fb *fb = to_fb(base_fb); > + > + if (plane >= XLNX_MAX_PLANES) > + return 0; > + > + return fb->obj[plane]->paddr; > +} > +EXPORT_SYMBOL_GPL(xlnx_fb_get_paddr); > + > +static int > +xlnx_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) > +{ > + struct drm_fb_helper *fb_helper = info->par; > + unsigned int i; > + int ret = 0; > + > + switch (cmd) { > + case FBIO_WAITFORVSYNC: > + for (i = 0; i < fb_helper->crtc_count; i++) { > + struct drm_mode_set *mode_set; > + struct drm_crtc *crtc; > + > + mode_set = &fb_helper->crtc_info[i].mode_set; > + crtc = mode_set->crtc; > + ret = drm_crtc_vblank
Re: [PATCH 02/10] drm: xlnx: Add xlnx crtc of Xilinx DRM KMS
On Thu, Jan 04, 2018 at 06:05:51PM -0800, Hyun Kwon wrote: > xlnx_crtc is a part of Xilinx DRM KMS and a layer that > provides some interface between the Xilinx DRM KMS and > crtc drivers. > > Signed-off-by: Hyun Kwon Personal style, but I don't see much value in these small helpers. Splitting them from the main driver at least makes reading the patches a bit harder. But no strong opinion, just a bikeshed, feel free to ignore :-) -Daniel > --- > drivers/gpu/drm/xlnx/xlnx_crtc.c | 194 > +++ > drivers/gpu/drm/xlnx/xlnx_crtc.h | 70 ++ > 2 files changed, 264 insertions(+) > create mode 100644 drivers/gpu/drm/xlnx/xlnx_crtc.c > create mode 100644 drivers/gpu/drm/xlnx/xlnx_crtc.h > > diff --git a/drivers/gpu/drm/xlnx/xlnx_crtc.c > b/drivers/gpu/drm/xlnx/xlnx_crtc.c > new file mode 100644 > index 000..57ee939 > --- /dev/null > +++ b/drivers/gpu/drm/xlnx/xlnx_crtc.c > @@ -0,0 +1,194 @@ > +/* > + * Xilinx DRM crtc driver > + * > + * Copyright (C) 2017 - 2018 Xilinx, Inc. > + * > + * Author: Hyun Woo Kwon > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#include > + > +#include > + > +#include "xlnx_crtc.h" > + > +/* > + * Overview > + * > + * > + * The Xilinx CRTC layer is to enable the custom interface to CRTC drivers. > + * The interface is used by Xilinx DRM driver where it needs CRTC > + * functionailty. CRTC drivers should attach the desired callbacks > + * to struct xlnx_crtc and register the xlnx_crtc with correcsponding > + * drm_device. It's highly recommended CRTC drivers register all callbacks > + * even though many of them are optional. > + * The CRTC helper simply walks through the registered CRTC device, > + * and call the callbacks. > + */ > + > +/** > + * struct xlnx_crtc_helper - Xilinx CRTC helper > + * @xlnx_crtcs: list of Xilinx CRTC devices > + * @lock: lock to protect @xlnx_crtcs > + * @drm: back pointer to DRM core > + */ > +struct xlnx_crtc_helper { > + struct list_head xlnx_crtcs; > + struct mutex lock; /* lock for @xlnx_crtcs */ > + struct drm_device *drm; > +}; > + > +#define XLNX_CRTC_MAX_HEIGHT_WIDTH UINT_MAX > + > +int xlnx_crtc_helper_enable_vblank(struct xlnx_crtc_helper *helper, > +unsigned int crtc_id) > +{ > + struct xlnx_crtc *crtc; > + > + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) > + if (drm_crtc_index(&crtc->crtc) == crtc_id) > + if (crtc->enable_vblank) > + return crtc->enable_vblank(crtc); > + return -ENODEV; > +} > + > +void xlnx_crtc_helper_disable_vblank(struct xlnx_crtc_helper *helper, > + unsigned int crtc_id) > +{ > + struct xlnx_crtc *crtc; > + > + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { > + if (drm_crtc_index(&crtc->crtc) == crtc_id) { > + if (crtc->disable_vblank) > + crtc->disable_vblank(crtc); > + return; > + } > + } > +} > + > +unsigned int xlnx_crtc_helper_get_align(struct xlnx_crtc_helper *helper) > +{ > + struct xlnx_crtc *crtc; > + unsigned int align = 1, tmp; > + > + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { > + if (crtc->get_align) { > + tmp = crtc->get_align(crtc); > + align = ALIGN(align, tmp); > + } > + } > + > + return align; > +} > + > +u64 xlnx_crtc_helper_get_dma_mask(struct xlnx_crtc_helper *helper) > +{ > + struct xlnx_crtc *crtc; > + u64 mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8), tmp; > + > + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { > + if (crtc->get_dma_mask) { > + tmp = crtc->get_dma_mask(crtc); > + mask = min(mask, tmp); > + } > + } > + > + return mask; > +} > + > +int xlnx_crtc_helper_get_max_width(struct xlnx_crtc_helper *helper) > +{ > + struct xlnx_crtc *crtc; > + unsigned int width = XLNX_CRTC_MAX_HEIGHT_WIDTH, tmp; > + > + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { > + if (crtc->get_max_width) { > + tmp = crtc->get_max_width(crtc); > + width = min(width, tmp); > + } > + } > + > + return width; > +} > + > +int xlnx_crtc_helper_get_max_height(struct xlnx_crtc_helper *helper) > +{ > + struct xlnx_crtc *crtc; > + unsigned int height = XLNX_CRTC_MAX_HEIGHT_WIDTH, tmp; > + > + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { > + if (crtc->get_max_height) { > + tmp = crtc->get_max_height(crtc); > + height = min(height, tmp); > + } > + } > + > + return height; > +} > + > +uint32_t xlnx_crtc_helper_get_format(struct xlnx_crtc_helper *helper) > +{ > + struct xlnx_crtc *crtc; > + u32 format = 0, tmp; >
Re: [PATCH 07/10] drm: xlnx: DRM KMS driver for Xilinx ZynqMP DP subsystem display
On Thu, Jan 04, 2018 at 06:05:56PM -0800, Hyun Kwon wrote: > Xilinx ZynqMP has a hardened display pipeline. The pipeline can > be logically partitioned into 2 parts: display and DisplayPort. > This driver handles the display part of the pipeline that handles > buffer management and blending. > > Signed-off-by: Hyun Kwon > --- > drivers/gpu/drm/xlnx/zynqmp_disp.c | 2935 > > drivers/gpu/drm/xlnx/zynqmp_disp.h | 28 + > 2 files changed, 2963 insertions(+) > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_disp.c > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_disp.h > > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c > b/drivers/gpu/drm/xlnx/zynqmp_disp.c > new file mode 100644 > index 000..68f829c > --- /dev/null > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c > @@ -0,0 +1,2935 @@ > +/* > + * ZynqMP Display Controller Driver > + * > + * Copyright (C) 2017 - 2018 Xilinx, Inc. > + * > + * Author: Hyun Woo Kwon > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "xlnx_crtc.h" > +#include "xlnx_fb.h" > +#include "zynqmp_disp.h" > +#include "zynqmp_dp.h" > +#include "zynqmp_dpsub.h" > + > +/* > + * Overview > + * > + * > + * The display part of ZynqMP DP subsystem. Internally, the device > + * is partitioned into 3 blocks: AV buffer manager, Blender, Audio. > + * The driver creates the DRM crtc and plane objectes and maps the DRM > + * interface into those 3 blocks. In high level, the driver is layered > + * in the following way: > + * > + * zynqmp_disp_crtc & zynqmp_disp_plane > + * |->zynqmp_disp > + * |->zynqmp_disp_aud > + * |->zynqmp_disp_blend > + * |->zynqmp_disp_av_buf > + * > + * The driver APIs are used externally by > + * - zynqmp_dpsub: Top level ZynqMP DP subsystem driver > + * - zynqmp_dp: ZynqMP DP driver > + * - xlnx_crtc: Xilinx DRM specific crtc functions > + */ > + > +/* Blender registers */ > +#define ZYNQMP_DISP_V_BLEND_BG_CLR_0 0x0 > +#define ZYNQMP_DISP_V_BLEND_BG_CLR_1 0x4 > +#define ZYNQMP_DISP_V_BLEND_BG_CLR_2 0x8 > +#define ZYNQMP_DISP_V_BLEND_BG_MAX 0xfff > +#define ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA 0xc > +#define ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_MASK0x1fe > +#define ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_MAX 0xff > +#define ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT 0x14 > +#define ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB 0x0 > +#define ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR444 0x1 > +#define ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR422 0x2 > +#define ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YONLY 0x3 > +#define ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_XVYCC 0x4 > +#define ZYNQMP_DISP_V_BLEND_OUTPUT_EN_DOWNSAMPLE BIT(4) > +#define ZYNQMP_DISP_V_BLEND_LAYER_CONTROL0x18 > +#define ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_EN_US BIT(0) > +#define ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_RGBBIT(1) > +#define ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_BYPASS BIT(8) > +#define ZYNQMP_DISP_V_BLEND_NUM_COEFF9 > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF0 0x20 > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF1 0x24 > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF2 0x28 > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF3 0x2c > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF4 0x30 > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF5 0x34 > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF6 0x38 > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF7 0x3c > +#define ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF8 0x40 > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF00x44 > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF10x48 > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF20x4c > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF30x50 > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF40x54 > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF50x58 > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF60x5c > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF70x60 > +#define ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF80x64 > +#define ZYNQMP_DISP_V_BLEND_NUM_OFFSET 3 > +#define ZYNQMP_DISP_V_BLEND_LUMA_IN1CSC_OFFSET 0x68 > +#define ZYNQMP_DISP_V_BLEND_CR_IN1CSC_OFFSET 0x6c > +#define ZYNQMP_DISP_V_BLEND_CB_IN1CSC_OFFSET 0x70 > +#define ZYNQMP_DISP_V_BLEND_LUMA_OUTCSC_OFFSET 0x74 > +#define ZYNQMP_DISP_V_BLEND_CR_OUTCSC_OFFSET 0x78 > +#define ZYNQMP_DISP_V_BLEND_CB_OUTCSC_OFFSET 0x7c > +#define ZYNQMP_DISP_V_BLEND_IN2CSC_COEFF00x80 > +#def
Re: [PATCH 05/10] drm: xlnx: Xilinx DRM KMS driver
On Thu, Jan 04, 2018 at 06:05:54PM -0800, Hyun Kwon wrote: > Xilinx has various platforms for display, where users can create > using multiple IPs in the programmable FPGA fabric, or where > some hardened piepline is available on the chip. Furthermore, > hardened pipeline can also interact with soft logics in FPGA. > > The Xilinx DRM KMS is a softwrae layer to glue subdevice drivers > with DRM core and integrate multiple subdevice drivers together. > > Signed-off-by: Hyun Kwon > --- > MAINTAINERS | 8 + > drivers/gpu/drm/Kconfig | 2 + > drivers/gpu/drm/Makefile | 1 + > drivers/gpu/drm/xlnx/Kconfig | 12 ++ > drivers/gpu/drm/xlnx/Makefile| 2 + > drivers/gpu/drm/xlnx/xlnx_crtc.c | 1 + > drivers/gpu/drm/xlnx/xlnx_drv.c | 436 > +++ > drivers/gpu/drm/xlnx/xlnx_drv.h | 22 ++ > drivers/gpu/drm/xlnx/xlnx_fb.c | 1 + > drivers/gpu/drm/xlnx/xlnx_gem.c | 1 + > 10 files changed, 486 insertions(+) > create mode 100644 drivers/gpu/drm/xlnx/Kconfig > create mode 100644 drivers/gpu/drm/xlnx/Makefile > create mode 100644 drivers/gpu/drm/xlnx/xlnx_drv.c > create mode 100644 drivers/gpu/drm/xlnx/xlnx_drv.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index d4b1635..101a3e6 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -4785,6 +4785,14 @@ F: drivers/gpu/drm/etnaviv/ > F: include/uapi/drm/etnaviv_drm.h > F: Documentation/devicetree/bindings/display/etnaviv/ > > +DRM DRIVERS FOR XILINX > +M: Hyun Kwon > +L: dri-devel@lists.freedesktop.org > +S: Maintained > +F: drivers/gpu/drm/xlnx/ > +F: Documentation/devicetree/bindings/display/xlnx/ > +T: git git://anongit.freedesktop.org/drm/drm-misc > + > DRM DRIVERS FOR ZTE ZX > M: Shawn Guo > L: dri-devel@lists.freedesktop.org > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index 0bc3744..82b7fc3 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -293,6 +293,8 @@ source "drivers/gpu/drm/pl111/Kconfig" > > source "drivers/gpu/drm/tve200/Kconfig" > > +source "drivers/gpu/drm/xlnx/Kconfig" > + > # Keep legacy drivers last > > menuconfig DRM_LEGACY > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index dd5ae67..72ee1a1 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -103,3 +103,4 @@ obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ > obj-$(CONFIG_DRM_PL111) += pl111/ > obj-$(CONFIG_DRM_TVE200) += tve200/ > obj-$(CONFIG_DRM_SCHED) += scheduler/ > +obj-$(CONFIG_DRM_XLNX) += xlnx/ > diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig > new file mode 100644 > index 000..19fd7cd > --- /dev/null > +++ b/drivers/gpu/drm/xlnx/Kconfig > @@ -0,0 +1,12 @@ > +config DRM_XLNX > + tristate "Xilinx DRM KMS Driver" > + depends on DRM && OF > + select DRM_KMS_HELPER > + select DRM_KMS_CMA_HELPER > + select DRM_GEM_CMA_HELPER > + help > + Xilinx DRM KMS driver. Choose this option if you have > + a Xilinx SoCs with hardened display pipeline or soft > + display pipeline using Xilinx IPs in FPGA. This module > + provides the kernel mode setting functionalities > + for Xilinx display drivers. > diff --git a/drivers/gpu/drm/xlnx/Makefile b/drivers/gpu/drm/xlnx/Makefile > new file mode 100644 > index 000..c60a281 > --- /dev/null > +++ b/drivers/gpu/drm/xlnx/Makefile > @@ -0,0 +1,2 @@ > +xlnx_drm-objs += xlnx_crtc.o xlnx_drv.o xlnx_fb.o xlnx_gem.o > +obj-$(CONFIG_DRM_XLNX) += xlnx_drm.o > diff --git a/drivers/gpu/drm/xlnx/xlnx_crtc.c > b/drivers/gpu/drm/xlnx/xlnx_crtc.c > index 57ee939..8387e1e 100644 > --- a/drivers/gpu/drm/xlnx/xlnx_crtc.c > +++ b/drivers/gpu/drm/xlnx/xlnx_crtc.c > @@ -13,6 +13,7 @@ > #include > > #include "xlnx_crtc.h" > +#include "xlnx_drv.h" > > /* > * Overview > diff --git a/drivers/gpu/drm/xlnx/xlnx_drv.c b/drivers/gpu/drm/xlnx/xlnx_drv.c > new file mode 100644 > index 000..273420b > --- /dev/null > +++ b/drivers/gpu/drm/xlnx/xlnx_drv.c > @@ -0,0 +1,436 @@ > +/* > + * Xilinx DRM KMS Driver > + * > + * Copyright (C) 2013 - 2018 Xilinx, Inc. > + * > + * Author: Hyun Woo Kwon > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "xlnx_crtc.h" > +#include "xlnx_fb.h" > +#include "xlnx_gem.h" > + > +#define DRIVER_NAME "xlnx" > +#define DRIVER_DESC "Xilinx DRM KMS Driver" > +#define DRIVER_DATE "20130509" > +#define DRIVER_MAJOR 1 > +#define DRIVER_MINOR 0 > + > +static uint xlnx_fbdev_vres = 2; > +module_param_named(fbdev_vres, xlnx_fbdev_vres, uint, 0444); > +MODULE_PARM_DESC(fbdev_vres, > + "fbdev virtual resolution multiplier for fb (default: 2)"); > + > +/** > + * struct xlnx_drm - Xilinx DRM private data > + * @drm: DRM core > + *
Re: [PATCH 10/10] drm: xlnx: zynqmp: Add debugfs
On Thu, Jan 04, 2018 at 06:05:59PM -0800, Hyun Kwon wrote: > Debugfs can be used to exploit some specific setting. Main purpose > is for testing and debug diagnostic. > > Signed-off-by: Tejas Upadhyay > Signed-off-by: Hyun Kwon Hm, not sure what's the use, it seems to just be for setting/getting your driver-private properties. Usually people use modetest and similar tools, but if there's demand for setting properties in debugfs (we already have all the infrastructure for dumping the entire kms state, see the various atomic_print_state callbacks) I think that should be done with generic drm code. I'd drop this patch for now (if there's no other reason for it). -Daniel > --- > drivers/gpu/drm/xlnx/Kconfig | 21 +++ > drivers/gpu/drm/xlnx/zynqmp_disp.c | 326 > + > drivers/gpu/drm/xlnx/zynqmp_dp.c | 304 ++ > 3 files changed, 651 insertions(+) > > diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig > index 7c5529c..befce0f 100644 > --- a/drivers/gpu/drm/xlnx/Kconfig > +++ b/drivers/gpu/drm/xlnx/Kconfig > @@ -21,3 +21,24 @@ config DRM_ZYNQMP_DPSUB > this option if you have a Xilinx ZynqMP SoC with DisplayPort > subsystem. The driver provides the kernel mode setting > functionlaities for ZynqMP DP subsystem. > + > +config DRM_ZYNQMP_DISP_DEBUG_FS > + bool "ZynqMP Display debugfs" > + depends on DEBUG_FS && DRM_ZYNQMP_DPSUB > + select DRM_ZYNQMP_DP_DEBUG_FS > + help > + Enable the debugfs code for DP Sub driver. The debugfs code > + enables debugging or testing related features. It exposes some > + low level controls to the user space to help testing automation, > + as well as can enable additional diagnostic or statistical > + information. > + > +config DRM_ZYNQMP_DP_DEBUG_FS > + bool "ZynqMP DP debugfs" > + depends on DEBUG_FS && DRM_ZYNQMP_DPSUB > + help > + Enable the debugfs code for DP driver. The debugfs code > + enables debugging or testing related features. It exposes some > + low level controls to the user space to help testing automation, > + as well as can enable additional diagnostic or statistical > + information. > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c > b/drivers/gpu/drm/xlnx/zynqmp_disp.c > index 68f829c..9fe6d49 100644 > --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c > @@ -17,6 +17,7 @@ > #include > > #include > +#include > #include > #include > #include > @@ -508,6 +509,325 @@ static void zynqmp_disp_set(void __iomem *base, int > offset, u32 set) > zynqmp_disp_write(base, offset, zynqmp_disp_read(base, offset) | set); > } > > +#ifdef CONFIG_DRM_ZYNQMP_DISP_DEBUG_FS > + > +#define ZYNQMP_DISP_DEBUGFS_READ_MAX_SIZE32UL > +#define ZYNQMP_DISP_DEBUGFS_MAX_BG_COLOR_VAL 0xFFF > +#define IN_RANGE(x, min, max) ({ \ > + typeof(x) _x = (x); \ > + _x >= (min) && _x <= (max); }) > + > +/* Match xilinx_dp_testcases vs dp_debugfs_reqs[] entry */ > +enum zynqmp_disp_testcases { > + DP_SUB_TC_BG_COLOR, > + DP_SUB_TC_OUTPUT_FMT, > + DP_SUB_TC_NONE > +}; > + > +struct zynqmp_disp_debugfs { > + enum zynqmp_disp_testcases testcase; > + u16 r_value; > + u16 g_value; > + u16 b_value; > + u32 output_fmt; > + struct zynqmp_disp *zynqmp_disp; > +}; > + > +static struct dentry *zynqmp_disp_debugfs_dir; > +struct zynqmp_disp_debugfs disp_debugfs; > +struct zynqmp_disp_debugfs_request { > + const char *req; > + enum zynqmp_disp_testcases tc; > + ssize_t (*read_handler)(char **kern_buff); > + ssize_t (*write_handler)(char **cmd); > +}; > + > +static void > +zynqmp_disp_set_output_fmt(struct zynqmp_disp *disp, unsigned int id); > +static s64 zynqmp_disp_debugfs_argument_value(char *arg) > +{ > + s64 value; > + > + if (!arg) > + return -1; > + > + if (!kstrtos64(arg, 0, &value)) > + return value; > + > + return -1; > +} > + > +static ssize_t > +zynqmp_disp_debugfs_background_color_write(char **disp_test_arg) > +{ > + char *r_color, *g_color, *b_color; > + s64 r_val, g_val, b_val; > + > + r_color = strsep(disp_test_arg, " "); > + g_color = strsep(disp_test_arg, " "); > + b_color = strsep(disp_test_arg, " "); > + > + /* char * to int conversion */ > + r_val = zynqmp_disp_debugfs_argument_value(r_color); > + g_val = zynqmp_disp_debugfs_argument_value(g_color); > + b_val = zynqmp_disp_debugfs_argument_value(b_color); > + > + if (!(IN_RANGE(r_val, 0, ZYNQMP_DISP_DEBUGFS_MAX_BG_COLOR_VAL) && > + IN_RANGE(g_val, 0, ZYNQMP_DISP_DEBUGFS_MAX_BG_COLOR_VAL) && > + IN_RANGE(b_val, 0, ZYNQMP_DISP_DEBUGFS_MAX_BG_COLOR_VAL))) > + return -EINVAL; > + > + disp_debugfs.r_value = r_val; > + disp_debugfs.g_value = g_val; > + disp_debugf
Re: [PATCH 00/10] Xilinx ZynqMP DisplayPort subsystem DRM KMS driver
On Thu, Jan 04, 2018 at 06:05:49PM -0800, Hyun Kwon wrote: > Hi, > > This patchset adds the DRM KMS driver for Xilinx ZynqMP DisplayPort > subsystem. The Xilinx ZynqMP SoC has a hardened full display pipeline > which supports blending of up to 2 planes, and the encoder is > DisplayPort v1.2 compatible. > > This series mainly includes 2 sets: Xilinx DRM KMS (patch 1/10 - 5/10) > and ZynqMP DP subsystem drivers (patch 6/10 - 10/10). > > The Xilinx DRM KMS is intended as a common layer shared across other > (upcoming) Xilinx sub-drivers. It helps sub-drivers for both hardened as > well as soft IPs interoperate together. > > ZynqMP DP subsystem driver is a sub-driver that implements corresponding > drm objects (crtc, plane, encoder, connector,,,) for ZynqMP SoC display > pipeline. The entire pipeline is mainly partitioned into 2 blocks: > generic display logic (zynqmp_disp.c) such as blending, csc,,, and the > DP transmitter logic (zynqmp_dp.c). I read through it all (well mostly the drm relevant bits, not your backend code) and looks fairly resonable. Few minor clenaups and code removals tbh. Wrt merging/maintianing, do you want to maintain it as part of the drm-misc small drivers group? Highly recommended imo. See https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html#small-drivers for details. Ideally we'd need 2 xilinx maintainers to be able to push patches & cross-review stuff. -Daniel > > Thanks, > -hyun > > Hyun Kwon (10): > dt-bindings: display: xlnx: Add Xilinx kms bindings > drm: xlnx: Add xlnx crtc of Xilinx DRM KMS > drm: xlnx: Add xlnx fb of Xilinx DRM KMS > drm: xlnx: Add xlnx gem of Xilinx DRM KMS > drm: xlnx: Xilinx DRM KMS driver > dt-bindings: display: xlnx: Add ZynqMP DP subsystem bindings > drm: xlnx: DRM KMS driver for Xilinx ZynqMP DP subsystem display > drm: xlnx: DRM KMS driver for Xilinx ZynqMP DisplayPort > drm: xlnx: ZynqMP DP subsystem DRM KMS driver > drm: xlnx: zynqmp: Add debugfs > > .../devicetree/bindings/display/xlnx/xlnx,kms.txt | 20 + > .../bindings/display/xlnx/xlnx,zynqmp-dpsub.txt| 94 + > MAINTAINERS|8 + > drivers/gpu/drm/Kconfig|2 + > drivers/gpu/drm/Makefile |1 + > drivers/gpu/drm/xlnx/Kconfig | 44 + > drivers/gpu/drm/xlnx/Makefile |5 + > drivers/gpu/drm/xlnx/xlnx_crtc.c | 195 ++ > drivers/gpu/drm/xlnx/xlnx_crtc.h | 70 + > drivers/gpu/drm/xlnx/xlnx_drv.c| 436 +++ > drivers/gpu/drm/xlnx/xlnx_drv.h| 22 + > drivers/gpu/drm/xlnx/xlnx_fb.c | 468 +++ > drivers/gpu/drm/xlnx/xlnx_fb.h | 30 + > drivers/gpu/drm/xlnx/xlnx_gem.c| 39 + > drivers/gpu/drm/xlnx/xlnx_gem.h| 18 + > drivers/gpu/drm/xlnx/zynqmp_disp.c | 3261 > > drivers/gpu/drm/xlnx/zynqmp_disp.h | 28 + > drivers/gpu/drm/xlnx/zynqmp_dp.c | 2168 + > drivers/gpu/drm/xlnx/zynqmp_dp.h | 29 + > drivers/gpu/drm/xlnx/zynqmp_dpsub.c| 141 + > drivers/gpu/drm/xlnx/zynqmp_dpsub.h| 19 + > 21 files changed, 7098 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/xlnx/xlnx,kms.txt > create mode 100644 > Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.txt > create mode 100644 drivers/gpu/drm/xlnx/Kconfig > create mode 100644 drivers/gpu/drm/xlnx/Makefile > create mode 100644 drivers/gpu/drm/xlnx/xlnx_crtc.c > create mode 100644 drivers/gpu/drm/xlnx/xlnx_crtc.h > create mode 100644 drivers/gpu/drm/xlnx/xlnx_drv.c > create mode 100644 drivers/gpu/drm/xlnx/xlnx_drv.h > create mode 100644 drivers/gpu/drm/xlnx/xlnx_fb.c > create mode 100644 drivers/gpu/drm/xlnx/xlnx_fb.h > create mode 100644 drivers/gpu/drm/xlnx/xlnx_gem.c > create mode 100644 drivers/gpu/drm/xlnx/xlnx_gem.h > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_disp.c > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_disp.h > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_dp.c > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_dp.h > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_dpsub.c > create mode 100644 drivers/gpu/drm/xlnx/zynqmp_dpsub.h > > -- > 2.7.4 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- 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
[Bug 104549] [radeonsi] [wine] [apitrace] Silent Hunter 3 2D texture artifacts / corrupted 3D redering on Polaris
https://bugs.freedesktop.org/show_bug.cgi?id=104549 Bug ID: 104549 Summary: [radeonsi] [wine] [apitrace] Silent Hunter 3 2D texture artifacts / corrupted 3D redering on Polaris Product: Mesa Version: 17.3 Hardware: x86-64 (AMD64) OS: Linux (All) Status: NEW Severity: normal Priority: medium Component: Drivers/Gallium/radeonsi Assignee: dri-devel@lists.freedesktop.org Reporter: banana_banana_ban...@gmx.net QA Contact: dri-devel@lists.freedesktop.org Silent Hunter 3 under wine (2.21 staging / 3.0rc4 as well) renders flickering corrupted textures that seem to be UI elements all over the place for some of its rendered frames, also 3D scene gets trashed every now and then. Game worked fine on my previous hardware (intel Haswell HD4600) and same mesa version 17.3.1, replaying the trace recorded while using polaris hardware renders correctly on intel HD4600 (it is noteworthy however, that replaying the trace throws more fragment shader errors on intel, so it could be possible it renders with no errors because of missing shaders?). Apitrace: https://drive.google.com/open?id=1182dA2LQp91izaPf0vOf9yS1ZZMz246F -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/etnaviv: don't fail to build on arches without PHYS_OFFSET
Am Montag, den 08.01.2018, 11:16 -0700 schrieb Joshua Clayton: > It seems wrong to define PHYS_OFFSET here in a gpu driver. > Is there an actual ARC system using vivante? Yes. > The bit of code that uses PHYS_OFFSET looks pretty ARM specific. > > If not, then at least maybe > > +#if !define (PHYS_OFFSET) && defined (COMPILE_TEST) > +#define PHY_OFFSET 0 > +#endif > > would be more appropriate? > > Maybe the use of PHYS_OFFSET should be moved into an inline in a > header > where it can be defined differently for other arches I don't want to spread the symbol around. It is defined to some (etnaviv specific) safe value in exactly the compilation unit where it is used. Regards, Lucas > On Sun, Jan 7, 2018 at 7:56 AM, Lucas Stach > wrote: > > Some architecture ports like ARC don't provide the PHYS_OFFSET > > symbol. > > Define it to 0 in that case, which is the most conservative default > > in > > the usage context of the etnaviv driver. > > > > Signed-off-by: Lucas Stach > > --- > > drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 4 > > 1 file changed, 4 insertions(+) > > > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > > b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > > index 935d99be748e..febbd1e5bbc7 100644 > > --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > > @@ -31,6 +31,10 @@ > > #include "state_hi.xml.h" > > #include "cmdstream.xml.h" > > > > +#ifndef PHYS_OFFSET > > +#define PHYS_OFFSET 0 > > +#endif > > + > > static const struct platform_device_id gpu_ids[] = { > > { .name = "etnaviv-gpu,2d" }, > > { }, > > -- > > 2.11.0 > > > > ___ > > etnaviv mailing list > > etna...@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/etnaviv > > > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 6/6] drm/tinydrm: Embed the mode in tinydrm_connector
On Mon, Jan 08, 2018 at 07:46:27PM -0600, David Lechner wrote: > On 01/07/2018 11:44 AM, Noralf Trønnes wrote: > > Embed the mode in tinydrm_connector instead of doing an devm_ allocation. > > Remove unnecessary use of ret variable at the end of > > tinydrm_display_pipe_init(). > > > > Signed-off-by: Noralf Trønnes > > --- > > Reviewed-by: David Lechner Since you two work together quit a bit, should we add David as drm-misc committer? -Daniel -- 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
[PATCH v3 06/13] drm/sun4i: engine: Add a VBLANK quirk callback
In some cases, the display engine needs to apply some quirks during the VBLANK event. In the Display Engine 1.0 case for example, we can only disable the frontend once the backend has been, which is at VBLANK. Let's introduce a callback that can be implemented by the various engines. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 4 drivers/gpu/drm/sun4i/sunxi_engine.h | 13 + 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index e122f5b2a395..55f54b54293c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -368,6 +368,7 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private) struct sun4i_tcon *tcon = private; struct drm_device *drm = tcon->drm; struct sun4i_crtc *scrtc = tcon->crtc; + struct sunxi_engine *engine = scrtc->engine; unsigned int status; regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status); @@ -385,6 +386,9 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private) SUN4I_TCON_GINT0_VBLANK_INT(1), 0); + if (engine->ops->vblank_quirk) + engine->ops->vblank_quirk(engine); + return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h index b819d4f9f02f..54c029877531 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -85,6 +85,19 @@ struct sunxi_engine_ops { * This function is optional. */ void (*disable_color_correction)(struct sunxi_engine *engine); + + /** +* @vblank_quirk: +* +* This callback is used to implement engine-specific +* behaviour part of the VBLANK event. It is run with all the +* constraints of an interrupt (can't sleep, all local +* interrupts disabled) and therefore should be as fast as +* possible. +* +* This function is optional. +*/ + void (*vblank_quirk)(struct sunxi_engine *engine); }; /** -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 00/13] drm/sun4i: Support the Display Engine frontend
Hi, This is a first serie to enable the display engine frontend. This hardware block is found in the first generation Display Engine from Allwinner. Its role is to implement more advanced features that the associated backend, even though the backend alone can be used (and was used so far) for basic composition. Among those features, we will find hardware scaling, that is supported in this serie, colorspace conversions, or more exotic formats support such as the one output by the VPU. Let me know what you think, Maxime Changes from v2: - Substracted PHYS_OFFSET to the buffer address - Make sure we only probe and add to the component list on frontends that are supported, and not simply the one enabled in the DTs - Reset the device at probe, and deassert the line after the clocks are enabled - Fixed the format value used - Used drm_fb_cma_get_gem_addr - Added a define for the COEF_ACCESS_CTRL bit - Fixed a wrong comment - Kept the ordering of the engine ops - Reapplied the NULL plane pointer patch that got squashed in v2 somehow - s/backend/engine/ in the engine_ops documentation Changes from v1: - Fixed the unbind function to not disable the already disabled clocks, and to remove ourself from the frontend list - Changed the log level of the frontend disabled message - Added blank lines where suggested by Neil - Fixed an artifact that was happening when the plane using the frontend was disabled. This was happening because the frontend was disabled before the backend layer (that would be disabled at the next vblank). This led to a significant rework of the patches, so I didn't apply all the tags. I also had to take a few patches in. - Added engine ops documentation - Fixed a bug in our duplicate_state callback that wouldn't preserve the frontend state - Removed the hardcoded register values and used the real ones instead. - Fixed some compilation errors reported by the 0-day bot. Maxime Ripard (13): drm/sun4i: backend: Move line stride setup to buffer setup function drm/sun4i: backend: Document the engine operations drm/sun4i: backend: Allow a NULL plane pointer to retrieve the format drm/sun4i: backend: Add a custom plane state drm/sun4i: engine: Add a custom crtc atomic_check drm/sun4i: engine: Add a VBLANK quirk callback drm/sun4i: engine: Create an atomic_begin callback drm/sun4i: Add a driver for the display frontend drm/sun4i: backend: Wire in the frontend drm/sun4i: backend: Add a custom atomic_check for the frontend drm/sun4i: backend: Use runtime_pm variant of atomic_commit_tail drm/sun4i: backend: Make sure we don't have a commit pending ARM: dts: sun8i: a33 Enable our display frontend arch/arm/boot/dts/sun8i-a33.dtsi | 1 +- drivers/gpu/drm/sun4i/Makefile| 3 +- drivers/gpu/drm/sun4i/sun4i_backend.c | 183 ++- drivers/gpu/drm/sun4i/sun4i_backend.h | 10 +- drivers/gpu/drm/sun4i/sun4i_crtc.c| 21 +- drivers/gpu/drm/sun4i/sun4i_drv.c | 27 +- drivers/gpu/drm/sun4i/sun4i_drv.h | 1 +- drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 6 +- drivers/gpu/drm/sun4i/sun4i_frontend.c| 384 +++- drivers/gpu/drm/sun4i/sun4i_frontend.h| 99 ++- drivers/gpu/drm/sun4i/sun4i_layer.c | 83 - drivers/gpu/drm/sun4i/sun4i_layer.h | 11 +- drivers/gpu/drm/sun4i/sun4i_tcon.c| 4 +- drivers/gpu/drm/sun4i/sunxi_engine.h | 89 +- 14 files changed, 901 insertions(+), 21 deletions(-) create mode 100644 drivers/gpu/drm/sun4i/sun4i_frontend.c create mode 100644 drivers/gpu/drm/sun4i/sun4i_frontend.h base-commit: f2e323798ce2553a10ddc720879553642e05e619 -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 01/13] drm/sun4i: backend: Move line stride setup to buffer setup function
Setup the line stride in the buffer setup function, since it's tied to the buffer itself, and is not needed when we do not set the buffer in the backend. This is for example the case when using the frontend and then routing its output to the backend. Reviewed-by: Chen-Yu Tsai Reviewed-by: Neil Armstrong Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index 847eecbe4d14..c99d1a7e815a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -141,7 +141,6 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, int layer, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; DRM_DEBUG_DRIVER("Updating layer %d\n", layer); @@ -153,12 +152,6 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, state->crtc_h)); } - /* Set the line width */ - DRM_DEBUG_DRIVER("Layer line width: %d bits\n", fb->pitches[0] * 8); - regmap_write(backend->engine.regs, -SUN4I_BACKEND_LAYLINEWIDTH_REG(layer), -fb->pitches[0] * 8); - /* Set height and width */ DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", state->crtc_w, state->crtc_h); @@ -218,6 +211,13 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, u32 lo_paddr, hi_paddr; dma_addr_t paddr; + /* Set the line width */ + DRM_DEBUG_DRIVER("Layer line width: %d bits\n", fb->pitches[0] * 8); + regmap_write(backend->engine.regs, +SUN4I_BACKEND_LAYLINEWIDTH_REG(layer), +fb->pitches[0] * 8); + + /* Get the start of the displayed memory */ paddr = drm_fb_cma_get_gem_addr(fb, state, 0); DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr); -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 02/13] drm/sun4i: backend: Document the engine operations
Our operations were missing some documentation to explain what was expected from them. Let's make that clearer. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sunxi_engine.h | 46 +- 1 file changed, 46 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h index 4cb70ae65c79..b374e074c7c3 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -15,12 +15,58 @@ struct drm_device; struct sunxi_engine; +/** + * struct sunxi_engine_ops - helper operations for sunXi engines + * + * These hooks are used by the common part of the DRM driver to + * implement the proper behaviour. + */ struct sunxi_engine_ops { + /** +* @commit: +* +* This callback will trigger the hardware switch to commit +* the new configuration that has been setup during the next +* vblank period. +* +* This function is optional. +*/ void (*commit)(struct sunxi_engine *engine); + + /** +* @layers_init: +* +* This callback is used to allocate, initialize and register +* the layers supported by that engine. +* +* This function is mandatory. +* +* RETURNS: +* +* The array of struct drm_plane backing the layers, or an +* error pointer on failure. +*/ struct drm_plane **(*layers_init)(struct drm_device *drm, struct sunxi_engine *engine); + /** +* @apply_color_correction: +* +* This callback will enable the color correction in the +* engine. This is useful only for the composite output. +* +* This function is optional. +*/ void (*apply_color_correction)(struct sunxi_engine *engine); + + /** +* @disable_color_correction: +* +* This callback will stop the color correction in the +* engine. This is useful only for the composite output. +* +* This function is optional. +*/ void (*disable_color_correction)(struct sunxi_engine *engine); }; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 03/13] drm/sun4i: backend: Allow a NULL plane pointer to retrieve the format
The function converting the DRM format to its equivalent in the backend registers was assuming that we were having a plane. However, we might want to use that function when setting up a plane using the frontend, in which case we will not have a plane associated to the backend's layer. Yet, we still need to setup the format to the one output by the frontend. Test for NULL plane pointers before referencing them, so that we can work around it. Reviewed-by: Neil Armstrong Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index c99d1a7e815a..f971d3fb5ee4 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -93,7 +93,7 @@ void sun4i_backend_layer_enable(struct sun4i_backend *backend, static int sun4i_backend_drm_format_to_layer(struct drm_plane *plane, u32 format, u32 *mode) { - if ((plane->type == DRM_PLANE_TYPE_PRIMARY) && + if (plane && (plane->type == DRM_PLANE_TYPE_PRIMARY) && (format == DRM_FORMAT_ARGB)) format = DRM_FORMAT_XRGB; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 05/13] drm/sun4i: engine: Add a custom crtc atomic_check
We have some restrictions on what the planes and CRTC can provide that are tied to only one generation of display engines. For example, on the first generation, we can only have one YUV plane or one plane that uses the frontend output. Let's allow our engines to provide an atomic_check callback to validate the current configuration. Reviewed-by: Chen-Yu Tsai Reviewed-by: Neil Armstrong Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_crtc.c | 14 ++ drivers/gpu/drm/sun4i/sunxi_engine.h | 17 + 2 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 5decae0069d0..2a565325714f 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -46,6 +46,19 @@ static struct drm_encoder *sun4i_crtc_get_encoder(struct drm_crtc *crtc) return NULL; } +static int sun4i_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); + struct sunxi_engine *engine = scrtc->engine; + int ret = 0; + + if (engine && engine->ops && engine->ops->atomic_check) + ret = engine->ops->atomic_check(engine, state); + + return ret; +} + static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { @@ -125,6 +138,7 @@ static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc) } static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { + .atomic_check = sun4i_crtc_atomic_check, .atomic_begin = sun4i_crtc_atomic_begin, .atomic_flush = sun4i_crtc_atomic_flush, .atomic_enable = sun4i_crtc_atomic_enable, diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h index b374e074c7c3..b819d4f9f02f 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -23,6 +23,23 @@ struct sunxi_engine; */ struct sunxi_engine_ops { /** +* @atomic_check: +* +* This callback allows to validate plane-update related CRTC +* constraints specific to engines. This is mirroring the +* &drm_crtc_helper_funcs.atomic_check callback, so any +* documentation there applies. +* +* This function is optional. +* +* RETURNS: +* +* 0 on success or a negative error code. +*/ + int (*atomic_check)(struct sunxi_engine *engine, + struct drm_crtc_state *state); + + /** * @commit: * * This callback will trigger the hardware switch to commit -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 07/13] drm/sun4i: engine: Create an atomic_begin callback
We have to implement some display engine specific behaviours in atomic_begin. Let's add a function for that. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_crtc.c | 6 +- drivers/gpu/drm/sun4i/sunxi_engine.h | 13 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 2a565325714f..f549f2874353 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -64,6 +64,7 @@ static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, { struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); struct drm_device *dev = crtc->dev; + struct sunxi_engine *engine = scrtc->engine; unsigned long flags; if (crtc->state->event) { @@ -73,7 +74,10 @@ static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, scrtc->event = crtc->state->event; spin_unlock_irqrestore(&dev->event_lock, flags); crtc->state->event = NULL; -} + } + + if (engine->ops->atomic_begin) + engine->ops->atomic_begin(engine, old_state); } static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h index 54c029877531..baa7a1f95300 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -23,6 +23,19 @@ struct sunxi_engine; */ struct sunxi_engine_ops { /** +* @atomic_begin: +* +* This callback allows to prepare our engine for an atomic +* update. This is mirroring the +* &drm_crtc_helper_funcs.atomic_begin callback, so any +* documentation there applies. +* +* This function is optional. +*/ + void (*atomic_begin)(struct sunxi_engine *engine, +struct drm_crtc_state *old_state); + + /** * @atomic_check: * * This callback allows to validate plane-update related CRTC -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 04/13] drm/sun4i: backend: Add a custom plane state
We will need to store some additional data in the future to the state. Create a custom plane state that will embed those data, in order to store the pipe or whether or not that plane should use the frontend. Reviewed-by: Chen-Yu Tsai Reviewed-by: Neil Armstrong Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_layer.c | 50 -- drivers/gpu/drm/sun4i/sun4i_layer.h | 10 ++- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 7bddf12548d3..b85a9a02d166 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -25,6 +25,50 @@ struct sun4i_plane_desc { uint32_tnformats; }; +static void sun4i_backend_layer_reset(struct drm_plane *plane) +{ + struct sun4i_layer_state *state; + + if (plane->state) { + state = state_to_sun4i_layer_state(plane->state); + + __drm_atomic_helper_plane_destroy_state(&state->state); + + kfree(state); + plane->state = NULL; + } + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (state) { + plane->state = &state->state; + plane->state->plane = plane; + } +} + +static struct drm_plane_state * +sun4i_backend_layer_duplicate_state(struct drm_plane *plane) +{ + struct sun4i_layer_state *copy; + + copy = kzalloc(sizeof(*copy), GFP_KERNEL); + if (!copy) + return NULL; + + __drm_atomic_helper_plane_duplicate_state(plane, ©->state); + + return ©->state; +} + +static void sun4i_backend_layer_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct sun4i_layer_state *s_state = state_to_sun4i_layer_state(state); + + __drm_atomic_helper_plane_destroy_state(state); + + kfree(s_state); +} + static void sun4i_backend_layer_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -52,11 +96,11 @@ static const struct drm_plane_helper_funcs sun4i_backend_layer_helper_funcs = { }; static const struct drm_plane_funcs sun4i_backend_layer_funcs = { - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = sun4i_backend_layer_destroy_state, + .atomic_duplicate_state = sun4i_backend_layer_duplicate_state, .destroy= drm_plane_cleanup, .disable_plane = drm_atomic_helper_disable_plane, - .reset = drm_atomic_helper_plane_reset, + .reset = sun4i_backend_layer_reset, .update_plane = drm_atomic_helper_update_plane, }; diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h b/drivers/gpu/drm/sun4i/sun4i_layer.h index 4e84f438b346..d2c19348d1b0 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.h +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h @@ -22,12 +22,22 @@ struct sun4i_layer { int id; }; +struct sun4i_layer_state { + struct drm_plane_state state; +}; + static inline struct sun4i_layer * plane_to_sun4i_layer(struct drm_plane *plane) { return container_of(plane, struct sun4i_layer, plane); } +static inline struct sun4i_layer_state * +state_to_sun4i_layer_state(struct drm_plane_state *state) +{ + return container_of(state, struct sun4i_layer_state, state); +} + struct drm_plane **sun4i_layers_init(struct drm_device *drm, struct sunxi_engine *engine); -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 10/13] drm/sun4i: backend: Add a custom atomic_check for the frontend
Now that we have everything in place, we can start enabling the frontend. This is more difficult than one would assume since there can only be one plane using the frontend per-backend. We therefore need to make sure that the userspace will not try to setup multiple planes using it, since that would be impossible. In order to prevent that, we can create an atomic_check callback that will check that only one plane will effectively make use of the frontend in a given configuration, and will toggle the switch in that plane state so that the proper setup function can do their role. Reviewed-by: Chen-Yu Tsai Reviewed-by: Neil Armstrong Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 65 - drivers/gpu/drm/sun4i/sun4i_backend.h | 2 +- 2 files changed, 67 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index 29e1ca7e01fe..4642f933765e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -271,6 +272,69 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, return 0; } +static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state) +{ + u16 src_h = state->src_h >> 16; + u16 src_w = state->src_w >> 16; + + DRM_DEBUG_DRIVER("Input size %dx%d, output size %dx%d\n", +src_w, src_h, state->crtc_w, state->crtc_h); + + if ((state->crtc_h != src_h) || (state->crtc_w != src_w)) + return true; + + return false; +} + +static bool sun4i_backend_plane_uses_frontend(struct drm_plane_state *state) +{ + struct sun4i_layer *layer = plane_to_sun4i_layer(state->plane); + struct sun4i_backend *backend = layer->backend; + + if (IS_ERR(backend->frontend)) + return false; + + return sun4i_backend_plane_uses_scaler(state); +} + +static int sun4i_backend_atomic_check(struct sunxi_engine *engine, + struct drm_crtc_state *crtc_state) +{ + struct drm_atomic_state *state = crtc_state->state; + struct drm_device *drm = state->dev; + struct drm_plane *plane; + unsigned int num_frontend_planes = 0; + + DRM_DEBUG_DRIVER("Starting checking our planes\n"); + + if (!crtc_state->planes_changed) + return 0; + + drm_for_each_plane_mask(plane, drm, crtc_state->plane_mask) { + struct drm_plane_state *plane_state = + drm_atomic_get_plane_state(state, plane); + struct sun4i_layer_state *layer_state = + state_to_sun4i_layer_state(plane_state); + + if (sun4i_backend_plane_uses_frontend(plane_state)) { + DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", +plane->index); + + layer_state->uses_frontend = true; + num_frontend_planes++; + } else { + layer_state->uses_frontend = false; + } + } + + if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) { + DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n"); + return -EINVAL; + } + + return 0; +} + static void sun4i_backend_vblank_quirk(struct sunxi_engine *engine) { struct sun4i_backend *backend = engine_to_sun4i_backend(engine); @@ -414,6 +478,7 @@ static struct sun4i_frontend *sun4i_backend_find_frontend(struct sun4i_drv *drv, } static const struct sunxi_engine_ops sun4i_backend_engine_ops = { + .atomic_check = sun4i_backend_atomic_check, .commit = sun4i_backend_commit, .layers_init= sun4i_layers_init, .apply_color_correction = sun4i_backend_apply_color_correction, diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h index 350a2dbde31a..b5edf2d50a24 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.h +++ b/drivers/gpu/drm/sun4i/sun4i_backend.h @@ -144,6 +144,8 @@ #define SUN4I_BACKEND_HWCCOLORTAB_OFF 0x4c00 #define SUN4I_BACKEND_PIPE_OFF(p) (0x5000 + (0x400 * (p))) +#define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1 + struct sun4i_backend { struct sunxi_engine engine; struct sun4i_frontend *frontend; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 11/13] drm/sun4i: backend: Use runtime_pm variant of atomic_commit_tail
During a hardware commit, the commit bit in the backend will only be cleared if the TCON is enabled. Use the runtime_pm variant of the atomic_commit_tail hook that makes sure that the CRTC, our TCON, is enabled when we perform an atomic_commit. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c index 2992f0a6b349..a01a5b7d46e6 100644 --- a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c +++ b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c @@ -10,6 +10,7 @@ * the License, or (at your option) any later version. */ +#include #include #include #include @@ -32,6 +33,10 @@ static const struct drm_mode_config_funcs sun4i_de_mode_config_funcs = { .fb_create = drm_gem_fb_create, }; +static struct drm_mode_config_helper_funcs sun4i_de_mode_config_helpers = { + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, +}; + struct drm_fbdev_cma *sun4i_framebuffer_init(struct drm_device *drm) { drm_mode_config_reset(drm); @@ -40,6 +45,7 @@ struct drm_fbdev_cma *sun4i_framebuffer_init(struct drm_device *drm) drm->mode_config.max_height = 8192; drm->mode_config.funcs = &sun4i_de_mode_config_funcs; + drm->mode_config.helper_private = &sun4i_de_mode_config_helpers; return drm_fbdev_cma_init(drm, 32, drm->mode_config.num_connector); } -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 12/13] drm/sun4i: backend: Make sure we don't have a commit pending
If we try to read the backend registers while it fetches the new values, we end up with the value of some random register instead of the one we asked for. In order to prevent that, let's make sure that the very first thing we do during our atomic modesetting is to let the commit bit come to a rest. We don't have to worry about anything else since the only time we will trigger a new transaction is during the atomic_commit which comes much later. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index 4642f933765e..a18c86a15748 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -297,6 +297,17 @@ static bool sun4i_backend_plane_uses_frontend(struct drm_plane_state *state) return sun4i_backend_plane_uses_scaler(state); } +static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, + struct drm_crtc_state *old_state) +{ + u32 val; + + WARN_ON(regmap_read_poll_timeout(engine->regs, +SUN4I_BACKEND_REGBUFFCTL_REG, +val, !(val & SUN4I_BACKEND_REGBUFFCTL_LOADCTL), +100, 5)); +} + static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct drm_crtc_state *crtc_state) { @@ -478,6 +489,7 @@ static struct sun4i_frontend *sun4i_backend_find_frontend(struct sun4i_drv *drv, } static const struct sunxi_engine_ops sun4i_backend_engine_ops = { + .atomic_begin = sun4i_backend_atomic_begin, .atomic_check = sun4i_backend_atomic_check, .commit = sun4i_backend_commit, .layers_init= sun4i_layers_init, -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 13/13] ARM: dts: sun8i: a33 Enable our display frontend
The display frontend can be used to do hardware scaling, colorspaces conversion or to implement the buffer format output by the Cedar VPU. Since we're starting to have some support for it in the DRM driver, let's enable its DT node. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a33.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index 50eb84fa246a..a21f2ed07a52 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -289,7 +289,6 @@ clock-names = "ahb", "mod", "ram"; resets = <&ccu RST_BUS_DE_FE>; - status = "disabled"; ports { #address-cells = <1>; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 08/13] drm/sun4i: Add a driver for the display frontend
The display frontend is an hardware block that can be used to implement some more advanced features like hardware scaling or colorspace conversions. It can also be used to implement the output format of the VPU. Let's create a minimal driver for it that will only enable the hardware scaling features. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/Makefile | 3 +- drivers/gpu/drm/sun4i/sun4i_drv.c | 27 +- drivers/gpu/drm/sun4i/sun4i_drv.h | 1 +- drivers/gpu/drm/sun4i/sun4i_frontend.c | 384 ++- drivers/gpu/drm/sun4i/sun4i_frontend.h | 99 +++- 5 files changed, 509 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/sun4i/sun4i_frontend.c create mode 100644 drivers/gpu/drm/sun4i/sun4i_frontend.h diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile index 0c2f8c7facae..b660d82011f4 100644 --- a/drivers/gpu/drm/sun4i/Makefile +++ b/drivers/gpu/drm/sun4i/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 sun4i-backend-y+= sun4i_backend.o sun4i_layer.o +sun4i-frontend-y += sun4i_frontend.o sun4i-drm-y+= sun4i_drv.o sun4i-drm-y+= sun4i_framebuffer.o @@ -21,6 +22,6 @@ obj-$(CONFIG_DRM_SUN4I) += sun4i-tcon.o obj-$(CONFIG_DRM_SUN4I)+= sun4i_tv.o obj-$(CONFIG_DRM_SUN4I)+= sun6i_drc.o -obj-$(CONFIG_DRM_SUN4I_BACKEND)+= sun4i-backend.o +obj-$(CONFIG_DRM_SUN4I_BACKEND)+= sun4i-backend.o sun4i-frontend.o obj-$(CONFIG_DRM_SUN4I_HDMI) += sun4i-drm-hdmi.o obj-$(CONFIG_DRM_SUN8I_MIXER) += sun8i-mixer.o diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 75c76cdd82bc..42e68cf3a2e8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -23,6 +23,7 @@ #include #include "sun4i_drv.h" +#include "sun4i_frontend.h" #include "sun4i_framebuffer.h" #include "sun4i_tcon.h" @@ -98,6 +99,7 @@ static int sun4i_drv_bind(struct device *dev) goto free_drm; } drm->dev_private = drv; + INIT_LIST_HEAD(&drv->frontend_list); INIT_LIST_HEAD(&drv->engine_list); INIT_LIST_HEAD(&drv->tcon_list); @@ -185,6 +187,14 @@ static bool sun4i_drv_node_is_frontend(struct device_node *node) of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend"); } +static bool sun4i_drv_node_is_supported_frontend(struct device_node *node) +{ + if (IS_ENABLED(CONFIG_DRM_SUN4I_BACKEND)) + return !!of_match_node(sun4i_frontend_of_table, node); + + return false; +} + static bool sun4i_drv_node_is_tcon(struct device_node *node) { return of_device_is_compatible(node, "allwinner,sun4i-a10-tcon") || @@ -239,9 +249,11 @@ static int sun4i_drv_add_endpoints(struct device *dev, int count = 0; /* -* We don't support the frontend for now, so we will never -* have a device bound. Just skip over it, but we still want -* the rest our pipeline to be added. +* The frontend has been disabled in some of our old device +* trees. If we find a node that is the frontend and is +* disabled, we should just follow through and parse its +* child, but without adding it to the component list. +* Otherwise, we obviously want to add it to the list. */ if (!sun4i_drv_node_is_frontend(node) && !of_device_is_available(node)) @@ -254,7 +266,14 @@ static int sun4i_drv_add_endpoints(struct device *dev, if (sun4i_drv_node_is_connector(node)) return 0; - if (!sun4i_drv_node_is_frontend(node)) { + /* +* If the device is either just a regular device, or an +* enabled frontend supported by the driver, we add it to our +* component list. +*/ + if (!sun4i_drv_node_is_frontend(node) || + (sun4i_drv_node_is_supported_frontend(node) && +of_device_is_available(node))) { /* Add current component */ DRM_DEBUG_DRIVER("Adding component %pOF\n", node); drm_of_component_match_add(dev, match, compare_of, node); diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.h b/drivers/gpu/drm/sun4i/sun4i_drv.h index a960c89270cc..9c26a345f85c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.h +++ b/drivers/gpu/drm/sun4i/sun4i_drv.h @@ -19,6 +19,7 @@ struct sun4i_drv { struct list_headengine_list; + struct list_headfrontend_list; struct list_headtcon_list; struct drm_fbdev_cma*fbdev; diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.c b/drivers/gpu/drm/sun4i/sun4i_frontend.c new file mode 100644 index ..c19238cec1b7 --- /dev/null +++ b/drivers/gpu/drm/sun4i/sun4i_frontend.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Fre
[PATCH v3 09/13] drm/sun4i: backend: Wire in the frontend
Now that we have a driver, we can make use of it. This is done by adding a flag to our custom plane state that will trigger whether we should use the frontend on that particular plane or not. The rest is just plumbing to set up the backend to not perform the DMA but receive its data from the frontend. Note that we're still not making any use of the frontend itself, as no one is setting the flag yet. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 90 - drivers/gpu/drm/sun4i/sun4i_backend.h | 8 ++- drivers/gpu/drm/sun4i/sun4i_crtc.c| 1 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 33 +- drivers/gpu/drm/sun4i/sun4i_layer.h | 1 +- 5 files changed, 130 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index f971d3fb5ee4..29e1ca7e01fe 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -26,6 +26,7 @@ #include "sun4i_backend.h" #include "sun4i_drv.h" +#include "sun4i_frontend.h" #include "sun4i_layer.h" #include "sunxi_engine.h" @@ -203,6 +204,30 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, return 0; } +int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend, + int layer, uint32_t fmt) +{ + u32 val; + int ret; + + ret = sun4i_backend_drm_format_to_layer(NULL, fmt, &val); + if (ret) { + DRM_DEBUG_DRIVER("Invalid format\n"); + return ret; + } + + regmap_update_bits(backend->engine.regs, + SUN4I_BACKEND_ATTCTL_REG0(layer), + SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN, + SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN); + + regmap_update_bits(backend->engine.regs, + SUN4I_BACKEND_ATTCTL_REG1(layer), + SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val); + + return 0; +} + int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, int layer, struct drm_plane *plane) { @@ -246,6 +271,36 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, return 0; } +static void sun4i_backend_vblank_quirk(struct sunxi_engine *engine) +{ + struct sun4i_backend *backend = engine_to_sun4i_backend(engine); + struct sun4i_frontend *frontend = backend->frontend; + + if (!frontend) + return; + + /* +* In a teardown scenario with the frontend involved, we have +* to keep the frontend enabled until the next vblank, and +* only then disable it. +* +* This is due to the fact that the backend will not take into +* account the new configuration (with the plane that used to +* be fed by the frontend now disabled) until we write to the +* commit bit and the hardware fetches the new configuration +* during the next vblank. +* +* So we keep the frontend around in order to prevent any +* visual artifacts. +*/ + spin_lock(&backend->frontend_lock); + if (backend->frontend_teardown) { + sun4i_frontend_exit(frontend); + backend->frontend_teardown = false; + } + spin_unlock(&backend->frontend_lock); +}; + static int sun4i_backend_init_sat(struct device *dev) { struct sun4i_backend *backend = dev_get_drvdata(dev); int ret; @@ -330,11 +385,40 @@ static int sun4i_backend_of_get_id(struct device_node *node) return ret; } +static struct sun4i_frontend *sun4i_backend_find_frontend(struct sun4i_drv *drv, + struct device_node *node) +{ + struct device_node *port, *ep, *remote; + struct sun4i_frontend *frontend; + + port = of_graph_get_port_by_id(node, 0); + if (!port) + return ERR_PTR(-EINVAL); + + for_each_available_child_of_node(port, ep) { + remote = of_graph_get_remote_port_parent(ep); + if (!remote) + continue; + + /* does this node match any registered engines? */ + list_for_each_entry(frontend, &drv->frontend_list, list) { + if (remote == frontend->node) { + of_node_put(remote); + of_node_put(port); + return frontend; + } + } + } + + return ERR_PTR(-EINVAL); +} + static const struct sunxi_engine_ops sun4i_backend_engine_ops = { .commit = sun4i_backend_commit, .layers_init= sun4i_layers_init, .apply_color_correction = sun4i_backend_apply_color_correction, .disable_color_correction
Re: [RFC v2 3/8] drm: Export some ioctl functions
On Wed, Jan 03, 2018 at 11:21:05PM +0100, Noralf Trønnes wrote: > Export the following functions so in-kernel users can allocate > dumb buffers: > - drm_file_alloc > - drm_file_free > - drm_prime_handle_to_fd_ioctl > - drm_mode_addfb2 > - drm_mode_create_dumb_ioctl > - drm_dropmaster_ioctl > > Signed-off-by: Noralf Trønnes > --- > drivers/gpu/drm/drm_auth.c | 1 + > drivers/gpu/drm/drm_crtc_internal.h | 4 > drivers/gpu/drm/drm_dumb_buffers.c | 1 + > drivers/gpu/drm/drm_file.c | 2 ++ > drivers/gpu/drm/drm_framebuffer.c | 1 + > drivers/gpu/drm/drm_internal.h | 6 -- > drivers/gpu/drm/drm_ioctl.c | 1 + > drivers/gpu/drm/drm_prime.c | 1 + > include/drm/drm_auth.h | 3 +++ > include/drm/drm_dumb_buffers.h | 10 ++ > include/drm/drm_file.h | 2 ++ > include/drm/drm_framebuffer.h | 3 +++ > include/drm/drm_prime.h | 2 ++ > 13 files changed, 27 insertions(+), 10 deletions(-) > create mode 100644 include/drm/drm_dumb_buffers.h > > diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c > index aad468d170a7..e35ed9ee0c5a 100644 > --- a/drivers/gpu/drm/drm_auth.c > +++ b/drivers/gpu/drm/drm_auth.c > @@ -236,6 +236,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void > *data, > mutex_unlock(&dev->master_mutex); > return ret; > } > +EXPORT_SYMBOL(drm_dropmaster_ioctl); > > int drm_master_open(struct drm_file *file_priv) > { > diff --git a/drivers/gpu/drm/drm_crtc_internal.h > b/drivers/gpu/drm/drm_crtc_internal.h > index 9ebb8841778c..86422492ad00 100644 > --- a/drivers/gpu/drm/drm_crtc_internal.h > +++ b/drivers/gpu/drm/drm_crtc_internal.h > @@ -63,8 +63,6 @@ int drm_mode_getresources(struct drm_device *dev, > > /* drm_dumb_buffers.c */ > /* IOCTLs */ > -int drm_mode_create_dumb_ioctl(struct drm_device *dev, > -void *data, struct drm_file *file_priv); > int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, >void *data, struct drm_file *file_priv); > int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, > @@ -164,8 +162,6 @@ void drm_fb_release(struct drm_file *file_priv); > /* IOCTL */ > int drm_mode_addfb(struct drm_device *dev, > void *data, struct drm_file *file_priv); > -int drm_mode_addfb2(struct drm_device *dev, > - void *data, struct drm_file *file_priv); > int drm_mode_rmfb(struct drm_device *dev, > void *data, struct drm_file *file_priv); > int drm_mode_getfb(struct drm_device *dev, > diff --git a/drivers/gpu/drm/drm_dumb_buffers.c > b/drivers/gpu/drm/drm_dumb_buffers.c > index 39ac15ce4702..199b279f7650 100644 > --- a/drivers/gpu/drm/drm_dumb_buffers.c > +++ b/drivers/gpu/drm/drm_dumb_buffers.c > @@ -90,6 +90,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, > > return dev->driver->dumb_create(file_priv, dev, args); > } > +EXPORT_SYMBOL(drm_mode_create_dumb_ioctl); > > /** > * drm_mode_mmap_dumb_ioctl - create an mmap offset for a dumb backing > storage buffer > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index d208faade27e..400d44437e93 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -180,6 +180,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) > > return ERR_PTR(ret); > } > +EXPORT_SYMBOL(drm_file_alloc); > > static void drm_events_release(struct drm_file *file_priv) > { > @@ -273,6 +274,7 @@ void drm_file_free(struct drm_file *file) > put_pid(file->pid); > kfree(file); > } > +EXPORT_SYMBOL(drm_file_free); I'd put the EXPORT_SYMBOL for the drm_file stuff into the first patch. That way it's next to the kerneldoc and code all in the same patch. > > static int drm_setup(struct drm_device * dev) > { > diff --git a/drivers/gpu/drm/drm_framebuffer.c > b/drivers/gpu/drm/drm_framebuffer.c > index 5a13ff29f4f0..0493977e6848 100644 > --- a/drivers/gpu/drm/drm_framebuffer.c > +++ b/drivers/gpu/drm/drm_framebuffer.c > @@ -341,6 +341,7 @@ int drm_mode_addfb2(struct drm_device *dev, > > return 0; > } > +EXPORT_SYMBOL(drm_mode_addfb2); > > struct drm_mode_rmfb_work { > struct work_struct work; > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h > index 40179c5fc6b8..7d62e412fbb8 100644 > --- a/drivers/gpu/drm/drm_internal.h > +++ b/drivers/gpu/drm/drm_internal.h > @@ -26,8 +26,6 @@ > > /* drm_file.c */ > extern struct mutex drm_global_mutex; > -struct drm_file *drm_file_alloc(struct drm_minor *minor); > -void drm_file_free(struct drm_file *file); > void drm_lastclose(struct drm_device *dev); > > /* drm_pci.c */ > @@ -37,8 +35,6 @@ void drm_pci_agp_destroy(struct drm_device *dev); > int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master); > > /* drm_prime.c */ > -int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, > -
Re: [RFC v2 4/8] drm/fb-helper: Ensure driver module is pinned in fb_open()
On Wed, Jan 03, 2018 at 11:21:06PM +0100, Noralf Trønnes wrote: > If struct fb_ops is defined in a library like cma, fb_open() and fbcon > takes a ref on the library instead of the driver module. Use > fb_ops.fb_open/fb_release to ensure that the driver module is pinned. > > Signed-off-by: Noralf Trønnes Reviewed-by: Daniel Vetter ... I guess the patch to roll it out to the various vfun tables and macros comes later? -Daniel > --- > drivers/gpu/drm/drm_fb_helper.c | 40 > include/drm/drm_fb_helper.h | 13 + > 2 files changed, 53 insertions(+) > > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index 035784ddd133..2c6adf1d80c2 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -1207,6 +1207,46 @@ void drm_fb_helper_cfb_imageblit(struct fb_info *info, > } > EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); > > +/** > + * drm_fb_helper_fb_open - implementation for &fb_ops.fb_open > + * @info: fbdev registered by the helper > + * @user: 1=userspace, 0=fbcon > + * > + * If &fb_ops is wrapped in a library, pin the driver module. > + */ > +int drm_fb_helper_fb_open(struct fb_info *info, int user) > +{ > + struct drm_fb_helper *fb_helper = info->par; > + struct drm_device *dev = fb_helper->dev; > + > + if (info->fbops->owner != dev->driver->fops->owner) { > + if (!try_module_get(dev->driver->fops->owner)) > + return -ENODEV; > + } > + > + return 0; > +} > +EXPORT_SYMBOL(drm_fb_helper_fb_open); > + > +/** > + * drm_fb_helper_fb_release - implementation for &fb_ops.fb_release > + * @info: fbdev registered by the helper > + * @user: 1=userspace, 0=fbcon > + * > + * If &fb_ops is wrapped in a library, unpin the driver module. > + */ > +int drm_fb_helper_fb_release(struct fb_info *info, int user) > +{ > + struct drm_fb_helper *fb_helper = info->par; > + struct drm_device *dev = fb_helper->dev; > + > + if (info->fbops->owner != dev->driver->fops->owner) > + module_put(dev->driver->fops->owner); > + > + return 0; > +} > +EXPORT_SYMBOL(drm_fb_helper_fb_release); > + > /** > * drm_fb_helper_set_suspend - wrapper around fb_set_suspend > * @fb_helper: driver-allocated fbdev helper, can be NULL > diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h > index b069433e7fc1..a593f01ff69e 100644 > --- a/include/drm/drm_fb_helper.h > +++ b/include/drm/drm_fb_helper.h > @@ -297,6 +297,9 @@ void drm_fb_helper_cfb_copyarea(struct fb_info *info, > void drm_fb_helper_cfb_imageblit(struct fb_info *info, >const struct fb_image *image); > > +int drm_fb_helper_fb_open(struct fb_info *info, int user); > +int drm_fb_helper_fb_release(struct fb_info *info, int user); > + > void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool > suspend); > void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, > bool suspend); > @@ -473,6 +476,16 @@ static inline void drm_fb_helper_cfb_imageblit(struct > fb_info *info, > { > } > > +static inline int drm_fb_helper_fb_open(struct fb_info *info, int user) > +{ > + return -ENODEV; > +} > + > +static inline int drm_fb_helper_fb_release(struct fb_info *info, int user) > +{ > + return -ENODEV; > +} > + > static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, >bool suspend) > { > -- > 2.14.2 > -- 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: [RFC v2 2/8] drm/ioctl: Remove trailing whitespace
On Wed, Jan 03, 2018 at 11:21:04PM +0100, Noralf Trønnes wrote: > Remove a couple of trailing spaces. > > Signed-off-by: Noralf Trønnes Reviewed-by: Daniel Vetter > --- > drivers/gpu/drm/drm_ioctl.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c > index 4aafe4802099..b1e96fb68ea8 100644 > --- a/drivers/gpu/drm/drm_ioctl.c > +++ b/drivers/gpu/drm/drm_ioctl.c > @@ -509,7 +509,7 @@ int drm_ioctl_permit(u32 flags, struct drm_file > *file_priv) > return -EACCES; > > /* MASTER is only for master or control clients */ > - if (unlikely((flags & DRM_MASTER) && > + if (unlikely((flags & DRM_MASTER) && >!drm_is_current_master(file_priv) && >!drm_is_control_client(file_priv))) > return -EACCES; > @@ -704,7 +704,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = { > * > * ##define DRM_IOCTL_MY_DRIVER_OPERATION \ > * DRM_IOW(DRM_COMMAND_BASE, struct my_driver_operation) > - * > + * > * DRM driver private IOCTL must be in the range from DRM_COMMAND_BASE to > * DRM_COMMAND_END. Finally you need an array of &struct drm_ioctl_desc to > wire > * up the handlers and set the access rights:: > -- > 2.14.2 > -- 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: [RFC v2 1/8] drm: provide management functions for drm_file
On Wed, Jan 03, 2018 at 11:21:03PM +0100, Noralf Trønnes wrote: > From: David Herrmann > > Rather than doing drm_file allocation/destruction right in the fops, lets > provide separate helpers. This decouples drm_file management from the > still-mandatory drm-fops. It prepares for use of drm_file without the > fops, both by possible separate fops implementations and APIs (not that I > am aware of any such plans), and more importantly from in-kernel use where > no real file is available. > > Signed-off-by: David Herrmann > [rebased] > Signed-off-by: Noralf Trønnes > --- > drivers/gpu/drm/drm_file.c | 309 > +++-- > drivers/gpu/drm/drm_internal.h | 2 + > 2 files changed, 179 insertions(+), 132 deletions(-) > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index b3c6e997ccdb..d208faade27e 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -101,6 +101,179 @@ DEFINE_MUTEX(drm_global_mutex); > > static int drm_open_helper(struct file *filp, struct drm_minor *minor); > > +/** > + * drm_file_alloc - allocate file context > + * @minor: minor to allocate on > + * > + * This allocates a new DRM file context. It is not linked into any context > and > + * can be used by the caller freely. Note that the context keeps a pointer to > + * @minor, so it must be freed before @minor is. > + * > + * The legacy paths might require the drm_global_mutex to be held. I'd remove this line, since it's only relevant to close the driver load vs. file open race for drivers still using the deprecated ->load callback. This only confuses and doesn't help anyone writing a new/modern driver. > + * > + * RETURNS: > + * Pointer to newly allocated context, ERR_PTR on failure. > + */ > +struct drm_file *drm_file_alloc(struct drm_minor *minor) > +{ > + struct drm_device *dev = minor->dev; > + struct drm_file *file; > + int ret; > + > + file = kzalloc(sizeof(*file), GFP_KERNEL); > + if (!file) > + return ERR_PTR(-ENOMEM); > + > + file->pid = get_pid(task_pid(current)); > + file->minor = minor; > + > + /* for compatibility root is always authenticated */ > + file->authenticated = capable(CAP_SYS_ADMIN); > + file->lock_count = 0; > + > + INIT_LIST_HEAD(&file->lhead); > + INIT_LIST_HEAD(&file->fbs); > + mutex_init(&file->fbs_lock); > + INIT_LIST_HEAD(&file->blobs); > + INIT_LIST_HEAD(&file->pending_event_list); > + INIT_LIST_HEAD(&file->event_list); > + init_waitqueue_head(&file->event_wait); > + file->event_space = 4096; /* set aside 4k for event buffer */ > + > + mutex_init(&file->event_read_lock); > + > + if (drm_core_check_feature(dev, DRIVER_GEM)) > + drm_gem_open(dev, file); > + > + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > + drm_syncobj_open(file); > + > + if (drm_core_check_feature(dev, DRIVER_PRIME)) > + drm_prime_init_file_private(&file->prime); > + > + if (dev->driver->open) { > + ret = dev->driver->open(dev, file); > + if (ret < 0) > + goto out_prime_destroy; > + } > + > + if (drm_is_primary_client(file)) { > + ret = drm_master_open(file); > + if (ret) > + goto out_close; > + } > + > + return file; > + > +out_close: > + if (dev->driver->postclose) > + dev->driver->postclose(dev, file); > +out_prime_destroy: > + if (drm_core_check_feature(dev, DRIVER_PRIME)) > + drm_prime_destroy_file_private(&file->prime); > + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > + drm_syncobj_release(file); > + if (drm_core_check_feature(dev, DRIVER_GEM)) > + drm_gem_release(dev, file); > + put_pid(file->pid); > + kfree(file); > + > + return ERR_PTR(ret); > +} > + > +static void drm_events_release(struct drm_file *file_priv) > +{ > + struct drm_device *dev = file_priv->minor->dev; > + struct drm_pending_event *e, *et; > + unsigned long flags; > + > + spin_lock_irqsave(&dev->event_lock, flags); > + > + /* Unlink pending events */ > + list_for_each_entry_safe(e, et, &file_priv->pending_event_list, > + pending_link) { > + list_del(&e->pending_link); > + e->file_priv = NULL; > + } > + > + /* Remove unconsumed events */ > + list_for_each_entry_safe(e, et, &file_priv->event_list, link) { > + list_del(&e->link); > + kfree(e); > + } > + > + spin_unlock_irqrestore(&dev->event_lock, flags); > +} > + > +/** > + * drm_file_free - free file context > + * @file: context to free, or NULL > + * > + * This destroys and deallocates a DRM file context previously allocated via > + * drm_file_alloc(). The caller must make sure to unlink it from any contexts > + * before calling this. > + * > + * The legacy paths might requir
Re: [RFC v2 4/8] drm/fb-helper: Ensure driver module is pinned in fb_open()
On Wed, Jan 03, 2018 at 11:21:06PM +0100, Noralf Trønnes wrote: > If struct fb_ops is defined in a library like cma, fb_open() and fbcon > takes a ref on the library instead of the driver module. Use > fb_ops.fb_open/fb_release to ensure that the driver module is pinned. > > Signed-off-by: Noralf Trønnes > --- > drivers/gpu/drm/drm_fb_helper.c | 40 > include/drm/drm_fb_helper.h | 13 + > 2 files changed, 53 insertions(+) > > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index 035784ddd133..2c6adf1d80c2 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -1207,6 +1207,46 @@ void drm_fb_helper_cfb_imageblit(struct fb_info *info, > } > EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); > > +/** > + * drm_fb_helper_fb_open - implementation for &fb_ops.fb_open > + * @info: fbdev registered by the helper > + * @user: 1=userspace, 0=fbcon > + * > + * If &fb_ops is wrapped in a library, pin the driver module. > + */ > +int drm_fb_helper_fb_open(struct fb_info *info, int user) > +{ > + struct drm_fb_helper *fb_helper = info->par; > + struct drm_device *dev = fb_helper->dev; > + > + if (info->fbops->owner != dev->driver->fops->owner) { Actually bikeshed potential here: I'd just unconditionally grab the module reference, makes the code simpler. Or is there a reason not to? -Daniel > + if (!try_module_get(dev->driver->fops->owner)) > + return -ENODEV; > + } > + > + return 0; > +} > +EXPORT_SYMBOL(drm_fb_helper_fb_open); > + > +/** > + * drm_fb_helper_fb_release - implementation for &fb_ops.fb_release > + * @info: fbdev registered by the helper > + * @user: 1=userspace, 0=fbcon > + * > + * If &fb_ops is wrapped in a library, unpin the driver module. > + */ > +int drm_fb_helper_fb_release(struct fb_info *info, int user) > +{ > + struct drm_fb_helper *fb_helper = info->par; > + struct drm_device *dev = fb_helper->dev; > + > + if (info->fbops->owner != dev->driver->fops->owner) > + module_put(dev->driver->fops->owner); > + > + return 0; > +} > +EXPORT_SYMBOL(drm_fb_helper_fb_release); > + > /** > * drm_fb_helper_set_suspend - wrapper around fb_set_suspend > * @fb_helper: driver-allocated fbdev helper, can be NULL > diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h > index b069433e7fc1..a593f01ff69e 100644 > --- a/include/drm/drm_fb_helper.h > +++ b/include/drm/drm_fb_helper.h > @@ -297,6 +297,9 @@ void drm_fb_helper_cfb_copyarea(struct fb_info *info, > void drm_fb_helper_cfb_imageblit(struct fb_info *info, >const struct fb_image *image); > > +int drm_fb_helper_fb_open(struct fb_info *info, int user); > +int drm_fb_helper_fb_release(struct fb_info *info, int user); > + > void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool > suspend); > void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, > bool suspend); > @@ -473,6 +476,16 @@ static inline void drm_fb_helper_cfb_imageblit(struct > fb_info *info, > { > } > > +static inline int drm_fb_helper_fb_open(struct fb_info *info, int user) > +{ > + return -ENODEV; > +} > + > +static inline int drm_fb_helper_fb_release(struct fb_info *info, int user) > +{ > + return -ENODEV; > +} > + > static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, >bool suspend) > { > -- > 2.14.2 > -- 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: [RFC v2 5/8] drm/fb-helper: Don't restore if fbdev is not in use
On Wed, Jan 03, 2018 at 11:21:07PM +0100, Noralf Trønnes wrote: > Keep track of fbdev users and only restore fbdev in > drm_fb_helper_restore_fbdev_mode_unlocked() when in use. This avoids > fbdev being restored in drm_driver.last_close when nothing uses it. > Additionally fbdev is turned off when the last user is closing. > fbcon is a user in this context. > > Signed-off-by: Noralf Trønnes > --- > drivers/gpu/drm/drm_fb_helper.c | 15 +++ > include/drm/drm_fb_helper.h | 14 ++ > 2 files changed, 29 insertions(+) > > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index 2c6adf1d80c2..f9dcc7a5761f 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -522,6 +522,9 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct > drm_fb_helper *fb_helper) > if (READ_ONCE(fb_helper->deferred_setup)) > return 0; > > + if (!atomic_read(&fb_helper->open_count)) > + return 0; > + > mutex_lock(&fb_helper->lock); > ret = restore_fbdev_mode(fb_helper); > > @@ -781,6 +784,7 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct > drm_fb_helper *helper, > INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker); > INIT_WORK(&helper->dirty_work, drm_fb_helper_dirty_work); > helper->dirty_clip.x1 = helper->dirty_clip.y1 = ~0; > + atomic_set(&helper->open_count, 1); > mutex_init(&helper->lock); > helper->funcs = funcs; > helper->dev = dev; > @@ -1212,6 +1216,7 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); > * @info: fbdev registered by the helper > * @user: 1=userspace, 0=fbcon > * > + * Increase fbdev use count. > * If &fb_ops is wrapped in a library, pin the driver module. > */ > int drm_fb_helper_fb_open(struct fb_info *info, int user) > @@ -1224,6 +1229,8 @@ int drm_fb_helper_fb_open(struct fb_info *info, int > user) > return -ENODEV; > } > > + atomic_inc(&fb_helper->open_count); > + > return 0; > } > EXPORT_SYMBOL(drm_fb_helper_fb_open); > @@ -1233,6 +1240,7 @@ EXPORT_SYMBOL(drm_fb_helper_fb_open); > * @info: fbdev registered by the helper > * @user: 1=userspace, 0=fbcon > * > + * Decrease fbdev use count and turn off if there are no users left. > * If &fb_ops is wrapped in a library, unpin the driver module. > */ > int drm_fb_helper_fb_release(struct fb_info *info, int user) > @@ -1240,6 +1248,10 @@ int drm_fb_helper_fb_release(struct fb_info *info, int > user) > struct drm_fb_helper *fb_helper = info->par; > struct drm_device *dev = fb_helper->dev; > > + if (atomic_dec_and_test(&fb_helper->open_count) && > + !drm_dev_is_unplugged(fb_helper->dev)) > + drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); > + > if (info->fbops->owner != dev->driver->fops->owner) > module_put(dev->driver->fops->owner); > > @@ -1936,6 +1948,9 @@ static int drm_fb_helper_single_fb_probe(struct > drm_fb_helper *fb_helper, > if (ret < 0) > return ret; > > + if (fb_helper->fbdev->fbops->fb_open == drm_fb_helper_fb_open) > + atomic_set(&fb_helper->open_count, 0); > + > strcpy(fb_helper->fb->comm, "[fbcon]"); > return 0; > } > diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h > index a593f01ff69e..16d8773b60e3 100644 > --- a/include/drm/drm_fb_helper.h > +++ b/include/drm/drm_fb_helper.h > @@ -232,6 +232,20 @@ struct drm_fb_helper { >* See also: @deferred_setup >*/ > int preferred_bpp; > + > + /** > + * @open_count: > + * > + * Keeps track of fbdev use to know when to not restore fbdev. > + * > + * Drivers that use drm_fb_helper_fb_open() as their \.fb_open > + * callback will get an initial value of 0 and get restore based on > + * actual use. Others will get an initial value of 1 which means that > + * fbdev will always be restored. Drivers that call > + * drm_fb_helper_fb_open() in their \.fb_open, thus needs to set the > + * initial value to 0 themselves. > + */ > + atomic_t open_count; Do we really need an atomic_t here? Especially the "disable stuff on last fb_close" would still be race without more locking, and from a quick look at the fbdev core code we're protected with fb_info->lock. I think an unsigned is perfectly fine here. And if we really need atomics, then refcount_t (for the safety checks that provides). With that changed: Reviewed-by: Daniel Vetter But before we merge this we definitely need to roll out fb_open/close to all drivers. But I guess that's why the RFC in your series. On that: There's some intersting runtime pm stuff for nouveau/amd/radeon. I guess we'll need to keep that. Plus udl has some defio fun :-/ -Daniel > }; > > /** > -- > 2.14.2 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch __
Re: [RFC v2 3/8] drm: Export some ioctl functions
Hi On Tue, Jan 9, 2018 at 11:16 AM, Daniel Vetter wrote: > On Wed, Jan 03, 2018 at 11:21:05PM +0100, Noralf Trønnes wrote: >> Export the following functions so in-kernel users can allocate >> dumb buffers: >> - drm_file_alloc >> - drm_file_free >> - drm_prime_handle_to_fd_ioctl >> - drm_mode_addfb2 >> - drm_mode_create_dumb_ioctl >> - drm_dropmaster_ioctl >> >> Signed-off-by: Noralf Trønnes >> --- >> drivers/gpu/drm/drm_auth.c | 1 + >> drivers/gpu/drm/drm_crtc_internal.h | 4 >> drivers/gpu/drm/drm_dumb_buffers.c | 1 + >> drivers/gpu/drm/drm_file.c | 2 ++ >> drivers/gpu/drm/drm_framebuffer.c | 1 + >> drivers/gpu/drm/drm_internal.h | 6 -- >> drivers/gpu/drm/drm_ioctl.c | 1 + >> drivers/gpu/drm/drm_prime.c | 1 + >> include/drm/drm_auth.h | 3 +++ >> include/drm/drm_dumb_buffers.h | 10 ++ >> include/drm/drm_file.h | 2 ++ >> include/drm/drm_framebuffer.h | 3 +++ >> include/drm/drm_prime.h | 2 ++ >> 13 files changed, 27 insertions(+), 10 deletions(-) >> create mode 100644 include/drm/drm_dumb_buffers.h >> >> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c >> index aad468d170a7..e35ed9ee0c5a 100644 >> --- a/drivers/gpu/drm/drm_auth.c >> +++ b/drivers/gpu/drm/drm_auth.c >> @@ -236,6 +236,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void >> *data, >> mutex_unlock(&dev->master_mutex); >> return ret; >> } >> +EXPORT_SYMBOL(drm_dropmaster_ioctl); >> >> int drm_master_open(struct drm_file *file_priv) >> { >> diff --git a/drivers/gpu/drm/drm_crtc_internal.h >> b/drivers/gpu/drm/drm_crtc_internal.h >> index 9ebb8841778c..86422492ad00 100644 >> --- a/drivers/gpu/drm/drm_crtc_internal.h >> +++ b/drivers/gpu/drm/drm_crtc_internal.h >> @@ -63,8 +63,6 @@ int drm_mode_getresources(struct drm_device *dev, >> >> /* drm_dumb_buffers.c */ >> /* IOCTLs */ >> -int drm_mode_create_dumb_ioctl(struct drm_device *dev, >> -void *data, struct drm_file *file_priv); >> int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, >>void *data, struct drm_file *file_priv); >> int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, >> @@ -164,8 +162,6 @@ void drm_fb_release(struct drm_file *file_priv); >> /* IOCTL */ >> int drm_mode_addfb(struct drm_device *dev, >> void *data, struct drm_file *file_priv); >> -int drm_mode_addfb2(struct drm_device *dev, >> - void *data, struct drm_file *file_priv); >> int drm_mode_rmfb(struct drm_device *dev, >> void *data, struct drm_file *file_priv); >> int drm_mode_getfb(struct drm_device *dev, >> diff --git a/drivers/gpu/drm/drm_dumb_buffers.c >> b/drivers/gpu/drm/drm_dumb_buffers.c >> index 39ac15ce4702..199b279f7650 100644 >> --- a/drivers/gpu/drm/drm_dumb_buffers.c >> +++ b/drivers/gpu/drm/drm_dumb_buffers.c >> @@ -90,6 +90,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, >> >> return dev->driver->dumb_create(file_priv, dev, args); >> } >> +EXPORT_SYMBOL(drm_mode_create_dumb_ioctl); >> >> /** >> * drm_mode_mmap_dumb_ioctl - create an mmap offset for a dumb backing >> storage buffer >> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c >> index d208faade27e..400d44437e93 100644 >> --- a/drivers/gpu/drm/drm_file.c >> +++ b/drivers/gpu/drm/drm_file.c >> @@ -180,6 +180,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) >> >> return ERR_PTR(ret); >> } >> +EXPORT_SYMBOL(drm_file_alloc); >> >> static void drm_events_release(struct drm_file *file_priv) >> { >> @@ -273,6 +274,7 @@ void drm_file_free(struct drm_file *file) >> put_pid(file->pid); >> kfree(file); >> } >> +EXPORT_SYMBOL(drm_file_free); > > I'd put the EXPORT_SYMBOL for the drm_file stuff into the first patch. > That way it's next to the kerneldoc and code all in the same patch. I agree. Feel free to amend my patch there. >> >> static int drm_setup(struct drm_device * dev) >> { >> diff --git a/drivers/gpu/drm/drm_framebuffer.c >> b/drivers/gpu/drm/drm_framebuffer.c >> index 5a13ff29f4f0..0493977e6848 100644 >> --- a/drivers/gpu/drm/drm_framebuffer.c >> +++ b/drivers/gpu/drm/drm_framebuffer.c >> @@ -341,6 +341,7 @@ int drm_mode_addfb2(struct drm_device *dev, >> >> return 0; >> } >> +EXPORT_SYMBOL(drm_mode_addfb2); >> >> struct drm_mode_rmfb_work { >> struct work_struct work; >> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h >> index 40179c5fc6b8..7d62e412fbb8 100644 >> --- a/drivers/gpu/drm/drm_internal.h >> +++ b/drivers/gpu/drm/drm_internal.h >> @@ -26,8 +26,6 @@ >> >> /* drm_file.c */ >> extern struct mutex drm_global_mutex; >> -struct drm_file *drm_file_alloc(struct drm_minor *minor); >> -void drm_file_free(struct drm_file *file); >> void drm_lastclose(struct drm_device *dev); >> >> /* drm_pci.c */ >> @@ -37,8 +35,6 @@ void drm_pci_agp_dest
Re: [RFC v2 1/8] drm: provide management functions for drm_file
Hi On Tue, Jan 9, 2018 at 11:20 AM, Daniel Vetter wrote: > On Wed, Jan 03, 2018 at 11:21:03PM +0100, Noralf Trønnes wrote: >> From: David Herrmann >> >> Rather than doing drm_file allocation/destruction right in the fops, lets >> provide separate helpers. This decouples drm_file management from the >> still-mandatory drm-fops. It prepares for use of drm_file without the >> fops, both by possible separate fops implementations and APIs (not that I >> am aware of any such plans), and more importantly from in-kernel use where >> no real file is available. >> >> Signed-off-by: David Herrmann >> [rebased] >> Signed-off-by: Noralf Trønnes >> --- For completeness: Still fine with me! Thanks for picking it up. Thanks David ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC v2 6/8] drm: Handle fbdev emulation in core
On Wed, Jan 03, 2018 at 11:21:08PM +0100, Noralf Trønnes wrote: > Prepare for generic fbdev emulation by letting DRM core work directly > with the fbdev compatibility layer. This is done by adding new fbdev > helper vtable callbacks for restore, hotplug_event, unregister and > release. > > Signed-off-by: Noralf Trønnes No clue whether my idea is any good, but inspired by the bootsplash discussion, and the prospect that we might get other in-kernel drm/kms clients I'm wondering whether we should make this a bit more generic and tie it to drm_file? The idea would be to have a list of internal drm clients by putting all the internal drm_files onto a list (same way we do with the userspace ones). Then we'd just walk that list and call ->hotplug, ->unregister and ->release at the right places. ->restore would be a bit different, I guess for that we'd only call the ->restore callback of the very first kernel-internal client. With that we could then add/remove kernel-internal drm clients like normal userspace clients, which should make integration of emergency consoles, boot splashes and whatever else real easy. And I think it would be a lot cleaner than leaking fb_helper knowledge into the drm core, which feels a rather backwards. Otoh that feels a bit overengineered (but at least it shouldn't be a lot more code really). If the list is too much work we could start with 1 drm_file * pointer for internal stuff (but would still need locking, so list_head is probably easier). Thoughts? -Daniel > --- > drivers/gpu/drm/drm_file.c | 12 +++- > drivers/gpu/drm/drm_mode_config.c | 10 ++ > drivers/gpu/drm/drm_probe_helper.c | 4 > include/drm/drm_fb_helper.h| 33 + > 4 files changed, 58 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index 400d44437e93..7ec09fb83135 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -35,6 +35,7 @@ > #include > #include > > +#include > #include > #include > > @@ -441,10 +442,19 @@ static void drm_legacy_dev_reinit(struct drm_device > *dev) > > void drm_lastclose(struct drm_device * dev) > { > + struct drm_fb_helper *fb_helper = dev->fb_helper; > + int ret; > + > DRM_DEBUG("\n"); > > - if (dev->driver->lastclose) > + if (dev->driver->lastclose) { > dev->driver->lastclose(dev); > + } else if (fb_helper && fb_helper->funcs && fb_helper->funcs->restore) { > + ret = fb_helper->funcs->restore(fb_helper); > + if (ret) > + DRM_ERROR("Failed to restore fbdev: %d\n", ret); > + } > + > DRM_DEBUG("driver lastclose completed\n"); > > if (drm_core_check_feature(dev, DRIVER_LEGACY)) > diff --git a/drivers/gpu/drm/drm_mode_config.c > b/drivers/gpu/drm/drm_mode_config.c > index bc5c46306b3d..260eb1730244 100644 > --- a/drivers/gpu/drm/drm_mode_config.c > +++ b/drivers/gpu/drm/drm_mode_config.c > @@ -21,6 +21,7 @@ > */ > > #include > +#include > #include > #include > > @@ -61,6 +62,11 @@ int drm_modeset_register_all(struct drm_device *dev) > > void drm_modeset_unregister_all(struct drm_device *dev) > { > + struct drm_fb_helper *fb_helper = dev->fb_helper; > + > + if (fb_helper && fb_helper->funcs && fb_helper->funcs->unregister) > + fb_helper->funcs->unregister(fb_helper); > + > drm_connector_unregister_all(dev); > drm_encoder_unregister_all(dev); > drm_crtc_unregister_all(dev); > @@ -408,6 +414,7 @@ EXPORT_SYMBOL(drm_mode_config_init); > */ > void drm_mode_config_cleanup(struct drm_device *dev) > { > + struct drm_fb_helper *fb_helper = dev->fb_helper; > struct drm_connector *connector; > struct drm_connector_list_iter conn_iter; > struct drm_crtc *crtc, *ct; > @@ -417,6 +424,9 @@ void drm_mode_config_cleanup(struct drm_device *dev) > struct drm_property_blob *blob, *bt; > struct drm_plane *plane, *plt; > > + if (fb_helper && fb_helper->funcs && fb_helper->funcs->release) > + fb_helper->funcs->release(fb_helper); > + > list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, >head) { > encoder->funcs->destroy(encoder); > diff --git a/drivers/gpu/drm/drm_probe_helper.c > b/drivers/gpu/drm/drm_probe_helper.c > index 555fbe54d6e2..9d8b0ba54173 100644 > --- a/drivers/gpu/drm/drm_probe_helper.c > +++ b/drivers/gpu/drm/drm_probe_helper.c > @@ -559,10 +559,14 @@ EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); > */ > void drm_kms_helper_hotplug_event(struct drm_device *dev) > { > + struct drm_fb_helper *fb_helper = dev->fb_helper; > + > /* send a uevent + call fbdev */ > drm_sysfs_hotplug_event(dev); > if (dev->mode_config.funcs->output_poll_changed) > dev->mode_config.funcs->output_poll_changed(dev); > +
Re: [PATCH 04/11] drm/bridge/synopsys: dw-hdmi: Export some PHY related functions
On 12/31/2017 02:31 AM, Jernej Skrabec wrote: Parts of PHY code could be useful also for custom PHYs. For example, Allwinner A83T has custom PHY which is probably Synopsys gen2 PHY with few additional memory mapped registers, so most of the Synopsys PHY related code could be reused. It turns out that even completely custom HDMI PHYs, such as the one found in Allwinner H3, can reuse some of those functions. This would suggest that (some?) functions exported in this commit are actually part of generic PHY interface and not really specific to Synopsys PHYs. Export useful PHY functions. Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 45 ++- drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++ include/drm/bridge/dw_hdmi.h | 10 +++ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 7ca14d7325b5..67467d0b683a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1037,19 +1037,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) HDMI_PHY_CONF0_SVSRET_MASK); } -static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) +void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) { hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, HDMI_PHY_CONF0_GEN2_PDDQ_MASK); } +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq); -static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) +void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) { hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); } +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron); static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) { @@ -1065,6 +1067,23 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) HDMI_PHY_CONF0_SELDIPIF_MASK); } +void dw_hdmi_phy_gen2_reset(struct dw_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_MC_PHYRSTZ, +HDMI_MC_PHYRSTZ_PHYRSTZ_OFFSET, +HDMI_MC_PHYRSTZ_PHYRSTZ_MASK); +} +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_reset); + +void dw_hdmi_phy_set_slave_addr(struct dw_hdmi *hdmi) +{ + hdmi_phy_test_clear(hdmi, 1); + hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, + HDMI_PHY_I2CM_SLAVE_ADDR); + hdmi_phy_test_clear(hdmi, 0); +} +EXPORT_SYMBOL_GPL(dw_hdmi_phy_set_slave_addr); Should this be called dw_hdmi_phy_gen2_set_slave_addr? Looks good otherwise. Same for patches 3 and 4 in this series. Thanks, Archit + static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) { const struct dw_hdmi_phy_data *phy = hdmi->phy.data; @@ -1204,15 +1223,12 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) dw_hdmi_phy_enable_svsret(hdmi, 1); /* PHY reset. The reset signal is active high on Gen2 PHYs. */ - hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); - hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); + dw_hdmi_phy_gen2_reset(hdmi, 1); + dw_hdmi_phy_gen2_reset(hdmi, 0); hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); - hdmi_phy_test_clear(hdmi, 1); - hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, - HDMI_PHY_I2CM_SLAVE_ADDR); - hdmi_phy_test_clear(hdmi, 0); + dw_hdmi_phy_set_slave_addr(hdmi); /* Write to the PHY as configured by the platform */ if (pdata->configure_phy) @@ -1251,15 +1267,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) dw_hdmi_phy_power_off(hdmi); } -static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, - void *data) +enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, + void *data) { return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? connector_status_connected : connector_status_disconnected; } +EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd); -static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, - bool force, bool disabled, bool rxsense) +void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, + bool force, bool disabled, bool rxsense) { u8 old_mask = hdmi->phy_mask; @@ -1271,8 +1288,9 @@ static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, if (old_mask != hdmi->phy_mask) hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); } +EX
Re: [RFC v2 7/8] drm/fb-helper: Add generic fbdev emulation
On Wed, Jan 03, 2018 at 11:21:09PM +0100, Noralf Trønnes wrote: > Add generic fbdev emulation which uses a drm_file to get a dumb_buffer > and drm_framebuffer. The buffer is exported and vmap/mmap called on > the dma-buf. > > Signed-off-by: Noralf Trønnes > --- > drivers/gpu/drm/drm_fb_helper.c | 301 > +++- > include/drm/drm_fb_helper.h | 33 + > 2 files changed, 333 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index f9dcc7a5761f..270ff6dc8045 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -30,12 +30,15 @@ > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > #include > +#include > #include > #include > #include > #include > #include > +#include > #include > +#include > #include > #include > #include > @@ -1951,7 +1954,9 @@ static int drm_fb_helper_single_fb_probe(struct > drm_fb_helper *fb_helper, > if (fb_helper->fbdev->fbops->fb_open == drm_fb_helper_fb_open) > atomic_set(&fb_helper->open_count, 0); > > - strcpy(fb_helper->fb->comm, "[fbcon]"); > + if (fb_helper->fb) > + strcpy(fb_helper->fb->comm, "[fbcon]"); > + > return 0; > } > > @@ -2975,6 +2980,300 @@ void drm_fb_helper_output_poll_changed(struct > drm_device *dev) > } > EXPORT_SYMBOL(drm_fb_helper_output_poll_changed); > > +static struct fb_deferred_io drm_fb_helper_generic_defio = { > + .delay = HZ / 20, > + .deferred_io= drm_fb_helper_deferred_io, > +}; > + > +static int drm_fb_helper_generic_alloc_buf(struct drm_fb_helper *fb_helper) > +{ > + struct drm_fb_helper_surface_size *sizes = &fb_helper->sizes; > + struct drm_mode_create_dumb dumb_args = { 0 }; > + struct drm_prime_handle prime_args = { 0 }; > + struct drm_mode_fb_cmd2 fb_args = { 0 }; > + struct drm_device *dev = fb_helper->dev; > + struct fb_info *fbi = fb_helper->fbdev; > + struct drm_framebuffer *fb; > + struct dma_buf *dma_buf; > + struct drm_file *file; > + void *vaddr; > + int ret; > + > + file = drm_file_alloc(dev->primary); > + if (IS_ERR(file)) > + return PTR_ERR(file); > + > + drm_dropmaster_ioctl(dev, NULL, file); Hm why do we need this? Feels a bit like drm_file_alloc shouldn't do the entire master dance for us ... Otherwise this looks awesome, I really like it. Reviewed-by: Daniel Vetter -Daniel > + > + dumb_args.width = sizes->surface_width; > + dumb_args.height = sizes->surface_height; > + dumb_args.bpp = sizes->surface_bpp; > + ret = drm_mode_create_dumb_ioctl(dev, &dumb_args, file); > + if (ret) > + goto err_free_file; > + > + fb_args.width = dumb_args.width; > + fb_args.height = dumb_args.height; > + fb_args.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, > + sizes->surface_depth); > + fb_args.handles[0] = dumb_args.handle; > + fb_args.pitches[0] = dumb_args.pitch; > + ret = drm_mode_addfb2(dev, &fb_args, file); > + if (ret) > + goto err_free_file; > + > + fb = drm_framebuffer_lookup(dev, file, fb_args.fb_id); > + if (!fb) { > + ret = -ENOENT; > + goto err_free_file; > + } > + > + /* drop the reference we picked up in framebuffer lookup */ > + drm_framebuffer_put(fb); > + > + strcpy(fb->comm, "[fbcon]"); > + > + prime_args.handle = dumb_args.handle; > + ret = drm_prime_handle_to_fd_ioctl(dev, &prime_args, file); > + if (ret) > + goto err_free_file; > + > + dma_buf = dma_buf_get(prime_args.fd); > + if (WARN_ON(IS_ERR(dma_buf))) { > + ret = PTR_ERR(dma_buf); > + goto err_free_file; > + } > + > + vaddr = dma_buf_vmap(dma_buf); > + if (!vaddr) { > + ret = -ENOMEM; > + goto err_put_dmabuf; > + } > + > + if (fb->funcs->dirty) { > + fbi->fbdefio = &drm_fb_helper_generic_defio; > + fb_deferred_io_init(fbi); > + } > + > + fbi->screen_size = fb->height * fb->pitches[0]; > + fbi->fix.smem_len = fbi->screen_size; > + fbi->screen_buffer = vaddr; > + > + fb_helper->dma_buf = dma_buf; > + fb_helper->file = file; > + > + mutex_lock(&fb_helper->lock); > + fb_helper->fb = fb; > + drm_setup_crtcs_fb(fb_helper); > + mutex_unlock(&fb_helper->lock); > + > + /* First time setup */ > + if (!fbi->var.bits_per_pixel) { > + struct fb_videomode mode; > + > + drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->format->depth); > + drm_fb_helper_fill_var(fbi, fb_helper, sizes->fb_width, > sizes->fb_height); > + > + /* Drop the mode added by register_framebuffer() */ > + fb_destroy_modelist(&fb_helper->fbdev->modelist); > + > + fb_var_to_vide
Re: [PATCH] drm/bridge/synopsys: dsi: use common mipi_dsi_create_packet()
Hi Brian, And many thanks for implementing these TODOs. On 01/06/2018 01:38 AM, Brian Norris wrote: > This takes care of 2 TODOs in this driver, by using the common DSI > packet-marshalling code instead of our custom short/long write code. > This both saves us some duplicated code and gets us free support for > command types that weren't already part of our switch block (e.g., > MIPI_DSI_GENERIC_LONG_WRITE). > > The code logic stays mostly intact, except that it becomes unnecessary > to split the short/long write functions, and we have to copy data a bit > more. > > Along the way, I noticed that loop bounds were a little odd: > > while (DIV_ROUND_UP(len, pld_data_bytes)) > > This really was just supposed to be 'len != 0', so I made that more > clear. > > Tested on RK3399 with some pending refactoring patches by Nickey Yang, > to make the Rockchip DSI driver wrap this common driver. > > Signed-off-by: Brian Norris > --- > Could use an extra look from folks. This looks like the correct trivial > transformation, but I'm not that familiar with DSI. > > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 78 > ++- > 1 file changed, 16 insertions(+), 62 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > index d9cca4fd66ec..2fed20e44dfe 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > @@ -136,10 +136,6 @@ >GEN_SW_0P_TX_LP) > > #define DSI_GEN_HDR 0x6c > -/* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() > */ > -#define GEN_HDATA(data) (((data) & 0x) << 8) > -#define GEN_HTYPE(type) (((type) & 0xff) << 0) > - > #define DSI_GEN_PLD_DATA0x70 > > #define DSI_CMD_PKT_STATUS 0x74 > @@ -359,44 +355,15 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct > dw_mipi_dsi *dsi, u32 hdr_val) > return 0; > } > > -static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi, > -const struct mipi_dsi_msg *msg) > -{ > - const u8 *tx_buf = msg->tx_buf; > - u16 data = 0; > - u32 val; > - > - if (msg->tx_len > 0) > - data |= tx_buf[0]; > - if (msg->tx_len > 1) > - data |= tx_buf[1] << 8; > - > - if (msg->tx_len > 2) { > - dev_err(dsi->dev, "too long tx buf length %zu for short > write\n", > - msg->tx_len); > - return -EINVAL; > - } > - > - val = GEN_HDATA(data) | GEN_HTYPE(msg->type); > - return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val); > -} > - > -static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, > - const struct mipi_dsi_msg *msg) > +static int dw_mipi_dsi_dcs_write(struct dw_mipi_dsi *dsi, > + const struct mipi_dsi_packet *packet) Both DCS and Generic dsi transfers are managed by drm_mipi_dsi.c helpers. So maybe dw_mipi_dsi_dcs_write() should be renamed dw_mipi_dsi_write()... > { > - const u8 *tx_buf = msg->tx_buf; > - int len = msg->tx_len, pld_data_bytes = sizeof(u32), ret; > - u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type); > + const u8 *tx_buf = packet->payload; > + int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret; > u32 remainder; > u32 val; > > - if (msg->tx_len < 3) { > - dev_err(dsi->dev, "wrong tx buf length %zu for long write\n", > - msg->tx_len); > - return -EINVAL; > - } > - > - while (DIV_ROUND_UP(len, pld_data_bytes)) { > + while (len) { > if (len < pld_data_bytes) { > remainder = 0; > memcpy(&remainder, tx_buf, len); > @@ -419,40 +386,27 @@ static int dw_mipi_dsi_dcs_long_write(struct > dw_mipi_dsi *dsi, > } > } > > - return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val); > + remainder = 0; > + memcpy(&remainder, packet->header, sizeof(packet->header)); > + return dw_mipi_dsi_gen_pkt_hdr_write(dsi, remainder); > } > > static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, >const struct mipi_dsi_msg *msg) > { > struct dw_mipi_dsi *dsi = host_to_dsi(host); > + struct mipi_dsi_packet packet; > int ret; > > - /* > - * TODO dw drv improvements > - * use mipi_dsi_create_packet() instead of all following > - * functions and code (no switch cases, no > - * dw_mipi_dsi_dcs_short_write(), only the loop in long_write...) > - * and use packet.header... > - */ > - dw_mipi_message_config(dsi, msg); > - > - switch (msg->type) { > - case MIPI_DSI_DCS_SHORT_WRITE: > - case MIPI_DSI_DCS_SHORT_WRITE_PARAM: > -
[PATCH 10/19] drm/sun4i: backend: Fix define typo
There was a typo in the width spelling of the (unused) SUN4I_BACKEND_IYUVLINEWITDTH_REG macro. Fix it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h index b5edf2d50a24..1ca8b7db6807 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.h +++ b/drivers/gpu/drm/sun4i/sun4i_backend.h @@ -112,7 +112,9 @@ #define SUN4I_BACKEND_SPRALPHACTL_REG 0x90c #define SUN4I_BACKEND_IYUVCTL_REG 0x920 #define SUN4I_BACKEND_IYUVADD_REG(c) (0x930 + (0x4 * (c))) -#define SUN4I_BACKEND_IYUVLINEWITDTH_REG(c)(0x940 + (0x4 * (c))) + +#define SUN4I_BACKEND_IYUVLINEWIDTH_REG(c) (0x940 + (0x4 * (c))) + #define SUN4I_BACKEND_YGCOEF_REG(c)(0x950 + (0x4 * (c))) #define SUN4I_BACKEND_YGCONS_REG 0x95c #define SUN4I_BACKEND_URCOEF_REG(c)(0x960 + (0x4 * (c))) -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 12/19] drm/sun4i: backend: Move the coord function in the shared part
The function supposed to update a plane's coordinates is called in both branches of our function. Let's move it out the if statement. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_layer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index f03da16eb92a..c448cb6b9fa9 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -106,14 +106,13 @@ static void sun4i_backend_layer_atomic_update(struct drm_plane *plane, DRM_FORMAT_ARGB); sun4i_backend_update_layer_frontend(backend, layer->id, DRM_FORMAT_ARGB); - sun4i_backend_update_layer_coord(backend, layer->id, plane); sun4i_frontend_enable(frontend); } else { - sun4i_backend_update_layer_coord(backend, layer->id, plane); sun4i_backend_update_layer_formats(backend, layer->id, plane); sun4i_backend_update_layer_buffer(backend, layer->id, plane); } + sun4i_backend_update_layer_coord(backend, layer->id, plane); sun4i_backend_layer_enable(backend, layer->id, true); } -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 11/19] drm/sun4i: framebuffer: Add a custom atomic_check
In order to support normalized zpos, we need to call drm_atomic_normalize_zpos in our driver's drm_mode_config_funcs' atomic_check. Let's duplicate the definition of drm_atomic_helper_check for now. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c index a01a5b7d46e6..e68004844abe 100644 --- a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c +++ b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c @@ -26,9 +26,21 @@ static void sun4i_de_output_poll_changed(struct drm_device *drm) drm_fbdev_cma_hotplug_event(drv->fbdev); } +static int sun4i_de_atomic_check(struct drm_device *dev, +struct drm_atomic_state *state) +{ + int ret; + + ret = drm_atomic_helper_check_modeset(dev, state); + if (ret) + return ret; + + return drm_atomic_helper_check_planes(dev, state); +} + static const struct drm_mode_config_funcs sun4i_de_mode_config_funcs = { .output_poll_changed= sun4i_de_output_poll_changed, - .atomic_check = drm_atomic_helper_check, + .atomic_check = sun4i_de_atomic_check, .atomic_commit = drm_atomic_helper_commit, .fb_create = drm_gem_fb_create, }; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 00/19] drm/sun4i: Support more planes, zpos and plane-wide alpha
Hi, This serie aims at enhancing the support for our planes in the current drm driver on the first generation of Allwinner's display engine. This also introduces a few generic stuff, as well as some conversion for some other drivers. This series basically implements three things that look orthogonal, but due to the way the hardware works are kind of related. The main feature is that instead of implementing 2 planes per backend, we are now able to use the planes that are available in hardware. This was unsupported before because of the way the composition works in the hardware. Indeed, the planes are first grouped into 2 pipes that are doing a basic composition, in case of overlapping planes, it just takes whatever plane has the highest priority (=> zpos). Then, the alpha blending is done between the two pipes. This was simplified so far by only using two planes, one for each pipe, which was allowing us to have an illusion of proper alpha blending. This is further complicated by the bug/feature that the lowest plane must not have any alpha at all, otherwise the pixel will turn black, no matter what the value of alpha is. This basically means that we can have a plane with alpha only in the second pipe. However, as we have more and more blocks being worked on, 2 planes are getting really limited and we need to support all 4 of them. This is mostly possible by extending our atomic_check and to make sure that we enforce those constraints, and assign the pipes automatically. This is done by looking at the number of planes using an alpha component, and we then end up in various scenarios: - 0 plane with alpha => we don't care for the pipes at all. All the planes are assigned to the first pipe - 1 plane with alpha => we assign all the planes without alpha below the plane with alpha to the first pipe, and then all the remaining planes to the second pipe. The plane with alpha will be the lowest plane on that pipe, which means that whatever plane is above it will have precedence, but the alpha component will remain and will be used on pixels that are not overlapping - 2-4 planes with alpha => we can't operate that way, we just reject the configuration. In addition to the formats that embed an alpha component, we also add support for plane-wide alpha property, and in order to tweak the configuration the way we want to, we also add support for configurable zpos. Let me know what you think, Maxime Maxime Ripard (19): drm/fourcc: Add a function to tell if the format embeds alpha drm/atmel-hlcdc: Use the alpha format helper drm/exynos: Use the alpha format helper drm/rockchip: Use the alpha format helper drm/vc4: Use the alpha format helper drm/blend: Add a generic alpha property drm/atmel-hclcdc: Convert to the new generic alpha property drm/rcar-du: Convert to the new generic alpha property drm/sun4i: backend: Fix structure indentation drm/sun4i: backend: Fix define typo drm/sun4i: framebuffer: Add a custom atomic_check drm/sun4i: backend: Move the coord function in the shared part drm/sun4i: backend: Set a default zpos in our reset hook drm/sun4i: backend: Add support for zpos drm/sun4i: backend: Check for the number of alpha planes drm/sun4i: backend: Assign the pipes automatically drm/sun4i: backend: Make zpos configurable drm/sun4i: Add support for plane alpha drm/sun4i: backend: Remove ARGB spoofing Documentation/gpu/kms-properties.csv| 2 +- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h| 13 +-- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 109 ++- drivers/gpu/drm/drm_atomic.c| 4 +- drivers/gpu/drm/drm_atomic_helper.c | 1 +- drivers/gpu/drm/drm_blend.c | 32 - drivers/gpu/drm/drm_fourcc.c| 43 ++- drivers/gpu/drm/exynos/exynos_mixer.c | 14 +-- drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 +- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 15 +-- drivers/gpu/drm/rcar-du/rcar_du_plane.h | 2 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 42 +-- drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 +-- drivers/gpu/drm/sun4i/sun4i_backend.c | 126 +++-- drivers/gpu/drm/sun4i/sun4i_backend.h | 11 +- drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 18 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 84 ++- drivers/gpu/drm/sun4i/sun4i_layer.h | 1 +- drivers/gpu/drm/vc4/vc4_plane.c | 19 +-- include/drm/drm_blend.h | 1 +- include/drm/drm_fourcc.h| 1 +- include/drm/drm_plane.h | 6 +- 24 files changed, 289 insertions(+), 276 deletions(-) base-commit: 53b519deaf2e507b121b64
[PATCH 03/19] drm/exynos: Use the alpha format helper
Now that the core has a drm format helper to tell if a format embeds an alpha component in it, let's use it. Cc: Inki Dae Cc: Joonyoung Shim Cc: Kyungmin Park Cc: Seung-Woo Kim Signed-off-by: Maxime Ripard --- drivers/gpu/drm/exynos/exynos_mixer.c | 14 +- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index dc5d79465f9b..d7339a6d072c 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -179,18 +179,6 @@ static const u8 filter_cr_horiz_tap4[] = { 70, 59, 48, 37, 27, 19, 11, 5, }; -static inline bool is_alpha_format(unsigned int pixel_format) -{ - switch (pixel_format) { - case DRM_FORMAT_ARGB: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_ARGB: - return true; - default: - return false; - } -} - static inline u32 vp_reg_read(struct mixer_context *ctx, u32 reg_id) { return readl(ctx->vp_regs + reg_id); @@ -625,7 +613,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx, mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr); mixer_cfg_layer(ctx, win, priority, true); - mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format)); + mixer_cfg_gfx_blend(ctx, win, drm_format_has_alpha(fb->format->format)); /* layer update mandatory for mixer 16.0.33.0 */ if (ctx->mxr_ver == MXR_VER_16_0_33_0 || -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 05/19] drm/vc4: Use the alpha format helper
Now that the core has a drm format helper to tell if a format embeds an alpha component in it, let's use it. Cc: Eric Anholt Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_plane.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 423a23ed8fc2..2c0e25128dcd 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -85,40 +85,39 @@ static const struct hvs_format { u32 drm; /* DRM_FORMAT_* */ u32 hvs; /* HVS_FORMAT_* */ u32 pixel_order; - bool has_alpha; bool flip_cbcr; } hvs_formats[] = { { .drm = DRM_FORMAT_XRGB, .hvs = HVS_PIXEL_FORMAT_RGBA, - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false, + .pixel_order = HVS_PIXEL_ORDER_ABGR, }, { .drm = DRM_FORMAT_ARGB, .hvs = HVS_PIXEL_FORMAT_RGBA, - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, + .pixel_order = HVS_PIXEL_ORDER_ABGR, }, { .drm = DRM_FORMAT_ABGR, .hvs = HVS_PIXEL_FORMAT_RGBA, - .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = true, + .pixel_order = HVS_PIXEL_ORDER_ARGB, }, { .drm = DRM_FORMAT_XBGR, .hvs = HVS_PIXEL_FORMAT_RGBA, - .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = false, + .pixel_order = HVS_PIXEL_ORDER_ARGB, }, { .drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565, - .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false, + .pixel_order = HVS_PIXEL_ORDER_XRGB, }, { .drm = DRM_FORMAT_BGR565, .hvs = HVS_PIXEL_FORMAT_RGB565, - .pixel_order = HVS_PIXEL_ORDER_XBGR, .has_alpha = false, + .pixel_order = HVS_PIXEL_ORDER_XBGR, }, { .drm = DRM_FORMAT_ARGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, + .pixel_order = HVS_PIXEL_ORDER_ABGR, }, { .drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false, + .pixel_order = HVS_PIXEL_ORDER_ABGR, }, { .drm = DRM_FORMAT_YUV422, @@ -601,7 +600,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, /* Position Word 2: Source Image Size, Alpha Mode */ vc4_state->pos2_offset = vc4_state->dlist_count; vc4_dlist_write(vc4_state, - VC4_SET_FIELD(format->has_alpha ? + VC4_SET_FIELD(drm_format_has_alpha(format->drm) ? SCALER_POS2_ALPHA_MODE_PIPELINE : SCALER_POS2_ALPHA_MODE_FIXED, SCALER_POS2_ALPHA_MODE) | -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 04/19] drm/rockchip: Use the alpha format helper
Now that the core has a drm format helper to tell if a format embeds an alpha component in it, let's use it. Cc: Mark Yao Signed-off-by: Maxime Ripard --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 19128b4dea54..cfc4d4909185 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -253,17 +253,6 @@ static bool is_yuv_support(uint32_t format) } } -static bool is_alpha_support(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_ARGB: - case DRM_FORMAT_ABGR: - return true; - default: - return false; - } -} - static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src, uint32_t dst, bool is_horizontal, int vsu_mode, int *vskiplines) @@ -790,7 +779,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, rb_swap = has_rb_swapped(fb->format->format); VOP_WIN_SET(vop, win, rb_swap, rb_swap); - if (is_alpha_support(fb->format->format)) { + if (drm_format_has_alpha(fb->format->format)) { VOP_WIN_SET(vop, win, dst_alpha_ctl, DST_FACTOR_M0(ALPHA_SRC_INVERSE)); val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) | -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 14/19] drm/sun4i: backend: Add support for zpos
Our various planes have a configurable zpos, that combined with the pipes allow to configure the composition. Since the interaction between the pipes, zpos and alphas framebuffers are not trivials, let's just enable the zpos as an immutable property for now, and use that zpos in our atomic_update part. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 15 +++ drivers/gpu/drm/sun4i/sun4i_backend.h | 2 ++ drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 4 drivers/gpu/drm/sun4i/sun4i_layer.c | 3 +++ 4 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index a18c86a15748..c4986054909b 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -272,6 +272,21 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, return 0; } +int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer, + struct drm_plane *plane) +{ + struct drm_plane_state *state = plane->state; + unsigned int priority = state->normalized_zpos; + + DRM_DEBUG_DRIVER("Setting layer %d priority to %d\n", layer, priority); + + regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer), + SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK, + SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority)); + + return 0; +} + static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state) { u16 src_h = state->src_h >> 16; diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h index 1ca8b7db6807..04a4f11b87a8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.h +++ b/drivers/gpu/drm/sun4i/sun4i_backend.h @@ -182,5 +182,7 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, int layer, struct drm_plane *plane); int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend, int layer, uint32_t in_fmt); +int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, + int layer, struct drm_plane *plane); #endif /* _SUN4I_BACKEND_H_ */ diff --git a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c index e68004844abe..5b3986437a50 100644 --- a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c +++ b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c @@ -35,6 +35,10 @@ static int sun4i_de_atomic_check(struct drm_device *dev, if (ret) return ret; + ret = drm_atomic_normalize_zpos(dev, state); + if (ret) + return ret; + return drm_atomic_helper_check_planes(dev, state); } diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 03549646528a..fbf25d59cf88 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -115,6 +115,7 @@ static void sun4i_backend_layer_atomic_update(struct drm_plane *plane, } sun4i_backend_update_layer_coord(backend, layer->id, plane); + sun4i_backend_update_layer_zpos(backend, layer->id, plane); sun4i_backend_layer_enable(backend, layer->id, true); } @@ -237,6 +238,8 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm, return ERR_CAST(layer); }; + drm_plane_create_zpos_immutable_property(&layer->plane, i); + DRM_DEBUG_DRIVER("Assigning %s plane to pipe %d\n", i ? "overlay" : "primary", plane->pipe); regmap_update_bits(engine->regs, SUN4I_BACKEND_ATTCTL_REG0(i), -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 01/19] drm/fourcc: Add a function to tell if the format embeds alpha
There's a bunch of drivers that duplicate the same function to know if a particular format embeds an alpha component or not. Let's create a helper to avoid duplicating that logic. Cc: Boris Brezillon Cc: Eric Anholt Cc: Inki Dae Cc: Joonyoung Shim Cc: Kyungmin Park Cc: Laurent Pinchart Cc: Mark Yao Cc: Seung-Woo Kim Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_fourcc.c | 43 +- include/drm/drm_fourcc.h | 1 +- 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index 9c0152df45ad..6e6227d6a46b 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t format, int plane) return height / info->vsub; } EXPORT_SYMBOL(drm_format_plane_height); + +/** + * drm_format_has_alpha - get whether the format embeds an alpha component + * @format: pixel format (DRM_FORMAT_*) + * + * Returns: + * true if the format embeds an alpha component, false otherwise. + */ +bool drm_format_has_alpha(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_RGBA: + case DRM_FORMAT_BGRA: + case DRM_FORMAT_ARGB1555: + case DRM_FORMAT_ABGR1555: + case DRM_FORMAT_RGBA5551: + case DRM_FORMAT_BGRA5551: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_RGBA: + case DRM_FORMAT_BGRA: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_BGRA1010102: + case DRM_FORMAT_AYUV: + case DRM_FORMAT_XRGB_A8: + case DRM_FORMAT_XBGR_A8: + case DRM_FORMAT_RGBX_A8: + case DRM_FORMAT_BGRX_A8: + case DRM_FORMAT_RGB888_A8: + case DRM_FORMAT_BGR888_A8: + case DRM_FORMAT_RGB565_A8: + case DRM_FORMAT_BGR565_A8: + return true; + + default: + return false; + } +} +EXPORT_SYMBOL(drm_format_has_alpha); diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h index 6942e84b6edd..e08fc22c5f78 100644 --- a/include/drm/drm_fourcc.h +++ b/include/drm/drm_fourcc.h @@ -69,5 +69,6 @@ int drm_format_vert_chroma_subsampling(uint32_t format); int drm_format_plane_width(int width, uint32_t format, int plane); int drm_format_plane_height(int height, uint32_t format, int plane); const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf); +bool drm_format_has_alpha(uint32_t format); #endif /* __DRM_FOURCC_H__ */ -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 07/19] drm/atmel-hclcdc: Convert to the new generic alpha property
Now that we have support for per-plane alpha in the core, let's use it. Cc: Boris Brezillon Signed-off-by: Maxime Ripard --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h| 13 +--- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 89 ++ 2 files changed, 14 insertions(+), 88 deletions(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h index 6833ee253cfa..704cac6399eb 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h @@ -298,7 +298,6 @@ struct atmel_hlcdc_layer { struct atmel_hlcdc_plane { struct drm_plane base; struct atmel_hlcdc_layer layer; - struct atmel_hlcdc_plane_properties *properties; }; static inline struct atmel_hlcdc_plane * @@ -345,18 +344,6 @@ struct atmel_hlcdc_dc_desc { }; /** - * Atmel HLCDC Plane properties. - * - * This structure stores plane property definitions. - * - * @alpha: alpha blending (or transparency) property - * @rotation: rotation property - */ -struct atmel_hlcdc_plane_properties { - struct drm_property *alpha; -}; - -/** * Atmel HLCDC Display Controller. * * @desc: HLCDC Display Controller description diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index 1a9318810a29..dbc508889e87 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -31,7 +31,6 @@ * @src_y: y buffer position * @src_w: buffer width * @src_h: buffer height - * @alpha: alpha blending of the plane * @disc_x: x discard position * @disc_y: y discard position * @disc_w: discard width @@ -54,8 +53,6 @@ struct atmel_hlcdc_plane_state { uint32_t src_w; uint32_t src_h; - u8 alpha; - int disc_x; int disc_y; int disc_w; @@ -385,7 +382,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, cfg |= ATMEL_HLCDC_LAYER_LAEN; else cfg |= ATMEL_HLCDC_LAYER_GAEN | - ATMEL_HLCDC_LAYER_GA(state->alpha); + ATMEL_HLCDC_LAYER_GA(state->base.alpha); } if (state->disc_h && state->disc_w) @@ -553,7 +550,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state) if (!ovl_s->fb || drm_format_has_alpha(ovl_s->fb->format->format) || - ovl_state->alpha != 255) + ovl_s->alpha != 255) continue; /* TODO: implement a smarter hidden area detection */ @@ -829,51 +826,18 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p) drm_plane_cleanup(p); } -static int atmel_hlcdc_plane_atomic_set_property(struct drm_plane *p, -struct drm_plane_state *s, -struct drm_property *property, -uint64_t val) -{ - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); - struct atmel_hlcdc_plane_properties *props = plane->properties; - struct atmel_hlcdc_plane_state *state = - drm_plane_state_to_atmel_hlcdc_plane_state(s); - - if (property == props->alpha) - state->alpha = val; - else - return -EINVAL; - - return 0; -} - -static int atmel_hlcdc_plane_atomic_get_property(struct drm_plane *p, - const struct drm_plane_state *s, - struct drm_property *property, - uint64_t *val) -{ - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); - struct atmel_hlcdc_plane_properties *props = plane->properties; - const struct atmel_hlcdc_plane_state *state = - container_of(s, const struct atmel_hlcdc_plane_state, base); - - if (property == props->alpha) - *val = state->alpha; - else - return -EINVAL; - - return 0; -} - -static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane, - struct atmel_hlcdc_plane_properties *props) +static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane) { const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER || - desc->type == ATMEL_HLCDC_CURSOR_LAYER) - drm_object_attach_property(&plane->base.base, - props->alpha, 255); + desc->type == ATMEL_HLCDC_CURSOR_LAYER) { + int ret; + + ret = drm_plane_create_alpha_property(&plane->base, 255); + if (ret) + return ret; +
[PATCH 06/19] drm/blend: Add a generic alpha property
Some drivers duplicate the logic to create a property to store a per-plane alpha. Let's create a helper in order to move that to the core. Cc: Boris Brezillon Cc: Laurent Pinchart Signed-off-by: Maxime Ripard --- Documentation/gpu/kms-properties.csv | 2 +- drivers/gpu/drm/drm_atomic.c | 4 - drivers/gpu/drm/drm_atomic_helper.c | 1 +- drivers/gpu/drm/drm_blend.c | 32 +- include/drm/drm_blend.h | 1 +- include/drm/drm_plane.h | 6 +- 6 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv index 927b65e14219..a3c3969c1992 100644 --- a/Documentation/gpu/kms-properties.csv +++ b/Documentation/gpu/kms-properties.csv @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from transparent (0) to opaque (255) ,,"""colorkey""",RANGE,"Min=0, Max=0x01ff",Plane,TBD diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index c2da5585e201..ade18cf62c89 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_w = val; } else if (property == config->prop_src_h) { state->src_h = val; + } else if (property == plane->alpha_property) { + state->alpha = val; } else if (property == plane->rotation_property) { if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) return -EINVAL; @@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->src_w; } else if (property == config->prop_src_h) { *val = state->src_h; + } else if (property == plane->alpha_property) { + *val = state->alpha; } else if (property == plane->rotation_property) { *val = state->rotation; } else if (property == plane->zpos_property) { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 71d712f1b56a..018993df4c18 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane) if (plane->state) { plane->state->plane = plane; + plane->state->alpha = 255; plane->state->rotation = DRM_MODE_ROTATE_0; } } diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index 2e5e089dd912..8eea2a8af458 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -104,6 +104,38 @@ */ /** + * drm_plane_create_alpha_property - create a new alpha property + * @plane: drm plane + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque) + * + * This function initializes a generic, mutable, alpha property and + * enables support for it in the DRM core. + * + * Drivers can then attach this property to their plane to enable + * support for configurable plane alpha. + * + * Returns: + * 0 on success, negative error code on failure. + */ +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha) +{ + struct drm_property *prop; + + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255); + if (!prop) + return -ENOMEM; + + drm_object_attach_property(&plane->base, prop, alpha); + plane->alpha_property = prop; + + if (plane->state) + plane->state->alpha = alpha; + + return 0; +} +EXPORT_SYMBOL(drm_plane_create_alpha_property); + +/** * drm_plane_create_rotation_property - create a new rotation property * @plane: drm plane * @rotation: initial value of the rotation property diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h index 17606026590b..5979a8fce453 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h @@ -36,6 +36,7 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation) return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270); } +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha); int drm_plane_create_rotation_property(struct drm_plane *plane, unsigned int rotation, unsigned int supported_rotations); diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 571615079230..a5e26064b132 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -42,6 +42,7 @@ struct drm_modeset_acquire_ct
[PATCH 09/19] drm/sun4i: backend: Fix structure indentation
The sun4i_plane_desc structure was somehow indented to two tabulations instead of one as we shoud do. Fix that. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_layer.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 4652b25be0d2..f03da16eb92a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -20,10 +20,10 @@ #include "sunxi_engine.h" struct sun4i_plane_desc { - enum drm_plane_type type; - u8 pipe; - const uint32_t *formats; - uint32_tnformats; + enum drm_plane_type type; + u8 pipe; + const uint32_t *formats; + uint32_tnformats; }; static void sun4i_backend_layer_reset(struct drm_plane *plane) -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 02/19] drm/atmel-hlcdc: Use the alpha format helper
Now that the core has a drm format helper to tell if a format embeds an alpha component in it, let's use it. Cc: Boris Brezillon Signed-off-by: Maxime Ripard --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 20 ++ 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index 703c2d13603f..1a9318810a29 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -194,20 +194,6 @@ static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode) return 0; } -static bool atmel_hlcdc_format_embeds_alpha(u32 format) -{ - int i; - - for (i = 0; i < sizeof(format); i++) { - char tmp = (format >> (8 * i)) & 0xff; - - if (tmp == 'A') - return true; - } - - return false; -} - static u32 heo_downscaling_xcoef[] = { 0x11343311, 0x00f7, @@ -395,7 +381,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL | ATMEL_HLCDC_LAYER_ITER; - if (atmel_hlcdc_format_embeds_alpha(format)) + if (drm_format_has_alpha(format)) cfg |= ATMEL_HLCDC_LAYER_LAEN; else cfg |= ATMEL_HLCDC_LAYER_GAEN | @@ -566,7 +552,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state) ovl_state = drm_plane_state_to_atmel_hlcdc_plane_state(ovl_s); if (!ovl_s->fb || - atmel_hlcdc_format_embeds_alpha(ovl_s->fb->format->format) || + drm_format_has_alpha(ovl_s->fb->format->format) || ovl_state->alpha != 255) continue; @@ -769,7 +755,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, if ((state->crtc_h != state->src_h || state->crtc_w != state->src_w) && (!desc->layout.memsize || -atmel_hlcdc_format_embeds_alpha(state->base.fb->format->format))) +drm_format_has_alpha(state->base.fb->format->format))) return -EINVAL; if (state->crtc_x < 0 || state->crtc_y < 0) -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 08/19] drm/rcar-du: Convert to the new generic alpha property
Now that we have support for per-plane alpha in the core, let's use it. Cc: Laurent Pinchart Signed-off-by: Maxime Ripard --- drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 +- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 +--- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 15 +++-- drivers/gpu/drm/rcar-du/rcar_du_plane.h | 2 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 42 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +- 6 files changed, 9 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index f8cd79488ece..aff04adaae53 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h @@ -89,7 +89,6 @@ struct rcar_du_device { struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS]; struct { - struct drm_property *alpha; struct drm_property *colorkey; } props; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 566d1a948c8f..e1b5a7b460cc 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -417,11 +417,6 @@ static int rcar_du_encoders_init(struct rcar_du_device *rcdu) static int rcar_du_properties_init(struct rcar_du_device *rcdu) { - rcdu->props.alpha = - drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255); - if (rcdu->props.alpha == NULL) - return -ENOMEM; - /* * The color key is expressed as an RGB888 triplet stored in a 32-bit * integer in XRGB format. Bit 24 is used as a flag to disable (0) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 61833cc1c699..5b34e8092c8b 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -423,7 +423,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp, rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0); else rcar_du_plane_write(rgrp, index, PnALPHAR, - PnALPHAR_ABIT_X | state->alpha); + PnALPHAR_ABIT_X | state->state.alpha); pnmr = PnMR_BM_MD | state->format->pnmr; @@ -667,11 +667,11 @@ static void rcar_du_plane_reset(struct drm_plane *plane) state->hwindex = -1; state->source = RCAR_DU_PLANE_MEMORY; - state->alpha = 255; state->colorkey = RCAR_DU_COLORKEY_NONE; state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; plane->state = &state->state; + plane->state->alpha = 255; plane->state->plane = plane; } @@ -683,9 +683,7 @@ static int rcar_du_plane_atomic_set_property(struct drm_plane *plane, struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev; - if (property == rcdu->props.alpha) - rstate->alpha = val; - else if (property == rcdu->props.colorkey) + if (property == rcdu->props.colorkey) rstate->colorkey = val; else return -EINVAL; @@ -701,9 +699,7 @@ static int rcar_du_plane_atomic_get_property(struct drm_plane *plane, container_of(state, const struct rcar_du_plane_state, state); struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev; - if (property == rcdu->props.alpha) - *val = rstate->alpha; - else if (property == rcdu->props.colorkey) + if (property == rcdu->props.colorkey) *val = rstate->colorkey; else return -EINVAL; @@ -772,10 +768,9 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp) continue; drm_object_attach_property(&plane->plane.base, - rcdu->props.alpha, 255); - drm_object_attach_property(&plane->plane.base, rcdu->props.colorkey, RCAR_DU_COLORKEY_NONE); + drm_plane_create_alpha_property(&plane->plane, 255); drm_plane_create_zpos_property(&plane->plane, 1, 1, 7); } diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h index f62e09f195de..2dc793ebd1a2 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h @@ -50,7 +50,6 @@ static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane) * @state: base DRM plane state * @format: information about the pixel format used by the plane * @hwindex: 0-based hardware plane index, -1 means unused - * @alpha: value of the plane alpha property * @colorkey: value of the plane colorkey property */ struct rcar_du_plane_state { @@ -60,7 +59,6 @@ struct rcar_du_plan
[PATCH 16/19] drm/sun4i: backend: Assign the pipes automatically
Since we now have a way to enforce the zpos, check for the number of alpha planes, the only missing part is to assign our pipe automatically instead of hardcoding it. The algorithm is quite simple, but requires two iterations over the list of planes. In the first one (which is the same one that we've had to check for alpha, the frontend usage, and so on), we order the planes by their zpos. We can then do a second iteration over that array by ascending zpos starting with the pipe 0. When and if we encounter our alpha plane, we put it and all the other subsequent planes in the second pipe. And since we have runtime checks and pipe assignments now, we can just remove the static declaration of the planes we used to have. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 41 +-- drivers/gpu/drm/sun4i/sun4i_layer.c | 50 drivers/gpu/drm/sun4i/sun4i_layer.h | 1 +- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index dd995a6b8b12..ad370ce66b4d 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -276,12 +276,16 @@ int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; + struct sun4i_layer_state *p_state = state_to_sun4i_layer_state(state); unsigned int priority = state->normalized_zpos; + unsigned int pipe = p_state->pipe; - DRM_DEBUG_DRIVER("Setting layer %d priority to %d\n", layer, priority); - + DRM_DEBUG_DRIVER("Setting layer %d priority to %d and pipe %d\n", +layer, priority, pipe); regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer), + SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK | SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK, + SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(p_state->pipe) | SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority)); return 0; @@ -326,12 +330,15 @@ static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct drm_crtc_state *crtc_state) { + struct drm_plane_state *plane_states[SUN4I_BACKEND_NUM_LAYERS] = { 0 }; struct drm_atomic_state *state = crtc_state->state; struct drm_device *drm = state->dev; struct drm_plane *plane; unsigned int num_planes = 0; unsigned int num_alpha_planes = 0; unsigned int num_frontend_planes = 0; + unsigned int current_pipe = 0; + unsigned int i; DRM_DEBUG_DRIVER("Starting checking our planes\n"); @@ -344,6 +351,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(plane_state); struct drm_framebuffer *fb = plane_state->fb; + struct drm_format_name_buf format_name; if (sun4i_backend_plane_uses_frontend(plane_state)) { DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", @@ -361,9 +369,19 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, if (drm_format_has_alpha(fb->format->format)) num_alpha_planes++; + DRM_DEBUG_DRIVER("Plane zpos is %d\n", +plane_state->normalized_zpos); + + /* Sort our planes by Zpos */ + plane_states[plane_state->normalized_zpos] = plane_state; + num_planes++; } + /* All our planes were disabled, bail out */ + if (!num_planes) + return 0; + /* * The hardware is a bit unusual here. * @@ -400,6 +418,25 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, return -EINVAL; } + /* We can't have an alpha plane at the lowest position */ + if (drm_format_has_alpha(plane_states[0]->fb->format->format)) + return -EINVAL; + + for (i = 1; i < num_planes; i++) { + struct drm_plane_state *p_state = plane_states[i]; + struct drm_framebuffer *fb = p_state->fb; + struct sun4i_layer_state *s_state = state_to_sun4i_layer_state(p_state); + + /* +* The only alpha position is the lowest plane of the +* second pipe. +*/ + if (drm_format_has_alpha(fb->format->format)) + current_pipe++; + + s_state->pipe = current_pipe; + } + if (num_frontend_planes > SUN4I_BACKEND_NUM_FRON
[PATCH 17/19] drm/sun4i: backend: Make zpos configurable
Now that we have everything in place, we can make zpos configurable now. Change the zpos property from an immutable one to a regular. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_layer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index ec7b906dbb84..9e538f761dcb 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -163,6 +163,9 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, &sun4i_backend_layer_helper_funcs); layer->backend = backend; + drm_plane_create_zpos_property(&layer->plane, 0, 0, + SUN4I_BACKEND_NUM_LAYERS - 1); + return layer; } @@ -189,8 +192,6 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm, return ERR_CAST(layer); }; - drm_plane_create_zpos_immutable_property(&layer->plane, i); - layer->id = i; planes[i] = &layer->plane; }; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 18/19] drm/sun4i: Add support for plane alpha
Our backend supports a per-plane alpha property. Support it through our new helper. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 18 +++--- drivers/gpu/drm/sun4i/sun4i_backend.h | 3 +++ drivers/gpu/drm/sun4i/sun4i_layer.c | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index ad370ce66b4d..ec47098bfdb2 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -191,6 +191,15 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n", interlaced ? "on" : "off"); + val = SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA(state->alpha); + if (state->alpha != 255) + val |= SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN; + regmap_update_bits(backend->engine.regs, + SUN4I_BACKEND_ATTCTL_REG0(layer), + SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_MASK | + SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN, + val); + ret = sun4i_backend_drm_format_to_layer(plane, fb->format->format, &val); if (ret) { @@ -366,7 +375,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, DRM_DEBUG_DRIVER("Plane FB format is %s\n", drm_get_format_name(fb->format->format, &format_name)); - if (drm_format_has_alpha(fb->format->format)) + if (drm_format_has_alpha(fb->format->format) || + (plane_state->alpha != 255)) num_alpha_planes++; DRM_DEBUG_DRIVER("Plane zpos is %d\n", @@ -419,7 +429,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, } /* We can't have an alpha plane at the lowest position */ - if (drm_format_has_alpha(plane_states[0]->fb->format->format)) + if (drm_format_has_alpha(plane_states[0]->fb->format->format) || + (plane_states[0]->alpha != 255)) return -EINVAL; for (i = 1; i < num_planes; i++) { @@ -431,7 +442,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, * The only alpha position is the lowest plane of the * second pipe. */ - if (drm_format_has_alpha(fb->format->format)) + if (drm_format_has_alpha(fb->format->format) || + (p_state->alpha != 255)) current_pipe++; s_state->pipe = current_pipe; diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h index 52e77591186a..03294d5dd1a2 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.h +++ b/drivers/gpu/drm/sun4i/sun4i_backend.h @@ -68,11 +68,14 @@ #define SUN4I_BACKEND_CKMIN_REG0x884 #define SUN4I_BACKEND_CKCFG_REG0x888 #define SUN4I_BACKEND_ATTCTL_REG0(l) (0x890 + (0x4 * (l))) +#define SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_MASKGENMASK(31, 24) +#define SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA(x) ((x) << 24) #define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK BIT(15) #define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(x) ((x) << 15) #define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK GENMASK(11, 10) #define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(x)((x) << 10) #define SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOENBIT(1) +#define SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN BIT(0) #define SUN4I_BACKEND_ATTCTL_REG1(l) (0x8a0 + (0x4 * (l))) #define SUN4I_BACKEND_ATTCTL_REG1_LAY_HSCAFCT GENMASK(15, 14) diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 9e538f761dcb..d5598de92f85 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -37,6 +37,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane) if (state) { plane->state = &state->state; plane->state->plane = plane; + plane->state->alpha = 255; plane->state->zpos = layer->id; } } @@ -163,6 +164,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, &sun4i_backend_layer_helper_funcs); layer->backend = backend; + drm_plane_create_alpha_property(&layer->plane, 255); drm_plane_create_zpos_property(&layer->plane, 0, 0, SUN4I_BACKEND_NUM_LAYERS - 1); -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.free
[PATCH 13/19] drm/sun4i: backend: Set a default zpos in our reset hook
The our plane state zpos value will be set only if there's an existing state attached to the plane when creating the property. However, this is not the case during the probe, and we therefore need to put our default value in our reset hook. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index c448cb6b9fa9..03549646528a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -28,6 +28,7 @@ struct sun4i_plane_desc { static void sun4i_backend_layer_reset(struct drm_plane *plane) { + struct sun4i_layer *layer = plane_to_sun4i_layer(plane); struct sun4i_layer_state *state; if (plane->state) { @@ -43,6 +44,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane) if (state) { plane->state = &state->state; plane->state->plane = plane; + plane->state->zpos = layer->id; } } -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 15/19] drm/sun4i: backend: Check for the number of alpha planes
Due to the way the composition is done in hardware, we can only have a single alpha-enabled plane active at a time, placed in the second (highest priority) pipe. Make sure of that in our atomic_check to not end up in an impossible scenario. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 50 - drivers/gpu/drm/sun4i/sun4i_backend.h | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 23 +- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index c4986054909b..dd995a6b8b12 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -329,6 +329,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct drm_atomic_state *state = crtc_state->state; struct drm_device *drm = state->dev; struct drm_plane *plane; + unsigned int num_planes = 0; + unsigned int num_alpha_planes = 0; unsigned int num_frontend_planes = 0; DRM_DEBUG_DRIVER("Starting checking our planes\n"); @@ -341,6 +343,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, drm_atomic_get_plane_state(state, plane); struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; if (sun4i_backend_plane_uses_frontend(plane_state)) { DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", @@ -351,6 +354,50 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, } else { layer_state->uses_frontend = false; } + + DRM_DEBUG_DRIVER("Plane FB format is %s\n", +drm_get_format_name(fb->format->format, +&format_name)); + if (drm_format_has_alpha(fb->format->format)) + num_alpha_planes++; + + num_planes++; + } + + /* +* The hardware is a bit unusual here. +* +* Even though it supports 4 layers, it does the composition +* in two separate steps. +* +* The first one is assigning a layer to one of its two +* pipes. If more that 1 layer is assigned to the same pipe, +* and if pixels overlaps, the pipe will take the pixel from +* the layer with the highest priority. +* +* The second step is the actual alpha blending, that takes +* the two pipes as input, and uses the eventual alpha +* component to do the transparency between the two. +* +* This two steps scenario makes us unable to guarantee a +* robust alpha blending between the 4 layers in all +* situations, since this means that we need to have one layer +* with alpha at the lowest position of our two pipes. +* +* However, we cannot even do that, since the hardware has a +* bug where the lowest plane of the lowest pipe (pipe 0, +* priority 0), if it has any alpha, will discard the pixel +* entirely and just display the pixels in the background +* color (black by default). +* +* Since means that we effectively have only three valid +* configurations with alpha, all of them with the alpha being +* on pipe1 with the lowest position, which can be 1, 2 or 3 +* depending on the number of planes and their zpos. +*/ + if (num_alpha_planes > SUN4I_BACKEND_NUM_ALPHA_LAYERS) { + DRM_DEBUG_DRIVER("Too many planes with alpha, rejecting...\n"); + return -EINVAL; } if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) { @@ -358,6 +405,9 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, return -EINVAL; } + DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video\n", +num_planes, num_alpha_planes, num_frontend_planes); + return 0; } diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h index 04a4f11b87a8..52e77591186a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.h +++ b/drivers/gpu/drm/sun4i/sun4i_backend.h @@ -146,6 +146,8 @@ #define SUN4I_BACKEND_HWCCOLORTAB_OFF 0x4c00 #define SUN4I_BACKEND_PIPE_OFF(p) (0x5000 + (0x400 * (p))) +#define SUN4I_BACKEND_NUM_LAYERS 4 +#define SUN4I_BACKEND_NUM_ALPHA_LAYERS 1 #define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1 struct sun4i_backend { diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index fbf25d59cf88..900e716443b8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm
[PATCH 19/19] drm/sun4i: backend: Remove ARGB spoofing
We've had some code for quite some time to prevent the alpha bug from happening on the lowest primary plane. Since we now check for this in our atomic_check, we can simply remove it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index ec47098bfdb2..15a7bce27412 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -92,13 +92,8 @@ void sun4i_backend_layer_enable(struct sun4i_backend *backend, SUN4I_BACKEND_MODCTL_LAY_EN(layer), val); } -static int sun4i_backend_drm_format_to_layer(struct drm_plane *plane, -u32 format, u32 *mode) +static int sun4i_backend_drm_format_to_layer(u32 format, u32 *mode) { - if (plane && (plane->type == DRM_PLANE_TYPE_PRIMARY) && - (format == DRM_FORMAT_ARGB)) - format = DRM_FORMAT_XRGB; - switch (format) { case DRM_FORMAT_ARGB: *mode = SUN4I_BACKEND_LAY_FBFMT_ARGB; @@ -200,8 +195,7 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN, val); - ret = sun4i_backend_drm_format_to_layer(plane, fb->format->format, - &val); + ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val); if (ret) { DRM_DEBUG_DRIVER("Invalid format\n"); return ret; @@ -220,7 +214,7 @@ int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend, u32 val; int ret; - ret = sun4i_backend_drm_format_to_layer(NULL, fmt, &val); + ret = sun4i_backend_drm_format_to_layer(fmt, &val); if (ret) { DRM_DEBUG_DRIVER("Invalid format\n"); return ret; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 0/6] iommu/arm-smmu: Add runtime pm/sleep support
On Tuesday, January 9, 2018 11:01:43 AM CET Vivek Gautam wrote: > This series provides the support for turning on the arm-smmu's > clocks/power domains using runtime pm. This is done using the > recently introduced device links patches, which lets the smmu's > runtime to follow the master's runtime pm, so the smmu remains > powered only when the masters use it. > > It also adds support for Qcom's arm-smmu-v2 variant that > has different clocks and power requirements. > > Took some reference from the exynos runtime patches [2]. > > Previous version of the patchset [1]. > > After much discussion [4] over the use of pm_runtime_get/put() in > .unmap op path for the arm-smmu, and after disussing over more than > a couple of approaches to address this, we are putting forward the > changes *without* using pm_runtime APIs in 'unmap'. Rather, letting > the client device take the control of powering on/off the connected > iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios > when the iommu power can't be directly controlled by clients through > device links. > Rafael has agreed to export the suppliers APIs [5]. > > [V5] >* Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over > the list [4] for the last patch series. >* Added a patch to export pm_runtime_get/put_suppliers() APIs to the > series as agreed with Rafael [5]. >* Added the related patch for msm drm iommu layer to use > pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs. >* Dropped arm-mmu500 clock patch since that would break existing > platforms. >* Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect > the IP version rather than the platform on which it is used. > The same IP is used across multiple platforms including msm8996, > and sdm845 etc. >* Using clock bulk APIs to handle the clocks available to the IP as > suggested by Stephen Boyd. >* The first patch in v4 version of the patch-series: > ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has > already made it to mainline. > > [V4] >* Reworked the clock handling part. We now take clock names as data > in the driver for supported compatible versions, and loop over them > to get, enable, and disable the clocks. >* Using qcom,msm8996 based compatibles for bindings instead of a generic > qcom compatible. >* Refactor MMU500 patch to just add the necessary clock names data and > corresponding bindings. >* Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by > Stanimir on top of previous patch version. >* Added a patch to fix error path in arm_smmu_add_device() >* Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings. > > [V3] >* Reworked the patches to keep the clocks init/enabling function > separately for each compatible. > >* Added clocks bindings for MMU40x/500. > >* Added a new compatible for qcom,smmu-v2 implementation and > the clock bindings for the same. > >* Rebased on top of 4.11-rc1 > > [V2] >* Split the patches little differently. > >* Addressed comments. > >* Removed the patch #4 [3] from previous post > for arm-smmu context save restore. Planning to > post this separately after reworking/addressing Robin's > feedback. > >* Reversed the sequence to disable clocks than enabling. > This was required for those cases where the > clocks are populated in a dependent order from DT. > > [1] https://www.spinics.net/lists/arm-kernel/msg567488.html > [2] https://lkml.org/lkml/2016/10/20/70 > [3] https://patchwork.kernel.org/patch/9389717/ > [4] https://patchwork.kernel.org/patch/9827825/ > [5] https://patchwork.kernel.org/patch/10102445/ > > Sricharan R (3): > iommu/arm-smmu: Add pm_runtime/sleep ops > iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device > iommu/arm-smmu: Add the device_link between masters and smmu > > Vivek Gautam (3): > base: power: runtime: Export pm_runtime_get/put_suppliers > iommu/arm-smmu: Add support for qcom,smmu-v2 variant > drm/msm: iommu: Replace runtime calls with runtime suppliers > > .../devicetree/bindings/iommu/arm,smmu.txt | 35 ++ > drivers/base/power/runtime.c | 2 + > drivers/gpu/drm/msm/msm_iommu.c| 16 +-- > drivers/iommu/arm-smmu.c | 124 > - > 4 files changed, 163 insertions(+), 14 deletions(-) I need some time to review the series. Thanks, Rafael ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/stm: ltdc: add clut mode support
Hi all, Do you think the patch is "acceptable" or should I change it somehow? Any opinion is welcomed : ) Many thanks, Philippe :-) On 11/24/2017 02:54 PM, Philippe CORNU wrote: > Hi Peter, > > On 11/13/2017 11:40 AM, Philippe CORNU wrote: >> Hi Peter, >> >> On 11/12/2017 01:31 PM, Peter Rosin wrote: >>> On 2017-11-10 17:12, Philippe CORNU wrote: Hi Peter, On 11/07/2017 05:34 PM, Peter Rosin wrote: > On 2017-11-07 16:53, Philippe CORNU wrote: >> + Peter >> >> Hi Peter, >> >> CLUT support on STM32 has been removed thanks to your clean up patch > > Support is a bit strong for what I thought was a dead function, or > are you saying that it used to work before my series? Really sorry > if that is the case! As I wrote in the previous related thread (https://lists.freedesktop.org/archives/dri-devel/2017-June/145070.html), STM32 chipsets supports 8-bit CLUT mode but this driver version does not support it "yet"... So, no worry regarding your clean up, I gave you an "acked-by" for that : ) >>> >>> Ok, good. Thanks for clearing that up! >>> > > Anyway, the function I removed seemed to indicate that the hardware > could handle a separate clut for each layer, but your new version > does not. Why is that? Yes I confirm the clut support is available for each layer... but I thought the gamma_lut was only at the crtc level, not at layer level... Maybe I am wrong. Moreover, small test applications I used play only with clut at crtc level... Anyway, could you please help me to "find" a per-layer clut implementation because when I read "crtc->state->gamma_lut->data" it looks like gamma_lut is per crtc, not per plane...? or maybe I have to add extra properties for that... >>> >>> I wasn't clear enough. Yes, there is to my knowledge only one clut, >>> not one per plane. What I noticed was that the function I removed >>> seemed to touch clut registers for multiple layers, but your new >>> function appears to only touch registers for one layer. So, I >>> wondered if the "one and only" clut needed to be copied to the >>> registers for the other layers, or if the old dead code was simply >>> confused. Clearer? >>> >> >> The old code was a generic helper function (ie. for all layers) but >> used only for the 1st layer. So, we could say that "old dead code was >> simply confused" :-) >> >> When I put back the clut support in this patch, I decided to update >> only the 1st layer (because there is no API for handling it on other >> layers). I also decided to not re-use the former generic helper >> function as the update loop is pretty small. >> >> This patch offers the clut mode feature for fbdev (only one plane in >> fbdev) and for drm (single plane for many use cases, 2nd plane being >> used mostly for video...) >> >> If tomorrow the API offers clut support per plane, the update loop >> will be moved to the plane update function, means the generic helper >> function will not be require anymore too. > > From the explanations above, do you think the patch is "acceptable" or > should I change it somehow? > What is your opinion? > Many thanks, > Philippe :-) > >> >> Many thanks >> Philippe :) >> >>> Cheers. >>> Peter >>> ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5] drm/omap: plane zpos/zorder management improvements
Use the plane index as default zpos for all planes. Even if the application is not setting zpos/zorder explicitly we will have unique zpos for each plane. Planes with identical zpos value will result undefined behavior: disappearing planes, screen flickering and it is not supported by the hardware. Enforce that all planes must have unique zpos on the given crtc by returning error when duplicate zpos value is requested. Signed-off-by: Peter Ujfalusi --- Hi, Changes since v4: - further simplify the zpos checking by using a mask and a single loop - Commit message has been extended Changes since v3: - Use drm_plane_index() instead of storing the same index wothin omap_plane struct - Optimize the zpos validation loop so we avoid extra checks. Changes since v2: - The check for duplicate zpos is moved to omap_crtc Changes since v1: - Dropped the zpos normalization related patches - New patch based on the discussion, see commit message. Regards, Peter drivers/gpu/drm/omapdrm/omap_crtc.c | 23 ++- drivers/gpu/drm/omapdrm/omap_plane.c | 15 --- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 1b8154e58d18..941a6440fc8e 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -486,6 +486,27 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) } } +static int omap_crtc_validate_zpos(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct drm_plane *plane; + const struct drm_plane_state *pstate; + unsigned int zpos_mask = 0; + + /* Check the crts's planes against duplicated zpos value */ + drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { + if (zpos_mask & BIT(pstate->zpos)) { + DBG("crtc%u: zpos must be unique (zpos: %u)", + crtc->index, pstate->zpos); + return -EINVAL; + } + + zpos_mask |= BIT(pstate->zpos); + } + + return 0; +} + static int omap_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -509,7 +530,7 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, omap_crtc_state->rotation = pri_state->rotation; } - return 0; + return omap_crtc_validate_zpos(crtc, state); } static void omap_crtc_atomic_begin(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 7d789d1551a1..39f25210bef1 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -97,8 +97,7 @@ static void omap_plane_atomic_disable(struct drm_plane *plane, struct omap_plane *omap_plane = to_omap_plane(plane); plane->state->rotation = DRM_MODE_ROTATE_0; - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY - ? 0 : omap_plane->id; + plane->state->zpos = drm_plane_index(plane); priv->dispc_ops->ovl_enable(omap_plane->id, false); } @@ -184,18 +183,12 @@ void omap_plane_install_properties(struct drm_plane *plane, static void omap_plane_reset(struct drm_plane *plane) { - struct omap_plane *omap_plane = to_omap_plane(plane); - drm_atomic_helper_plane_reset(plane); if (!plane->state) return; - /* -* Set the zpos default depending on whether we are a primary or overlay -* plane. -*/ - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY - ? 0 : omap_plane->id; + /* Set the zpos to the plane index. */ + plane->state->zpos = drm_plane_index(plane); } static int omap_plane_atomic_set_property(struct drm_plane *plane, @@ -295,7 +288,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, drm_plane_helper_add(plane, &omap_plane_helper_funcs); omap_plane_install_properties(plane, &plane->base); - drm_plane_create_zpos_property(plane, 0, 0, num_planes - 1); + drm_plane_create_zpos_property(plane, idx, 0, num_planes - 1); return plane; -- Peter Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 104555] RX 560 DPM auto - driver doesn't reliably set high clocks, causing stutter in mpv
https://bugs.freedesktop.org/show_bug.cgi?id=104555 Bug ID: 104555 Summary: RX 560 DPM auto - driver doesn't reliably set high clocks, causing stutter in mpv Product: DRI Version: unspecified Hardware: x86-64 (AMD64) OS: Linux (All) Status: NEW Severity: major Priority: medium Component: DRM/AMDgpu Assignee: dri-devel@lists.freedesktop.org Reporter: tempel.jul...@gmail.com When I use modest quality settings in mpv (0.28.0), the result is stuttery when power_dpm_force_performance_level = auto. The stuttering completely disappears when I set power_dpm_force_performance_level = high. Modest mpv settings would be these: profile=gpu-hq video-sync=display-resample interpolation tscale=linear The stuttering isn't recognized by mpv's stats, so we unfortunately have to judge with eyes (thus cheap interpolation is enabled, so result should be smooth regardless of refreshrate). It's very obvious with camera pans and it's most severe when I do any 2160p 60fps video downscaling to 1440p (in fullscreen on Xorg without compositor). This happens with Linux 4.14.12 and 4.15 RC7, I didn't test older kernels. Display is 2560x1440 75Hz, but it also happens at 60Hz (so probably regardless of refreshrate or timings). (my first report here, so plz don't tear it apart in case something's not to your satisfaction) -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 01/19] drm/fourcc: Add a function to tell if the format embeds alpha
On Tue, 9 Jan 2018 11:56:20 +0100 Maxime Ripard wrote: > There's a bunch of drivers that duplicate the same function to know if a > particular format embeds an alpha component or not. > > Let's create a helper to avoid duplicating that logic. > > Cc: Boris Brezillon Reviewed-by: Boris Brezillon > Cc: Eric Anholt > Cc: Inki Dae > Cc: Joonyoung Shim > Cc: Kyungmin Park > Cc: Laurent Pinchart > Cc: Mark Yao > Cc: Seung-Woo Kim > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/drm_fourcc.c | 43 +- > include/drm/drm_fourcc.h | 1 +- > 2 files changed, 44 insertions(+) > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c > index 9c0152df45ad..6e6227d6a46b 100644 > --- a/drivers/gpu/drm/drm_fourcc.c > +++ b/drivers/gpu/drm/drm_fourcc.c > @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t format, > int plane) > return height / info->vsub; > } > EXPORT_SYMBOL(drm_format_plane_height); > + > +/** > + * drm_format_has_alpha - get whether the format embeds an alpha component > + * @format: pixel format (DRM_FORMAT_*) > + * > + * Returns: > + * true if the format embeds an alpha component, false otherwise. > + */ > +bool drm_format_has_alpha(uint32_t format) > +{ > + switch (format) { > + case DRM_FORMAT_ARGB: > + case DRM_FORMAT_ABGR: > + case DRM_FORMAT_RGBA: > + case DRM_FORMAT_BGRA: > + case DRM_FORMAT_ARGB1555: > + case DRM_FORMAT_ABGR1555: > + case DRM_FORMAT_RGBA5551: > + case DRM_FORMAT_BGRA5551: > + case DRM_FORMAT_ARGB: > + case DRM_FORMAT_ABGR: > + case DRM_FORMAT_RGBA: > + case DRM_FORMAT_BGRA: > + case DRM_FORMAT_ARGB2101010: > + case DRM_FORMAT_ABGR2101010: > + case DRM_FORMAT_RGBA1010102: > + case DRM_FORMAT_BGRA1010102: > + case DRM_FORMAT_AYUV: > + case DRM_FORMAT_XRGB_A8: > + case DRM_FORMAT_XBGR_A8: > + case DRM_FORMAT_RGBX_A8: > + case DRM_FORMAT_BGRX_A8: > + case DRM_FORMAT_RGB888_A8: > + case DRM_FORMAT_BGR888_A8: > + case DRM_FORMAT_RGB565_A8: > + case DRM_FORMAT_BGR565_A8: > + return true; > + > + default: > + return false; > + } > +} > +EXPORT_SYMBOL(drm_format_has_alpha); > diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h > index 6942e84b6edd..e08fc22c5f78 100644 > --- a/include/drm/drm_fourcc.h > +++ b/include/drm/drm_fourcc.h > @@ -69,5 +69,6 @@ int drm_format_vert_chroma_subsampling(uint32_t format); > int drm_format_plane_width(int width, uint32_t format, int plane); > int drm_format_plane_height(int height, uint32_t format, int plane); > const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf > *buf); > +bool drm_format_has_alpha(uint32_t format); > > #endif /* __DRM_FOURCC_H__ */ ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 02/19] drm/atmel-hlcdc: Use the alpha format helper
On Tue, 9 Jan 2018 11:56:21 +0100 Maxime Ripard wrote: > Now that the core has a drm format helper to tell if a format embeds an > alpha component in it, let's use it. > > Cc: Boris Brezillon Acked-by: Boris Brezillon > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 20 ++ > 1 file changed, 3 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > index 703c2d13603f..1a9318810a29 100644 > --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > @@ -194,20 +194,6 @@ static int atmel_hlcdc_format_to_plane_mode(u32 format, > u32 *mode) > return 0; > } > > -static bool atmel_hlcdc_format_embeds_alpha(u32 format) > -{ > - int i; > - > - for (i = 0; i < sizeof(format); i++) { > - char tmp = (format >> (8 * i)) & 0xff; > - > - if (tmp == 'A') > - return true; > - } > - > - return false; > -} > - > static u32 heo_downscaling_xcoef[] = { > 0x11343311, > 0x00f7, > @@ -395,7 +381,7 @@ atmel_hlcdc_plane_update_general_settings(struct > atmel_hlcdc_plane *plane, > cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL | > ATMEL_HLCDC_LAYER_ITER; > > - if (atmel_hlcdc_format_embeds_alpha(format)) > + if (drm_format_has_alpha(format)) > cfg |= ATMEL_HLCDC_LAYER_LAEN; > else > cfg |= ATMEL_HLCDC_LAYER_GAEN | > @@ -566,7 +552,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state > *c_state) > ovl_state = drm_plane_state_to_atmel_hlcdc_plane_state(ovl_s); > > if (!ovl_s->fb || > - atmel_hlcdc_format_embeds_alpha(ovl_s->fb->format->format) > || > + drm_format_has_alpha(ovl_s->fb->format->format) || > ovl_state->alpha != 255) > continue; > > @@ -769,7 +755,7 @@ static int atmel_hlcdc_plane_atomic_check(struct > drm_plane *p, > > if ((state->crtc_h != state->src_h || state->crtc_w != state->src_w) && > (!desc->layout.memsize || > - atmel_hlcdc_format_embeds_alpha(state->base.fb->format->format))) > + drm_format_has_alpha(state->base.fb->format->format))) > return -EINVAL; > > if (state->crtc_x < 0 || state->crtc_y < 0) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 01/19] drm/fourcc: Add a function to tell if the format embeds alpha
Hi Maxime, Thank you for the patch. On Tuesday, 9 January 2018 12:56:20 EET Maxime Ripard wrote: > There's a bunch of drivers that duplicate the same function to know if a > particular format embeds an alpha component or not. > > Let's create a helper to avoid duplicating that logic. > > Cc: Boris Brezillon > Cc: Eric Anholt > Cc: Inki Dae > Cc: Joonyoung Shim > Cc: Kyungmin Park > Cc: Laurent Pinchart > Cc: Mark Yao > Cc: Seung-Woo Kim > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/drm_fourcc.c | 43 +- > include/drm/drm_fourcc.h | 1 +- > 2 files changed, 44 insertions(+) > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c > index 9c0152df45ad..6e6227d6a46b 100644 > --- a/drivers/gpu/drm/drm_fourcc.c > +++ b/drivers/gpu/drm/drm_fourcc.c > @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t > format, int plane) return height / info->vsub; > } > EXPORT_SYMBOL(drm_format_plane_height); > + > +/** > + * drm_format_has_alpha - get whether the format embeds an alpha component > + * @format: pixel format (DRM_FORMAT_*) > + * > + * Returns: > + * true if the format embeds an alpha component, false otherwise. > + */ > +bool drm_format_has_alpha(uint32_t format) > +{ > + switch (format) { > + case DRM_FORMAT_ARGB: > + case DRM_FORMAT_ABGR: > + case DRM_FORMAT_RGBA: > + case DRM_FORMAT_BGRA: > + case DRM_FORMAT_ARGB1555: > + case DRM_FORMAT_ABGR1555: > + case DRM_FORMAT_RGBA5551: > + case DRM_FORMAT_BGRA5551: > + case DRM_FORMAT_ARGB: > + case DRM_FORMAT_ABGR: > + case DRM_FORMAT_RGBA: > + case DRM_FORMAT_BGRA: > + case DRM_FORMAT_ARGB2101010: > + case DRM_FORMAT_ABGR2101010: > + case DRM_FORMAT_RGBA1010102: > + case DRM_FORMAT_BGRA1010102: > + case DRM_FORMAT_AYUV: > + case DRM_FORMAT_XRGB_A8: > + case DRM_FORMAT_XBGR_A8: > + case DRM_FORMAT_RGBX_A8: > + case DRM_FORMAT_BGRX_A8: > + case DRM_FORMAT_RGB888_A8: > + case DRM_FORMAT_BGR888_A8: > + case DRM_FORMAT_RGB565_A8: > + case DRM_FORMAT_BGR565_A8: > + return true; > + > + default: > + return false; > + } > +} > +EXPORT_SYMBOL(drm_format_has_alpha); How about adding the information to struct drm_format_info instead ? drm_format_has_alpha() could then be implemented as bool drm_format_has_alpha(uint32_t format) { const struct drm_format_info *info; info = drm_format_info(format); return info ? info->has_alpha : false; } although drivers should really use the drm_framebuffer::format field directly in most cases, so the helper might not be needed at all. > diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h > index 6942e84b6edd..e08fc22c5f78 100644 > --- a/include/drm/drm_fourcc.h > +++ b/include/drm/drm_fourcc.h > @@ -69,5 +69,6 @@ int drm_format_vert_chroma_subsampling(uint32_t format); > int drm_format_plane_width(int width, uint32_t format, int plane); > int drm_format_plane_height(int height, uint32_t format, int plane); > const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf > *buf); > +bool drm_format_has_alpha(uint32_t format); > > #endif /* __DRM_FOURCC_H__ */ -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 06/19] drm/blend: Add a generic alpha property
On Tue, 9 Jan 2018 11:56:25 +0100 Maxime Ripard wrote: > Some drivers duplicate the logic to create a property to store a per-plane > alpha. > > Let's create a helper in order to move that to the core. > > Cc: Boris Brezillon Reviewed-by: Boris Brezillon > Cc: Laurent Pinchart > Signed-off-by: Maxime Ripard > --- > Documentation/gpu/kms-properties.csv | 2 +- > drivers/gpu/drm/drm_atomic.c | 4 - > drivers/gpu/drm/drm_atomic_helper.c | 1 +- > drivers/gpu/drm/drm_blend.c | 32 +- > include/drm/drm_blend.h | 1 +- > include/drm/drm_plane.h | 6 +- > 6 files changed, 45 insertions(+), 1 deletion(-) > > diff --git a/Documentation/gpu/kms-properties.csv > b/Documentation/gpu/kms-properties.csv > index 927b65e14219..a3c3969c1992 100644 > --- a/Documentation/gpu/kms-properties.csv > +++ b/Documentation/gpu/kms-properties.csv > @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD > ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD > ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD > ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD > -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD > +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from > transparent (0) to opaque (255) > ,,"""colorkey""",RANGE,"Min=0, Max=0x01ff",Plane,TBD > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index c2da5585e201..ade18cf62c89 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct drm_plane > *plane, > state->src_w = val; > } else if (property == config->prop_src_h) { > state->src_h = val; > + } else if (property == plane->alpha_property) { > + state->alpha = val; > } else if (property == plane->rotation_property) { > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) > return -EINVAL; > @@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, > *val = state->src_w; > } else if (property == config->prop_src_h) { > *val = state->src_h; > + } else if (property == plane->alpha_property) { > + *val = state->alpha; > } else if (property == plane->rotation_property) { > *val = state->rotation; > } else if (property == plane->zpos_property) { > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > b/drivers/gpu/drm/drm_atomic_helper.c > index 71d712f1b56a..018993df4c18 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane > *plane) > > if (plane->state) { > plane->state->plane = plane; > + plane->state->alpha = 255; > plane->state->rotation = DRM_MODE_ROTATE_0; > } > } > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c > index 2e5e089dd912..8eea2a8af458 100644 > --- a/drivers/gpu/drm/drm_blend.c > +++ b/drivers/gpu/drm/drm_blend.c > @@ -104,6 +104,38 @@ > */ > > /** > + * drm_plane_create_alpha_property - create a new alpha property > + * @plane: drm plane > + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque) > + * > + * This function initializes a generic, mutable, alpha property and > + * enables support for it in the DRM core. > + * > + * Drivers can then attach this property to their plane to enable > + * support for configurable plane alpha. > + * > + * Returns: > + * 0 on success, negative error code on failure. > + */ > +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha) > +{ > + struct drm_property *prop; > + > + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255); > + if (!prop) > + return -ENOMEM; > + > + drm_object_attach_property(&plane->base, prop, alpha); > + plane->alpha_property = prop; > + > + if (plane->state) > + plane->state->alpha = alpha; > + > + return 0; > +} > +EXPORT_SYMBOL(drm_plane_create_alpha_property); > + > +/** > * drm_plane_create_rotation_property - create a new rotation property > * @plane: drm plane > * @rotation: initial value of the rotation property > diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h > index 17606026590b..5979a8fce453 100644 > --- a/include/drm/drm_blend.h > +++ b/include/drm/drm_blend.h > @@ -36,6 +36,7 @@ static inline bool drm_rotation_90_or_270(unsigned int > rotation) > return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270); > } > > +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha); > int drm_plane_create_rotation_property(struct drm_plane *plane, > unsigned int rotation, >
Re: [PATCH 07/19] drm/atmel-hclcdc: Convert to the new generic alpha property
On Tue, 9 Jan 2018 11:56:26 +0100 Maxime Ripard wrote: > Now that we have support for per-plane alpha in the core, let's use it. > > Cc: Boris Brezillon Acked-by: Boris Brezillon > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h| 13 +--- > drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 89 ++ > 2 files changed, 14 insertions(+), 88 deletions(-) > > diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h > b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h > index 6833ee253cfa..704cac6399eb 100644 > --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h > +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h > @@ -298,7 +298,6 @@ struct atmel_hlcdc_layer { > struct atmel_hlcdc_plane { > struct drm_plane base; > struct atmel_hlcdc_layer layer; > - struct atmel_hlcdc_plane_properties *properties; > }; > > static inline struct atmel_hlcdc_plane * > @@ -345,18 +344,6 @@ struct atmel_hlcdc_dc_desc { > }; > > /** > - * Atmel HLCDC Plane properties. > - * > - * This structure stores plane property definitions. > - * > - * @alpha: alpha blending (or transparency) property > - * @rotation: rotation property > - */ > -struct atmel_hlcdc_plane_properties { > - struct drm_property *alpha; > -}; > - > -/** > * Atmel HLCDC Display Controller. > * > * @desc: HLCDC Display Controller description > diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > index 1a9318810a29..dbc508889e87 100644 > --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > @@ -31,7 +31,6 @@ > * @src_y: y buffer position > * @src_w: buffer width > * @src_h: buffer height > - * @alpha: alpha blending of the plane > * @disc_x: x discard position > * @disc_y: y discard position > * @disc_w: discard width > @@ -54,8 +53,6 @@ struct atmel_hlcdc_plane_state { > uint32_t src_w; > uint32_t src_h; > > - u8 alpha; > - > int disc_x; > int disc_y; > int disc_w; > @@ -385,7 +382,7 @@ atmel_hlcdc_plane_update_general_settings(struct > atmel_hlcdc_plane *plane, > cfg |= ATMEL_HLCDC_LAYER_LAEN; > else > cfg |= ATMEL_HLCDC_LAYER_GAEN | > -ATMEL_HLCDC_LAYER_GA(state->alpha); > +ATMEL_HLCDC_LAYER_GA(state->base.alpha); > } > > if (state->disc_h && state->disc_w) > @@ -553,7 +550,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state > *c_state) > > if (!ovl_s->fb || > drm_format_has_alpha(ovl_s->fb->format->format) || > - ovl_state->alpha != 255) > + ovl_s->alpha != 255) > continue; > > /* TODO: implement a smarter hidden area detection */ > @@ -829,51 +826,18 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane > *p) > drm_plane_cleanup(p); > } > > -static int atmel_hlcdc_plane_atomic_set_property(struct drm_plane *p, > - struct drm_plane_state *s, > - struct drm_property *property, > - uint64_t val) > -{ > - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); > - struct atmel_hlcdc_plane_properties *props = plane->properties; > - struct atmel_hlcdc_plane_state *state = > - drm_plane_state_to_atmel_hlcdc_plane_state(s); > - > - if (property == props->alpha) > - state->alpha = val; > - else > - return -EINVAL; > - > - return 0; > -} > - > -static int atmel_hlcdc_plane_atomic_get_property(struct drm_plane *p, > - const struct drm_plane_state *s, > - struct drm_property *property, > - uint64_t *val) > -{ > - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); > - struct atmel_hlcdc_plane_properties *props = plane->properties; > - const struct atmel_hlcdc_plane_state *state = > - container_of(s, const struct atmel_hlcdc_plane_state, base); > - > - if (property == props->alpha) > - *val = state->alpha; > - else > - return -EINVAL; > - > - return 0; > -} > - > -static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane, > - struct atmel_hlcdc_plane_properties *props) > +static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane) > { > const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; > > if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER || > - desc->type == ATMEL_HLCDC_CURSOR_LAYER) > - drm_object_attach_property(&plane->base.base, > -
Re: [PATCH 06/19] drm/blend: Add a generic alpha property
On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote: > Some drivers duplicate the logic to create a property to store a per-plane > alpha. > > Let's create a helper in order to move that to the core. > > Cc: Boris Brezillon > Cc: Laurent Pinchart > Signed-off-by: Maxime Ripard Do we have userspace for this? Is encoding a fixed 0-255 range really the best idea? I know other drivers have skimped on the rules here a bit ... But at least internally (i.e. within the drm_plane_state) we probably should restrict ourselves to u8. And this needs real docs (i.e. the full blend equation drivers are supposed to implement). -Daniel > --- > Documentation/gpu/kms-properties.csv | 2 +- > drivers/gpu/drm/drm_atomic.c | 4 - > drivers/gpu/drm/drm_atomic_helper.c | 1 +- > drivers/gpu/drm/drm_blend.c | 32 +- > include/drm/drm_blend.h | 1 +- > include/drm/drm_plane.h | 6 +- > 6 files changed, 45 insertions(+), 1 deletion(-) > > diff --git a/Documentation/gpu/kms-properties.csv > b/Documentation/gpu/kms-properties.csv > index 927b65e14219..a3c3969c1992 100644 > --- a/Documentation/gpu/kms-properties.csv > +++ b/Documentation/gpu/kms-properties.csv > @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD > ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD > ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD > ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD > -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD > +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from > transparent (0) to opaque (255) > ,,"""colorkey""",RANGE,"Min=0, Max=0x01ff",Plane,TBD > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index c2da5585e201..ade18cf62c89 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct drm_plane > *plane, > state->src_w = val; > } else if (property == config->prop_src_h) { > state->src_h = val; > + } else if (property == plane->alpha_property) { > + state->alpha = val; > } else if (property == plane->rotation_property) { > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) > return -EINVAL; > @@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, > *val = state->src_w; > } else if (property == config->prop_src_h) { > *val = state->src_h; > + } else if (property == plane->alpha_property) { > + *val = state->alpha; > } else if (property == plane->rotation_property) { > *val = state->rotation; > } else if (property == plane->zpos_property) { > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > b/drivers/gpu/drm/drm_atomic_helper.c > index 71d712f1b56a..018993df4c18 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane > *plane) > > if (plane->state) { > plane->state->plane = plane; > + plane->state->alpha = 255; > plane->state->rotation = DRM_MODE_ROTATE_0; > } > } > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c > index 2e5e089dd912..8eea2a8af458 100644 > --- a/drivers/gpu/drm/drm_blend.c > +++ b/drivers/gpu/drm/drm_blend.c > @@ -104,6 +104,38 @@ > */ > > /** > + * drm_plane_create_alpha_property - create a new alpha property > + * @plane: drm plane > + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque) > + * > + * This function initializes a generic, mutable, alpha property and > + * enables support for it in the DRM core. > + * > + * Drivers can then attach this property to their plane to enable > + * support for configurable plane alpha. > + * > + * Returns: > + * 0 on success, negative error code on failure. > + */ > +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha) > +{ > + struct drm_property *prop; > + > + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255); > + if (!prop) > + return -ENOMEM; > + > + drm_object_attach_property(&plane->base, prop, alpha); > + plane->alpha_property = prop; > + > + if (plane->state) > + plane->state->alpha = alpha; > + > + return 0; > +} > +EXPORT_SYMBOL(drm_plane_create_alpha_property); > + > +/** > * drm_plane_create_rotation_property - create a new rotation property > * @plane: drm plane > * @rotation: initial value of the rotation property > diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h > index 17606026590b..5979a8fce453 100644 > --- a/include/drm/drm_blend.h > +++ b/include/drm/drm_blend.h > @@ -36,6 +36,7 @@ static inline bool drm_rotation_90_or_27
Re: [PATCH 06/19] drm/blend: Add a generic alpha property
Hi Maxime, Thank you for the patch. On Tuesday, 9 January 2018 12:56:25 EET Maxime Ripard wrote: > Some drivers duplicate the logic to create a property to store a per-plane > alpha. > > Let's create a helper in order to move that to the core. > > Cc: Boris Brezillon > Cc: Laurent Pinchart > Signed-off-by: Maxime Ripard > --- > Documentation/gpu/kms-properties.csv | 2 +- > drivers/gpu/drm/drm_atomic.c | 4 - > drivers/gpu/drm/drm_atomic_helper.c | 1 +- > drivers/gpu/drm/drm_blend.c | 32 +- > include/drm/drm_blend.h | 1 +- > include/drm/drm_plane.h | 6 +- > 6 files changed, 45 insertions(+), 1 deletion(-) > > diff --git a/Documentation/gpu/kms-properties.csv > b/Documentation/gpu/kms-properties.csv index 927b65e14219..a3c3969c1992 > 100644 > --- a/Documentation/gpu/kms-properties.csv > +++ b/Documentation/gpu/kms-properties.csv > @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD > ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD > ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD > ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD > -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD > +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from > transparent (0) to opaque (255) ,,"""colorkey""",RANGE,"Min=0, > Max=0x01ff",Plane,TBD I think more documentation is needed. You should explain how the property operates and which formats it is applicable to. For instance you need to clarify what happens for format that contain an alpha component. > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index c2da5585e201..ade18cf62c89 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct > drm_plane *plane, state->src_w = val; > } else if (property == config->prop_src_h) { > state->src_h = val; > + } else if (property == plane->alpha_property) { > + state->alpha = val; > } else if (property == plane->rotation_property) { > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) > return -EINVAL; > @@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, > *val = state->src_w; > } else if (property == config->prop_src_h) { > *val = state->src_h; > + } else if (property == plane->alpha_property) { > + *val = state->alpha; > } else if (property == plane->rotation_property) { > *val = state->rotation; > } else if (property == plane->zpos_property) { > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > b/drivers/gpu/drm/drm_atomic_helper.c index 71d712f1b56a..018993df4c18 > 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane > *plane) > > if (plane->state) { > plane->state->plane = plane; > + plane->state->alpha = 255; If you keep the ability to select an initial value other than fully opaque (see my comment below about that) you should reset to that value instead of hardcoding 255. > plane->state->rotation = DRM_MODE_ROTATE_0; > } > } > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c > index 2e5e089dd912..8eea2a8af458 100644 > --- a/drivers/gpu/drm/drm_blend.c > +++ b/drivers/gpu/drm/drm_blend.c > @@ -104,6 +104,38 @@ > */ > > /** > + * drm_plane_create_alpha_property - create a new alpha property > + * @plane: drm plane > + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque) Do you have a use case for initializing the alpha value to something else than fully opaque ? > + * This function initializes a generic, mutable, alpha property and > + * enables support for it in the DRM core. > + * > + * Drivers can then attach this property to their plane to enable > + * support for configurable plane alpha. The function attaches the property to the plane, is the documentation outdated ? > + * Returns: > + * 0 on success, negative error code on failure. > + */ > +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha) > +{ > + struct drm_property *prop; > + > + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255); Do you think the 0-255 range will fit all use cases ? > + if (!prop) > + return -ENOMEM; > + > + drm_object_attach_property(&plane->base, prop, alpha); > + plane->alpha_property = prop; > + > + if (plane->state) > + plane->state->alpha = alpha; > + > + return 0; > +} > +EXPORT_SYMBOL(drm_plane_create_alpha_property); > + > +/** > * drm_plane_create_rotation_property - create a new rotation property > * @plane: drm plane > * @rotation:
Re: [PATCH 05/19] drm/vc4: Use the alpha format helper
On Tue, Jan 09, 2018 at 11:56:24AM +0100, Maxime Ripard wrote: > Now that the core has a drm format helper to tell if a format embeds an > alpha component in it, let's use it. > > Cc: Eric Anholt > Signed-off-by: Maxime Ripard On patches 1-5: Reviewed-by: Daniel Vetter > --- > drivers/gpu/drm/vc4/vc4_plane.c | 19 +-- > 1 file changed, 9 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c > index 423a23ed8fc2..2c0e25128dcd 100644 > --- a/drivers/gpu/drm/vc4/vc4_plane.c > +++ b/drivers/gpu/drm/vc4/vc4_plane.c > @@ -85,40 +85,39 @@ static const struct hvs_format { > u32 drm; /* DRM_FORMAT_* */ > u32 hvs; /* HVS_FORMAT_* */ > u32 pixel_order; > - bool has_alpha; > bool flip_cbcr; > } hvs_formats[] = { > { > .drm = DRM_FORMAT_XRGB, .hvs = HVS_PIXEL_FORMAT_RGBA, > - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false, > + .pixel_order = HVS_PIXEL_ORDER_ABGR, > }, > { > .drm = DRM_FORMAT_ARGB, .hvs = HVS_PIXEL_FORMAT_RGBA, > - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, > + .pixel_order = HVS_PIXEL_ORDER_ABGR, > }, > { > .drm = DRM_FORMAT_ABGR, .hvs = HVS_PIXEL_FORMAT_RGBA, > - .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = true, > + .pixel_order = HVS_PIXEL_ORDER_ARGB, > }, > { > .drm = DRM_FORMAT_XBGR, .hvs = HVS_PIXEL_FORMAT_RGBA, > - .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = false, > + .pixel_order = HVS_PIXEL_ORDER_ARGB, > }, > { > .drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565, > - .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false, > + .pixel_order = HVS_PIXEL_ORDER_XRGB, > }, > { > .drm = DRM_FORMAT_BGR565, .hvs = HVS_PIXEL_FORMAT_RGB565, > - .pixel_order = HVS_PIXEL_ORDER_XBGR, .has_alpha = false, > + .pixel_order = HVS_PIXEL_ORDER_XBGR, > }, > { > .drm = DRM_FORMAT_ARGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, > - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, > + .pixel_order = HVS_PIXEL_ORDER_ABGR, > }, > { > .drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, > - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false, > + .pixel_order = HVS_PIXEL_ORDER_ABGR, > }, > { > .drm = DRM_FORMAT_YUV422, > @@ -601,7 +600,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, > /* Position Word 2: Source Image Size, Alpha Mode */ > vc4_state->pos2_offset = vc4_state->dlist_count; > vc4_dlist_write(vc4_state, > - VC4_SET_FIELD(format->has_alpha ? > + VC4_SET_FIELD(drm_format_has_alpha(format->drm) ? > SCALER_POS2_ALPHA_MODE_PIPELINE : > SCALER_POS2_ALPHA_MODE_FIXED, > SCALER_POS2_ALPHA_MODE) | > -- > git-series 0.9.1 > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- 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: [PATCH 08/19] drm/rcar-du: Convert to the new generic alpha property
Hi Maxime, Thank you for the patch. On Tuesday, 9 January 2018 12:56:27 EET Maxime Ripard wrote: > Now that we have support for per-plane alpha in the core, let's use it. > > Cc: Laurent Pinchart > Signed-off-by: Maxime Ripard Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 +- > drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 +--- > drivers/gpu/drm/rcar-du/rcar_du_plane.c | 15 +++-- > drivers/gpu/drm/rcar-du/rcar_du_plane.h | 2 +- > drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 42 ++ > drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +- > 6 files changed, 9 insertions(+), 58 deletions(-) > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h > b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index f8cd79488ece..aff04adaae53 > 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h > +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h > @@ -89,7 +89,6 @@ struct rcar_du_device { > struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS]; > > struct { > - struct drm_property *alpha; > struct drm_property *colorkey; > } props; > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c > b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 566d1a948c8f..e1b5a7b460cc > 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c > @@ -417,11 +417,6 @@ static int rcar_du_encoders_init(struct rcar_du_device > *rcdu) > > static int rcar_du_properties_init(struct rcar_du_device *rcdu) > { > - rcdu->props.alpha = > - drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255); > - if (rcdu->props.alpha == NULL) > - return -ENOMEM; > - > /* >* The color key is expressed as an RGB888 triplet stored in a 32-bit >* integer in XRGB format. Bit 24 is used as a flag to disable (0) > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c > b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 61833cc1c699..5b34e8092c8b > 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c > @@ -423,7 +423,7 @@ static void rcar_du_plane_setup_mode(struct > rcar_du_group *rgrp, rcar_du_plane_write(rgrp, index, PnALPHAR, > PnALPHAR_ABIT_0); > else > rcar_du_plane_write(rgrp, index, PnALPHAR, > - PnALPHAR_ABIT_X | state->alpha); > + PnALPHAR_ABIT_X | state->state.alpha); > > pnmr = PnMR_BM_MD | state->format->pnmr; > > @@ -667,11 +667,11 @@ static void rcar_du_plane_reset(struct drm_plane > *plane) > > state->hwindex = -1; > state->source = RCAR_DU_PLANE_MEMORY; > - state->alpha = 255; > state->colorkey = RCAR_DU_COLORKEY_NONE; > state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; > > plane->state = &state->state; > + plane->state->alpha = 255; > plane->state->plane = plane; > } > > @@ -683,9 +683,7 @@ static int rcar_du_plane_atomic_set_property(struct > drm_plane *plane, struct rcar_du_plane_state *rstate = > to_rcar_plane_state(state); struct rcar_du_device *rcdu = > to_rcar_plane(plane)->group->dev; > > - if (property == rcdu->props.alpha) > - rstate->alpha = val; > - else if (property == rcdu->props.colorkey) > + if (property == rcdu->props.colorkey) > rstate->colorkey = val; > else > return -EINVAL; > @@ -701,9 +699,7 @@ static int rcar_du_plane_atomic_get_property(struct > drm_plane *plane, container_of(state, const struct rcar_du_plane_state, > state); > struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev; > > - if (property == rcdu->props.alpha) > - *val = rstate->alpha; > - else if (property == rcdu->props.colorkey) > + if (property == rcdu->props.colorkey) > *val = rstate->colorkey; > else > return -EINVAL; > @@ -772,10 +768,9 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp) > continue; > > drm_object_attach_property(&plane->plane.base, > -rcdu->props.alpha, 255); > - drm_object_attach_property(&plane->plane.base, > rcdu->props.colorkey, > RCAR_DU_COLORKEY_NONE); > + drm_plane_create_alpha_property(&plane->plane, 255); > drm_plane_create_zpos_property(&plane->plane, 1, 1, 7); > } > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h > b/drivers/gpu/drm/rcar-du/rcar_du_plane.h index f62e09f195de..2dc793ebd1a2 > 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h > +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h > @@ -50,7 +50,6 @@ static inline struct rcar_du_plane *to_rcar_plane(struct > drm_plane *plane) * @state: base DRM plane state > * @format: information about the pixel format used by the plane > * @hwindex: 0-based hardware
Re: [PATCH 1/2] drm/blend: Account also the primary plane of the crtc for normalized_zpos
On Fri, Dec 22, 2017 at 05:15:05PM +0200, Peter Ujfalusi wrote: > Hi, > > On 2017-12-22 12:12, Ville Syrjälä wrote: > > On Fri, Dec 22, 2017 at 11:16:47AM +0200, Tomi Valkeinen wrote: > >> On 21/12/17 17:12, Ville Syrjälä wrote: > >> > If the userspace knows this, then it knows which primary plane is for > which crtc, right? > > And if it doesn't know this, then the userspace cannot associate any > plane to any crtc (except what it configures itself). > > So... If using legacy modesetting (and non-universal planes), there's no > problem, primary planes are fixed and at low zpos. If using atomic > modesetting and universal planes, there's really no (default) > association between planes and crtcs, and "primary plane" doesn't have > much meaning. Is that correct? > > If so... Then I guess the atomic modesetting client essentially randomly > picks which plane it uses as a "root plane" (if it even needs such), and > which planes as overlay planes? If that's the case, then this patch > doesn't quite fix the issue... > >>> > >>> I'm not sure anyone has really thought how userspace would/should assign > >>> planes to crtcs. My only idea so far has been the crtc and their > >>> preferred primary planes should be registered in the same order. But > >>> someone should then also implement that same policy in userspace when > >>> it's trying to figure out which plane to use. There are other > >>> heuristics it should probably use, like preferring to pick a primary > >>> plane for any fullscreen surface. > >>> > >>> I guess from functional point of view it shouldn't matter which plane > >>> you pick as long as the plane's user visible capabilities are > >>> sufficient. But there might be user invisible power saving features and > >>> whatnot that only work with specific planes. So from that point of view > >>> maybe the order in which the planes get registered is important. Or we > >>> could maybe come up with some kind of plane usage hints in the uapi > >>> which could help userspace decide? > >> > >> I was thinking about this, and... maybe there isn't even any problem (at > >> least for OMAP). So lets say we set the default plane zpos to the plane > >> index, and that the primary planes are reserved first (i.e. have lower > >> zpos than overlay planes). > >> > >> We have three different cases: > >> > >> Legacy modesetting: No problems, primary plane is always at the bottom. > >> If the userspace uses 2+ overlay planes, it can expect the zpos to be > >> based on the plane id, or it can set the zpos. > >> > >> Atomic+Universal, the application uses one primary plane, and zero or > >> more overlay planes: No problems here, the situation is the same as for > >> legacy. > >> > >> Atomic+Universal, the application uses more than one primary plane, and > >> zero or more overlay planes: in this case the app _has_ to manage zpos, > >> because using two primary planes in a single screen, and expecting it to > >> work by default, doesn't make sense. > >> > >> If the above "rules" are valid, then there's no need for this patch. > >> > >> But one question I don't have a good answer is that why would we want to > >> normalize the zpos, instead of returning an error? If the above rules > >> are valid, I think returning an error is better than normalizing and > >> hiding the bad configuration. > > > > IIRC I argued against the normalization, but some people really > > wanted it for whatever reason. > > OK, please ignore this series, I'll send a patch instead next year. So now we end up with a bunch of kms drivers that normalize zpos, and a bunch of others which rejects duplicated zpos. That sounds even worse. Can we pls try to be consistent (even if it turns out to be a not-so-great uapi decision, it's uapi, so let's not make things worse by making it inconsistent). -Daniel -- 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: [PATCH v5] drm/omap: plane zpos/zorder management improvements
On Tue, Jan 09, 2018 at 01:45:56PM +0200, Peter Ujfalusi wrote: > Use the plane index as default zpos for all planes. Even if the > application is not setting zpos/zorder explicitly we will have unique zpos > for each plane. > > Planes with identical zpos value will result undefined behavior: > disappearing planes, screen flickering and it is not supported by the > hardware. > > Enforce that all planes must have unique zpos on the given crtc by > returning error when duplicate zpos value is requested. > > Signed-off-by: Peter Ujfalusi > --- > Hi, > > Changes since v4: > - further simplify the zpos checking by using a mask and a single loop > - Commit message has been extended > > Changes since v3: > - Use drm_plane_index() instead of storing the same index wothin omap_plane > struct > - Optimize the zpos validation loop so we avoid extra checks. > > Changes since v2: > - The check for duplicate zpos is moved to omap_crtc > > Changes since v1: > - Dropped the zpos normalization related patches > - New patch based on the discussion, see commit message. Sorry for jumping in late to the party, but except when you have a really, really, really good reason for why omapdrm has to not normalize zpos like the other drivers do in this case, then I think we should be consistent. An inconsistent kms uapi is a lot worse than an uapi with some design issues: The latter just means we eventually need v2, the former guarantees we need v2. Thanks, Daniel > > Regards, > Peter > > drivers/gpu/drm/omapdrm/omap_crtc.c | 23 ++- > drivers/gpu/drm/omapdrm/omap_plane.c | 15 --- > 2 files changed, 26 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c > b/drivers/gpu/drm/omapdrm/omap_crtc.c > index 1b8154e58d18..941a6440fc8e 100644 > --- a/drivers/gpu/drm/omapdrm/omap_crtc.c > +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c > @@ -486,6 +486,27 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc > *crtc) > } > } > > +static int omap_crtc_validate_zpos(struct drm_crtc *crtc, > +struct drm_crtc_state *state) > +{ > + struct drm_plane *plane; > + const struct drm_plane_state *pstate; > + unsigned int zpos_mask = 0; > + > + /* Check the crts's planes against duplicated zpos value */ > + drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { > + if (zpos_mask & BIT(pstate->zpos)) { > + DBG("crtc%u: zpos must be unique (zpos: %u)", > + crtc->index, pstate->zpos); > + return -EINVAL; > + } > + > + zpos_mask |= BIT(pstate->zpos); > + } > + > + return 0; > +} > + > static int omap_crtc_atomic_check(struct drm_crtc *crtc, > struct drm_crtc_state *state) > { > @@ -509,7 +530,7 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, > omap_crtc_state->rotation = pri_state->rotation; > } > > - return 0; > + return omap_crtc_validate_zpos(crtc, state); > } > > static void omap_crtc_atomic_begin(struct drm_crtc *crtc, > diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c > b/drivers/gpu/drm/omapdrm/omap_plane.c > index 7d789d1551a1..39f25210bef1 100644 > --- a/drivers/gpu/drm/omapdrm/omap_plane.c > +++ b/drivers/gpu/drm/omapdrm/omap_plane.c > @@ -97,8 +97,7 @@ static void omap_plane_atomic_disable(struct drm_plane > *plane, > struct omap_plane *omap_plane = to_omap_plane(plane); > > plane->state->rotation = DRM_MODE_ROTATE_0; > - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY > -? 0 : omap_plane->id; > + plane->state->zpos = drm_plane_index(plane); > > priv->dispc_ops->ovl_enable(omap_plane->id, false); > } > @@ -184,18 +183,12 @@ void omap_plane_install_properties(struct drm_plane > *plane, > > static void omap_plane_reset(struct drm_plane *plane) > { > - struct omap_plane *omap_plane = to_omap_plane(plane); > - > drm_atomic_helper_plane_reset(plane); > if (!plane->state) > return; > > - /* > - * Set the zpos default depending on whether we are a primary or overlay > - * plane. > - */ > - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY > -? 0 : omap_plane->id; > + /* Set the zpos to the plane index. */ > + plane->state->zpos = drm_plane_index(plane); > } > > static int omap_plane_atomic_set_property(struct drm_plane *plane, > @@ -295,7 +288,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, > drm_plane_helper_add(plane, &omap_plane_helper_funcs); > > omap_plane_install_properties(plane, &plane->base); > - drm_plane_create_zpos_property(plane, 0, 0, num_planes - 1); > + drm_plane_create_zpos_property(plane, idx, 0, num_planes - 1); > > return plane; > > -- > Peter > > Texas Instruments Finland Oy, Porkka
Re: [PATCHv5 0/3] drm/i915: add DisplayPort CEC-Tunneling-over-AUX support
First of all a Happy New Year for all of you! And secondly: can this v5 patch series be reviewed/merged? It's been waiting for that for a very long time now... Regards, Hans On 12/11/17 09:57, Hans Verkuil wrote: > Ping again. Added a CC to Ville whom I inexplicably forgot to add when > I sent the v5 patch series. > > Regards, > > Hans > > On 01/12/17 08:23, Hans Verkuil wrote: >> Ping! >> >> I really like to get this in for 4.16 so I can move forward with hooking >> this up for nouveau/amd. >> >> Regards, >> >> Hans >> >> On 11/20/2017 12:42 PM, Hans Verkuil wrote: >>> This patch series adds support for the DisplayPort CEC-Tunneling-over-AUX >>> feature. This patch series is based on the 4.14 mainline release but applies >>> as well to drm-next. >>> >>> This patch series has been tested with my NUC7i5BNK, a Samsung USB-C to >>> HDMI adapter and a Club 3D DisplayPort MST Hub + modified UpTab DP-to-HDMI >>> adapter (where the CEC pin is wired up). >>> >>> Please note this comment at the start of drm_dp_cec.c: >>> >>> -- >>> Unfortunately it turns out that we have a chicken-and-egg situation >>> here. Quite a few active (mini-)DP-to-HDMI or USB-C-to-HDMI adapters >>> have a converter chip that supports CEC-Tunneling-over-AUX (usually the >>> Parade PS176 or MegaChips MCDP2900), but they do not wire up the CEC pin, >>> thus making CEC useless. >>> >>> Sadly there is no way for this driver to know this. What happens is >>> that a /dev/cecX device is created that is isolated and unable to see >>> any of the other CEC devices. Quite literally the CEC wire is cut >>> (or in this case, never connected in the first place). >>> >>> I suspect that the reason so few adapters support this is that this >>> tunneling protocol was never supported by any OS. So there was no >>> easy way of testing it, and no incentive to correctly wire up the >>> CEC pin. >>> >>> Hopefully by creating this driver it will be easier for vendors to >>> finally fix their adapters and test the CEC functionality. >>> >>> I keep a list of known working adapters here: >>> >>> https://hverkuil.home.xs4all.nl/cec-status.txt >>> >>> Please mail me (hverk...@xs4all.nl) if you find an adapter that works >>> and is not yet listed there. >>> >>> Note that the current implementation does not support CEC over an MST hub. >>> As far as I can see there is no mechanism defined in the DisplayPort >>> standard to transport CEC interrupts over an MST device. It might be >>> possible to do this through polling, but I have not been able to get that >>> to work. >>> -- >>> >>> I really hope that this work will provide an incentive for vendors to >>> finally connect the CEC pin. It's a shame that there are so few adapters >>> that work (I found only two USB-C to HDMI adapters that work, and no >>> (mini-)DP to HDMI adapters at all). >>> >>> Hopefully if this gets merged there will be an incentive for vendors >>> to make adapters where this actually works. It is a very nice feature >>> for HTPC boxes. >>> >>> The main reason why this v5 is delayed by 2 months is due to the fact >>> that I needed some dedicated time to investigate what happens when an >>> MST hub is in use. It turns out that this is not working. There is no >>> mechanism defined in the DisplayPort standard to transport the CEC >>> interrupt back up the MST chain. I was actually able to send a CEC >>> message but the interrupt that tells when the transmit finished is >>> unavailable. >>> >>> I attempted to implement this via polling, but I got weird errors >>> and was not able to read the DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1 >>> register. I decided to give up on this for now and just disable CEC >>> for DP-to-HDMI adapters after an MST hub. I plan to revisit this >>> later since it would be neat to make this work as well. Although it >>> might not be possible at all. >>> >>> If anyone is interested, work-in-progress for this is here: >>> >>> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=dp-cec-mst >>> >>> Note that I removed the Tested-by tag from Carlos Santa due to the >>> almost complete rework of the third patch. Carlos, can you test this again? >>> >>> Regards, >>> >>> Hans >>> >>> Changes since v4: >>> >>> - Updated comment at the start of drm_dp_cec.c >>> - Add edid pointer to drm_dp_cec_configure_adapter >>> - Reworked the last patch (adding CEC to i915) based on Ville's comments >>> and my MST testing: >>> - register/unregister CEC in intel_dp_connector_register/unregister >>> - add comment and check if connector is registered in long_pulse >>> - unregister CEC if an MST 'connector' is detected. >>> >>> ___ >>> dri-devel mailing list >>> dri-devel@lists.freedesktop.org >>> https://lists.freedesktop.org/mailman/listinfo/dri-devel >>> >> >>
Re: [PATCH v5] drm/omap: plane zpos/zorder management improvements
Hi Peter, Thank you for the patch. On Tuesday, 9 January 2018 13:45:56 EET Peter Ujfalusi wrote: > Use the plane index as default zpos for all planes. Even if the > application is not setting zpos/zorder explicitly we will have unique zpos > for each plane. > > Planes with identical zpos value will result undefined behavior: > disappearing planes, screen flickering and it is not supported by the > hardware. > > Enforce that all planes must have unique zpos on the given crtc by > returning error when duplicate zpos value is requested. > > Signed-off-by: Peter Ujfalusi Reviewed-by: Laurent Pinchart > --- > Hi, > > Changes since v4: > - further simplify the zpos checking by using a mask and a single loop > - Commit message has been extended > > Changes since v3: > - Use drm_plane_index() instead of storing the same index wothin omap_plane > struct > - Optimize the zpos validation loop so we avoid extra checks. > > Changes since v2: > - The check for duplicate zpos is moved to omap_crtc > > Changes since v1: > - Dropped the zpos normalization related patches > - New patch based on the discussion, see commit message. > > Regards, > Peter > > drivers/gpu/drm/omapdrm/omap_crtc.c | 23 ++- > drivers/gpu/drm/omapdrm/omap_plane.c | 15 --- > 2 files changed, 26 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c > b/drivers/gpu/drm/omapdrm/omap_crtc.c index 1b8154e58d18..941a6440fc8e > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_crtc.c > +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c > @@ -486,6 +486,27 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc > *crtc) } > } > > +static int omap_crtc_validate_zpos(struct drm_crtc *crtc, > +struct drm_crtc_state *state) > +{ > + struct drm_plane *plane; > + const struct drm_plane_state *pstate; > + unsigned int zpos_mask = 0; > + > + /* Check the crts's planes against duplicated zpos value */ > + drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { > + if (zpos_mask & BIT(pstate->zpos)) { > + DBG("crtc%u: zpos must be unique (zpos: %u)", > + crtc->index, pstate->zpos); > + return -EINVAL; > + } > + > + zpos_mask |= BIT(pstate->zpos); > + } > + > + return 0; > +} > + > static int omap_crtc_atomic_check(struct drm_crtc *crtc, > struct drm_crtc_state *state) > { > @@ -509,7 +530,7 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, > omap_crtc_state->rotation = pri_state->rotation; > } > > - return 0; > + return omap_crtc_validate_zpos(crtc, state); > } > > static void omap_crtc_atomic_begin(struct drm_crtc *crtc, > diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c > b/drivers/gpu/drm/omapdrm/omap_plane.c index 7d789d1551a1..39f25210bef1 > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_plane.c > +++ b/drivers/gpu/drm/omapdrm/omap_plane.c > @@ -97,8 +97,7 @@ static void omap_plane_atomic_disable(struct drm_plane > *plane, struct omap_plane *omap_plane = to_omap_plane(plane); > > plane->state->rotation = DRM_MODE_ROTATE_0; > - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY > -? 0 : omap_plane->id; > + plane->state->zpos = drm_plane_index(plane); > > priv->dispc_ops->ovl_enable(omap_plane->id, false); > } > @@ -184,18 +183,12 @@ void omap_plane_install_properties(struct drm_plane > *plane, > > static void omap_plane_reset(struct drm_plane *plane) > { > - struct omap_plane *omap_plane = to_omap_plane(plane); > - > drm_atomic_helper_plane_reset(plane); > if (!plane->state) > return; > > - /* > - * Set the zpos default depending on whether we are a primary or overlay > - * plane. > - */ > - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY > -? 0 : omap_plane->id; > + /* Set the zpos to the plane index. */ > + plane->state->zpos = drm_plane_index(plane); > } > > static int omap_plane_atomic_set_property(struct drm_plane *plane, > @@ -295,7 +288,7 @@ struct drm_plane *omap_plane_init(struct drm_device > *dev, drm_plane_helper_add(plane, &omap_plane_helper_funcs); > > omap_plane_install_properties(plane, &plane->base); > - drm_plane_create_zpos_property(plane, 0, 0, num_planes - 1); > + drm_plane_create_zpos_property(plane, idx, 0, num_planes - 1); > > return plane; -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 104556] WARNING: CPU: 1 PID: 7288 at mm/slab_common.c:971 kmalloc_slab+0x5e/0x70
https://bugs.freedesktop.org/show_bug.cgi?id=104556 Bug ID: 104556 Summary: WARNING: CPU: 1 PID: 7288 at mm/slab_common.c:971 kmalloc_slab+0x5e/0x70 Product: DRI Version: XOrg git Hardware: Other OS: All Status: NEW Severity: normal Priority: medium Component: DRM/AMDgpu Assignee: dri-devel@lists.freedesktop.org Reporter: pmenzel+bugs.freedesk...@molgen.mpg.de With Linux 4.14.12 and libdrm 2.4.89, running `sudo tests/amdgpu/amdgpu_test l`, it hangs at *gfx ring block test*, and the Linux messages below can be seen running `dmesg`. ``` [ 175.540929] [ cut here ] [ 175.540933] WARNING: CPU: 1 PID: 7288 at mm/slab_common.c:971 kmalloc_slab+0x5e/0x70 [ 175.540934] Modules linked in: nfsv4 nfs 8021q garp mrp stp llc amdgpu ttm drm_kms_helper cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt hci_uart fb_sys_fops cfbcopyarea fb font fbdev drm btqca btintel bluetooth wmi_bmof video ecdh_generic wmi nfsd auth_rpcgss oid_registry nfs_acl lockd grace sunrpc ipv6 autofs4 unix [ 175.540960] CPU: 1 PID: 7288 Comm: lt-amdgpu_test Not tainted 4.14.12.mx64.200 #1 [ 175.540961] Hardware name: Dell Inc. OptiPlex 5040/0R790T, BIOS 1.2.7 01/15/2016 [ 175.540961] task: 8802389b90c0 task.stack: c9000b724000 [ 175.540963] RIP: 0010:kmalloc_slab+0x5e/0x70 [ 175.540963] RSP: 0018:c9000b727928 EFLAGS: 00010246 [ 175.540964] RAX: RBX: 880250789008 RCX: c9000b727a90 [ 175.540965] RDX: 048c27c0 RSI: RDI: 048c27c0 [ 175.540965] RBP: c9000b727a90 R08: 880250789008 R09: 880250789038 [ 175.540965] R10: 8802427426c8 R11: R12: 014080c0 [ 175.540966] R13: 048c27c0 R14: a0338314 R15: 8802427426c8 [ 175.540966] FS: 7f56b969c700() GS:88025c48() knlGS: [ 175.540967] CS: 0010 DS: ES: CR0: 80050033 [ 175.540967] CR2: 7f56b96d1000 CR3: 00024a95e004 CR4: 003606e0 [ 175.540968] DR0: DR1: DR2: [ 175.540968] DR3: DR6: fffe0ff0 DR7: 0400 [ 175.540968] Call Trace: [ 175.540971] __kmalloc+0x23/0x240 [ 175.541001] amdgpu_vram_mgr_new+0xc4/0x2b0 [amdgpu] [ 175.541004] ttm_bo_mem_space+0x111/0x4e0 [ttm] [ 175.541009] ? add_hole+0xcc/0xf0 [drm] [ 175.541010] ttm_bo_validate+0xab/0x120 [ttm] [ 175.541014] ? drm_prime_handle_to_fd_ioctl+0x3e/0x50 [drm] [ 175.541016] ttm_bo_init_reserved+0x343/0x400 [ttm] [ 175.541022] amdgpu_bo_create_restricted+0x1db/0x460 [amdgpu] [ 175.541029] ? amdgpu_fill_buffer+0x2e0/0x2e0 [amdgpu] [ 175.541036] amdgpu_bo_create+0xbd/0x1b0 [amdgpu] [ 175.541043] amdgpu_gem_object_create+0x76/0xe0 [amdgpu] [ 175.541050] ? amdgpu_gem_object_close+0x1b0/0x1b0 [amdgpu] [ 175.541056] amdgpu_gem_create_ioctl+0x84/0x100 [amdgpu] [ 175.541059] drm_ioctl_kernel+0x65/0xb0 [drm] [ 175.541062] drm_ioctl+0x28b/0x330 [drm] [ 175.541069] ? amdgpu_gem_object_close+0x1b0/0x1b0 [amdgpu] [ 175.541070] ? tty_write+0x1e6/0x2c0 [ 175.541071] ? n_tty_open+0xd0/0xd0 [ 175.541076] amdgpu_drm_ioctl+0x46/0x80 [amdgpu] [ 175.541078] do_vfs_ioctl+0x8f/0x5b0 [ 175.541079] ? vfs_write+0x194/0x1b0 [ 175.541080] SyS_ioctl+0x3b/0x70 [ 175.541081] entry_SYSCALL_64_fastpath+0x13/0x6c [ 175.541082] RIP: 0033:0x7f56b86993e7 [ 175.541083] RSP: 002b:7ffe44526408 EFLAGS: 0246 [ 175.541083] Code: 82 f3 c3 48 85 ff b8 10 00 00 00 74 f4 48 83 ef 01 48 c1 ef 03 48 63 ff 0f be 87 c0 f6 46 82 eb d1 31 c0 81 e6 00 02 00 00 75 d6 <0f> ff c3 48 8b 04 c5 c0 74 b3 82 c3 66 0f 1f 44 00 00 0f 1f 44 [ 175.541097] ---[ end trace bd4b3546ebd3d3ae ]--- [ 175.541108] [drm:amdgpu_gem_object_create [amdgpu]] *ERROR* Failed to allocate GEM object (1, 6, 4096, -12) ``` -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 104556] WARNING: CPU: 1 PID: 7288 at mm/slab_common.c:971 kmalloc_slab+0x5e/0x70
https://bugs.freedesktop.org/show_bug.cgi?id=104556 --- Comment #1 from Paul Menzel --- ``` $ dmesg [0.00] Linux version 4.14.12.mx64.200 (r...@orpheus.molgen.mpg.de) (gcc version 5.3.0 (GCC)) #1 SMP Mon Jan 8 12:53:28 CET 2018 [0.00] Command line: BOOT_IMAGE=/boot/bzImage-4.14.12.mx64.200 crashkernel=256M root=LABEL=root ro console=ttyS1,115200n8 console=tty0 [0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' [0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers' [0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers' [0.00] x86/fpu: Supporting XSAVE feature 0x008: 'MPX bounds registers' [0.00] x86/fpu: Supporting XSAVE feature 0x010: 'MPX CSR' [0.00] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256 [0.00] x86/fpu: xstate_offset[3]: 832, xstate_sizes[3]: 64 [0.00] x86/fpu: xstate_offset[4]: 896, xstate_sizes[4]: 64 [0.00] x86/fpu: Enabled xstate features 0x1f, context size is 960 bytes, using 'compacted' format. [0.00] e820: BIOS-provided physical RAM map: [0.00] BIOS-e820: [mem 0x-0x000907ff] usable [0.00] BIOS-e820: [mem 0x00090800-0x0009] reserved [0.00] BIOS-e820: [mem 0x000e-0x000f] reserved [0.00] BIOS-e820: [mem 0x0010-0x9082cfff] usable [0.00] BIOS-e820: [mem 0x9082d000-0x9082dfff] ACPI NVS [0.00] BIOS-e820: [mem 0x9082e000-0x90857fff] reserved [0.00] BIOS-e820: [mem 0x90858000-0x908abfff] usable [0.00] BIOS-e820: [mem 0x908ac000-0x910acfff] reserved [0.00] BIOS-e820: [mem 0x910ad000-0x9db54fff] usable [0.00] BIOS-e820: [mem 0x9db55000-0x9f2bbfff] reserved [0.00] BIOS-e820: [mem 0x9f2bc000-0x9f309fff] ACPI data [0.00] BIOS-e820: [mem 0x9f30a000-0x9fabefff] ACPI NVS [0.00] BIOS-e820: [mem 0x9fabf000-0x9fffefff] reserved [0.00] BIOS-e820: [mem 0x9000-0x9fff] usable [0.00] BIOS-e820: [mem 0xa000-0xa00f] reserved [0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved [0.00] BIOS-e820: [mem 0xfe00-0xfe010fff] reserved [0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved [0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved [0.00] BIOS-e820: [mem 0xff00-0x] reserved [0.00] BIOS-e820: [mem 0x0001-0x00025c7f] usable [0.00] NX (Execute Disable) protection: active [0.00] random: fast init done [0.00] SMBIOS 2.8 present. [0.00] DMI: Dell Inc. OptiPlex 5040/0R790T, BIOS 1.2.7 01/15/2016 [0.00] e820: update [mem 0x-0x0fff] usable ==> reserved [0.00] e820: remove [mem 0x000a-0x000f] usable [0.00] e820: last_pfn = 0x25c800 max_arch_pfn = 0x4 [0.00] MTRR default type: write-back [0.00] MTRR fixed ranges enabled: [0.00] 0-9 write-back [0.00] A-B uncachable [0.00] C-F write-protect [0.00] MTRR variable ranges enabled: [0.00] 0 base 00C000 mask 7FC000 uncachable [0.00] 1 base 00B000 mask 7FF000 uncachable [0.00] 2 base 00A800 mask 7FF800 uncachable [0.00] 3 base 00A400 mask 7FFC00 uncachable [0.00] 4 base 00A200 mask 7FFE00 uncachable [0.00] 5 base 00A180 mask 7FFF80 uncachable [0.00] 6 disabled [0.00] 7 disabled [0.00] 8 disabled [0.00] 9 disabled [0.00] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WP UC- WT [0.00] e820: last_pfn = 0xa max_arch_pfn = 0x4 [0.00] found SMP MP-table at [mem 0x000fcdf0-0x000fcdff] mapped at [ff200df0] [0.00] Base memory trampoline at [8808a000] 8a000 size 24576 [0.00] Using GB pages for direct mapping [0.00] BRK [0x02b6b000, 0x02b6bfff] PGTABLE [0.00] BRK [0x02b6c000, 0x02b6cfff] PGTABLE [0.00] BRK [0x02b6d000, 0x02b6dfff] PGTABLE [0.00] BRK [0x02b6e000, 0x02b6efff] PGTABLE [0.00] BRK [0x02b6f000, 0x02b6] PGTABLE [0.00] BRK [0x02b7, 0x02b70fff] PGTABLE [0.00] RAMDISK: [mem 0x375e7000-0x37aeafff] [0.00] ACPI: Early table checksum verification disabled [0.00] ACPI: RSDP 0x000F05B0 24 (v02 DELL ) [0.00] ACPI: XSDT 0x9F2DC0A0 C4 (v01 DELL CBX3 01072009 AMI 00010013) [0.00] ACPI: FACP 0x9F2FE770 00010C (v05 DELL CBX3 01072009 AMI 00010013) [0.00] ACPI: DSD
Re: [PATCH 03/11] drm/bridge/synopsys: dw-hdmi: Enable workaround for v1.32a
Hi Jernej, Thank you for the patch. On Saturday, 30 December 2017 23:01:55 EET Jernej Skrabec wrote: > Allwinner SoCs have dw hdmi controller v1.32a which exhibits same > magenta line issue as i.MX6Q and i.MX6DL. Enable workaround for it. > > Tests show that one iteration is enough. > > Signed-off-by: Jernej Skrabec This does not break R-Car DU, so Acked-by: Laurent Pinchart > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index > a38db40ce990..7ca14d7325b5 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -1634,9 +1634,10 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi > *hdmi) * then write one of the FC registers several times. >* >* The number of iterations matters and depends on the HDMI TX revision > - * (and possibly on the platform). So far only i.MX6Q (v1.30a) and > - * i.MX6DL (v1.31a) have been identified as needing the workaround, with > - * 4 and 1 iterations respectively. > + * (and possibly on the platform). So far i.MX6Q (v1.30a), i.MX6DL > + * (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified > + * as needing the workaround, with 4 iterations for v1.30a and 1 > + * iteration for others. >*/ > > switch (hdmi->version) { > @@ -1644,6 +1645,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi > *hdmi) count = 4; > break; > case 0x131a: > + case 0x132a: > count = 1; > break; > default: -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 104556] WARNING: CPU: 1 PID: 7288 at mm/slab_common.c:971 kmalloc_slab+0x5e/0x70
https://bugs.freedesktop.org/show_bug.cgi?id=104556 --- Comment #2 from Paul Menzel --- The system seems to hang afterward, even after killing the test. The X.Org X server doesn’t start, and it doesn’t shut down. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/virtio: Add window server support
On 28 December 2017 at 12:53, Tomeu Vizoso wrote: > This is to allow clients running within VMs to be able to communicate > with a compositor in the host. Clients will use the communication > protocol that the compositor supports, and virtio-gpu will assist with > making buffers available in both sides, and copying content as needed. Here is the qemu side, a bit hackier atm: https://gitlab.collabora.com/tomeu/qemu/commits/winsrv-wip Regards, Tomeu > It is expected that a service in the guest will act as a proxy, > interacting with virtio-gpu to support unmodified clients. For some > features of the protocol, the hypervisor might have to intervene and > also parse the protocol data to properly bridge resources. The following > IOCTLs have been added to this effect: > > *_WINSRV_CONNECT: Opens a connection to the compositor in the host, > returns a FD that represents this connection and on which the following > IOCTLs can be used. Callers are expected to poll this FD for new > messages from the compositor. > > *_WINSRV_TX: Asks the hypervisor to forward a message to the compositor > > *_WINSRV_RX: Returns all queued messages > > Alongside protocol data that is opaque to the kernel, the client can > send file descriptors that reference GEM buffers allocated by > virtio-gpu. The guest proxy is expected to figure out when a client is > passing a FD that refers to shared memory in the guest and allocate a > virtio-gpu buffer of the same size with DRM_VIRTGPU_RESOURCE_CREATE. > > When the client notifies the compositor that it can read from that buffer, > the proxy should copy the contents from the SHM region to the virtio-gpu > resource and call DRM_VIRTGPU_TRANSFER_TO_HOST. > > This has been tested with Wayland clients that make use of wl_shm to > pass buffers to the compositor, but is expected to work similarly for X > clients that make use of MIT-SHM with FD passing. > > v2: * Add padding to two virtio command structs > * Properly cast two __user pointers (kbuild test robot) > > Signed-off-by: Tomeu Vizoso > Cc: Zach Reizner > > --- > > Hi, > > this work is based on the virtio_wl driver in the ChromeOS kernel by > Zach Reizner, currently at: > > https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-4.4/drivers/virtio/virtio_wl.c > > There's two features missing in this patch when compared with virtio_wl: > > * Allow the guest access directly host memory, without having to resort > to TRANSFER_TO_HOST > > * Pass FDs from host to guest (Wayland specifies that the compositor > shares keyboard data with the guest via a shared buffer) > > I plan to work on this next, but I would like to get some comments on > the general approach so I can better choose which patch to follow. > > Thanks, > > Tomeu > --- > drivers/gpu/drm/virtio/virtgpu_drv.h | 39 - > drivers/gpu/drm/virtio/virtgpu_ioctl.c | 168 +++ > drivers/gpu/drm/virtio/virtgpu_kms.c | 58 +-- > drivers/gpu/drm/virtio/virtgpu_vq.c| 285 > - > include/uapi/drm/virtgpu_drm.h | 29 > include/uapi/linux/virtio_gpu.h| 41 + > 6 files changed, 605 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h > b/drivers/gpu/drm/virtio/virtgpu_drv.h > index da2fb585fea4..268b386e1232 100644 > --- a/drivers/gpu/drm/virtio/virtgpu_drv.h > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h > @@ -178,6 +178,8 @@ struct virtio_gpu_device { > > struct virtio_gpu_queue ctrlq; > struct virtio_gpu_queue cursorq; > + struct virtio_gpu_queue winsrv_rxq; > + struct virtio_gpu_queue winsrv_txq; > struct kmem_cache *vbufs; > bool vqs_ready; > > @@ -205,10 +207,32 @@ struct virtio_gpu_device { > > struct virtio_gpu_fpriv { > uint32_t ctx_id; > + > + struct list_head winsrv_conns; /* list of virtio_gpu_winsrv_conn */ > + spinlock_t winsrv_lock; > +}; > + > +struct virtio_gpu_winsrv_rx_qentry { > + struct virtio_gpu_winsrv_rx *cmd; > + struct list_head next; > +}; > + > +struct virtio_gpu_winsrv_conn { > + struct virtio_gpu_device *vgdev; > + > + spinlock_t lock; > + > + int fd; > + struct drm_file *drm_file; > + > + struct list_head cmdq; /* queue of virtio_gpu_winsrv_rx_qentry */ > + wait_queue_head_t cmdwq; > + > + struct list_head next; > }; > > /* virtio_ioctl.c */ > -#define DRM_VIRTIO_NUM_IOCTLS 10 > +#define DRM_VIRTIO_NUM_IOCTLS 11 > extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; > > /* virtio_kms.c */ > @@ -318,9 +342,22 @@ virtio_gpu_cmd_resource_create_3d(struct > virtio_gpu_device *vgdev, > void virtio_gpu_ctrl_ack(struct virtqueue *vq); > void virtio_gpu_cursor_ack(struct virtqueue *vq); > void virtio_gpu_fence_ack(struct virtqueue *vq); > +void virtio_gpu_winsrv_tx_ack(struct virtqueue *vq); > +void virtio_gpu_winsrv_rx_read(struct virtqueue *vq); > void virtio_gpu_dequeue_ctrl_
Re: [PATCH] drm/bridge/synopsis: stop clobbering drvdata
Hi Archit, Andrzej & Laurent, Regarding this patch from Brian, I think it could be nice to merge it (1xAcked-by, 2xReviewed-by). Could you please have a look? Only the small "typo" in the headline needs to be changed. Many thanks, Philippe :-) On 11/28/2017 10:34 AM, Philippe CORNU wrote: > Hi Brian, > > On 11/28/2017 02:05 AM, Brian Norris wrote: >> Bridge drivers/helpers shouldn't be clobbering the drvdata, since a >> parent driver might need to own this. Instead, let's return our >> 'dw_mipi_dsi' object and have callers pass that back to us for removal. > > And many thanks for this cleanup. > (please update the headline with "synopsys") > > Successfully tested on stm. > > Acked-by: Philippe Cornu > > Many thanks, > Philippe :-) >> >> Signed-off-by: Brian Norris >> --- >> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 36 >> ++- >> drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 14 +++ >> include/drm/bridge/dw_mipi_dsi.h | 17 - >> 3 files changed, 33 insertions(+), 34 deletions(-) >> >> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c >> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c >> index d9cca4fd66ec..c39c7dce20ed 100644 >> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c >> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c >> @@ -922,8 +922,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, >> dsi->bridge.of_node = pdev->dev.of_node; >> #endif >> - dev_set_drvdata(dev, dsi); >> - >> return dsi; >> } >> @@ -935,23 +933,16 @@ static void __dw_mipi_dsi_remove(struct >> dw_mipi_dsi *dsi) >> /* >> * Probe/remove API, used from platforms based on the DRM bridge API. >> */ >> -int dw_mipi_dsi_probe(struct platform_device *pdev, >> - const struct dw_mipi_dsi_plat_data *plat_data) >> +struct dw_mipi_dsi * >> +dw_mipi_dsi_probe(struct platform_device *pdev, >> + const struct dw_mipi_dsi_plat_data *plat_data) >> { >> - struct dw_mipi_dsi *dsi; >> - >> - dsi = __dw_mipi_dsi_probe(pdev, plat_data); >> - if (IS_ERR(dsi)) >> - return PTR_ERR(dsi); >> - >> - return 0; >> + return __dw_mipi_dsi_probe(pdev, plat_data); >> } >> EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe); >> -void dw_mipi_dsi_remove(struct platform_device *pdev) >> +void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) >> { >> - struct dw_mipi_dsi *dsi = platform_get_drvdata(pdev); >> - >> mipi_dsi_host_unregister(&dsi->dsi_host); >> __dw_mipi_dsi_remove(dsi); >> @@ -961,31 +952,30 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove); >> /* >> * Bind/unbind API, used from platforms based on the component >> framework. >> */ >> -int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder >> *encoder, >> - const struct dw_mipi_dsi_plat_data *plat_data) >> +struct dw_mipi_dsi * >> +dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder >> *encoder, >> + const struct dw_mipi_dsi_plat_data *plat_data) >> { >> struct dw_mipi_dsi *dsi; >> int ret; >> dsi = __dw_mipi_dsi_probe(pdev, plat_data); >> if (IS_ERR(dsi)) >> - return PTR_ERR(dsi); >> + return dsi; >> ret = drm_bridge_attach(encoder, &dsi->bridge, NULL); >> if (ret) { >> - dw_mipi_dsi_remove(pdev); >> + dw_mipi_dsi_remove(dsi); >> DRM_ERROR("Failed to initialize bridge with drm\n"); >> - return ret; >> + return ERR_PTR(ret); >> } >> - return 0; >> + return dsi; >> } >> EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind); >> -void dw_mipi_dsi_unbind(struct device *dev) >> +void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi) >> { >> - struct dw_mipi_dsi *dsi = dev_get_drvdata(dev); >> - >> __dw_mipi_dsi_remove(dsi); >> } >> EXPORT_SYMBOL_GPL(dw_mipi_dsi_unbind); >> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c >> b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c >> index e5b6310240fe..7ed0ef7f6ec2 100644 >> --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c >> +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c >> @@ -66,6 +66,7 @@ enum dsi_color { >> struct dw_mipi_dsi_stm { >> void __iomem *base; >> struct clk *pllref_clk; >> + struct dw_mipi_dsi *dsi; >> }; >> static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, >> u32 val) >> @@ -318,21 +319,24 @@ static int dw_mipi_dsi_stm_probe(struct >> platform_device *pdev) >> dw_mipi_dsi_stm_plat_data.base = dsi->base; >> dw_mipi_dsi_stm_plat_data.priv_data = dsi; >> - ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); >> - if (ret) { >> + platform_set_drvdata(pdev, dsi); >> + >> + dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); >> + if (IS_ERR(dsi->dsi)) { >> DRM_ERROR("Failed to initialize mipi dsi host\n"); >> clk_disable_unprepare(dsi->pllref_clk); >> + return PTR_ERR(dsi->dsi); >> } >> - return ret; >> + return 0; >> } >> sta
Re: [PATCH] drm/stm: ltdc: add clut mode support
2018-01-09 12:56 GMT+01:00 Peter Rosin : > On 2018-01-09 12:28, Philippe CORNU wrote: >> Hi all, >> >> Do you think the patch is "acceptable" or should I change it somehow? >> Any opinion is welcomed : ) > > Maybe you should try Daniel Vetter? He was very helpful (thanks) when > I worked on the clut changes... Since it only impact stm driver, I have applied it on drm-misc-next. Regards, Benjamin > > Cheers, > Peter ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 01/19] drm/fourcc: Add a function to tell if the format embeds alpha
Hi Laurent, On Tue, Jan 09, 2018 at 02:29:58PM +0200, Laurent Pinchart wrote: > On Tuesday, 9 January 2018 12:56:20 EET Maxime Ripard wrote: > > There's a bunch of drivers that duplicate the same function to know if a > > particular format embeds an alpha component or not. > > > > Let's create a helper to avoid duplicating that logic. > > > > Cc: Boris Brezillon > > Cc: Eric Anholt > > Cc: Inki Dae > > Cc: Joonyoung Shim > > Cc: Kyungmin Park > > Cc: Laurent Pinchart > > Cc: Mark Yao > > Cc: Seung-Woo Kim > > Signed-off-by: Maxime Ripard > > --- > > drivers/gpu/drm/drm_fourcc.c | 43 +- > > include/drm/drm_fourcc.h | 1 +- > > 2 files changed, 44 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c > > index 9c0152df45ad..6e6227d6a46b 100644 > > --- a/drivers/gpu/drm/drm_fourcc.c > > +++ b/drivers/gpu/drm/drm_fourcc.c > > @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t > > format, int plane) return height / info->vsub; > > } > > EXPORT_SYMBOL(drm_format_plane_height); > > + > > +/** > > + * drm_format_has_alpha - get whether the format embeds an alpha component > > + * @format: pixel format (DRM_FORMAT_*) > > + * > > + * Returns: > > + * true if the format embeds an alpha component, false otherwise. > > + */ > > +bool drm_format_has_alpha(uint32_t format) > > +{ > > + switch (format) { > > + case DRM_FORMAT_ARGB: > > + case DRM_FORMAT_ABGR: > > + case DRM_FORMAT_RGBA: > > + case DRM_FORMAT_BGRA: > > + case DRM_FORMAT_ARGB1555: > > + case DRM_FORMAT_ABGR1555: > > + case DRM_FORMAT_RGBA5551: > > + case DRM_FORMAT_BGRA5551: > > + case DRM_FORMAT_ARGB: > > + case DRM_FORMAT_ABGR: > > + case DRM_FORMAT_RGBA: > > + case DRM_FORMAT_BGRA: > > + case DRM_FORMAT_ARGB2101010: > > + case DRM_FORMAT_ABGR2101010: > > + case DRM_FORMAT_RGBA1010102: > > + case DRM_FORMAT_BGRA1010102: > > + case DRM_FORMAT_AYUV: > > + case DRM_FORMAT_XRGB_A8: > > + case DRM_FORMAT_XBGR_A8: > > + case DRM_FORMAT_RGBX_A8: > > + case DRM_FORMAT_BGRX_A8: > > + case DRM_FORMAT_RGB888_A8: > > + case DRM_FORMAT_BGR888_A8: > > + case DRM_FORMAT_RGB565_A8: > > + case DRM_FORMAT_BGR565_A8: > > + return true; > > + > > + default: > > + return false; > > + } > > +} > > +EXPORT_SYMBOL(drm_format_has_alpha); > > How about adding the information to struct drm_format_info instead ? > drm_format_has_alpha() could then be implemented as > > bool drm_format_has_alpha(uint32_t format) > { > const struct drm_format_info *info; > > info = drm_format_info(format); > return info ? info->has_alpha : false; > } I considered it, and wasn't too sure about if adding more fields to drm_format_info was ok. I can definitely do it that way. > although drivers should really use the drm_framebuffer::format field directly > in most cases, so the helper might not be needed at all. The drivers converted in my serie shouldn't be too hard to convert to use drm_format_info directly, so that can be removed as well. Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 04/11] drm/bridge/synopsys: dw-hdmi: Export some PHY related functions
Hi Jernej, Thank you for the patch. On Saturday, 30 December 2017 23:01:56 EET Jernej Skrabec wrote: > Parts of PHY code could be useful also for custom PHYs. For example, > Allwinner A83T has custom PHY which is probably Synopsys gen2 PHY > with few additional memory mapped registers, so most of the Synopsys PHY > related code could be reused. > > It turns out that even completely custom HDMI PHYs, such as the one > found in Allwinner H3, can reuse some of those functions. This would > suggest that (some?) functions exported in this commit are actually part > of generic PHY interface and not really specific to Synopsys PHYs. That's correct, those functions control the interface between the HDMI controller and the PHY. They're not specific to Synopsys PHYs, but they're specific to the PHY interface as designed by Synopsys. > Export useful PHY functions. > > Signed-off-by: Jernej Skrabec > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 45 --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++ > include/drm/bridge/dw_hdmi.h | 10 +++ > 3 files changed, 44 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index > 7ca14d7325b5..67467d0b683a 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -1037,19 +1037,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi > *hdmi, u8 enable) HDMI_PHY_CONF0_SVSRET_MASK); > } > > -static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) > +void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) > { > hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, >HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, >HDMI_PHY_CONF0_GEN2_PDDQ_MASK); > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq); > > -static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) > +void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) > { > hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, >HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, >HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron); > > static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) > { > @@ -1065,6 +1067,23 @@ static void dw_hdmi_phy_sel_interface_control(struct > dw_hdmi *hdmi, u8 enable) HDMI_PHY_CONF0_SELDIPIF_MASK); > } > > +void dw_hdmi_phy_gen2_reset(struct dw_hdmi *hdmi, u8 enable) > +{ > + hdmi_mask_writeb(hdmi, enable, HDMI_MC_PHYRSTZ, > + HDMI_MC_PHYRSTZ_PHYRSTZ_OFFSET, > + HDMI_MC_PHYRSTZ_PHYRSTZ_MASK); > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_reset); > + > +void dw_hdmi_phy_set_slave_addr(struct dw_hdmi *hdmi) > +{ > + hdmi_phy_test_clear(hdmi, 1); > + hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, > + HDMI_PHY_I2CM_SLAVE_ADDR); > + hdmi_phy_test_clear(hdmi, 0); > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_set_slave_addr); Should the I2C address be passed as an argument ? > static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) > { > const struct dw_hdmi_phy_data *phy = hdmi->phy.data; > @@ -1204,15 +1223,12 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) > dw_hdmi_phy_enable_svsret(hdmi, 1); > > /* PHY reset. The reset signal is active high on Gen2 PHYs. */ > - hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); > - hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); > + dw_hdmi_phy_gen2_reset(hdmi, 1); > + dw_hdmi_phy_gen2_reset(hdmi, 0); > > hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); > > - hdmi_phy_test_clear(hdmi, 1); > - hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, > - HDMI_PHY_I2CM_SLAVE_ADDR); > - hdmi_phy_test_clear(hdmi, 0); > + dw_hdmi_phy_set_slave_addr(hdmi); > > /* Write to the PHY as configured by the platform */ > if (pdata->configure_phy) > @@ -1251,15 +1267,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi > *hdmi, void *data) dw_hdmi_phy_power_off(hdmi); > } > > -static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, > - void *data) > +enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, > +void *data) > { > return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? > connector_status_connected : connector_status_disconnected; > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd); > > -static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, > -bool force, bool disabled, bool rxsense) > +void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, > + bool force, bool disabled, bool rxsense) > { > u8 old_mask = h
Re: [PATCH] drm/bridge/synopsis: stop clobbering drvdata
Hi Brian, On Tuesday, 28 November 2017 20:21:23 EET Brian Norris wrote: > On Tue, Nov 28, 2017 at 02:51:46PM +0200, Laurent Pinchart wrote: > > Hi Brian, > > > > Thank you for the patch. > > > > I'd mention dw-mipi-dsi in the subject line as the directory contains the > > dw-hdmi driver as well that this patch doesn't touch. > > Yep. Does it need another tag in the subject? e.g., '.../dw-mipi-dsi:'? > > > On Tuesday, 28 November 2017 03:05:38 EET Brian Norris wrote: > >> Bridge drivers/helpers shouldn't be clobbering the drvdata, since a > >> parent driver might need to own this. > > > > By parent driver I assume you mean a glue driver that binds to the SoC- > > specific compatible string for the DSI transmitter. > > Indeed. Nickey picked this up for his Rockchip driver submission, but > maybe we should reword the commit message a bit. How about "drm: dw-mipi-dsi: Stop clobbering drvdata" ? > >> Instead, let's return our > >> 'dw_mipi_dsi' object and have callers pass that back to us for removal. > >> > >> Signed-off-by: Brian Norris > > > > Wouldn't it be cleaner to embed the dw_mipi_dsi structure in the parent- > > specific data structure (struct dw_mipi_dsi_stm and struct > > dw_mipi_dsi_rockchip when the "[PATCH v3 0/5] Update ROCKCHIP DSI driver > > that uses dw-mipi-dsi bridge" patch series will land) instead of > > allocating it dynamically ? We would then have a single object to track. > > I suppose we could do that too. But that would require exposing the > whole layout of 'struct dw_mipi_dsi' to users. Do we want to sacrifice > the enforced separation for a little bit of nicer object handling? I certainly don't think we should go for spaghetti code with all objects accessing each other :) On the other hand, we're talking about C code, and we thus have no way to enforce access restrictions in the compiler, so it's a lost battle anyway. I don't see an issue with exposing the object in the sense of moving its definition to a header file if it results in cleaner code. I think we need to trust developers not to abuse internal APIs, and if they do, catch it during review. > Also, this was modeled a bit after the similar rework needed to untangle > the drvdata handling in the Rockchip analogix DP driver vs. the analogix > bridge DP code: > > [PATCH v6 03/10] drm/bridge: analogix: Do not use device's drvdata > https://patchwork.kernel.org/patch/10015875/ -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge/synopsis: stop clobbering drvdata
Hi Philippe, On Tuesday, 9 January 2018 15:01:02 EET Philippe CORNU wrote: > Hi Archit, Andrzej & Laurent, > > Regarding this patch from Brian, I think it could be nice to merge it > (1xAcked-by, 2xReviewed-by). > > Could you please have a look? > > Only the small "typo" in the headline needs to be changed. > > Many thanks, I've just replied to Brian in this mail thread. Sorry for the delay, it slipped through the cracks. Thank you for pinging me. > On 11/28/2017 10:34 AM, Philippe CORNU wrote: > > > Hi Brian, > > > > On 11/28/2017 02:05 AM, Brian Norris wrote: > > > >> Bridge drivers/helpers shouldn't be clobbering the drvdata, since a > >> parent driver might need to own this. Instead, let's return our > >> 'dw_mipi_dsi' object and have callers pass that back to us for removal. > > > > > > And many thanks for this cleanup. > > (please update the headline with "synopsys") > > > > Successfully tested on stm. > > > > Acked-by: Philippe Cornu > > > > Many thanks, > > Philippe :-) > > > >> > >> > >> Signed-off-by: Brian Norris > >> --- > >> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 36 > >> ++- > >> drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 14 +++ > >> include/drm/bridge/dw_mipi_dsi.h | 17 - > >> 3 files changed, 33 insertions(+), 34 deletions(-) > >> > >> > >> > >> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > >> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > >> index d9cca4fd66ec..c39c7dce20ed 100644 > >> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > >> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > >> @@ -922,8 +922,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > >> dsi->bridge.of_node = pdev->dev.of_node; > >> #endif > >> -dev_set_drvdata(dev, dsi); > >> - > >> return dsi; > >> } > >> @@ -935,23 +933,16 @@ static void __dw_mipi_dsi_remove(struct > >> dw_mipi_dsi *dsi) > >> /* > >>* Probe/remove API, used from platforms based on the DRM bridge API. > >>*/ > >> -int dw_mipi_dsi_probe(struct platform_device *pdev, > >> - const struct dw_mipi_dsi_plat_data *plat_data) > >> +struct dw_mipi_dsi * > >> +dw_mipi_dsi_probe(struct platform_device *pdev, > >> + const struct dw_mipi_dsi_plat_data *plat_data) > >> { > >> -struct dw_mipi_dsi *dsi; > >> - > >> -dsi = __dw_mipi_dsi_probe(pdev, plat_data); > >> -if (IS_ERR(dsi)) > >> -return PTR_ERR(dsi); > >> - > >> -return 0; > >> +return __dw_mipi_dsi_probe(pdev, plat_data); > >> } > >> EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe); > >> -void dw_mipi_dsi_remove(struct platform_device *pdev) > >> +void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) > >> { > >> -struct dw_mipi_dsi *dsi = platform_get_drvdata(pdev); > >> - > >> mipi_dsi_host_unregister(&dsi->dsi_host); > >> __dw_mipi_dsi_remove(dsi); > >> @@ -961,31 +952,30 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove); > >> /* > >>* Bind/unbind API, used from platforms based on the component > >> framework. > >>*/ > >> -int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder > >> *encoder, > >> - const struct dw_mipi_dsi_plat_data *plat_data) > >> +struct dw_mipi_dsi * > >> +dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder > >> *encoder, > >> + const struct dw_mipi_dsi_plat_data *plat_data) > >> { > >> struct dw_mipi_dsi *dsi; > >> int ret; > >> dsi = __dw_mipi_dsi_probe(pdev, plat_data); > >> if (IS_ERR(dsi)) > >> -return PTR_ERR(dsi); > >> +return dsi; > >> ret = drm_bridge_attach(encoder, &dsi->bridge, NULL); > >> if (ret) { > >> -dw_mipi_dsi_remove(pdev); > >> +dw_mipi_dsi_remove(dsi); > >> DRM_ERROR("Failed to initialize bridge with drm\n"); > >> -return ret; > >> +return ERR_PTR(ret); > >> } > >> -return 0; > >> +return dsi; > >> } > >> EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind); > >> -void dw_mipi_dsi_unbind(struct device *dev) > >> +void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi) > >> { > >> -struct dw_mipi_dsi *dsi = dev_get_drvdata(dev); > >> - > >> __dw_mipi_dsi_remove(dsi); > >> } > >> EXPORT_SYMBOL_GPL(dw_mipi_dsi_unbind); > >> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > >> b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > >> index e5b6310240fe..7ed0ef7f6ec2 100644 > >> --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > >> +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > >> @@ -66,6 +66,7 @@ enum dsi_color { > >> struct dw_mipi_dsi_stm { > >> void __iomem *base; > >> struct clk *pllref_clk; > >> +struct dw_mipi_dsi *dsi; > >> }; > >> static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, > >> u32 val) > >> @@ -318,21 +319,24 @@ static int dw_mipi_dsi_stm_probe(struct > >> platform_device *pdev) > >> dw_mipi_dsi_stm_plat_data.base = dsi->base; > >> dw_mipi_ds