Re: DRM_UDL and GPU under Xserver

2018-04-05 Thread Jose Abreu
Hi Alexey, Daniel,

On 05-04-2018 10:32, Daniel Vetter wrote:
> On Thu, Apr 5, 2018 at 9:16 AM, Alexey Brodkin
>  wrote:
>> Hi Daniel,
>>
>> On Thu, 2018-04-05 at 08:18 +0200, Daniel Vetter wrote:
>>> On Wed, Apr 4, 2018 at 10:06 PM, Alexey Brodkin
>>>  wrote:
 Hello,

 We're trying to use DisplayLink USB2-to-HDMI adapter to render 
 GPU-accelerated graphics.
 Hardware setup is as simple as a devboard + DisplayLink adapter.
 Devboards we use for this experiment are:
  * Wandboard Quad (based on IMX6 SoC with Vivante GPU) or
  * HSDK (based on Synopsys ARC HS38 SoC with Vivante GPU as well)

 I'm sure any other board with DRM supported GPU will work, those we just 
 used
 as the very recent Linux kernels could be easily run on them both.

 Basically the problem is UDL needs to be explicitly notified about new data
 to be rendered on the screen compared to typical bit-streamers that 
 infinitely
 scan a dedicated buffer in memory.

 In case of UDL there're just 2 ways for this notification:
  1) DRM_IOCTL_MODE_PAGE_FLIP that calls drm_crtc_funcs->page_flip()
  2) DRM_IOCTL_MODE_DIRTYFB that calls drm_framebuffer_funcs->dirty()

 But neither of IOCTLs happen when we run Xserver with xf86-video-armada 
 driver
 (see 
 https://urldefense.proofpoint.com/v2/url?u=http-3A__git.arm.linux.org.uk_cgit_xf86-2Dvideo-2Darmada.git_log_-3Fh-3Dunstable-2Ddevel=DwIBaQ;
 c=DPL6_X_6JkXFx7AXWqB0tg=lqdeeSSEes0GFDDl656eViXO7breS55ytWkhpk5R81I=oEAlP64L9vkuUs_k3kGwwwlN1WJbDMJbCo0uDhwKwwk=3ZHj-
 6JXZBLSTWg_4KMnL0VNi7z8c0RxHzj2U5ywVIw=).

 Is it something missing in Xserver or in UDL driver?
>>> Use the -modesetting driverr for UDL, that one works correctly.
>> If you're talking about "modesetting" driver of Xserver [1] then indeed
>> picture is displayed on the screen. But there I guess won't be any 3D 
>> acceleration.
>>
>> At least that's what was suggested to me earlier here [2] by Lucas:
>> >8---
>> For 3D acceleration to work under X you need the etnaviv specific DDX
>> driver, which can be found here:
>>
>> https://urldefense.proofpoint.com/v2/url?u=http-3A__git.arm.linux.org.uk_cgit_xf86-2Dvideo-2Darmada.git_log_-3Fh-3Dunstable-2Ddevel=DwIGaQ=DPL6_X_6JkXFx7AXWqB0tg=yaVFU4TjGY0gVF8El1uKcisy6TPsyCl9uN7Wsis-qhY=NxAlhKaLZI6JlMs1pUBPHr79zFQ8ytECx0wtkVRrkeQ=9XSI0qYPrADUy1eUuKDexVOT98l9APph-ArYowGWwow=
> You definitely want to use -modesetting for UDL. And I thought with
> glamour and the corresponding mesa work you should also get
> accelaration. Insisting that you must use a driver-specific ddx is
> broken, the world doesn't work like that anymore.

I think what Alexey wants to do is not supported by -modesetting
driver. He wants to offload rendering to a Vivante GPU and then
display the result in *another* output ... For this I think full
PRIME support is needed, right? I see -modesetting has
drmPrimeFDToHandle but no drmPrimeHandleToFD support. In other
words -modesetting can not export buffers to another -modesetting
driver, it can only import them (?)

Thanks and Best Regards,
Jose Miguel Abreu

>
> Lucas, can you pls clarify? Also, why does -armada bind against all
> kms drivers, that's probaly too much.
> -Daniel
>
>> >8---
>>
>> [1] 
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__cgit.freedesktop.org_xorg_xserver_tree_hw_xfree86_drivers_modesetting=DwIGaQ=DPL6_X_6JkXFx7AXWqB0tg=yaVFU4TjGY0gVF8El1uKcisy6TPsyCl9uN7Wsis-qhY=NxAlhKaLZI6JlMs1pUBPHr79zFQ8ytECx0wtkVRrkeQ=yvnVItPaOgvVT8aJFwTO5XXLCCmlSiD89JwhcGeo7MI=
>> [2] 
>> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.infradead.org_pipermail_linux-2Dsnps-2Darc_2017-2DNovember_003031.html=DwIGaQ=DPL6_X_6JkXFx7AXWqB0tg=yaVFU4TjGY0gVF8El1uKcisy6TPsyCl9uN7Wsis-qhY=NxAlhKaLZI6JlMs1pUBPHr79zFQ8ytECx0wtkVRrkeQ=8gdiQaxAN7AT_2vwaIpXpXfVPSPKPM275rlmcQZKu28=
>>
>> -Alexey
>
>

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


Re: [PATCHv2] drm/sun4i: validate modes for HDMI

2017-12-13 Thread Jose Abreu
Hi,

On 13-12-2017 11:05, Hans Verkuil wrote:
> On 13/12/17 11:30, Maxime Ripard wrote:
>> Hi Hans,
>>
>> On Fri, Dec 08, 2017 at 04:48:47PM +0100, Hans Verkuil wrote:
>>> When I connected my cubieboard running 4.15-rc1 to my 4k display I got no 
>>> picture. Some
>>> digging found that there is no check against the upper pixelclock limit of 
>>> the HDMI
>>> output, so X selects a 4kp60 format at 594 MHz, which obviously won't work.
>>>
>>> The patch below adds a check for the upper bound of what this hardware can 
>>> do, and
>>> it checks if the requested tmds clock can be obtained.
>>>
>>> Signed-off-by: Hans Verkuil 
>>> ---
>>>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 19 +++
>>>  1 file changed, 19 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
>>> b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>>> index dda904ec0534..c10400a19b33 100644
>>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>>> @@ -208,8 +208,27 @@ static int sun4i_hdmi_get_modes(struct drm_connector 
>>> *connector)
>>> return ret;
>>>  }
>>>
>>> +static int sun4i_hdmi_mode_valid(struct drm_connector *connector,
>>> +struct drm_display_mode *mode)
>>> +{
>>> +   struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
>>> +   unsigned long rate = mode->clock * 1000;
>>> +   long rounded_rate;
>>> +
>>> +   /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
>>> +   if (rate > 16500)
>>> +   return MODE_CLOCK_HIGH;
>>> +   rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
>>> +   if (rounded_rate < rate)
>>> +   return MODE_CLOCK_LOW;
>>> +   if (rounded_rate > rate)
>>> +   return MODE_CLOCK_HIGH;
>>> +   return MODE_OK;
>>> +}
>> This looks much better, thanks!
>>
>> One thing that I was mentionning in my other mail is that our rate
>> rounding might not provide the exact TMDS clock rate advertised by the
>> EDID, while staying in the tolerancy.
>>
>> We've raised this issue before, without coming to a conclusion. Would
>> you happen to know what that tolerancy would be on an HDMI link?
> I can't actually find anything about that in the HDMI spec. However, the VESA 
> DMT
> spec specifies a tolerance of +/- 0.5% for the pixelclock.
>
> The HDMI 2.1 spec also suggests that this is the tolerance (caveat: I have 
> not had
> the time to study this in detail, but it does mention it when describing the 
> new
> variable refresh rate feature).
>
> That said, the problem with a 0.5% tolerance is that the slight slowdown for 
> 59.94
> vs 60 Hz framerate falls within that tolerance (it's a 0.1% slowdown).
>
> Generally clocks will be able to hit the standard frequencies (74.25, 148.5, 
> etc)
> exactly, but if you want to slow down for 59.94 framerate they tend to be off 
> by
> a bit.
>
> In the end I think keeping a margin of 0.4 or 0.5% is the best approach.

We had the same problem in arcpgu, please check if commit [1] can
be used by you.

Best Regards,
Jose Miguel Abreu

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=22d0be2a557e53a22feb484e8fce255fe09e6ad5

>
> Regards,
>
>   Hans
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.freedesktop.org_mailman_listinfo_dri-2Ddevel=DwIGaQ=DPL6_X_6JkXFx7AXWqB0tg=yaVFU4TjGY0gVF8El1uKcisy6TPsyCl9uN7Wsis-qhY=HwJwBnLWatgtXZ6tmlyN-ibL-Cj4hheMGPCEW6rh7sY=0f011r4qaTVGDQc5-niD-Faj5yc2kl6jq2KtxKdU20o=

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


Re: [PATCH v4 0/9] drm/i915: Implement HDCP

2017-12-07 Thread Jose Abreu
Hi Sean,

On 07-12-2017 00:00, Sean Paul wrote:
> Welcome to version 4 of the patchset. I think we're nearing the finish line
> (hopefully) now. This set addresses the review feedback from v3. I applied 
> some
> R-b's from v3 review, and converted others to Cc since other changes were made
> to the patch, and I didn't want to speak for reviewers.
>
> Thanks for all the review feedback!

Thanks for your patches, nice to see HDCP patches making it into DRM!

I'm not familiar with i915 driver/hw but I do am familiar with
HDCP for HDMI. Here goes a few notes:
- You should make sure that you are streaming valid TMDS data
after reading the BKSV. I think by spec you can read BKSV at any
point but the remaining operations need to be done *after* you
start sending video, otherwise you can end up with wrong Ri's
because Ri rotation is done using TMDS clock...
- Also according to spec you should make sure BSTATUS reports DVI
state in first read (i.e. before start sending video) and that
HDMI_RESERVED field is tied to one.
- I think you should clearly indicate that this is for HDCP 1.4
because HDCP 2.2 is a lot different.

Also, is there any possibility to port any of these functions for
main DRM core? I mean, not the shim ops which seem very specific
for your HW, but at least a .enable, .disable, .link_check
callbacks would be useful to help others to also implement HDCP ...

Best Regards,
Jose Miguel Abreu

>
> Sean
>
> Sean Paul (9):
>   drm: Fix link-status kerneldoc line lengths
>   drm/i915: Add more control to wait_for routines
>   drm: Add Content Protection property
>   drm: Add some HDCP related #defines
>   drm/i915: Add HDCP framework + base implementation
>   drm/i915: Make use of indexed write GMBUS feature
>   drm/i915: Add function to output Aksv over GMBUS
>   drm/i915: Implement HDCP for HDMI
>   drm/i915: Implement HDCP for DisplayPort
>
>  drivers/gpu/drm/drm_atomic.c |   8 +
>  drivers/gpu/drm/drm_connector.c  |  87 -
>  drivers/gpu/drm/drm_sysfs.c  |   1 +
>  drivers/gpu/drm/i915/Makefile|   1 +
>  drivers/gpu/drm/i915/i915_drv.h  |   1 +
>  drivers/gpu/drm/i915/i915_reg.h  |  85 
>  drivers/gpu/drm/i915/intel_atomic.c  |   2 +
>  drivers/gpu/drm/i915/intel_ddi.c |  36 ++
>  drivers/gpu/drm/i915/intel_display.c |   4 +
>  drivers/gpu/drm/i915/intel_dp.c  | 244 +++-
>  drivers/gpu/drm/i915/intel_drv.h | 106 -
>  drivers/gpu/drm/i915/intel_hdcp.c| 735 
> +++
>  drivers/gpu/drm/i915/intel_hdmi.c| 250 
>  drivers/gpu/drm/i915/intel_i2c.c |  81 +++-
>  drivers/gpu/drm/i915/intel_uncore.c  |  23 +-
>  drivers/gpu/drm/i915/intel_uncore.h  |  14 +-
>  include/drm/drm_connector.h  |  16 +
>  include/drm/drm_dp_helper.h  |  17 +
>  include/drm/drm_hdcp.h   |  56 +++
>  include/uapi/drm/drm_mode.h  |   4 +
>  20 files changed, 1728 insertions(+), 43 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/intel_hdcp.c
>  create mode 100644 include/drm/drm_hdcp.h
>

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


Re: xf86-video-armada via UDL [was: Re: UDL's fbdev doesn't work for user-space apps]

2017-12-05 Thread Jose Abreu
On 05-12-2017 11:53, Alexey Brodkin wrote:
>
> From my note above about udl_drm_gem_mmap() being only used in case of Xserver
> I barely may conclude anything. Given my lack of knowledge of DRM guts
> especially
> when it comes to complicated cases with DMA buffer exports/imports I cannot 
> say
> immediately if that's just improper implementation of
> udl_drm_gem_mmap() or not.
> Even though I do see some differences between implementation of 
> file_operations->mmap()
> callback in UDL and
> say exynos_drm_gem_mmap() or qxl_mmap() it's not clear
> why this and that implementation was done.

Oh, I've seen this before. This is the same thing that arcpgu
used to do in the mmap callback! Please comment out the call to
update_vm_cache_attr() in the mmap callback and check if it works.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: xf86-video-armada via UDL [was: Re: UDL's fbdev doesn't work for user-space apps]

2017-12-05 Thread Jose Abreu
Hi Alexey,

On 04-12-2017 17:29, Alexey Brodkin wrote:
>
> Indeed, in case of kmscube etnaviv is a renderer while UDL
> outputs the picture on the screen.

Thats nice :)

Ok, from your logs I was not able to see anything wrong. X server
does not error exit and Prime seems to be working in DRM ...

Lets try one more thing: Enable all debug in DRM (drm.debug=0x3f)
and try to correlate the log with the actions. i.e.

[boot]
[log]
[x start]
[log]
[xclock start]
[log]
[glmark2-es2 start]
[log]

If that does not give any more info then maybe someone with
better understanding of etnaviv, UDL and X can help (maybe cc X
devel list also ...)

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: xf86-video-armada via UDL [was: Re: UDL's fbdev doesn't work for user-space apps]

2017-12-04 Thread Jose Abreu
On 04-12-2017 16:00, Alexey Brodkin wrote:
> [30.763] (II) armada(0): etnaviv: Xv: using YUY2 format intermediate YUV 
> target
>

I'm wondering if this means that target format for UDL is YUV ...

But anyway, I revisited your first email and noticed that you
said kmscube runs fine. Is this using etnaviv as renderer? And
you also said X is claiming the screen but nothing appears ...
which X client are you using to test this?
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: xf86-video-armada via UDL [was: Re: UDL's fbdev doesn't work for user-space apps]

2017-12-04 Thread Jose Abreu
On 04-12-2017 14:53, Alexey Brodkin wrote:
> Full log you may find below.

Sorry but I meant /var/log/Xorg.0.log file.

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


Re: xf86-video-armada via UDL [was: Re: UDL's fbdev doesn't work for user-space apps]

2017-12-04 Thread Jose Abreu
On 04-12-2017 13:16, Alexey Brodkin wrote:
> Option  "kmsdev" "/dev/dri/card1"

Which drm driver uses /dev/dri/card0? I'm seing drmOpen code and
if you don't specify the busID it will fallback for the first
card that matches "armada-drm" or "imx-drm" or "udl".

> But if I swap "imx-drm" to "udl" I don't see anything on my screen
> (connected via UDL) even though Xserver seems to really start claiming the 
> screen
> (so I see it becomes black, effectively overriding whatever was there before) 
> and
> glmark benchmark prints results.
>
>

Xorg.log can help confirm if everything is ok.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: UDL's fbdev doesn't work for user-space apps

2017-12-04 Thread Jose Abreu
Hi Alexey,

On 04-12-2017 11:32, Alexey Brodkin wrote:
> My first [probably incorrect] assumption is Xserver requires fbdev (/dev/fbX)
> and it cannot use DRI video card natively. Is that correct?
>
>

Xserver can use DRI directly, you need to enable modesetting
driver in Xorg config or use the designated driver for your card
(if there is any).

e.g.:

Section "Device"
Identifier "Card0"
Driver "modesetting"
Option "kmsdev" "/dev/dri/card0"
Option "SWcursor" "true"
BusID "PCI:X:X:X"
EndSection

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: PROBLEM: Asus C201 video mode problems on HDMI hotplug (regression)

2017-12-04 Thread Jose Abreu
On 03-12-2017 05:20, Nick Bowler wrote:
>
> Your patch changes things.  With this applied on top of 4.15-rc1
> it is failing 100% of the time instead of only half of the time.

Ok, it was a long shot anyway.

>
> I brought the original test equipment back to the setup so I can
> see the video and pink bar again.  The symptoms remain the same
> (unexpected size, pink bar, and no audio).
>

Can you tell me which test equipment are you using?

> It is very consistent: pink bar <=> no audio.
>
> My suspicion is that the audio problem is just the wrong video mode
> on the sink side messing things up, but I have no way of confirming
> that (that I know of).

Hmmm, my first thought was that audio is being configured first
because of the phy lock wait time, I've seen this happening before.

Lets try this:
- Disable all alsa clients (e.g. pulseaudio, ...) so that no one
tries to configure audio.
- Plug out/in the cable until the issue appears
- When the issue appears use aplay to play audio through the HDMI
output
- Repeat several times with different audio rates and with no
resample (you can use the plughw interface in aplay).

>
> Thanks,
>   Nick

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


Re: PROBLEM: Asus C201 video mode problems on HDMI hotplug (regression)

2017-12-02 Thread Jose Abreu
Hi Nick,

On 01-12-2017 00:11, Nick Bowler wrote:
> Hi,
>
> On 2017-11-27 22:30 -0500, Nick Bowler wrote:
>> A note about the test setup: I had to remove the test equipment so I
>> no longer have any information about the video mode from the sink side
>> (like in the photos).  Thus, with the current setup, I am using the
>> presense or absense of audio to determine whether the issue is present
>> or not.
>>
>> The test procedure is: boot up, start music, then hotplug the hdmi four
>> times.  If sound is heard after all four connections, PASS; otherwise FAIL.
>>
>>  - I retested on 4.15-rc1 to confirm that the issue is still present (it is).
>>
>>  - I applied the functional revert from earlier on top of 4.15-rc1 and the
>>problem is fixed.
>>
>>  - Returning to 4.15-rc1 and applying [Laurent Pinchart's] patch --
>>the issue is present again (no change in behaviour compared to
>>4.15-rc1).
> Another data point... the following patch appears sufficient to restore
> working behaviour.
>
> Cheers,
>   Nick
>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 -
>  1 file changed, 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index bf14214fa464..3118fbd8433d 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1101,8 +1101,6 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>  static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
>  {
>   const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> - unsigned int i;
> - u8 val;
>  
>   if (phy->gen == 1) {
>   dw_hdmi_phy_enable_powerdown(hdmi, false);
> @@ -1116,21 +1114,6 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
>   dw_hdmi_phy_gen2_txpwron(hdmi, 1);
>   dw_hdmi_phy_gen2_pddq(hdmi, 0);
>  
> - /* Wait for PHY PLL lock */
> - for (i = 0; i < 5; ++i) {
> - val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
> - if (val)
> - break;
> -
> - usleep_range(1000, 2000);
> - }
> -
> - if (!val) {
> - dev_err(hdmi->dev, "PHY PLL failed to lock\n");
> - return -ETIMEDOUT;
> - }
> -
> - dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i);
>   return 0;
>  }
>  

I don't think you can do this. The phy pll lock check is
recommended and can indicate hw failure. Can you please check if
this untested, uncompiled patch makes it work correctly ?

-->8---
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index bf14214..456fc54 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1669,7 +1669,7 @@ static void
hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 
 static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct
drm_display_mode *mode)
 {
-   int ret;
+   int ret, vsync_len = mode->vsync_end - mode->vsync_start;
 
hdmi_disable_overflow_interrupts(hdmi);
 
@@ -1722,6 +1722,14 @@ static int dw_hdmi_setup(struct dw_hdmi
*hdmi, struct drm_display_mode *mode)
return ret;
hdmi->phy.enabled = true;
 
+   /* Reset all clock domains */
+   hdmi_writeb(hdmi, 0x00, HDMI_MC_SWRSTZ);
+
+   /* Rewrite vsync register to latch previous written values */
+   if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+   vsync_len /= 2;
+   hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
+
/* HDMI Initialization Step B.3 */
dw_hdmi_enable_video_path(hdmi);
 
-->8---

I would expect this patch to end your wrong image issue but the
audio part may be a different problem.

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 04/10] drm/uapi: Deprecate DRM_MODE_FLAG_BCAST

2017-11-15 Thread Jose Abreu


On 14-11-2017 18:32, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrj...@linux.intel.com>
>
> Reject any mode with DRM_MODE_FLAG_BCAST. We have no code that even
> checks for this flag hence it can't possibly do any good.
>
> I think this maybe originated from fbdev where it was supposed to
> indicate PAL/NTSC broadcast timings. I have no idea why those would
> have to be identified by a flag rather than by just the timings
> themselves. And then I assume it got copied into xfree86 for
> fbdevhw, and later on it leaked into the randr protocol and kms uapi.
>
> Since kms fbdev emulation never uses the corresponding fbdev flag
> there should be no sane way for this to come back into kms via
> userspace either.
>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Cc: Adam Jackson <a...@redhat.com>
> Cc: Keith Packard <kei...@keithp.com>
> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
>

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 03/10] drm/uapi: Deprecate DRM_MODE_FLAG_PIXMUX

2017-11-15 Thread Jose Abreu


On 14-11-2017 18:32, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrj...@linux.intel.com>
>
> Reject any mode with DRM_MODE_FLAG_PIXMUX. We have no code that even
> checks for this flag hence it can't possibly do any good.
>
> Looks like this flag had something to do the the controller<->ramdac
> interface with some ancient S3 graphics adapters. Why someone though
> it would be a good idea to expose it directly to users I don't know.
> And later on it got copied into the randr protocol and kms uapi.
>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Cc: Adam Jackson <a...@redhat.com>
> Cc: Keith Packard <kei...@keithp.com>
> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
>

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 08/10] drm/uapi: Deprecate nonsense kms mode types

2017-11-15 Thread Jose Abreu


On 15-11-2017 15:45, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrj...@linux.intel.com>
>
> BUILTIN, CRTC_C, CLOCK_C, and DEFULT mode types are unused. Let's
> refuse to generate them or accept them from userspace either. A
> cursory check didn't reveal any userspace code that would depend
> on these.
>
> v2: Recommend DRIVER instead of BUILTIN (ajax)
>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Cc: Adam Jackson <a...@redhat.com>
> Cc: Keith Packard <kei...@keithp.com>
> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
> Reviewed-by: Adam Jackson <a...@redhat.com>
> Reviewed-by: Alex Deucher <alexander.deuc...@amd.com>
>

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 02/10] drm/uapi: Validate the mode flags/type

2017-11-15 Thread Jose Abreu
Hi Ville,

On 15-11-2017 15:49, Ville Syrjala wrote:
>  
> +#define  DRM_MODE_FLAG_ALL   (DRM_MODE_FLAG_PHSYNC | \
> +  DRM_MODE_FLAG_NHSYNC | \
> +  DRM_MODE_FLAG_PVSYNC | \
> +  DRM_MODE_FLAG_NVSYNC | \
> +  DRM_MODE_FLAG_INTERLACE |  \
> +  DRM_MODE_FLAG_DBLSCAN |\
> +  DRM_MODE_FLAG_CSYNC |  \
> +  DRM_MODE_FLAG_PCSYNC | \
> +  DRM_MODE_FLAG_NCSYNC | \
> +  DRM_MODE_FLAG_HSKEW |  \
> +  DRM_MODE_FLAG_BCAST |  \
> +  DRM_MODE_FLAG_PIXMUX | \
> +  DRM_MODE_FLAG_DBLCLK | \
> +  DRM_MODE_FLAG_CLKDIV2 |\
> +  DRM_MODE_FLAG_3D_MASK)
> +
>  

I see this doesn't include the picture aspect ratio flags.
Shouldn't we add this now so that userspace can start using them?

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 08/10] video/hdmi: Reject illegal picture aspect ratios

2017-11-13 Thread Jose Abreu


On 13-11-2017 17:04, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrj...@linux.intel.com>
>
> AVI infoframe can only carry none, 4:3, or 16:9 picture aspect
> ratios. Return an error if the user asked for something different.
>
> Cc: Shashank Sharma <shashank.sha...@intel.com>
> Cc: "Lin, Jia" <lin.a@intel.com>
> Cc: Akashdeep Sharma <akashdeep.sha...@intel.com>
> Cc: Jim Bride <jim.br...@linux.intel.com>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
> Cc: Emil Velikov <emil.l.veli...@gmail.com>
> Cc: Thierry Reding <thierry.red...@gmail.com>
> Cc: Hans Verkuil <hans.verk...@cisco.com>
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best Regards,
Jose Miguel Abreu

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


Re: [PATCH 07/10] drm/edid: Don't send bogus aspect ratios in AVI infoframes

2017-11-13 Thread Jose Abreu


On 13-11-2017 17:04, Ville Syrjala wrote:
> From: Ville Syrjälä 
>
> If the user mode would specify an aspect ratio other than 4:3 or 16:9
> we now silently ignore it. Maybe a better apporoach is to return an
> error? Let's try that.
>
> Also we must be careful that we don't try to send illegal picture
> aspect in the infoframe as it's only capable of signalling none,
> 4:3, and 16:9. Currently we're sending these bogus infoframes
> whenever the cea mode specifies some other aspect ratio.
>
>

Yes, this is a bug. Following my input from the previous patch I
think you should also check for HDMI_PICTURE_ASPECT_RESERVED or
user a helper to check that. I'm also wondering if this should go
to stable since the vics with aspect ratio > 16:9 were
introduced. We are indeed corrupting the AVI infoframe.

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 06/10] drm/edid: Fix cea mode aspect ratio handling

2017-11-13 Thread Jose Abreu
Hi Ville,

On 13-11-2017 17:04, Ville Syrjala wrote:
>  
> + if (to_match->picture_aspect_ratio)
> + match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
> +
>

Maybe "if (to_match->picture_aspect_ratio !=
HDMI_PICTURE_ASPECT_NONE && to_match->picture_aspect_ratio !=
HDMI_PICTURE_ASPECT_RESERVED)"?

Or some kind of helper to validate the aspect ratio from userspace?

Best Regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RESEND RFC PATCH 0/7] sun8i H3 HDMI glue driver for DW HDMI

2017-09-21 Thread Jose Abreu
Hi Jernej,

On 20-09-2017 21:01, Jernej Skrabec wrote:
> [added media mailing list due to CEC question]
>
> This patch series adds a HDMI glue driver for Allwinner H3 SoC. For now, only
> video and CEC functionality is supported. Audio needs more tweaks.
>
> Series is based on the H3 DE2 patch series available on mailing list:
> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.infradead.org_pipermail_linux-2Darm-2Dkernel_2017-2DAugust_522697.html=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=coyfcQKSr2asrHcaCeWFmAP_9nkFkRK8s7Uw5bmVei4=JCFaMXK1MmZ3jE745_YcqZhZkaqtc6UapGfSSapcz_s=
>  
> (ignore patches marked with [NOT FOR REVIEW NOW] tag)
>
> Patch 1 adds support for polling plug detection since custom PHY used here
> doesn't support HPD interrupt.
>
> Patch 2 enables overflow workaround for v1.32a. This HDMI controller exhibits
> same issues as HDMI controller used in iMX6 SoCs.
>
> Patch 3 adds CLK_SET_RATE_PARENT to hdmi clock.
>
> Patch 4 adds dt bindings documentation.
>
> Patch 5 adds actual H3 HDMI glue driver.
>
> Patch 6 and 7 add HDMI node to DT and enable it where needed.
>
> Allwinner used DW HDMI controller in a non standard way:
> - register offsets obfuscation layer, which can fortunately be turned off
> - register read lock, which has to be disabled by magic number
> - custom PHY, which have to be initialized before DW HDMI controller
> - non standard clocks
> - no HPD interrupt
>
> Because of that, I have two questions:
> - Since HPD have to be polled, is it enough just to enable poll mode? I'm
>   mainly concerned about invalidating CEC address here.

You mean you get no interrupt when HPD status changes? Hans can
answer this better but then you will need to invalidate the cec
physical address yourself because right now its invalidated in
the dw-hdmi irq handler (see dw_hdmi_irq()).

> - PHY has to be initialized before DW HDMI controller to disable offset
>   obfuscation and read lock among other things. This means that all clocks 
> have
>   to be enabled in glue driver. This poses a problem, since when using
>   component model, dw-hdmi bridge uses drvdata for it's own private data and
>   prevents glue layer to pass a pointer to unbind function, where clocks 
> should
>   be disabled. I noticed same issue in meson DW HDMI glue driver, where clocks
>   are also not disabled when unbind callback is called. I noticed that when H3
>   SoC is shutdown, HDMI output is still enabled and lastest image is shown on
>   monitor until it is unplugged from power supply. Is there any simple 
> solution
>   to this?

I don't know if you can use an empty platform device created with
platform_device_alloc(). Perhaps it would be better fix this in
the dw-hdmi driver. I see two solutions:

- Either you return the dw-hdmi private structure in the bind
callback, store it and pass it in the unbind
- Or, you pass your own private data to the dw-hdmi bind, the
dw-hdmi stores it and you just create a public function in the
dw-hdmi driver called like dw_hdmi_get_auxdata(struct device
*dev) which returns your private data.

I think first option is nice, maybe anyone else can suggest
something better?

Best regards,
Jose Miguel Abreu

>
> Chen-Yu,
> TL Lim was unable to obtain any answer from Allwinner about HDMI clocks. I 
> think
> it is safe to assume that divider in HDMI clock doesn't have any effect.
>
> Branch based on linux-next from 1. September with integrated patches is
> available here:
> https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_jernejsk_linux-2D1_tree_h3-5Fhdmi-5Frfc=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=coyfcQKSr2asrHcaCeWFmAP_9nkFkRK8s7Uw5bmVei4=lDAnd3egsc2sxqVM-Ya_Me9ozWXKWvxxvsdV3Jn3vpA=
>  
>
> Some additonal info about H3 HDMI:
> https://urldefense.proofpoint.com/v2/url?u=https-3A__linux-2Dsunxi.org_DWC-5FHDMI-5FController=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=coyfcQKSr2asrHcaCeWFmAP_9nkFkRK8s7Uw5bmVei4=d9iEgk23RCLJL4oXJ4kkt6NyYK90_vFy0mCD3WauJDk=
>  
>
> Thanks to Jens Kuske, who figured out that it is actually DW HDMI controller
> and mapped scrambled register offsets to original ones.
>
> Icenowy Zheng (1):
>   ARM: sun8i: h3: Add DesignWare HDMI controller node
>
> Jernej Skrabec (6):
>   drm: bridge: Enable polling hpd event in dw_hdmi
>   drm: bridge: Enable workaround in dw_hdmi for v1.32a
>   clk: sunxi: Add CLK_SET_RATE_PARENT flag for H3 HDMI clock
>   dt-bindings: Document Allwinner DWC HDMI TX node
>   drm: sun4i: Add a glue for the DesignWare HDMI controller in H3
>   ARM: sun8i: h3: Enable HDMI output on H3 boards
>
>  .../bindings/display/sunxi/sun4i-drm.txt   | 158 ++-
>  arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts|  33 ++
>  arch/arm/boot/dts/sun8i-h3-beelink-x2.dts  |  33 ++
>  arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts   |  33 ++
>  arch/arm/boot/dts/sun8i-h3-orangepi-2.dts  |  33 ++
>  

Re: [RFC][PATCH v3] drm: kirin: Add mode_valid logic to avoid mode clocks we can't generate

2017-07-20 Thread Jose Abreu

On 19-07-2017 20:21, John Stultz wrote:
> On Wed, Jul 19, 2017 at 3:16 AM, Jose Abreu <jose.ab...@synopsys.com> wrote:
>> Hi John,
>>
>>
>> On 18-07-2017 18:59, John Stultz wrote:
>>> Currently the hikey dsi logic cannot generate accurate byte
>>> clocks values for all pixel clock values. Thus if a mode clock
>>> is selected that cannot match the calculated byte clock, the
>>> device will boot with a blank screen.
>>>
>>> This patch uses the new mode_valid callback (many thanks to
>>> Jose Abreu for upstreaming it!) to ensure we don't select
>>> modes we cannot generate.
>>>
>>> Also, since the ade crtc code will adjust the mode in mode_set,
>>> this patch also adds a mode_fixup callback which we use to make
>>> sure we are validating the mode clock that will eventually be
>>> used.
>>>
>>> Many thanks to Jose and Daniel for recent feedback. I think this
>>> version is looking much nicer. But I'd still welcome any feedback
>>> or suggestions!
>>>
>>> Cc: Daniel Vetter <daniel.vet...@intel.com>
>>> Cc: Jani Nikula <jani.nik...@linux.intel.com>
>>> Cc: Sean Paul <seanp...@chromium.org>
>>> Cc: David Airlie <airl...@linux.ie>
>>> Cc: Rob Clark <robdcl...@gmail.com>
>>> Cc: Xinliang Liu <xinliang@linaro.org>
>>> Cc: Xinliang Liu <z.liuxinli...@hisilicon.com>
>>> Cc: Rongrong Zou <zourongr...@gmail.com>
>>> Cc: Xinwei Kong <kong.kongxin...@hisilicon.com>
>>> Cc: Chen Feng <puck.c...@hisilicon.com>
>>> Cc: Jose Abreu <jose.ab...@synopsys.com>
>>> Cc: Archit Taneja <arch...@codeaurora.org>
>>> Cc: dri-devel@lists.freedesktop.org
>>> Signed-off-by: John Stultz <john.stu...@linaro.org>
>>> ---
>>> v2: Reworked to calculate if modeclock matches the phy's
>>> byteclock, rather then using a whitelist of known modes.
>>>
>>> v3: Reworked to check across all possible crtcs (even though for
>>> us there is only one), and use mode_fixup instead of a custom
>>> function, as suggested by Jose and Daniel.
>>> ---
>>>  drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c| 62 
>>> +
>>>  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 14 ++
>>>  2 files changed, 76 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c 
>>> b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
>>> index f77dcfa..d7b5820 100644
>>> --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
>>> +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
>>> @@ -603,6 +603,67 @@ static void dsi_encoder_enable(struct drm_encoder 
>>> *encoder)
>>>   dsi->enable = true;
>>>  }
>>>
>>> +static enum drm_mode_status dsi_encoder_phy_mode_valid(struct drm_encoder 
>>> *encoder,
>>> + const struct drm_display_mode *mode)
>>> +{
>>> + struct dw_dsi *dsi = encoder_to_dsi(encoder);
>>> + struct mipi_phy_params phy;
>>> + u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
>>> + u32 req_kHz, act_kHz, lane_byte_clk_kHz;
>>> +
>>> + /* Calculate the lane byte clk using the adjusted mode clk */
>>> + memset(, 0, sizeof(phy));
>>> + req_kHz = mode->clock * bpp / dsi->lanes;
>>> + act_kHz = dsi_calc_phy_rate(req_kHz, );
>>> + lane_byte_clk_kHz = act_kHz / 8;
>>> +
>>> + DRM_DEBUG_DRIVER("Checking mode %ix%i-%i@%i clock: %i...",
>>> + mode->hdisplay, mode->vdisplay, bpp,
>>> + drm_mode_vrefresh(mode), mode->clock);
>>> +
>>> + /*
>>> +  * Make sure the adjused mode clock and the lane byte clk
>>> +  * have a common denominator base frequency
>>> +  */
>>> + if (mode->clock/dsi->lanes == lane_byte_clk_kHz/3) {
>>> + DRM_DEBUG_DRIVER("OK!\n");
>>> + return MODE_OK;
>>> + }
>>> +
>>> + DRM_DEBUG_DRIVER("BAD!\n");
>>> + return MODE_BAD;
>>> +}
>>> +
>>> +static enum drm_mode_status dsi_encoder_mode_valid(struct drm_encoder 
>>> *encoder,
>>> + const struct drm_display_mode *mode)
>>> +
>>> +{
>>> + 

Re: [RFC][PATCH v3] drm: kirin: Add mode_valid logic to avoid mode clocks we can't generate

2017-07-19 Thread Jose Abreu
Hi John,


On 18-07-2017 18:59, John Stultz wrote:
> Currently the hikey dsi logic cannot generate accurate byte
> clocks values for all pixel clock values. Thus if a mode clock
> is selected that cannot match the calculated byte clock, the
> device will boot with a blank screen.
>
> This patch uses the new mode_valid callback (many thanks to
> Jose Abreu for upstreaming it!) to ensure we don't select
> modes we cannot generate.
>
> Also, since the ade crtc code will adjust the mode in mode_set,
> this patch also adds a mode_fixup callback which we use to make
> sure we are validating the mode clock that will eventually be
> used.
>
> Many thanks to Jose and Daniel for recent feedback. I think this
> version is looking much nicer. But I'd still welcome any feedback
> or suggestions!
>
> Cc: Daniel Vetter <daniel.vet...@intel.com>
> Cc: Jani Nikula <jani.nik...@linux.intel.com>
> Cc: Sean Paul <seanp...@chromium.org>
> Cc: David Airlie <airl...@linux.ie>
> Cc: Rob Clark <robdcl...@gmail.com>
> Cc: Xinliang Liu <xinliang@linaro.org>
> Cc: Xinliang Liu <z.liuxinli...@hisilicon.com>
> Cc: Rongrong Zou <zourongr...@gmail.com>
> Cc: Xinwei Kong <kong.kongxin...@hisilicon.com>
> Cc: Chen Feng <puck.c...@hisilicon.com>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Cc: Archit Taneja <arch...@codeaurora.org>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: John Stultz <john.stu...@linaro.org>
> ---
> v2: Reworked to calculate if modeclock matches the phy's
> byteclock, rather then using a whitelist of known modes.
>
> v3: Reworked to check across all possible crtcs (even though for
> us there is only one), and use mode_fixup instead of a custom
> function, as suggested by Jose and Daniel.
> ---
>  drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c| 62 
> +
>  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 14 ++
>  2 files changed, 76 insertions(+)
>
> diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c 
> b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
> index f77dcfa..d7b5820 100644
> --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
> +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
> @@ -603,6 +603,67 @@ static void dsi_encoder_enable(struct drm_encoder 
> *encoder)
>   dsi->enable = true;
>  }
>  
> +static enum drm_mode_status dsi_encoder_phy_mode_valid(struct drm_encoder 
> *encoder,
> + const struct drm_display_mode *mode)
> +{
> + struct dw_dsi *dsi = encoder_to_dsi(encoder);
> + struct mipi_phy_params phy;
> + u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> + u32 req_kHz, act_kHz, lane_byte_clk_kHz;
> +
> + /* Calculate the lane byte clk using the adjusted mode clk */
> + memset(, 0, sizeof(phy));
> + req_kHz = mode->clock * bpp / dsi->lanes;
> + act_kHz = dsi_calc_phy_rate(req_kHz, );
> + lane_byte_clk_kHz = act_kHz / 8;
> +
> + DRM_DEBUG_DRIVER("Checking mode %ix%i-%i@%i clock: %i...",
> + mode->hdisplay, mode->vdisplay, bpp,
> + drm_mode_vrefresh(mode), mode->clock);
> +
> + /*
> +  * Make sure the adjused mode clock and the lane byte clk
> +  * have a common denominator base frequency
> +  */
> + if (mode->clock/dsi->lanes == lane_byte_clk_kHz/3) {
> + DRM_DEBUG_DRIVER("OK!\n");
> + return MODE_OK;
> + }
> +
> + DRM_DEBUG_DRIVER("BAD!\n");
> + return MODE_BAD;
> +}
> +
> +static enum drm_mode_status dsi_encoder_mode_valid(struct drm_encoder 
> *encoder,
> + const struct drm_display_mode *mode)
> +
> +{
> + const struct drm_crtc_helper_funcs *crtc_funcs = NULL;
> + struct drm_crtc *crtc = NULL;
> + struct drm_display_mode adj_mode;
> + int ret;

This int should be an enum drm_mode_status ...

> +
> + memcpy(_mode, mode, sizeof(adj_mode));

Maybe you should move this to the loop so that you pass a "clean"
adjusted mode (i.e. adj_mode == mode) for each crtc. You could
also use drm_mode_duplicate()/drm_mode_destroy() ...

> +
> + /*
> +  * The crtc might adjust the mode, so go through the
> +  * possible crtcs (technically just one) and call
> +  * mode_fixup to figure out the adjusted mode before we
> +  * validate it.
> +  */
> + drm_for_each_crtc(crtc, encoder->dev) {
> + crtc_funcs = crtc->helper_private;
> + if (crtc_funcs && crtc_funcs->mode_fixup)
> + 

Re: [RFC][PATCH v2] drm: kirin: Add mode_valid logic to avoid mode clocks we can't generate

2017-07-19 Thread Jose Abreu

On 18-07-2017 17:56, John Stultz wrote:
> On Tue, Jul 18, 2017 at 4:10 AM, Jose Abreu <jose.ab...@synopsys.com> wrote:
>> Hi John,
>>
>>
>> On 18-07-2017 05:22, John Stultz wrote:
>>> Currently the hikey dsi logic cannot generate accurate byte
>>> clocks values for all pixel clock values. Thus if a mode clock
>>> is selected that cannot match the calculated byte clock, the
>>> device will boot with a blank screen.
>>>
>>> This patch uses the new mode_valid callback (many thanks to
>>> Jose Abreu for upstreaming it!) to ensure we don't select
>>> modes we cannot generate.
>>>
>>> NOTE: Stylistically I suspect there are better ways to do what
>>> I'm trying to do here. The encoder -> crtc bit is terrible, and
>>> getting the crtc adjusted mode from the encoder logic feels
>>> less then ideal. So feedback would be greatly appreciated!
>>>
>>> Cc: Daniel Vetter <daniel.vet...@intel.com>
>>> Cc: Jani Nikula <jani.nik...@linux.intel.com>
>>> Cc: Sean Paul <seanp...@chromium.org>
>>> Cc: David Airlie <airl...@linux.ie>
>>> Cc: Rob Clark <robdcl...@gmail.com>
>>> Cc: Xinliang Liu <xinliang@linaro.org>
>>> Cc: Xinliang Liu <z.liuxinli...@hisilicon.com>
>>> Cc: Rongrong Zou <zourongr...@gmail.com>
>>> Cc: Xinwei Kong <kong.kongxin...@hisilicon.com>
>>> Cc: Chen Feng <puck.c...@hisilicon.com>
>>> Cc: Jose Abreu <jose.ab...@synopsys.com>
>>> Cc: Archit Taneja <arch...@codeaurora.org>
>>> Cc: dri-devel@lists.freedesktop.org
>>> Signed-off-by: John Stultz <john.stu...@linaro.org>
>>> ---
>>> v2: Reworked to calculate if modeclock matches the phy's byteclock,
>>> rather then using a whitelist of known modes.
>> Something like Daniel suggested would be simpler maybe:
>>
>> encoder_mode_valid_aux()
>> {
>> ...
>> }
>>
>> dsi_encoder_mode_valid(...)
>> {
>> drm_for_each_crtc(crtc, dev) {
>> crtc->mode_fixup(crtc, mode, adjusted_mode);
>> ret = encoder_mode_valid_aux(adjusted_mode);
>> if (ret != MODE_OK)
>> return ret;
>> }
>> }
>>
>> BTW, I think at commit stage you have encoder->crtc populated,
>> not sure though. But at probbing stage it will not be bound. And
>> also if you have more than one crtc this may be wrong. (How will
>> you know which crtc will be bound to the encoder so that you can
>> get the right clock?).
>
> Thanks so much for the suggestion above and the explanation. I only
> have a rough sense of the components and not as much sense of an
> overview on how they are all initialized, so this is very helpful!
>
> And yes, my case is fairly limited since the encoder and crtc are used
> together for this driver, but I know it can be more complex with
> others, so I'll re-implement as you've suggested!
>
> One thing that does worry me with trying to validate modes without
> knowing which path is to be used, is that if there were two crtcs (and
> again, on my hardware, thankfully there isn't), and for a given mode,
> one adjusted the mode and one didn't.  So then for that given mode the
> encoder could only generate a valid mode for one of the crtcs, its not
> clear if that is MODE_OK or MODE_BAD.  We don't want to prune modes
> that could possibly work with other crtcs, but we don't want a mode
> that cannot be generated be selected either.  To me it seems we should
> have the path figured out before we go pruning modes. Obviously there
> needs to be a probe step that checks if any mode works with a given
> pipeline (so that we can validate the pipeline), but it seems like
> there should be a second step to ensure once we have a pipeline bound
> we don't try to use modes it cannot support. Am I further
> misunderstanding something here?

Well, we can't know at probbing stage the path that will be
chosen. If you check drm_mode_validate_pipeline() at
drm_probe_helper.c you will see that we start from the connector,
then check which encoders can belong to the connector and which
crtc's can belong to the encoder. So, for any possible pipeline
we validate the mode and if at least one is accepted then the
mode is probbed. I only tested this in arcpgu, which only has 1
pipeline. Maybe when there is a more complex driver using this we
can find if this is the right approach :)

Best regards,
Jose Miguel Abreu

>
> Thanks again!
> -john

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


Re: [RFC][PATCH v2] drm: kirin: Add mode_valid logic to avoid mode clocks we can't generate

2017-07-18 Thread Jose Abreu
Hi John,


On 18-07-2017 05:22, John Stultz wrote:
> Currently the hikey dsi logic cannot generate accurate byte
> clocks values for all pixel clock values. Thus if a mode clock
> is selected that cannot match the calculated byte clock, the
> device will boot with a blank screen.
>
> This patch uses the new mode_valid callback (many thanks to
> Jose Abreu for upstreaming it!) to ensure we don't select
> modes we cannot generate.
>
> NOTE: Stylistically I suspect there are better ways to do what
> I'm trying to do here. The encoder -> crtc bit is terrible, and
> getting the crtc adjusted mode from the encoder logic feels
> less then ideal. So feedback would be greatly appreciated!
>
> Cc: Daniel Vetter <daniel.vet...@intel.com>
> Cc: Jani Nikula <jani.nik...@linux.intel.com>
> Cc: Sean Paul <seanp...@chromium.org>
> Cc: David Airlie <airl...@linux.ie>
> Cc: Rob Clark <robdcl...@gmail.com>
> Cc: Xinliang Liu <xinliang@linaro.org>
> Cc: Xinliang Liu <z.liuxinli...@hisilicon.com>
> Cc: Rongrong Zou <zourongr...@gmail.com>
> Cc: Xinwei Kong <kong.kongxin...@hisilicon.com>
> Cc: Chen Feng <puck.c...@hisilicon.com>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Cc: Archit Taneja <arch...@codeaurora.org>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: John Stultz <john.stu...@linaro.org>
> ---
> v2: Reworked to calculate if modeclock matches the phy's byteclock,
> rather then using a whitelist of known modes.

Something like Daniel suggested would be simpler maybe:

encoder_mode_valid_aux()
{
...
}

dsi_encoder_mode_valid(...)
{
drm_for_each_crtc(crtc, dev) {
crtc->mode_fixup(crtc, mode, adjusted_mode);
ret = encoder_mode_valid_aux(adjusted_mode);
if (ret != MODE_OK)
return ret;
}
}

BTW, I think at commit stage you have encoder->crtc populated,
not sure though. But at probbing stage it will not be bound. And
also if you have more than one crtc this may be wrong. (How will
you know which crtc will be bound to the encoder so that you can
get the right clock?).

Best regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/3] drm: arcpgu: Fix module unload

2017-07-17 Thread Jose Abreu
At module unload we are expecting a struct drm_device but at
probing we are not setting it right. Fix this and correct the
arcpgu module unload.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Fixes: 0c4250e7b15e ("drm: Add support of ARC PGU display controller")
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@intel.com>
Cc: Dave Airlie <airl...@gmail.com>
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 20ab68f..8abc987 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -120,7 +120,7 @@ static int arcpgu_load(struct drm_device *drm)
return -ENODEV;
}
 
-   platform_set_drvdata(pdev, arcpgu);
+   platform_set_drvdata(pdev, drm);
return 0;
 }
 
-- 
1.9.1


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


[PATCH 0/3] arcpgu: Fixes and improvements

2017-07-17 Thread Jose Abreu
Hi all,

Two fixes and an improvement for arcpgu. I've sent this patches in separate
but I've now collected them all to ease the review.

Best regards,
Jose Miguel Abreu

Jose Abreu (3):
  drm: arcpgu: Fix mmap() callback
  drm: arcpgu: Fix module unload
  drm: arcpgu: Allow some clock deviation in crtc->mode_valid() callback

Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@intel.com>
Cc: Dave Airlie <airl...@gmail.com>

 drivers/gpu/drm/arc/arcpgu_crtc.c |  7 ---
 drivers/gpu/drm/arc/arcpgu_drv.c  | 26 ++
 2 files changed, 6 insertions(+), 27 deletions(-)

-- 
1.9.1


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


[PATCH 1/3] drm: arcpgu: Fix mmap() callback

2017-07-17 Thread Jose Abreu
Now that ARC properly supports DMA mmap() we can use the standard
CMA helper to map dumb buffers. This makes ARC PGU works with
standard DRM consumer applications like, for example, mpv/mplayer
via DRM. While at it, use the DEFINE_DRM_GEM_CMA_FOPS() helper.

This fixes the use of dumb buffers.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Fixes: 0c4250e7b15e ("drm: Add support of ARC PGU display controller")
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@intel.com>
Cc: Dave Airlie <airl...@gmail.com>
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 24 +---
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 3e43a5d..20ab68f 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -48,29 +48,7 @@ static void arcpgu_setup_mode_config(struct drm_device *drm)
drm->mode_config.funcs = _drm_modecfg_funcs;
 }
 
-static int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-   int ret;
-
-   ret = drm_gem_mmap(filp, vma);
-   if (ret)
-   return ret;
-
-   vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
-   return 0;
-}
-
-static const struct file_operations arcpgu_drm_ops = {
-   .owner = THIS_MODULE,
-   .open = drm_open,
-   .release = drm_release,
-   .unlocked_ioctl = drm_ioctl,
-   .compat_ioctl = drm_compat_ioctl,
-   .poll = drm_poll,
-   .read = drm_read,
-   .llseek = no_llseek,
-   .mmap = arcpgu_gem_mmap,
-};
+DEFINE_DRM_GEM_CMA_FOPS(arcpgu_drm_ops);
 
 static void arcpgu_lastclose(struct drm_device *drm)
 {
-- 
1.9.1


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


DRM module unload and empty modesetting

2017-07-17 Thread Jose Abreu
Hi Daniel, all,

So, I was playing around with arcpgu and I found a bug at module
unloading. I corrected it and tested (using a 4.12 kernel) and I
got a nice WARNING from DRM core at unloading (instead of the old
NULL pointer I got :D). I debugged it and found out that an empty
modesetting (i.e. a mode with no clock) was being set by the core
and validated with crtc->atomic_check() callback. At arcpgu we
are expecting the clock value to be valid and > 0 so we were
rejecting the empty modesetting which caused the core to not set
the final mode before unloading.

I guess then it's expectable that atomic_check()/mode_valid()
callbacks can be called with an empty mode, right? Is this
documented anywhere?

Also, do we really need to call atomic check in this case? I
mean, its an empty modesetting and the mode is not valid so it
should be rejected, no?

Also notice that this error doesn't happen with 4.13 because we
switched to crtc->mode_valid() callback which instead is only
called if a full crtc/encoder/connector pipeline is set, which in
the case of unloading is not.

Best regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 3/3] drm: arcpgu: Allow some clock deviation in crtc->mode_valid() callback

2017-07-17 Thread Jose Abreu
Currently we expect that clock driver produces the exact same value
as we are requiring. There can, and will, be some deviation
however so we need to take that into account instead of just
rejecting the mode.

According to the HDMI spec we have a max of +-0.5% for the pixel clock
frequency deviation. Lets take that into an advantage and use it to
calculate how much deviation we can support.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Acked-by: Alexey Brodkin <abrod...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@intel.com>
Cc: Dave Airlie <airl...@gmail.com>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 1859dd3..55c5d5b 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -69,12 +69,13 @@ static enum drm_mode_status arc_pgu_crtc_mode_valid(struct 
drm_crtc *crtc,
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
long rate, clk_rate = mode->clock * 1000;
+   long diff = clk_rate / 200; /* +-0.5% allowed by HDMI spec */
 
rate = clk_round_rate(arcpgu->clk, clk_rate);
-   if (rate != clk_rate)
-   return MODE_NOCLOCK;
+   if ((max(rate, clk_rate) - min(rate, clk_rate) < diff) && (rate > 0))
+   return MODE_OK;
 
-   return MODE_OK;
+   return MODE_NOCLOCK;
 }
 
 static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
-- 
1.9.1


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


[PATCH] drm: arcpgu: Fix mmap() callback

2017-07-15 Thread Jose Abreu
Now that ARC properly supports DMA mmapping we can use the
standard CMA helper to map dumb buffers. This makes ARC PGU
works with standard DRM consumer applications like, for
example, mpv via DRM.

This fixes the use of dumb buffers.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Fixes: 0c4250e7b15e ("drm: Add support of ARC PGU display controller")
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 14 +-
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 1926b20..890bc87 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -48,18 +48,6 @@ static void arcpgu_setup_mode_config(struct drm_device *drm)
drm->mode_config.funcs = _drm_modecfg_funcs;
 }
 
-static int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-   int ret;
-
-   ret = drm_gem_mmap(filp, vma);
-   if (ret)
-   return ret;
-
-   vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
-   return 0;
-}
-
 static const struct file_operations arcpgu_drm_ops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -69,7 +57,7 @@ static int arcpgu_gem_mmap(struct file *filp, struct 
vm_area_struct *vma)
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,
-   .mmap = arcpgu_gem_mmap,
+   .mmap = drm_gem_cma_mmap,
 };
 
 static void arcpgu_lastclose(struct drm_device *drm)
-- 
1.9.1


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


Re: [PATCH v2] drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY

2017-07-07 Thread Jose Abreu
Hi Archit,


On 23-06-2017 10:36, Jose Abreu wrote:
> Currently HDMI 2.0 PHYs do not have a default configuration function.
>
> As *some* of the HDMI 2.0 PHYs have the same register layout as the 3D
> PHYs we can provide the same default configuration function for both
> and still let user overwrite this with custom configuration function
> if needed.
>
> If, for some reason, the PHY is custom or has a register different
> register layout then custom configuration function *must* be provided
> in order for the system to work correctly. As we prefer the pdata
> provided configuration function over the internal one this change
> will not make any impact in custom platforms.
>
> This patch is based on today's drm-misc-next branch.
>
> Signed-off-by: Jose Abreu <joab...@synopsys.com>
> Tested-by: Mark Yao <mark@rock-chips.com>

This is needed for RK3399 support. Can you please apply it?

Best regards,
Jose Miguel Abreu

> Cc: Kieran Bingham <kieran.bingham+rene...@ideasonboard.com>
> Cc: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> Cc: Archit Taneja <arch...@codeaurora.org>
> Cc: Andrzej Hajda <a.ha...@samsung.com>
> Cc: Mark Yao <mark@rock-chips.com>
> Cc: Carlos Palminha <palmi...@synopsys.com>
> Cc: Heiko Stübner <he...@sntech.de>
>
> Changes in v2:
>   - Rebased and refrased commit message
> ---
>
> Hi All,
>
> There as been a little confusion about dw-hdmi phys so I will expand a little 
> bit
> here so that I can base my decision about this patch and why does it only 
> works
> in some platforms.
>
> First, if you read dw-hdmi.c code, you will see that there is an 
> identification
> register for the phy type being used. Unfortunatelly, this only states the 
> phy type
> and not the phy version.
>
> Second, we have many HDMI 2.0 phys (so, same phy type: 0xf3) but, as you may 
> have guessed,
> HW team decided to change regbank between some versions.
>
> Third and last, each phy in a SoC has unique characteristics, so each phy 
> (event if
> they are the same version) will have different PLL configuration parameters.
>
> Given all this I managed to conclude that Mark's phy is still an HDMI 2.0 phy 
> but with
> the same register layout as previous 3D PHY's. I found at least 2 phys with 
> the same
> register layout and only 1 phy which has a different layout, so I think 
> majority wins
> here and we should let the default configuration function for HDMI 2.0 phys 
> be the same
> one as the 3D.
>
> Short story: There is no way to correctly identify, at runtime, the phy 
> version being
> used by the controller so we can't provide a default configuration function. 
> We can,
> however assume that most of the HDMI 2.0 phys will have the 3D layout BUT 
> each developer
> must confirm that the layout in its SoC is the expected one and if not, 
> provide a custom
> configuration function.
>
> Best regards,
> Jose Miguel Abreu
>
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index ead1124..10c8d8c 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2170,6 +2170,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>   .name = "DWC HDMI 2.0 TX PHY",
>   .gen = 2,
>   .has_svsret = true,
> + .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
>   }, {
>   .type = DW_HDMI_PHY_VENDOR_PHY,
>   .name = "Vendor PHY",

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


Re: [PATCH] drm/bridge: dw_hdmi: add cec notifier support

2017-07-06 Thread Jose Abreu
Hi Neil,


On 06-07-2017 11:33, Neil Armstrong wrote:
> From: Russell King 
>
> Add CEC notifier support to the HDMI bridge driver, so that the CEC
> part of the IP can receive its physical address.
>
> Tested-by: Neil Armstrong 
> Acked-by: Neil Armstrong 
> Acked-by: Hans Verkuil 
> Signed-off-by: Russell King 
> Signed-off-by: Neil Armstrong 
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++
>  1 file changed, 18 insertions(+)
>
> Hi Archit, Hans,
>
> This is repost of Russell's patch from his dw-hdmi CEC patchset.
>
> Since his CEC implementation will be integrated in the bridge driver,
> this notifier patch won't be re-posted.
>
> But the Amlogic Platform needs a notifier since it uses a standalone CEC
> controller.
>
> Thanks,
> Neil
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index ead1124..9c03846 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -33,6 +33,8 @@
>  #include 
>  #include 
>  
> +#include 

Don't you also have to "select CEC_NOTIFIER" in Kconfig? Or is it
not needed anymore with the recent Kconfig changes of CEC?

Best regards,
Jose Miguel Abreu

> +
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
>  
> @@ -175,6 +177,8 @@ struct dw_hdmi {
>   struct regmap *regm;
>   void (*enable_audio)(struct dw_hdmi *hdmi);
>   void (*disable_audio)(struct dw_hdmi *hdmi);
> +
> + struct cec_notifier *cec_notifier;
>  };
>  
>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
> @@ -1896,6 +1900,7 @@ static int dw_hdmi_connector_get_modes(struct 
> drm_connector *connector)
>   hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>   hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>   drm_mode_connector_update_edid_property(connector, edid);
> + cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>   ret = drm_add_edid_modes(connector, edid);
>   /* Store the ELD */
>   drm_edid_to_eld(connector, edid);
> @@ -2077,6 +2082,10 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, 
> bool hpd, bool rx_sense)
>   dw_hdmi_update_phy_mask(hdmi);
>   }
>   mutex_unlock(>mutex);
> +
> + if (!rx_sense && !hpd)
> + cec_notifier_set_phys_addr(hdmi->cec_notifier,
> +CEC_PHYS_ADDR_INVALID);
>  }
>  
>  void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense)
> @@ -2376,6 +2385,12 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>   if (ret)
>   goto err_iahb;
>  
> + hdmi->cec_notifier = cec_notifier_get(dev);
> + if (!hdmi->cec_notifier) {
> + ret = -ENOMEM;
> + goto err_iahb;
> + }
> +
>   /*
>* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>* N and cts values before enabling phy
> @@ -2452,6 +2467,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>   hdmi->ddc = NULL;
>   }
>  
> + if (hdmi->cec_notifier)
> + cec_notifier_put(hdmi->cec_notifier);
> +
>   clk_disable_unprepare(hdmi->iahb_clk);
>  err_isfr:
>   clk_disable_unprepare(hdmi->isfr_clk);

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


[PATCH] drm: arcpgu: Allow some clock deviation in crtc->mode_valid() callback

2017-06-28 Thread Jose Abreu
Currently we expect that clock driver produces the exact same value
as we are requiring. There can, and will, be some deviation however
so we need to take into account that instead of rejecting the mode.

According to HDMI spec we have a max of +-0.5% for the pixel clock
frequency variation. Lets take that into an advantage and use it
to calculate how much deviation we can support.

This patch was based on today's drm-misc-next.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 611af74..20528ba 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -69,12 +69,13 @@ static enum drm_mode_status arc_pgu_crtc_mode_valid(struct 
drm_crtc *crtc,
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
long rate, clk_rate = mode->clock * 1000;
+   long diff = clk_rate / 200; /* +-0.5% allowed by HDMI spec*/
 
rate = clk_round_rate(arcpgu->clk, clk_rate);
-   if (rate != clk_rate)
-   return MODE_NOCLOCK;
+   if ((max(rate, clk_rate) - min(rate, clk_rate)) < diff)
+   return MODE_OK;
 
-   return MODE_OK;
+   return MODE_NOCLOCK;
 }
 
 static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
-- 
1.9.1


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


[PATCH v2] drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY

2017-06-25 Thread Jose Abreu
Currently HDMI 2.0 PHYs do not have a default configuration function.

As *some* of the HDMI 2.0 PHYs have the same register layout as the 3D
PHYs we can provide the same default configuration function for both
and still let user overwrite this with custom configuration function
if needed.

If, for some reason, the PHY is custom or has a register different
register layout then custom configuration function *must* be provided
in order for the system to work correctly. As we prefer the pdata
provided configuration function over the internal one this change
will not make any impact in custom platforms.

This patch is based on today's drm-misc-next branch.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Tested-by: Mark Yao <mark@rock-chips.com>
Cc: Kieran Bingham <kieran.bingham+rene...@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Mark Yao <mark@rock-chips.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Heiko Stübner <he...@sntech.de>

Changes in v2:
- Rebased and refrased commit message
---

Hi All,

There as been a little confusion about dw-hdmi phys so I will expand a little 
bit
here so that I can base my decision about this patch and why does it only works
in some platforms.

First, if you read dw-hdmi.c code, you will see that there is an identification
register for the phy type being used. Unfortunatelly, this only states the phy 
type
and not the phy version.

Second, we have many HDMI 2.0 phys (so, same phy type: 0xf3) but, as you may 
have guessed,
HW team decided to change regbank between some versions.

Third and last, each phy in a SoC has unique characteristics, so each phy 
(event if
they are the same version) will have different PLL configuration parameters.

Given all this I managed to conclude that Mark's phy is still an HDMI 2.0 phy 
but with
the same register layout as previous 3D PHY's. I found at least 2 phys with the 
same
register layout and only 1 phy which has a different layout, so I think 
majority wins
here and we should let the default configuration function for HDMI 2.0 phys be 
the same
one as the 3D.

Short story: There is no way to correctly identify, at runtime, the phy version 
being
used by the controller so we can't provide a default configuration function. We 
can,
however assume that most of the HDMI 2.0 phys will have the 3D layout BUT each 
developer
must confirm that the layout in its SoC is the expected one and if not, provide 
a custom
configuration function.

Best regards,
Jose Miguel Abreu

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ead1124..10c8d8c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2170,6 +2170,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
.name = "DWC HDMI 2.0 TX PHY",
.gen = 2,
.has_svsret = true,
+   .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
}, {
.type = DW_HDMI_PHY_VENDOR_PHY,
.name = "Vendor PHY",
-- 
1.9.1


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


Re: [PATCH v5 05/10] drm: arcpgu: Use crtc->mode_valid() callback

2017-06-21 Thread Jose Abreu
Hi Daniel, Alexey,


On 25-05-2017 15:19, Jose Abreu wrote:
> Now that we have a callback to check if crtc supports a given mode
> we can use it in arcpgu so that we restrict the number of probbed
> modes to the ones we can actually display.
>
> This is specially useful because arcpgu crtc is responsible to set
> a clock value in the commit() stage but unfortunatelly this clock
> does not support all the needed ranges.
>
> Also, remove the atomic_check() callback as mode_valid() callback
> will be called before.
>
> Signed-off-by: Jose Abreu <joab...@synopsys.com>
> Reviewed-by: Alexey Brodkin <abrod...@synopsys.com>

@Daniel: I know that arcpgu is not under drm-misc but could you
apply this into drm-misc-next? Alexey (the arcpgu maintainer)
already gave the reviewed-by and this is also "Reviewed-by: Neil
Armstrong <narmstr...@baylibre.com>". It was also tested-by: me.

@Alexey: Is this ok for you?

I need this because I have a pending patch for accepting clock
variations instead of always failing when clk_round_rate() does
not return the expected rate.

Best regards,
Jose Miguel Abreu

> Cc: Carlos Palminha <palmi...@synopsys.com>
> Cc: Alexey Brodkin <abrod...@synopsys.com>
> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
> Cc: Dave Airlie <airl...@linux.ie>
> Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
>
> Changes v4->v5:
>   - Change commit message to "arcpgu" (Alexey)
> Changes v3->v4:
>   - Do not use aux function (Laurent)
>
> ---
>  drivers/gpu/drm/arc/arcpgu_crtc.c | 29 ++---
>  1 file changed, 14 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
> b/drivers/gpu/drm/arc/arcpgu_crtc.c
> index ad9a959..99fbdae 100644
> --- a/drivers/gpu/drm/arc/arcpgu_crtc.c
> +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
> @@ -64,6 +64,19 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>   .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
>  };
>  
> +enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
> +  const struct drm_display_mode 
> *mode)
> +{
> + struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
> + long rate, clk_rate = mode->clock * 1000;
> +
> + rate = clk_round_rate(arcpgu->clk, clk_rate);
> + if (rate != clk_rate)
> + return MODE_NOCLOCK;
> +
> + return MODE_OK;
> +}
> +
>  static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
>  {
>   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
> @@ -129,20 +142,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
> ~ARCPGU_CTRL_ENABLE_MASK);
>  }
>  
> -static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
> -  struct drm_crtc_state *state)
> -{
> - struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
> - struct drm_display_mode *mode = >adjusted_mode;
> - long rate, clk_rate = mode->clock * 1000;
> -
> - rate = clk_round_rate(arcpgu->clk, clk_rate);
> - if (rate != clk_rate)
> - return -EINVAL;
> -
> - return 0;
> -}
> -
>  static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
> struct drm_crtc_state *state)
>  {
> @@ -158,6 +157,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc 
> *crtc,
>  }
>  
>  static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
> + .mode_valid = arc_pgu_crtc_mode_valid,
>   .mode_set   = drm_helper_crtc_mode_set,
>   .mode_set_base  = drm_helper_crtc_mode_set_base,
>   .mode_set_nofb  = arc_pgu_crtc_mode_set_nofb,
> @@ -165,7 +165,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc 
> *crtc,
>   .disable= arc_pgu_crtc_disable,
>   .prepare= arc_pgu_crtc_disable,
>   .commit = arc_pgu_crtc_enable,
> - .atomic_check   = arc_pgu_crtc_atomic_check,
>   .atomic_begin   = arc_pgu_crtc_atomic_begin,
>  };
>  

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


Re: [PATCH] drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY

2017-06-13 Thread Jose Abreu
Hi Laurent,


Sorry for the late reply!


On 10-06-2017 09:50, Laurent Pinchart wrote:
> Hi Jose,
>
> On Friday 09 Jun 2017 13:53:12 Jose Abreu wrote:
>> On 09-06-2017 12:04, Jose Abreu wrote:
>>> Currently HDMI 2.0 PHYs do not have a default configuration function.
>>>
>>> As these PHYs have the same register layout as the 3D PHYs we can
>>> safely use the default configuration function.
>> I may have been a little to fast arriving at this conclusion. I
>> mean most of the registers match but in the configuration
>> function there are registers that do not match. Did you actually
>> test this configuration function with an HDMI 2.0 phy? And did
>> you test with different video modes? From my experience the phy
>> may be wrongly configured and sometimes work anyway.
>>
>> Do please retest with as many video modes as you can and give me
>> your phy ID (read from controller config reg HDMI_CONFIG2_ID).
> The Renesas R-Car Gen3 HDMI PHY reports an DWC HDMI 2.0 TX PHY ID, but has a 
> configuration function (rcar_hdmi_phy_configure() in drivers/gpu/drm/rcar-
> du/rcar_dw_hdmi.c) that doesn't match hdmi_phy_configure_dwc_hdmi_3d_tx(). 
> From the information I have been given the layout of the configuration 
> registers haven't been changed by Renesas. I know we've briefly discussed 
> this 
> in the past, but I'd appreciate if you could have a second look and tell me 
> what you think.

Yup, yours seems correct. Though at the time you submitted I
found it odd that only 3 registers needed to be written whilst
for HDMI 2.0 phys I have here 6 registers, but you said it is
working so I though your phy was different ...

Even so, one thing I would like to know is what was the max
resolution you tested? I see you have clock values up to 297MHz,
so 4k@30Hz? If I send a patch with a general config function for
HDMI 2.0 phys can you test it on your platform?

Best regards,
Jose Miguel Abreu

>
>>>  If, for some reason,
>>>
>>> the PHY is custom this change will not make any impact because
>>> in configuration function we prefer the pdata provided configuration
>>> function over the internal one.
>>>
>>> This patch is based on today's drm-misc-next branch.
>>>
>>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>>> Cc: Kieran Bingham <kieran.bingham+rene...@ideasonboard.com>
>>> Cc: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
>>> Cc: Archit Taneja <arch...@codeaurora.org>
>>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>>> Cc: Mark Yao <mark@rock-chips.com>
>>> Cc: Carlos Palminha <palmi...@synopsys.com>
>>> ---
>>>
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index ead1124..10c8d8c 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -2170,6 +2170,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void
>>> *dev_id)
>>> .name = "DWC HDMI 2.0 TX PHY",
>>> .gen = 2,
>>> .has_svsret = true,
>>> +   .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
>>> }, {
>>> .type = DW_HDMI_PHY_VENDOR_PHY,
>>> .name = "Vendor PHY",

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


Re: [PATCH v3 2/6] dt-bindings: display: Add Synopsys DW MIPI DSI DRM bridge driver

2017-06-11 Thread Jose Abreu
Hello,


On 09-06-2017 05:11, Archit Taneja wrote:
> Hi Philippe, Rob,
>
> On 06/08/2017 09:10 PM, Rob Herring wrote:
>> Seems strange there's not also a pixel or bit clock? Or this
>> gets driven
>> from the phy?
>
> Since you mention phy here, I wanted to share a concern with
> the bindings.
> These bindings don't have a separate PHY DT node. The PHY is
> assumed as a
> part of the IP when integrated by a SoC. There are already
> rockchip and
> hisil DSI bindings that use this IP but don't define a PHY node.
>
> It's a similar situation with the DW-HDMI bindings.
>
> For example, when the DW HDMI is integrated in rockchip or
> renesas SoC, the
> bindings "rockchip,rk3288-dw-hdmi" or "renesas,r8a7795-dw-hdmi"
> are used,
> and they don't have a separate PHY DT node.
>
> I wasn't sure whether this is the right way to proceed or not
> for such IPs.
> Some advice would help us here.
>
> Thanks,
> Archit
>

I just want to add that read/writes from/to phy are done using
the controller (in HDMI and in MIPI DSI Host), so the only way to
have a phy driver is that if some custom callbacks are provided
or if the memory region is shared.

Anyway, I agree with Archit in the sense that phy + controller
are highly tied. Also, these two "pieces" are SoC specific and
sometimes very different between SoC's because they can be
customized so I think a different compatible string suits well here.

Best regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY

2017-06-11 Thread Jose Abreu
Currently HDMI 2.0 PHYs do not have a default configuration function.

As these PHYs have the same register layout as the 3D PHYs we can
safely use the default configuration function. If, for some reason,
the PHY is custom this change will not make any impact because
in configuration function we prefer the pdata provided configuration
function over the internal one.

This patch is based on today's drm-misc-next branch.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Kieran Bingham <kieran.bingham+rene...@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Mark Yao <mark@rock-chips.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ead1124..10c8d8c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2170,6 +2170,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
.name = "DWC HDMI 2.0 TX PHY",
.gen = 2,
.has_svsret = true,
+   .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
}, {
.type = DW_HDMI_PHY_VENDOR_PHY,
.name = "Vendor PHY",
-- 
1.9.1


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


Re: [PATCH 1/4] drm: bridge: dw-hdmi: Export hdmi_phy_configure_dwc_hdmi_3d_tx

2017-06-11 Thread Jose Abreu
Hi Mark,


On 09-06-2017 05:03, Mark yao wrote:
> Ignore this patch, Jose has a better patch to solve rk3399 hdmi
> phy configure.
>
> Hi Jose
>
> Sorry for missing your patch about hdmi 2.0 vendor phy fixup:
> https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_patch_9702229=DwIDaQ=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=8R_vb_WsWrT4y-nLrSn1RBR3e11-CkyKvht1NtJ2ZgM=ajY_TW_nm7T6pUv_I9ZZctUjTaEEDe9BnF-mnlvxEEs=
> It works fine on rk3399/rk3288, can you resend a standard patch
> to upstream?

Sure. I forgot to send this earlier. I will send it today.

Best regards,
Jose Miguel Abreu

>
> Thanks
>
> On 2017年06月09日 10:45, Mark Yao wrote:
>> So dw-hdmi vendor driver can reuse
>> hdmi_phy_configure_dwc_hdmi_3d_tx
>> to configure their hardware.
>>
>> Signed-off-by: Mark Yao 
>> ---
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 ++-
>>   include/drm/bridge/dw_hdmi.h  | 3 +++
>>   2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 4e1f54a..c1ceec7 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -1097,7 +1097,7 @@ static int dw_hdmi_phy_power_on(struct
>> dw_hdmi *hdmi)
>>* information the DWC MHL PHY has the same register layout
>> and is thus also
>>* supported by this function.
>>*/
>> -static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi
>> *hdmi,
>> +int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
>>   const struct dw_hdmi_plat_data *pdata,
>>   unsigned long mpixelclock)
>>   {
>> @@ -1146,6 +1146,7 @@ static int
>> hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
>> return 0;
>>   }
>> +EXPORT_SYMBOL_GPL(hdmi_phy_configure_dwc_hdmi_3d_tx);
>> static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>>   {
>> diff --git a/include/drm/bridge/dw_hdmi.h
>> b/include/drm/bridge/dw_hdmi.h
>> index ed599be..7eb67e6 100644
>> --- a/include/drm/bridge/dw_hdmi.h
>> +++ b/include/drm/bridge/dw_hdmi.h
>> @@ -150,6 +150,9 @@ int dw_hdmi_probe(struct platform_device
>> *pdev,
>>   int dw_hdmi_bind(struct platform_device *pdev, struct
>> drm_encoder *encoder,
>>const struct dw_hdmi_plat_data *plat_data);
>>   +int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
>> +const struct dw_hdmi_plat_data *pdata,
>> +unsigned long mpixelclock);
>>   void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd,
>> bool rx_sense);
>> void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi,
>> unsigned int rate);
>
>

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


Re: [PATCH] drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY

2017-06-11 Thread Jose Abreu
Hi Mark,


On 09-06-2017 12:04, Jose Abreu wrote:
> Currently HDMI 2.0 PHYs do not have a default configuration function.
>
> As these PHYs have the same register layout as the 3D PHYs we can
> safely use the default configuration function.

I may have been a little to fast arriving at this conclusion. I
mean most of the registers match but in the configuration
function there are registers that do not match. Did you actually
test this configuration function with an HDMI 2.0 phy? And did
you test with different video modes? From my experience the phy
may be wrongly configured and sometimes work anyway.

Do please retest with as many video modes as you can and give me
your phy ID (read from controller config reg HDMI_CONFIG2_ID).

Best regards,
Jose Miguel Abreu

>  If, for some reason,
> the PHY is custom this change will not make any impact because
> in configuration function we prefer the pdata provided configuration
> function over the internal one.
>
> This patch is based on today's drm-misc-next branch.
>
> Signed-off-by: Jose Abreu <joab...@synopsys.com>
> Cc: Kieran Bingham <kieran.bingham+rene...@ideasonboard.com>
> Cc: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> Cc: Archit Taneja <arch...@codeaurora.org>
> Cc: Andrzej Hajda <a.ha...@samsung.com>
> Cc: Mark Yao <mark@rock-chips.com>
> Cc: Carlos Palminha <palmi...@synopsys.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index ead1124..10c8d8c 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2170,6 +2170,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>   .name = "DWC HDMI 2.0 TX PHY",
>   .gen = 2,
>   .has_svsret = true,
> + .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
>   }, {
>   .type = DW_HDMI_PHY_VENDOR_PHY,
>   .name = "Vendor PHY",

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


Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver

2017-06-02 Thread Jose Abreu
Hi Hans,


On 02-06-2017 07:31, Hans Verkuil wrote:
> On 06/01/2017 03:47 PM, Neil Armstrong wrote:
>> On 05/30/2017 04:23 PM, Russell King wrote:
>>> Add a CEC driver for the dw-hdmi hardware.
>>>
>>> Signed-off-by: Russell King 
>>> ---
>>>   drivers/gpu/drm/bridge/synopsys/Kconfig   |   8 +
>>>   drivers/gpu/drm/bridge/synopsys/Makefile  |   1 +
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320
>>> ++
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |  40 +++-
>>>   5 files changed, 387 insertions(+), 1 deletion(-)
>>>   create mode 100644
>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>   create mode 100644
>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> index 40d2827a6d19..bd30a0a07272 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>>   help
>>> Support the I2S Audio interface which is part of the
>>> Synopsys
>>> Designware HDMI block.
>>> +
>>> +config DRM_DW_HDMI_CEC
>>> +tristate "Synopsis Designware CEC interface"
>>> +depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>>> +select MEDIA_CEC_NOTIFIER
>>> +help
>>> +  Support the CE interface which is part of the Synopsis
>>> +  Designware HDMI block.
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
>>> b/drivers/gpu/drm/bridge/synopsys/Makefile
>>> index 17aa7a65b57e..6fe415903668 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
>>> @@ -3,3 +3,4 @@
>>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> new file mode 100644
>>> index ..761ef5ae687d
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> @@ -0,0 +1,320 @@
>>> +/*
>>> + * Designware HDMI CEC driver
>>> + *
>>> + * Copyright (C) 2015-2017 Russell King.
>>> + *
>>> + * This program is free software; you can redistribute it
>>> and/or modify
>>> + * it under the terms of the GNU General Public License
>>> version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +
>>> +#include 
>>> +
>>> +#include 
>>> +#include 
>>> +
>>> +#include "dw-hdmi-cec.h"
>>> +
>>> +enum {
>>> +HDMI_IH_CEC_STAT0= 0x0106,
>>> +HDMI_IH_MUTE_CEC_STAT0= 0x0186,
>>> +
>>> +HDMI_CEC_CTRL= 0x7d00,
>>> +CEC_CTRL_START= BIT(0),
>>> +CEC_CTRL_NORMAL= 1 << 1,
>>> +
>>> +HDMI_CEC_STAT= 0x7d01,
>>> +CEC_STAT_DONE= BIT(0),
>>> +CEC_STAT_EOM= BIT(1),
>>> +CEC_STAT_NACK= BIT(2),
>>> +CEC_STAT_ARBLOST= BIT(3),
>>> +CEC_STAT_ERROR_INIT= BIT(4),
>>> +CEC_STAT_ERROR_FOLL= BIT(5),
>>> +CEC_STAT_WAKEUP= BIT(6),
>
> I hadn't realized until Jose Abreu's latest reply, but you need
> to check the
> ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.
>
> I think CEC_STAT_ERROR_FOLL might equal
> CEC_TX_STATUS_LOW_DRIVE, but without
> documentation I can't be sure.
>
> My experience is that this low drive condition tends to be
> poorly reported by
> hardware. Either that or poorly documented. This is why I added a
> CEC_TX_STATUS_ERROR status as a catch-all error status when it
> is unclear from
> the hardware/documentation what error occurred.
>
> Jose, do you know which status bit is used to report a follower
> pulling the
> CEC line low for a long time (approx. 3.6 ms) to signal a CEC
> error?

Bit 5 for follower error, bit 4 for initiator error.

Best regards,
Jose Miguel Abreu

>
> Regards,
>
> Hans

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


Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver

2017-06-02 Thread Jose Abreu


On 01-06-2017 23:30, Russell King - ARM Linux wrote:
> On Thu, Jun 01, 2017 at 01:53:21AM +0100, Jose Abreu wrote:
>> Hi Russell,
>>
>>
>> On 30-05-2017 15:23, Russell King wrote:
>>> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
>>> +   u32 signal_free_time, struct cec_msg *msg)
>>> +{
>>> +   struct dw_hdmi_cec *cec = adap->priv;
>>> +   unsigned i;
>>> +
>>> +   cec->retries = attempts;
>> I think you should check first if CEC engine is in normal
>> operation mode, as a safety measure.
> I'm not sure what you mean there, because the iMX6 manuals don't mention
> anything about that.  The only "modes" it talks about is initiator mode
> and follower mode.  Moreover, there's nothing in what was FSL's driver
> that hints at that either.
>
> Maybe you could provide some further technical information on this
> point?
>

You should check that CEC is: not in standy, acknowledges
broadcast messages, signal free time is 5bit period, and not lost
arbitration, which basically means CEC_CTRL must be 0x2 and
IH_CEC_STAT0 must not have ARB_LOST set. I do know you set 0x3 at
the end of this function but according to all the docs I have you
must first set 0x2 before writing message.

Best regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver

2017-06-01 Thread Jose Abreu
Hi Russell,


On 30-05-2017 15:23, Russell King wrote:
> Add a CEC driver for the dw-hdmi hardware.
>
> Signed-off-by: Russell King 
> ---
>  drivers/gpu/drm/bridge/synopsys/Kconfig   |   8 +
>  drivers/gpu/drm/bridge/synopsys/Makefile  |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 
> ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |  40 +++-
>  5 files changed, 387 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig 
> b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index 40d2827a6d19..bd30a0a07272 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>   help
> Support the I2S Audio interface which is part of the Synopsys
> Designware HDMI block.
> +
> +config DRM_DW_HDMI_CEC
> + tristate "Synopsis Designware CEC interface"
> + depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> + select MEDIA_CEC_NOTIFIER
> + help
> +   Support the CE interface which is part of the Synopsis

Synopsis -> Synopsys

> +   Designware HDMI block.
> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile 
> b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 17aa7a65b57e..6fe415903668 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -3,3 +3,4 @@
>  obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>  obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>  obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> new file mode 100644
> index ..761ef5ae687d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> @@ -0,0 +1,320 @@
> +/*
> + * Designware HDMI CEC driver
> + *
> + * Copyright (C) 2015-2017 Russell King.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include 
> +#include 
> +
> +#include "dw-hdmi-cec.h"
> +
> +enum {
> + HDMI_IH_CEC_STAT0   = 0x0106,
> + HDMI_IH_MUTE_CEC_STAT0  = 0x0186,
> +
> + HDMI_CEC_CTRL   = 0x7d00,
> + CEC_CTRL_START  = BIT(0),
> + CEC_CTRL_NORMAL = 1 << 1,
> +
> + HDMI_CEC_STAT   = 0x7d01,
> + CEC_STAT_DONE   = BIT(0),
> + CEC_STAT_EOM= BIT(1),
> + CEC_STAT_NACK   = BIT(2),
> + CEC_STAT_ARBLOST= BIT(3),
> + CEC_STAT_ERROR_INIT = BIT(4),
> + CEC_STAT_ERROR_FOLL = BIT(5),
> + CEC_STAT_WAKEUP = BIT(6),

I rather like the format HDMI_{REGISTER_NAME}_{FIELD_NAME} so
that it clearly identifies this is a internal driver register and
not a CEC core register, but I guess its up to you :)

> +
> + HDMI_CEC_MASK   = 0x7d02,
> + HDMI_CEC_POLARITY   = 0x7d03,
> + HDMI_CEC_INT= 0x7d04,
> + HDMI_CEC_ADDR_L = 0x7d05,
> + HDMI_CEC_ADDR_H = 0x7d06,
> + HDMI_CEC_TX_CNT = 0x7d07,
> + HDMI_CEC_RX_CNT = 0x7d08,
> + HDMI_CEC_TX_DATA0   = 0x7d10,
> + HDMI_CEC_RX_DATA0   = 0x7d20,
> + HDMI_CEC_LOCK   = 0x7d30,
> + HDMI_CEC_WKUPCTRL   = 0x7d31,
> +};
> +
> +struct dw_hdmi_cec {
> + struct dw_hdmi *hdmi;
> + const struct dw_hdmi_cec_ops *ops;
> + u32 addresses;
> + struct cec_adapter *adap;
> + struct cec_msg rx_msg;
> + unsigned int tx_status;
> + bool tx_done;
> + bool rx_done;
> + struct cec_notifier *notify;
> + int retries;
> + int irq;
> +};
> +
> +static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
> +{
> + cec->ops->write(cec->hdmi, val, offset);
> +}
> +
> +static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
> +{
> + return cec->ops->read(cec->hdmi, offset);
> +}
> +
> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> + struct dw_hdmi_cec *cec = adap->priv;

You can use "cec = cec_get_drvdata(adap)" here, as in the rest of
the code.

> + u32 addresses;
> +
> + if (logical_addr == CEC_LOG_ADDR_INVALID)
> + addresses = cec->addresses = 0;
> + else
> + addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> +
> + dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> + dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
> +
> + return 0;
> +}
> +
> 

Re: [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control

2017-06-01 Thread Jose Abreu
Hi Russell,


On 30-05-2017 15:23, Russell King wrote:
> The video setup path aways sets the clock disable register to a specific
> value, which has the effect of disabling the CEC engine.  When we add the
> CEC driver, this becomes a problem.
>
> Fix this by only setting/clearing the bits that the video path needs to.
>
> Signed-off-by: Russell King <rmk+ker...@armlinux.org.uk>

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++--
>  1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 966422576c44..58781d4c1034 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -166,6 +166,7 @@ struct dw_hdmi {
>   bool bridge_is_on;  /* indicates the bridge is on */
>   bool rxsense;   /* rxsense state */
>   u8 phy_mask;/* desired phy int mask settings */
> + u8 mc_clkdis;   /* clock disable register */
>  
>   spinlock_t audio_lock;
>   struct mutex audio_mutex;
> @@ -1543,8 +1544,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  /* HDMI Initialization Step B.4 */
>  static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  {
> - u8 clkdis;
> -
>   /* control period minimum duration */
>   hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
>   hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
> @@ -1556,17 +1555,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi 
> *hdmi)
>   hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
>  
>   /* Enable pixel clock and tmds data path */
> - clkdis = 0x7F;
> - clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> - hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> + hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
> +HDMI_MC_CLKDIS_CSCCLK_DISABLE |
> +HDMI_MC_CLKDIS_AUDCLK_DISABLE |
> +HDMI_MC_CLKDIS_PREPCLK_DISABLE |
> +HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
> - clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> - hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
>   /* Enable csc path */
>   if (is_color_space_conversion(hdmi)) {
> - clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> - hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>   }
>  
>   /* Enable color space conversion if needed */
> @@ -1580,7 +1583,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi 
> *hdmi)
>  
>  static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
>  {
> - hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
> + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
> + hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  }
>  
>  /* Workaround to clear the overflow condition */
> @@ -2261,6 +2265,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>   hdmi->disabled = true;
>   hdmi->rxsense = true;
>   hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
> + hdmi->mc_clkdis = 0x7f;
>  
>   mutex_init(>mutex);
>   mutex_init(>audio_mutex);

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


[PATCH v5 08/10] drm/arm: malidp: Use crtc->mode_valid() callback

2017-05-25 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in malidp so that we restrict the number of probbed
modes to the ones we can actually display.

Also, remove the mode_fixup() callback as this is no longer needed
because mode_valid() will be called before.

NOTE: Not even compiled tested

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Liviu Dudau <liviu.du...@arm.com>
Cc: Brian Starkey <brian.star...@arm.com>
Cc: David Airlie <airl...@linux.ie>
---
 drivers/gpu/drm/arm/malidp_crtc.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_crtc.c 
b/drivers/gpu/drm/arm/malidp_crtc.c
index 9446a67..4bb38a2 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -22,9 +22,8 @@
 #include "malidp_drv.h"
 #include "malidp_hw.h"
 
-static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc,
-  const struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status malidp_crtc_mode_valid(struct drm_crtc *crtc,
+  const struct 
drm_display_mode *mode)
 {
struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
struct malidp_hw_device *hwdev = malidp->dev;
@@ -40,11 +39,11 @@ static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc,
if (rate != req_rate) {
DRM_DEBUG_DRIVER("pxlclk doesn't support %ld Hz\n",
 req_rate);
-   return false;
+   return MODE_NOCLOCK;
}
}
 
-   return true;
+   return MODE_OK;
 }
 
 static void malidp_crtc_enable(struct drm_crtc *crtc)
@@ -408,7 +407,7 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = {
-   .mode_fixup = malidp_crtc_mode_fixup,
+   .mode_valid = malidp_crtc_mode_valid,
.enable = malidp_crtc_enable,
.disable = malidp_crtc_disable,
.atomic_check = malidp_crtc_atomic_check,
-- 
1.9.1


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


[PATCH v5 06/10] drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback

2017-05-25 Thread Jose Abreu
Now that we have a callback to check if bridge supports a given mode
we can use it in Analogix bridge so that we restrict the number of
probbed modes to the ones we can actually display.

Also, there is no need to use mode_fixup() callback as mode_valid()
will handle the mode validation.

NOTE: Only compile tested.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Cc: David Airlie <airl...@linux.ie>
---
 drivers/gpu/drm/bridge/analogix-anx78xx.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c 
b/drivers/gpu/drm/bridge/analogix-anx78xx.c
index a2a8236..cf69a1c 100644
--- a/drivers/gpu/drm/bridge/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c
@@ -1061,18 +1061,17 @@ static int anx78xx_bridge_attach(struct drm_bridge 
*bridge)
return 0;
 }
 
-static bool anx78xx_bridge_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+enum drm_mode_status anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode 
*mode)
 {
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-   return false;
+   return MODE_NO_INTERLACE;
 
/* Max 1200p at 5.4 Ghz, one lane */
if (mode->clock > 154000)
-   return false;
+   return MODE_CLOCK_HIGH;
 
-   return true;
+   return MODE_OK;
 }
 
 static void anx78xx_bridge_disable(struct drm_bridge *bridge)
@@ -1129,7 +1128,7 @@ static void anx78xx_bridge_enable(struct drm_bridge 
*bridge)
 
 static const struct drm_bridge_funcs anx78xx_bridge_funcs = {
.attach = anx78xx_bridge_attach,
-   .mode_fixup = anx78xx_bridge_mode_fixup,
+   .mode_valid = anx78xx_bridge_mode_valid,
.disable = anx78xx_bridge_disable,
.mode_set = anx78xx_bridge_mode_set,
.enable = anx78xx_bridge_enable,
-- 
1.9.1


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


[PATCH v5 09/10] drm/atmel-hlcdc: Use crtc->mode_valid() callback

2017-05-25 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in atmel-hlcdc so that we restrict the number of probbed
modes to the ones we can actually display.

Also, remove the mode_fixup() callback as this is no longer needed
because mode_valid() will be called before.

NOTE: Not even compiled tested

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Boris Brezillon <boris.brezil...@free-electrons.com>
Cc: David Airlie <airl...@linux.ie>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 53bfa56..bdfe74e 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -140,13 +140,12 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct 
drm_crtc *c)
   cfg);
 }
 
-static bool atmel_hlcdc_crtc_mode_fixup(struct drm_crtc *c,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status atmel_hlcdc_crtc_mode_valid(struct drm_crtc *c,
+   const struct 
drm_display_mode *mode)
 {
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
 
-   return atmel_hlcdc_dc_mode_valid(crtc->dc, adjusted_mode) == MODE_OK;
+   return atmel_hlcdc_dc_mode_valid(crtc->dc, mode);
 }
 
 static void atmel_hlcdc_crtc_disable(struct drm_crtc *c)
@@ -315,7 +314,7 @@ static void atmel_hlcdc_crtc_atomic_flush(struct drm_crtc 
*crtc,
 }
 
 static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = {
-   .mode_fixup = atmel_hlcdc_crtc_mode_fixup,
+   .mode_valid = atmel_hlcdc_crtc_mode_valid,
.mode_set = drm_helper_crtc_mode_set,
.mode_set_nofb = atmel_hlcdc_crtc_mode_set_nofb,
.mode_set_base = drm_helper_crtc_mode_set_base,
-- 
1.9.1


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


[PATCH v5 03/10] drm: Use new mode_valid() helpers in connector probe helper

2017-05-25 Thread Jose Abreu
This changes the connector probe helper function to use the new
encoder->mode_valid(), bridge->mode_valid() and crtc->mode_valid()
helper callbacks to validate the modes.

The new callbacks are optional so the behaviour remains the same
if they are not implemented. If they are, then the code loops
through all the connector's encodersXbridgesXcrtcs and calls the
callback.

If at least a valid encoderXbridgeXcrtc combination is found which
accepts the mode then the function returns MODE_OK.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

Changes v3->v4:
- Change function name (Laurent)
Changes v2->v3:
- Call also bridge->mode_valid (Daniel)
Changes v1->v2:
- Use new helpers suggested by Ville
- Change documentation (Daniel)

---
 drivers/gpu/drm/drm_probe_helper.c | 67 +++---
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index f01abdc..00e6832 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -83,6 +83,61 @@
return MODE_OK;
 }
 
+static enum drm_mode_status
+drm_mode_validate_pipeline(struct drm_display_mode *mode,
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   uint32_t *ids = connector->encoder_ids;
+   enum drm_mode_status ret = MODE_OK;
+   unsigned int i;
+
+   /* Step 1: Validate against connector */
+   ret = drm_connector_mode_valid(connector, mode);
+   if (ret != MODE_OK)
+   return ret;
+
+   /* Step 2: Validate against encoders and crtcs */
+   for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+   struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+   struct drm_crtc *crtc;
+
+   if (!encoder)
+   continue;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   /* No point in continuing for crtc check as this encoder
+* will not accept the mode anyway. If all encoders
+* reject the mode then, at exit, ret will not be
+* MODE_OK. */
+   continue;
+   }
+
+   ret = drm_bridge_mode_valid(encoder->bridge, mode);
+   if (ret != MODE_OK) {
+   /* There is also no point in continuing for crtc check
+* here. */
+   continue;
+   }
+
+   drm_for_each_crtc(crtc, dev) {
+   if (!drm_encoder_crtc_ok(encoder, crtc))
+   continue;
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret == MODE_OK) {
+   /* If we get to this point there is at least
+* one combination of encoder+crtc that works
+* for this mode. Lets return now. */
+   return ret;
+   }
+   }
+   }
+
+   return ret;
+}
+
 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
 {
struct drm_cmdline_mode *cmdline_mode;
@@ -322,7 +377,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
  *- drm_mode_validate_flag() checks the modes against basic connector
  *  capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
  *- the optional _connector_helper_funcs.mode_valid helper can perform
- *  driver and/or hardware specific checks
+ *  driver and/or sink specific checks
+ *- the optional _crtc_helper_funcs.mode_valid,
+ *  _bridge_funcs.mode_valid and _encoder_helper_funcs.mode_valid
+ *  helpers can perform driver and/or source specific checks which are also
+ *  enforced by the modeset/atomic helpers
  *
  * 5. Any mode whose status is not OK is pruned from the connector's modes 
list,
  *accompanied by a debug message indicating the reason for the mode's
@@ -466,9 +525,9 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_flag(mode, mode_flags);
 
-   if (mode->status == MODE_OK && connector_funcs->mode_valid)
-   mode->status = connector_funcs->mode_valid(connector,
-  mode);
+   if (

[PATCH v5 05/10] drm: arcpgu: Use crtc->mode_valid() callback

2017-05-25 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in arcpgu so that we restrict the number of probbed
modes to the ones we can actually display.

This is specially useful because arcpgu crtc is responsible to set
a clock value in the commit() stage but unfortunatelly this clock
does not support all the needed ranges.

Also, remove the atomic_check() callback as mode_valid() callback
will be called before.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Alexey Brodkin <abrod...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

Changes v4->v5:
- Change commit message to "arcpgu" (Alexey)
Changes v3->v4:
- Do not use aux function (Laurent)

---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 29 ++---
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index ad9a959..99fbdae 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -64,6 +64,19 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
+enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode 
*mode)
+{
+   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
+   long rate, clk_rate = mode->clock * 1000;
+
+   rate = clk_round_rate(arcpgu->clk, clk_rate);
+   if (rate != clk_rate)
+   return MODE_NOCLOCK;
+
+   return MODE_OK;
+}
+
 static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -129,20 +142,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
  ~ARCPGU_CTRL_ENABLE_MASK);
 }
 
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
-struct drm_crtc_state *state)
-{
-   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-   struct drm_display_mode *mode = >adjusted_mode;
-   long rate, clk_rate = mode->clock * 1000;
-
-   rate = clk_round_rate(arcpgu->clk, clk_rate);
-   if (rate != clk_rate)
-   return -EINVAL;
-
-   return 0;
-}
-
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
  struct drm_crtc_state *state)
 {
@@ -158,6 +157,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
+   .mode_valid = arc_pgu_crtc_mode_valid,
.mode_set   = drm_helper_crtc_mode_set,
.mode_set_base  = drm_helper_crtc_mode_set_base,
.mode_set_nofb  = arc_pgu_crtc_mode_set_nofb,
@@ -165,7 +165,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
.disable= arc_pgu_crtc_disable,
.prepare= arc_pgu_crtc_disable,
.commit = arc_pgu_crtc_enable,
-   .atomic_check   = arc_pgu_crtc_atomic_check,
.atomic_begin   = arc_pgu_crtc_atomic_begin,
 };
 
-- 
1.9.1


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


[PATCH v5 01/10] drm: Add drm_{crtc/encoder/connector}_mode_valid()

2017-05-25 Thread Jose Abreu
Add a new helper to call crtc->mode_valid, connector->mode_valid
and encoder->mode_valid callbacks.

Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Dave Airlie <airl...@linux.ie>

Changes v2->v3:
- Move helpers to drm_probe_helper.c (Daniel)
- Squeeze patches that introduce helpers into a single
one (Daniel)

Signed-off-by: Jose Abreu <joab...@synopsys.com>
---
 drivers/gpu/drm/drm_crtc_helper_internal.h | 13 ++
 drivers/gpu/drm/drm_probe_helper.c | 38 ++
 2 files changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_helper_internal.h 
b/drivers/gpu/drm/drm_crtc_helper_internal.h
index 28295e5..97dfe20 100644
--- a/drivers/gpu/drm/drm_crtc_helper_internal.h
+++ b/drivers/gpu/drm/drm_crtc_helper_internal.h
@@ -26,7 +26,11 @@
  * implementation details and are not exported to drivers.
  */
 
+#include 
+#include 
 #include 
+#include 
+#include 
 
 /* drm_fb_helper.c */
 #ifdef CONFIG_DRM_FBDEV_EMULATION
@@ -62,4 +66,13 @@ static inline int drm_dp_aux_register_devnode(struct 
drm_dp_aux *aux)
 static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
 {
 }
+
+/* drm_probe_helper.c */
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode);
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode 
*mode);
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode);
+
 #endif
diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 1b0c14a..f01abdc 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+
+#include "drm_crtc_helper_internal.h"
 
 /**
  * DOC: output probing helper overview
@@ -113,6 +116,41 @@ static int drm_helper_probe_add_cmdline_mode(struct 
drm_connector *connector)
return 1;
 }
 
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode)
+{
+   const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+   if (!crtc_funcs || !crtc_funcs->mode_valid)
+   return MODE_OK;
+
+   return crtc_funcs->mode_valid(crtc, mode);
+}
+
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode *mode)
+{
+   const struct drm_encoder_helper_funcs *encoder_funcs =
+   encoder->helper_private;
+
+   if (!encoder_funcs || !encoder_funcs->mode_valid)
+   return MODE_OK;
+
+   return encoder_funcs->mode_valid(encoder, mode);
+}
+
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+   const struct drm_connector_helper_funcs *connector_funcs =
+   connector->helper_private;
+
+   if (!connector_funcs || !connector_funcs->mode_valid)
+   return MODE_OK;
+
+   return connector_funcs->mode_valid(connector, mode);
+}
+
 #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
 /**
  * drm_kms_helper_poll_enable - re-enable output polling.
-- 
1.9.1


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


[PATCH v5 00/10] Introduce new mode validation callbacks

2017-05-25 Thread Jose Abreu
NOTE: In this version I just did a rebase onto today's drm-next and
added the tags we've collected plus the changelog plus the missing
maintainers that I forgot to cc in previous version :/

This series is a follow up from the discussion at [1]. We start by
introducing crtc->mode_valid(), encoder->mode_valid() and
bridge->mode_valid() callbacks which will be used in followup
patches and also by cleaning the documentation a little bit. This
patch is available at [2] and the series depends on it.

We proceed by introducing new helpers to call this new callbacks
at 1/10.

At 2/10 a helper function is introduced that calls all mode_valid()
from a set of bridges.

Next, at 3/10 we modify the connector probe helper so that only modes
which are supported by a given bridge+encoder+crtc combination are
probbed.

At 4/10 we call all the mode_valid() callbacks for a given pipeline,
except the connector->mode_valid one, so that the mode is validated.
This is done before calling mode_fixup().

Finally, from 5/10 to 10/10 we use the new callbacks in drivers that
can implement it.

[1] https://patchwork.kernel.org/patch/9702233/
[2] https://lists.freedesktop.org/archives/dri-devel/2017-May/141761.html

Jose Abreu (10):
  drm: Add drm_{crtc/encoder/connector}_mode_valid()
  drm: Introduce drm_bridge_mode_valid()
  drm: Use new mode_valid() helpers in connector probe helper
  drm: Use mode_valid() in atomic modeset
  drm: arcpgu: Use crtc->mode_valid() callback
  drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback
  drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback
  drm/arm: malidp: Use crtc->mode_valid() callback
  drm/atmel-hlcdc: Use crtc->mode_valid() callback
  drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks

Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

 drivers/gpu/drm/arc/arcpgu_crtc.c  |  29 ---
 drivers/gpu/drm/arm/malidp_crtc.c  |  11 ++-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c |   9 +--
 drivers/gpu/drm/bridge/analogix-anx78xx.c  |  13 ++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c  |  40 +++---
 drivers/gpu/drm/drm_atomic_helper.c|  76 +-
 drivers/gpu/drm/drm_bridge.c   |  33 
 drivers/gpu/drm/drm_crtc_helper_internal.h |  13 +++
 drivers/gpu/drm/drm_probe_helper.c | 105 -
 drivers/gpu/drm/imx/dw_hdmi-imx.c  |   4 +-
 drivers/gpu/drm/meson/meson_dw_hdmi.c  |   2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c|   2 +-
 drivers/gpu/drm/vc4/vc4_crtc.c |  13 ++-
 drivers/gpu/drm/vc4/vc4_dpi.c  |  13 ++-
 include/drm/bridge/dw_hdmi.h   |   2 +-
 include/drm/drm_bridge.h   |   2 +
 16 files changed, 280 insertions(+), 87 deletions(-)

-- 
1.9.1


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


[PATCH v5 07/10] drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback

2017-05-25 Thread Jose Abreu
Now that we have a callback to check if bridge supports a given mode
we can use it in Synopsys Designware HDMI bridge so that we restrict
the number of probbed modes to the ones we can actually display.

Also, there is no need to use mode_fixup() callback as mode_valid()
will handle the mode validation.

NOTE: Only compile tested
NOTE 2: I also had to change the pdata declaration of mode_valid
custom callback so that the passed modes are const. I also changed
in the platforms I found. Not even compiled it though.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Acked-by: Neil Armstrong <narmstr...@baylibre.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Cc: David Airlie <airl...@linux.ie>
Cc: Philipp Zabel <p.za...@pengutronix.de>
Cc: Carlo Caione <ca...@caione.org>
Cc: Kevin Hilman <khil...@baylibre.com>
Cc: Mark Yao <mark@rock-chips.com>
Cc: Heiko Stuebner <he...@sntech.de>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 40 +
 drivers/gpu/drm/imx/dw_hdmi-imx.c   |  4 +--
 drivers/gpu/drm/meson/meson_dw_hdmi.c   |  2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  2 +-
 include/drm/bridge/dw_hdmi.h|  2 +-
 5 files changed, 17 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 8737de8..038dc43 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1907,24 +1907,6 @@ static int dw_hdmi_connector_get_modes(struct 
drm_connector *connector)
return ret;
 }
 
-static enum drm_mode_status
-dw_hdmi_connector_mode_valid(struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-   struct dw_hdmi *hdmi = container_of(connector,
-  struct dw_hdmi, connector);
-   enum drm_mode_status mode_status = MODE_OK;
-
-   /* We don't support double-clocked modes */
-   if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-   return MODE_BAD;
-
-   if (hdmi->plat_data->mode_valid)
-   mode_status = hdmi->plat_data->mode_valid(connector, mode);
-
-   return mode_status;
-}
-
 static void dw_hdmi_connector_force(struct drm_connector *connector)
 {
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
@@ -1950,7 +1932,6 @@ static void dw_hdmi_connector_force(struct drm_connector 
*connector)
 
 static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs 
= {
.get_modes = dw_hdmi_connector_get_modes,
-   .mode_valid = dw_hdmi_connector_mode_valid,
.best_encoder = drm_atomic_helper_best_encoder,
 };
 
@@ -1973,18 +1954,21 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
*bridge)
return 0;
 }
 
-static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *orig_mode,
- struct drm_display_mode *mode)
+static enum drm_mode_status dw_hdmi_bridge_mode_valid(struct drm_bridge 
*bridge,
+ const struct 
drm_display_mode *mode)
 {
struct dw_hdmi *hdmi = bridge->driver_private;
struct drm_connector *connector = >connector;
-   enum drm_mode_status status;
+   enum drm_mode_status mode_status = MODE_OK;
 
-   status = dw_hdmi_connector_mode_valid(connector, mode);
-   if (status != MODE_OK)
-   return false;
-   return true;
+   /* We don't support double-clocked modes */
+   if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+   return MODE_BAD;
+
+   if (hdmi->plat_data->mode_valid)
+   mode_status = hdmi->plat_data->mode_valid(connector, mode);
+
+   return mode_status;
 }
 
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
@@ -2028,7 +2012,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge 
*bridge)
.enable = dw_hdmi_bridge_enable,
.disable = dw_hdmi_bridge_disable,
.mode_set = dw_hdmi_bridge_mode_set,
-   .mode_fixup = dw_hdmi_bridge_mode_fixup,
+   .mode_valid = dw_hdmi_bridge_mode_valid,
 };
 
 static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index f039641..5f561c8 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -148,7 +148,7 @@ static int dw_hdmi_imx_atomic_check(struct drm_encoder 
*encoder,
 };
 
 static enum drm_mode_status imx6q_hdmi_mode_valid(struct drm_connector *con,
-

[PATCH v5 04/10] drm: Use mode_valid() in atomic modeset

2017-05-25 Thread Jose Abreu
This patches makes use of the new mode_valid() callbacks introduced
previously to validate the full video pipeline when modesetting.

This calls the connector->mode_valid(), encoder->mode_valid(),
bridge->mode_valid() and crtc->mode_valid() so that we can
make sure that the mode will be accepted in every components.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

Changes v1->v2:
- Removed call to connector->mode_valid (Ville, Daniel)
- Changed function name (Ville)
- Use for_each_new_connector_in_state (Ville)
- Do not validate if connector and mode didn't change (Ville)
- Use new helpers to call mode_valid

Signed-off-by: Jose Abreu <joab...@synopsys.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 76 +++--
 1 file changed, 73 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 6426339..21afca4 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 
+#include "drm_crtc_helper_internal.h"
 #include "drm_crtc_internal.h"
 
 /**
@@ -452,6 +453,69 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
return 0;
 }
 
+static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
+   struct drm_encoder *encoder,
+   struct drm_crtc *crtc,
+   struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] mode_valid() failed\n",
+   encoder->base.id, encoder->name);
+   return ret;
+   }
+
+   ret = drm_bridge_mode_valid(encoder->bridge, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
+   return ret;
+   }
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode_valid() failed\n",
+   crtc->base.id, crtc->name);
+   return ret;
+   }
+
+   return ret;
+}
+
+static int
+mode_valid(struct drm_atomic_state *state)
+{
+   struct drm_connector_state *conn_state;
+   struct drm_connector *connector;
+   int i;
+
+   for_each_new_connector_in_state(state, connector, conn_state, i) {
+   struct drm_encoder *encoder = conn_state->best_encoder;
+   struct drm_crtc *crtc = conn_state->crtc;
+   struct drm_crtc_state *crtc_state;
+   enum drm_mode_status mode_status;
+   struct drm_display_mode *mode;
+
+   if (!crtc || !encoder)
+   continue;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   if (!crtc_state)
+   continue;
+   if (!crtc_state->mode_changed && 
!crtc_state->connectors_changed)
+   continue;
+
+   mode = _state->mode;
+
+   mode_status = mode_valid_path(connector, encoder, crtc, mode);
+   if (mode_status != MODE_OK)
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 /**
  * drm_atomic_helper_check_modeset - validate state object for modeset changes
  * @dev: DRM device
@@ -466,13 +530,15 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
  * 2. _connector_helper_funcs.atomic_check to validate the connector state.
  * 3. If it's determined a modeset is needed then all connectors on the 
affected crtc
  *crtc are added and _connector_helper_funcs.atomic_check is run on 
them.
- * 4. _bridge_funcs.mode_fixup is called on all encoder bridges.
- * 5. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
+ * 4. _encoder_helper_funcs.mode_valid, _bridge_funcs.mode_valid and
+ *_crtc_helper_funcs.mode_valid are called on the affected components.
+ * 5. _bridge_funcs.mode_fixup is called on all encoder bridges.
+ * 6. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
  *This function is only called when the encoder will be part of a 
con

[PATCH v5 10/10] drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks

2017-05-25 Thread Jose Abreu
Now that we have a callback to check if crtc and encoder supports a
given mode we can use it in vc4 so that we restrict the number of
probbed modes to the ones we can actually display.

Also, remove the mode_fixup() calls as these are no longer needed
because mode_valid() will be called before.

NOTE: Not even compiled tested

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Eric Anholt <e...@anholt.net>
Cc: David Airlie <airl...@linux.ie>
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 13 ++---
 drivers/gpu/drm/vc4/vc4_dpi.c  | 13 ++---
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 1b4dbe9..20703c8 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -542,18 +542,17 @@ static void vc4_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
 }
 
-static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
+   const struct drm_display_mode 
*mode)
 {
/* Do not allow doublescan modes from user space */
-   if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) {
+   if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n",
  crtc->base.id);
-   return false;
+   return MODE_NO_DBLESCAN;
}
 
-   return true;
+   return MODE_OK;
 }
 
 static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
@@ -863,7 +862,7 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
.mode_set_nofb = vc4_crtc_mode_set_nofb,
.disable = vc4_crtc_disable,
.enable = vc4_crtc_enable,
-   .mode_fixup = vc4_crtc_mode_fixup,
+   .mode_valid = vc4_crtc_mode_valid,
.atomic_check = vc4_crtc_atomic_check,
.atomic_flush = vc4_crtc_atomic_flush,
 };
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index c6d7039..61958ab 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -330,20 +330,19 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
*encoder)
}
 }
 
-static bool vc4_dpi_encoder_mode_fixup(struct drm_encoder *encoder,
-  const struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder 
*encoder,
+  const struct 
drm_display_mode *mode)
 {
-   if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
-   return false;
+   if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+   return MODE_NO_INTERLACE;
 
-   return true;
+   return MODE_OK;
 }
 
 static const struct drm_encoder_helper_funcs vc4_dpi_encoder_helper_funcs = {
.disable = vc4_dpi_encoder_disable,
.enable = vc4_dpi_encoder_enable,
-   .mode_fixup = vc4_dpi_encoder_mode_fixup,
+   .mode_valid = vc4_dpi_encoder_mode_valid,
 };
 
 static const struct of_device_id vc4_dpi_dt_match[] = {
-- 
1.9.1


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


[PATCH v5 02/10] drm: Introduce drm_bridge_mode_valid()

2017-05-25 Thread Jose Abreu
Introduce a new helper function which calls mode_valid() callback
for all bridges in an encoder chain.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/drm_bridge.c | 33 +
 include/drm/drm_bridge.h |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 86a7637..dc8cdfe 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
 EXPORT_SYMBOL(drm_bridge_mode_fixup);
 
 /**
+ * drm_bridge_mode_valid - validate the mode against all bridges in the
+ *encoder chain.
+ * @bridge: bridge control structure
+ * @mode: desired mode to be validated
+ *
+ * Calls _bridge_funcs.mode_valid for all the bridges in the encoder
+ * chain, starting from the first bridge to the last. If at least one bridge
+ * does not accept the mode the function returns the error code.
+ *
+ * Note: the bridge passed should be the one closest to the encoder.
+ *
+ * RETURNS:
+ * MODE_OK on success, drm_mode_status Enum error code on failure
+ */
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret = MODE_OK;
+
+   if (!bridge)
+   return ret;
+
+   if (bridge->funcs->mode_valid)
+   ret = bridge->funcs->mode_valid(bridge, mode);
+
+   if (ret != MODE_OK)
+   return ret;
+
+   return drm_bridge_mode_valid(bridge->next, mode);
+}
+EXPORT_SYMBOL(drm_bridge_mode_valid);
+
+/**
  * drm_bridge_disable - disables all bridges in the encoder chain
  * @bridge: bridge control structure
  *
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 00c6c36..8358eb3 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct 
drm_bridge *bridge,
 bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode);
 void drm_bridge_disable(struct drm_bridge *bridge);
 void drm_bridge_post_disable(struct drm_bridge *bridge);
 void drm_bridge_mode_set(struct drm_bridge *bridge,
-- 
1.9.1


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


Re: [PATCH v4 00/10] Introduce new mode validation callbacks

2017-05-23 Thread Jose Abreu
Hi Daniel,


On 22-05-2017 16:31, Daniel Vetter wrote:
> On Mon, May 22, 2017 at 09:56:00AM +0200, Daniel Vetter wrote:
>> On Fri, May 19, 2017 at 01:52:09AM +0100, Jose Abreu wrote:
>>> This series is a follow up from the discussion at [1]. We start by
>>> introducing crtc->mode_valid(), encoder->mode_valid() and
>>> bridge->mode_valid() callbacks which will be used in followup
>>> patches and also by cleaning the documentation a little bit. This
>>> patch is available at [2] and the series depends on it.
>>>
>>> We proceed by introducing new helpers to call this new callbacks
>>> at 1/10.
>>>
>>> At 2/10 a helper function is introduced that calls all mode_valid()
>>> from a set of bridges.
>>>
>>> Next, at 3/10 we modify the connector probe helper so that only modes
>>> which are supported by a given bridge+encoder+crtc combination are
>>> probbed.
>>>
>>> At 4/10 we call all the mode_valid() callbacks for a given pipeline,
>>> except the connector->mode_valid one, so that the mode is validated.
>>> This is done before calling mode_fixup().
>>>
>>> Finally, from 5/10 to 10/10 we use the new callbacks in drivers that
>>> can implement it.
>>>
>>> [1] 
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_patch_9702233_=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=YohmJizS2YWha2kjTAHGImBe-ghyCyY_4jKYalIhqcU=mtXW7k5AwOp9H790Zg-U0ZB_OXCyW-SRQD9H5kTX5Ec=
>>>  
>>> [2] 
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.freedesktop.org_archives_dri-2Ddevel_2017-2DMay_141761.html=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=YohmJizS2YWha2kjTAHGImBe-ghyCyY_4jKYalIhqcU=N3-YUnWxQAD9jw0y7xFB0fAuCGa_B6Q6yRsL2OmGWM0=
>>>  
>>>
>>> Jose Abreu (10):
>>>   drm: Add drm_{crtc/encoder/connector}_mode_valid()
>>>   drm: Introduce drm_bridge_mode_valid()
>>>   drm: Use new mode_valid() helpers in connector probe helper
>>>   drm: Use mode_valid() in atomic modeset
>>>   drm: arc: Use crtc->mode_valid() callback
>>>   drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback
>>>   drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback
>>>   drm/arm: malidp: Use crtc->mode_valid() callback
>>>   drm/atmel-hlcdc: Use crtc->mode_valid() callback
>>>   drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
>> Looks all real nice, I think a bit more time to get acks/reviews/tested-by
>> for the driver conversions and I'll go and vacuum this all up.
> On that: You didn't cc driver maintainers on the driver conversion patches
> (not all are bridge drivers maintainer by Archit), without that they
> might miss it. Please remember to do that (you might need to resend to get
> their attention), scripts/get_maintainers.pl helps with that.

Yeah, I'm really sorry about that. I was in a different time zone
with all my head messed up with jetlag so I missed this and maybe
more :/ Lets wait for some input and I will resend the series if
needed.

Thanks!

Best regards,
Jose Miguel Abreu

>
> Thanks, Daniel

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


Re: [PATCH v4 00/10] Introduce new mode validation callbacks

2017-05-22 Thread Jose Abreu
Hi Daniel,


On 22-05-2017 08:56, Daniel Vetter wrote:
> On Fri, May 19, 2017 at 01:52:09AM +0100, Jose Abreu wrote:
>> This series is a follow up from the discussion at [1]. We start by
>> introducing crtc->mode_valid(), encoder->mode_valid() and
>> bridge->mode_valid() callbacks which will be used in followup
>> patches and also by cleaning the documentation a little bit. This
>> patch is available at [2] and the series depends on it.
>>
>> We proceed by introducing new helpers to call this new callbacks
>> at 1/10.
>>
>> At 2/10 a helper function is introduced that calls all mode_valid()
>> from a set of bridges.
>>
>> Next, at 3/10 we modify the connector probe helper so that only modes
>> which are supported by a given bridge+encoder+crtc combination are
>> probbed.
>>
>> At 4/10 we call all the mode_valid() callbacks for a given pipeline,
>> except the connector->mode_valid one, so that the mode is validated.
>> This is done before calling mode_fixup().
>>
>> Finally, from 5/10 to 10/10 we use the new callbacks in drivers that
>> can implement it.
>>
>> [1] 
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_patch_9702233_=DwIDAw=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=k-nrzbop60GvJmHyy9k4CfcDFfpSPQEZVA4lpNurIXo=rkPEIZmYcjgdVLR6jC_5SMwjNRc_Ye9r4RO95axhtwQ=
>>  
>> [2] 
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.freedesktop.org_archives_dri-2Ddevel_2017-2DMay_141761.html=DwIDAw=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=k-nrzbop60GvJmHyy9k4CfcDFfpSPQEZVA4lpNurIXo=z5gY8e9Yii5F4HDTa-MQojgFHenigkUt2aKPaGGVQLg=
>>  
>>
>> Jose Abreu (10):
>>   drm: Add drm_{crtc/encoder/connector}_mode_valid()
>>   drm: Introduce drm_bridge_mode_valid()
>>   drm: Use new mode_valid() helpers in connector probe helper
>>   drm: Use mode_valid() in atomic modeset
>>   drm: arc: Use crtc->mode_valid() callback
>>   drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback
>>   drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback
>>   drm/arm: malidp: Use crtc->mode_valid() callback
>>   drm/atmel-hlcdc: Use crtc->mode_valid() callback
>>   drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
> Looks all real nice, I think a bit more time to get acks/reviews/tested-by
> for the driver conversions and I'll go and vacuum this all up.

Yeah, I would really like someone to test these, especially the
drivers part.

>
> Thanks a lot for doing this.

No problem :) Thanks!

Best regards,
Jose Miguel Abreu

> -Daniel
>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
>>
>>  drivers/gpu/drm/arc/arcpgu_crtc.c  |  29 ---
>>  drivers/gpu/drm/arm/malidp_crtc.c  |  11 ++-
>>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c |   9 +--
>>  drivers/gpu/drm/bridge/analogix-anx78xx.c  |  13 ++-
>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c  |  40 +++---
>>  drivers/gpu/drm/drm_atomic_helper.c|  76 +-
>>  drivers/gpu/drm/drm_bridge.c   |  33 
>>  drivers/gpu/drm/drm_crtc_helper_internal.h |  13 +++
>>  drivers/gpu/drm/drm_probe_helper.c | 105 
>> -
>>  drivers/gpu/drm/imx/dw_hdmi-imx.c  |   4 +-
>>  drivers/gpu/drm/meson/meson_dw_hdmi.c  |   2 +-
>>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c|   2 +-
>>  drivers/gpu/drm/vc4/vc4_crtc.c |  13 ++-
>>  drivers/gpu/drm/vc4/vc4_dpi.c  |  13 ++-
>>  include/drm/bridge/dw_hdmi.h   |   2 +-
>>  include/drm/drm_bridge.h   |   2 +
>>  16 files changed, 280 insertions(+), 87 deletions(-)
>>
>> -- 
>> 1.9.1
>>
>>

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


[PATCH v4 07/10] drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback

2017-05-18 Thread Jose Abreu
Now that we have a callback to check if bridge supports a given mode
we can use it in Synopsys Designware HDMI bridge so that we restrict
the number of probbed modes to the ones we can actually display.

Also, there is no need to use mode_fixup() callback as mode_valid()
will handle the mode validation.

NOTE: Only compile tested
NOTE 2: I also had to change the pdata declaration of mode_valid
custom callback so that the passed modes are const. I also changed
in the platforms I found. Not even compiled it though.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 40 +
 drivers/gpu/drm/imx/dw_hdmi-imx.c   |  4 +--
 drivers/gpu/drm/meson/meson_dw_hdmi.c   |  2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  2 +-
 include/drm/bridge/dw_hdmi.h|  2 +-
 5 files changed, 17 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4e1f54a..864e946 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1881,24 +1881,6 @@ static int dw_hdmi_connector_get_modes(struct 
drm_connector *connector)
return ret;
 }
 
-static enum drm_mode_status
-dw_hdmi_connector_mode_valid(struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-   struct dw_hdmi *hdmi = container_of(connector,
-  struct dw_hdmi, connector);
-   enum drm_mode_status mode_status = MODE_OK;
-
-   /* We don't support double-clocked modes */
-   if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-   return MODE_BAD;
-
-   if (hdmi->plat_data->mode_valid)
-   mode_status = hdmi->plat_data->mode_valid(connector, mode);
-
-   return mode_status;
-}
-
 static void dw_hdmi_connector_force(struct drm_connector *connector)
 {
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
@@ -1924,7 +1906,6 @@ static void dw_hdmi_connector_force(struct drm_connector 
*connector)
 
 static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs 
= {
.get_modes = dw_hdmi_connector_get_modes,
-   .mode_valid = dw_hdmi_connector_mode_valid,
.best_encoder = drm_atomic_helper_best_encoder,
 };
 
@@ -1947,18 +1928,21 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
*bridge)
return 0;
 }
 
-static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *orig_mode,
- struct drm_display_mode *mode)
+static enum drm_mode_status dw_hdmi_bridge_mode_valid(struct drm_bridge 
*bridge,
+ const struct 
drm_display_mode *mode)
 {
struct dw_hdmi *hdmi = bridge->driver_private;
struct drm_connector *connector = >connector;
-   enum drm_mode_status status;
+   enum drm_mode_status mode_status = MODE_OK;
 
-   status = dw_hdmi_connector_mode_valid(connector, mode);
-   if (status != MODE_OK)
-   return false;
-   return true;
+   /* We don't support double-clocked modes */
+   if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+   return MODE_BAD;
+
+   if (hdmi->plat_data->mode_valid)
+   mode_status = hdmi->plat_data->mode_valid(connector, mode);
+
+   return mode_status;
 }
 
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
@@ -2002,7 +1986,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge 
*bridge)
.enable = dw_hdmi_bridge_enable,
.disable = dw_hdmi_bridge_disable,
.mode_set = dw_hdmi_bridge_mode_set,
-   .mode_fixup = dw_hdmi_bridge_mode_fixup,
+   .mode_valid = dw_hdmi_bridge_mode_valid,
 };
 
 static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index f039641..5f561c8 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -148,7 +148,7 @@ static int dw_hdmi_imx_atomic_check(struct drm_encoder 
*encoder,
 };
 
 static enum drm_mode_status imx6q_hdmi_mode_valid(struct drm_connector *con,
- struct drm_display_mode *mode)
+ const struct drm_display_mode 
*mode)
 {
if (mode->clock < 13500)
   

[PATCH v4 04/10] drm: Use mode_valid() in atomic modeset

2017-05-18 Thread Jose Abreu
This patches makes use of the new mode_valid() callbacks introduced
previously to validate the full video pipeline when modesetting.

This calls the connector->mode_valid(), encoder->mode_valid(),
bridge->mode_valid() and crtc->mode_valid() so that we can
make sure that the mode will be accepted in every components.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 76 +++--
 1 file changed, 73 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 8be9719..5a3c458 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 
+#include "drm_crtc_helper_internal.h"
 #include "drm_crtc_internal.h"
 
 /**
@@ -452,6 +453,69 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
return 0;
 }
 
+static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
+   struct drm_encoder *encoder,
+   struct drm_crtc *crtc,
+   struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] mode_valid() failed\n",
+   encoder->base.id, encoder->name);
+   return ret;
+   }
+
+   ret = drm_bridge_mode_valid(encoder->bridge, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
+   return ret;
+   }
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode_valid() failed\n",
+   crtc->base.id, crtc->name);
+   return ret;
+   }
+
+   return ret;
+}
+
+static int
+mode_valid(struct drm_atomic_state *state)
+{
+   struct drm_connector_state *conn_state;
+   struct drm_connector *connector;
+   int i;
+
+   for_each_new_connector_in_state(state, connector, conn_state, i) {
+   struct drm_encoder *encoder = conn_state->best_encoder;
+   struct drm_crtc *crtc = conn_state->crtc;
+   struct drm_crtc_state *crtc_state;
+   enum drm_mode_status mode_status;
+   struct drm_display_mode *mode;
+
+   if (!crtc || !encoder)
+   continue;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   if (!crtc_state)
+   continue;
+   if (!crtc_state->mode_changed && 
!crtc_state->connectors_changed)
+   continue;
+
+   mode = _state->mode;
+
+   mode_status = mode_valid_path(connector, encoder, crtc, mode);
+   if (mode_status != MODE_OK)
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 /**
  * drm_atomic_helper_check_modeset - validate state object for modeset changes
  * @dev: DRM device
@@ -466,13 +530,15 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
  * 2. _connector_helper_funcs.atomic_check to validate the connector state.
  * 3. If it's determined a modeset is needed then all connectors on the 
affected crtc
  *crtc are added and _connector_helper_funcs.atomic_check is run on 
them.
- * 4. _bridge_funcs.mode_fixup is called on all encoder bridges.
- * 5. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
+ * 4. _encoder_helper_funcs.mode_valid, _bridge_funcs.mode_valid and
+ *_crtc_helper_funcs.mode_valid are called on the affected components.
+ * 5. _bridge_funcs.mode_fixup is called on all encoder bridges.
+ * 6. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
  *This function is only called when the encoder will be part of a 
configured crtc,
  *it must not be used for implementing connector property validation.
  *If this function is NULL, _atomic_encoder_helper_funcs.mode_fixup is 
called
  *instead.
- * 6. _crtc_helper_funcs.mode_fixup is called last, to fix up the mode 
with crtc constraints.

[PATCH v4 10/10] drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks

2017-05-18 Thread Jose Abreu
Now that we have a callback to check if crtc and encoder supports a
given mode we can use it in vc4 so that we restrict the number of
probbed modes to the ones we can actually display.

Also, remove the mode_fixup() calls as these are no longer needed
because mode_valid() will be called before.

NOTE: Not even compiled tested

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 13 ++---
 drivers/gpu/drm/vc4/vc4_dpi.c  | 13 ++---
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index d86c8cc..aae8c56 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -556,18 +556,17 @@ static void vc4_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
 }
 
-static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
+   const struct drm_display_mode 
*mode)
 {
/* Do not allow doublescan modes from user space */
-   if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) {
+   if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n",
  crtc->base.id);
-   return false;
+   return MODE_NO_DBLESCAN;
}
 
-   return true;
+   return MODE_OK;
 }
 
 static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
@@ -877,7 +876,7 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
.mode_set_nofb = vc4_crtc_mode_set_nofb,
.disable = vc4_crtc_disable,
.enable = vc4_crtc_enable,
-   .mode_fixup = vc4_crtc_mode_fixup,
+   .mode_valid = vc4_crtc_mode_valid,
.atomic_check = vc4_crtc_atomic_check,
.atomic_flush = vc4_crtc_atomic_flush,
 };
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index c6d7039..61958ab 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -330,20 +330,19 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
*encoder)
}
 }
 
-static bool vc4_dpi_encoder_mode_fixup(struct drm_encoder *encoder,
-  const struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder 
*encoder,
+  const struct 
drm_display_mode *mode)
 {
-   if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
-   return false;
+   if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+   return MODE_NO_INTERLACE;
 
-   return true;
+   return MODE_OK;
 }
 
 static const struct drm_encoder_helper_funcs vc4_dpi_encoder_helper_funcs = {
.disable = vc4_dpi_encoder_disable,
.enable = vc4_dpi_encoder_enable,
-   .mode_fixup = vc4_dpi_encoder_mode_fixup,
+   .mode_valid = vc4_dpi_encoder_mode_valid,
 };
 
 static const struct of_device_id vc4_dpi_dt_match[] = {
-- 
1.9.1


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


[PATCH v4 02/10] drm: Introduce drm_bridge_mode_valid()

2017-05-18 Thread Jose Abreu
Introduce a new helper function which calls mode_valid() callback
for all bridges in an encoder chain.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/drm_bridge.c | 33 +
 include/drm/drm_bridge.h |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 86a7637..dc8cdfe 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
 EXPORT_SYMBOL(drm_bridge_mode_fixup);
 
 /**
+ * drm_bridge_mode_valid - validate the mode against all bridges in the
+ *encoder chain.
+ * @bridge: bridge control structure
+ * @mode: desired mode to be validated
+ *
+ * Calls _bridge_funcs.mode_valid for all the bridges in the encoder
+ * chain, starting from the first bridge to the last. If at least one bridge
+ * does not accept the mode the function returns the error code.
+ *
+ * Note: the bridge passed should be the one closest to the encoder.
+ *
+ * RETURNS:
+ * MODE_OK on success, drm_mode_status Enum error code on failure
+ */
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret = MODE_OK;
+
+   if (!bridge)
+   return ret;
+
+   if (bridge->funcs->mode_valid)
+   ret = bridge->funcs->mode_valid(bridge, mode);
+
+   if (ret != MODE_OK)
+   return ret;
+
+   return drm_bridge_mode_valid(bridge->next, mode);
+}
+EXPORT_SYMBOL(drm_bridge_mode_valid);
+
+/**
  * drm_bridge_disable - disables all bridges in the encoder chain
  * @bridge: bridge control structure
  *
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 00c6c36..8358eb3 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct 
drm_bridge *bridge,
 bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode);
 void drm_bridge_disable(struct drm_bridge *bridge);
 void drm_bridge_post_disable(struct drm_bridge *bridge);
 void drm_bridge_mode_set(struct drm_bridge *bridge,
-- 
1.9.1


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


[PATCH v4 06/10] drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback

2017-05-18 Thread Jose Abreu
Now that we have a callback to check if bridge supports a given mode
we can use it in Analogix bridge so that we restrict the number of
probbed modes to the ones we can actually display.

Also, there is no need to use mode_fixup() callback as mode_valid()
will handle the mode validation.

NOTE: Only compile tested.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/bridge/analogix-anx78xx.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c 
b/drivers/gpu/drm/bridge/analogix-anx78xx.c
index a2a8236..cf69a1c 100644
--- a/drivers/gpu/drm/bridge/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c
@@ -1061,18 +1061,17 @@ static int anx78xx_bridge_attach(struct drm_bridge 
*bridge)
return 0;
 }
 
-static bool anx78xx_bridge_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+enum drm_mode_status anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode 
*mode)
 {
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-   return false;
+   return MODE_NO_INTERLACE;
 
/* Max 1200p at 5.4 Ghz, one lane */
if (mode->clock > 154000)
-   return false;
+   return MODE_CLOCK_HIGH;
 
-   return true;
+   return MODE_OK;
 }
 
 static void anx78xx_bridge_disable(struct drm_bridge *bridge)
@@ -1129,7 +1128,7 @@ static void anx78xx_bridge_enable(struct drm_bridge 
*bridge)
 
 static const struct drm_bridge_funcs anx78xx_bridge_funcs = {
.attach = anx78xx_bridge_attach,
-   .mode_fixup = anx78xx_bridge_mode_fixup,
+   .mode_valid = anx78xx_bridge_mode_valid,
.disable = anx78xx_bridge_disable,
.mode_set = anx78xx_bridge_mode_set,
.enable = anx78xx_bridge_enable,
-- 
1.9.1


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


[PATCH v4 08/10] drm/arm: malidp: Use crtc->mode_valid() callback

2017-05-18 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in malidp so that we restrict the number of probbed
modes to the ones we can actually display.

Also, remove the mode_fixup() callback as this is no longer needed
because mode_valid() will be called before.

NOTE: Not even compiled tested

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/arm/malidp_crtc.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_crtc.c 
b/drivers/gpu/drm/arm/malidp_crtc.c
index 9446a67..4bb38a2 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -22,9 +22,8 @@
 #include "malidp_drv.h"
 #include "malidp_hw.h"
 
-static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc,
-  const struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status malidp_crtc_mode_valid(struct drm_crtc *crtc,
+  const struct 
drm_display_mode *mode)
 {
struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
struct malidp_hw_device *hwdev = malidp->dev;
@@ -40,11 +39,11 @@ static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc,
if (rate != req_rate) {
DRM_DEBUG_DRIVER("pxlclk doesn't support %ld Hz\n",
 req_rate);
-   return false;
+   return MODE_NOCLOCK;
}
}
 
-   return true;
+   return MODE_OK;
 }
 
 static void malidp_crtc_enable(struct drm_crtc *crtc)
@@ -408,7 +407,7 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = {
-   .mode_fixup = malidp_crtc_mode_fixup,
+   .mode_valid = malidp_crtc_mode_valid,
.enable = malidp_crtc_enable,
.disable = malidp_crtc_disable,
.atomic_check = malidp_crtc_atomic_check,
-- 
1.9.1


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


[PATCH v4 05/10] drm: arc: Use crtc->mode_valid() callback

2017-05-18 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in arcpgu so that we restrict the number of probbed
modes to the ones we can actually display.

This is specially useful because arcpgu crtc is responsible to set
a clock value in the commit() stage but unfortunatelly this clock
does not support all the needed ranges.

Also, remove the atomic_check() callback as mode_valid() callback
will be called before.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 29 ++---
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index ad9a959..99fbdae 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -64,6 +64,19 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
+enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode 
*mode)
+{
+   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
+   long rate, clk_rate = mode->clock * 1000;
+
+   rate = clk_round_rate(arcpgu->clk, clk_rate);
+   if (rate != clk_rate)
+   return MODE_NOCLOCK;
+
+   return MODE_OK;
+}
+
 static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -129,20 +142,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
  ~ARCPGU_CTRL_ENABLE_MASK);
 }
 
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
-struct drm_crtc_state *state)
-{
-   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-   struct drm_display_mode *mode = >adjusted_mode;
-   long rate, clk_rate = mode->clock * 1000;
-
-   rate = clk_round_rate(arcpgu->clk, clk_rate);
-   if (rate != clk_rate)
-   return -EINVAL;
-
-   return 0;
-}
-
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
  struct drm_crtc_state *state)
 {
@@ -158,6 +157,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
+   .mode_valid = arc_pgu_crtc_mode_valid,
.mode_set   = drm_helper_crtc_mode_set,
.mode_set_base  = drm_helper_crtc_mode_set_base,
.mode_set_nofb  = arc_pgu_crtc_mode_set_nofb,
@@ -165,7 +165,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
.disable= arc_pgu_crtc_disable,
.prepare= arc_pgu_crtc_disable,
.commit = arc_pgu_crtc_enable,
-   .atomic_check   = arc_pgu_crtc_atomic_check,
.atomic_begin   = arc_pgu_crtc_atomic_begin,
 };
 
-- 
1.9.1


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


[PATCH v4 00/10] Introduce new mode validation callbacks

2017-05-18 Thread Jose Abreu
This series is a follow up from the discussion at [1]. We start by
introducing crtc->mode_valid(), encoder->mode_valid() and
bridge->mode_valid() callbacks which will be used in followup
patches and also by cleaning the documentation a little bit. This
patch is available at [2] and the series depends on it.

We proceed by introducing new helpers to call this new callbacks
at 1/10.

At 2/10 a helper function is introduced that calls all mode_valid()
from a set of bridges.

Next, at 3/10 we modify the connector probe helper so that only modes
which are supported by a given bridge+encoder+crtc combination are
probbed.

At 4/10 we call all the mode_valid() callbacks for a given pipeline,
except the connector->mode_valid one, so that the mode is validated.
This is done before calling mode_fixup().

Finally, from 5/10 to 10/10 we use the new callbacks in drivers that
can implement it.

[1] https://patchwork.kernel.org/patch/9702233/
[2] https://lists.freedesktop.org/archives/dri-devel/2017-May/141761.html

Jose Abreu (10):
  drm: Add drm_{crtc/encoder/connector}_mode_valid()
  drm: Introduce drm_bridge_mode_valid()
  drm: Use new mode_valid() helpers in connector probe helper
  drm: Use mode_valid() in atomic modeset
  drm: arc: Use crtc->mode_valid() callback
  drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback
  drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback
  drm/arm: malidp: Use crtc->mode_valid() callback
  drm/atmel-hlcdc: Use crtc->mode_valid() callback
  drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks

Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

 drivers/gpu/drm/arc/arcpgu_crtc.c  |  29 ---
 drivers/gpu/drm/arm/malidp_crtc.c  |  11 ++-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c |   9 +--
 drivers/gpu/drm/bridge/analogix-anx78xx.c  |  13 ++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c  |  40 +++---
 drivers/gpu/drm/drm_atomic_helper.c|  76 +-
 drivers/gpu/drm/drm_bridge.c   |  33 
 drivers/gpu/drm/drm_crtc_helper_internal.h |  13 +++
 drivers/gpu/drm/drm_probe_helper.c | 105 -
 drivers/gpu/drm/imx/dw_hdmi-imx.c  |   4 +-
 drivers/gpu/drm/meson/meson_dw_hdmi.c  |   2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c|   2 +-
 drivers/gpu/drm/vc4/vc4_crtc.c |  13 ++-
 drivers/gpu/drm/vc4/vc4_dpi.c  |  13 ++-
 include/drm/bridge/dw_hdmi.h   |   2 +-
 include/drm/drm_bridge.h   |   2 +
 16 files changed, 280 insertions(+), 87 deletions(-)

-- 
1.9.1


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


[PATCH v4 03/10] drm: Use new mode_valid() helpers in connector probe helper

2017-05-18 Thread Jose Abreu
This changes the connector probe helper function to use the new
encoder->mode_valid(), bridge->mode_valid() and crtc->mode_valid()
helper callbacks to validate the modes.

The new callbacks are optional so the behaviour remains the same
if they are not implemented. If they are, then the code loops
through all the connector's encodersXbridgesXcrtcs and calls the
callback.

If at least a valid encoderXbridgeXcrtc combination is found which
accepts the mode then the function returns MODE_OK.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 67 +++---
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index f01abdc..00e6832 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -83,6 +83,61 @@
return MODE_OK;
 }
 
+static enum drm_mode_status
+drm_mode_validate_pipeline(struct drm_display_mode *mode,
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   uint32_t *ids = connector->encoder_ids;
+   enum drm_mode_status ret = MODE_OK;
+   unsigned int i;
+
+   /* Step 1: Validate against connector */
+   ret = drm_connector_mode_valid(connector, mode);
+   if (ret != MODE_OK)
+   return ret;
+
+   /* Step 2: Validate against encoders and crtcs */
+   for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+   struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+   struct drm_crtc *crtc;
+
+   if (!encoder)
+   continue;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   /* No point in continuing for crtc check as this encoder
+* will not accept the mode anyway. If all encoders
+* reject the mode then, at exit, ret will not be
+* MODE_OK. */
+   continue;
+   }
+
+   ret = drm_bridge_mode_valid(encoder->bridge, mode);
+   if (ret != MODE_OK) {
+   /* There is also no point in continuing for crtc check
+* here. */
+   continue;
+   }
+
+   drm_for_each_crtc(crtc, dev) {
+   if (!drm_encoder_crtc_ok(encoder, crtc))
+   continue;
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret == MODE_OK) {
+   /* If we get to this point there is at least
+* one combination of encoder+crtc that works
+* for this mode. Lets return now. */
+   return ret;
+   }
+   }
+   }
+
+   return ret;
+}
+
 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
 {
struct drm_cmdline_mode *cmdline_mode;
@@ -322,7 +377,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
  *- drm_mode_validate_flag() checks the modes against basic connector
  *  capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
  *- the optional _connector_helper_funcs.mode_valid helper can perform
- *  driver and/or hardware specific checks
+ *  driver and/or sink specific checks
+ *- the optional _crtc_helper_funcs.mode_valid,
+ *  _bridge_funcs.mode_valid and _encoder_helper_funcs.mode_valid
+ *  helpers can perform driver and/or source specific checks which are also
+ *  enforced by the modeset/atomic helpers
  *
  * 5. Any mode whose status is not OK is pruned from the connector's modes 
list,
  *accompanied by a debug message indicating the reason for the mode's
@@ -466,9 +525,9 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_flag(mode, mode_flags);
 
-   if (mode->status == MODE_OK && connector_funcs->mode_valid)
-   mode->status = connector_funcs->mode_valid(connector,
-  mode);
+   if (mode->status == MODE_OK)
+   mode->status = drm_mode_validate_pipeline(mode,

[PATCH v4 01/10] drm: Add drm_{crtc/encoder/connector}_mode_valid()

2017-05-18 Thread Jose Abreu
Add a new helper to call crtc->mode_valid, connector->mode_valid
and encoder->mode_valid callbacks.

Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jose Abreu <joab...@synopsys.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/drm_crtc_helper_internal.h | 13 ++
 drivers/gpu/drm/drm_probe_helper.c | 38 ++
 2 files changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_helper_internal.h 
b/drivers/gpu/drm/drm_crtc_helper_internal.h
index 28295e5..97dfe20 100644
--- a/drivers/gpu/drm/drm_crtc_helper_internal.h
+++ b/drivers/gpu/drm/drm_crtc_helper_internal.h
@@ -26,7 +26,11 @@
  * implementation details and are not exported to drivers.
  */
 
+#include 
+#include 
 #include 
+#include 
+#include 
 
 /* drm_fb_helper.c */
 #ifdef CONFIG_DRM_FBDEV_EMULATION
@@ -62,4 +66,13 @@ static inline int drm_dp_aux_register_devnode(struct 
drm_dp_aux *aux)
 static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
 {
 }
+
+/* drm_probe_helper.c */
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode);
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode 
*mode);
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode);
+
 #endif
diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 1b0c14a..f01abdc 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+
+#include "drm_crtc_helper_internal.h"
 
 /**
  * DOC: output probing helper overview
@@ -113,6 +116,41 @@ static int drm_helper_probe_add_cmdline_mode(struct 
drm_connector *connector)
return 1;
 }
 
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode)
+{
+   const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+   if (!crtc_funcs || !crtc_funcs->mode_valid)
+   return MODE_OK;
+
+   return crtc_funcs->mode_valid(crtc, mode);
+}
+
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode *mode)
+{
+   const struct drm_encoder_helper_funcs *encoder_funcs =
+   encoder->helper_private;
+
+   if (!encoder_funcs || !encoder_funcs->mode_valid)
+   return MODE_OK;
+
+   return encoder_funcs->mode_valid(encoder, mode);
+}
+
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+   const struct drm_connector_helper_funcs *connector_funcs =
+   connector->helper_private;
+
+   if (!connector_funcs || !connector_funcs->mode_valid)
+   return MODE_OK;
+
+   return connector_funcs->mode_valid(connector, mode);
+}
+
 #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
 /**
  * drm_kms_helper_poll_enable - re-enable output polling.
-- 
1.9.1


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


[PATCH v4 09/10] drm/atmel-hlcdc: Use crtc->mode_valid() callback

2017-05-18 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in atmel-hlcdc so that we restrict the number of probbed
modes to the ones we can actually display.

Also, remove the mode_fixup() callback as this is no longer needed
because mode_valid() will be called before.

NOTE: Not even compiled tested

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 53bfa56..bdfe74e 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -140,13 +140,12 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct 
drm_crtc *c)
   cfg);
 }
 
-static bool atmel_hlcdc_crtc_mode_fixup(struct drm_crtc *c,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status atmel_hlcdc_crtc_mode_valid(struct drm_crtc *c,
+   const struct 
drm_display_mode *mode)
 {
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
 
-   return atmel_hlcdc_dc_mode_valid(crtc->dc, adjusted_mode) == MODE_OK;
+   return atmel_hlcdc_dc_mode_valid(crtc->dc, mode);
 }
 
 static void atmel_hlcdc_crtc_disable(struct drm_crtc *c)
@@ -315,7 +314,7 @@ static void atmel_hlcdc_crtc_atomic_flush(struct drm_crtc 
*crtc,
 }
 
 static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = {
-   .mode_fixup = atmel_hlcdc_crtc_mode_fixup,
+   .mode_valid = atmel_hlcdc_crtc_mode_valid,
.mode_set = drm_helper_crtc_mode_set,
.mode_set_nofb = atmel_hlcdc_crtc_mode_set_nofb,
.mode_set_base = drm_helper_crtc_mode_set_base,
-- 
1.9.1


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


Re: [PATCH 2/2] drm/doc: Clarify mode_fixup vs. atomic_check a bit more

2017-05-16 Thread Jose Abreu
Hi Daniel,


On 15-05-2017 10:11, Daniel Vetter wrote:
> Brought up by both Laurent and Andrzej when reviewing the new
> ->mode_valid hooks. Since mode_fixup is just a simpler version of the
> much more generic atomic_check we can't really unify it with
> mode_valid. Most drivers should probably switch their current
> mode_fixup code to either the new mode_valid or the atomic_check
> hooks, but e.g. that doesn't exist yet for bridges, and for CRTCs the
> situation is a bit more complicated. Hence there's no clear
> equivalence between mode_fixup and mode_valid, even if it looks like
> that at first glance.
>
> Cc: Andrzej Hajda <a.ha...@samsung.com>
> Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Signed-off-by: Daniel Vetter <daniel.vet...@intel.com>

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  include/drm/drm_modeset_helper_vtables.h | 15 +--
>  1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/include/drm/drm_modeset_helper_vtables.h 
> b/include/drm/drm_modeset_helper_vtables.h
> index c72fca544a41..613b2a602b77 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -156,7 +156,11 @@ struct drm_crtc_helper_funcs {
>* allowed.
>*
>* Atomic drivers which need to inspect and adjust more state should
> -  * instead use the @atomic_check callback.
> +  * instead use the @atomic_check callback, but note that they're not
> +  * perfectly equivalent: @mode_valid is called from
> +  * drm_atomic_helper_check_modeset(), but @atomic_check is called from
> +  * drm_atomic_helper_check_planes(), because originally it was meant for
> +  * plane update checks only..
>*
>* Also beware that userspace can request its own custom modes, neither
>* core nor helpers filter modes to the list of probe modes reported by
> @@ -529,7 +533,9 @@ struct drm_encoder_helper_funcs {
>* allowed.
>*
>* Atomic drivers which need to inspect and adjust more state should
> -  * instead use the @atomic_check callback.
> +  * instead use the @atomic_check callback. If @atomic_check is used,
> +  * this hook isn't called since @atomic_check allows a strict superset
> +  * of the functionality of @mode_fixup.
>*
>* Also beware that userspace can request its own custom modes, neither
>* core nor helpers filter modes to the list of probe modes reported by
> @@ -716,6 +722,11 @@ struct drm_encoder_helper_funcs {
>* update the CRTC to match what the encoder needs for the requested
>* connector.
>*
> +  * Since this provides a strict superset of the functionality of
> +  * @mode_fixup (the requested and adjusted modes are both available
> +  * through the passed in  drm_crtc_state) @mode_fixup is not
> +  * called when @atomic_check is implemented.
> +  *
>* This function is used by the atomic helpers, but it is optional.
>*
>* NOTE:

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


Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper

2017-05-16 Thread Jose Abreu
Hi Laurent,


On 15-05-2017 08:05, Laurent Pinchart wrote:
> On Monday 15 May 2017 08:47:49 Daniel Vetter wrote:
>> On Sun, May 14, 2017 at 02:04:24PM +0300, Laurent Pinchart wrote:
>>> On Friday 12 May 2017 17:06:14 Jose Abreu wrote:
>>>> On 12-05-2017 10:35, Laurent Pinchart wrote:
>>>>> On Tuesday 09 May 2017 18:00:12 Jose Abreu wrote:
>>>>>> +if (mode->status == MODE_OK)
>>>>>> +mode->status = 
> drm_mode_validate_connector(connector,
>>>>>> 
> mode);
>>>>> I would reverse the arguments order to match the style of the other
>>>>> validation functions.
>>>> Hmm, I think it makes more sense to pass connector first and then
>>>> mode ...
>>> I disagree, as this function validates a mode against a pipeline, the same
>>> way the other validation functions validate a mode against other
>>> parameters, but it's your patch :-)
>> Call it drm_connector_validate_mode, because the first argument is
>> generally the object we operate on :-)
> But the function doesn't validate a mode for a connector, it validates a mode 
> for a complete pipeline...
>

Hmm, but note that in the same function there is
drm_mode_validate_size() and drm_mode_validate_flag() calls,
which take as first argument the mode and then the object to
validate (I hadn't seen this). So, maybe leave it as
drm_mode_validate_connector() as it takes a connector as argument
or change to drm_mode_validate_pipeline() as you said, or even
drm_mode_validate_datapath(), drm_mode_validate_videopath(),
drm_mode_validate_components() ?

Best regards,
Jose Miguel Abreu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] drm/doc: Document adjusted/request modes a bit better

2017-05-16 Thread Jose Abreu
Hi Daniel,


On 15-05-2017 10:11, Daniel Vetter wrote:
> Laurent started a massive discussion on IRC about this. Let's try to
> document common usage a bit better.
>
> v2: Cross-links+typos.
>
> Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> Cc: Jose Abreu <jose.ab...@synopsys.com>
> Signed-off-by: Daniel Vetter <daniel.vet...@intel.com>

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  include/drm/drm_bridge.h |  2 +-
>  include/drm/drm_crtc.h   | 28 +---
>  include/drm/drm_modeset_helper_vtables.h |  6 --
>  3 files changed, 30 insertions(+), 6 deletions(-)
>
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index f694de756ecf..f3ad38d0d621 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -91,7 +91,7 @@ struct drm_bridge_funcs {
>* the display chain, either the final _connector or the next
>* _bridge. The parameter adjusted_mode is the input mode the bridge
>* requires. It can be modified by this callback and does not need to
> -  * match mode.
> +  * match mode. See also _crtc_state.adjusted_mode for more details.
>*
>* This is the only hook that allows a bridge to reject a modeset. If
>* this function passes all other callbacks must succeed for this
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 06236b002c22..5f5d53973ca5 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -90,8 +90,6 @@ struct drm_plane_helper_funcs;
>   * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
>   * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of 
> attached connectors
>   * @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached 
> encoders
> - * @adjusted_mode: for use by helpers and drivers to compute adjusted mode 
> timings
> - * @mode: current mode timings
>   * @mode_blob: _property_blob for @mode
>   * @state: backpointer to global drm_atomic_state
>   *
> @@ -131,9 +129,33 @@ struct drm_crtc_state {
>   u32 connector_mask;
>   u32 encoder_mask;
>  
> - /* adjusted_mode: for use by helpers and drivers */
> + /**
> +  * @adjusted_mode:
> +  *
> +  * Internal display timings which can be used by the driver to handle
> +  * differences between the mode requested by userspace in @mode and what
> +  * is actually programmed into the hardware. It is purely driver
> +  * implementation defined what exactly this adjusted mode means. Usually
> +  * it is used to store the hardware display timings used between the
> +  * CRTC and encoder blocks.
> +  */
>   struct drm_display_mode adjusted_mode;
>  
> + /**
> +  * @mode:
> +  *
> +  * Display timings requested by userspace. The driver should try to
> +  * match the refresh rate as close as possible (but note that it's
> +  * undefined what exactly is close enough, e.g. some of the HDMI modes
> +  * only differ in less than 1% of the refresh rate). The active width
> +  * and height as observed by userspace for positioning planes must match
> +  * exactly.
> +  *
> +  * For external connectors where the sink isn't fixed (like with a
> +  * built-in panel), this mode here should match the physical mode on the
> +  * wire to the last details (i.e. including sync polarities and
> +  * everything).
> +  */
>   struct drm_display_mode mode;
>  
>   /* blob property to expose current mode to atomic userspace */
> diff --git a/include/drm/drm_modeset_helper_vtables.h 
> b/include/drm/drm_modeset_helper_vtables.h
> index 91d071ff1232..c72fca544a41 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -138,7 +138,8 @@ struct drm_crtc_helper_funcs {
>* encoders need to be fed with. Note that this is the inverse semantics
>* of the meaning for the _encoder and _bridge_funcs.mode_fixup
>* vfunc. If the CRTC cannot support the requested conversion from mode
> -  * to adjusted_mode it should reject the modeset.
> +  * to adjusted_mode it should reject the modeset. See also
> +  * _crtc_state.adjusted_mode for more details.
>*
>* This function is used by both legacy CRTC helpers and atomic helpers.
>* With atomic helpers it is optional.
> @@ -510,7 +511,8 @@ struct drm_encoder_helper_funcs {
>* mode is the display mode that should be fed t

Re: [PATCH v3 6/6] drm: arc: Use crtc->mode_valid() callback

2017-05-15 Thread Jose Abreu
Hi Daniel,


On 15-05-2017 16:52, Daniel Vetter wrote:
> On Mon, May 15, 2017 at 10:53:25AM +0200, Daniel Vetter wrote:
>> On Thu, May 11, 2017 at 10:06:02AM +0100, Jose Abreu wrote:
>>> Now that we have a callback to check if crtc supports a given mode
>>> we can use it in arcpgu so that we restrict the number of probbed
>>> modes to the ones we can actually display.
>>>
>>> This is specially useful because arcpgu crtc is responsible to set
>>> a clock value in the commit() stage but unfortunatelly this clock
>>> does not support all the needed ranges.
>>>
>>> Also, remove the atomic_check() callback as mode_valid() callback
>>> will be called before.
>>>
>>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>>> Cc: Carlos Palminha <palmi...@synopsys.com>
>>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>>> Cc: Dave Airlie <airl...@linux.ie>
>>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>>> Cc: Archit Taneja <arch...@codeaurora.org>
>> Btw for justifying your patch series a bit more, would be real sweet to
>> roll ->mode_valid out to more drivers. I see two easy cases:
>>
>> bridge/analogix-anx78xx.c: has a simple mode_fixup which really is just a
>> mode_valid callback
>>
>> bridge/synopsys/dw-hdmi.c: simply hand-rolls what you've done here, we
>> could move the connector_mode valid to the bridge and done.
>>
>> Care to type these 2 patches on top, just to make this a bit more useful
>> and a clearer case for merging?
> Aside: There's a pile more drivers (encoders and crtc drivers) which would
> similarly benefit and dont really look like they'd be hard to patch up:
> - malidp_crtc_mode_fixup
> - armada_drm_crtc_mode_fixup (armada isn't atomic, so forget this one)
> - atmel_hlcdc_crtc_mode_fixup
> - hdmi_mode_fixup in exynos_hdmi.c
> - vc4_crtc_mode_fixup and vc4_dpi_encoder_mode_fixup (they both just check
>   for interlaced modes, we could probably dump the same check in
>   connector->mode_valid).
>
> Plus the 2 bridge drivers. Everyone else does either something more
> complex, or something that's not quite correct.
> -Daniel

Sorry for being silent but I am away from office this week. I
will try to evaluate and add this in next version. In the
meantime I will review the documentation patches you sent. Thanks!

Best regards,
Jose Miguel Abreu

>
>> Thanks, Daniel
>>
>>> ---
>>>  drivers/gpu/drm/arc/arcpgu_crtc.c | 39 
>>> ---
>>>  1 file changed, 24 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
>>> b/drivers/gpu/drm/arc/arcpgu_crtc.c
>>> index ad9a959..01cae0a 100644
>>> --- a/drivers/gpu/drm/arc/arcpgu_crtc.c
>>> +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
>>> @@ -32,6 +32,18 @@
>>> { "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 },
>>>  };
>>>  
>>> +static bool arc_pgu_is_mode_valid(struct arcpgu_drm_private *arcpgu,
>>> + const struct drm_display_mode *mode)
>>> +{
>>> +   long rate, clk_rate = mode->clock * 1000;
>>> +
>>> +   rate = clk_round_rate(arcpgu->clk, clk_rate);
>>> +   if (rate != clk_rate)
>>> +   return false;
>>> +
>>> +   return true;
>>> +}
>>> +
>>>  static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>>>  {
>>> struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>>> @@ -64,6 +76,17 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>>> .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
>>>  };
>>>  
>>> +enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
>>> +const struct drm_display_mode 
>>> *mode)
>>> +{
>>> +   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>>> +
>>> +   if (!arc_pgu_is_mode_valid(arcpgu, mode))
>>> +   return MODE_NOCLOCK;
>>> +
>>> +   return MODE_OK;
>>> +}
>>> +
>>>  static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
>>>  {
>>> struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>>> @@ -129,20 +152,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
>>>

Re: [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback

2017-05-15 Thread Jose Abreu
Hi Laurent,


Sorry for the late reply.


On 12-05-2017 10:57, Laurent Pinchart wrote:
> Hi Jose,
>
> Thank you for the patch.
>
> On Tuesday 09 May 2017 18:00:15 Jose Abreu wrote:
>> Now that we have a callback to check if crtc supports a given mode
>> we can use it in arcpgu so that we restrict the number of probbed
>> modes to the ones we can actually display.
>>
>> This is specially useful because arcpgu crtc is responsible to set
>> a clock value in the commit() stage but unfortunatelly this clock
>> does not support all the needed ranges.
>>
>> Also, remove the atomic_check() callback as mode_valid() callback
>> will be called before.
>>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> ---
>>  drivers/gpu/drm/arc/arcpgu_crtc.c | 39 ---
>>  1 file changed, 24 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c
>> b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a959..01cae0a 100644
>> --- a/drivers/gpu/drm/arc/arcpgu_crtc.c
>> +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
>> @@ -32,6 +32,18 @@
>>  { "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 },
>>  };
>>
>> +static bool arc_pgu_is_mode_valid(struct arcpgu_drm_private *arcpgu,
>> +  const struct drm_display_mode *mode)
>> +{
>> +long rate, clk_rate = mode->clock * 1000;
>> +
>> +rate = clk_round_rate(arcpgu->clk, clk_rate);
>> +if (rate != clk_rate)
>> +return false;
> This isn't anything new introduced by this patch, but shouldn't drivers allow 
> for some margin in clock frequencies ? Surely if the mode requires a 
> 60.000.000 Hz frequency and the hardware can only generate 59.999.999 Hz or 
> 60.000.001 Hz we shouldn't fail. As far as I understand, this is something 
> the 
> mode_fixup() operation is supposed to handle, but the arc driver doesn't 
> implement it.

Its funny you mentioned this because I had exactly the same
discussion with Alexey (arcpgu maintainer) last Friday. Perhaps
we could think about a better way for this.

The main problem is that clock driver does not have all the
available clock values, so some modes will not have a compliant
clock value. Right now we are using clk_round_rate() and checking
if the return value matches the one we supplied, but as you
mentioned for 60vs59.94, for example, the mode will still fail to
commit because the clock will not be the same. We reached to the
conclusion that we could in this function have a max deviation
(which would be determined by max allowed tmds variation in HDMI
spec). What do you think?

Initially my idea was that clock driver should support this
variation and just return the same rate if the clock supported it
(i.e. if the deviation was not that much), but, as mentioned by
Alexey, the clock driver is agnostic of TMDS deviation, its just
a clock driver.

>
>> +return true;
>> +}
> Can't you inline this in arc_pgu_crtc_mode_valid() as there's a single caller 
> ?

Yeah, I will in next version. This was a leftover from previous
version where atomic_check() and mode_valid() did the same
validation.

Thanks!

Best regards,
Jose Miguel Abreu

>>  static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>>  {
>>  struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>> @@ -64,6 +76,17 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>>  .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
>>  };
>>
>> +enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
>> + const struct drm_display_mode 
> *mode)
>> +{
>> +struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>> +
>> +if (!arc_pgu_is_mode_valid(arcpgu, mode))
>> +return MODE_NOCLOCK;
>> +
>> +return MODE_OK;
>> +}
>> +
>>  static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
>>  {
>>  struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>> @@ -129,20 +152,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
>> ~ARCPGU_CTRL_ENABLE_MASK);
>>  }
>>
>> -static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
>> - 

Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper

2017-05-12 Thread Jose Abreu
Hi Laurent,


On 12-05-2017 10:35, Laurent Pinchart wrote:
> Hi Jose,
>
> Thank you for the patch.
>
> On Tuesday 09 May 2017 18:00:12 Jose Abreu wrote:
>> This changes the connector probe helper function to use the new
>> encoder->mode_valid() and crtc->mode_valid() helper callbacks to
>> validate the modes.
>>
>> The new callbacks are optional so the behaviour remains the same
>> if they are not implemented. If they are, then the code loops
>> through all the connector's encodersXcrtcs and calls the
>> callback.
>>
>> If at least a valid encoderXcrtc combination is found which
>> accepts the mode then the function returns MODE_OK.
>>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> ---
>>
>> Changes v1->v2:
>>  - Use new helpers suggested by Ville
>>  - Change documentation (Daniel)
>>
>>  drivers/gpu/drm/drm_probe_helper.c | 60 +--
>>  1 file changed, 57 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_probe_helper.c
>> b/drivers/gpu/drm/drm_probe_helper.c index 1b0c14a..de47413 100644
>> --- a/drivers/gpu/drm/drm_probe_helper.c
>> +++ b/drivers/gpu/drm/drm_probe_helper.c
>> @@ -39,6 +39,8 @@
>>  #include 
>>  #include 
>>
>> +#include "drm_crtc_internal.h"
>> +
>>  /**
>>   * DOC: output probing helper overview
>>   *
>> @@ -80,6 +82,54 @@
>>  return MODE_OK;
>>  }
>>
>> +static enum drm_mode_status
>> +drm_mode_validate_connector(struct drm_connector *connector,
>> +struct drm_display_mode *mode)
> This does more than validating the mode against the connector, it validates 
> it 
> against the whole pipeline. I would call the function 
> drm_mode_validate_pipeline() (or any other similar name).

Yeah, in previous version I had something similar but I changed
in order to address review comments. I can change again though...

>
>> +{
>> +struct drm_device *dev = connector->dev;
>> +uint32_t *ids = connector->encoder_ids;
>> +enum drm_mode_status ret = MODE_OK;
>> +unsigned int i;
>> +
>> +/* Step 1: Validate against connector */
>> +ret = drm_connector_mode_valid(connector, mode);
>> +if (ret != MODE_OK)
>> +return ret;
>> +
>> +/* Step 2: Validate against encoders and crtcs */
>> +for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
>> +struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
>> +struct drm_crtc *crtc;
>> +
>> +if (!encoder)
>> +continue;
>> +
>> +ret = drm_encoder_mode_valid(encoder, mode);
>> +if (ret != MODE_OK) {
>> +/* No point in continuing for crtc check as this 
> encoder
>> + * will not accept the mode anyway. If all encoders
>> + * reject the mode then, at exit, ret will not be
>> + * MODE_OK. */
>> +continue;
>> +}
>> +
>> +drm_for_each_crtc(crtc, dev) {
>> +if (!drm_encoder_crtc_ok(encoder, crtc))
>> +continue;
>> +
>> +ret = drm_crtc_mode_valid(crtc, mode);
>> +if (ret == MODE_OK) {
>> +/* If we get to this point there is at least
>> + * one combination of encoder+crtc that works
>> + * for this mode. Lets return now. */
>> +return ret;
>> +}
>> +}
>> +}
>> +
>> +return ret;
>> +}
>> +
>>  static int drm_helper_probe_add_cmdline_mode(struct drm_connector
>> *connector)
>>  {
>>  struct drm_cmdline_mode *cmdline_mode;
>> @@ -284,7 +334,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
>>   *- drm_mode_validate_flag() checks the modes against basic connector
>>   *  capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
>>   *- the optiona

Re: [PATCH] drm: Add crtc/encoder/bridge->mode_valid() callbacks

2017-05-12 Thread Jose Abreu
Hi Daniel,


On 12-05-2017 08:31, Daniel Vetter wrote:
> From: Jose Abreu <jose.ab...@synopsys.com>
>
> This adds a new callback to crtc, encoder and bridge helper functions
> called mode_valid(). This callback shall be implemented if the
> corresponding component has some sort of restriction in the modes
> that can be displayed. A NULL callback implicates that the component
> can display all the modes.
>
> We also change the documentation so that the new and old callbacks
> are correctly documented.
>
> Only the callbacks were implemented to simplify review process,
> following patches will make use of them.
>
> Changes in v2 from Daniel:
> - Update the warning about how modes aren't filtered in atomic_check -
>   the heleprs help out a lot more now.
> - Consistenly roll out that warning, crtc/encoder's atomic_check
>   missed it.
> - Sprinkle more links all over the place, so it's easier to see where
>   this stuff is used and how the differen hooks are related.
> - Note that ->mode_valid is optional everywhere.
> - Explain why the connector's mode_valid is special and does _not_ get
>   called in atomic_check.
>
> Signed-off-by: Jose Abreu <joab...@synopsys.com>
> Cc: Jose Abreu <joab...@synopsys.com>
> Cc: Carlos Palminha <palmi...@synopsys.com>
> Cc: Alexey Brodkin <abrod...@synopsys.com>
> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
> Cc: Dave Airlie <airl...@linux.ie>
> Cc: Andrzej Hajda <a.ha...@samsung.com>
> Cc: Archit Taneja <arch...@codeaurora.org>
> Signed-off-by: Daniel Vetter <daniel.vet...@ffwll.ch> (v2)

Thanks! Looks fine by me.

Reviewed-by: Jose Abreu <joab...@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  include/drm/drm_bridge.h |  31 +
>  include/drm/drm_modeset_helper_vtables.h | 116 
> ++-
>  2 files changed, 114 insertions(+), 33 deletions(-)
>
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index fdd82fcbf168..f694de756ecf 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -59,6 +59,31 @@ struct drm_bridge_funcs {
>   void (*detach)(struct drm_bridge *bridge);
>  
>   /**
> +  * @mode_valid:
> +  *
> +  * This callback is used to check if a specific mode is valid in this
> +  * bridge. This should be implemented if the bridge has some sort of
> +  * restriction in the modes it can display. For example, a given bridge
> +  * may be responsible to set a clock value. If the clock can not
> +  * produce all the values for the available modes then this callback
> +  * can be used to restrict the number of modes to only the ones that
> +  * can be displayed.
> +  *
> +  * This hook is used by the probe helpers to filter the mode list in
> +  * drm_helper_probe_single_connector_modes(), and it is used by the
> +  * atomic helpers to validate modes supplied by userspace in
> +  * drm_atomic_helper_check_modeset().
> +  *
> +  * This function is optional.
> +  *
> +  * RETURNS:
> +  *
> +  * drm_mode_status Enum
> +  */
> + enum drm_mode_status (*mode_valid)(struct drm_bridge *crtc,
> +const struct drm_display_mode *mode);
> +
> + /**
>* @mode_fixup:
>*
>* This callback is used to validate and adjust a mode. The paramater
> @@ -82,6 +107,12 @@ struct drm_bridge_funcs {
>* NOT touch any persistent state (hardware or software) or data
>* structures except the passed in @state parameter.
>*
> +  * Also beware that userspace can request its own custom modes, neither
> +  * core nor helpers filter modes to the list of probe modes reported by
> +  * the GETCONNECTOR IOCTL and stored in _connector.modes. To ensure
> +  * that modes are filtered consistently put any bridge constraints and
> +  * limits checks into @mode_valid.
> +  *
>* RETURNS:
>*
>* True if an acceptable configuration is possible, false if the modeset
> diff --git a/include/drm/drm_modeset_helper_vtables.h 
> b/include/drm/drm_modeset_helper_vtables.h
> index c01c328f6cc8..91d071ff1232 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -106,6 +106,31 @@ struct drm_crtc_helper_funcs {
>   void (*commit)(struct drm_crtc *crtc);
>  
>   /**
> +  * @mode_valid:
> +  *
> +  * This callback is used to check if a specific mode is valid in this
> +  * crtc. This

[PATCH v3 2/6] drm: Add drm_{crtc/encoder/connector}_mode_valid()

2017-05-11 Thread Jose Abreu
Add a new helper to call crtc->mode_valid, connector->mode_valid
and encoder->mode_valid callbacks.

Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

Changes v2->v3:
- Move helpers to drm_probe_helper.c (Daniel)
- Squeeze patches that introduce the helpers into a single
one (Daniel)

 drivers/gpu/drm/drm_crtc_helper_internal.h | 13 ++
 drivers/gpu/drm/drm_probe_helper.c | 38 ++
 2 files changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_helper_internal.h 
b/drivers/gpu/drm/drm_crtc_helper_internal.h
index 28295e5..97dfe20 100644
--- a/drivers/gpu/drm/drm_crtc_helper_internal.h
+++ b/drivers/gpu/drm/drm_crtc_helper_internal.h
@@ -26,7 +26,11 @@
  * implementation details and are not exported to drivers.
  */
 
+#include 
+#include 
 #include 
+#include 
+#include 
 
 /* drm_fb_helper.c */
 #ifdef CONFIG_DRM_FBDEV_EMULATION
@@ -62,4 +66,13 @@ static inline int drm_dp_aux_register_devnode(struct 
drm_dp_aux *aux)
 static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
 {
 }
+
+/* drm_probe_helper.c */
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode);
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode 
*mode);
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode);
+
 #endif
diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 1b0c14a..f01abdc 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+
+#include "drm_crtc_helper_internal.h"
 
 /**
  * DOC: output probing helper overview
@@ -113,6 +116,41 @@ static int drm_helper_probe_add_cmdline_mode(struct 
drm_connector *connector)
return 1;
 }
 
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode)
+{
+   const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+   if (!crtc_funcs || !crtc_funcs->mode_valid)
+   return MODE_OK;
+
+   return crtc_funcs->mode_valid(crtc, mode);
+}
+
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode *mode)
+{
+   const struct drm_encoder_helper_funcs *encoder_funcs =
+   encoder->helper_private;
+
+   if (!encoder_funcs || !encoder_funcs->mode_valid)
+   return MODE_OK;
+
+   return encoder_funcs->mode_valid(encoder, mode);
+}
+
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+   const struct drm_connector_helper_funcs *connector_funcs =
+   connector->helper_private;
+
+   if (!connector_funcs || !connector_funcs->mode_valid)
+   return MODE_OK;
+
+   return connector_funcs->mode_valid(connector, mode);
+}
+
 #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
 /**
  * drm_kms_helper_poll_enable - re-enable output polling.
-- 
1.9.1


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


[PATCH v3 4/6] drm: Use new mode_valid() helpers in connector probe helper

2017-05-11 Thread Jose Abreu
This changes the connector probe helper function to use the new
encoder->mode_valid(), bridge->mode_valid() and crtc->mode_valid()
helper callbacks to validate the modes.

The new callbacks are optional so the behaviour remains the same
if they are not implemented. If they are, then the code loops
through all the connector's encodersXbridgesXcrtcs and calls the
callback.

If at least a valid encoderXbridgeXcrtc combination is found which
accepts the mode then the function returns MODE_OK.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

Changes v2->v3:
- Call also bridge->mode_valid (Daniel)
Changes v1->v2:
- Use new helpers suggested by Ville
- Change documentation (Daniel)

 drivers/gpu/drm/drm_probe_helper.c | 65 --
 1 file changed, 62 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index f01abdc..84d660e 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -83,6 +83,61 @@
return MODE_OK;
 }
 
+static enum drm_mode_status
+drm_mode_validate_connector(struct drm_connector *connector,
+   struct drm_display_mode *mode)
+{
+   struct drm_device *dev = connector->dev;
+   uint32_t *ids = connector->encoder_ids;
+   enum drm_mode_status ret = MODE_OK;
+   unsigned int i;
+
+   /* Step 1: Validate against connector */
+   ret = drm_connector_mode_valid(connector, mode);
+   if (ret != MODE_OK)
+   return ret;
+
+   /* Step 2: Validate against encoders and crtcs */
+   for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+   struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+   struct drm_crtc *crtc;
+
+   if (!encoder)
+   continue;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   /* No point in continuing for crtc check as this encoder
+* will not accept the mode anyway. If all encoders
+* reject the mode then, at exit, ret will not be
+* MODE_OK. */
+   continue;
+   }
+
+   ret = drm_bridge_mode_valid(encoder->bridge, mode);
+   if (ret != MODE_OK) {
+   /* There is also no point in continuing for crtc check
+* here. */
+   continue;
+   }
+
+   drm_for_each_crtc(crtc, dev) {
+   if (!drm_encoder_crtc_ok(encoder, crtc))
+   continue;
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret == MODE_OK) {
+   /* If we get to this point there is at least
+* one combination of encoder+crtc that works
+* for this mode. Lets return now. */
+   return ret;
+   }
+   }
+   }
+
+   return ret;
+}
+
 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
 {
struct drm_cmdline_mode *cmdline_mode;
@@ -322,7 +377,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
  *- drm_mode_validate_flag() checks the modes against basic connector
  *  capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
  *- the optional _connector_helper_funcs.mode_valid helper can perform
- *  driver and/or hardware specific checks
+ *  driver and/or sink specific checks
+ *- the optional _crtc_helper_funcs.mode_valid,
+ *  _bridge_funcs.mode_valid and _encoder_helper_funcs.mode_valid
+ *  helpers can perform driver and/or source specific checks which are also
+ *  enforced by the modeset/atomic helpers
  *
  * 5. Any mode whose status is not OK is pruned from the connector's modes 
list,
  *accompanied by a debug message indicating the reason for the mode's
@@ -466,8 +525,8 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_flag(mode, mode_flags);
 
-   if (mode->status == MODE_OK && connector_funcs->mode_valid)
-   mode->status = connector_funcs->mode_valid(connector,
+   i

[PATCH v3 0/6] Introduce new mode validation callbacks

2017-05-11 Thread Jose Abreu
This series is a follow up from the discussion at [1]. We start by
introducing crtc->mode_valid(), encoder->mode_valid() and
bridge->mode_valid() callbacks which will be used in followup
patches and also by cleaning the documentation a little bit.

We proceed by introducing new helpers to call this new callbacks
at 2/6.

At 3/6 a helper function is introduced that calls all mode_valid()
from a set of bridges.

Next, at 4/6 we modify the connector probe helper so that only modes
which are supported by a given bridge+encoder+crtc combination are
probbed.

At 5/6 we call all the mode_valid() callbacks for a given pipeline,
except the connector->mode_valid one, so that the mode is validated.
This is done before calling mode_fixup().

Finally, at 6/6 we use the new crtc->mode_valid() callback in arcpgu
and remove the atomic_check() callback.

[1] https://patchwork.kernel.org/patch/9702233/

Jose Abreu (6):
  drm: Add crtc/encoder/bridge->mode_valid() callbacks
  drm: Add drm_{crtc/encoder/connector}_mode_valid()
  drm: Introduce drm_bridge_mode_valid()
  drm: Use new mode_valid() helpers in connector probe helper
  drm: Use mode_valid() in atomic modeset
  drm: arc: Use crtc->mode_valid() callback

Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>

 drivers/gpu/drm/arc/arcpgu_crtc.c  |  39 ++
 drivers/gpu/drm/drm_atomic_helper.c|  76 +++-
 drivers/gpu/drm/drm_bridge.c   |  33 +
 drivers/gpu/drm/drm_crtc_helper_internal.h |  13 
 drivers/gpu/drm/drm_probe_helper.c | 103 ++-
 include/drm/drm_bridge.h   |  22 ++
 include/drm/drm_modeset_helper_vtables.h   | 110 ++---
 7 files changed, 348 insertions(+), 48 deletions(-)

-- 
1.9.1


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


[PATCH v3 6/6] drm: arc: Use crtc->mode_valid() callback

2017-05-11 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in arcpgu so that we restrict the number of probbed
modes to the ones we can actually display.

This is specially useful because arcpgu crtc is responsible to set
a clock value in the commit() stage but unfortunatelly this clock
does not support all the needed ranges.

Also, remove the atomic_check() callback as mode_valid() callback
will be called before.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 39 ---
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index ad9a959..01cae0a 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -32,6 +32,18 @@
{ "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 },
 };
 
+static bool arc_pgu_is_mode_valid(struct arcpgu_drm_private *arcpgu,
+ const struct drm_display_mode *mode)
+{
+   long rate, clk_rate = mode->clock * 1000;
+
+   rate = clk_round_rate(arcpgu->clk, clk_rate);
+   if (rate != clk_rate)
+   return false;
+
+   return true;
+}
+
 static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -64,6 +76,17 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
+enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode 
*mode)
+{
+   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
+
+   if (!arc_pgu_is_mode_valid(arcpgu, mode))
+   return MODE_NOCLOCK;
+
+   return MODE_OK;
+}
+
 static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -129,20 +152,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
  ~ARCPGU_CTRL_ENABLE_MASK);
 }
 
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
-struct drm_crtc_state *state)
-{
-   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-   struct drm_display_mode *mode = >adjusted_mode;
-   long rate, clk_rate = mode->clock * 1000;
-
-   rate = clk_round_rate(arcpgu->clk, clk_rate);
-   if (rate != clk_rate)
-   return -EINVAL;
-
-   return 0;
-}
-
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
  struct drm_crtc_state *state)
 {
@@ -158,6 +167,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
+   .mode_valid = arc_pgu_crtc_mode_valid,
.mode_set   = drm_helper_crtc_mode_set,
.mode_set_base  = drm_helper_crtc_mode_set_base,
.mode_set_nofb  = arc_pgu_crtc_mode_set_nofb,
@@ -165,7 +175,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
.disable= arc_pgu_crtc_disable,
.prepare= arc_pgu_crtc_disable,
.commit = arc_pgu_crtc_enable,
-   .atomic_check   = arc_pgu_crtc_atomic_check,
.atomic_begin   = arc_pgu_crtc_atomic_begin,
 };
 
-- 
1.9.1


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


[PATCH v3 1/6] drm: Add crtc/encoder/bridge->mode_valid() callbacks

2017-05-11 Thread Jose Abreu
This adds a new callback to crtc, encoder and bridge helper functions
called mode_valid(). This callback shall be implemented if the
corresponding component has some sort of restriction in the modes
that can be displayed. A NULL callback implicates that the component
can display all the modes.

We also change the documentation so that the new and old callbacks
are correctly documented.

Only the callbacks were implemented to simplify review process,
following patches will make use of them.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

Changes v2->v3:
- Try to document the callbacks a little bit better and
review current documentation (Daniel)
Changes v1->v2:
- Change description of connector->mode_valid() (Daniel)

 include/drm/drm_bridge.h |  20 ++
 include/drm/drm_modeset_helper_vtables.h | 110 +++
 2 files changed, 103 insertions(+), 27 deletions(-)

diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index fdd82fc..00c6c36 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -59,6 +59,26 @@ struct drm_bridge_funcs {
void (*detach)(struct drm_bridge *bridge);
 
/**
+* @mode_valid:
+*
+* This callback is used to check if a specific mode is valid in this
+* bridge. This should be implemented if the bridge has some sort of
+* restriction in the modes it can display. For example, a given bridge
+* may be responsible to set a clock value. If the clock can not
+* produce all the values for the available modes then this callback
+* can be used to restrict the number of modes to only the ones that
+* can be displayed.
+*
+* This is called at mode probe and at atomic check phase.
+*
+* RETURNS:
+*
+* drm_mode_status Enum
+*/
+   enum drm_mode_status (*mode_valid)(struct drm_bridge *crtc,
+  const struct drm_display_mode *mode);
+
+   /**
 * @mode_fixup:
 *
 * This callback is used to validate and adjust a mode. The paramater
diff --git a/include/drm/drm_modeset_helper_vtables.h 
b/include/drm/drm_modeset_helper_vtables.h
index c01c328..b07b7cd 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -106,14 +106,37 @@ struct drm_crtc_helper_funcs {
void (*commit)(struct drm_crtc *crtc);
 
/**
+* @mode_valid:
+*
+* This callback is used to check if a specific mode is valid in this
+* crtc. This should be implemented if the crtc has some sort of
+* restriction in the modes it can display. For example, a given crtc
+* may be responsible to set a clock value. If the clock can not
+* produce all the values for the available modes then this callback
+* can be used to restrict the number of modes to only the ones that
+* can be displayed.
+*
+* This is called at mode probe and at atomic check phase.
+*
+* RETURNS:
+*
+* drm_mode_status Enum
+*/
+   enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+  const struct drm_display_mode *mode);
+
+   /**
 * @mode_fixup:
 *
-* This callback is used to validate a mode. The parameter mode is the
-* display mode that userspace requested, adjusted_mode is the mode the
-* encoders need to be fed with. Note that this is the inverse semantics
-* of the meaning for the _encoder and _bridge_funcs.mode_fixup
-* vfunc. If the CRTC cannot support the requested conversion from mode
-* to adjusted_mode it should reject the modeset.
+* This callback is used to do the validation of an adjusted mode in the
+* crtc. The parameter mode is the display mode that userspace 
requested,
+* adjusted_mode is the mode the encoders need to be fed with. Note that
+* this is the inverse semantics of the meaning for the _encoder and
+* _bridge_funcs.mode_fixup vfunc. If the CRTC cannot support the
+* requested conversion from mode to adjusted_mode it should reject the
+* modeset. Also note that initial validation of a mode supplied by
+* userspace should be done in _crtc_helper_funcs.mode_valid and not
+* in this callback.
 *
 * This function is used by both legacy CRTC helpers and atomic helpers.
 * With atomic helpers it is opt

[PATCH v3 3/6] drm: Introduce drm_bridge_mode_valid()

2017-05-11 Thread Jose Abreu
Introduce a new helper function which calls mode_valid() callback
for all bridges in an encoder chain.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---
 drivers/gpu/drm/drm_bridge.c | 33 +
 include/drm/drm_bridge.h |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 86a7637..dc8cdfe 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
 EXPORT_SYMBOL(drm_bridge_mode_fixup);
 
 /**
+ * drm_bridge_mode_valid - validate the mode against all bridges in the
+ *encoder chain.
+ * @bridge: bridge control structure
+ * @mode: desired mode to be validated
+ *
+ * Calls _bridge_funcs.mode_valid for all the bridges in the encoder
+ * chain, starting from the first bridge to the last. If at least one bridge
+ * does not accept the mode the function returns the error code.
+ *
+ * Note: the bridge passed should be the one closest to the encoder.
+ *
+ * RETURNS:
+ * MODE_OK on success, drm_mode_status Enum error code on failure
+ */
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret = MODE_OK;
+
+   if (!bridge)
+   return ret;
+
+   if (bridge->funcs->mode_valid)
+   ret = bridge->funcs->mode_valid(bridge, mode);
+
+   if (ret != MODE_OK)
+   return ret;
+
+   return drm_bridge_mode_valid(bridge->next, mode);
+}
+EXPORT_SYMBOL(drm_bridge_mode_valid);
+
+/**
  * drm_bridge_disable - disables all bridges in the encoder chain
  * @bridge: bridge control structure
  *
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 00c6c36..8358eb3 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct 
drm_bridge *bridge,
 bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode);
 void drm_bridge_disable(struct drm_bridge *bridge);
 void drm_bridge_post_disable(struct drm_bridge *bridge);
 void drm_bridge_mode_set(struct drm_bridge *bridge,
-- 
1.9.1


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


[PATCH v3 5/6] drm: Use mode_valid() in atomic modeset

2017-05-11 Thread Jose Abreu
This patches makes use of the new mode_valid() callbacks introduced
previously to validate the full video pipeline when modesetting.

This calls the encoder->mode_valid(), bridge->mode_valid() and
crtc->mode_valid() so that we can make sure that the mode will
be accepted in every components.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

Changes v1->v2:
- Removed call to connector->mode_valid (Ville, Daniel)
- Change function name (Ville)
- Use for_each_new_connector_in_state (Ville)
- Do not validate if connector and mode didn't change (Ville)
- Use new helpers to call mode_valid

 drivers/gpu/drm/drm_atomic_helper.c | 76 +++--
 1 file changed, 73 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 8be9719..5a3c458 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 
+#include "drm_crtc_helper_internal.h"
 #include "drm_crtc_internal.h"
 
 /**
@@ -452,6 +453,69 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
return 0;
 }
 
+static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
+   struct drm_encoder *encoder,
+   struct drm_crtc *crtc,
+   struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] mode_valid() failed\n",
+   encoder->base.id, encoder->name);
+   return ret;
+   }
+
+   ret = drm_bridge_mode_valid(encoder->bridge, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
+   return ret;
+   }
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode_valid() failed\n",
+   crtc->base.id, crtc->name);
+   return ret;
+   }
+
+   return ret;
+}
+
+static int
+mode_valid(struct drm_atomic_state *state)
+{
+   struct drm_connector_state *conn_state;
+   struct drm_connector *connector;
+   int i;
+
+   for_each_new_connector_in_state(state, connector, conn_state, i) {
+   struct drm_encoder *encoder = conn_state->best_encoder;
+   struct drm_crtc *crtc = conn_state->crtc;
+   struct drm_crtc_state *crtc_state;
+   enum drm_mode_status mode_status;
+   struct drm_display_mode *mode;
+
+   if (!crtc || !encoder)
+   continue;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   if (!crtc_state)
+   continue;
+   if (!crtc_state->mode_changed && 
!crtc_state->connectors_changed)
+   continue;
+
+   mode = _state->mode;
+
+   mode_status = mode_valid_path(connector, encoder, crtc, mode);
+   if (mode_status != MODE_OK)
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 /**
  * drm_atomic_helper_check_modeset - validate state object for modeset changes
  * @dev: DRM device
@@ -466,13 +530,15 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
  * 2. _connector_helper_funcs.atomic_check to validate the connector state.
  * 3. If it's determined a modeset is needed then all connectors on the 
affected crtc
  *crtc are added and _connector_helper_funcs.atomic_check is run on 
them.
- * 4. _bridge_funcs.mode_fixup is called on all encoder bridges.
- * 5. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
+ * 4. _encoder_helper_funcs.mode_valid, _bridge_funcs.mode_valid and
+ *_crtc_helper_funcs.mode_valid are called on the affected components.
+ * 5. _bridge_funcs.mode_fixup is called on all encoder bridges.
+ * 6. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
  *This function is only called when the encoder will be part of a 
configured crtc,
  *it must not be used for implementing connector property validation.
  *If this function is NULL, _atomic_encoder_helper_funcs.mode_fixup is 
called
  *instead.
- * 6. _crtc_helper_funcs.m

Re: [PATCH v2 1/8] drm: Add crtc/encoder/bridge->mode_valid() callbacks

2017-05-10 Thread Jose Abreu
Hi Daniel,


On 10-05-2017 09:03, Daniel Vetter wrote:
> On Tue, May 09, 2017 at 06:00:08PM +0100, Jose Abreu wrote:
>> This adds a new callback to crtc, encoder and bridge helper functions
>> called mode_valid(). This callback shall be implemented if the
>> corresponding component has some sort of restriction in the modes
>> that can be displayed. A NULL callback implicates that the component
>> can display all the modes.
>>
>> We also change the description of connector->mode_valid() callback
>> so that it matches the existing behaviour: It is never called in
>> atomic check phase.
>>
>> Only the callbacks were implemented to simplify review process,
>> following patches will make use of them.
>>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> ---
>>
>> Changes v1->v2:
>>  - Change description of connector->mode_valid() (Daniel)
>>
>>  include/drm/drm_bridge.h | 20 ++
>>  include/drm/drm_modeset_helper_vtables.h | 45 
>> 
>>  2 files changed, 65 insertions(+)
>>
>> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
>> index fdd82fc..00c6c36 100644
>> --- a/include/drm/drm_bridge.h
>> +++ b/include/drm/drm_bridge.h
>> @@ -59,6 +59,26 @@ struct drm_bridge_funcs {
>>  void (*detach)(struct drm_bridge *bridge);
>>  
>>  /**
>> + * @mode_valid:
>> + *
>> + * This callback is used to check if a specific mode is valid in this
>> + * bridge. This should be implemented if the bridge has some sort of
>> + * restriction in the modes it can display. For example, a given bridge
>> + * may be responsible to set a clock value. If the clock can not
>> + * produce all the values for the available modes then this callback
>> + * can be used to restrict the number of modes to only the ones that
>> + * can be displayed.
>> + *
>> + * This is called at mode probe and at atomic check phase.
>> + *
>> + * RETURNS:
>> + *
>> + * drm_mode_status Enum
>> + */
>> +enum drm_mode_status (*mode_valid)(struct drm_bridge *crtc,
>> +   const struct drm_display_mode *mode);
>> +
>> +/**
>>   * @mode_fixup:
>>   *
>>   * This callback is used to validate and adjust a mode. The paramater
>> diff --git a/include/drm/drm_modeset_helper_vtables.h 
>> b/include/drm/drm_modeset_helper_vtables.h
>> index c01c328..eec2c70 100644
>> --- a/include/drm/drm_modeset_helper_vtables.h
>> +++ b/include/drm/drm_modeset_helper_vtables.h
>> @@ -106,6 +106,26 @@ struct drm_crtc_helper_funcs {
>>  void (*commit)(struct drm_crtc *crtc);
>>  
>>  /**
>> + * @mode_valid:
>> + *
>> + * This callback is used to check if a specific mode is valid in this
>> + * crtc. This should be implemented if the crtc has some sort of
>> + * restriction in the modes it can display. For example, a given crtc
>> + * may be responsible to set a clock value. If the clock can not
>> + * produce all the values for the available modes then this callback
>> + * can be used to restrict the number of modes to only the ones that
>> + * can be displayed.
>> + *
>> + * This is called at mode probe and at atomic check phase.
>> + *
>> + * RETURNS:
>> + *
>> + * drm_mode_status Enum
>> + */
>> +enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
>> +   const struct drm_display_mode *mode);
>> +
>> +/**
>>   * @mode_fixup:
>>   *
>>   * This callback is used to validate a mode. The parameter mode is the
>> @@ -457,6 +477,26 @@ struct drm_encoder_helper_funcs {
>>  void (*dpms)(struct drm_encoder *encoder, int mode);
>>  
>>  /**
>> + * @mode_valid:
>> + *
>> + * This callback is used to check if a specific mode is valid in this
>> + * encoder. This should be implemented if the encoder has some sort
>> + * of restriction in the modes it can displa

Re: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()

2017-05-10 Thread Jose Abreu
Hi Daniel,


On 10-05-2017 08:59, Daniel Vetter wrote:
> On Tue, May 09, 2017 at 06:00:09PM +0100, Jose Abreu wrote:
>> Add a new helper to call crtc->mode_valid callback.
>>
>> Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> ---
>>  drivers/gpu/drm/drm_crtc.c  | 22 ++
>>  drivers/gpu/drm/drm_crtc_internal.h |  3 +++
>>  2 files changed, 25 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>> index 5af25ce..07ae705 100644
>> --- a/drivers/gpu/drm/drm_crtc.c
>> +++ b/drivers/gpu/drm/drm_crtc.c
>> @@ -38,6 +38,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -741,3 +742,24 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object 
>> *obj,
>>  
>>  return ret;
>>  }
>> +
>> +/**
>> + * drm_crtc_mode_valid - call crtc->mode_valid callback, if any.
>> + * @crtc: crtc
>> + * @mode: mode to be validated
>> + *
>> + * If no mode_valid callback is available this will return MODE_OK.
>> + *
>> + * Returns: drm_mode_status Enum
>> + */
>> +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
>> + const struct drm_display_mode *mode)
>> +{
>> +const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
> This is clearly a helper func, but you place it into the core and
> EXPORT_SYMBOL it. Imo this should be entirely internal to the helpers,
> perhaps just stuff them all into drm_probe_helpers.c? Header file would be
> drm_crtc_helper_internal.h.

Yeah, at first I was not planning to export it but then I saw
that drm_bridge_mode_fixup() is exported (and is in drm_bridge.c)
so it kind of felt right to place this in drm_crtc.c. Anyway, I
will move them to drm_probe_helpers.c, indeed there is no point
in exporting this.

>
> That also means no need for kernel-doc (only the driver api is formally
> documented) and then these 3 patches are so tiny it's better to squash
> them into the patch that adds their users.

Ok, will remove the docs but I think its better to have a single
patch which adds all the helpers so that I can use the
suggested-by tag. Thanks!

Best regards,
Jose Miguel Abreu

>
> Thanks, Daniel
>> +
>> +if (!crtc_funcs || !crtc_funcs->mode_valid)
>> +return MODE_OK;
>> +
>> +return crtc_funcs->mode_valid(crtc, mode);
>> +}
>> +EXPORT_SYMBOL(drm_crtc_mode_valid);
>> diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
>> b/drivers/gpu/drm/drm_crtc_internal.h
>> index d077c54..3800abd 100644
>> --- a/drivers/gpu/drm/drm_crtc_internal.h
>> +++ b/drivers/gpu/drm/drm_crtc_internal.h
>> @@ -45,6 +45,9 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
>>  
>>  struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
>>  
>> +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
>> + const struct drm_display_mode *mode);
>> +
>>  /* IOCTLs */
>>  int drm_mode_getcrtc(struct drm_device *dev,
>>   void *data, struct drm_file *file_priv);
>> -- 
>> 1.9.1
>>
>>

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


Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

2017-05-10 Thread Jose Abreu
Hi Ville,


On 10-05-2017 15:01, Jose Abreu wrote:
> Hi Ville,
>
>
> On 10-05-2017 14:41, Ville Syrjälä wrote:
>> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
>>> Introduce a new helper function which calls mode_valid() callback
>>> for all bridges in an encoder chain.
>>>
>>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>>> Cc: Carlos Palminha <palmi...@synopsys.com>
>>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>>> Cc: Dave Airlie <airl...@linux.ie>
>>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>>> Cc: Archit Taneja <arch...@codeaurora.org>
>>> ---
>>>  drivers/gpu/drm/drm_bridge.c | 33 +
>>>  include/drm/drm_bridge.h |  2 ++
>>>  2 files changed, 35 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>>> index 86a7637..dc8cdfe 100644
>>> --- a/drivers/gpu/drm/drm_bridge.c
>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
>>>  
>>>  /**
>>> + * drm_bridge_mode_valid - validate the mode against all bridges in the
>>> + *encoder chain.
>>> + * @bridge: bridge control structure
>>> + * @mode: desired mode to be validated
>>> + *
>>> + * Calls _bridge_funcs.mode_valid for all the bridges in the encoder
>>> + * chain, starting from the first bridge to the last. If at least one 
>>> bridge
>>> + * does not accept the mode the function returns the error code.
>>> + *
>>> + * Note: the bridge passed should be the one closest to the encoder.
>>> + *
>>> + * RETURNS:
>>> + * MODE_OK on success, drm_mode_status Enum error code on failure
>>> + */
>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>>> +  const struct drm_display_mode *mode)
>>> +{
>>> +   enum drm_mode_status ret = MODE_OK;
>>> +
>>> +   if (!bridge)
>>> +   return ret;
>>> +
>>> +   if (bridge->funcs->mode_valid)
>>> +   ret = bridge->funcs->mode_valid(bridge, mode);
>>> +
>>> +   if (ret != MODE_OK)
>>> +   return ret;
>>> +
>>> +   return drm_bridge_mode_valid(bridge->next, mode);
>> Looks like it should be pretty trivial to avoid the recursion.
>>
>> Am I correct in interpreting this that bridges have some kind of
>> a hand rolled linked list implementation? Reusing the standard
>> linked lists would allow you to use list_for_each() etc.
> I reused the drm_bridge_mode_fixup but now I see how its done
> like that: so that the fixup is propagated in the correct order.
> As for mode_valid we just need to check if ret != MODE_OK then I
> think we can use the list_for_each_entry(bridge->list).

Oops, I got this wrong sorry. I meant there is a list but its for
all the system bridges. This is a "custom" linked list yeah.

Best regards,
Jose Miguel Abreu

>
> Best regards,
> Jose Miguel Abreu
>
>>> +}
>>> +EXPORT_SYMBOL(drm_bridge_mode_valid);
>>> +
>>> +/**
>>>   * drm_bridge_disable - disables all bridges in the encoder chain
>>>   * @bridge: bridge control structure
>>>   *
>>> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
>>> index 00c6c36..8358eb3 100644
>>> --- a/include/drm/drm_bridge.h
>>> +++ b/include/drm/drm_bridge.h
>>> @@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, 
>>> struct drm_bridge *bridge,
>>>  bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>> const struct drm_display_mode *mode,
>>> struct drm_display_mode *adjusted_mode);
>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>>> +  const struct drm_display_mode *mode);
>>>  void drm_bridge_disable(struct drm_bridge *bridge);
>>>  void drm_bridge_post_disable(struct drm_bridge *bridge);
>>>  void drm_bridge_mode_set(struct drm_bridge *bridge,
>>> -- 
>>> 1.9.1
>>>

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


Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

2017-05-10 Thread Jose Abreu
Hi Ville,


On 10-05-2017 14:41, Ville Syrjälä wrote:
> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
>> Introduce a new helper function which calls mode_valid() callback
>> for all bridges in an encoder chain.
>>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> ---
>>  drivers/gpu/drm/drm_bridge.c | 33 +
>>  include/drm/drm_bridge.h |  2 ++
>>  2 files changed, 35 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>> index 86a7637..dc8cdfe 100644
>> --- a/drivers/gpu/drm/drm_bridge.c
>> +++ b/drivers/gpu/drm/drm_bridge.c
>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
>>  
>>  /**
>> + * drm_bridge_mode_valid - validate the mode against all bridges in the
>> + * encoder chain.
>> + * @bridge: bridge control structure
>> + * @mode: desired mode to be validated
>> + *
>> + * Calls _bridge_funcs.mode_valid for all the bridges in the encoder
>> + * chain, starting from the first bridge to the last. If at least one bridge
>> + * does not accept the mode the function returns the error code.
>> + *
>> + * Note: the bridge passed should be the one closest to the encoder.
>> + *
>> + * RETURNS:
>> + * MODE_OK on success, drm_mode_status Enum error code on failure
>> + */
>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>> +   const struct drm_display_mode *mode)
>> +{
>> +enum drm_mode_status ret = MODE_OK;
>> +
>> +if (!bridge)
>> +return ret;
>> +
>> +if (bridge->funcs->mode_valid)
>> +ret = bridge->funcs->mode_valid(bridge, mode);
>> +
>> +if (ret != MODE_OK)
>> +return ret;
>> +
>> +return drm_bridge_mode_valid(bridge->next, mode);
> Looks like it should be pretty trivial to avoid the recursion.
>
> Am I correct in interpreting this that bridges have some kind of
> a hand rolled linked list implementation? Reusing the standard
> linked lists would allow you to use list_for_each() etc.

I reused the drm_bridge_mode_fixup but now I see how its done
like that: so that the fixup is propagated in the correct order.
As for mode_valid we just need to check if ret != MODE_OK then I
think we can use the list_for_each_entry(bridge->list).

Best regards,
Jose Miguel Abreu

>
>> +}
>> +EXPORT_SYMBOL(drm_bridge_mode_valid);
>> +
>> +/**
>>   * drm_bridge_disable - disables all bridges in the encoder chain
>>   * @bridge: bridge control structure
>>   *
>> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
>> index 00c6c36..8358eb3 100644
>> --- a/include/drm/drm_bridge.h
>> +++ b/include/drm/drm_bridge.h
>> @@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, 
>> struct drm_bridge *bridge,
>>  bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>  const struct drm_display_mode *mode,
>>  struct drm_display_mode *adjusted_mode);
>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>> +   const struct drm_display_mode *mode);
>>  void drm_bridge_disable(struct drm_bridge *bridge);
>>  void drm_bridge_post_disable(struct drm_bridge *bridge);
>>  void drm_bridge_mode_set(struct drm_bridge *bridge,
>> -- 
>> 1.9.1
>>

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


Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper

2017-05-10 Thread Jose Abreu
Hi Daniel,


On 10-05-2017 09:01, Daniel Vetter wrote:
> On Tue, May 09, 2017 at 06:00:12PM +0100, Jose Abreu wrote:
>> This changes the connector probe helper function to use the new
>> encoder->mode_valid() and crtc->mode_valid() helper callbacks to
>> validate the modes.
>>
>> The new callbacks are optional so the behaviour remains the same
>> if they are not implemented. If they are, then the code loops
>> through all the connector's encodersXcrtcs and calls the
>> callback.
>>
>> If at least a valid encoderXcrtc combination is found which
>> accepts the mode then the function returns MODE_OK.
>>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> ---
>>
>> Changes v1->v2:
>>  - Use new helpers suggested by Ville
>>  - Change documentation (Daniel)
>>
>>  drivers/gpu/drm/drm_probe_helper.c | 60 
>> --
>>  1 file changed, 57 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
>> b/drivers/gpu/drm/drm_probe_helper.c
>> index 1b0c14a..de47413 100644
>> --- a/drivers/gpu/drm/drm_probe_helper.c
>> +++ b/drivers/gpu/drm/drm_probe_helper.c
>> @@ -39,6 +39,8 @@
>>  #include 
>>  #include 
>>  
>> +#include "drm_crtc_internal.h"
>> +
>>  /**
>>   * DOC: output probing helper overview
>>   *
>> @@ -80,6 +82,54 @@
>>  return MODE_OK;
>>  }
>>  
>> +static enum drm_mode_status
>> +drm_mode_validate_connector(struct drm_connector *connector,
>> +struct drm_display_mode *mode)
>> +{
>> +struct drm_device *dev = connector->dev;
>> +uint32_t *ids = connector->encoder_ids;
>> +enum drm_mode_status ret = MODE_OK;
>> +unsigned int i;
>> +
>> +/* Step 1: Validate against connector */
>> +ret = drm_connector_mode_valid(connector, mode);
>> +if (ret != MODE_OK)
>> +return ret;
>> +
>> +/* Step 2: Validate against encoders and crtcs */
>> +for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
>> +struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
>> +struct drm_crtc *crtc;
>> +
>> +if (!encoder)
>> +continue;
>> +
>> +ret = drm_encoder_mode_valid(encoder, mode);
>> +if (ret != MODE_OK) {
>> +/* No point in continuing for crtc check as this encoder
>> + * will not accept the mode anyway. If all encoders
>> + * reject the mode then, at exit, ret will not be
>> + * MODE_OK. */
>> +continue;
>> +}
> One thing I've forgotten the last time around: Please also check
> bridge->mode_valid here. The encoder->bridge mapping is fixed.

Ok, will add in next version.

Best regards,
Jose Miguel Abreu

>
> Otherwise I think this looks good.
> -Daniel
>
>> +
>> +drm_for_each_crtc(crtc, dev) {
>> +if (!drm_encoder_crtc_ok(encoder, crtc))
>> +continue;
>> +
>> +ret = drm_crtc_mode_valid(crtc, mode);
>> +if (ret == MODE_OK) {
>> +/* If we get to this point there is at least
>> + * one combination of encoder+crtc that works
>> + * for this mode. Lets return now. */
>> +return ret;
>> +}
>> +}
>> +}
>> +
>> +return ret;
>> +}
>> +
>>  static int drm_helper_probe_add_cmdline_mode(struct drm_connector 
>> *connector)
>>  {
>>  struct drm_cmdline_mode *cmdline_mode;
>> @@ -284,7 +334,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
>>   *- drm_mode_validate_flag() checks the modes against basic connector
>>   *  capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
>>   *- the optional _connector_helper_funcs.mode_valid helper can 
>> perform
>> 

[PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback

2017-05-09 Thread Jose Abreu
Now that we have a callback to check if crtc supports a given mode
we can use it in arcpgu so that we restrict the number of probbed
modes to the ones we can actually display.

This is specially useful because arcpgu crtc is responsible to set
a clock value in the commit() stage but unfortunatelly this clock
does not support all the needed ranges.

Also, remove the atomic_check() callback as mode_valid() callback
will be called before.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 39 ---
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index ad9a959..01cae0a 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -32,6 +32,18 @@
{ "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 },
 };
 
+static bool arc_pgu_is_mode_valid(struct arcpgu_drm_private *arcpgu,
+ const struct drm_display_mode *mode)
+{
+   long rate, clk_rate = mode->clock * 1000;
+
+   rate = clk_round_rate(arcpgu->clk, clk_rate);
+   if (rate != clk_rate)
+   return false;
+
+   return true;
+}
+
 static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -64,6 +76,17 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
+enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode 
*mode)
+{
+   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
+
+   if (!arc_pgu_is_mode_valid(arcpgu, mode))
+   return MODE_NOCLOCK;
+
+   return MODE_OK;
+}
+
 static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -129,20 +152,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
  ~ARCPGU_CTRL_ENABLE_MASK);
 }
 
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
-struct drm_crtc_state *state)
-{
-   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-   struct drm_display_mode *mode = >adjusted_mode;
-   long rate, clk_rate = mode->clock * 1000;
-
-   rate = clk_round_rate(arcpgu->clk, clk_rate);
-   if (rate != clk_rate)
-   return -EINVAL;
-
-   return 0;
-}
-
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
  struct drm_crtc_state *state)
 {
@@ -158,6 +167,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
+   .mode_valid = arc_pgu_crtc_mode_valid,
.mode_set   = drm_helper_crtc_mode_set,
.mode_set_base  = drm_helper_crtc_mode_set_base,
.mode_set_nofb  = arc_pgu_crtc_mode_set_nofb,
@@ -165,7 +175,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
.disable= arc_pgu_crtc_disable,
.prepare= arc_pgu_crtc_disable,
.commit = arc_pgu_crtc_enable,
-   .atomic_check   = arc_pgu_crtc_atomic_check,
.atomic_begin   = arc_pgu_crtc_atomic_begin,
 };
 
-- 
1.9.1


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


[PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper

2017-05-09 Thread Jose Abreu
This changes the connector probe helper function to use the new
encoder->mode_valid() and crtc->mode_valid() helper callbacks to
validate the modes.

The new callbacks are optional so the behaviour remains the same
if they are not implemented. If they are, then the code loops
through all the connector's encodersXcrtcs and calls the
callback.

If at least a valid encoderXcrtc combination is found which
accepts the mode then the function returns MODE_OK.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

Changes v1->v2:
- Use new helpers suggested by Ville
- Change documentation (Daniel)

 drivers/gpu/drm/drm_probe_helper.c | 60 --
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 1b0c14a..de47413 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -39,6 +39,8 @@
 #include 
 #include 
 
+#include "drm_crtc_internal.h"
+
 /**
  * DOC: output probing helper overview
  *
@@ -80,6 +82,54 @@
return MODE_OK;
 }
 
+static enum drm_mode_status
+drm_mode_validate_connector(struct drm_connector *connector,
+   struct drm_display_mode *mode)
+{
+   struct drm_device *dev = connector->dev;
+   uint32_t *ids = connector->encoder_ids;
+   enum drm_mode_status ret = MODE_OK;
+   unsigned int i;
+
+   /* Step 1: Validate against connector */
+   ret = drm_connector_mode_valid(connector, mode);
+   if (ret != MODE_OK)
+   return ret;
+
+   /* Step 2: Validate against encoders and crtcs */
+   for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+   struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+   struct drm_crtc *crtc;
+
+   if (!encoder)
+   continue;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   /* No point in continuing for crtc check as this encoder
+* will not accept the mode anyway. If all encoders
+* reject the mode then, at exit, ret will not be
+* MODE_OK. */
+   continue;
+   }
+
+   drm_for_each_crtc(crtc, dev) {
+   if (!drm_encoder_crtc_ok(encoder, crtc))
+   continue;
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret == MODE_OK) {
+   /* If we get to this point there is at least
+* one combination of encoder+crtc that works
+* for this mode. Lets return now. */
+   return ret;
+   }
+   }
+   }
+
+   return ret;
+}
+
 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
 {
struct drm_cmdline_mode *cmdline_mode;
@@ -284,7 +334,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
  *- drm_mode_validate_flag() checks the modes against basic connector
  *  capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
  *- the optional _connector_helper_funcs.mode_valid helper can perform
- *  driver and/or hardware specific checks
+ *  driver and/or sink specific checks
+ *- the optional _crtc_helper_funcs.mode_valid and
+ *  _encoder_helper_funcs.mode_valid helpers can perform driver and/or
+ *  source specific checks which are also enforced by the modeset/atomic
+ *  helpers
  *
  * 5. Any mode whose status is not OK is pruned from the connector's modes 
list,
  *accompanied by a debug message indicating the reason for the mode's
@@ -428,8 +482,8 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_flag(mode, mode_flags);
 
-   if (mode->status == MODE_OK && connector_funcs->mode_valid)
-   mode->status = connector_funcs->mode_valid(connector,
+   if (mode->status == MODE_OK)
+   mode->status = drm_mode_validate_connector(connector,
   mode);
}
 
-- 
1.9.1


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


[PATCH v2 2/8] drm: Add drm_crtc_mode_valid()

2017-05-09 Thread Jose Abreu
Add a new helper to call crtc->mode_valid callback.

Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---
 drivers/gpu/drm/drm_crtc.c  | 22 ++
 drivers/gpu/drm/drm_crtc_internal.h |  3 +++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5af25ce..07ae705 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -741,3 +742,24 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
 
return ret;
 }
+
+/**
+ * drm_crtc_mode_valid - call crtc->mode_valid callback, if any.
+ * @crtc: crtc
+ * @mode: mode to be validated
+ *
+ * If no mode_valid callback is available this will return MODE_OK.
+ *
+ * Returns: drm_mode_status Enum
+ */
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode)
+{
+   const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+   if (!crtc_funcs || !crtc_funcs->mode_valid)
+   return MODE_OK;
+
+   return crtc_funcs->mode_valid(crtc, mode);
+}
+EXPORT_SYMBOL(drm_crtc_mode_valid);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
b/drivers/gpu/drm/drm_crtc_internal.h
index d077c54..3800abd 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -45,6 +45,9 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
 
 struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
 
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+const struct drm_display_mode *mode);
+
 /* IOCTLs */
 int drm_mode_getcrtc(struct drm_device *dev,
 void *data, struct drm_file *file_priv);
-- 
1.9.1


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


[PATCH v2 0/8] Introduce new mode validation callbacks

2017-05-09 Thread Jose Abreu
This series is a follow up from the discussion at [1]. We start by
introducing crtc->mode_valid(), encoder->mode_valid() and
bridge->mode_valid() callbacks which will be used in followup
patches.

We proceed by introducing new helpers to call this new callbacks
at 2/8, 3/8 and 4/8.

Next, at 5/8 we modify the connector probe helper so that only modes
which are supported by a given encoder+crtc combination are probbed.

At 6/8 a helper function is introduced that calls all mode_valid()
from a set of bridges.

At 7/8 we call all the mode_valid() callbacks for a given pipeline,
except the connector->mode_valid one, so that the mode is validated.
This is done before calling mode_fixup().

Finally, at 8/8 we use the new crtc->mode_valid() callback in arcpgu
and remove the atomic_check() callback.

[1] https://patchwork.kernel.org/patch/9702233/

Jose Abreu (8):
  drm: Add crtc/encoder/bridge->mode_valid() callbacks
  drm: Add drm_crtc_mode_valid()
  drm: Add drm_encoder_mode_valid()
  drm: Add drm_connector_mode_valid()
  drm: Use new mode_valid() helpers in connector probe helper
  drm: Introduce drm_bridge_mode_valid()
  drm: Use mode_valid() in atomic modeset
  drm: arc: Use crtc->mode_valid() callback

Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>

 drivers/gpu/drm/arc/arcpgu_crtc.c| 39 ++---
 drivers/gpu/drm/drm_atomic_helper.c  | 75 ++--
 drivers/gpu/drm/drm_bridge.c | 33 ++
 drivers/gpu/drm/drm_connector.c  | 23 ++
 drivers/gpu/drm/drm_crtc.c   | 22 ++
 drivers/gpu/drm/drm_crtc_internal.h  |  7 +++
 drivers/gpu/drm/drm_encoder.c| 23 ++
 drivers/gpu/drm/drm_probe_helper.c   | 60 +++--
 include/drm/drm_bridge.h | 22 ++
 include/drm/drm_modeset_helper_vtables.h | 45 +++
 10 files changed, 328 insertions(+), 21 deletions(-)

-- 
1.9.1


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


[PATCH v2 3/8] drm: Add drm_encoder_mode_valid()

2017-05-09 Thread Jose Abreu
Add a new helper to call encoder->mode_valid callback.

Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---
 drivers/gpu/drm/drm_crtc_internal.h |  2 ++
 drivers/gpu/drm/drm_encoder.c   | 23 +++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
b/drivers/gpu/drm/drm_crtc_internal.h
index 3800abd..6165bc9 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -129,6 +129,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, 
void *data,
 /* drm_encoder.c */
 int drm_encoder_register_all(struct drm_device *dev);
 void drm_encoder_unregister_all(struct drm_device *dev);
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode 
*mode);
 
 /* IOCTL */
 int drm_mode_getencoder(struct drm_device *dev,
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 0708779..af75f42 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "drm_crtc_internal.h"
 
@@ -239,3 +240,25 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
 
return 0;
 }
+
+/**
+ * drm_encoder_mode_valid - call encoder->mode_valid callback, if any.
+ * @encoder: encoder
+ * @mode: mode to be validated
+ *
+ * If no mode_valid callback is available this will return MODE_OK.
+ *
+ * Returns: drm_mode_status Enum
+ */
+enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
+   const struct drm_display_mode *mode)
+{
+   const struct drm_encoder_helper_funcs *encoder_funcs =
+   encoder->helper_private;
+
+   if (!encoder_funcs || !encoder_funcs->mode_valid)
+   return MODE_OK;
+
+   return encoder_funcs->mode_valid(encoder, mode);
+}
+EXPORT_SYMBOL(drm_encoder_mode_valid);
-- 
1.9.1


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


[PATCH v2 4/8] drm: Add drm_connector_mode_valid()

2017-05-09 Thread Jose Abreu
Add a new helper to call connector->mode_valid callback.

Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

TODO: function prototype should receive a const, but currently
mode_valid declaration is not const. In order to change this
I needed to touch *every* driver who uses this callback.
Postponed to when I have the time.

 drivers/gpu/drm/drm_connector.c | 23 +++
 drivers/gpu/drm/drm_crtc_internal.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 9f84761..f2634a2 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
@@ -1418,3 +1419,25 @@ struct drm_tile_group *drm_mode_create_tile_group(struct 
drm_device *dev,
return tg;
 }
 EXPORT_SYMBOL(drm_mode_create_tile_group);
+
+/**
+ * drm_connector_mode_valid - call connector->mode_valid callback, if any.
+ * @connector: connector
+ * @mode: mode to be validated
+ *
+ * If no mode_valid callback is available this will return MODE_OK.
+ *
+ * Returns: drm_mode_status Enum
+ */
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+   const struct drm_connector_helper_funcs *connector_funcs =
+   connector->helper_private;
+
+   if (!connector_funcs || !connector_funcs->mode_valid)
+   return MODE_OK;
+
+   return connector_funcs->mode_valid(connector, mode);
+}
+EXPORT_SYMBOL(drm_connector_mode_valid);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
b/drivers/gpu/drm/drm_crtc_internal.h
index 6165bc9..018b154 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -146,6 +146,8 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object 
*obj,
uint64_t value);
 int drm_connector_create_standard_properties(struct drm_device *dev);
 const char *drm_get_connector_force_name(enum drm_connector_force force);
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode);
 
 /* IOCTL */
 int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
-- 
1.9.1


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


[PATCH v2 1/8] drm: Add crtc/encoder/bridge->mode_valid() callbacks

2017-05-09 Thread Jose Abreu
This adds a new callback to crtc, encoder and bridge helper functions
called mode_valid(). This callback shall be implemented if the
corresponding component has some sort of restriction in the modes
that can be displayed. A NULL callback implicates that the component
can display all the modes.

We also change the description of connector->mode_valid() callback
so that it matches the existing behaviour: It is never called in
atomic check phase.

Only the callbacks were implemented to simplify review process,
following patches will make use of them.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

Changes v1->v2:
- Change description of connector->mode_valid() (Daniel)

 include/drm/drm_bridge.h | 20 ++
 include/drm/drm_modeset_helper_vtables.h | 45 
 2 files changed, 65 insertions(+)

diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index fdd82fc..00c6c36 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -59,6 +59,26 @@ struct drm_bridge_funcs {
void (*detach)(struct drm_bridge *bridge);
 
/**
+* @mode_valid:
+*
+* This callback is used to check if a specific mode is valid in this
+* bridge. This should be implemented if the bridge has some sort of
+* restriction in the modes it can display. For example, a given bridge
+* may be responsible to set a clock value. If the clock can not
+* produce all the values for the available modes then this callback
+* can be used to restrict the number of modes to only the ones that
+* can be displayed.
+*
+* This is called at mode probe and at atomic check phase.
+*
+* RETURNS:
+*
+* drm_mode_status Enum
+*/
+   enum drm_mode_status (*mode_valid)(struct drm_bridge *crtc,
+  const struct drm_display_mode *mode);
+
+   /**
 * @mode_fixup:
 *
 * This callback is used to validate and adjust a mode. The paramater
diff --git a/include/drm/drm_modeset_helper_vtables.h 
b/include/drm/drm_modeset_helper_vtables.h
index c01c328..eec2c70 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -106,6 +106,26 @@ struct drm_crtc_helper_funcs {
void (*commit)(struct drm_crtc *crtc);
 
/**
+* @mode_valid:
+*
+* This callback is used to check if a specific mode is valid in this
+* crtc. This should be implemented if the crtc has some sort of
+* restriction in the modes it can display. For example, a given crtc
+* may be responsible to set a clock value. If the clock can not
+* produce all the values for the available modes then this callback
+* can be used to restrict the number of modes to only the ones that
+* can be displayed.
+*
+* This is called at mode probe and at atomic check phase.
+*
+* RETURNS:
+*
+* drm_mode_status Enum
+*/
+   enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+  const struct drm_display_mode *mode);
+
+   /**
 * @mode_fixup:
 *
 * This callback is used to validate a mode. The parameter mode is the
@@ -457,6 +477,26 @@ struct drm_encoder_helper_funcs {
void (*dpms)(struct drm_encoder *encoder, int mode);
 
/**
+* @mode_valid:
+*
+* This callback is used to check if a specific mode is valid in this
+* encoder. This should be implemented if the encoder has some sort
+* of restriction in the modes it can display. For example, a given
+* encoder may be responsible to set a clock value. If the clock can
+* not produce all the values for the available modes then this callback
+* can be used to restrict the number of modes to only the ones that
+* can be displayed.
+*
+* This is called at mode probe and at atomic check phase.
+*
+* RETURNS:
+*
+* drm_mode_status Enum
+*/
+   enum drm_mode_status (*mode_valid)(struct drm_encoder *crtc,
+  const struct drm_display_mode *mode);
+
+   /**
 * @mode_fixup:
 *
 * This callback is used to validate and adjust a mode. The parameter
@@ -795,6 +835,11 @@ struct drm_connector_helper_funcs {
 * (which is usually derived from the EDID data block from the sink).
  

[PATCH v2 7/8] drm: Use mode_valid() in atomic modeset

2017-05-09 Thread Jose Abreu
This patches makes use of the new mode_valid() callbacks introduced
previously to validate the full video pipeline when modesetting.

This calls the connector->mode_valid(), encoder->mode_valid(),
bridge->mode_valid() and crtc->mode_valid() so that we can
make sure that the mode will be accepted in every components.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---

Changes v1->v2:
- Removed call to connector->mode_valid (Ville, Daniel)
- Change function name (Ville)
- Use for_each_new_connector_in_state (Ville)
- Do not validate if connector and mode didn't change (Ville)
- Use new helpers to call mode_valid

 drivers/gpu/drm/drm_atomic_helper.c | 75 +++--
 1 file changed, 72 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 8be9719..19d0ea1 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -452,6 +452,69 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
return 0;
 }
 
+static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
+   struct drm_encoder *encoder,
+   struct drm_crtc *crtc,
+   struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret;
+
+   ret = drm_encoder_mode_valid(encoder, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] mode_valid() failed\n",
+   encoder->base.id, encoder->name);
+   return ret;
+   }
+
+   ret = drm_bridge_mode_valid(encoder->bridge, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
+   return ret;
+   }
+
+   ret = drm_crtc_mode_valid(crtc, mode);
+   if (ret != MODE_OK) {
+   DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode_valid() failed\n",
+   crtc->base.id, crtc->name);
+   return ret;
+   }
+
+   return ret;
+}
+
+static int
+mode_valid(struct drm_atomic_state *state)
+{
+   struct drm_connector_state *conn_state;
+   struct drm_connector *connector;
+   int i;
+
+   for_each_new_connector_in_state(state, connector, conn_state, i) {
+   struct drm_encoder *encoder = conn_state->best_encoder;
+   struct drm_crtc *crtc = conn_state->crtc;
+   struct drm_crtc_state *crtc_state;
+   enum drm_mode_status mode_status;
+   struct drm_display_mode *mode;
+
+   if (!crtc || !encoder)
+   continue;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+   if (!crtc_state)
+   continue;
+   if (!crtc_state->mode_changed && 
!crtc_state->connectors_changed)
+   continue;
+
+   mode = _state->mode;
+
+   mode_status = mode_valid_path(connector, encoder, crtc, mode);
+   if (mode_status != MODE_OK)
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 /**
  * drm_atomic_helper_check_modeset - validate state object for modeset changes
  * @dev: DRM device
@@ -466,13 +529,15 @@ static int handle_conflicting_encoders(struct 
drm_atomic_state *state,
  * 2. _connector_helper_funcs.atomic_check to validate the connector state.
  * 3. If it's determined a modeset is needed then all connectors on the 
affected crtc
  *crtc are added and _connector_helper_funcs.atomic_check is run on 
them.
- * 4. _bridge_funcs.mode_fixup is called on all encoder bridges.
- * 5. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
+ * 4. _encoder_helper_funcs.mode_valid, _bridge_funcs.mode_valid and
+ *_crtc_helper_funcs.mode_valid are called on the affected components.
+ * 5. _bridge_funcs.mode_fixup is called on all encoder bridges.
+ * 6. _encoder_helper_funcs.atomic_check is called to validate any encoder 
state.
  *This function is only called when the encoder will be part of a 
configured crtc,
  *it must not be used for implementing connector property validation.
  *If this function is NULL, _atomic_encoder_helper_funcs.mode_fixup is 
called
  *instead.
- * 6. _crtc_helper_funcs.mode_fixup is called last, to fix up the mode 
with crtc constraints.
+ * 7. _crtc_helper_funcs.mode_f

[PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

2017-05-09 Thread Jose Abreu
Introduce a new helper function which calls mode_valid() callback
for all bridges in an encoder chain.

Signed-off-by: Jose Abreu <joab...@synopsys.com>
Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>
---
 drivers/gpu/drm/drm_bridge.c | 33 +
 include/drm/drm_bridge.h |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 86a7637..dc8cdfe 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
 EXPORT_SYMBOL(drm_bridge_mode_fixup);
 
 /**
+ * drm_bridge_mode_valid - validate the mode against all bridges in the
+ *encoder chain.
+ * @bridge: bridge control structure
+ * @mode: desired mode to be validated
+ *
+ * Calls _bridge_funcs.mode_valid for all the bridges in the encoder
+ * chain, starting from the first bridge to the last. If at least one bridge
+ * does not accept the mode the function returns the error code.
+ *
+ * Note: the bridge passed should be the one closest to the encoder.
+ *
+ * RETURNS:
+ * MODE_OK on success, drm_mode_status Enum error code on failure
+ */
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode)
+{
+   enum drm_mode_status ret = MODE_OK;
+
+   if (!bridge)
+   return ret;
+
+   if (bridge->funcs->mode_valid)
+   ret = bridge->funcs->mode_valid(bridge, mode);
+
+   if (ret != MODE_OK)
+   return ret;
+
+   return drm_bridge_mode_valid(bridge->next, mode);
+}
+EXPORT_SYMBOL(drm_bridge_mode_valid);
+
+/**
  * drm_bridge_disable - disables all bridges in the encoder chain
  * @bridge: bridge control structure
  *
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 00c6c36..8358eb3 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct 
drm_bridge *bridge,
 bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode);
 void drm_bridge_disable(struct drm_bridge *bridge);
 void drm_bridge_post_disable(struct drm_bridge *bridge);
 void drm_bridge_mode_set(struct drm_bridge *bridge,
-- 
1.9.1


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


Re: [PATCH 2/5] drm: Use new mode_valid() helpers in connector probe helper

2017-05-08 Thread Jose Abreu
Hi Daniel,


On 08-05-2017 08:50, Daniel Vetter wrote:
> On Thu, May 04, 2017 at 03:11:39PM +0100, Jose Abreu wrote:
>> This changes the connector probe helper function to use the new
>> encoder->mode_valid() and crtc->mode_valid() helper callbacks to
>> validate the modes.
>>
>> The new callbacks are optional so the behaviour remains the same
>> if they are not implemented. If they are, then the code loops
>> through all the connector's encodersXcrtcs and calls the
>> callback.
>>
>> If at least a valid encoderXcrtc combination is found which
>> accepts the mode then the function returns MODE_OK.
>>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
> A few comments below.
> -Daniel

Thanks for the review!

>
>> ---
>>  drivers/gpu/drm/drm_probe_helper.c | 71 
>> +++---
>>  1 file changed, 67 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
>> b/drivers/gpu/drm/drm_probe_helper.c
>> index 1b0c14a..bf19f82 100644
>> --- a/drivers/gpu/drm/drm_probe_helper.c
>> +++ b/drivers/gpu/drm/drm_probe_helper.c
>> @@ -80,6 +80,67 @@
>>  return MODE_OK;
>>  }
>>  
>> +static enum drm_mode_status
>> +drm_mode_validate_connector(struct drm_connector *connector,
>> +struct drm_display_mode *mode)
>> +{
>> +const struct drm_connector_helper_funcs *connector_funcs =
>> +connector->helper_private;
>> +struct drm_device *dev = connector->dev;
>> +uint32_t *ids = connector->encoder_ids;
>> +enum drm_mode_status ret = MODE_OK;
>> +unsigned int i;
>> +
>> +/* Step 1: Validate against connector */
>> +if (connector_funcs && connector_funcs->mode_valid)
>> +ret = connector_funcs->mode_valid(connector, mode);
>> +
>> +if (ret != MODE_OK)
>> +return ret;
>> +
>> +/* Step 2: Validate against encoders and crtcs */
>> +for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
>> +struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
>> +const struct drm_encoder_helper_funcs *encoder_funcs;
>> +struct drm_crtc *crtc;
>> +
>> +if (!encoder)
>> +continue;
>> +
>> +encoder_funcs = encoder->helper_private;
>> +if (encoder_funcs && encoder_funcs->mode_valid)
>> +ret = encoder_funcs->mode_valid(encoder, mode);
>> +else
>> +ret = MODE_OK; /* encoder accepts everything */
>> +
>> +/* No point in continuing for crtc check as this encoder will
>> + * not accept the mode anyway. If all encoders reject the mode
>> + * then, at exit, ret will not be MODE_OK. */
>> +if (ret != MODE_OK)
>> +continue;
> I think we should validate encoders against connector->possible_ids here.
> Might be that not many drivers fill this out correctly, and in case fixing
> that is much work, perhaps as a follow-up. But would be good to at least
> help look down that part of uapi a bit more.

I'm sorry but I'm not following you here (I think I need more
coffee :)).

What do you mean by connector->possible_ids ? Is this something
new ? Because I didn't find anything in my tree and I'm based on
today's drm-next from Dave.

>
> This isn't checked within atomic and legacy helpers since we assume that
> ->best_encoder respectively ->atomic_best_encoder gives us a valid encoder
> ...
>
>> +
>> +drm_for_each_crtc(crtc, dev) {
>> +const struct drm_crtc_helper_funcs *crtc_funcs;
>> +
>> +if (!drm_encoder_crtc_ok(encoder, crtc))
>> +continue;
> We check this one here already in both atomic and legacy helpers, so all
> drivers should get this right.

But drm_for_each_crtc() iterates over all crtc from a device and
some crtcs may only be used by specific encoders (by setting
encoder->possible_crtcs), right ? We need to iterate only over
the encoder's crtc we want to validate.

>
>> +
>&g

Re: [PATCH 2/5] drm: Use new mode_valid() helpers in connector probe helper

2017-05-04 Thread Jose Abreu
Hi Ville,


On 04-05-2017 15:32, Ville Syrjälä wrote:
> On Thu, May 04, 2017 at 03:11:39PM +0100, Jose Abreu wrote:
>> This changes the connector probe helper function to use the new
>> encoder->mode_valid() and crtc->mode_valid() helper callbacks to
>> validate the modes.
>>
>> The new callbacks are optional so the behaviour remains the same
>> if they are not implemented. If they are, then the code loops
>> through all the connector's encodersXcrtcs and calls the
>> callback.
>>
>> If at least a valid encoderXcrtc combination is found which
>> accepts the mode then the function returns MODE_OK.
>>
>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>> Cc: Carlos Palminha <palmi...@synopsys.com>
>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>> Cc: Dave Airlie <airl...@linux.ie>
>> Cc: Andrzej Hajda <a.ha...@samsung.com>
>> Cc: Archit Taneja <arch...@codeaurora.org>
>> ---
>>  drivers/gpu/drm/drm_probe_helper.c | 71 
>> +++---
>>  1 file changed, 67 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
>> b/drivers/gpu/drm/drm_probe_helper.c
>> index 1b0c14a..bf19f82 100644
>> --- a/drivers/gpu/drm/drm_probe_helper.c
>> +++ b/drivers/gpu/drm/drm_probe_helper.c
>> @@ -80,6 +80,67 @@
>>  return MODE_OK;
>>  }
>>  
>> +static enum drm_mode_status
>> +drm_mode_validate_connector(struct drm_connector *connector,
>> +struct drm_display_mode *mode)
>> +{
>> +const struct drm_connector_helper_funcs *connector_funcs =
>> +connector->helper_private;
>> +struct drm_device *dev = connector->dev;
>> +uint32_t *ids = connector->encoder_ids;
>> +enum drm_mode_status ret = MODE_OK;
>> +unsigned int i;
>> +
>> +/* Step 1: Validate against connector */
>> +if (connector_funcs && connector_funcs->mode_valid)
>> +ret = connector_funcs->mode_valid(connector, mode);
>> +
>> +if (ret != MODE_OK)
>> +return ret;
>> +
>> +/* Step 2: Validate against encoders and crtcs */
>> +for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
>> +struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
>> +const struct drm_encoder_helper_funcs *encoder_funcs;
>> +struct drm_crtc *crtc;
>> +
>> +if (!encoder)
>> +continue;
>> +
>> +encoder_funcs = encoder->helper_private;
>> +if (encoder_funcs && encoder_funcs->mode_valid)
>> +ret = encoder_funcs->mode_valid(encoder, mode);
>> +else
>> +ret = MODE_OK; /* encoder accepts everything */
> Since you already added the drm_bridge_mode_valid() helper, maybe add one
> for connectors, encoders and crtcs as well. Might keep the logic in this
> function a bit more clear on account of not having to check for the
> presence of the vfunc. Right now all three cases look slightly
> different from one another.

Ok, will add in next version. Thanks!

Best regards,
Jose Miguel Abreu

>
>> +
>> +/* No point in continuing for crtc check as this encoder will
>> + * not accept the mode anyway. If all encoders reject the mode
>> + * then, at exit, ret will not be MODE_OK. */
>> +if (ret != MODE_OK)
>> +continue;
>> +
>> +drm_for_each_crtc(crtc, dev) {
>> +const struct drm_crtc_helper_funcs *crtc_funcs;
>> +
>> +if (!drm_encoder_crtc_ok(encoder, crtc))
>> +continue;
>> +
>> +crtc_funcs = crtc->helper_private;
>> +if (!crtc_funcs || !crtc_funcs->mode_valid)
>> +return MODE_OK; /* crtc accepts everything */
>> +
>> +ret = crtc_funcs->mode_valid(crtc, mode);
>> +if (ret == MODE_OK)
>> +/* If we get to this point there is at least
>> + * one combination of encoder+crtc that works
>> + * for this mode. Lets return now. */
>> +return ret;
>> +}
>> +}
>&g

[PATCH 0/5] Introduce new mode validation callbacks

2017-05-04 Thread Jose Abreu
This series is a follow up from the discussion at [1]. We start by
introducing crtc->mode_valid(), encoder->mode_valid() and
bridge->mode_valid() callbacks which will be used in followup
patches.

Next, at 2/5 we modify the connector probe helper so that only modes
which are supported by a given encoder+crtc combination are probbed.

At 3/5 a helper function is introduced that calls all mode_valid()
from a set of bridges.

At 4/5 we call all the mode_valid() callbacks for a given pipeline
so that the mode is validated. This is done before calling mode_fixup().

Finally, at 5/5 we use the new crtc->mode_valid() callback in arcpgu
and remove the atomic_check() callback.

[1] https://patchwork.kernel.org/patch/9702233/

Jose Abreu (5):
  drm: Add crtc/encoder/bridge->mode_valid() callbacks
  drm: Use new mode_valid() helpers in connector probe helper
  drm: Introduce drm_bridge_mode_valid()
  drm: Use mode_valid() in atomic modeset
  drm: arc: Use crtc->mode_valid() callback

Cc: Carlos Palminha <palmi...@synopsys.com>
Cc: Alexey Brodkin <abrod...@synopsys.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@linux.ie>
Cc: Andrzej Hajda <a.ha...@samsung.com>
Cc: Archit Taneja <arch...@codeaurora.org>

 drivers/gpu/drm/arc/arcpgu_crtc.c| 39 --
 drivers/gpu/drm/drm_atomic_helper.c  | 92 ++--
 drivers/gpu/drm/drm_bridge.c | 33 
 drivers/gpu/drm/drm_probe_helper.c   | 71 ++--
 include/drm/drm_bridge.h | 22 
 include/drm/drm_modeset_helper_vtables.h | 40 ++
 6 files changed, 275 insertions(+), 22 deletions(-)

-- 
1.9.1


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


Re: [PATCH 1/2] drm: Introduce crtc->mode_valid() callback

2017-05-04 Thread Jose Abreu
Hi Daniel,


On 03-05-2017 16:00, Daniel Vetter wrote:
> On Wed, May 03, 2017 at 03:16:13PM +0100, Jose Abreu wrote:
>> Hi Daniel,
>>
>>
>> On 03-05-2017 07:19, Daniel Vetter wrote:
>>> On Tue, May 2, 2017 at 11:29 AM, Jose Abreu <jose.ab...@synopsys.com> wrote:
>>>> On 02-05-2017 09:48, Daniel Vetter wrote:
>>>>> On Wed, Apr 26, 2017 at 11:48:34AM +0100, Jose Abreu wrote:
>>>>>> Some crtc's may have restrictions in the mode they can display. In
>>>>>> this patch a new callback (crtc->mode_valid()) is introduced that
>>>>>> is called at the same stage of connector->mode_valid() callback.
>>>>>>
>>>>>> This shall be implemented if the crtc has some sort of restriction
>>>>>> so that we don't probe modes that will fail in the commit() stage.
>>>>>> For example: A given crtc may be responsible to set a clock value.
>>>>>> If the clock can not produce all the values for the available
>>>>>> modes then this callback can be used to restrict the number of
>>>>>> probbed modes to only the ones that can be displayed.
>>>>>>
>>>>>> If the crtc does not implement the callback then the behaviour will
>>>>>> remain the same. Also, for a given set of crtcs that can be bound to
>>>>>> the connector, if at least one can display the mode then the mode
>>>>>> will be probbed.
>>>>>>
>>>>>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>>>>>> Cc: Carlos Palminha <palmi...@synopsys.com>
>>>>>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>>>>>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>>>>>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>>>>>> Cc: Dave Airlie <airl...@linux.ie>
>>>>> Not sure this is useful, since you still have to duplicate the exact same
>>>>> check into your ->mode_fixup hook. That seems to make things even more
>>>>> confusing.
>>>> Yeah, in arcpgu I had to duplicate the code in ->atomic_check.
>>>>
>>>>> Also this doesn't update the various kerneldoc comments. For the existing
>>>>> hooks. Since this topic causes so much confusion, I don't think a
>>>>> half-solution will help, but has some good potential to make things worse.
>>>> I only documented the callback in drm_modeset_helper_vtables.h.
>>>>
>>>> Despite all of this, I think it doesn't makes sense delivering
>>>> modes to userspace which can never be used.
>>>>
>>>> This is really annoying in arcpgu. Imagine: I try to use mpv to
>>>> play a video, the full set of modes from EDID were probed so if I
>>>> just start mpv it will pick the native mode of the TV instead of
>>>> the one that is supported, so mpv will fail to play. I know the
>>>> value of clock which will work (so I know what mode shall be
>>>> used), but a normal user which is not aware of the HW will have
>>>> to cycle through the list of modes and try them all until it hits
>>>> one that works. Its really boring.
>>>>
>>>> For the modes that user specifies manually there is nothing we
>>>> can do, but we should not trick users into thinking that a given
>>>> mode is supported when it will always fail at commit.
>>> Yes, you are supposed to filter these out in ->mode_valid. But my
>>> stance is that only adding a half-baked support for a new callback to
>>> the core isn't going to make life easier for drivers, it will just add
>>> to the confusion. There's already piles of docs for both @mode_valid
>>> and @mode_fixup hooks explaining this, I don't want to make the
>>> documentation even more complex. And half-baked crtc checking is
>>> _much_ easier to implement in the driver directly (e.g. i915 checks
>>> for crtc constraints since forever, as do the other big x86 drivers).
>> But i915 crtc checks are done after handing the mode to
>> userspace, arcpgu also does that. We must let users specify
>> manually a mode but there is no point in returning modes in
>> get_connector which will always fail to commit. I get your point
>> and this can lead to code duplication, but I don't think it will
>> lead to confusion as long as it is well documented. And besides,
>> the callback is completely optional.
> Look closer, e.g. intel_dp_mode_valid cal

Re: [PATCH 1/2] drm: Introduce crtc->mode_valid() callback

2017-05-04 Thread Jose Abreu
Hi Daniel,


On 03-05-2017 07:19, Daniel Vetter wrote:
> On Tue, May 2, 2017 at 11:29 AM, Jose Abreu <jose.ab...@synopsys.com> wrote:
>> On 02-05-2017 09:48, Daniel Vetter wrote:
>>> On Wed, Apr 26, 2017 at 11:48:34AM +0100, Jose Abreu wrote:
>>>> Some crtc's may have restrictions in the mode they can display. In
>>>> this patch a new callback (crtc->mode_valid()) is introduced that
>>>> is called at the same stage of connector->mode_valid() callback.
>>>>
>>>> This shall be implemented if the crtc has some sort of restriction
>>>> so that we don't probe modes that will fail in the commit() stage.
>>>> For example: A given crtc may be responsible to set a clock value.
>>>> If the clock can not produce all the values for the available
>>>> modes then this callback can be used to restrict the number of
>>>> probbed modes to only the ones that can be displayed.
>>>>
>>>> If the crtc does not implement the callback then the behaviour will
>>>> remain the same. Also, for a given set of crtcs that can be bound to
>>>> the connector, if at least one can display the mode then the mode
>>>> will be probbed.
>>>>
>>>> Signed-off-by: Jose Abreu <joab...@synopsys.com>
>>>> Cc: Carlos Palminha <palmi...@synopsys.com>
>>>> Cc: Alexey Brodkin <abrod...@synopsys.com>
>>>> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
>>>> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
>>>> Cc: Dave Airlie <airl...@linux.ie>
>>> Not sure this is useful, since you still have to duplicate the exact same
>>> check into your ->mode_fixup hook. That seems to make things even more
>>> confusing.
>> Yeah, in arcpgu I had to duplicate the code in ->atomic_check.
>>
>>> Also this doesn't update the various kerneldoc comments. For the existing
>>> hooks. Since this topic causes so much confusion, I don't think a
>>> half-solution will help, but has some good potential to make things worse.
>> I only documented the callback in drm_modeset_helper_vtables.h.
>>
>> Despite all of this, I think it doesn't makes sense delivering
>> modes to userspace which can never be used.
>>
>> This is really annoying in arcpgu. Imagine: I try to use mpv to
>> play a video, the full set of modes from EDID were probed so if I
>> just start mpv it will pick the native mode of the TV instead of
>> the one that is supported, so mpv will fail to play. I know the
>> value of clock which will work (so I know what mode shall be
>> used), but a normal user which is not aware of the HW will have
>> to cycle through the list of modes and try them all until it hits
>> one that works. Its really boring.
>>
>> For the modes that user specifies manually there is nothing we
>> can do, but we should not trick users into thinking that a given
>> mode is supported when it will always fail at commit.
> Yes, you are supposed to filter these out in ->mode_valid. But my
> stance is that only adding a half-baked support for a new callback to
> the core isn't going to make life easier for drivers, it will just add
> to the confusion. There's already piles of docs for both @mode_valid
> and @mode_fixup hooks explaining this, I don't want to make the
> documentation even more complex. And half-baked crtc checking is
> _much_ easier to implement in the driver directly (e.g. i915 checks
> for crtc constraints since forever, as do the other big x86 drivers).

But i915 crtc checks are done after handing the mode to
userspace, arcpgu also does that. We must let users specify
manually a mode but there is no point in returning modes in
get_connector which will always fail to commit. I get your point
and this can lead to code duplication, but I don't think it will
lead to confusion as long as it is well documented. And besides,
the callback is completely optional.

>
> So all taken together, if we add a ->mode_valid to crtcs, then imo we
> should do it right and actually make life easier for drivers. A good
> proof would be if your patch would allow us to drop a lot of the
> lenghty language from the @mode_valid hooks.

I completely agree that it should make life easier for drivers
but unfortunately I don't really see how :/

So, in summary:
Disadvantage 1: Code duplication
Disadvantage 2: Confusing documentation can lead to callback
misuse

Advantage 1: User will get life simpler

Best regards,
Jose Miguel Abreu

> -Daniel

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


  1   2   3   4   >