Re: [PATCH 7/8] drm: Add old state pointer to CRTC .enable() helper function

2017-06-28 Thread Boris Brezillon
Le Wed, 28 Jun 2017 00:16:20 +0300,
Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com> a écrit :

> The old state is useful for drivers that need to perform operations at
> enable time that depend on the transition between the old and new
> states.
> 
> While at it, rename the operation to .atomic_enable() to be consistent
> with .atomic_disable(), as the .enable() operation is used by atomic
> helpers only.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> ---
>  drivers/gpu/drm/arc/arcpgu_crtc.c   |  5 ++--
>  drivers/gpu/drm/arm/hdlcd_crtc.c|  5 ++--
>  drivers/gpu/drm/arm/malidp_crtc.c   |  5 ++--
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c  |  5 ++--

For atmel-hlcdc:

Acked-by: Boris Brezillon <boris.brezil...@free-electrons.com>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-18 Thread Boris Brezillon
On Thu, 7 Sep 2017 15:06:13 +0530
Archit Taneja <arch...@codeaurora.org> wrote:

> Hi,
> 
> On 08/31/2017 09:25 PM, Boris Brezillon wrote:
> > Add a driver for Cadence DPI -> DSI bridge.
> > 
> > This driver only support a subset of Cadence DSI bridge capabilities.
> > 
> > Here is a non-exhaustive list of missing features:
> >   * burst mode
> >   * dynamic configuration of the DPHY based on the
> >   * support for additional input interfaces (SDI input)
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> > ---
> > Changes in v3:
> > - replace magic values by real timing calculation. The DPHY PLL clock
> >is still hardcoded since we don't have a working DPHY block yet, and
> >this is the piece of HW we need to dynamically configure the PLL
> >rate based on the display refresh rate and the resolution.
> > - parse DSI devices represented with the OF-graph. This is needed to
> >support DSI devices controlled through an external bus like I2C or
> >SPI.
> > - use the DRM panel-bridge infrastructure to simplify the DRM panel
> >logic
> > 
> > Changes in v2:
> > - rebase on v4.12-rc1 and adapt to driver to the drm_bridge API changes
> > - return the correct error when devm_clk_get(sysclk) fails
> > - add missing depends on OF and select DRM_PANEL in the Kconfig entry
> > ---
> >   drivers/gpu/drm/bridge/Kconfig|9 +
> >   drivers/gpu/drm/bridge/Makefile   |1 +
> >   drivers/gpu/drm/bridge/cdns-dsi.c | 1090 
> > +
> >   3 files changed, 1100 insertions(+)
> >   create mode 100644 drivers/gpu/drm/bridge/cdns-dsi.c
> > 
> > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> > index adf9ae0e0b7c..88c324b12e16 100644
> > --- a/drivers/gpu/drm/bridge/Kconfig
> > +++ b/drivers/gpu/drm/bridge/Kconfig
> > @@ -25,6 +25,15 @@ config DRM_ANALOGIX_ANX78XX
> >   the HDMI output of an application processor to MyDP
> >   or DisplayPort.
> >   
> > +config DRM_CDNS_DSI
> > +   tristate "Cadence DPI/DSI bridge"
> > +   select DRM_KMS_HELPER
> > +   select DRM_MIPI_DSI
> > +   select DRM_PANEL
> > +   depends on OF
> > +   help
> > + Support Cadence DPI to DSI bridge.  
> 
> Maybe we can briefly mention here that it's a internal bridge/IP, and not an 
> external chip?

Sure.

> 
> > +
> >   config DRM_DUMB_VGA_DAC
> > tristate "Dumb VGA DAC Bridge support"
> > depends on OF
> > diff --git a/drivers/gpu/drm/bridge/Makefile 
> > b/drivers/gpu/drm/bridge/Makefile
> > index defcf1e7ca1c..77b65e8ecf59 100644
> > --- a/drivers/gpu/drm/bridge/Makefile
> > +++ b/drivers/gpu/drm/bridge/Makefile
> > @@ -1,4 +1,5 @@
> >   obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
> > +obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
> >   obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
> >   obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
> >   obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
> > megachips-stdp-ge-b850v3-fw.o
> > diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c 
> > b/drivers/gpu/drm/bridge/cdns-dsi.c  
> 
> 
> 
> > +
> > +static void cdns_dsi_bridge_disable(struct drm_bridge *bridge)
> > +{
> > +   struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
> > +   struct cdns_dsi *dsi = input_to_dsi(input);
> > +   u32 val;
> > +
> > +   val = readl(dsi->regs + MCTL_MAIN_DATA_CTL);
> > +   val &= ~(IF_VID_SELECT_MASK | IF_VID_MODE | VID_EN | HOST_EOT_GEN |
> > +DISP_EOT_GEN);  
> 
> I see some truncation related sparse warnings here and a couple of other 
> places
> when building against arm32. Those would be nice to fix.

I'll have a look.


> > +static int cdns_dsi_attach(struct mipi_dsi_host *host,
> > +  struct mipi_dsi_device *dev)
> > +{
> > +   struct cdns_dsi *dsi = to_cdns_dsi(host);
> > +   struct cdns_dsi_output *output = >output;
> > +   struct cdns_dsi_input *input = >input;
> > +   struct drm_bridge *bridge;
> > +   struct drm_panel *panel;
> > +   struct device_node *np;
> > +   int ret;
> > +
> > +   /*
> > +* We currently do not support connecting several DSI devices to the
> > +* same host. In order to support that we'd need the DRM bridge
> > +* framework to allow dynamic reconfiguration of the bridge chain.
> > +*/
> > +   if (output->dev)
> > +

Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-19 Thread Boris Brezillon
On Tue, 19 Sep 2017 16:38:31 +0300
Tomi Valkeinen <tomi.valkei...@ti.com> wrote:

> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> On 19/09/17 16:25, Boris Brezillon wrote:
> > On Tue, 19 Sep 2017 15:59:20 +0300
> > Tomi Valkeinen <tomi.valkei...@ti.com> wrote:
> >   
> >> Hi Boris,
> >>
> >>
> >> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> >> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> >>
> >> On 31/08/17 18:55, Boris Brezillon wrote:  
> >>> Add a driver for Cadence DPI -> DSI bridge.
> >>>
> >>> This driver only support a subset of Cadence DSI bridge capabilities.
> >>>
> >>> Here is a non-exhaustive list of missing features:
> >>>  * burst mode
> >>>  * dynamic configuration of the DPHY based on the
> >>>  * support for additional input interfaces (SDI input)
> >>>
> >>> Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> >>
> >> 
> >>  
> >>> + dsi->pclk = devm_clk_get(>dev, "pclk");
> >>> + if (IS_ERR(dsi->pclk))
> >>> + return PTR_ERR(dsi->pclk);
> >>
> >> What's the purpose of pclk? Isn't that normally dealt with the normal
> >> modesetting, enabled with the video stream? How could it even be enabled
> >> here, without anyone setting the rate?  
> > 
> > It's the peripheral clock, not the pixel clock, and AFAIU it has to be
> > enabled before accessing DSI registers.  
> 
> Is that the dsi_p_clk? I can't find "peripheral clock" in the specs.

Yep, it is dsi_p_clk (the APB clock).

> 
> I think calling it "pclk" in a display driver is very confusing, as
> pclk, at least for me, always means pixel clock =).

I can rename it if you prefer. What name would you like to see?
abp_clk? periph_clk? Something else?

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


Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-19 Thread Boris Brezillon
On Tue, 19 Sep 2017 15:59:20 +0300
Tomi Valkeinen <tomi.valkei...@ti.com> wrote:

> Hi Boris,
> 
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> On 31/08/17 18:55, Boris Brezillon wrote:
> > Add a driver for Cadence DPI -> DSI bridge.
> > 
> > This driver only support a subset of Cadence DSI bridge capabilities.
> > 
> > Here is a non-exhaustive list of missing features:
> >  * burst mode
> >  * dynamic configuration of the DPHY based on the
> >  * support for additional input interfaces (SDI input)
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>  
> 
> 
> 
> > +   dsi->pclk = devm_clk_get(>dev, "pclk");
> > +   if (IS_ERR(dsi->pclk))
> > +   return PTR_ERR(dsi->pclk);  
> 
> What's the purpose of pclk? Isn't that normally dealt with the normal
> modesetting, enabled with the video stream? How could it even be enabled
> here, without anyone setting the rate?

It's the peripheral clock, not the pixel clock, and AFAIU it has to be
enabled before accessing DSI registers.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-20 Thread Boris Brezillon
On Wed, 20 Sep 2017 14:55:02 +0300
Tomi Valkeinen <tomi.valkei...@ti.com> wrote:

> Hi Boris,
> 
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> On 31/08/17 18:55, Boris Brezillon wrote:
> > Add a driver for Cadence DPI -> DSI bridge.
> > 
> > This driver only support a subset of Cadence DSI bridge capabilities.
> > 
> > Here is a non-exhaustive list of missing features:
> >  * burst mode
> >  * dynamic configuration of the DPHY based on the
> >  * support for additional input interfaces (SDI input)
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> > ---
> > Changes in v3:
> > - replace magic values by real timing calculation. The DPHY PLL clock
> >   is still hardcoded since we don't have a working DPHY block yet, and
> >   this is the piece of HW we need to dynamically configure the PLL
> >   rate based on the display refresh rate and the resolution.
> > - parse DSI devices represented with the OF-graph. This is needed to
> >   support DSI devices controlled through an external bus like I2C or
> >   SPI.
> > - use the DRM panel-bridge infrastructure to simplify the DRM panel
> >   logic
> > 
> > Changes in v2:
> > - rebase on v4.12-rc1 and adapt to driver to the drm_bridge API changes
> > - return the correct error when devm_clk_get(sysclk) fails
> > - add missing depends on OF and select DRM_PANEL in the Kconfig entry
> > ---
> >  drivers/gpu/drm/bridge/Kconfig|9 +
> >  drivers/gpu/drm/bridge/Makefile   |1 +
> >  drivers/gpu/drm/bridge/cdns-dsi.c | 1090 
> > +
> >  3 files changed, 1100 insertions(+)
> >  create mode 100644 drivers/gpu/drm/bridge/cdns-dsi.c  
> 
> We need some power management. At the moment the clocks are kept always
> enabled. Those need to be turned off when the IP is not used.

I can try to move the clk_prepare_enable/disable_unprepare() calls in
the bridge->enable/disable() hooks, but I'm not sure the DSI regs
content is kept when I disable dsi_p_clk.

> 
> > +static irqreturn_t cdns_dsi_interrupt(int irq, void *data)
> > +{
> > +   struct cdns_dsi *dsi = data;
> > +   irqreturn_t ret = IRQ_NONE;
> > +   u32 flag, ctl;
> > +
> > +   flag = readl(dsi->regs + DIRECT_CMD_STS_FLAG);
> > +   if (flag) {
> > +   ctl = readl(dsi->regs + DIRECT_CMD_STS_CTL);
> > +   ctl &= ~flag;
> > +   writel(ctl, dsi->regs + DIRECT_CMD_STS_CTL);  
> 
> I presume it's the enable/disable bit in STS_CTL that prevents the
> interrupt from triggering again, instead of the status flag?

Yep.

> Just making
> sure, because I think on some IPs the status flag has been the one that
> triggers the interrupt.
> 
> > +   complete(>direct_cmd_comp);
> > +   ret = IRQ_HANDLED;
> > +   }
> > +
> > +   return ret;
> > +}
> > +
> > +static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host,
> > +const struct mipi_dsi_msg *msg)
> > +{
> > +   struct cdns_dsi *dsi = to_cdns_dsi(host);
> > +   u32 cmd, sts, val, wait = WRITE_COMPLETED, ctl = 0;
> > +   struct mipi_dsi_packet packet;
> > +   int ret, i, tx_len, rx_len;
> > +
> > +   ret = mipi_dsi_create_packet(, msg);
> > +   if (ret)
> > +   return ret;
> > +
> > +   tx_len = msg->tx_buf ? msg->tx_len : 0;
> > +   rx_len = msg->rx_buf ? msg->rx_len : 0;
> > +
> > +   /* For read operations, the maximum TX len is 2. */  
> 
> Hmm, why is that?

I don't know, that's what is stated in the spec.
Excerpt from the CMD_SIZE field description:

"
For read operations, any value
written which is larger than 2
bytes will be ignored and the
command payload will be truncated
to 2 bytes.
"

> 
> > +   if (rx_len && tx_len > 2)
> > +   return -ENOTSUPP;
> > +
> > +   /* TX len is limited by the CMD FIFO depth. */
> > +   if (tx_len > dsi->direct_cmd_fifo_depth)
> > +   return -ENOTSUPP;
> > +
> > +   /* RX len is limited by the RX FIFO depth. */
> > +   if (rx_len > dsi->rx_fifo_depth)
> > +   return -ENOTSUPP;
> > +
> > +   cmd = CMD_SIZE(tx_len) | CMD_VCHAN_ID(msg->channel) |
> > + CMD_DATATYPE(msg->type);
> > +
> > +   if (msg->flags & MIPI_DSI_MSG_USE_LPM)
> > +   cmd |= CMD_LP_EN;
> > +
> > +   if (mipi_dsi_packet_format_is_long(msg->type

Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-20 Thread Boris Brezillon
On Tue, 19 Sep 2017 17:25:29 +0300
Tomi Valkeinen <tomi.valkei...@ti.com> wrote:

> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> On 19/09/17 16:48, Boris Brezillon wrote:
> > On Tue, 19 Sep 2017 16:38:31 +0300
> > Tomi Valkeinen <tomi.valkei...@ti.com> wrote:
> >   
> >> 
> >> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> >> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> >>
> >> On 19/09/17 16:25, Boris Brezillon wrote:  
> >>> On Tue, 19 Sep 2017 15:59:20 +0300
> >>> Tomi Valkeinen <tomi.valkei...@ti.com> wrote:
> >>> 
> >>>> Hi Boris,
> >>>>
> >>>>
> >>>> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> >>>> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> >>>>
> >>>> On 31/08/17 18:55, Boris Brezillon wrote:
> >>>>> Add a driver for Cadence DPI -> DSI bridge.
> >>>>>
> >>>>> This driver only support a subset of Cadence DSI bridge capabilities.
> >>>>>
> >>>>> Here is a non-exhaustive list of missing features:
> >>>>>  * burst mode
> >>>>>  * dynamic configuration of the DPHY based on the
> >>>>>  * support for additional input interfaces (SDI input)
> >>>>>
> >>>>> Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com> 
> >>>>>  
> >>>>
> >>>> 
> >>>>
> >>>>> +   dsi->pclk = devm_clk_get(>dev, "pclk");
> >>>>> +   if (IS_ERR(dsi->pclk))
> >>>>> +   return PTR_ERR(dsi->pclk);  
> >>>>
> >>>> What's the purpose of pclk? Isn't that normally dealt with the normal
> >>>> modesetting, enabled with the video stream? How could it even be enabled
> >>>> here, without anyone setting the rate?
> >>>
> >>> It's the peripheral clock, not the pixel clock, and AFAIU it has to be
> >>> enabled before accessing DSI registers.
> >>
> >> Is that the dsi_p_clk? I can't find "peripheral clock" in the specs.  
> > 
> > Yep, it is dsi_p_clk (the APB clock).
> >   
> >>
> >> I think calling it "pclk" in a display driver is very confusing, as
> >> pclk, at least for me, always means pixel clock =).  
> > 
> > I can rename it if you prefer. What name would you like to see?
> > abp_clk? periph_clk? Something else?  
> 
> Is there something wrong with dsi_p_clk? If possible, it's nice if the
> terms in SW match to the HW docs. In the minimum, the DT doc should give
> the mapping from SW to HW terms, at the moment it just says "pclk".

I'll switch to dsi_p_clk and dsi_sys_clk.

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


Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-20 Thread Boris Brezillon
On Wed, 20 Sep 2017 15:42:50 +0300
Tomi Valkeinen <tomi.valkei...@ti.com> wrote:

> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> On 20/09/17 15:32, Boris Brezillon wrote:
> > On Wed, 20 Sep 2017 14:55:02 +0300
> > Tomi Valkeinen <tomi.valkei...@ti.com> wrote:
> >   
> >> Hi Boris,
> >>
> >>
> >> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> >> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> >>
> >> On 31/08/17 18:55, Boris Brezillon wrote:  
> >>> Add a driver for Cadence DPI -> DSI bridge.
> >>>
> >>> This driver only support a subset of Cadence DSI bridge capabilities.
> >>>
> >>> Here is a non-exhaustive list of missing features:
> >>>  * burst mode
> >>>  * dynamic configuration of the DPHY based on the
> >>>  * support for additional input interfaces (SDI input)
> >>>
> >>> Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> >>> ---
> >>> Changes in v3:
> >>> - replace magic values by real timing calculation. The DPHY PLL clock
> >>>   is still hardcoded since we don't have a working DPHY block yet, and
> >>>   this is the piece of HW we need to dynamically configure the PLL
> >>>   rate based on the display refresh rate and the resolution.
> >>> - parse DSI devices represented with the OF-graph. This is needed to
> >>>   support DSI devices controlled through an external bus like I2C or
> >>>   SPI.
> >>> - use the DRM panel-bridge infrastructure to simplify the DRM panel
> >>>   logic
> >>>
> >>> Changes in v2:
> >>> - rebase on v4.12-rc1 and adapt to driver to the drm_bridge API changes
> >>> - return the correct error when devm_clk_get(sysclk) fails
> >>> - add missing depends on OF and select DRM_PANEL in the Kconfig entry
> >>> ---
> >>>  drivers/gpu/drm/bridge/Kconfig|9 +
> >>>  drivers/gpu/drm/bridge/Makefile   |1 +
> >>>  drivers/gpu/drm/bridge/cdns-dsi.c | 1090 
> >>> +
> >>>  3 files changed, 1100 insertions(+)
> >>>  create mode 100644 drivers/gpu/drm/bridge/cdns-dsi.c
> >>
> >> We need some power management. At the moment the clocks are kept always
> >> enabled. Those need to be turned off when the IP is not used.  
> > 
> > I can try to move the clk_prepare_enable/disable_unprepare() calls in
> > the bridge->enable/disable() hooks, but I'm not sure the DSI regs
> > content is kept when I disable dsi_p_clk.  
> 
> Yes, context restore has to be handled.
> 
> I'm not sure how different it would be but you could use runtime PM, and
> its resume and suspend callbacks. Then you'd get delayed power-down for
> free, which would prevent suspend, for example, when the bridge is
> disabled, reconfigured and enabled again right away.

As you might already know I'm testing on an emulated system, and I'm
not sure everything is behaving as it will in the final design (once
integrated in a real SoC). I can add support for advanced PM mechanism
but I probably won't be able to test it, so I'd recommend doing the PM
related changes in a follow-up patch (AFAICT, none of the design
choices made in this driver prevent PM optimizations, so it should be
pretty easy to add this afterward).

> 
> >>> +static irqreturn_t cdns_dsi_interrupt(int irq, void *data)
> >>> +{
> >>> + struct cdns_dsi *dsi = data;
> >>> + irqreturn_t ret = IRQ_NONE;
> >>> + u32 flag, ctl;
> >>> +
> >>> + flag = readl(dsi->regs + DIRECT_CMD_STS_FLAG);
> >>> + if (flag) {
> >>> + ctl = readl(dsi->regs + DIRECT_CMD_STS_CTL);
> >>> + ctl &= ~flag;
> >>> + writel(ctl, dsi->regs + DIRECT_CMD_STS_CTL);
> >>
> >> I presume it's the enable/disable bit in STS_CTL that prevents the
> >> interrupt from triggering again, instead of the status flag?  
> > 
> > Yep.
> >   
> >> Just making
> >> sure, because I think on some IPs the status flag has been the one that
> >> triggers the interrupt.
> >>  
> >>> + complete(>direct_cmd_comp);
> >>> + ret = IRQ_HANDLED;
> >>> + }
> >>> +
> >>> + return ret;
> >>> +}
> >>> +
&

Re: [PATCH] drm/gem-cma-helper: Change the level of the allocation failure message

2017-10-05 Thread Boris Brezillon
On Thu, 5 Oct 2017 09:48:24 +0100
Eric Engestrom <eric.engest...@imgtec.com> wrote:

> On Wednesday, 2017-10-04 22:28:54 +, Eric Anholt wrote:
> > Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> >   
> > > drm_gem_cma_create() prints an error message when dma_alloc_wc() fails to
> > > allocate the amount of memory we requested. This can lead to annoying
> > > error messages when CMA is only one possible source of memory for the BO
> > > allocation.
> > >
> > > Turn this error message into a debug one and add a __must_check specifier
> > > to make sure all callers are checking the return value.
> > >
> > > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>  
> > 
> > The __must_check seems unnecessary to me -- you're definitely going to
> > be doing something with the return value, because otherwise why did you
> > call the object allocate function?  
> 
> Indeed, `__must_check` (aka `warn_unused_result`) only makes sure the
> return value is not discarded, which will probably always be true here.

I agree, this __must_check is not really useful here.

> 
> > The `warn_unused_result` attribute causes a warning to be emitted if
> > a caller of the function with this attribute does not use its return
> > value.  
> 
> I think we need a sparse attribute to check that the return value is
> IS_ERR()-checked?

Can we just turn the dev_err() into dev_dbg() for now? The 'force
callers to check IS_ERR()' is kind of orthogonal to the change I'm
doing here.

> (not volunteering, I have no idea how to add a sparse attribute :)

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


[PATCH v2] drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl

2017-10-04 Thread Boris Brezillon
This ioctl will allow us to purge inactive userspace buffers when the
system is running out of contiguous memory.

For now, the purge logic is rather dumb in that it does not try to
release only the amount of BO needed to meet the last CMA alloc request
but instead purges all objects placed in the purgeable pool as soon as
we experience a CMA allocation failure.

Note that the in-kernel BO cache is always purged before the purgeable
cache because those objects are known to be unused while objects marked
as purgeable by a userspace application/library might have to be
restored when they are marked back as unpurgeable, which can be
expensive.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
Hello,

Updates to libdrm, mesa and igt making use of this kernel feature can
be found on my github repos [1][2][3].

There's currently no debugfs hook to manually force a purge, but this
is being discussed and might be added later on.

Regards,

Boris

[1]https://github.com/bbrezillon/drm/tree/vc4/purgeable
[2]https://github.com/bbrezillon/mesa/tree/vc4/purgeable
[3]https://github.com/bbrezillon/igt/tree/vc4/purgeable

Changes in v2:
- Do not re-allocate BO's memory after when WILLNEED is asked after a purge
- Add purgeable/purged stats to debugfs and dumpstats
- Pad the drm_vc4_gem_madvise to make it 64-bit aligned
- Forbid madvise calls on internal BO objects (everything that is not
  meant to be exposed to userspace)
- Do not increment/decrement usecnt on internal BOs (they cannot be marked
  purgeable, so doing that is useless and error prone)
- Fix a few bugs related to usecnt refcounting
---
 drivers/gpu/drm/vc4/vc4_bo.c| 284 ++--
 drivers/gpu/drm/vc4/vc4_drv.c   |  10 +-
 drivers/gpu/drm/vc4/vc4_drv.h   |  44 +++
 drivers/gpu/drm/vc4/vc4_gem.c   | 153 +-
 drivers/gpu/drm/vc4/vc4_plane.c |  20 +++
 include/uapi/drm/vc4_drm.h  |  18 +++
 6 files changed, 512 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 3afdbf4bc10b..edb0062a58c7 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -42,7 +42,8 @@ static bool is_user_label(int label)
 
 static void vc4_bo_stats_dump(struct vc4_dev *vc4)
 {
-   int i;
+   size_t purgeable_size, purged_size;
+   int i, npurgeable, npurged;
 
for (i = 0; i < vc4->num_labels; i++) {
if (!vc4->bo_labels[i].num_allocated)
@@ -53,6 +54,21 @@ static void vc4_bo_stats_dump(struct vc4_dev *vc4)
 vc4->bo_labels[i].size_allocated / 1024,
 vc4->bo_labels[i].num_allocated);
}
+
+   mutex_lock(>purgeable.lock);
+   npurgeable = vc4->purgeable.num;
+   purgeable_size = vc4->purgeable.size;
+   purged_size = vc4->purgeable.purged_size;
+   npurged = vc4->purgeable.purged_num;
+   mutex_unlock(>purgeable.lock);
+
+   if (npurgeable)
+   DRM_INFO("%30s: %6dkb BOs (%d)\n", "userspace BO cache",
+purgeable_size / 1024, npurgeable);
+
+   if (npurged)
+   DRM_INFO("%30s: %6dkb BOs (%d)\n", "total purged BO",
+purged_size / 1024, npurged);
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -61,7 +77,8 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
struct drm_info_node *node = (struct drm_info_node *)m->private;
struct drm_device *dev = node->minor->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
-   int i;
+   size_t purgeable_size, purged_size;
+   int i, npurgeable, npurged;
 
mutex_lock(>bo_lock);
for (i = 0; i < vc4->num_labels; i++) {
@@ -75,6 +92,21 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
}
mutex_unlock(>bo_lock);
 
+   mutex_lock(>purgeable.lock);
+   npurgeable = vc4->purgeable.num;
+   purgeable_size = vc4->purgeable.size;
+   purged_size = vc4->purgeable.purged_size;
+   npurged = vc4->purgeable.purged_num;
+   mutex_unlock(>purgeable.lock);
+
+   if (npurgeable)
+   seq_printf(m, "%30s: %6dkb BOs (%d)\n", "userspace BO cache",
+  purgeable_size / 1024, npurgeable);
+
+   if (npurged)
+   seq_printf(m, "%30s: %6dkb BOs (%d)\n", "total purged BO",
+  purged_size / 1024, npurged);
+
return 0;
 }
 #endif
@@ -247,6 +279,104 @@ static void vc4_bo_cache_purge(struct drm_device *dev)
mutex_unlock(>bo_lock);
 }
 
+void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo)
+{
+   struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
+
+   mutex_lock(>purgeable.lock);
+   list_add_tail(>size_head, >purgeable.list);
+   vc4->purgeable.num++;
+   v

[PATCH] cma: Take __GFP_NOWARN into account in cma_alloc()

2017-10-04 Thread Boris Brezillon
cma_alloc() unconditionally prints an INFO message when the CMA
allocation fails. Make this message conditional on the non-presence of
__GFP_NOWARN in gfp_mask.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
Hello,

This patch aims at removing INFO messages that are displayed when the
VC4 driver tries to allocate buffer objects. From the driver perspective
an allocation failure is acceptable, and the driver can possibly do
something to make following allocation succeed (like flushing the VC4
internal cache).

Also, I don't understand why this message is only an INFO message, and
not a WARN (pr_warn()). Please let me know if you have good reasons to
keep it as an unconditional pr_info().

Thanks,

Boris
---
 mm/cma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/cma.c b/mm/cma.c
index c0da318c020e..022e52bd8370 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -460,7 +460,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, 
unsigned int align,
 
trace_cma_alloc(pfn, page, count, align);
 
-   if (ret) {
+   if (ret && !(gfp_mask & __GFP_NOWARN)) {
pr_info("%s: alloc failed, req-size: %zu pages, ret: %d\n",
__func__, count, ret);
cma_debug_show_areas(cma);
-- 
2.11.0

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


[PATCH] drm/gem-cma-helper: Change the level of the allocation failure message

2017-10-04 Thread Boris Brezillon
drm_gem_cma_create() prints an error message when dma_alloc_wc() fails to
allocate the amount of memory we requested. This can lead to annoying
error messages when CMA is only one possible source of memory for the BO
allocation.

Turn this error message into a debug one and add a __must_check specifier
to make sure all callers are checking the return value.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
Hello,

This problem happens with the VC4 driver which can flush its internal
cache if case of CMA allocation failures. We should only complain if the
last CMA allocation fails (the one happening after all internal caches
have been flushed).

Regards,

Boris
---
 drivers/gpu/drm/drm_gem_cma_helper.c | 4 ++--
 include/drm/drm_gem_cma_helper.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index 373e33f22be4..e96c95c4fd23 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -95,7 +95,7 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size)
  *
  * Returns:
  * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative
- * error code on failure.
+ * error code on failure. Callers must check the return value.
  */
 struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
  size_t size)
@@ -112,7 +112,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct 
drm_device *drm,
cma_obj->vaddr = dma_alloc_wc(drm->dev, size, _obj->paddr,
  GFP_KERNEL | __GFP_NOWARN);
if (!cma_obj->vaddr) {
-   dev_err(drm->dev, "failed to allocate buffer with size %zu\n",
+   dev_dbg(drm->dev, "failed to allocate buffer with size %zu\n",
size);
ret = -ENOMEM;
goto error;
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index 58a739bf15f1..1b7d938a31a0 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -77,8 +77,8 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv,
 int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma);
 
 /* allocate physical memory */
-struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
- size_t size);
+struct drm_gem_cma_object *
+__must_check drm_gem_cma_create(struct drm_device *drm, size_t size);
 
 extern const struct vm_operations_struct drm_gem_cma_vm_ops;
 
-- 
2.11.0

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


Re: [PATCH v2] drm/gem-cma-helper: Change the level of the allocation failure message

2017-10-16 Thread Boris Brezillon
On Thu,  5 Oct 2017 13:29:17 +0200
Boris Brezillon <boris.brezil...@free-electrons.com> wrote:

> drm_gem_cma_create() prints an error message when dma_alloc_wc() fails to
> allocate the amount of memory we requested. This can lead to annoying
> error messages when CMA is only one possible source of memory for the BO
> allocation. Turn this error message into a debug one.

Applied to drm-misc-next.

> 
> Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
> Reviewed-by: Eric Engestrom <eric.engest...@imgtec.com>
> ---
> Changes in v2:
> - Remove __must_check attribute
> ---
>  drivers/gpu/drm/drm_gem_cma_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
> b/drivers/gpu/drm/drm_gem_cma_helper.c
> index 373e33f22be4..020e7668dfab 100644
> --- a/drivers/gpu/drm/drm_gem_cma_helper.c
> +++ b/drivers/gpu/drm/drm_gem_cma_helper.c
> @@ -112,7 +112,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct 
> drm_device *drm,
>   cma_obj->vaddr = dma_alloc_wc(drm->dev, size, _obj->paddr,
> GFP_KERNEL | __GFP_NOWARN);
>   if (!cma_obj->vaddr) {
> - dev_err(drm->dev, "failed to allocate buffer with size %zu\n",
> + dev_dbg(drm->dev, "failed to allocate buffer with size %zu\n",
>   size);
>   ret = -ENOMEM;
>   goto error;

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


[PATCH v2] drm/gem-cma-helper: Change the level of the allocation failure message

2017-10-05 Thread Boris Brezillon
drm_gem_cma_create() prints an error message when dma_alloc_wc() fails to
allocate the amount of memory we requested. This can lead to annoying
error messages when CMA is only one possible source of memory for the BO
allocation. Turn this error message into a debug one.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Reviewed-by: Eric Engestrom <eric.engest...@imgtec.com>
---
Changes in v2:
- Remove __must_check attribute
---
 drivers/gpu/drm/drm_gem_cma_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index 373e33f22be4..020e7668dfab 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -112,7 +112,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct 
drm_device *drm,
cma_obj->vaddr = dma_alloc_wc(drm->dev, size, _obj->paddr,
  GFP_KERNEL | __GFP_NOWARN);
if (!cma_obj->vaddr) {
-   dev_err(drm->dev, "failed to allocate buffer with size %zu\n",
+   dev_dbg(drm->dev, "failed to allocate buffer with size %zu\n",
size);
ret = -ENOMEM;
goto error;
-- 
2.11.0

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


[PATCH v3] drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl

2017-10-13 Thread Boris Brezillon
This ioctl will allow us to purge inactive userspace buffers when the
system is running out of contiguous memory.

For now, the purge logic is rather dumb in that it does not try to
release only the amount of BO needed to meet the last CMA alloc request
but instead purges all objects placed in the purgeable pool as soon as
we experience a CMA allocation failure.

Note that the in-kernel BO cache is always purged before the purgeable
cache because those objects are known to be unused while objects marked
as purgeable by a userspace application/library might have to be
restored when they are marked back as unpurgeable, which can be
expensive.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
Hello,

Updates to libdrm, mesa and igt making use of this kernel feature can
be found on my github repos [1][2][3].

There's currently no debugfs hook to manually force a purge, but this
is being discussed and might be added later on.

Regards,

Boris

[1]https://github.com/bbrezillon/drm/tree/vc4/purgeable
[2]https://github.com/bbrezillon/mesa/tree/vc4/purgeable
[3]https://github.com/bbrezillon/igt/tree/vc4/purgeable

Changes in v3:
- Use %zd formatters when printing size_t values
- rework detection of BOs that do not support the MADV ioctl
- replace DRM_ERROR by DRM_DEBUG in the ioctl path
- do not explicitly memzero purged BO mem
- check that pad is set to zero in the madv ioctl function

Changes in v2:
- Do not re-allocate BO's memory after when WILLNEED is asked after a purge
- Add purgeable/purged stats to debugfs and dumpstats
- Pad the drm_vc4_gem_madvise to make it 64-bit aligned
- Forbid madvise calls on internal BO objects (everything that is not
  meant to be exposed to userspace)
- Do not increment/decrement usecnt on internal BOs (they cannot be marked
  purgeable, so doing that is useless and error prone)
- Fix a few bugs related to usecnt refcounting
---
 drivers/gpu/drm/vc4/vc4_bo.c| 292 ++--
 drivers/gpu/drm/vc4/vc4_drv.c   |  10 +-
 drivers/gpu/drm/vc4/vc4_drv.h   |  30 +
 drivers/gpu/drm/vc4/vc4_gem.c   | 156 -
 drivers/gpu/drm/vc4/vc4_plane.c |  20 +++
 include/uapi/drm/vc4_drm.h  |  19 +++
 6 files changed, 512 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 3afdbf4bc10b..e4d13bbef54f 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -42,6 +42,8 @@ static bool is_user_label(int label)
 
 static void vc4_bo_stats_dump(struct vc4_dev *vc4)
 {
+   size_t purgeable_size, purged_size;
+   unsigned int npurgeable, npurged;
int i;
 
for (i = 0; i < vc4->num_labels; i++) {
@@ -53,6 +55,21 @@ static void vc4_bo_stats_dump(struct vc4_dev *vc4)
 vc4->bo_labels[i].size_allocated / 1024,
 vc4->bo_labels[i].num_allocated);
}
+
+   mutex_lock(>purgeable.lock);
+   npurgeable = vc4->purgeable.num;
+   purgeable_size = vc4->purgeable.size;
+   purged_size = vc4->purgeable.purged_size;
+   npurged = vc4->purgeable.purged_num;
+   mutex_unlock(>purgeable.lock);
+
+   if (npurgeable)
+   DRM_INFO("%30s: %6zdkb BOs (%d)\n", "userspace BO cache",
+purgeable_size / 1024, npurgeable);
+
+   if (npurged)
+   DRM_INFO("%30s: %6zdkb BOs (%d)\n", "total purged BO",
+purged_size / 1024, npurged);
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -61,6 +78,8 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
struct drm_info_node *node = (struct drm_info_node *)m->private;
struct drm_device *dev = node->minor->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+   size_t purgeable_size, purged_size;
+   unsigned int npurgeable, npurged;
int i;
 
mutex_lock(>bo_lock);
@@ -75,6 +94,21 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
}
mutex_unlock(>bo_lock);
 
+   mutex_lock(>purgeable.lock);
+   npurgeable = vc4->purgeable.num;
+   purgeable_size = vc4->purgeable.size;
+   purged_size = vc4->purgeable.purged_size;
+   npurged = vc4->purgeable.purged_num;
+   mutex_unlock(>purgeable.lock);
+
+   if (npurgeable)
+   seq_printf(m, "%30s: %6dkb BOs (%d)\n", "userspace BO cache",
+  purgeable_size / 1024, npurgeable);
+
+   if (npurged)
+   seq_printf(m, "%30s: %6dkb BOs (%d)\n", "total purged BO",
+  purged_size / 1024, npurged);
+
return 0;
 }
 #endif
@@ -247,6 +281,102 @@ static void vc4_bo_cache_purge(struct drm_device *dev)
mutex_unlock(>bo_lock);
 }
 
+void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo)
+{
+   struct vc4_dev *vc

Re: [PATCH v2] drm/vc4: Fix sleeps during the IRQ handler for DSI transactions.

2017-10-14 Thread Boris Brezillon
On Fri, 13 Oct 2017 17:12:55 -0700
Eric Anholt <e...@anholt.net> wrote:

> VC4's DSI1 has a bug where the AXI connection is broken for 32-bit
> writes from the CPU, so we use the DMA engine to DMA 32-bit values
> into registers instead.  That sleeps, so we can't do it from the top
> half.
> 
> As a solution, use an interrupt thread so that all our writes happen
> when sleeping is is allowed.
> 
> v2: Use IRQF_ONESHOT (suggested by Boris)
> 
> Signed-off-by: Eric Anholt <e...@anholt.net>

Reviewed-by: Boris Brezillon <boris.brezil...@free-electrons.com>

> ---
> 
> Boris, that cleanup ended up working and it looks great.  Thanks!
> 
>  drivers/gpu/drm/vc4/vc4_dsi.c | 31 +--
>  1 file changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
> index 554605af344e..3b74fda5662d 100644
> --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> @@ -1360,6 +1360,25 @@ static void dsi_handle_error(struct vc4_dsi *dsi,
>   *ret = IRQ_HANDLED;
>  }
>  
> +/* Initial handler for port 1 where we need the reg_dma workaround.
> + * The register DMA writes sleep, so we can't do it in the top half.
> + * Instead we use IRQF_ONESHOT so that the IRQ gets disabled in the
> + * parent interrupt contrller until our interrupt thread is done.
> + */
> +static irqreturn_t vc4_dsi_irq_defer_to_thread_handler(int irq, void *data)
> +{
> + struct vc4_dsi *dsi = data;
> + u32 stat = DSI_PORT_READ(INT_STAT);
> +
> + if (!stat)
> + return IRQ_NONE;
> +
> + return IRQ_WAKE_THREAD;
> +}
> +
> +/* Normal IRQ handler for port 0, or the threaded IRQ handler for port
> + * 1 where we need the reg_dma workaround.
> + */
>  static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)
>  {
>   struct vc4_dsi *dsi = data;
> @@ -1539,8 +1558,16 @@ static int vc4_dsi_bind(struct device *dev, struct 
> device *master, void *data)
>   /* Clear any existing interrupt state. */
>   DSI_PORT_WRITE(INT_STAT, DSI_PORT_READ(INT_STAT));
>  
> - ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
> -vc4_dsi_irq_handler, 0, "vc4 dsi", dsi);
> + if (dsi->reg_dma_mem) {
> + ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
> + 
> vc4_dsi_irq_defer_to_thread_handler,
> + vc4_dsi_irq_handler,
> + IRQF_ONESHOT,
> + "vc4 dsi", dsi);
> + } else {
> + ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
> +vc4_dsi_irq_handler, 0, "vc4 dsi", dsi);
> + }
>   if (ret) {
>   if (ret != -EPROBE_DEFER)
>   dev_err(dev, "Failed to get interrupt: %d\n", ret);

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


Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-10-11 Thread Boris Brezillon
Hi Archit,

On Thu, 7 Sep 2017 15:06:13 +0530
Archit Taneja  wrote:

> 
> > +
> > +static void cdns_dsi_bridge_disable(struct drm_bridge *bridge)
> > +{
> > +   struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
> > +   struct cdns_dsi *dsi = input_to_dsi(input);
> > +   u32 val;
> > +
> > +   val = readl(dsi->regs + MCTL_MAIN_DATA_CTL);
> > +   val &= ~(IF_VID_SELECT_MASK | IF_VID_MODE | VID_EN | HOST_EOT_GEN |
> > +DISP_EOT_GEN);  
> 
> I see some truncation related sparse warnings here and a couple of other 
> places
> when building against arm32. Those would be nice to fix.

I had a look and it seems to happen everytime I use GENMASK() (the
truncation is harmless, but sparse complains).
If you don't mind, I'd prefer to keep GENMASK() rather than manually
defining masks, but maybe you have an idea how to fix these warnings
without getting rid of GENMASK().

> 
> > +   writel(val, dsi->regs + MCTL_MAIN_DATA_CTL);
> > +
> > +   val = readl(dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id);
> > +   writel(val, dsi->regs + MCTL_MAIN_EN);
> > +}

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


Re: [PATCH v6 1/5] drm/vc4: Move the DSI clock divider workaround closer to the clock call.

2017-10-11 Thread Boris Brezillon
On Tue, 15 Aug 2017 16:47:18 -0700
Eric Anholt <e...@anholt.net> wrote:

> We want the adjusted_mode->clock to be the actual clock we're
> expecting to program, so that consumers see the right values for clock
> and vrefresh.
> 
> Signed-off-by: Eric Anholt <e...@anholt.net>

Reviewed-by: Boris Brezillon <boris.brezil...@free-electrons.com>

> ---
>  drivers/gpu/drm/vc4/vc4_dsi.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
> index d1e0dc908048..eb787eed8abe 100644
> --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> @@ -859,11 +859,7 @@ static bool vc4_dsi_encoder_mode_fixup(struct 
> drm_encoder *encoder,
>   pll_clock = parent_rate / divider;
>   pixel_clock_hz = pll_clock / dsi->divider;
>  
> - /* Round up the clk_set_rate() request slightly, since
> -  * PLLD_DSI1 is an integer divider and its rate selection will
> -  * never round up.
> -  */
> - adjusted_mode->clock = pixel_clock_hz / 1000 + 1;
> + adjusted_mode->clock = pixel_clock_hz / 1000;
>  
>   /* Given the new pixel clock, adjust HFP to keep vrefresh the same. */
>   adjusted_mode->htotal = pixel_clock_hz / (mode->vrefresh * 
> mode->vtotal);
> @@ -900,7 +896,11 @@ static void vc4_dsi_encoder_enable(struct drm_encoder 
> *encoder)
>   vc4_dsi_dump_regs(dsi);
>   }
>  
> - phy_clock = pixel_clock_hz * dsi->divider;
> + /* Round up the clk_set_rate() request slightly, since
> +  * PLLD_DSI1 is an integer divider and its rate selection will
> +  * never round up.
> +  */
> + phy_clock = (pixel_clock_hz + 1000) * dsi->divider;
>   ret = clk_set_rate(dsi->pll_phy_clock, phy_clock);
>   if (ret) {
>   dev_err(>pdev->dev,

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


Re: [PATCH v6 2/5] drm/vc4: Avoid using vrefresh==0 mode in DSI htotal math.

2017-10-11 Thread Boris Brezillon
On Tue, 15 Aug 2017 16:47:19 -0700
Eric Anholt <e...@anholt.net> wrote:

> The incoming mode might have a missing vrefresh field if it came from
> drmModeSetCrtc(), which the kernel is supposed to calculate using
> drm_mode_vrefresh().  We could either use that or the adjusted_mode's
> original vrefresh value.
> 
> However, we can maintain a more exact vrefresh value (not just the
> integer approximation), by scaling by the ratio of our clocks.
> 
> v2: Use math suggested by Andrzej Hajda instead.
> v3: Simplify math now that adjusted_mode->clock isn't padded.
> 
> Signed-off-by: Eric Anholt <e...@anholt.net>

Reviewed-by: Boris Brezillon <boris.brezil...@free-electrons.com>

> ---
>  drivers/gpu/drm/vc4/vc4_dsi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
> index eb787eed8abe..2516cd3a1d87 100644
> --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> @@ -862,7 +862,8 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder 
> *encoder,
>   adjusted_mode->clock = pixel_clock_hz / 1000;
>  
>   /* Given the new pixel clock, adjust HFP to keep vrefresh the same. */
> - adjusted_mode->htotal = pixel_clock_hz / (mode->vrefresh * 
> mode->vtotal);
> + adjusted_mode->htotal = (adjusted_mode->clock * mode->htotal /
> +  mode->clock);
>   adjusted_mode->hsync_end += adjusted_mode->htotal - mode->htotal;
>   adjusted_mode->hsync_start += adjusted_mode->htotal - mode->htotal;
>  

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


Re: [PATCH] drm/vc4: Fix pitch setup for T-format scanout.

2017-10-11 Thread Boris Brezillon
On Wed, 27 Sep 2017 12:32:09 -0700
Eric Anholt <e...@anholt.net> wrote:

> The documentation said to use src_w here, and I didn't consider that
> we actually needed to be using pitch somewhere in our setup.  Fixes
> scanout on my DSI panel when X11 does initial setup with 1920x1080
> HDMI and 800x480 DSI both at 0,0 of the same framebuffer.
> 
> Signed-off-by: Eric Anholt <e...@anholt.net>
> Fixes: 98830d91da08 ("drm/vc4: Add T-format scanout support.")
> ---
>  drivers/gpu/drm/vc4/vc4_plane.c | 20 +++-
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index 2968b3ebb895..4ad0b9fcae99 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -547,14 +547,24 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
>   tiling = SCALER_CTL0_TILING_LINEAR;
>   pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH);
>   break;
> - case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
> +
> + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: {
> + /* For T-tiled, the FB pitch is "how many bytes from
> +  * one row to the next, such that pitch * tile_h ==
> +  * tile_size * tiles_per_row."
> +  */
> + u32 tile_size_shift = 12;
> + u32 tile_h_shift = 5;

Maybe you should explain where those _shift values come from in the
above comment (tile size is 4K hence tile_size_shift = 12 and a
tile is a 32x32 pixels element, hence tile_h_shift = 5).

Other than that,

Reviewed-by: Boris Brezillon <boris.brezil...@free-electrons.com>

> + u32 tiles_w = fb->pitches[0] >> (tile_size_shift - 
> tile_h_shift);
> +
>   tiling = SCALER_CTL0_TILING_256B_OR_T;
>  
> - pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET),
> -   VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L),
> -   VC4_SET_FIELD((vc4_state->src_w[0] + 31) >> 5,
> - SCALER_PITCH0_TILE_WIDTH_R));
> + pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET) |
> +   VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L) |
> +   VC4_SET_FIELD(tiles_w, SCALER_PITCH0_TILE_WIDTH_R));
>   break;
> + }
> +
>   default:
>   DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx",
> (long long)fb->modifier);

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


Re: [PATCH 06/15] mtd: make device_type const

2017-08-21 Thread Boris Brezillon
Le Sat, 19 Aug 2017 13:52:17 +0530,
Bhumika Goyal  a écrit :

> Make this const as it is only stored in the type field of a device
> structure, which is const.
> Done using Coccinelle.
> 

Applied to l2-mtd/master.

Thanks,

Boris

> Signed-off-by: Bhumika Goyal 
> ---
>  drivers/mtd/mtdcore.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index f872a99..e7ea842 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -340,7 +340,7 @@ static ssize_t mtd_bbtblocks_show(struct device *dev,
>  };
>  ATTRIBUTE_GROUPS(mtd);
>  
> -static struct device_type mtd_devtype = {
> +static const struct device_type mtd_devtype = {
>   .name   = "mtd",
>   .groups = mtd_groups,
>   .release= mtd_release,

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


Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-01 Thread Boris Brezillon
On Fri, 01 Sep 2017 09:51:59 +0200
Andrzej Hajda <a.ha...@samsung.com> wrote:

> On 31.08.2017 17:55, Boris Brezillon wrote:
> > Add a driver for Cadence DPI -> DSI bridge.
> >
> > This driver only support a subset of Cadence DSI bridge capabilities.
> >
> > Here is a non-exhaustive list of missing features:
> >  * burst mode
> >  * dynamic configuration of the DPHY based on the
> >  * support for additional input interfaces (SDI input)
> >
> > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> > ---
> > Changes in v3:
> > - replace magic values by real timing calculation. The DPHY PLL clock
> >   is still hardcoded since we don't have a working DPHY block yet, and
> >   this is the piece of HW we need to dynamically configure the PLL
> >   rate based on the display refresh rate and the resolution.
> > - parse DSI devices represented with the OF-graph. This is needed to
> >   support DSI devices controlled through an external bus like I2C or
> >   SPI.
> > - use the DRM panel-bridge infrastructure to simplify the DRM panel
> >   logic
> >
> > Changes in v2:
> > - rebase on v4.12-rc1 and adapt to driver to the drm_bridge API changes
> > - return the correct error when devm_clk_get(sysclk) fails
> > - add missing depends on OF and select DRM_PANEL in the Kconfig entry
> > ---
> >  drivers/gpu/drm/bridge/Kconfig|9 +
> >  drivers/gpu/drm/bridge/Makefile   |1 +
> >  drivers/gpu/drm/bridge/cdns-dsi.c | 1090 
> > +
> >  3 files changed, 1100 insertions(+)
> >  create mode 100644 drivers/gpu/drm/bridge/cdns-dsi.c
> >
> > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> > index adf9ae0e0b7c..88c324b12e16 100644
> > --- a/drivers/gpu/drm/bridge/Kconfig
> > +++ b/drivers/gpu/drm/bridge/Kconfig
> > @@ -25,6 +25,15 @@ config DRM_ANALOGIX_ANX78XX
> >   the HDMI output of an application processor to MyDP
> >   or DisplayPort.
> >  
> > +config DRM_CDNS_DSI
> > +   tristate "Cadence DPI/DSI bridge"
> > +   select DRM_KMS_HELPER
> > +   select DRM_MIPI_DSI
> > +   select DRM_PANEL  
> 
> what about:
> select DRM_PANEL_BRIDGE

Oops, indeed. I'll add this dependency.

[...]

> > +
> > +static const struct of_device_id cdns_dsi_of_match[] = {
> > +   { .compatible = "cdns,dsi-1.3.1" },  
> 
> Do you really need version here? Wouldn't be enough checking ID_REG?
> This is only suggestion, no strong feelings.

You're right, I'll drop the version number.

> 
> The rest looks OK, so with Eric's comments addressed you can add:
> Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>

Thanks for your review.

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


[PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-08-31 Thread Boris Brezillon
Add a driver for Cadence DPI -> DSI bridge.

This driver only support a subset of Cadence DSI bridge capabilities.

Here is a non-exhaustive list of missing features:
 * burst mode
 * dynamic configuration of the DPHY based on the
 * support for additional input interfaces (SDI input)

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
Changes in v3:
- replace magic values by real timing calculation. The DPHY PLL clock
  is still hardcoded since we don't have a working DPHY block yet, and
  this is the piece of HW we need to dynamically configure the PLL
  rate based on the display refresh rate and the resolution.
- parse DSI devices represented with the OF-graph. This is needed to
  support DSI devices controlled through an external bus like I2C or
  SPI.
- use the DRM panel-bridge infrastructure to simplify the DRM panel
  logic

Changes in v2:
- rebase on v4.12-rc1 and adapt to driver to the drm_bridge API changes
- return the correct error when devm_clk_get(sysclk) fails
- add missing depends on OF and select DRM_PANEL in the Kconfig entry
---
 drivers/gpu/drm/bridge/Kconfig|9 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/cdns-dsi.c | 1090 +
 3 files changed, 1100 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cdns-dsi.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index adf9ae0e0b7c..88c324b12e16 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -25,6 +25,15 @@ config DRM_ANALOGIX_ANX78XX
  the HDMI output of an application processor to MyDP
  or DisplayPort.
 
+config DRM_CDNS_DSI
+   tristate "Cadence DPI/DSI bridge"
+   select DRM_KMS_HELPER
+   select DRM_MIPI_DSI
+   select DRM_PANEL
+   depends on OF
+   help
+ Support Cadence DPI to DSI bridge.
+
 config DRM_DUMB_VGA_DAC
tristate "Dumb VGA DAC Bridge support"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index defcf1e7ca1c..77b65e8ecf59 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
+obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
 obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
 obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
megachips-stdp-ge-b850v3-fw.o
diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c 
b/drivers/gpu/drm/bridge/cdns-dsi.c
new file mode 100644
index ..f5dc26c90b20
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cdns-dsi.c
@@ -0,0 +1,1090 @@
+/*
+ * Copyright: 2017 Cadence Design Systems, Inc.
+ *
+ * Author: Boris Brezillon <boris.brezil...@free-electrons.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IP_CONF0x0
+#define SP_HS_FIFO_DEPTH(x)(((x) & GENMASK(30, 26)) >> 26)
+#define SP_LP_FIFO_DEPTH(x)(((x) & GENMASK(25, 21)) >> 21)
+#define VRS_FIFO_DEPTH(x)  (((x) & GENMASK(20, 16)) >> 16)
+#define DIRCMD_FIFO_DEPTH(x)   (((x) & GENMASK(15, 13)) >> 13)
+#define SDI_IFACE_32   BIT(12)
+#define INTERNAL_DATAPATH_32   (0 << 10)
+#define INTERNAL_DATAPATH_16   (1 << 10)
+#define INTERNAL_DATAPATH_8(3 << 10)
+#define INTERNAL_DATAPATH_SIZE ((x) & GENMASK(11, 10))
+#define INTERNAL_DATAPATH_32   (0 << 10)
+#define INTERNAL_DATAPATH_16   (1 << 10)
+#define INTERNAL_DATAPATH_8(3 << 10)
+#define NUM_IFACE(x)   x) & GENMASK(9, 8)) >> 8) + 1)
+#define MAX_LANE_NB(x) (((x) & GENMASK(7, 6)) >> 6)
+#define RX_FIFO_DEPTH(x)   ((x) & GENMASK(5, 0))
+
+#define MCTL_MAIN_DATA_CTL 0x4
+#define TE_MIPI_POLLING_EN BIT(25)
+#define TE_HW_POLLING_EN   BIT(24)
+#define DISP_EOT_GEN   BIT(18)
+#define HOST_EOT_GEN   BIT(17)
+#define DISP_GEN_CHECKSUM  BIT(16)
+#define DISP_GEN_ECC

[PATCH v3 2/2] dt-bindings: drm/bridge: Document Cadence DSI bridge bindings

2017-08-31 Thread Boris Brezillon
Document the bindings used for the Cadence DSI bridge.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
Changes in v3:
- Fix clock names in the example
- Document how to represent DSI devices that are controller through
  an external bus like I2C or SPI

Changes in v2:
- None
---
 .../bindings/display/bridge/cdns,dsi.txt   | 109 +
 1 file changed, 109 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt

diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt 
b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt
new file mode 100644
index ..c70008bd8c0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt
@@ -0,0 +1,109 @@
+Cadence DSI bridge
+==
+
+The Cadence DSI bridge is a DPI to DSI bridge supporting up to 4 DSI lanes.
+
+Required properties:
+- compatible: should be set to "cdns,dsi-1.3.1".
+- reg: physical base address and length of the controller's registers.
+- interrupts: interrupt line connected to the DSI bridge.
+- clocks: DSI bridge clocks.
+- clock-names: must contain "pclk" and "sysclk".
+- phys: phandle link to the MIPI D-PHY controller.
+- phy-names: must contain "dphy".
+- #address-cells: must be set to 1.
+- #size-cells: must be set to 0.
+
+Required subnodes:
+- ports: Ports as described in Documentation/devicetree/bindings/graph.txt.
+  2 ports are available:
+  * port 0: this port is only needed if some of your DSI devices are
+   controlled through  an external bus like I2C or SPI. Can have at
+   most 4 endpoints. The endpoint number is directly encoding the
+   DSI virtual channel used by this device.
+  * port 1: represents the DPI input.
+  Other ports will be added later to support the new kind of inputs.
+
+- one subnode per DSI device connected on the DSI bus. Each DSI device should
+  contain a reg property encoding its virtual channel.
+
+Example:
+
+   dsi0: dsi@fd0c {
+   compatible = "cdns,dsi-1.3.1";
+   reg = <0x0 0xfd0c 0x0 0x1000>;
+   clocks = <>, <>;
+   clock-names = "pclk", "sysclk";
+   interrupts = <1>;
+   phys = <>;
+   phy-names = "dphy";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@1 {
+   reg = <1>;
+   dsi0_dpi_input: endpoint {
+   remote-endpoint = <_dpi_output>;
+   };
+   };
+   };
+
+   panel: dsi-dev@0 {
+   compatible = "<vendor,panel>";
+   reg = <0>;
+   };
+   };
+
+or
+
+   dsi0: dsi@fd0c {
+   compatible = "cdns,dsi";
+   reg = <0x0 0xfd0c 0x0 0x1000>;
+   clocks = <>, <>;
+   clock-names = "pclk", "sysclk";
+   interrupts = <1>;
+   phys = <>;
+   phy-names = "dphy";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   dsi0_output: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <_panel_input>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   dsi0_dpi_input: endpoint {
+   remote-endpoint = <_dpi_output>;
+   };
+   };
+   };
+   };
+
+   i2c@xxx {
+   panel: panel@59 {
+   compatible = "<vendor,panel>";
+   reg = <0x59>;
+
+   port {
+   dsi_panel_input: endpoint {
+   remote-endpoint = <_output>;
+   };
+   };
+   };
+   };
-- 
2.11.0

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


Re: [PATCH v3 2/2] dt-bindings: drm/bridge: Document Cadence DSI bridge bindings

2017-09-01 Thread Boris Brezillon
Hi Andrzej,

On Fri, 01 Sep 2017 08:28:13 +0200
Andrzej Hajda <a.ha...@samsung.com> wrote:

> On 31.08.2017 17:55, Boris Brezillon wrote:
> > Document the bindings used for the Cadence DSI bridge.
> >
> > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> > ---
> > Changes in v3:
> > - Fix clock names in the example
> > - Document how to represent DSI devices that are controller through
> >   an external bus like I2C or SPI
> >
> > Changes in v2:
> > - None
> > ---
> >  .../bindings/display/bridge/cdns,dsi.txt   | 109 
> > +
> >  1 file changed, 109 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt
> >
> > diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt 
> > b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt
> > new file mode 100644
> > index ..c70008bd8c0d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt
> > @@ -0,0 +1,109 @@
> > +Cadence DSI bridge
> > +==
> > +
> > +The Cadence DSI bridge is a DPI to DSI bridge supporting up to 4 DSI lanes.
> > +
> > +Required properties:
> > +- compatible: should be set to "cdns,dsi-1.3.1".
> > +- reg: physical base address and length of the controller's registers.
> > +- interrupts: interrupt line connected to the DSI bridge.
> > +- clocks: DSI bridge clocks.
> > +- clock-names: must contain "pclk" and "sysclk".
> > +- phys: phandle link to the MIPI D-PHY controller.
> > +- phy-names: must contain "dphy".
> > +- #address-cells: must be set to 1.
> > +- #size-cells: must be set to 0.
> > +
> > +Required subnodes:
> > +- ports: Ports as described in Documentation/devicetree/bindings/graph.txt.
> > +  2 ports are available:
> > +  * port 0: this port is only needed if some of your DSI devices are
> > +   controlled through  an external bus like I2C or SPI. Can have at
> > +   most 4 endpoints. The endpoint number is directly encoding the
> > +   DSI virtual channel used by this device.
> > +  * port 1: represents the DPI input.
> > +  Other ports will be added later to support the new kind of inputs.  
> 
> I think usual practice is to use lower numbers for input ports, higher
> for output ports.
> Is there a reason to do it this way?

The main reason I did that is because we only have one output port and
can have 1, 2 or 3 input ports: one is the DPI and the 2 others are
called SDI (some kind of serial input). I thought it would be better to
have all inputs using contiguous port numbers, and if we put inputs
first that means having a hole between the input and output port (port 0
would be the DPI input and port 3 the DSI output).

Honestly, that's just a detail, so if you prefer to have the input
ports start at 0 I'm fine with that.

Regards,

Boris


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


Re: [PATCH v3 1/2] drm/bridge: Add Cadence DSI driver

2017-09-01 Thread Boris Brezillon
Hi Eric,

On Thu, 31 Aug 2017 10:03:23 -0700
Eric Anholt <e...@anholt.net> wrote:

> Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> 
> > Add a driver for Cadence DPI -> DSI bridge.
> >
> > This driver only support a subset of Cadence DSI bridge capabilities.
> >
> > Here is a non-exhaustive list of missing features:
> >  * burst mode
> >  * dynamic configuration of the DPHY based on the
> >  * support for additional input interfaces (SDI input)
> >
> > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> > ---
> > Changes in v3:
> > - replace magic values by real timing calculation. The DPHY PLL clock
> >   is still hardcoded since we don't have a working DPHY block yet, and
> >   this is the piece of HW we need to dynamically configure the PLL
> >   rate based on the display refresh rate and the resolution.
> > - parse DSI devices represented with the OF-graph. This is needed to
> >   support DSI devices controlled through an external bus like I2C or
> >   SPI.
> > - use the DRM panel-bridge infrastructure to simplify the DRM panel
> >   logic  
> 
> Just a few comments from me.  With the few straightforward nitpicks
> fixed, it gets my:
> 
> Acked-by: Eric Anholt <e...@anholt.net>
> 
> > +static enum drm_mode_status
> > +cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> > +  const struct drm_display_mode *mode)
> > +{
> > +   struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
> > +   struct cdns_dsi *dsi = input_to_dsi(input);
> > +   struct cdns_dsi_output *output = >output;
> > +   int bpp;
> > +
> > +   /*
> > +* VFP_DSI should be less than VFP_DPI and VFP_DSI should be at
> > +* least 1.
> > +*/
> > +   if (mode->vtotal - mode->vsync_end < 2)
> > +   return MODE_V_ILLEGAL;
> > +
> > +   /* VSA_DSI = VSA_DPI and must be at least 2. */
> > +   if (mode->vsync_end - mode->vsync_start < 2)
> > +   return MODE_V_ILLEGAL;
> > +
> > +   /* HACT must be a 32-bits aligned. */  
> 
> s/a /
> 
> > +   bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
> > +   if ((mode->hdisplay * bpp) % 32)
> > +   return MODE_H_ILLEGAL;
> > +
> > +   return MODE_OK;
> > +}  
> 
> 
> > +static void cdns_dsi_bridge_enable(struct drm_bridge *bridge)
> > +{
> > +   struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
> > +   struct cdns_dsi *dsi = input_to_dsi(input);
> > +   struct cdns_dsi_output *output = >output;
> > +   u32 hsize0, hsa, hline, tmp, reg_wakeup, div;
> > +   unsigned long dphy_pll_period, tx_byte_period;
> > +   struct drm_display_mode *mode;
> > +   int bpp, nlanes;
> > +
> > +   mode = >encoder->crtc->state->adjusted_mode;
> > +   bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
> > +   nlanes = output->dev->lanes;
> > +
> > +   if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
> > +   tmp = mode->crtc_htotal - mode->crtc_hsync_end;
> > +   else
> > +   tmp = mode->crtc_htotal - mode->crtc_hsync_start;
> > +   tmp = (tmp * bpp) / 8;
> > +   tmp = tmp < DSI_HBP_FRAME_OVERHEAD ? 0 : tmp - DSI_HBP_FRAME_OVERHEAD;
> > +   hsize0 = HBP_LEN(tmp);
> > +
> > +   tmp = mode->crtc_hsync_start - mode->crtc_hdisplay;
> > +   tmp = (tmp * bpp) / 8;  
> 
> How is this scaling supposed to work when you have RGB666_PACKED (bpp =
> 18)?  It seems like there would be bad rounding issues.

That's a good question. The spec does not say anything about rounding,
but I guess rounding up is safer. Richard, any opinion on that?

> 
> > +   tmp = tmp < DSI_HFP_FRAME_OVERHEAD ? 0 : tmp - DSI_HFP_FRAME_OVERHEAD;
> > +   hsize0 |= HFP_LEN(tmp);
> > +
> > +   if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
> > +   tmp = mode->crtc_hsync_end - mode->crtc_hsync_start;
> > +   else
> > +   tmp = 0;
> > +   tmp = (tmp * 8) / bpp;  
> 
> This scaling is suspiciously different from the others around it.  Did
> you mean this?

It's a mistake, I'll fix that.

> 
> > +   tmp = tmp < DSI_HSA_FRAME_OVERHEAD ? 0 : tmp - DSI_HSA_FRAME_OVERHEAD;
> > +   hsa = tmp;
> > +   hsize0 |= HSA_LEN(tmp);
> > +
> > +   writel(hsize0, dsi->regs + VID_HSIZE1);
> > +   writel((mode->crtc_hdisplay * bpp) / 8, dsi->regs + VID_HSIZE2);
> 

Re: [PATCH] drm/vc4: Fix sleeps during the IRQ handler for DSI transactions.

2017-10-11 Thread Boris Brezillon
On Thu, 17 Aug 2017 14:04:55 -0700
Eric Anholt  wrote:

> VC4's DSI1 has a bug where the AXI connection is broken for 32-bit
> writes from the CPU, so we use the DMA engine to DMA 32-bit values
> into registers instead.  That sleeps, so we can't do it from the top
> half.
> 
> As a solution (suggested by Arnd), we can mask the IRQ in the irqchip
> in the top half, and re-enable it from an irqthread.
> 
> Signed-off-by: Eric Anholt 
> ---
>  drivers/gpu/drm/vc4/vc4_dsi.c | 39 +--
>  1 file changed, 37 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
> index ec1d646b3151..9556236b67d0 100644
> --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> @@ -516,6 +516,8 @@ struct vc4_dsi {
>   /* Whether we're on bcm2835's DSI0 or DSI1. */
>   int port;
>  
> + int irq;
> +
>   /* DSI channel for the panel we're connected to. */
>   u32 channel;
>   u32 lanes;
> @@ -1360,6 +1362,28 @@ static void dsi_handle_error(struct vc4_dsi *dsi,
>   *ret = IRQ_HANDLED;
>  }
>  
> +/* Initial handler for port 1 where we need the reg_dma workaround.
> + * The register DMA writes sleep, so we can't do it in the top half.
> + * Instead we just disable the interrupt in the only way we have
> + * available (mask it in the irqchip), and continue on to the threaded
> + * handler.
> + */
> +static irqreturn_t vc4_dsi_irq_defer_to_thread_handler(int irq, void *data)
> +{
> + struct vc4_dsi *dsi = data;
> + u32 stat = DSI_PORT_READ(INT_STAT);
> +
> + if (!stat)
> + return IRQ_NONE;
> +
> + disable_irq_nosync(dsi->irq);

Are you sure you need to explicitly disable the IRQ here? Did you try
with an IRQF_ONESHOT flag when registering your irq handler (this
should do exactly what you're doing here: mask the interrupt until
the threaded handler returns IRQ_DONE or IRQ_NONE [1])?

[1]http://elixir.free-electrons.com/linux/v4.3.2/source/include/linux/interrupt.h#L50

> +
> + return IRQ_WAKE_THREAD;
> +}
> +
> +/* Normal IRQ handler for port 0, or the threaded IRQ handler for port
> + * 1 where we need the reg_dma workaround.
> + */
>  static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)
>  {
>   struct vc4_dsi *dsi = data;
> @@ -1368,6 +1392,9 @@ static irqreturn_t vc4_dsi_irq_handler(int irq, void 
> *data)
>  
>   DSI_PORT_WRITE(INT_STAT, stat);
>  
> + if (dsi->reg_dma_mem)
> + enable_irq(dsi->irq);
> +
>   dsi_handle_error(dsi, , stat,
>DSI1_INT_ERR_SYNC_ESC, "LPDT sync");
>   dsi_handle_error(dsi, , stat,
> @@ -1539,8 +1566,16 @@ static int vc4_dsi_bind(struct device *dev, struct 
> device *master, void *data)
>   /* Clear any existing interrupt state. */
>   DSI_PORT_WRITE(INT_STAT, DSI_PORT_READ(INT_STAT));
>  
> - ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
> -vc4_dsi_irq_handler, 0, "vc4 dsi", dsi);
> + dsi->irq = platform_get_irq(pdev, 0);
> + if (dsi->reg_dma_mem) {
> + ret = devm_request_threaded_irq(dev, dsi->irq,
> + 
> vc4_dsi_irq_defer_to_thread_handler,
> + vc4_dsi_irq_handler, 0,
> + "vc4 dsi", dsi);
> + } else {
> + ret = devm_request_irq(dev, dsi->irq,
> +vc4_dsi_irq_handler, 0, "vc4 dsi", dsi);
> + }
>   if (ret) {
>   if (ret != -EPROBE_DEFER)
>   dev_err(dev, "Failed to get interrupt: %d\n", ret);

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


Re: [PATCH v6 3/5] drm/vc4: Set up the DSI host at pdev probe time, not component bind.

2017-10-11 Thread Boris Brezillon
On Tue, 15 Aug 2017 16:47:20 -0700
Eric Anholt <e...@anholt.net> wrote:

> We need the following things to happen in sequence:
> 
> DSI host creation
> DSI device creation in the panel driver (needs DSI host)
> DSI device attach from panel to host.
> DSI drm_panel_add()
> DSI encoder creation
> DSI encoder's DRM panel/bridge attach
> 
> Unless we allow device creation while the host isn't up yet, we need
> to break the -EPROBE_DEFER deadlock between the panel driver looking
> up the host and the host driver looking up the panel.  We can do so by
> moving the DSI host creation outside of the component bind loop, and
> the panel/bridge lookup/attach into the component bind process.
> 
> Signed-off-by: Eric Anholt <e...@anholt.net>

Reviewed-by: Boris Brezillon <boris.brezil...@free-electrons.com>

> ---
>  drivers/gpu/drm/vc4/vc4_dsi.c | 97 
> +--
>  1 file changed, 57 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
> index 2516cd3a1d87..ec1d646b3151 100644
> --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> @@ -33,6 +33,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -504,7 +505,6 @@ struct vc4_dsi {
>   struct mipi_dsi_host dsi_host;
>   struct drm_encoder *encoder;
>   struct drm_bridge *bridge;
> - bool is_panel_bridge;
>  
>   void __iomem *regs;
>  
> @@ -1289,7 +1289,6 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host 
> *host,
>  struct mipi_dsi_device *device)
>  {
>   struct vc4_dsi *dsi = host_to_dsi(host);
> - int ret = 0;
>  
>   dsi->lanes = device->lanes;
>   dsi->channel = device->channel;
> @@ -1324,34 +1323,12 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host 
> *host,
>   return 0;
>   }
>  
> - dsi->bridge = of_drm_find_bridge(device->dev.of_node);
> - if (!dsi->bridge) {
> - struct drm_panel *panel =
> - of_drm_find_panel(device->dev.of_node);
> -
> - dsi->bridge = drm_panel_bridge_add(panel,
> -DRM_MODE_CONNECTOR_DSI);
> - if (IS_ERR(dsi->bridge)) {
> - ret = PTR_ERR(dsi->bridge);
> - dsi->bridge = NULL;
> - return ret;
> - }
> - dsi->is_panel_bridge = true;
> - }
> -
> - return drm_bridge_attach(dsi->encoder, dsi->bridge, NULL);
> + return 0;
>  }
>  
>  static int vc4_dsi_host_detach(struct mipi_dsi_host *host,
>  struct mipi_dsi_device *device)
>  {
> - struct vc4_dsi *dsi = host_to_dsi(host);
> -
> - if (dsi->is_panel_bridge) {
> - drm_panel_bridge_remove(dsi->bridge);
> - dsi->bridge = NULL;
> - }
> -
>   return 0;
>  }
>  
> @@ -1493,16 +1470,13 @@ static int vc4_dsi_bind(struct device *dev, struct 
> device *master, void *data)
>   struct platform_device *pdev = to_platform_device(dev);
>   struct drm_device *drm = dev_get_drvdata(master);
>   struct vc4_dev *vc4 = to_vc4_dev(drm);
> - struct vc4_dsi *dsi;
> + struct vc4_dsi *dsi = dev_get_drvdata(dev);
>   struct vc4_dsi_encoder *vc4_dsi_encoder;
> + struct drm_panel *panel;
>   const struct of_device_id *match;
>   dma_cap_mask_t dma_mask;
>   int ret;
>  
> - dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
> - if (!dsi)
> - return -ENOMEM;
> -
>   match = of_match_device(vc4_dsi_dt_match, dev);
>   if (!match)
>   return -ENODEV;
> @@ -1517,7 +1491,6 @@ static int vc4_dsi_bind(struct device *dev, struct 
> device *master, void *data)
>   vc4_dsi_encoder->dsi = dsi;
>   dsi->encoder = _dsi_encoder->base.base;
>  
> - dsi->pdev = pdev;
>   dsi->regs = vc4_ioremap_regs(pdev, 0);
>   if (IS_ERR(dsi->regs))
>   return PTR_ERR(dsi->regs);
> @@ -1598,6 +1571,18 @@ static int vc4_dsi_bind(struct device *dev, struct 
> device *master, void *data)
>   return ret;
>   }
>  
> + ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> +   , >bridge);
> + if (ret)
> + return ret;
> +
> + if (panel) {
> + dsi->bridge = devm_drm_panel_bridge_add(dev, panel,
> + 

[PATCH] drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl

2017-09-27 Thread Boris Brezillon
This ioctl will allow us to purge inactive userspace buffers when the
system is running out of contiguous memory.

For now, the purge logic is rather dumb in that it does not try to
release only the amount of BO needed to meet the last CMA alloc request
but instead purges all objects placed in the purgeable pool as soon as
we experience a CMA allocation failure.

Note that the in-kernel BO cache is always purged before the purgeable
cache because those objects are known to be unused while objects marked
as purgeable by a userspace application/library might have to be
restored when they are marked back as unpurgeable, which can be
expensive.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
Hello,

Updates to libdrm, mesa and igt making use of this kernel feature can
be found on my github repos [1][2][3].

There's currently no debugfs hook to manually force a purge, but this
is being discussed and will probably be added in v2.

Regards,

Boris

[1]https://github.com/bbrezillon/drm/tree/vc4/purgeable
[2]https://github.com/bbrezillon/mesa/tree/vc4/purgeable
[3]https://github.com/bbrezillon/igt/tree/vc4/purgeable
---
 drivers/gpu/drm/vc4/vc4_bo.c| 188 +--
 drivers/gpu/drm/vc4/vc4_drv.c   |   9 +-
 drivers/gpu/drm/vc4/vc4_drv.h   |  26 +
 drivers/gpu/drm/vc4/vc4_gem.c   | 213 +++-
 drivers/gpu/drm/vc4/vc4_plane.c |  20 
 drivers/gpu/drm/vc4/vc4_render_cl.c |   3 +
 include/uapi/drm/vc4_drm.h  |  12 ++
 7 files changed, 455 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 3afdbf4bc10b..f53aa508cb6f 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -233,7 +233,7 @@ static struct list_head *vc4_get_cache_list_for_size(struct 
drm_device *dev,
return >bo_cache.size_list[page_index];
 }
 
-static void vc4_bo_cache_purge(struct drm_device *dev)
+void vc4_bo_cache_purge(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
 
@@ -293,6 +293,8 @@ struct drm_gem_object *vc4_create_object(struct drm_device 
*dev, size_t size)
if (!bo)
return ERR_PTR(-ENOMEM);
 
+   bo->madv = VC4_MADV_WILLNEED;
+   mutex_init(>madv_lock);
mutex_lock(>bo_lock);
bo->label = VC4_BO_TYPE_KERNEL;
vc4->bo_labels[VC4_BO_TYPE_KERNEL].num_allocated++;
@@ -330,13 +332,29 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, 
size_t unaligned_size,
 * CMA allocations we've got laying around and try again.
 */
vc4_bo_cache_purge(dev);
+   cma_obj = drm_gem_cma_create(dev, size);
+   }
 
+   if (IS_ERR(cma_obj)) {
+   /*
+* Still not enough CMA memory, purge the userspace BO
+* cache and retry.
+* This is sub-optimal since we purge the whole userspace
+* BO cache which forces user that want to re-use the BO to
+* restore its initial content.
+* Ideally, we should purge entries one by one and retry
+* after each to see if CMA allocation succeeds. Or even
+* better, try to find an entry with at least the same
+* size.
+*/
+   vc4_userspace_bo_cache_purge(dev);
cma_obj = drm_gem_cma_create(dev, size);
-   if (IS_ERR(cma_obj)) {
-   DRM_ERROR("Failed to allocate from CMA:\n");
-   vc4_bo_stats_dump(vc4);
-   return ERR_PTR(-ENOMEM);
-   }
+   }
+
+   if (IS_ERR(cma_obj)) {
+   DRM_ERROR("Failed to allocate from CMA:\n");
+   vc4_bo_stats_dump(vc4);
+   return ERR_PTR(-ENOMEM);
}
bo = to_vc4_bo(_obj->base);
 
@@ -403,6 +421,15 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
struct vc4_bo *bo = to_vc4_bo(gem_bo);
struct list_head *cache_list;
 
+   /* Remove the BO from the purgeable list. */
+   mutex_lock(>madv_lock);
+   if (bo->madv == VC4_MADV_DONTNEED && !refcount_read(>usecnt)) {
+   mutex_lock(>purgeable.lock);
+   list_del(>size_head);
+   mutex_unlock(>purgeable.lock);
+   }
+   mutex_unlock(>madv_lock);
+
mutex_lock(>bo_lock);
/* If the object references someone else's memory, we can't cache it.
 */
@@ -418,7 +445,8 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
}
 
/* If this object was partially constructed but CMA allocation
-* had failed, just free it.
+* had failed, just free it. Can also happen when the BO has been
+* purged.
 */
if (!bo->base.vaddr) {
vc4_bo_destroy(bo);
@@ -437,

Re: [PATCH v3] drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl

2017-10-18 Thread Boris Brezillon
On Tue, 17 Oct 2017 17:16:29 -0700
Eric Anholt <e...@anholt.net> wrote:

> Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> 
> > This ioctl will allow us to purge inactive userspace buffers when the
> > system is running out of contiguous memory.
> >
> > For now, the purge logic is rather dumb in that it does not try to
> > release only the amount of BO needed to meet the last CMA alloc request
> > but instead purges all objects placed in the purgeable pool as soon as
> > we experience a CMA allocation failure.
> >
> > Note that the in-kernel BO cache is always purged before the purgeable
> > cache because those objects are known to be unused while objects marked
> > as purgeable by a userspace application/library might have to be
> > restored when they are marked back as unpurgeable, which can be
> > expensive.
> >
> > Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>  
> 
> Looking good!  Just a couple things I'd like to sort out before we
> merge.
> 
> > ---
> > Hello,
> >
> > Updates to libdrm, mesa and igt making use of this kernel feature can
> > be found on my github repos [1][2][3].
> >
> > There's currently no debugfs hook to manually force a purge, but this
> > is being discussed and might be added later on.
> >
> > Regards,
> >
> > Boris
> >
> > [1]https://github.com/bbrezillon/drm/tree/vc4/purgeable
> > [2]https://github.com/bbrezillon/mesa/tree/vc4/purgeable
> > [3]https://github.com/bbrezillon/igt/tree/vc4/purgeable
> >
> > Changes in v3:
> > - Use %zd formatters when printing size_t values
> > - rework detection of BOs that do not support the MADV ioctl
> > - replace DRM_ERROR by DRM_DEBUG in the ioctl path
> > - do not explicitly memzero purged BO mem
> > - check that pad is set to zero in the madv ioctl function
> >
> > Changes in v2:
> > - Do not re-allocate BO's memory after when WILLNEED is asked after a purge
> > - Add purgeable/purged stats to debugfs and dumpstats
> > - Pad the drm_vc4_gem_madvise to make it 64-bit aligned
> > - Forbid madvise calls on internal BO objects (everything that is not
> >   meant to be exposed to userspace)
> > - Do not increment/decrement usecnt on internal BOs (they cannot be marked
> >   purgeable, so doing that is useless and error prone)
> > - Fix a few bugs related to usecnt refcounting
> > ---
> >  drivers/gpu/drm/vc4/vc4_bo.c| 292 
> > ++--
> >  drivers/gpu/drm/vc4/vc4_drv.c   |  10 +-
> >  drivers/gpu/drm/vc4/vc4_drv.h   |  30 +
> >  drivers/gpu/drm/vc4/vc4_gem.c   | 156 -
> >  drivers/gpu/drm/vc4/vc4_plane.c |  20 +++
> >  include/uapi/drm/vc4_drm.h  |  19 +++
> >  6 files changed, 512 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
> > index 3afdbf4bc10b..e4d13bbef54f 100644
> > --- a/drivers/gpu/drm/vc4/vc4_bo.c
> > +++ b/drivers/gpu/drm/vc4/vc4_bo.c
> > @@ -42,6 +42,8 @@ static bool is_user_label(int label)
> >  
> >  static void vc4_bo_stats_dump(struct vc4_dev *vc4)
> >  {
> > +   size_t purgeable_size, purged_size;
> > +   unsigned int npurgeable, npurged;
> > int i;
> >  
> > for (i = 0; i < vc4->num_labels; i++) {
> > @@ -53,6 +55,21 @@ static void vc4_bo_stats_dump(struct vc4_dev *vc4)
> >  vc4->bo_labels[i].size_allocated / 1024,
> >  vc4->bo_labels[i].num_allocated);
> > }
> > +
> > +   mutex_lock(>purgeable.lock);
> > +   npurgeable = vc4->purgeable.num;
> > +   purgeable_size = vc4->purgeable.size;
> > +   purged_size = vc4->purgeable.purged_size;
> > +   npurged = vc4->purgeable.purged_num;
> > +   mutex_unlock(>purgeable.lock);
> > +
> > +   if (npurgeable)
> > +   DRM_INFO("%30s: %6zdkb BOs (%d)\n", "userspace BO cache",
> > +purgeable_size / 1024, npurgeable);
> > +
> > +   if (npurged)
> > +   DRM_INFO("%30s: %6zdkb BOs (%d)\n", "total purged BO",
> > +purged_size / 1024, npurged);
> >  }
> >  
> >  #ifdef CONFIG_DEBUG_FS
> > @@ -61,6 +78,8 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
> > struct drm_info_node *node = (struct drm_info_node *)m->private;
> > struct drm_device *dev = node->minor->dev;
> > struct vc4_dev *vc4 = to_vc4_dev(dev);
&

Re: [BUG] drm: vc4: refcount_t: increment on 0; use-after-free.

2017-11-26 Thread Boris Brezillon
Hi Kees,

On Sat, 25 Nov 2017 12:57:04 -0800
Kees Cook <keesc...@chromium.org> wrote:

> On Wed, Nov 22, 2017 at 11:57 PM, Daniel Vetter <dan...@ffwll.ch> wrote:
> > On Wed, Nov 22, 2017 at 07:21:00PM +0100, Boris Brezillon wrote:  
> >> On Wed, 22 Nov 2017 19:13:09 +0100
> >> Daniel Vetter <dan...@ffwll.ch> wrote:
> >>  
> >> > On Wed, Nov 22, 2017 at 6:51 PM, Boris Brezillon
> >> > <boris.brezil...@free-electrons.com> wrote:  
> >> > > Hi Stefan,
> >> > >
> >> > > On Wed, 22 Nov 2017 17:43:35 +0100 (CET)
> >> > > Stefan Wahren <stefan.wah...@i2se.com> wrote:
> >> > >  
> >> > >> Hi Boris,
> >> > >> if i boot Raspberry Pi 3 (ARM64, defconfig, linux-next-20171122) with 
> >> > >> sufficient CMA memory (32 MB), i'll get this warning during boot:
> >> > >>
> >> > >> [7.623510] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops 
> >> > >> [vc4])
> >> > >> [7.632453] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops 
> >> > >> [vc4])
> >> > >> [7.639707] vc4-drm soc:gpu: bound 3f40.hvs (ops vc4_hvs_ops 
> >> > >> [vc4])
> >> > >> [7.647364] vc4-drm soc:gpu: bound 3f206000.pixelvalve (ops 
> >> > >> vc4_crtc_ops [vc4])
> >> > >> [7.655451] vc4-drm soc:gpu: bound 3f207000.pixelvalve (ops 
> >> > >> vc4_crtc_ops [vc4])
> >> > >> [7.663415] vc4-drm soc:gpu: bound 3f807000.pixelvalve (ops 
> >> > >> vc4_crtc_ops [vc4])
> >> > >> [7.730580] vc4-drm soc:gpu: bound 3fc0.v3d (ops vc4_v3d_ops 
> >> > >> [vc4])
> >> > >> [7.743965] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on 
> >> > >> minor 0
> >> > >> [7.750841] [drm] Supports vblank timestamp caching Rev 2 
> >> > >> (21.10.2013).
> >> > >> [7.757620] [drm] Driver supports precise vblank timestamp query.
> >> > >> [7.811775] [ cut here ]
> >> > >> [7.811780] refcount_t: increment on 0; use-after-free.
> >> > >> [7.811881] WARNING: CPU: 2 PID: 2188 at lib/refcount.c:153 
> >> > >> refcount_inc+0x44/0x50
> >> > >> [7.811884] Modules linked in: vc4(+) cfg80211 cec drm_kms_helper 
> >> > >> smsc95xx usbnet drm rfkill brcmutil bcm2835_rng rng_core bcm2835_dma 
> >> > >> crc32_ce i2c_bcm2835 pwm_bcm2835 ip_tables x_tables ipv6
> >> > >> [7.811950] CPU: 2 PID: 2188 Comm: systemd-udevd Not tainted 
> >> > >> 4.14.0-next-20171122 #1
> >> > >> [7.811953] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT)
> >> > >> [7.811958] task: 800036b91c00 task.stack: 0d6f
> >> > >> [7.811967] pstate: 2005 (nzCv daif -PAN -UAO)
> >> > >> [7.811974] pc : refcount_inc+0x44/0x50
> >> > >> [7.811981] lr : refcount_inc+0x44/0x50
> >> > >> [7.811984] sp : 0d6f3300
> >> > >> [7.811988] x29: 0d6f3300 x28: 
> >> > >> [7.811996] x27: 0003 x26: 800037107800
> >> > >> [7.812004] x25: 0001 x24: 800035afdc00
> >> > >> [7.812012] x23:  x22: 800035dfa600
> >> > >> [7.812020] x21: 800035afd9b0 x20: 800035afd9a4
> >> > >> [7.812027] x19:  x18: 
> >> > >> [7.812034] x17: 0001 x16: 0019
> >> > >> [7.812042] x15: 0001 x14: fff0
> >> > >> [7.812049] x13: 090ae840 x12: 08fa2d50
> >> > >> [7.812057] x11: 08fa2000 x10: 090ad000
> >> > >> [7.812064] x9 :  x8 : 090b5c2f
> >> > >> [7.812072] x7 :  x6 : 0015ee00
> >> > >> [7.812079] x5 :  x4 : 
> >> > >> [7.812087] x3 :  x2 : 800030047000
> >> > >> [7.812094] x1 : 800036b91c00 x0 : 002b
> >> > >> [7.812102] Call trace:
> >> > >> [7.812109]  refcount_inc+0x44/0x50
> >> > >> [7.812226

Re: [PATCH] drm/vc4: Fix false positive WARN() backtrace on refcount_inc() usage

2017-11-23 Thread Boris Brezillon
On Wed, 22 Nov 2017 16:13:31 -0800
Eric Anholt <e...@anholt.net> wrote:

> Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> 
> > On Wed, 22 Nov 2017 13:16:08 -0800
> > Eric Anholt <e...@anholt.net> wrote:
> >  
> >> Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> >>   
> >> > With CONFIG_REFCOUNT_FULL enabled, refcount_inc() complains when it's
> >> > passed a refcount object that has its counter set to 0. In this driver,
> >> > this is a valid use case since we want to increment ->usecnt only when
> >> > the BO object starts to be used by real HW components and this is
> >> > definitely not the case when the BO is created.
> >> >
> >> > Fix the problem by using refcount_inc_not_zero() instead of
> >> > refcount_inc() and fallback to refcount_set(1) when
> >> > refcount_inc_not_zero() returns false. Note that this 2-steps operation
> >> > is not racy here because the whole section is protected by a mutex
> >> > which guarantees that the counter does not change between the
> >> > refcount_inc_not_zero() and refcount_set() calls.
> >> 
> >> If we're not following the model, and protecting the refcount by a
> >> mutex, shouldn't we just be using addition and subtraction instead of
> >> refcount's atomics?  
> >
> > Actually, this mutex is protecting the bo->madv value which has to be
> > checked when the counter reaches 0 (when decrementing) or 1 (when
> > incrementing). We just benefit from this protection here, but ideally
> > it would be better to have an refcount_inc_allow_zero() as suggested by
> > Daniel.  
> 
> Let me restate this to see if it makes sense: The refcount is always >=
> 0, this is is the only path that increases the refcount from 0 to 1, and
> it's (incidentally) protected by a mutex, so there's no race between the
> attempted increase from nonzero and the set from nonzero to 1.

Yep.

> 
> This seems fine to me as a bugfix.

The discussion is going on in the other thread, let's wait a bit
before taking a decision.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [BUG] drm: vc4: refcount_t: increment on 0; use-after-free.

2017-11-22 Thread Boris Brezillon
Hi Stefan,

On Wed, 22 Nov 2017 17:43:35 +0100 (CET)
Stefan Wahren  wrote:

> Hi Boris,
> if i boot Raspberry Pi 3 (ARM64, defconfig, linux-next-20171122) with 
> sufficient CMA memory (32 MB), i'll get this warning during boot:
> 
> [7.623510] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops [vc4])
> [7.632453] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4])
> [7.639707] vc4-drm soc:gpu: bound 3f40.hvs (ops vc4_hvs_ops [vc4])
> [7.647364] vc4-drm soc:gpu: bound 3f206000.pixelvalve (ops vc4_crtc_ops 
> [vc4])
> [7.655451] vc4-drm soc:gpu: bound 3f207000.pixelvalve (ops vc4_crtc_ops 
> [vc4])
> [7.663415] vc4-drm soc:gpu: bound 3f807000.pixelvalve (ops vc4_crtc_ops 
> [vc4])
> [7.730580] vc4-drm soc:gpu: bound 3fc0.v3d (ops vc4_v3d_ops [vc4])
> [7.743965] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 0
> [7.750841] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> [7.757620] [drm] Driver supports precise vblank timestamp query.
> [7.811775] [ cut here ]
> [7.811780] refcount_t: increment on 0; use-after-free.
> [7.811881] WARNING: CPU: 2 PID: 2188 at lib/refcount.c:153 
> refcount_inc+0x44/0x50
> [7.811884] Modules linked in: vc4(+) cfg80211 cec drm_kms_helper smsc95xx 
> usbnet drm rfkill brcmutil bcm2835_rng rng_core bcm2835_dma crc32_ce 
> i2c_bcm2835 pwm_bcm2835 ip_tables x_tables ipv6
> [7.811950] CPU: 2 PID: 2188 Comm: systemd-udevd Not tainted 
> 4.14.0-next-20171122 #1
> [7.811953] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT)
> [7.811958] task: 800036b91c00 task.stack: 0d6f
> [7.811967] pstate: 2005 (nzCv daif -PAN -UAO)
> [7.811974] pc : refcount_inc+0x44/0x50
> [7.811981] lr : refcount_inc+0x44/0x50
> [7.811984] sp : 0d6f3300
> [7.811988] x29: 0d6f3300 x28:  
> [7.811996] x27: 0003 x26: 800037107800 
> [7.812004] x25: 0001 x24: 800035afdc00 
> [7.812012] x23:  x22: 800035dfa600 
> [7.812020] x21: 800035afd9b0 x20: 800035afd9a4 
> [7.812027] x19:  x18:  
> [7.812034] x17: 0001 x16: 0019 
> [7.812042] x15: 0001 x14: fff0 
> [7.812049] x13: 090ae840 x12: 08fa2d50 
> [7.812057] x11: 08fa2000 x10: 090ad000 
> [7.812064] x9 :  x8 : 090b5c2f 
> [7.812072] x7 :  x6 : 0015ee00 
> [7.812079] x5 :  x4 :  
> [7.812087] x3 :  x2 : 800030047000 
> [7.812094] x1 : 800036b91c00 x0 : 002b 
> [7.812102] Call trace:
> [7.812109]  refcount_inc+0x44/0x50
> [7.812226]  vc4_bo_inc_usecnt+0x84/0x88 [vc4]
> [7.812310]  vc4_prepare_fb+0x40/0xf0 [vc4]
> [7.812460]  drm_atomic_helper_prepare_planes+0x54/0xf0 [drm_kms_helper]
> [7.812543]  vc4_atomic_commit+0x88/0x130 [vc4]
> [7.812868]  drm_atomic_commit+0x48/0x68 [drm]
> [7.813002]  restore_fbdev_mode_atomic+0x1d8/0x1e8 [drm_kms_helper]
> [7.813113]  restore_fbdev_mode+0x28/0x160 [drm_kms_helper]
> [7.813223]  drm_fb_helper_restore_fbdev_mode_unlocked.part.24+0x28/0x90 
> [drm_kms_helper]
> [7.813331]  drm_fb_helper_set_par+0x54/0xa8 [drm_kms_helper]
> [7.813346]  fbcon_init+0x4e8/0x538
> [7.813357]  visual_init+0xb4/0x108
> [7.813366]  do_bind_con_driver+0x1b8/0x3a0
> [7.813373]  do_take_over_console+0x150/0x1d0
> [7.813380]  do_fbcon_takeover+0x6c/0xf0
> [7.813387]  fbcon_event_notify+0x8fc/0x928
> [7.813399]  notifier_call_chain+0x50/0x90
> [7.813406]  __blocking_notifier_call_chain+0x4c/0x90
> [7.813413]  blocking_notifier_call_chain+0x14/0x20
> [7.813420]  fb_notifier_call_chain+0x1c/0x28
> [7.813426]  register_framebuffer+0x1d0/0x2d8
> [7.813533]  __drm_fb_helper_initial_config_and_unlock+0x1e8/0x350 
> [drm_kms_helper]
> [7.813639]  drm_fb_helper_initial_config+0x40/0x58 [drm_kms_helper]
> [7.813747]  drm_fbdev_cma_init_with_funcs+0x88/0x158 [drm_kms_helper]
> [7.813855]  drm_fbdev_cma_init+0x14/0x28 [drm_kms_helper]
> [7.813943]  vc4_kms_load+0xa4/0xf0 [vc4]
> [7.814026]  vc4_drm_bind+0x100/0x168 [vc4]
> [7.814038]  try_to_bring_up_master+0x144/0x1a8
> [7.814044]  component_master_add_with_match+0x9c/0xe0
> [7.814128]  vc4_platform_drm_probe+0xb4/0xf0 [vc4]
> [7.814137]  platform_drv_probe+0x58/0xc0
> [7.814146]  driver_probe_device+0x224/0x308
> [7.814153]  __driver_attach+0xac/0xb0
> [7.814161]  bus_for_each_dev+0x64/0xa0
> [7.814169]  driver_attach+0x20/0x28
> [7.814177]  bus_add_driver+0x108/0x228
> [7.814184]  driver_register+0x60/0xf8
> [7.814190]  __platform_driver_register+0x40/0x48
> [7.814274]  

Re: [BUG] drm: vc4: refcount_t: increment on 0; use-after-free.

2017-11-22 Thread Boris Brezillon
On Wed, 22 Nov 2017 19:13:09 +0100
Daniel Vetter <dan...@ffwll.ch> wrote:

> On Wed, Nov 22, 2017 at 6:51 PM, Boris Brezillon
> <boris.brezil...@free-electrons.com> wrote:
> > Hi Stefan,
> >
> > On Wed, 22 Nov 2017 17:43:35 +0100 (CET)
> > Stefan Wahren <stefan.wah...@i2se.com> wrote:
> >  
> >> Hi Boris,
> >> if i boot Raspberry Pi 3 (ARM64, defconfig, linux-next-20171122) with 
> >> sufficient CMA memory (32 MB), i'll get this warning during boot:
> >>
> >> [7.623510] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops 
> >> [vc4])
> >> [7.632453] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4])
> >> [7.639707] vc4-drm soc:gpu: bound 3f40.hvs (ops vc4_hvs_ops [vc4])
> >> [7.647364] vc4-drm soc:gpu: bound 3f206000.pixelvalve (ops 
> >> vc4_crtc_ops [vc4])
> >> [7.655451] vc4-drm soc:gpu: bound 3f207000.pixelvalve (ops 
> >> vc4_crtc_ops [vc4])
> >> [7.663415] vc4-drm soc:gpu: bound 3f807000.pixelvalve (ops 
> >> vc4_crtc_ops [vc4])
> >> [7.730580] vc4-drm soc:gpu: bound 3fc0.v3d (ops vc4_v3d_ops [vc4])
> >> [7.743965] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 0
> >> [7.750841] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> >> [7.757620] [drm] Driver supports precise vblank timestamp query.
> >> [7.811775] [ cut here ]
> >> [7.811780] refcount_t: increment on 0; use-after-free.
> >> [7.811881] WARNING: CPU: 2 PID: 2188 at lib/refcount.c:153 
> >> refcount_inc+0x44/0x50
> >> [7.811884] Modules linked in: vc4(+) cfg80211 cec drm_kms_helper 
> >> smsc95xx usbnet drm rfkill brcmutil bcm2835_rng rng_core bcm2835_dma 
> >> crc32_ce i2c_bcm2835 pwm_bcm2835 ip_tables x_tables ipv6
> >> [7.811950] CPU: 2 PID: 2188 Comm: systemd-udevd Not tainted 
> >> 4.14.0-next-20171122 #1
> >> [7.811953] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT)
> >> [7.811958] task: 800036b91c00 task.stack: 0d6f
> >> [7.811967] pstate: 2005 (nzCv daif -PAN -UAO)
> >> [7.811974] pc : refcount_inc+0x44/0x50
> >> [7.811981] lr : refcount_inc+0x44/0x50
> >> [7.811984] sp : 0d6f3300
> >> [7.811988] x29: 0d6f3300 x28: 
> >> [7.811996] x27: 0003 x26: 800037107800
> >> [7.812004] x25: 0001 x24: 800035afdc00
> >> [7.812012] x23:  x22: 800035dfa600
> >> [7.812020] x21: 800035afd9b0 x20: 800035afd9a4
> >> [7.812027] x19:  x18: 
> >> [7.812034] x17: 0001 x16: 0019
> >> [7.812042] x15: 0001 x14: fff0
> >> [7.812049] x13: 090ae840 x12: 08fa2d50
> >> [7.812057] x11: 08fa2000 x10: 090ad000
> >> [7.812064] x9 :  x8 : 090b5c2f
> >> [7.812072] x7 :  x6 : 0015ee00
> >> [7.812079] x5 :  x4 : 
> >> [7.812087] x3 :  x2 : 800030047000
> >> [7.812094] x1 : 800036b91c00 x0 : 002b
> >> [7.812102] Call trace:
> >> [7.812109]  refcount_inc+0x44/0x50
> >> [7.812226]  vc4_bo_inc_usecnt+0x84/0x88 [vc4]
> >> [7.812310]  vc4_prepare_fb+0x40/0xf0 [vc4]
> >> [7.812460]  drm_atomic_helper_prepare_planes+0x54/0xf0 [drm_kms_helper]
> >> [7.812543]  vc4_atomic_commit+0x88/0x130 [vc4]
> >> [7.812868]  drm_atomic_commit+0x48/0x68 [drm]
> >> [7.813002]  restore_fbdev_mode_atomic+0x1d8/0x1e8 [drm_kms_helper]
> >> [7.813113]  restore_fbdev_mode+0x28/0x160 [drm_kms_helper]
> >> [7.813223]  
> >> drm_fb_helper_restore_fbdev_mode_unlocked.part.24+0x28/0x90 
> >> [drm_kms_helper]
> >> [7.813331]  drm_fb_helper_set_par+0x54/0xa8 [drm_kms_helper]
> >> [7.813346]  fbcon_init+0x4e8/0x538
> >> [7.813357]  visual_init+0xb4/0x108
> >> [7.813366]  do_bind_con_driver+0x1b8/0x3a0
> >> [7.813373]  do_take_over_console+0x150/0x1d0
> >> [7.813380]  do_fbcon_takeover+0x6c/0xf0
> >> [7.813387]  fbcon_event_notify+0x8fc/0x928
> >> [7.813399]  notifier_call_chain+0x50/0x90
> >> [7.813406]  __blocking_notifier_call_chain+0x4c/0x90
> >> [7.813413]  blocking_notifier_call_chain+0x14/0x20
> >> 

[PATCH] drm/vc4: Fix false positive WARN() backtrace on refcount_inc() usage

2017-11-22 Thread Boris Brezillon
With CONFIG_REFCOUNT_FULL enabled, refcount_inc() complains when it's
passed a refcount object that has its counter set to 0. In this driver,
this is a valid use case since we want to increment ->usecnt only when
the BO object starts to be used by real HW components and this is
definitely not the case when the BO is created.

Fix the problem by using refcount_inc_not_zero() instead of
refcount_inc() and fallback to refcount_set(1) when
refcount_inc_not_zero() returns false. Note that this 2-steps operation
is not racy here because the whole section is protected by a mutex
which guarantees that the counter does not change between the
refcount_inc_not_zero() and refcount_set() calls.

Fixes: b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl")
Reported-by: Stefan Wahren <stefan.wah...@i2se.com>
Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
 drivers/gpu/drm/vc4/vc4_bo.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 4ae45d7dac42..2decc8e2c79f 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -637,7 +637,8 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo)
mutex_lock(>madv_lock);
switch (bo->madv) {
case VC4_MADV_WILLNEED:
-   refcount_inc(>usecnt);
+   if (!refcount_inc_not_zero(>usecnt))
+   refcount_set(>usecnt, 1);
ret = 0;
break;
case VC4_MADV_DONTNEED:
-- 
2.11.0

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


Re: [PATCH] drm/vc4: Fix false positive WARN() backtrace on refcount_inc() usage

2017-11-22 Thread Boris Brezillon
On Wed, 22 Nov 2017 13:16:08 -0800
Eric Anholt <e...@anholt.net> wrote:

> Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> 
> > With CONFIG_REFCOUNT_FULL enabled, refcount_inc() complains when it's
> > passed a refcount object that has its counter set to 0. In this driver,
> > this is a valid use case since we want to increment ->usecnt only when
> > the BO object starts to be used by real HW components and this is
> > definitely not the case when the BO is created.
> >
> > Fix the problem by using refcount_inc_not_zero() instead of
> > refcount_inc() and fallback to refcount_set(1) when
> > refcount_inc_not_zero() returns false. Note that this 2-steps operation
> > is not racy here because the whole section is protected by a mutex
> > which guarantees that the counter does not change between the
> > refcount_inc_not_zero() and refcount_set() calls.  
> 
> If we're not following the model, and protecting the refcount by a
> mutex, shouldn't we just be using addition and subtraction instead of
> refcount's atomics?

Actually, this mutex is protecting the bo->madv value which has to be
checked when the counter reaches 0 (when decrementing) or 1 (when
incrementing). We just benefit from this protection here, but ideally
it would be better to have an refcount_inc_allow_zero() as suggested by
Daniel.

Anyway, I can also use a regular counter and protect it with the madv
mutex, it's just that I thought using the existing refcount
infrastructure would be safer than open-coding it (actually, I found
several unbalanced refcounting issues thanks to this API while
developing the feature).
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 05/22] drm/atmel-hlcdc: Use drm_fb_cma_fbdev_init/fini()

2017-11-06 Thread Boris Brezillon
On Sat,  4 Nov 2017 14:03:59 +0100
Noralf Trønnes <nor...@tronnes.org> wrote:

> Use drm_fb_cma_fbdev_init() and drm_fb_cma_fbdev_fini() which relies on
> the fact that drm_device holds a pointer to the drm_fb_helper structure.
> This means that the driver doesn't have to keep track of that.
> Also use the drm_fb_helper functions directly.
> 
> Cc: Boris Brezillon <boris.brezil...@free-electrons.com>

Acked-by: Boris Brezillon <boris.brezil...@free-electrons.com>

> Signed-off-by: Noralf Trønnes <nor...@tronnes.org>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 26 --
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h |  2 +-
>  2 files changed, 5 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c 
> b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index c6e8061ffcfc..c1ea5c36b006 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -461,13 +461,6 @@ static struct drm_framebuffer 
> *atmel_hlcdc_fb_create(struct drm_device *dev,
>   return drm_gem_fb_create(dev, file_priv, mode_cmd);
>  }
>  
> -static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev)
> -{
> - struct atmel_hlcdc_dc *dc = dev->dev_private;
> -
> - drm_fbdev_cma_hotplug_event(dc->fbdev);
> -}
> -
>  struct atmel_hlcdc_dc_commit {
>   struct work_struct work;
>   struct drm_device *dev;
> @@ -563,7 +556,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device 
> *dev,
>  
>  static const struct drm_mode_config_funcs mode_config_funcs = {
>   .fb_create = atmel_hlcdc_fb_create,
> - .output_poll_changed = atmel_hlcdc_fb_output_poll_changed,
> + .output_poll_changed = drm_fb_helper_output_poll_changed,
>   .atomic_check = drm_atomic_helper_check,
>   .atomic_commit = atmel_hlcdc_dc_atomic_commit,
>  };
> @@ -665,10 +658,7 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev)
>  
>   platform_set_drvdata(pdev, dev);
>  
> - dc->fbdev = drm_fbdev_cma_init(dev, 24,
> - dev->mode_config.num_connector);
> - if (IS_ERR(dc->fbdev))
> - dc->fbdev = NULL;
> + drm_fb_cma_fbdev_init(dev, 24, 0);
>  
>   drm_kms_helper_poll_init(dev);
>  
> @@ -688,8 +678,7 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
>  {
>   struct atmel_hlcdc_dc *dc = dev->dev_private;
>  
> - if (dc->fbdev)
> - drm_fbdev_cma_fini(dc->fbdev);
> + drm_fb_cma_fbdev_fini(dev);
>   flush_workqueue(dc->wq);
>   drm_kms_helper_poll_fini(dev);
>   drm_mode_config_cleanup(dev);
> @@ -705,13 +694,6 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
>   destroy_workqueue(dc->wq);
>  }
>  
> -static void atmel_hlcdc_dc_lastclose(struct drm_device *dev)
> -{
> - struct atmel_hlcdc_dc *dc = dev->dev_private;
> -
> - drm_fbdev_cma_restore_mode(dc->fbdev);
> -}
> -
>  static int atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
>  {
>   struct atmel_hlcdc_dc *dc = dev->dev_private;
> @@ -744,7 +726,7 @@ static struct drm_driver atmel_hlcdc_dc_driver = {
>   .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
>  DRIVER_MODESET | DRIVER_PRIME |
>  DRIVER_ATOMIC,
> - .lastclose = atmel_hlcdc_dc_lastclose,
> + .lastclose = drm_fb_helper_lastclose,
>   .irq_handler = atmel_hlcdc_dc_irq_handler,
>   .irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
>   .irq_postinstall = atmel_hlcdc_dc_irq_postinstall,
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h 
> b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> index 6833ee253cfa..ab32d5b268d2 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> @@ -32,6 +32,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -374,7 +375,6 @@ struct atmel_hlcdc_dc {
>   const struct atmel_hlcdc_dc_desc *desc;
>   struct dma_pool *dscrpool;
>   struct atmel_hlcdc *hlcdc;
> - struct drm_fbdev_cma *fbdev;
>   struct drm_crtc *crtc;
>   struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
>   struct workqueue_struct *wq;

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


[PATCH] drm/vc4: Fix wrong printk format in vc4_bo_stats_debugfs()

2017-11-01 Thread Boris Brezillon
vc4->purgeable.size and vc4->purgeable.purged_size are size_t fields
and should be printed with a %zd specifier.

Fixes: b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl")
Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
 drivers/gpu/drm/vc4/vc4_bo.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 3c3d11236910..4ae45d7dac42 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -88,11 +88,11 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
 
mutex_lock(>purgeable.lock);
if (vc4->purgeable.num)
-   seq_printf(m, "%30s: %6dkb BOs (%d)\n", "userspace BO cache",
+   seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "userspace BO cache",
   vc4->purgeable.size / 1024, vc4->purgeable.num);
 
if (vc4->purgeable.purged_num)
-   seq_printf(m, "%30s: %6dkb BOs (%d)\n", "total purged BO",
+   seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "total purged BO",
   vc4->purgeable.purged_size / 1024,
   vc4->purgeable.purged_num);
mutex_unlock(>purgeable.lock);
-- 
2.11.0

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


Re: [PATCH] drm/vc4: use %z format string for size_t

2017-11-02 Thread Boris Brezillon
Hi Arnd,

On Thu,  2 Nov 2017 12:20:43 +0100
Arnd Bergmann  wrote:

> Printing a size_t variable needs to use the %z format string modifier
> rather than %l, otherwise we get this warning on 64-bit architectures:
> 
> drivers/gpu/drm/vc4/vc4_bo.c: In function 'vc4_bo_stats_debugfs':
> drivers/gpu/drm/vc4/vc4_bo.c:91:26: error: format '%d' expects argument of 
> type 'int', but argument 4 has type 'size_t {aka long unsigned int}' 
> [-Werror=format=]
> 

I already sent (and applied) a fix for this bug [1].

Regards,

Boris

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

> Fixes: b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl")
> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/gpu/drm/vc4/vc4_bo.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
> index 3c3d11236910..4ae45d7dac42 100644
> --- a/drivers/gpu/drm/vc4/vc4_bo.c
> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
> @@ -88,11 +88,11 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
>  
>   mutex_lock(>purgeable.lock);
>   if (vc4->purgeable.num)
> - seq_printf(m, "%30s: %6dkb BOs (%d)\n", "userspace BO cache",
> + seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "userspace BO cache",
>  vc4->purgeable.size / 1024, vc4->purgeable.num);
>  
>   if (vc4->purgeable.purged_num)
> - seq_printf(m, "%30s: %6dkb BOs (%d)\n", "total purged BO",
> + seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "total purged BO",
>  vc4->purgeable.purged_size / 1024,
>  vc4->purgeable.purged_num);
>   mutex_unlock(>purgeable.lock);

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


Re: [PATCH] drm/vc4: Fix wrong printk format in vc4_bo_stats_debugfs()

2017-11-02 Thread Boris Brezillon
On Wed,  1 Nov 2017 10:57:31 +0100
Boris Brezillon <boris.brezil...@free-electrons.com> wrote:

> vc4->purgeable.size and vc4->purgeable.purged_size are size_t fields
> and should be printed with a %zd specifier.

Applied to drm-misc-next.

> 
> Fixes: b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl")
> Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> ---
>  drivers/gpu/drm/vc4/vc4_bo.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
> index 3c3d11236910..4ae45d7dac42 100644
> --- a/drivers/gpu/drm/vc4/vc4_bo.c
> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
> @@ -88,11 +88,11 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
>  
>   mutex_lock(>purgeable.lock);
>   if (vc4->purgeable.num)
> - seq_printf(m, "%30s: %6dkb BOs (%d)\n", "userspace BO cache",
> + seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "userspace BO cache",
>  vc4->purgeable.size / 1024, vc4->purgeable.num);
>  
>   if (vc4->purgeable.purged_num)
> - seq_printf(m, "%30s: %6dkb BOs (%d)\n", "total purged BO",
> + seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "total purged BO",
>  vc4->purgeable.purged_size / 1024,
>  vc4->purgeable.purged_num);
>   mutex_unlock(>purgeable.lock);

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


[PATCH 2/2] drm/vc4: Expose performance counters to userspace

2017-12-07 Thread Boris Brezillon
The V3D engine has various hardware counters which might be interesting
to userspace performance analysis tools.

Expose new ioctls to create/destroy a performance monitor object and
query the counter values of this perfmance monitor.

Not that a perfomance monitor is given an ID that is only valid on the
file descriptor it has been allocated from. A perfmance monitor can be
attached to a CL submission and the driver will enable HW counters for
this request and update the performance monitor values at the end of the
job.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
 drivers/gpu/drm/vc4/Makefile  |   1 +
 drivers/gpu/drm/vc4/vc4_drv.c |  26 +
 drivers/gpu/drm/vc4/vc4_drv.h |  43 +
 drivers/gpu/drm/vc4/vc4_gem.c |  33 +--
 drivers/gpu/drm/vc4/vc4_irq.c |  13 ++-
 drivers/gpu/drm/vc4/vc4_perfmon.c | 195 ++
 drivers/gpu/drm/vc4/vc4_regs.h|  35 +--
 drivers/gpu/drm/vc4/vc4_v3d.c |  64 ++---
 include/uapi/drm/vc4_drm.h|  75 +++
 9 files changed, 414 insertions(+), 71 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_perfmon.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index 719a771f3d5c..1100e34d1947 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -14,6 +14,7 @@ vc4-y := \
vc4_vec.o \
vc4_hvs.o \
vc4_irq.o \
+   vc4_perfmon.o \
vc4_plane.o \
vc4_render_cl.o \
vc4_trace_points.o \
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 5c62013f8ca3..ca0d4419ba5a 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -102,6 +102,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void 
*data,
case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
case DRM_VC4_PARAM_SUPPORTS_MADVISE:
case DRM_VC4_PARAM_SUPPORTS_EXTENDED_CL:
+   case DRM_VC4_PARAM_SUPPORTS_PERFMON:
args->value = true;
break;
default:
@@ -119,6 +120,26 @@ static void vc4_lastclose(struct drm_device *dev)
drm_fbdev_cma_restore_mode(vc4->fbdev);
 }
 
+static int vc4_open(struct drm_device *dev, struct drm_file *file)
+{
+   struct vc4_file *vc4file;
+
+   vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL);
+   if (!vc4file)
+   return -ENOMEM;
+
+   vc4_perfmon_open_file(vc4file);
+   file->driver_priv = vc4file;
+   return 0;
+}
+
+static void vc4_close(struct drm_device *dev, struct drm_file *file)
+{
+   struct vc4_file *vc4file = file->driver_priv;
+
+   vc4_perfmon_close_file(vc4file);
+}
+
 static const struct vm_operations_struct vc4_vm_ops = {
.fault = vc4_fault,
.open = drm_gem_vm_open,
@@ -151,6 +172,9 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(VC4_LABEL_BO, vc4_label_bo_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(VC4_GEM_MADVISE, vc4_gem_madvise_ioctl, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(VC4_PERFMON_CREATE, vc4_perfmon_create_ioctl, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(VC4_PERFMON_DESTROY, vc4_perfmon_destroy_ioctl, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(VC4_PERFMON_GET_VALUES, vc4_perfmon_get_values_ioctl, 
DRM_RENDER_ALLOW),
 };
 
 static struct drm_driver vc4_drm_driver = {
@@ -161,6 +185,8 @@ static struct drm_driver vc4_drm_driver = {
DRIVER_RENDER |
DRIVER_PRIME),
.lastclose = vc4_lastclose,
+   .open = vc4_open,
+   .postclose = vc4_close,
.irq_handler = vc4_irq,
.irq_preinstall = vc4_irq_preinstall,
.irq_postinstall = vc4_irq_postinstall,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 3c54cc386443..d8156a00d77a 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -11,6 +11,8 @@
 #include 
 #include 
 
+#include "uapi/drm/vc4_drm.h"
+
 /* Don't forget to update vc4_bo.c: bo_type_names[] when adding to
  * this.
  */
@@ -29,6 +31,13 @@ enum vc4_kernel_bo_type {
VC4_BO_TYPE_COUNT
 };
 
+struct vc4_perfmon {
+   refcount_t refcnt;
+   u8 ncounters;
+   u8 events[DRM_VC4_MAX_PERF_COUNTERS];
+   u64 counters[0];
+};
+
 struct vc4_dev {
struct drm_device *dev;
 
@@ -158,6 +167,8 @@ struct vc4_dev {
} hangcheck;
 
struct semaphore async_modeset;
+
+   bool perfmon_active;
 };
 
 static inline struct vc4_dev *
@@ -410,6 +421,22 @@ struct vc4_exec_info {
void *uniforms_v;
uint32_t uniforms_p;
uint32_t uniforms_size;
+
+   /* Pointer to a performance monitor object if the user requested it,
+* NULL otherwise.
+*/
+   struct vc4_perfmon *perfmon;
+};
+
+/*
+ * Per

[PATCH 0/2] drm/vc4: Expose HW perf counters

2017-12-07 Thread Boris Brezillon
Hello,

Here is a proposal to expose VC4 HW perf counters to userspace. This
is done through 3 new ioctls which are allowing one to create, destroy
and query the status of a perf monitor object.

A perfmon object does not count things by its own, it has to be
attached to a SUBMIT_CL request to be activated. After the request, the
perfmon object stays around and can be attached to another request if
needed. Everytime the perfmon is attached to a SUBMIT_CL request, its
values are incremented by the HW perf counter values, so that the
counters can count things across GPU jobs. If you want to reset the
values of a perfmon, just destroy it and create a new one.

Note that the first patch is not directly related to perfmon itself,
but will allow us to easily extend what is passed to a SUBMIT_CL
request without having to add new ioctls.

Regards,

Boris
---

Boris Brezillon (2):
  drm/vc4: Add a mechanism to easily extend CL submissions
  drm/vc4: Expose performance counters to userspace

 drivers/gpu/drm/vc4/Makefile  |   1 +
 drivers/gpu/drm/vc4/vc4_drv.c |  27 ++
 drivers/gpu/drm/vc4/vc4_drv.h |  45 +
 drivers/gpu/drm/vc4/vc4_gem.c |  89 -
 drivers/gpu/drm/vc4/vc4_irq.c |  13 ++-
 drivers/gpu/drm/vc4/vc4_perfmon.c | 195 ++
 drivers/gpu/drm/vc4/vc4_regs.h|  35 +--
 drivers/gpu/drm/vc4/vc4_v3d.c |  64 ++---
 include/uapi/drm/vc4_drm.h| 156 --
 9 files changed, 545 insertions(+), 80 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_perfmon.c

-- 
2.11.0

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


[PATCH 1/2] drm/vc4: Add a mechanism to easily extend CL submissions

2017-12-07 Thread Boris Brezillon
The number of attributes/objects you can pass to the
DRM_IOCTL_VC4_SUBMIT_CL ioctl is limited by the drm_vc4_submit_cl struct
size.

Add a mechanism to easily pass extra attributes when submitting a CL to
the V3D engine.

Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
 drivers/gpu/drm/vc4/vc4_drv.c |  1 +
 drivers/gpu/drm/vc4/vc4_drv.h |  2 ++
 drivers/gpu/drm/vc4/vc4_gem.c | 60 +++-
 include/uapi/drm/vc4_drm.h| 81 +--
 4 files changed, 133 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index e3c29729da2e..5c62013f8ca3 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -101,6 +101,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void 
*data,
case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
case DRM_VC4_PARAM_SUPPORTS_MADVISE:
+   case DRM_VC4_PARAM_SUPPORTS_EXTENDED_CL:
args->value = true;
break;
default:
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 9c0d380c96f2..3c54cc386443 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -318,6 +318,8 @@ struct vc4_exec_info {
 
/* Kernel-space copy of the ioctl arguments */
struct drm_vc4_submit_cl *args;
+   uint32_t nchunks;
+   union drm_vc4_submit_cl_chunk *chunks;
 
/* This is the array of BOs that were looked up at the start of exec.
 * Command validation will use indices into this array.
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 6c32c89a83a9..06976c61422a 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -920,6 +920,7 @@ vc4_complete_exec(struct drm_device *dev, struct 
vc4_exec_info *exec)
}
mutex_unlock(>power_lock);
 
+   kfree(exec->chunks);
kfree(exec);
 }
 
@@ -1048,6 +1049,27 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
return ret;
 }
 
+static int
+vc4_parse_cl_chunk(struct vc4_dev *vc4, struct vc4_exec_info *exec,
+  const union drm_vc4_submit_cl_chunk *chunk)
+{
+   switch(chunk->dummy.type) {
+   case VC4_BIN_CL_CHUNK:
+   /* Update bin_cl related fields so that we don't have to patch
+* existing vc4_get_bcl() logic to support the BIN_CL
+* chunk.
+*/
+   exec->args->bin_cl = chunk->bin.ptr;
+   exec->args->bin_cl_size = chunk->bin.size;
+   break;
+
+   default:
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 /**
  * vc4_submit_cl_ioctl() - Submits a job (frame) to the VC4.
  * @dev: DRM device
@@ -1073,11 +1095,18 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR |
 VC4_SUBMIT_CL_FIXED_RCL_ORDER |
 VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X |
-VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y)) != 0) {
+VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y |
+VC4_SUBMIT_CL_EXTENDED)) != 0) {
DRM_DEBUG("Unknown flags: 0x%02x\n", args->flags);
return -EINVAL;
}
 
+   if ((args->flags & VC4_SUBMIT_CL_EXTENDED) &&
+   !args->num_cl_chunks) {
+   DRM_DEBUG("CL_EXTENDED flag set but no chunks provided\n");
+   return -EINVAL;
+   }
+
exec = kcalloc(1, sizeof(*exec), GFP_KERNEL);
if (!exec) {
DRM_ERROR("malloc failure on exec struct\n");
@@ -1103,6 +1132,35 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
if (ret)
goto fail;
 
+   if (args->flags & VC4_SUBMIT_CL_EXTENDED) {
+   uint32_t i;
+
+   ret = -ENOMEM;
+   exec->nchunks = args->num_cl_chunks;
+   exec->chunks = kcalloc(exec->nchunks, sizeof(*exec->chunks),
+  GFP_KERNEL);
+   if (!exec->chunks)
+   goto fail;
+
+   if (copy_from_user(exec->chunks,
+  u64_to_user_ptr(args->cl_chunks),
+  exec->nchunks *
+  sizeof(*exec->chunks)))
+   goto fail;
+
+   /* Reset ->bin_cl fields so that if no BIN_CL chunk is
+* passed, vc4_get_bcl() is skipped.
+*/
+   exec->args->bin_cl = 0;
+   exec->args->bin_cl_size = 0;
+   for (i = 0; i < exec->nchunks; i++) {
+

Re: [PATCH] drm/vc4: Fix false positive WARN() backtrace on refcount_inc() usage

2017-12-07 Thread Boris Brezillon
On Thu, 7 Dec 2017 13:31:34 +0100
Stefan Wahren <stefan.wah...@i2se.com> wrote:

> Hi Daniel,
> 
> 
> Am 24.11.2017 um 15:52 schrieb Daniel Vetter:
> > On Thu, Nov 23, 2017 at 09:24:11AM +0100, Boris Brezillon wrote:  
> >> On Wed, 22 Nov 2017 16:13:31 -0800
> >> Eric Anholt <e...@anholt.net> wrote:
> >>  
> >>> Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> >>>  
> >>>> On Wed, 22 Nov 2017 13:16:08 -0800
> >>>> Eric Anholt <e...@anholt.net> wrote:
> >>>> 
> >>>>> Boris Brezillon <boris.brezil...@free-electrons.com> writes:
> >>>>>  
> >>>>>> With CONFIG_REFCOUNT_FULL enabled, refcount_inc() complains when it's
> >>>>>> passed a refcount object that has its counter set to 0. In this driver,
> >>>>>> this is a valid use case since we want to increment ->usecnt only when
> >>>>>> the BO object starts to be used by real HW components and this is
> >>>>>> definitely not the case when the BO is created.
> >>>>>>
> >>>>>> Fix the problem by using refcount_inc_not_zero() instead of
> >>>>>> refcount_inc() and fallback to refcount_set(1) when
> >>>>>> refcount_inc_not_zero() returns false. Note that this 2-steps operation
> >>>>>> is not racy here because the whole section is protected by a mutex
> >>>>>> which guarantees that the counter does not change between the
> >>>>>> refcount_inc_not_zero() and refcount_set() calls.  
> >>>>> If we're not following the model, and protecting the refcount by a
> >>>>> mutex, shouldn't we just be using addition and subtraction instead of
> >>>>> refcount's atomics?  
> >>>> Actually, this mutex is protecting the bo->madv value which has to be
> >>>> checked when the counter reaches 0 (when decrementing) or 1 (when
> >>>> incrementing). We just benefit from this protection here, but ideally
> >>>> it would be better to have an refcount_inc_allow_zero() as suggested by
> >>>> Daniel.  
> >>> Let me restate this to see if it makes sense: The refcount is always >=
> >>> 0, this is is the only path that increases the refcount from 0 to 1, and
> >>> it's (incidentally) protected by a mutex, so there's no race between the
> >>> attempted increase from nonzero and the set from nonzero to 1.  
> >> Yep.
> >>  
> >>> This seems fine to me as a bugfix.  
> >> The discussion is going on in the other thread, let's wait a bit
> >> before taking a decision.  
> > Let's not block the bugfix on reaching perfection imo. I'd merge this as
> > the minimal fix, and then apply the pretty paint once we have a clear idea
> > for that.
> > -Daniel  
> 
> sorry but i can't find it in the DRI tree.

Sorry for the delay. I applied it this morning [1] and it should appear
in the next -rc.

Regards,

Boris

[1]https://cgit.freedesktop.org/drm/drm-misc/log/?h=drm-misc-fixes
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 6/6] drm/panel: rpi-touchscreen: Set status to "fail" when ->probe() fails

2018-05-04 Thread Boris Brezillon
On Fri, 4 May 2018 16:24:04 +0200
Boris Brezillon <boris.brezil...@bootlin.com> wrote:

> On Fri, 4 May 2018 16:20:17 +0200
> Daniel Vetter <dan...@ffwll.ch> wrote:
> 
> > On Fri, May 04, 2018 at 02:17:49PM +0200, Boris Brezillon wrote:  
> > > On Fri, 4 May 2018 11:47:48 +0200
> > > Thierry Reding <thierry.red...@gmail.com> wrote:
> > >     
> > > > On Fri, May 04, 2018 at 10:06:53AM +0200, Boris Brezillon wrote:
> > > > > Hi Rob,
> > > > > 
> > > > > On Thu, 3 May 2018 12:12:39 -0500
> > > > > Rob Herring <robh...@kernel.org> wrote:
> > > > >   
> > > > > > On Thu, May 3, 2018 at 11:40 AM, Boris Brezillon
> > > > > > <boris.brezil...@bootlin.com> wrote:  
> > > > > > > The device might be described in the device tree but not 
> > > > > > > connected to
> > > > > > > the I2C bus. Update the status property so that the DRM panel 
> > > > > > > logic
> > > > > > > returns -ENODEV when someone tries to get the panel attached to 
> > > > > > > this
> > > > > > > DT node.
> > > > > > >
> > > > > > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > > > > > > ---
> > > > > > >  .../gpu/drm/panel/panel-raspberrypi-touchscreen.c  | 35 
> > > > > > > ++
> > > > > > >  1 file changed, 35 insertions(+)
> > > > > > >
> > > > > > > diff --git 
> > > > > > > a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
> > > > > > > b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > > > > index 2c9c9722734f..b8fcb1acef75 100644
> > > > > > > --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > > > > +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > > > > @@ -358,6 +358,39 @@ static const struct drm_panel_funcs 
> > > > > > > rpi_touchscreen_funcs = {
> > > > > > > .get_modes = rpi_touchscreen_get_modes,
> > > > > > >  };
> > > > > > >
> > > > > > > +static void rpi_touchscreen_set_status_fail(struct i2c_client 
> > > > > > > *i2c)
> > > > > > > +{
> > > > > > > +   struct property *newprop;
> > > > > > > +
> > > > > > > +   newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
> > > > > > > +   if (!newprop)
> > > > > > > +   return;
> > > > > > > +
> > > > > > > +   newprop->name = kstrdup("status", GFP_KERNEL);
> > > > > > > +   if (!newprop->name)
> > > > > > > +   goto err;
> > > > > > > +
> > > > > > > +   newprop->value = kstrdup("fail", GFP_KERNEL);
> > > > > > > +   if (!newprop->value)
> > > > > > > +   goto err;
> > > > > > > +
> > > > > > > +   newprop->length = sizeof("fail");
> > > > > > > +
> > > > > > > +   if (of_update_property(i2c->dev.of_node, newprop))
> > > > > > > +   goto err;
> > > > > > > +
> > > > > > 
> > > > > > As I mentioned on irc, can you make this a common DT function.  
> > > > > 
> > > > > Yep, will move that to drivers/of/base.c and make it generic.
> > > > >   
> > > > > > 
> > > > > > I'm not sure if it matters that we set status to fail vs. disabled. 
> > > > > > I
> > > > > > somewhat prefer the latter as we already have other cases and I'd
> > > > > > rather the api not pass a string in. I can't think of any reason to
> > > > > > distinguish the difference between fail and disabled.  
> > > > > 
> > > > > Well, I just read the ePAPR doc pointed by Thierry [1] (section 
> > > > > 2.3.4),
> > > > > and "fail" seemed like a good match for what we are trying to express
> > > > > here: "we failed to c

Re: [BUG] drm/vc4: vblank wait timed out

2018-05-07 Thread Boris Brezillon
On Sun, 6 May 2018 01:56:36 +0200 (CEST)
Stefan Wahren <stefan.wah...@i2se.com> wrote:

> > Boris Brezillon <boris.brezil...@bootlin.com> hat am 5. Mai 2018 um 20:00 
> > geschrieben:
> > 
> > 
> > On Sat, 5 May 2018 19:44:57 +0200 (CEST)
> > Stefan Wahren <stefan.wah...@i2se.com> wrote:
> >   
> > > Hi Stefan,
> > >   
> > > > Stefan Schake <stsch...@gmail.com> hat am 5. Mai 2018 um 19:29
> > > > geschrieben:
> > > > 
> > > > 
> > > > On Sat, May 5, 2018 at 1:47 PM, Stefan Wahren
> > > > <stefan.wah...@i2se.com> wrote:
> > > > > Hi,
> > > > >
> > > > > after submit of the latest bcm2835 clock fixes, i thought this
> > > > > issue has been fixed. But i've seen this issue with current
> > > > > mainline 4.17-rc3 (bcm2835_defconfig) on Raspberry Pi 1 B (using
> > > > > U-Boot TFTP Boot). Strangly i couldn't reproduce this issue with
> > > > > same kernel but using only the Foundation bootloader (without
> > > > > U-Boot TFTP Boot).
> > > > >
> > > > > U-Boot version: 2018.03
> > > > >
> > > > > I triggered the warning using my HDMI switch:
> > > > >
> > > > > [  198.304572] [ cut here ]
> > > > > [  198.304693] WARNING: CPU: 0 PID: 10 at
> > > > > drivers/gpu/drm/drm_atomic_helper.c:1351
> > > > > drm_atomic_helper_wait_for_vblanks+0x1d4/0x1f0 [  198.304703]
> > > > > [CRTC:68:crtc-2] vblank wait timed out [  198.304751] Modules
> > > > > linked in: bcm2835_rng rng_core vchiq(C) [  198.304790] CPU: 0
> > > > > PID: 10 Comm: kworker/0:1 Tainted: G C4.17.0-rc3+
> > > > > #1 [  198.304796] Hardware name: BCM2835 [  198.304817]
> > > > > Workqueue: events output_poll_execute [  198.304867] []
> > > > > (unwind_backtrace) from [] (show_stack+0x20/0x24)
> > > > > [  198.304934] [] (show_stack) from []
> > > > > (dump_stack+0x20/0x28) [  198.304971] [] (dump_stack)
> > > > > from [] (__warn+0xec/0x104) [  198.305012] []
> > > > > (__warn) from [] (warn_slowpath_fmt+0x48/0x50)
> > > > > [  198.305048] [] (warn_slowpath_fmt) from []
> > > > > (drm_atomic_helper_wait_for_vblanks+0x1d4/0x1f0) [  198.305098]
> > > > > [] (drm_atomic_helper_wait_for_vblanks) from
> > > > > [] (vc4_atomic_complete_commit+0x80/0xb8)
> > > > > [  198.305144] [] (vc4_atomic_complete_commit) from
> > > > > [] (vc4_atomic_commit+0x110/0x11c) [  198.305174]
> > > > > [] (vc4_atomic_commit) from []
> > > > > (drm_atomic_commit+0x50/0x60) [  198.305202] []
> > > > > (drm_atomic_commit) from []
> > > > > (restore_fbdev_mode_atomic+0x80/0x1cc) [  198.305228]
> > > > > [] (restore_fbdev_mode_atomic) from []
> > > > > (restore_fbdev_mode+0x38/0x144) [  198.305270] []
> > > > > (restore_fbdev_mode) from []
> > > > > (drm_fb_helper_restore_fbdev_mode_unlocked+0x58/0x8c)
> > > > > [  198.305296] []
> > > > > (drm_fb_helper_restore_fbdev_mode_unlocked) from []
> > > > > (drm_fb_helper_set_par+0x54/0x60) [  198.305320] []
> > > > > (drm_fb_helper_set_par) from []
> > > > > (drm_fb_helper_hotplug_event+0xc8/0xd4) [  198.305343]
> > > > > [] (drm_fb_helper_hotplug_event) from []
> > > > > (drm_fb_helper_output_poll_changed+0x1c/0x20) [  198.305382]
> > > > > [] (drm_fb_helper_output_poll_changed) from
> > > > > [] (drm_kms_helper_hotplug_event+0x34/0x38)
> > > > > [  198.305409] [] (drm_kms_helper_hotplug_event) from
> > > > > [] (output_poll_execute+0x16c/0x17c) [  198.305440]
> > > > > [] (output_poll_execute) from []
> > > > > (process_one_work+0x1e0/0x368) [  198.305466] []
> > > > > (process_one_work) from [] (worker_thread+0x2a0/0x418)
> > > > > [  198.305511] [] (worker_thread) from []
> > > > > (kthread+0x144/0x15c) [  198.305539] [] (kthread) from
> > > > > [] (ret_from_fork+0x14/0x2c) [  198.305549] Exception
> > > > > stack(0xc9939fb0 to 0xc9939ff8) [  198.305562]
> > > > > 9fa0:  
> > > > >   [  198.305578] 9fc0:   
> > > > >  

Re: [PATCH v2 6/6] drm/panel: rpi-touchscreen: Set status to "fail" when ->probe() fails

2018-05-07 Thread Boris Brezillon
On Fri, 4 May 2018 14:29:27 -0500
Rob Herring <robh...@kernel.org> wrote:

> On Fri, May 4, 2018 at 9:20 AM, Daniel Vetter <dan...@ffwll.ch> wrote:
> > On Fri, May 04, 2018 at 02:17:49PM +0200, Boris Brezillon wrote:  
> >> On Fri, 4 May 2018 11:47:48 +0200
> >> Thierry Reding <thierry.red...@gmail.com> wrote:
> >>  
> >> > On Fri, May 04, 2018 at 10:06:53AM +0200, Boris Brezillon wrote:  
> >> > > Hi Rob,
> >> > >
> >> > > On Thu, 3 May 2018 12:12:39 -0500
> >> > > Rob Herring <robh...@kernel.org> wrote:
> >> > >  
> >> > > > On Thu, May 3, 2018 at 11:40 AM, Boris Brezillon
> >> > > > <boris.brezil...@bootlin.com> wrote:  
> >> > > > > The device might be described in the device tree but not connected 
> >> > > > > to
> >> > > > > the I2C bus. Update the status property so that the DRM panel logic
> >> > > > > returns -ENODEV when someone tries to get the panel attached to 
> >> > > > > this
> >> > > > > DT node.
> >> > > > >
> >> > > > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> >> > > > > ---
> >> > > > >  .../gpu/drm/panel/panel-raspberrypi-touchscreen.c  | 35 
> >> > > > > ++
> >> > > > >  1 file changed, 35 insertions(+)
> >> > > > >
> >> > > > > diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
> >> > > > > b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> >> > > > > index 2c9c9722734f..b8fcb1acef75 100644
> >> > > > > --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> >> > > > > +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> >> > > > > @@ -358,6 +358,39 @@ static const struct drm_panel_funcs 
> >> > > > > rpi_touchscreen_funcs = {
> >> > > > > .get_modes = rpi_touchscreen_get_modes,
> >> > > > >  };
> >> > > > >
> >> > > > > +static void rpi_touchscreen_set_status_fail(struct i2c_client 
> >> > > > > *i2c)
> >> > > > > +{
> >> > > > > +   struct property *newprop;
> >> > > > > +
> >> > > > > +   newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
> >> > > > > +   if (!newprop)
> >> > > > > +   return;
> >> > > > > +
> >> > > > > +   newprop->name = kstrdup("status", GFP_KERNEL);
> >> > > > > +   if (!newprop->name)
> >> > > > > +   goto err;
> >> > > > > +
> >> > > > > +   newprop->value = kstrdup("fail", GFP_KERNEL);
> >> > > > > +   if (!newprop->value)
> >> > > > > +   goto err;
> >> > > > > +
> >> > > > > +   newprop->length = sizeof("fail");
> >> > > > > +
> >> > > > > +   if (of_update_property(i2c->dev.of_node, newprop))
> >> > > > > +   goto err;
> >> > > > > +  
> >> > > >
> >> > > > As I mentioned on irc, can you make this a common DT function.  
> >> > >
> >> > > Yep, will move that to drivers/of/base.c and make it generic.
> >> > >  
> >> > > >
> >> > > > I'm not sure if it matters that we set status to fail vs. disabled. I
> >> > > > somewhat prefer the latter as we already have other cases and I'd
> >> > > > rather the api not pass a string in. I can't think of any reason to
> >> > > > distinguish the difference between fail and disabled.  
> >> > >
> >> > > Well, I just read the ePAPR doc pointed by Thierry [1] (section 2.3.4),
> >> > > and "fail" seemed like a good match for what we are trying to express
> >> > > here: "we failed to communicate with the device in the probe function
> >> > > and want to mark it unusable", which is a bit different from "the
> >> > > device was explicitly disabled by the user".
> >> > >
> >> >

Re: [BUG] drm/vc4: vblank wait timed out

2018-05-05 Thread Boris Brezillon
On Sat, 5 May 2018 13:47:25 +0200 (CEST)
Stefan Wahren  wrote:

> Hi,
> 
> after submit of the latest bcm2835 clock fixes, i thought this issue has been 
> fixed. But i've seen this issue with current mainline 4.17-rc3 
> (bcm2835_defconfig) on Raspberry Pi 1 B (using U-Boot TFTP Boot). Strangly i 
> couldn't reproduce this issue with same kernel but using only the Foundation 
> bootloader (without U-Boot TFTP Boot).
> 
> U-Boot version: 2018.03
> 
> I triggered the warning using my HDMI switch:
> 
> [  198.304572] [ cut here ]
> [  198.304693] WARNING: CPU: 0 PID: 10 at 
> drivers/gpu/drm/drm_atomic_helper.c:1351 
> drm_atomic_helper_wait_for_vblanks+0x1d4/0x1f0
> [  198.304703] [CRTC:68:crtc-2] vblank wait timed out
> [  198.304751] Modules linked in: bcm2835_rng rng_core vchiq(C)
> [  198.304790] CPU: 0 PID: 10 Comm: kworker/0:1 Tainted: G C
> 4.17.0-rc3+ #1
> [  198.304796] Hardware name: BCM2835
> [  198.304817] Workqueue: events output_poll_execute
> [  198.304867] [] (unwind_backtrace) from [] 
> (show_stack+0x20/0x24)
> [  198.304934] [] (show_stack) from [] 
> (dump_stack+0x20/0x28)
> [  198.304971] [] (dump_stack) from [] (__warn+0xec/0x104)
> [  198.305012] [] (__warn) from [] 
> (warn_slowpath_fmt+0x48/0x50)
> [  198.305048] [] (warn_slowpath_fmt) from [] 
> (drm_atomic_helper_wait_for_vblanks+0x1d4/0x1f0)
> [  198.305098] [] (drm_atomic_helper_wait_for_vblanks) from 
> [] (vc4_atomic_complete_commit+0x80/0xb8)
> [  198.305144] [] (vc4_atomic_complete_commit) from [] 
> (vc4_atomic_commit+0x110/0x11c)
> [  198.305174] [] (vc4_atomic_commit) from [] 
> (drm_atomic_commit+0x50/0x60)
> [  198.305202] [] (drm_atomic_commit) from [] 
> (restore_fbdev_mode_atomic+0x80/0x1cc)
> [  198.305228] [] (restore_fbdev_mode_atomic) from [] 
> (restore_fbdev_mode+0x38/0x144)
> [  198.305270] [] (restore_fbdev_mode) from [] 
> (drm_fb_helper_restore_fbdev_mode_unlocked+0x58/0x8c)
> [  198.305296] [] (drm_fb_helper_restore_fbdev_mode_unlocked) from 
> [] (drm_fb_helper_set_par+0x54/0x60)
> [  198.305320] [] (drm_fb_helper_set_par) from [] 
> (drm_fb_helper_hotplug_event+0xc8/0xd4)
> [  198.305343] [] (drm_fb_helper_hotplug_event) from [] 
> (drm_fb_helper_output_poll_changed+0x1c/0x20)
> [  198.305382] [] (drm_fb_helper_output_poll_changed) from 
> [] (drm_kms_helper_hotplug_event+0x34/0x38)
> [  198.305409] [] (drm_kms_helper_hotplug_event) from [] 
> (output_poll_execute+0x16c/0x17c)
> [  198.305440] [] (output_poll_execute) from [] 
> (process_one_work+0x1e0/0x368)
> [  198.305466] [] (process_one_work) from [] 
> (worker_thread+0x2a0/0x418)
> [  198.305511] [] (worker_thread) from [] 
> (kthread+0x144/0x15c)
> [  198.305539] [] (kthread) from [] 
> (ret_from_fork+0x14/0x2c)
> [  198.305549] Exception stack(0xc9939fb0 to 0xc9939ff8)
> [  198.305562] 9fa0:   
>  
> [  198.305578] 9fc0:       
>  
> [  198.305591] 9fe0:     0013 
> [  198.305630] ---[ end trace 9c4071c657268b83 ]---
> 
> I also dumped clk_summary in both cases, but they were identical.
> 
> Are their any helpful information, which i can provide?

I doubt this will fix your problem, but can you try with this patch
[1] applied?

Also, is u-boot touching PLLH or anything related to HDMI?

[1]https://patchwork.kernel.org/patch/10207159/
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/vc4: Fix scaling of uni-planar formats

2018-05-07 Thread Boris Brezillon
When using uni-planar formats (like RGB), the scaling parameters are
stored in plane 0, not plane 1.

Fixes: fc04023fafec ("drm/vc4: Add support for YUV planes.")
Cc: sta...@vger.kernel.org
Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
 drivers/gpu/drm/vc4/vc4_plane.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index ebf081c7a53b..6831975604b5 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -541,7 +541,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
 * the scl fields here.
 */
if (num_planes == 1) {
-   scl0 = vc4_get_scl_field(state, 1);
+   scl0 = vc4_get_scl_field(state, 0);
scl1 = scl0;
} else {
scl0 = vc4_get_scl_field(state, 1);
-- 
2.14.1

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


Re: [PATCH v2 1/6] drm/tegra: Fix a device_node leak when the DRM panel is not found

2018-05-04 Thread Boris Brezillon
On Fri, 4 May 2018 11:50:16 +0200
Thierry Reding <thierry.red...@gmail.com> wrote:

> On Thu, May 03, 2018 at 06:40:04PM +0200, Boris Brezillon wrote:
> > of_node_put(panel) is not called when of_drm_find_panel(panel) returns
> > NULL, thus leaking the reference we hold on panel.
> > 
> > Fixes: 9be7d864cf07 ("drm/tegra: Implement panel support")
> > Cc: <sta...@vger.kernel.org>
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> >  drivers/gpu/drm/tegra/output.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)  
> 
> I'm not sure this warrants a backport, it's a very minor reference leak
> so doesn't really have an impact on system stability or functionality.
> 
> Since this patch is unrelated from the rest of the series, do you mind
> if I pick this up into the drm/tegra tree?

Sure, and feel free to remove the Cc-stable and Fixes tag if you think
they are not necessary.

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


[PATCH 0/3] drm/connector: Provide generic support for underscan

2018-05-07 Thread Boris Brezillon
Hello,

This is an attempt at providing generic support for underscan connector
props. We already have 3 drivers defining the same underscan, underscan
vborder and underscan hborder properties (amd, radeon and nouveau) and
I am about to add a new one, hence my proposal to put the prop parsing
code in the core and add ->underscan fields to drm_connector_state.

Note that I use this new infrastructure to support underscan in VC4
(path 2 and 3) but did not patch existing drivers yet, mainly because I
don't want to do this work before making sure I got the generic bits
right.

Regards,

Boris 

Boris Brezillon (3):
  drm/connector: Add generic underscan properties
  drm/vc4: Take underscan setup into account when updating planes
  drm/vc4: Attach underscan props to the HDMI connector

 drivers/gpu/drm/drm_atomic.c|  12 
 drivers/gpu/drm/drm_connector.c | 120 
 drivers/gpu/drm/vc4/vc4_hdmi.c  |  25 +
 drivers/gpu/drm/vc4/vc4_plane.c |  49 +++-
 include/drm/drm_connector.h |  78 ++
 5 files changed, 283 insertions(+), 1 deletion(-)

-- 
2.14.1

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


[PATCH 1/3] drm/connector: Add generic underscan properties

2018-05-07 Thread Boris Brezillon
We have 3 drivers defining the "underscan", "underscan hborder" and
"underscan vborder" properties (radeon, amd and nouveau) and we are
about to add the same kind of thing in VC4.

Define generic underscan props and add new fields to the drm_connector
state so that the property parsing logic can be shared by all DRM
drivers.

A driver can now attach underscan properties to its connector through
the drm_connector_attach_underscan_properties() helper, and can
check/apply the underscan setup based on the
drm_connector_state->underscan fields.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
 drivers/gpu/drm/drm_atomic.c|  12 
 drivers/gpu/drm/drm_connector.c | 120 
 include/drm/drm_connector.h |  78 ++
 3 files changed, 210 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index dc850b4b6e21..b7312bd172c9 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1278,6 +1278,12 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
return -EINVAL;
}
state->content_protection = val;
+   } else if (property == connector->underscan_mode_property) {
+   state->underscan.mode = val;
+   } else if (property == connector->underscan_hborder_property) {
+   state->underscan.hborder = val;
+   } else if (property == connector->underscan_vborder_property) {
+   state->underscan.vborder = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -1359,6 +1365,12 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->scaling_mode;
} else if (property == connector->content_protection_property) {
*val = state->content_protection;
+   } else if (property == connector->underscan_mode_property) {
+   *val = state->underscan.mode;
+   } else if (property == connector->underscan_hborder_property) {
+   *val = state->underscan.hborder;
+   } else if (property == connector->underscan_vborder_property) {
+   *val = state->underscan.vborder;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index dfc8ca1e9413..9937390b8a25 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -914,6 +914,31 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, 
drm_cp_enum_list)
  * can also expose this property to external outputs, in which case they
  * must support "None", which should be the default (since external screens
  * have a built-in scaler).
+ *
+ * underscan:
+ * This properties defines whether underscan is activated or not, and when
+ * it is activated, how the horizontal and vertical borders are calculated:
+ *
+ * off:
+ * Underscan is disabled. The output image shouldn't be scaled to
+ * take screen borders into account.
+ * on:
+ * Underscan is activated and horizontal and vertical borders are
+ * specified through the "underscan hborder" and
+ * "underscan vborder" properties.
+ * auto:
+ * Underscan is activated and horizontal and vertical borders are
+ * automatically chosen by the driver.
+ *
+ * underscan hborder:
+ * Horizontal border expressed in pixels. The border is symmetric, which
+ * means you'll have half of this value placed on the left and the other
+ * half on the right.
+ *
+ * underscan vborder:
+ * Vertical border expressed in pixels. The border is symmetric, which
+ * means you'll have half of this value placed on the top and the other
+ * half on the bottom.
  */
 
 int drm_connector_create_standard_properties(struct drm_device *dev)
@@ -1108,6 +1133,101 @@ int drm_mode_create_tv_properties(struct drm_device 
*dev,
 }
 EXPORT_SYMBOL(drm_mode_create_tv_properties);
 
+static const struct drm_prop_enum_list drm_underscan_mode_enum_list[] = {
+   { DRM_UNDERSCAN_OFF, "off" },
+   { DRM_UNDERSCAN_ON, "on" },
+   { DRM_UNDERSCAN_AUTO, "auto" },
+};
+
+/**
+ * drm_connector_attach_underscan_properties - attach atomic underscan
+ *properties
+ * @connector: connector to attach underscan mode properties on.
+ * @mode_mask: bitmask of %DRM_UNDERSCAN_XX modes encoding the supported

[PATCH 2/3] drm/vc4: Take underscan setup into account when updating planes

2018-05-07 Thread Boris Brezillon
Applying an underscan setup is just a matter of scaling all planes
appropriately and adjusting the CRTC X/Y offset to account for the
horizontal and vertical border.

Create an vc4_plane_underscan_adj() function doing that and call it from
vc4_plane_setup_clipping_and_scaling() so that we are ready to attach
underscan properties to the HDMI connector.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
 drivers/gpu/drm/vc4/vc4_plane.c | 49 -
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 71d44c357d35..7d5667b1f990 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -258,6 +258,49 @@ static u32 vc4_get_scl_field(struct drm_plane_state 
*state, int plane)
}
 }
 
+static int vc4_plane_underscan_adj(struct drm_plane_state *pstate)
+{
+   struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate);
+   struct drm_connector_state *conn_state = NULL;
+   struct drm_connector *conn;
+   struct drm_crtc_state *crtc_state;
+   int i;
+
+   for_each_new_connector_in_state(pstate->state, conn, conn_state, i) {
+   if (conn_state->crtc == pstate->crtc)
+   break;
+   }
+
+   if (i == pstate->state->num_connector)
+   return 0;
+
+   if (conn_state->underscan.mode != DRM_UNDERSCAN_ON)
+   return 0;
+
+   crtc_state = drm_atomic_get_new_crtc_state(pstate->state,
+  pstate->crtc);
+
+   if (conn_state->underscan.hborder >= crtc_state->mode.hdisplay ||
+   conn_state->underscan.vborder >= crtc_state->mode.vdisplay)
+   return -EINVAL;
+
+   vc4_pstate->crtc_x += conn_state->underscan.hborder / 2;
+   vc4_pstate->crtc_y += conn_state->underscan.vborder / 2;
+   vc4_pstate->crtc_w = (vc4_pstate->crtc_w *
+ (crtc_state->mode.hdisplay -
+  conn_state->underscan.hborder)) /
+crtc_state->mode.hdisplay;
+   vc4_pstate->crtc_h = (vc4_pstate->crtc_h *
+ (crtc_state->mode.vdisplay -
+  conn_state->underscan.vborder)) /
+crtc_state->mode.vdisplay;
+
+   if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h)
+   return -EINVAL;
+
+   return 0;
+}
+
 static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
 {
struct drm_plane *plane = state->plane;
@@ -269,7 +312,7 @@ static int vc4_plane_setup_clipping_and_scaling(struct 
drm_plane_state *state)
int num_planes = fb->format->num_planes;
u32 h_subsample = 1;
u32 v_subsample = 1;
-   int i;
+   int i, ret;
 
for (i = 0; i < num_planes; i++)
vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
@@ -292,6 +335,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct 
drm_plane_state *state)
vc4_state->crtc_w = state->crtc_w;
vc4_state->crtc_h = state->crtc_h;
 
+   ret = vc4_plane_underscan_adj(state);
+   if (ret)
+   return ret;
+
vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0],
   vc4_state->crtc_w);
vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0],
-- 
2.14.1

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


[PATCH 3/3] drm/vc4: Attach underscan props to the HDMI connector

2018-05-07 Thread Boris Brezillon
Now that the plane code takes the underscan setup into account, we can
safely attach the underscan props to the HDMI connector.

We also take care of filling AVI infoframes correctly to expose the
top/botton/left/right bar.

Note that these underscan props match pretty well the
overscan_{left,right,top,bottom} properties defined in config.txt and
parsed by the VC4 firmware.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 1a6db291d48b..17464b5981f9 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -323,6 +323,16 @@ static struct drm_connector 
*vc4_hdmi_connector_init(struct drm_device *dev,
   DRM_MODE_CONNECTOR_HDMIA);
drm_connector_helper_add(connector, _hdmi_connector_helper_funcs);
 
+   /* The hborder and vborder limit is arbitrarily set to 1024 which
+* should be more than enough for real use cases. Note that the actual
+* limitation comes from the display mode:
+*  hborder < hdisplay && vborder < vdisplay
+*/
+   drm_connector_attach_underscan_properties(connector,
+ BIT(DRM_UNDERSCAN_OFF) |
+ BIT(DRM_UNDERSCAN_ON),
+ 1024, 1024);
+
connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
 DRM_CONNECTOR_POLL_DISCONNECT);
 
@@ -408,6 +418,9 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder 
*encoder,
 static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
 {
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+   struct vc4_dev *vc4 = encoder->dev->dev_private;
+   struct vc4_hdmi *hdmi = vc4->hdmi;
+   struct drm_connector_state *cstate = hdmi->connector->state;
struct drm_crtc *crtc = encoder->crtc;
const struct drm_display_mode *mode = >state->adjusted_mode;
union hdmi_infoframe frame;
@@ -426,6 +439,18 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder 
*encoder)
   vc4_encoder->rgb_range_selectable,
   false);
 
+   if (cstate->underscan.mode == DRM_UNDERSCAN_ON) {
+   if (cstate->underscan.hborder) {
+   frame.avi.right_bar = cstate->underscan.hborder / 2;
+   frame.avi.left_bar = frame.avi.right_bar;
+   }
+
+   if (cstate->underscan.vborder) {
+   frame.avi.top_bar = cstate->underscan.vborder / 2;
+   frame.avi.bottom_bar = frame.avi.top_bar;
+   }
+   }
+
vc4_hdmi_write_infoframe(encoder, );
 }
 
-- 
2.14.1

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


Re: [PATCH 0/3] drm/connector: Provide generic support for underscan

2018-05-09 Thread Boris Brezillon
Hi,

On Mon,  7 May 2018 16:44:31 +0200
Boris Brezillon <boris.brezil...@bootlin.com> wrote:

> Hello,
> 
> This is an attempt at providing generic support for underscan connector
> props. We already have 3 drivers defining the same underscan, underscan
> vborder and underscan hborder properties (amd, radeon and nouveau) and
> I am about to add a new one, hence my proposal to put the prop parsing
> code in the core and add ->underscan fields to drm_connector_state.
> 
> Note that I use this new infrastructure to support underscan in VC4
> (path 2 and 3) but did not patch existing drivers yet, mainly because I
> don't want to do this work before making sure I got the generic bits
> right.

Thanks everyone for your reviews. After the discussion we had on IRC
and the feedback I had on this patchset it's a bit unclear to me what
the next iteration should look like. Should I continue with the
underscan props, should I use TV margins exposed by the TV connector
state, should I create new props?

Remember that all I need is a way to define margins in order to let
the VC4 HW scaler shrink the planes and adjust their positions on the
screen.

Thanks,

Boris

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


Re: [PATCH] drm/vc4: Fix scaling of uni-planar formats

2018-05-09 Thread Boris Brezillon
On Mon,  7 May 2018 14:13:03 +0200
Boris Brezillon <boris.brezil...@bootlin.com> wrote:

> When using uni-planar formats (like RGB), the scaling parameters are
> stored in plane 0, not plane 1.
> 
> Fixes: fc04023fafec ("drm/vc4: Add support for YUV planes.")
> Cc: sta...@vger.kernel.org
> Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>

Queued to drm-misc-fixes.

> ---
>  drivers/gpu/drm/vc4/vc4_plane.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index ebf081c7a53b..6831975604b5 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -541,7 +541,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
>* the scl fields here.
>*/
>   if (num_planes == 1) {
> - scl0 = vc4_get_scl_field(state, 1);
> + scl0 = vc4_get_scl_field(state, 0);
>   scl1 = scl0;
>   } else {
>   scl0 = vc4_get_scl_field(state, 1);

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


Re: [PATCH] drm/vc4: Fix scaling of uni-planar formats

2018-05-09 Thread Boris Brezillon
On Mon, 7 May 2018 18:11:02 +0200
Boris Brezillon <boris.brezil...@bootlin.com> wrote:

> On Mon, 07 May 2018 08:56:14 -0700
> Eric Anholt <e...@anholt.net> wrote:
> 
> > Boris Brezillon <boris.brezil...@bootlin.com> writes:
> >   
> > > When using uni-planar formats (like RGB), the scaling parameters are
> > > stored in plane 0, not plane 1.
> > >
> > > Fixes: fc04023fafec ("drm/vc4: Add support for YUV planes.")
> > > Cc: sta...@vger.kernel.org
> > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > 
> > Reviewed-by: Eric Anholt <e...@anholt.net>
> > 
> > Looking at the other branch, did I get the scl0/scl1 backwards?  HVS
> > docs say for non-444 YCBCR: "In these cases Channel 0 performs Y/Alpha
> > scaling and Channel 1 performs CB/CR scaling and should be configured as
> > appropriate."  
> 
> Didn't test, but I think rescaling of multi-planar format is correct.

I just tested, and I confirm the other branch is correct.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 3/3] drm/vc4: Attach underscan props to the HDMI connector

2018-05-09 Thread Boris Brezillon
On Mon, 7 May 2018 17:24:08 +0200
Daniel Vetter <dan...@ffwll.ch> wrote:

> On Mon, May 07, 2018 at 04:44:34PM +0200, Boris Brezillon wrote:
> > Now that the plane code takes the underscan setup into account, we can
> > safely attach the underscan props to the HDMI connector.
> > 
> > We also take care of filling AVI infoframes correctly to expose the
> > top/botton/left/right bar.
> > 
> > Note that these underscan props match pretty well the
> > overscan_{left,right,top,bottom} properties defined in config.txt and
> > parsed by the VC4 firmware.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +
> >  1 file changed, 25 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index 1a6db291d48b..17464b5981f9 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -323,6 +323,16 @@ static struct drm_connector 
> > *vc4_hdmi_connector_init(struct drm_device *dev,
> >DRM_MODE_CONNECTOR_HDMIA);
> > drm_connector_helper_add(connector, _hdmi_connector_helper_funcs);
> >  
> > +   /* The hborder and vborder limit is arbitrarily set to 1024 which
> > +* should be more than enough for real use cases. Note that the actual
> > +* limitation comes from the display mode:
> > +*  hborder < hdisplay && vborder < vdisplay
> > +*/
> > +   drm_connector_attach_underscan_properties(connector,  
> 
> We should probably sprinkle __must_check over all these :-)

I'm perfectly fine adding __must_check to
drm_connector_attach_underscan_properties(), but I'm definitely not
volunteering for a massive __must_check sanitization :P.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 2/4] drm/panel: Let of_drm_find_panel() return -ENODEV when the panel is disabled

2018-05-09 Thread Boris Brezillon
DT nodes might be present in the DT but with a status property set to
"disabled" or "fail". In this case, we should not return -EPROBE_DEFER
when the caller asks for a drm_panel instance. Return -ENODEV instead.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
Reviewed-by: Thierry Reding <tred...@nvidia.com>
Acked-by: Thierry Reding <tred...@nvidia.com>
---
Changes in v3:
- Add Thierry's A-b/R-b

Changes in v2:
- New commit
---
 drivers/gpu/drm/drm_panel.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 49642d79df8f..1a59c9bd2327 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -136,13 +136,18 @@ EXPORT_SYMBOL(drm_panel_detach);
  *
  * Return: A pointer to the panel registered for the specified device tree
  * node or an ERR_PTR() if no panel matching the device tree node can be found.
- * The only error that can be reported is -EPROBE_DEFER, meaning that the panel
- * device has not been probed yet, and the caller should retry later.
+ * Possible error codes returned by this function:
+ * - EPROBE_DEFER: the panel device has not been probed yet, and the caller
+ *   should retry later
+ * - ENODEV: the device is not available (status != "okay" or "ok")
  */
 struct drm_panel *of_drm_find_panel(const struct device_node *np)
 {
struct drm_panel *panel;
 
+   if (!of_device_is_available(np))
+   return ERR_PTR(-ENODEV);
+
mutex_lock(_lock);
 
list_for_each_entry(panel, _list, list) {
-- 
2.14.1

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


[PATCH v3 4/4] drm/vc4: Support the case where the DSI device is disabled

2018-05-09 Thread Boris Brezillon
Having a device with a status property != "okay" in the DT is a valid
use case, and we should not prevent the registration of the DRM device
when the DSI device connected to the DSI controller is disabled.

Consider the ENODEV return code as a valid result and do not expose the
DSI encoder/connector when it happens.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
Changes in v3:
- None

Changes in v2:
- New commit
---
 drivers/gpu/drm/vc4/vc4_dsi.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index 8aa897835118..db2f137f8b7b 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -1606,8 +1606,18 @@ static int vc4_dsi_bind(struct device *dev, struct 
device *master, void *data)
 
ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
  , >bridge);
-   if (ret)
+   if (ret) {
+   /* If the bridge or panel pointed by dev->of_node is not
+* enabled, just return 0 here so that we don't prevent the DRM
+* dev from being registered. Of course that means the DSI
+* encoder won't be exposed, but that's not a problem since
+* nothing is connected to it.
+*/
+   if (ret == -ENODEV)
+   return 0;
+
return ret;
+   }
 
if (panel) {
dsi->bridge = devm_drm_panel_bridge_add(dev, panel,
@@ -1652,7 +1662,8 @@ static void vc4_dsi_unbind(struct device *dev, struct 
device *master,
struct vc4_dev *vc4 = to_vc4_dev(drm);
struct vc4_dsi *dsi = dev_get_drvdata(dev);
 
-   pm_runtime_disable(dev);
+   if (dsi->bridge)
+   pm_runtime_disable(dev);
 
vc4_dsi_encoder_destroy(dsi->encoder);
 
-- 
2.14.1

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


[PATCH v3 1/4] drm/panel: Make of_drm_find_panel() return an ERR_PTR() instead of NULL

2018-05-09 Thread Boris Brezillon
Right now, the DRM panel logic returns NULL when a panel pointing to
the passed OF node is not present in the list of registered panels.

Most drivers interpret this NULL value as -EPROBE_DEFER, but we are
about to modify the semantic of of_drm_find_panel() and let the
framework return -ENODEV when the device node we're pointing to has
a status property that is not equal to "okay" or "ok".

Let's first patch the of_drm_find_panel() implementation to return
ERR_PTR(-EPROBE_DEFER) instead of NULL and patch all callers to replace
the '!panel' check by an 'IS_ERR(panel)' one.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
Changes in v3:
- Rework error handling in a few drivers as suggested by Thierry
- Return -ENODEV when CONFIG_OF or CONFIG_DRM_PANEL are not enabled

Changes in v2:
- New commit
---
 drivers/gpu/drm/bridge/cdns-dsi.c   | 2 +-
 drivers/gpu/drm/bridge/lvds-encoder.c   | 4 ++--
 drivers/gpu/drm/drm_of.c| 4 +++-
 drivers/gpu/drm/drm_panel.c | 6 --
 drivers/gpu/drm/exynos/exynos_dp.c  | 6 --
 drivers/gpu/drm/exynos/exynos_drm_dpi.c | 4 ++--
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 3 +++
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c   | 5 +++--
 drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c   | 4 ++--
 drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c | 5 -
 drivers/gpu/drm/msm/dsi/dsi_host.c  | 2 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 4 ++--
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c  | 2 +-
 drivers/gpu/drm/sti/sti_dvo.c   | 4 +++-
 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c  | 4 ++--
 drivers/gpu/drm/tegra/dsi.c | 3 +++
 drivers/gpu/drm/tegra/output.c  | 4 ++--
 include/drm/drm_panel.h | 2 +-
 18 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c 
b/drivers/gpu/drm/bridge/cdns-dsi.c
index c255fc3e1be5..2c5991cf5397 100644
--- a/drivers/gpu/drm/bridge/cdns-dsi.c
+++ b/drivers/gpu/drm/bridge/cdns-dsi.c
@@ -1152,7 +1152,7 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host,
np = of_node_get(dev->dev.of_node);
 
panel = of_drm_find_panel(np);
-   if (panel) {
+   if (!IS_ERR(panel)) {
bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
} else {
bridge = of_drm_find_bridge(dev->dev.of_node);
diff --git a/drivers/gpu/drm/bridge/lvds-encoder.c 
b/drivers/gpu/drm/bridge/lvds-encoder.c
index 75b0d3f6e4de..f56c92f7af7c 100644
--- a/drivers/gpu/drm/bridge/lvds-encoder.c
+++ b/drivers/gpu/drm/bridge/lvds-encoder.c
@@ -68,9 +68,9 @@ static int lvds_encoder_probe(struct platform_device *pdev)
 
panel = of_drm_find_panel(panel_node);
of_node_put(panel_node);
-   if (!panel) {
+   if (IS_ERR(panel)) {
dev_dbg(>dev, "panel not found, deferring probe\n");
-   return -EPROBE_DEFER;
+   return PTR_ERR(panel);
}
 
lvds_encoder->panel_bridge =
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 1fe122461298..81d3f76c43f3 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -240,8 +240,10 @@ int drm_of_find_panel_or_bridge(const struct device_node 
*np,
 
if (panel) {
*panel = of_drm_find_panel(remote);
-   if (*panel)
+   if (!IS_ERR(*panel))
ret = 0;
+   else
+   *panel = NULL;
}
 
/* No panel found yet, check for a bridge next. */
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 308d442a531b..49642d79df8f 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -135,7 +135,9 @@ EXPORT_SYMBOL(drm_panel_detach);
  * tree node. If a matching panel is found, return a pointer to it.
  *
  * Return: A pointer to the panel registered for the specified device tree
- * node or NULL if no panel matching the device tree node can be found.
+ * node or an ERR_PTR() if no panel matching the device tree node can be found.
+ * The only error that can be reported is -EPROBE_DEFER, meaning that the panel
+ * device has not been probed yet, and the caller should retry later.
  */
 struct drm_panel *of_drm_find_panel(const struct device_node *np)
 {
@@ -151,7 +153,7 @@ struct drm_panel *of_drm_find_panel(const struct 
device_node *np)
}
 
mutex_unlock(_lock);
-   return NULL;
+   return ERR_PTR(-EPROBE_DEFER);
 }
 EXPORT_SYMBOL(of_drm_find_panel);
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c 
b/drivers/gpu/drm/exynos/exynos_dp.c
index 86330f396784..af7ab1ceb50f 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/ex

[PATCH v3 3/4] drm/of: Make drm_of_find_panel_or_bridge() fail when the device is disabled

2018-05-09 Thread Boris Brezillon
There's no point searching for a drm_bridge or drm_panel if the OF node
we're pointing has a status property that is not "okay" or "ok". Just
return -ENODEV in this case.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
Reviewed-by: Thierry Reding <tred...@nvidia.com>
Acked-by: Thierry Reding <tred...@nvidia.com>
---
Changes in v3:
- Add Thierry's A-b/R-b

Changes in v2:
- New commit
---
 drivers/gpu/drm/drm_of.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 81d3f76c43f3..7678100fd772 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -238,6 +238,11 @@ int drm_of_find_panel_or_bridge(const struct device_node 
*np,
if (!remote)
return -ENODEV;
 
+   if (!of_device_is_available(remote)) {
+   of_node_put(remote);
+   return -ENODEV;
+   }
+
if (panel) {
*panel = of_drm_find_panel(remote);
if (!IS_ERR(*panel))
-- 
2.14.1

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


[PATCH v3 0/4] drm/panel: Handle the "panel is missing" case properly

2018-05-09 Thread Boris Brezillon
Hello,

This is a new attempt at fixing the "panel is missing" issue (described
in this thread [1]). I lost track of Eric's proposal, but I recently
proposed to address this problem through a new ->detect() hook in the
panel_funcs interface [2], which was rejected.

So here is a new version based on the feedback I had from Daniel,
Thierry and Rob.

The idea is to allow of_drm_find_panel() to return -ENODEV and let the
DRM driver decide what to do with that (silently ignore the missing
component and register the DRM device, or fail to register the DRM
device).

Patch 1 changes the semantic of of_drm_find_panel() so that it returns
an ERR_PTR() instead of NULL when the panel is not found. This way
we'll be able to differentiate the "panel is missing" from "panel has
not been probed yet" errors.

Patch 2 and 3 are adding new tests in of_drm_find_panel() and
drm_of_find_panel_or_bridge() to return -ENODEV when the status
property of the DT node is not set to "okay".

Patch 4 is patching the VC4 DSI encoder driver to gracefully handle the
-ENODEV case and allow the registration of the DRM device when the DSI
device is disabled.

Note that patch 6 which was modifying the panel status prop from the
I2C driver has been dropped because I'm not sure yet how to solve the
"force probe of deferred-probe devices even if no new devices have been
bound to drivers" problem. Anyway, even without this patch, the series
still makes sense to handle the case where devices are described in the
DT but marked "disabled" (either at compilation time or tweaked by the
bootloader).

Regards,

Boris

Changes in v3:
- Dropped patch 1 since it's been acked by Thierry and should be
  applied soon (either through the drm-tegra or drm-misc tree)
- Dropped patch 6 because we are still discussing who should mark
  the device "disabled" or "fail" and how we should trigger the
  re-probe of deferred-probe devices in this case

Changes in v2:
- Everything :-)

[1]https://lists.freedesktop.org/archives/dri-devel/2017-November/157688.html
[2]https://www.spinics.net/lists/dri-devel/msg174808.html

*** BLURB HERE ***

Boris Brezillon (4):
  drm/panel: Make of_drm_find_panel() return an ERR_PTR() instead of
NULL
  drm/panel: Let of_drm_find_panel() return -ENODEV when the panel is
disabled
  drm/of: Make drm_of_find_panel_or_bridge() fail when the device is
disabled
  drm/vc4: Support the case where the DSI device is disabled

 drivers/gpu/drm/bridge/cdns-dsi.c   |  2 +-
 drivers/gpu/drm/bridge/lvds-encoder.c   |  4 ++--
 drivers/gpu/drm/drm_of.c|  9 -
 drivers/gpu/drm/drm_panel.c | 11 +--
 drivers/gpu/drm/exynos/exynos_dp.c  |  6 --
 drivers/gpu/drm/exynos/exynos_drm_dpi.c |  4 ++--
 drivers/gpu/drm/exynos/exynos_drm_dsi.c |  3 +++
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c   |  5 +++--
 drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c   |  4 ++--
 drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c |  5 -
 drivers/gpu/drm/msm/dsi/dsi_host.c  |  2 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c |  4 ++--
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c  |  2 +-
 drivers/gpu/drm/sti/sti_dvo.c   |  4 +++-
 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c  |  4 ++--
 drivers/gpu/drm/tegra/dsi.c |  3 +++
 drivers/gpu/drm/tegra/output.c  |  4 ++--
 drivers/gpu/drm/vc4/vc4_dsi.c   | 15 +--
 include/drm/drm_panel.h |  2 +-
 19 files changed, 66 insertions(+), 27 deletions(-)

-- 
2.14.1

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


[PATCH v2 0/4] drm/connector: Provide generic support for underscan

2018-05-11 Thread Boris Brezillon
Hello,

This is an attempt at providing generic support for underscan connector
props. We already have 3 drivers defining the same underscan, underscan
vborder and underscan hborder properties (amd, radeon and nouveau) and
I am about to add a new one, hence my proposal to put the prop parsing
code in the core and add ->underscan fields to drm_connector_state.

In this v2, I also converted the nouveau driver to the generic
approach. The amdgpu and radeon ones can't be converted since they're
still not converted to the atomic interface.

Regards,

Boris 

Boris Brezillon (4):
  drm/connector: Add generic underscan properties
  drm/vc4: Take underscan setup into account when updating planes
  drm/vc4: Attach underscan props to the HDMI connector
  drm/nouveau: Switch to the generic underscan props

 drivers/gpu/drm/drm_atomic.c|  12 +++
 drivers/gpu/drm/drm_connector.c | 127 
 drivers/gpu/drm/nouveau/nouveau_connector.c |  39 ++---
 drivers/gpu/drm/nouveau/nouveau_connector.h |   9 --
 drivers/gpu/drm/nouveau/nouveau_display.c   |  14 ---
 drivers/gpu/drm/nouveau/nouveau_display.h   |   3 -
 drivers/gpu/drm/nouveau/nv50_display.c  |  17 ++--
 drivers/gpu/drm/vc4/vc4_hdmi.c  |  25 ++
 drivers/gpu/drm/vc4/vc4_plane.c |  49 ++-
 include/drm/drm_connector.h |  80 ++
 10 files changed, 310 insertions(+), 65 deletions(-)

-- 
2.14.1

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


[PATCH v2 1/4] drm/connector: Add generic underscan properties

2018-05-11 Thread Boris Brezillon
We have 3 drivers defining the "underscan", "underscan hborder" and
"underscan vborder" properties (radeon, amd and nouveau) and we are
about to add the same kind of thing in VC4.

Define generic underscan props and add new fields to the drm_connector
state so that the property parsing logic can be shared by all DRM
drivers.

A driver can now attach underscan properties to its connector through
the drm_connector_attach_underscan_properties() helper, and can
check/apply the underscan setup based on the
drm_connector_state->underscan fields.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
Changes in v2:
- Add a new section in the connector props doc to describe underscan
  props
- Fix description of auto mode (auto means apply underscan for HDMI
  monitors only)
- Fix description of vborder/hborder:
right_border = left_border = hborder
top_border = bottom_border = vborder
  not
right_border = left_border = hborder / 2
top_border = bottom_border = vborder / 2
- Rename drm_underscan into drm_underscan_state
---
 drivers/gpu/drm/drm_atomic.c|  12 
 drivers/gpu/drm/drm_connector.c | 127 
 include/drm/drm_connector.h |  80 +
 3 files changed, 219 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index dc850b4b6e21..b7312bd172c9 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1278,6 +1278,12 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
return -EINVAL;
}
state->content_protection = val;
+   } else if (property == connector->underscan_mode_property) {
+   state->underscan.mode = val;
+   } else if (property == connector->underscan_hborder_property) {
+   state->underscan.hborder = val;
+   } else if (property == connector->underscan_vborder_property) {
+   state->underscan.vborder = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -1359,6 +1365,12 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->scaling_mode;
} else if (property == connector->content_protection_property) {
*val = state->content_protection;
+   } else if (property == connector->underscan_mode_property) {
+   *val = state->underscan.mode;
+   } else if (property == connector->underscan_hborder_property) {
+   *val = state->underscan.hborder;
+   } else if (property == connector->underscan_vborder_property) {
+   *val = state->underscan.vborder;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 9b9ba5d5ec0c..826af6267a4f 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -914,6 +914,38 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, 
drm_cp_enum_list)
  * can also expose this property to external outputs, in which case they
  * must support "None", which should be the default (since external screens
  * have a built-in scaler).
+ *
+ * Connectors for non-analog outputs may also have standardized underscan
+ * properties (drivers can set this up by calling
+ * drm_connector_attach_content_protection_property() on initialization):
+ *
+ * underscan:
+ * This properties defines whether underscan is activated or not, and when
+ * it is activated, how the horizontal and vertical borders are calculated:
+ *
+ * off:
+ * Underscan is disabled. The output image shouldn't be scaled to
+ * take screen borders into account.
+ * on:
+ * Underscan is activated and horizontal and vertical borders are
+ * specified through the "underscan hborder" and
+ * "underscan vborder" properties.
+ * auto:
+ * Underscan is activated only for HDMI monitors.
+ *
+ * underscan hborder:
+ * Horizontal border expressed in pixels. The border is symmetric, which
+ * means you'll have a border of 'hborder' pixels on the left and on the
+ * same border on the right.
+ * When this value is 0 and underscan is "on" or "auto", the driver will
+ * pick a default value (the default value is driver dependent).
+ *
+ * underscan vborder:
+ * Vertical border expressed in pixels. The border is symmetric, which
+ * means you'll have a border of 'vborder' pixels

[PATCH v2 4/4] drm/nouveau: Switch to the generic underscan props

2018-05-11 Thread Boris Brezillon
Now that underscan props can be parsed by the core and assigned to
conn_state->underscan.xxx, we can rely on this implementation and get
rid of the nouveau-specific underscan props.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
 drivers/gpu/drm/nouveau/nouveau_connector.c | 39 +
 drivers/gpu/drm/nouveau/nouveau_connector.h |  9 ---
 drivers/gpu/drm/nouveau/nouveau_display.c   | 14 ---
 drivers/gpu/drm/nouveau/nouveau_display.h   |  3 ---
 drivers/gpu/drm/nouveau/nv50_display.c  | 17 +
 5 files changed, 18 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 6ed9cb053dfa..0ce055d3b89e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -105,12 +105,6 @@ nouveau_conn_atomic_get_property(struct drm_connector 
*connector,
 
if (property == dev->mode_config.scaling_mode_property)
*val = asyc->scaler.mode;
-   else if (property == disp->underscan_property)
-   *val = asyc->scaler.underscan.mode;
-   else if (property == disp->underscan_hborder_property)
-   *val = asyc->scaler.underscan.hborder;
-   else if (property == disp->underscan_vborder_property)
-   *val = asyc->scaler.underscan.vborder;
else if (property == disp->dithering_mode)
*val = asyc->dither.mode;
else if (property == disp->dithering_depth)
@@ -170,24 +164,6 @@ nouveau_conn_atomic_set_property(struct drm_connector 
*connector,
asyc->set.scaler = true;
}
} else
-   if (property == disp->underscan_property) {
-   if (asyc->scaler.underscan.mode != val) {
-   asyc->scaler.underscan.mode = val;
-   asyc->set.scaler = true;
-   }
-   } else
-   if (property == disp->underscan_hborder_property) {
-   if (asyc->scaler.underscan.hborder != val) {
-   asyc->scaler.underscan.hborder = val;
-   asyc->set.scaler = true;
-   }
-   } else
-   if (property == disp->underscan_vborder_property) {
-   if (asyc->scaler.underscan.vborder != val) {
-   asyc->scaler.underscan.vborder = val;
-   asyc->set.scaler = true;
-   }
-   } else
if (property == disp->dithering_mode) {
if (asyc->dither.mode != val) {
asyc->dither.mode = val;
@@ -256,7 +232,6 @@ nouveau_conn_reset(struct drm_connector *connector)
asyc->dither.mode = DITHERING_MODE_AUTO;
asyc->dither.depth = DITHERING_DEPTH_AUTO;
asyc->scaler.mode = DRM_MODE_SCALE_NONE;
-   asyc->scaler.underscan.mode = UNDERSCAN_OFF;
asyc->procamp.color_vibrance = 150;
asyc->procamp.vibrant_hue = 90;
 
@@ -285,18 +260,16 @@ nouveau_conn_attach_properties(struct drm_connector 
*connector)
   dvi_i_subconnector_property, 0);
 
/* Add overscan compensation options to digital outputs. */
-   if (disp->underscan_property &&
+   if (disp->disp.oclass >= NV50_DISP &&
(connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
 connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
 connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)) {
-   drm_object_attach_property(>base,
-  disp->underscan_property,
-  UNDERSCAN_OFF);
-   drm_object_attach_property(>base,
-  disp->underscan_hborder_property, 0);
-   drm_object_attach_property(>base,
-  disp->underscan_vborder_property, 0);
+   WARN_ON(drm_connector_attach_underscan_properties(connector,
+   BIT(DRM_UNDERSCAN_OFF) |
+   BIT(DRM_UNDERSCAN_ON) |
+   BIT(DRM_UNDERSCAN_AUTO),
+   128, 128));
}
 
/* Add hue and saturation options. */
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h 
b/drivers/gpu/drm/nouveau/nouveau_connector.h
index a4d1a059bd3d..1d3ec65288e1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -111,15 +111,6 @@ struct nouveau_conn_atom {
 
struct {
int mode;   /* DRM_

[PATCH v2 3/4] drm/vc4: Attach underscan props to the HDMI connector

2018-05-11 Thread Boris Brezillon
Now that the plane code takes the underscan setup into account, we can
safely attach the underscan props to the HDMI connector.

We also take care of filling AVI infoframes correctly to expose the
top/botton/left/right bar.

Note that these underscan props match pretty well the
overscan_{left,right,top,bottom} properties defined in config.txt and
parsed by the VC4 firmware.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
Changes in v2:
- none
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 1a6db291d48b..17464b5981f9 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -323,6 +323,16 @@ static struct drm_connector 
*vc4_hdmi_connector_init(struct drm_device *dev,
   DRM_MODE_CONNECTOR_HDMIA);
drm_connector_helper_add(connector, _hdmi_connector_helper_funcs);
 
+   /* The hborder and vborder limit is arbitrarily set to 1024 which
+* should be more than enough for real use cases. Note that the actual
+* limitation comes from the display mode:
+*  hborder < hdisplay && vborder < vdisplay
+*/
+   drm_connector_attach_underscan_properties(connector,
+ BIT(DRM_UNDERSCAN_OFF) |
+ BIT(DRM_UNDERSCAN_ON),
+ 1024, 1024);
+
connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
 DRM_CONNECTOR_POLL_DISCONNECT);
 
@@ -408,6 +418,9 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder 
*encoder,
 static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
 {
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+   struct vc4_dev *vc4 = encoder->dev->dev_private;
+   struct vc4_hdmi *hdmi = vc4->hdmi;
+   struct drm_connector_state *cstate = hdmi->connector->state;
struct drm_crtc *crtc = encoder->crtc;
const struct drm_display_mode *mode = >state->adjusted_mode;
union hdmi_infoframe frame;
@@ -426,6 +439,18 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder 
*encoder)
   vc4_encoder->rgb_range_selectable,
   false);
 
+   if (cstate->underscan.mode == DRM_UNDERSCAN_ON) {
+   if (cstate->underscan.hborder) {
+   frame.avi.right_bar = cstate->underscan.hborder / 2;
+   frame.avi.left_bar = frame.avi.right_bar;
+   }
+
+   if (cstate->underscan.vborder) {
+   frame.avi.top_bar = cstate->underscan.vborder / 2;
+   frame.avi.bottom_bar = frame.avi.top_bar;
+   }
+   }
+
vc4_hdmi_write_infoframe(encoder, );
 }
 
-- 
2.14.1

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


[PATCH v2 2/4] drm/vc4: Take underscan setup into account when updating planes

2018-05-11 Thread Boris Brezillon
Applying an underscan setup is just a matter of scaling all planes
appropriately and adjusting the CRTC X/Y offset to account for the
horizontal and vertical border.

Create an vc4_plane_underscan_adj() function doing that and call it from
vc4_plane_setup_clipping_and_scaling() so that we are ready to attach
underscan properties to the HDMI connector.

Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
---
Changes in v2:
- Take changes on hborder/vborder meaning into account
---
 drivers/gpu/drm/vc4/vc4_plane.c | 49 -
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 71d44c357d35..61ed60841cd6 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -258,6 +258,49 @@ static u32 vc4_get_scl_field(struct drm_plane_state 
*state, int plane)
}
 }
 
+static int vc4_plane_underscan_adj(struct drm_plane_state *pstate)
+{
+   struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate);
+   struct drm_connector_state *conn_state = NULL;
+   struct drm_connector *conn;
+   struct drm_crtc_state *crtc_state;
+   int i;
+
+   for_each_new_connector_in_state(pstate->state, conn, conn_state, i) {
+   if (conn_state->crtc == pstate->crtc)
+   break;
+   }
+
+   if (i == pstate->state->num_connector)
+   return 0;
+
+   if (conn_state->underscan.mode != DRM_UNDERSCAN_ON)
+   return 0;
+
+   crtc_state = drm_atomic_get_new_crtc_state(pstate->state,
+  pstate->crtc);
+
+   if (conn_state->underscan.hborder >= crtc_state->mode.hdisplay ||
+   conn_state->underscan.vborder >= crtc_state->mode.vdisplay)
+   return -EINVAL;
+
+   vc4_pstate->crtc_x += conn_state->underscan.hborder;
+   vc4_pstate->crtc_y += conn_state->underscan.vborder;
+   vc4_pstate->crtc_w = (vc4_pstate->crtc_w *
+ (crtc_state->mode.hdisplay -
+  (conn_state->underscan.hborder * 2))) /
+crtc_state->mode.hdisplay;
+   vc4_pstate->crtc_h = (vc4_pstate->crtc_h *
+ (crtc_state->mode.vdisplay -
+  (conn_state->underscan.vborder * 2))) /
+crtc_state->mode.vdisplay;
+
+   if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h)
+   return -EINVAL;
+
+   return 0;
+}
+
 static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
 {
struct drm_plane *plane = state->plane;
@@ -269,7 +312,7 @@ static int vc4_plane_setup_clipping_and_scaling(struct 
drm_plane_state *state)
int num_planes = fb->format->num_planes;
u32 h_subsample = 1;
u32 v_subsample = 1;
-   int i;
+   int i, ret;
 
for (i = 0; i < num_planes; i++)
vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
@@ -292,6 +335,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct 
drm_plane_state *state)
vc4_state->crtc_w = state->crtc_w;
vc4_state->crtc_h = state->crtc_h;
 
+   ret = vc4_plane_underscan_adj(state);
+   if (ret)
+   return ret;
+
vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0],
   vc4_state->crtc_w);
vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0],
-- 
2.14.1

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


Re: [PATCH v2 2/4] drm/vc4: Take underscan setup into account when updating planes

2018-05-11 Thread Boris Brezillon
On Fri, 11 May 2018 18:34:50 +0300
Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:

> On Fri, May 11, 2018 at 04:59:17PM +0200, Boris Brezillon wrote:
> > Applying an underscan setup is just a matter of scaling all planes
> > appropriately and adjusting the CRTC X/Y offset to account for the
> > horizontal and vertical border.
> > 
> > Create an vc4_plane_underscan_adj() function doing that and call it from
> > vc4_plane_setup_clipping_and_scaling() so that we are ready to attach
> > underscan properties to the HDMI connector.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> > Changes in v2:
> > - Take changes on hborder/vborder meaning into account
> > ---
> >  drivers/gpu/drm/vc4/vc4_plane.c | 49 
> > -
> >  1 file changed, 48 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_plane.c 
> > b/drivers/gpu/drm/vc4/vc4_plane.c
> > index 71d44c357d35..61ed60841cd6 100644
> > --- a/drivers/gpu/drm/vc4/vc4_plane.c
> > +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> > @@ -258,6 +258,49 @@ static u32 vc4_get_scl_field(struct drm_plane_state 
> > *state, int plane)
> > }
> >  }
> >  
> > +static int vc4_plane_underscan_adj(struct drm_plane_state *pstate)
> > +{
> > +   struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate);
> > +   struct drm_connector_state *conn_state = NULL;
> > +   struct drm_connector *conn;
> > +   struct drm_crtc_state *crtc_state;
> > +   int i;
> > +
> > +   for_each_new_connector_in_state(pstate->state, conn, conn_state, i) {
> > +   if (conn_state->crtc == pstate->crtc)
> > +   break;
> > +   }
> > +
> > +   if (i == pstate->state->num_connector)
> > +   return 0;
> > +
> > +   if (conn_state->underscan.mode != DRM_UNDERSCAN_ON)
> > +   return 0;
> > +
> > +   crtc_state = drm_atomic_get_new_crtc_state(pstate->state,
> > +  pstate->crtc);
> > +
> > +   if (conn_state->underscan.hborder >= crtc_state->mode.hdisplay ||
> > +   conn_state->underscan.vborder >= crtc_state->mode.vdisplay)
> > +   return -EINVAL;  
> 
> border * 2 ?

Oops, indeed. I'll fix that.

> 
> > +
> > +   vc4_pstate->crtc_x += conn_state->underscan.hborder;
> > +   vc4_pstate->crtc_y += conn_state->underscan.vborder;
> > +   vc4_pstate->crtc_w = (vc4_pstate->crtc_w *
> > + (crtc_state->mode.hdisplay -
> > +  (conn_state->underscan.hborder * 2))) /
> > +crtc_state->mode.hdisplay;
> > +   vc4_pstate->crtc_h = (vc4_pstate->crtc_h *
> > + (crtc_state->mode.vdisplay -
> > +  (conn_state->underscan.vborder * 2))) /
> > +crtc_state->mode.vdisplay;  
> 
> So you're now scaling all planes? The code seems to reject scaling for
> the cursor plane, how are you dealing with that? Or just no cursor
> allowed when underscanning?

No, I just didn't test with a cursor plane. We should probably avoid
scaling the cursor plane and just adjust its position. Eric any opinion
on that?

> 
> I'm also wondering if there's any way we can reconcile these border
> props with the scaling mode prop, should we ever wish to expose
> these props on connectors that already have the scaling mode prop.

Nouveau seems to expose both, and I don't see why we couldn't.

> Maybe we just have to require the scaling mode to be set to fullscreen 
> to allow borders to be specified explictly?
> 
> > +
> > +   if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h)
> > +   return -EINVAL;
> > +
> > +   return 0;
> > +}
> > +
> >  static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state 
> > *state)
> >  {
> > struct drm_plane *plane = state->plane;
> > @@ -269,7 +312,7 @@ static int vc4_plane_setup_clipping_and_scaling(struct 
> > drm_plane_state *state)
> > int num_planes = fb->format->num_planes;
> > u32 h_subsample = 1;
> > u32 v_subsample = 1;
> > -   int i;
> > +   int i, ret;
> >  
> > for (i = 0; i < num_planes; i++)
> > vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
> > @@ -292,6 +335,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct 
> > drm_plane_state *state)
> > vc4_

Re: [PATCH 1/3] drm/connector: Add generic underscan properties

2018-05-11 Thread Boris Brezillon
On Mon, 7 May 2018 17:25:30 +0200
Daniel Vetter <dan...@ffwll.ch> wrote:

> On Mon, May 07, 2018 at 05:15:33PM +0200, Daniel Vetter wrote:
> > On Mon, May 07, 2018 at 04:44:32PM +0200, Boris Brezillon wrote:  
> > > We have 3 drivers defining the "underscan", "underscan hborder" and
> > > "underscan vborder" properties (radeon, amd and nouveau) and we are
> > > about to add the same kind of thing in VC4.
> > > 
> > > Define generic underscan props and add new fields to the drm_connector
> > > state so that the property parsing logic can be shared by all DRM
> > > drivers.
> > > 
> > > A driver can now attach underscan properties to its connector through
> > > the drm_connector_attach_underscan_properties() helper, and can
> > > check/apply the underscan setup based on the
> > > drm_connector_state->underscan fields.
> > > 
> > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > > ---
> > >  drivers/gpu/drm/drm_atomic.c|  12 
> > >  drivers/gpu/drm/drm_connector.c | 120 
> > > 
> > >  include/drm/drm_connector.h |  78 ++
> > >  3 files changed, 210 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > index dc850b4b6e21..b7312bd172c9 100644
> > > --- a/drivers/gpu/drm/drm_atomic.c
> > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > @@ -1278,6 +1278,12 @@ static int 
> > > drm_atomic_connector_set_property(struct drm_connector *connector,
> > >   return -EINVAL;
> > >   }
> > >   state->content_protection = val;
> > > + } else if (property == connector->underscan_mode_property) {
> > > + state->underscan.mode = val;
> > > + } else if (property == connector->underscan_hborder_property) {
> > > + state->underscan.hborder = val;
> > > + } else if (property == connector->underscan_vborder_property) {
> > > + state->underscan.vborder = val;
> > >   } else if (connector->funcs->atomic_set_property) {
> > >   return connector->funcs->atomic_set_property(connector,
> > >   state, property, val);
> > > @@ -1359,6 +1365,12 @@ drm_atomic_connector_get_property(struct 
> > > drm_connector *connector,
> > >   *val = state->scaling_mode;
> > >   } else if (property == connector->content_protection_property) {
> > >   *val = state->content_protection;
> > > + } else if (property == connector->underscan_mode_property) {
> > > + *val = state->underscan.mode;
> > > + } else if (property == connector->underscan_hborder_property) {
> > > + *val = state->underscan.hborder;
> > > + } else if (property == connector->underscan_vborder_property) {
> > > + *val = state->underscan.vborder;
> > >   } else if (connector->funcs->atomic_get_property) {
> > >   return connector->funcs->atomic_get_property(connector,
> > >   state, property, val);
> > > diff --git a/drivers/gpu/drm/drm_connector.c 
> > > b/drivers/gpu/drm/drm_connector.c
> > > index dfc8ca1e9413..9937390b8a25 100644
> > > --- a/drivers/gpu/drm/drm_connector.c
> > > +++ b/drivers/gpu/drm/drm_connector.c
> > > @@ -914,6 +914,31 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, 
> > > drm_cp_enum_list)
> > >   *   can also expose this property to external outputs, in which 
> > > case they
> > >   *   must support "None", which should be the default (since 
> > > external screens
> > >   *   have a built-in scaler).  
> > 
> > I think a new section here would be good, to make it more obvious this is
> > a group of properties. Plus a reference to
> > drm_connector_attach_underscan_properties().
> >   
> > > + *
> > > + * underscan:
> > > + *   This properties defines whether underscan is activated or not, 
> > > and when
> > > + *   it is activated, how the horizontal and vertical borders are 
> > > calculated:
> > > + *
> > > + *   off:
> > > + *   Underscan is disabled. The output image shouldn't be 
> > > scaled to
> > > + *   take screen borders into account.
> > > + *   o

Re: [PATCH 1/3] drm/connector: Add generic underscan properties

2018-05-11 Thread Boris Brezillon
On Tue, 8 May 2018 10:18:10 +1000
Ben Skeggs <skeg...@gmail.com> wrote:

> On 8 May 2018 at 04:26, Harry Wentland <harry.wentl...@amd.com> wrote:
> >
> >
> > On 2018-05-07 12:19 PM, Boris Brezillon wrote:  
> >> On Mon, 7 May 2018 18:01:44 +0300
> >> Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:
> >>  
> >>> On Mon, May 07, 2018 at 04:44:32PM +0200, Boris Brezillon wrote:  
> >>>> We have 3 drivers defining the "underscan", "underscan hborder" and
> >>>> "underscan vborder" properties (radeon, amd and nouveau) and we are
> >>>> about to add the same kind of thing in VC4.
> >>>>
> >>>> Define generic underscan props and add new fields to the drm_connector
> >>>> state so that the property parsing logic can be shared by all DRM
> >>>> drivers.
> >>>>
> >>>> A driver can now attach underscan properties to its connector through
> >>>> the drm_connector_attach_underscan_properties() helper, and can
> >>>> check/apply the underscan setup based on the
> >>>> drm_connector_state->underscan fields.
> >>>>
> >>>> Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> >>>> ---
> >>>>  drivers/gpu/drm/drm_atomic.c|  12 
> >>>>  drivers/gpu/drm/drm_connector.c | 120 
> >>>> 
> >>>>  include/drm/drm_connector.h |  78 ++
> >>>>  3 files changed, 210 insertions(+)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >>>> index dc850b4b6e21..b7312bd172c9 100644
> >>>> --- a/drivers/gpu/drm/drm_atomic.c
> >>>> +++ b/drivers/gpu/drm/drm_atomic.c
> >>>> @@ -1278,6 +1278,12 @@ static int 
> >>>> drm_atomic_connector_set_property(struct drm_connector *connector,
> >>>> return -EINVAL;
> >>>> }
> >>>> state->content_protection = val;
> >>>> +   } else if (property == connector->underscan_mode_property) {
> >>>> +   state->underscan.mode = val;
> >>>> +   } else if (property == connector->underscan_hborder_property) {
> >>>> +   state->underscan.hborder = val;
> >>>> +   } else if (property == connector->underscan_vborder_property) {
> >>>> +   state->underscan.vborder = val;
> >>>> } else if (connector->funcs->atomic_set_property) {
> >>>> return connector->funcs->atomic_set_property(connector,
> >>>> state, property, val);
> >>>> @@ -1359,6 +1365,12 @@ drm_atomic_connector_get_property(struct 
> >>>> drm_connector *connector,
> >>>> *val = state->scaling_mode;
> >>>> } else if (property == connector->content_protection_property) {
> >>>> *val = state->content_protection;
> >>>> +   } else if (property == connector->underscan_mode_property) {
> >>>> +   *val = state->underscan.mode;
> >>>> +   } else if (property == connector->underscan_hborder_property) {
> >>>> +   *val = state->underscan.hborder;
> >>>> +   } else if (property == connector->underscan_vborder_property) {
> >>>> +   *val = state->underscan.vborder;
> >>>> } else if (connector->funcs->atomic_get_property) {
> >>>> return connector->funcs->atomic_get_property(connector,
> >>>> state, property, val);
> >>>> diff --git a/drivers/gpu/drm/drm_connector.c 
> >>>> b/drivers/gpu/drm/drm_connector.c
> >>>> index dfc8ca1e9413..9937390b8a25 100644
> >>>> --- a/drivers/gpu/drm/drm_connector.c
> >>>> +++ b/drivers/gpu/drm/drm_connector.c
> >>>> @@ -914,6 +914,31 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, 
> >>>> drm_cp_enum_list)
> >>>>   * can also expose this property to external outputs, in which case they
> >>>>   * must support "None", which should be the default (since external 
> >>>> screens
> >>>>   * have a built-in scaler).
> >>>> + *
> >>>> + * underscan:
&

Re: [PATCH v2 2/4] drm/vc4: Take underscan setup into account when updating planes

2018-05-11 Thread Boris Brezillon
On Fri, 11 May 2018 19:54:02 +0300
Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:

> On Fri, May 11, 2018 at 05:52:56PM +0200, Boris Brezillon wrote:
> > On Fri, 11 May 2018 18:34:50 +0300
> > Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:
> >   
> > > On Fri, May 11, 2018 at 04:59:17PM +0200, Boris Brezillon wrote:  
> > > > Applying an underscan setup is just a matter of scaling all planes
> > > > appropriately and adjusting the CRTC X/Y offset to account for the
> > > > horizontal and vertical border.
> > > > 
> > > > Create an vc4_plane_underscan_adj() function doing that and call it from
> > > > vc4_plane_setup_clipping_and_scaling() so that we are ready to attach
> > > > underscan properties to the HDMI connector.
> > > > 
> > > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > > > ---
> > > > Changes in v2:
> > > > - Take changes on hborder/vborder meaning into account
> > > > ---
> > > >  drivers/gpu/drm/vc4/vc4_plane.c | 49 
> > > > -
> > > >  1 file changed, 48 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/vc4/vc4_plane.c 
> > > > b/drivers/gpu/drm/vc4/vc4_plane.c
> > > > index 71d44c357d35..61ed60841cd6 100644
> > > > --- a/drivers/gpu/drm/vc4/vc4_plane.c
> > > > +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> > > > @@ -258,6 +258,49 @@ static u32 vc4_get_scl_field(struct 
> > > > drm_plane_state *state, int plane)
> > > > }
> > > >  }
> > > >  
> > > > +static int vc4_plane_underscan_adj(struct drm_plane_state *pstate)
> > > > +{
> > > > +   struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate);
> > > > +   struct drm_connector_state *conn_state = NULL;
> > > > +   struct drm_connector *conn;
> > > > +   struct drm_crtc_state *crtc_state;
> > > > +   int i;
> > > > +
> > > > +   for_each_new_connector_in_state(pstate->state, conn, 
> > > > conn_state, i) {
> > > > +   if (conn_state->crtc == pstate->crtc)
> > > > +   break;
> > > > +   }
> > > > +
> > > > +   if (i == pstate->state->num_connector)
> > > > +   return 0;
> > > > +
> > > > +   if (conn_state->underscan.mode != DRM_UNDERSCAN_ON)
> > > > +   return 0;
> > > > +
> > > > +   crtc_state = drm_atomic_get_new_crtc_state(pstate->state,
> > > > +  pstate->crtc);
> > > > +
> > > > +   if (conn_state->underscan.hborder >= crtc_state->mode.hdisplay 
> > > > ||
> > > > +   conn_state->underscan.vborder >= crtc_state->mode.vdisplay)
> > > > +   return -EINVAL;
> > > 
> > > border * 2 ?  
> > 
> > Oops, indeed. I'll fix that.
> >   
> > >   
> > > > +
> > > > +   vc4_pstate->crtc_x += conn_state->underscan.hborder;
> > > > +   vc4_pstate->crtc_y += conn_state->underscan.vborder;
> > > > +   vc4_pstate->crtc_w = (vc4_pstate->crtc_w *
> > > > + (crtc_state->mode.hdisplay -
> > > > +  (conn_state->underscan.hborder * 2))) /
> > > > +crtc_state->mode.hdisplay;
> > > > +   vc4_pstate->crtc_h = (vc4_pstate->crtc_h *
> > > > + (crtc_state->mode.vdisplay -
> > > > +  (conn_state->underscan.vborder * 2))) /
> > > > +crtc_state->mode.vdisplay;
> > > 
> > > So you're now scaling all planes? The code seems to reject scaling for
> > > the cursor plane, how are you dealing with that? Or just no cursor
> > > allowed when underscanning?  
> > 
> > No, I just didn't test with a cursor plane. We should probably avoid
> > scaling the cursor plane and just adjust its position. Eric any opinion
> > on that?  
> 
> I don't think you can just not scale it. The user asked for the cursor
> to be at a specific place with a specific size. Can't just ignore
> that and do something else. Also eg. i915 wou

Re: [PATCH v2 2/4] drm/vc4: Take underscan setup into account when updating planes

2018-05-11 Thread Boris Brezillon
On Fri, 11 May 2018 20:29:48 +0300
Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:

> On Fri, May 11, 2018 at 07:12:21PM +0200, Boris Brezillon wrote:
> > On Fri, 11 May 2018 19:54:02 +0300
> > Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:
> >   
> > > On Fri, May 11, 2018 at 05:52:56PM +0200, Boris Brezillon wrote:  
> > > > On Fri, 11 May 2018 18:34:50 +0300
> > > > Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:
> > > > 
> > > > > On Fri, May 11, 2018 at 04:59:17PM +0200, Boris Brezillon wrote:
> > > > > > Applying an underscan setup is just a matter of scaling all planes
> > > > > > appropriately and adjusting the CRTC X/Y offset to account for the
> > > > > > horizontal and vertical border.
> > > > > > 
> > > > > > Create an vc4_plane_underscan_adj() function doing that and call it 
> > > > > > from
> > > > > > vc4_plane_setup_clipping_and_scaling() so that we are ready to 
> > > > > > attach
> > > > > > underscan properties to the HDMI connector.
> > > > > > 
> > > > > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > > > > > ---
> > > > > > Changes in v2:
> > > > > > - Take changes on hborder/vborder meaning into account
> > > > > > ---
> > > > > >  drivers/gpu/drm/vc4/vc4_plane.c | 49 
> > > > > > -
> > > > > >  1 file changed, 48 insertions(+), 1 deletion(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/vc4/vc4_plane.c 
> > > > > > b/drivers/gpu/drm/vc4/vc4_plane.c
> > > > > > index 71d44c357d35..61ed60841cd6 100644
> > > > > > --- a/drivers/gpu/drm/vc4/vc4_plane.c
> > > > > > +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> > > > > > @@ -258,6 +258,49 @@ static u32 vc4_get_scl_field(struct 
> > > > > > drm_plane_state *state, int plane)
> > > > > > }
> > > > > >  }
> > > > > >  
> > > > > > +static int vc4_plane_underscan_adj(struct drm_plane_state *pstate)
> > > > > > +{
> > > > > > +   struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate);
> > > > > > +   struct drm_connector_state *conn_state = NULL;
> > > > > > +   struct drm_connector *conn;
> > > > > > +   struct drm_crtc_state *crtc_state;
> > > > > > +   int i;
> > > > > > +
> > > > > > +   for_each_new_connector_in_state(pstate->state, conn, 
> > > > > > conn_state, i) {
> > > > > > +   if (conn_state->crtc == pstate->crtc)
> > > > > > +   break;
> > > > > > +   }
> > > > > > +
> > > > > > +   if (i == pstate->state->num_connector)
> > > > > > +   return 0;
> > > > > > +
> > > > > > +   if (conn_state->underscan.mode != DRM_UNDERSCAN_ON)
> > > > > > +   return 0;
> > > > > > +
> > > > > > +   crtc_state = drm_atomic_get_new_crtc_state(pstate->state,
> > > > > > +  pstate->crtc);
> > > > > > +
> > > > > > +   if (conn_state->underscan.hborder >= crtc_state->mode.hdisplay 
> > > > > > ||
> > > > > > +   conn_state->underscan.vborder >= crtc_state->mode.vdisplay)
> > > > > > +   return -EINVAL;  
> > > > > 
> > > > > border * 2 ?
> > > > 
> > > > Oops, indeed. I'll fix that.
> > > > 
> > > > > 
> > > > > > +
> > > > > > +   vc4_pstate->crtc_x += conn_state->underscan.hborder;
> > > > > > +   vc4_pstate->crtc_y += conn_state->underscan.vborder;
> > > > > > +   vc4_pstate->crtc_w = (vc4_pstate->crtc_w *
> > > > > > + (crtc_state->mode.hdisplay -
> > > > > > +  (conn_state->underscan.hborder * 2))) /
> > > > > > +crtc_state->mode.hdisplay;
> > > > > > +   vc4_pstate->crtc_h = (vc4_pst

Re: [BUG] drm/vc4: vblank wait timed out

2018-05-05 Thread Boris Brezillon
On Sat, 5 May 2018 19:44:57 +0200 (CEST)
Stefan Wahren  wrote:

> Hi Stefan,
> 
> > Stefan Schake  hat am 5. Mai 2018 um 19:29
> > geschrieben:
> > 
> > 
> > On Sat, May 5, 2018 at 1:47 PM, Stefan Wahren
> >  wrote:  
> > > Hi,
> > >
> > > after submit of the latest bcm2835 clock fixes, i thought this
> > > issue has been fixed. But i've seen this issue with current
> > > mainline 4.17-rc3 (bcm2835_defconfig) on Raspberry Pi 1 B (using
> > > U-Boot TFTP Boot). Strangly i couldn't reproduce this issue with
> > > same kernel but using only the Foundation bootloader (without
> > > U-Boot TFTP Boot).
> > >
> > > U-Boot version: 2018.03
> > >
> > > I triggered the warning using my HDMI switch:
> > >
> > > [  198.304572] [ cut here ]
> > > [  198.304693] WARNING: CPU: 0 PID: 10 at
> > > drivers/gpu/drm/drm_atomic_helper.c:1351
> > > drm_atomic_helper_wait_for_vblanks+0x1d4/0x1f0 [  198.304703]
> > > [CRTC:68:crtc-2] vblank wait timed out [  198.304751] Modules
> > > linked in: bcm2835_rng rng_core vchiq(C) [  198.304790] CPU: 0
> > > PID: 10 Comm: kworker/0:1 Tainted: G C4.17.0-rc3+
> > > #1 [  198.304796] Hardware name: BCM2835 [  198.304817]
> > > Workqueue: events output_poll_execute [  198.304867] []
> > > (unwind_backtrace) from [] (show_stack+0x20/0x24)
> > > [  198.304934] [] (show_stack) from []
> > > (dump_stack+0x20/0x28) [  198.304971] [] (dump_stack)
> > > from [] (__warn+0xec/0x104) [  198.305012] []
> > > (__warn) from [] (warn_slowpath_fmt+0x48/0x50)
> > > [  198.305048] [] (warn_slowpath_fmt) from []
> > > (drm_atomic_helper_wait_for_vblanks+0x1d4/0x1f0) [  198.305098]
> > > [] (drm_atomic_helper_wait_for_vblanks) from
> > > [] (vc4_atomic_complete_commit+0x80/0xb8)
> > > [  198.305144] [] (vc4_atomic_complete_commit) from
> > > [] (vc4_atomic_commit+0x110/0x11c) [  198.305174]
> > > [] (vc4_atomic_commit) from []
> > > (drm_atomic_commit+0x50/0x60) [  198.305202] []
> > > (drm_atomic_commit) from []
> > > (restore_fbdev_mode_atomic+0x80/0x1cc) [  198.305228]
> > > [] (restore_fbdev_mode_atomic) from []
> > > (restore_fbdev_mode+0x38/0x144) [  198.305270] []
> > > (restore_fbdev_mode) from []
> > > (drm_fb_helper_restore_fbdev_mode_unlocked+0x58/0x8c)
> > > [  198.305296] []
> > > (drm_fb_helper_restore_fbdev_mode_unlocked) from []
> > > (drm_fb_helper_set_par+0x54/0x60) [  198.305320] []
> > > (drm_fb_helper_set_par) from []
> > > (drm_fb_helper_hotplug_event+0xc8/0xd4) [  198.305343]
> > > [] (drm_fb_helper_hotplug_event) from []
> > > (drm_fb_helper_output_poll_changed+0x1c/0x20) [  198.305382]
> > > [] (drm_fb_helper_output_poll_changed) from
> > > [] (drm_kms_helper_hotplug_event+0x34/0x38)
> > > [  198.305409] [] (drm_kms_helper_hotplug_event) from
> > > [] (output_poll_execute+0x16c/0x17c) [  198.305440]
> > > [] (output_poll_execute) from []
> > > (process_one_work+0x1e0/0x368) [  198.305466] []
> > > (process_one_work) from [] (worker_thread+0x2a0/0x418)
> > > [  198.305511] [] (worker_thread) from []
> > > (kthread+0x144/0x15c) [  198.305539] [] (kthread) from
> > > [] (ret_from_fork+0x14/0x2c) [  198.305549] Exception
> > > stack(0xc9939fb0 to 0xc9939ff8) [  198.305562]
> > > 9fa0:  
> > >   [  198.305578] 9fc0:   
> > >      [  198.305591] 9fe0:
> > >     0013 
> > > [  198.305630] ---[ end trace 9c4071c657268b83 ]---
> > >
> > > I also dumped clk_summary in both cases, but they were identical.
> > >
> > > Are their any helpful information, which i can provide?
> > >
> > > Best regards
> > > Stefan  
> > 
> > I have seen this happen with one of those cheap Waveshare HDMI
> > displays. More often when connecting its power to the RPi versus on
> > a separate supply. Goes away when using a real, proper HDMI
> > display. They come with bad EDID data so I pretty much just blamed
> > the display at the time.
> > 
> > Does this happen during a switch and whats on the other end?  
> 
> The issue happens only in combination with U-Boot. If i switch the
> source between my PC and the RPi then sometimes the warning is
> triggered.

Is it working despite the WARN backtrace, or do you then get a black
screen? You say sometimes, that means sometimes it works, right? Also,
do you remember the mode (resolution+refresh-rate) you're using?
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/vc4: Fix scaling of uni-planar formats

2018-05-07 Thread Boris Brezillon
On Mon, 07 May 2018 08:56:14 -0700
Eric Anholt <e...@anholt.net> wrote:

> Boris Brezillon <boris.brezil...@bootlin.com> writes:
> 
> > When using uni-planar formats (like RGB), the scaling parameters are
> > stored in plane 0, not plane 1.
> >
> > Fixes: fc04023fafec ("drm/vc4: Add support for YUV planes.")
> > Cc: sta...@vger.kernel.org
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>  
> 
> Reviewed-by: Eric Anholt <e...@anholt.net>
> 
> Looking at the other branch, did I get the scl0/scl1 backwards?  HVS
> docs say for non-444 YCBCR: "In these cases Channel 0 performs Y/Alpha
> scaling and Channel 1 performs CB/CR scaling and should be configured as
> appropriate."

Didn't test, but I think rescaling of multi-planar format is correct.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/3] drm/connector: Add generic underscan properties

2018-05-07 Thread Boris Brezillon
On Mon, 7 May 2018 18:01:44 +0300
Ville Syrjälä <ville.syrj...@linux.intel.com> wrote:

> On Mon, May 07, 2018 at 04:44:32PM +0200, Boris Brezillon wrote:
> > We have 3 drivers defining the "underscan", "underscan hborder" and
> > "underscan vborder" properties (radeon, amd and nouveau) and we are
> > about to add the same kind of thing in VC4.
> > 
> > Define generic underscan props and add new fields to the drm_connector
> > state so that the property parsing logic can be shared by all DRM
> > drivers.
> > 
> > A driver can now attach underscan properties to its connector through
> > the drm_connector_attach_underscan_properties() helper, and can
> > check/apply the underscan setup based on the
> > drm_connector_state->underscan fields.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> >  drivers/gpu/drm/drm_atomic.c|  12 
> >  drivers/gpu/drm/drm_connector.c | 120 
> > 
> >  include/drm/drm_connector.h |  78 ++
> >  3 files changed, 210 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index dc850b4b6e21..b7312bd172c9 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -1278,6 +1278,12 @@ static int drm_atomic_connector_set_property(struct 
> > drm_connector *connector,
> > return -EINVAL;
> > }
> > state->content_protection = val;
> > +   } else if (property == connector->underscan_mode_property) {
> > +   state->underscan.mode = val;
> > +   } else if (property == connector->underscan_hborder_property) {
> > +   state->underscan.hborder = val;
> > +   } else if (property == connector->underscan_vborder_property) {
> > +   state->underscan.vborder = val;
> > } else if (connector->funcs->atomic_set_property) {
> > return connector->funcs->atomic_set_property(connector,
> > state, property, val);
> > @@ -1359,6 +1365,12 @@ drm_atomic_connector_get_property(struct 
> > drm_connector *connector,
> > *val = state->scaling_mode;
> > } else if (property == connector->content_protection_property) {
> > *val = state->content_protection;
> > +   } else if (property == connector->underscan_mode_property) {
> > +   *val = state->underscan.mode;
> > +   } else if (property == connector->underscan_hborder_property) {
> > +   *val = state->underscan.hborder;
> > +   } else if (property == connector->underscan_vborder_property) {
> > +   *val = state->underscan.vborder;
> > } else if (connector->funcs->atomic_get_property) {
> > return connector->funcs->atomic_get_property(connector,
> > state, property, val);
> > diff --git a/drivers/gpu/drm/drm_connector.c 
> > b/drivers/gpu/drm/drm_connector.c
> > index dfc8ca1e9413..9937390b8a25 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -914,6 +914,31 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, 
> > drm_cp_enum_list)
> >   * can also expose this property to external outputs, in which case they
> >   * must support "None", which should be the default (since external screens
> >   * have a built-in scaler).
> > + *
> > + * underscan:
> > + * This properties defines whether underscan is activated or not, and when
> > + * it is activated, how the horizontal and vertical borders are calculated:
> > + *
> > + * off:
> > + * Underscan is disabled. The output image shouldn't be scaled to
> > + * take screen borders into account.  
> 
> > + * on:
> > + * Underscan is activated and horizontal and vertical borders are
> > + * specified through the "underscan hborder" and
> > + * "underscan vborder" properties.  
> 
> How is the output scaled?

In HW. The formula is

hfactor = (hdisplay - hborder) / hdisplay
vfactor = (vdisplay - vborder) / vdisplay

> What does the user mode hdisplay/vdisplay mean
> in this case?

The same as before this patch: the output resolution. You just add
black margins.

> What if I want underscan without scaling?

Then don't involve the DRM driver and do that from userspace: just
fill the visible portion of the framebuffer

Re: [PATCH v2 5/6] drm/vc4: Support the case where the DSI device is disabled

2018-05-04 Thread Boris Brezillon
On Fri, 4 May 2018 12:28:33 +0200
Thierry Reding <thierry.red...@gmail.com> wrote:

> On Thu, May 03, 2018 at 06:40:08PM +0200, Boris Brezillon wrote:
> > Having a device with a status property != "okay" in the DT is a valid
> > use case, and we should not prevent the registration of the DRM device
> > when the DSI device connected to the DSI controller is disabled.
> > 
> > Consider the ENODEV return code as a valid result and do not expose the
> > DSI encoder/connector when it happens.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> >  drivers/gpu/drm/vc4/vc4_dsi.c | 15 +--
> >  1 file changed, 13 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
> > index 8aa897835118..db2f137f8b7b 100644
> > --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> > @@ -1606,8 +1606,18 @@ static int vc4_dsi_bind(struct device *dev, struct 
> > device *master, void *data)
> >  
> > ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> >   , >bridge);
> > -   if (ret)
> > +   if (ret) {
> > +   /* If the bridge or panel pointed by dev->of_node is not
> > +* enabled, just return 0 here so that we don't prevent the DRM
> > +* dev from being registered. Of course that means the DSI
> > +* encoder won't be exposed, but that's not a problem since
> > +* nothing is connected to it.
> > +*/
> > +   if (ret == -ENODEV)
> > +   return 0;
> > +
> > return ret;
> > +   }
> >  
> > if (panel) {
> > dsi->bridge = devm_drm_panel_bridge_add(dev, panel,
> > @@ -1652,7 +1662,8 @@ static void vc4_dsi_unbind(struct device *dev, struct 
> > device *master,
> > struct vc4_dev *vc4 = to_vc4_dev(drm);
> > struct vc4_dsi *dsi = dev_get_drvdata(dev);
> >  
> > -   pm_runtime_disable(dev);
> > +   if (dsi->bridge)
> > +   pm_runtime_disable(dev);  
> 
> Is this safe? This uses component/master, so dsi->bridge is going to
> remain valid until the driver's ->remove() is called. So technically you
> could have a situation where drm_of_find_panel_or_bridge() returned some
> error code that remains stored in dsi->bridge and cause the above
> condition to be incorrectly true.

No, because of_drm_find_bridge() (which is called from
drm_of_find_panel_or_bridge() returns either NULL or a valid bridge
pointer), so dsi->bridge either points to a valid bridge object or is
NULL. Am I missing something?

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


Re: [PATCH v2 5/6] drm/vc4: Support the case where the DSI device is disabled

2018-05-04 Thread Boris Brezillon
On Fri, 4 May 2018 12:30:25 +0200
Thierry Reding <thierry.red...@gmail.com> wrote:

> On Thu, May 03, 2018 at 06:40:08PM +0200, Boris Brezillon wrote:
> > Having a device with a status property != "okay" in the DT is a valid
> > use case, and we should not prevent the registration of the DRM device
> > when the DSI device connected to the DSI controller is disabled.
> > 
> > Consider the ENODEV return code as a valid result and do not expose the
> > DSI encoder/connector when it happens.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> >  drivers/gpu/drm/vc4/vc4_dsi.c | 15 +--
> >  1 file changed, 13 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
> > index 8aa897835118..db2f137f8b7b 100644
> > --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> > @@ -1606,8 +1606,18 @@ static int vc4_dsi_bind(struct device *dev, struct 
> > device *master, void *data)
> >  
> > ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> >   , >bridge);
> > -   if (ret)
> > +   if (ret) {
> > +   /* If the bridge or panel pointed by dev->of_node is not
> > +* enabled, just return 0 here so that we don't prevent the DRM
> > +* dev from being registered. Of course that means the DSI
> > +* encoder won't be exposed, but that's not a problem since
> > +* nothing is connected to it.
> > +*/  
> 
> Also, nit: this isn't the correct style for block comments.

Just trying to keep it consistent with the rest of the file.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 6/6] drm/panel: rpi-touchscreen: Set status to "fail" when ->probe() fails

2018-05-04 Thread Boris Brezillon
On Fri, 4 May 2018 11:47:48 +0200
Thierry Reding <thierry.red...@gmail.com> wrote:

> On Fri, May 04, 2018 at 10:06:53AM +0200, Boris Brezillon wrote:
> > Hi Rob,
> > 
> > On Thu, 3 May 2018 12:12:39 -0500
> > Rob Herring <robh...@kernel.org> wrote:
> >   
> > > On Thu, May 3, 2018 at 11:40 AM, Boris Brezillon
> > > <boris.brezil...@bootlin.com> wrote:  
> > > > The device might be described in the device tree but not connected to
> > > > the I2C bus. Update the status property so that the DRM panel logic
> > > > returns -ENODEV when someone tries to get the panel attached to this
> > > > DT node.
> > > >
> > > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > > > ---
> > > >  .../gpu/drm/panel/panel-raspberrypi-touchscreen.c  | 35 
> > > > ++
> > > >  1 file changed, 35 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
> > > > b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > index 2c9c9722734f..b8fcb1acef75 100644
> > > > --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > @@ -358,6 +358,39 @@ static const struct drm_panel_funcs 
> > > > rpi_touchscreen_funcs = {
> > > > .get_modes = rpi_touchscreen_get_modes,
> > > >  };
> > > >
> > > > +static void rpi_touchscreen_set_status_fail(struct i2c_client *i2c)
> > > > +{
> > > > +   struct property *newprop;
> > > > +
> > > > +   newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
> > > > +   if (!newprop)
> > > > +   return;
> > > > +
> > > > +   newprop->name = kstrdup("status", GFP_KERNEL);
> > > > +   if (!newprop->name)
> > > > +   goto err;
> > > > +
> > > > +   newprop->value = kstrdup("fail", GFP_KERNEL);
> > > > +   if (!newprop->value)
> > > > +   goto err;
> > > > +
> > > > +   newprop->length = sizeof("fail");
> > > > +
> > > > +   if (of_update_property(i2c->dev.of_node, newprop))
> > > > +   goto err;
> > > > +
> > > 
> > > As I mentioned on irc, can you make this a common DT function.  
> > 
> > Yep, will move that to drivers/of/base.c and make it generic.
> >   
> > > 
> > > I'm not sure if it matters that we set status to fail vs. disabled. I
> > > somewhat prefer the latter as we already have other cases and I'd
> > > rather the api not pass a string in. I can't think of any reason to
> > > distinguish the difference between fail and disabled.  
> > 
> > Well, I just read the ePAPR doc pointed by Thierry [1] (section 2.3.4),
> > and "fail" seemed like a good match for what we are trying to express
> > here: "we failed to communicate with the device in the probe function
> > and want to mark it unusable", which is a bit different from "the
> > device was explicitly disabled by the user".
> > 
> > Anyway, if you think "disabled" is more appropriate, I'll use that.
> >   
> > >   
> > > > +   /* We intentionally leak the memory we allocate here, because 
> > > > the new
> > > > +* OF property might live longer than the underlying dev, so no 
> > > > way
> > > > +* we can use devm_kzalloc() here.
> > > > +*/
> > > > +   return;
> > > > +
> > > > +err:
> > > > +   kfree(newprop->value);
> > > > +   kfree(newprop->name);
> > > > +   kfree(newprop);
> > > > +}
> > > > +
> > > >  static int rpi_touchscreen_probe(struct i2c_client *i2c,
> > > >  const struct i2c_device_id *id)
> > > >  {
> > > > @@ -382,6 +415,7 @@ static int rpi_touchscreen_probe(struct i2c_client 
> > > > *i2c,
> > > >
> > > > ver = rpi_touchscreen_i2c_read(ts, REG_ID);
> > > > if (ver < 0) {
> > > > +   rpi_touchscreen_set_status_fail(i2c);
> > > 
> > > I've thought some more about this and I s

Re: [PATCH v2 2/6] drm/panel: Make of_drm_find_panel() return an ERR_PTR() instead of NULL

2018-05-04 Thread Boris Brezillon
Hi Thierry,

On Fri, 4 May 2018 12:18:52 +0200
Thierry Reding <thierry.red...@gmail.com> wrote:

> On Thu, May 03, 2018 at 06:40:05PM +0200, Boris Brezillon wrote:
> > Right now, the DRM panel logic returns NULL when a panel pointing to
> > the passed OF node is not present in the list of registered panels.
> > 
> > Most drivers interpret this NULL value as -EPROBE_DEFER, but we are
> > about to modify the semantic of of_drm_find_panel() and let the
> > framework return -ENODEV when the device node we're pointing to has
> > a status property that is not equal to "okay" or "ok".
> > 
> > Let's first patch the of_drm_find_panel() implementation to return
> > ERR_PTR(-EPROBE_DEFER) instead of NULL and patch all callers to replace
> > the '!panel' check by an 'IS_ERR(panel)' one.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> >  drivers/gpu/drm/bridge/cdns-dsi.c   |  2 +-
> >  drivers/gpu/drm/bridge/lvds-encoder.c   |  4 ++--
> >  drivers/gpu/drm/drm_of.c|  8 ++--
> >  drivers/gpu/drm/drm_panel.c |  6 --
> >  drivers/gpu/drm/exynos/exynos_dp.c  |  9 ++---
> >  drivers/gpu/drm/exynos/exynos_drm_dpi.c |  9 ++---
> >  drivers/gpu/drm/exynos/exynos_drm_dsi.c |  6 --
> >  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c   |  8 +---
> >  drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c   |  4 ++--
> >  drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c | 10 +++---
> >  drivers/gpu/drm/msm/dsi/dsi_host.c  |  2 +-
> >  drivers/gpu/drm/rcar-du/rcar_lvds.c |  9 ++---
> >  drivers/gpu/drm/rockchip/dw-mipi-dsi.c  |  2 +-
> >  drivers/gpu/drm/sti/sti_dvo.c   |  7 +--
> >  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c  |  4 ++--
> >  drivers/gpu/drm/tegra/dsi.c |  6 --
> >  drivers/gpu/drm/tegra/output.c  | 18 +++---
> >  include/drm/drm_panel.h |  2 +-
> >  18 files changed, 74 insertions(+), 42 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c 
> > b/drivers/gpu/drm/bridge/cdns-dsi.c
> > index c255fc3e1be5..2c5991cf5397 100644
> > --- a/drivers/gpu/drm/bridge/cdns-dsi.c
> > +++ b/drivers/gpu/drm/bridge/cdns-dsi.c
> > @@ -1152,7 +1152,7 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host,
> > np = of_node_get(dev->dev.of_node);
> >  
> > panel = of_drm_find_panel(np);
> > -   if (panel) {
> > +   if (!IS_ERR(panel)) {
> > bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
> > } else {
> > bridge = of_drm_find_bridge(dev->dev.of_node);
> > diff --git a/drivers/gpu/drm/bridge/lvds-encoder.c 
> > b/drivers/gpu/drm/bridge/lvds-encoder.c
> > index 75b0d3f6e4de..f56c92f7af7c 100644
> > --- a/drivers/gpu/drm/bridge/lvds-encoder.c
> > +++ b/drivers/gpu/drm/bridge/lvds-encoder.c
> > @@ -68,9 +68,9 @@ static int lvds_encoder_probe(struct platform_device 
> > *pdev)
> >  
> > panel = of_drm_find_panel(panel_node);
> > of_node_put(panel_node);
> > -   if (!panel) {
> > +   if (IS_ERR(panel)) {
> > dev_dbg(>dev, "panel not found, deferring probe\n");
> > -   return -EPROBE_DEFER;
> > +   return PTR_ERR(panel);
> > }
> >  
> > lvds_encoder->panel_bridge =
> > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> > index 1fe122461298..f413fae6f6dc 100644
> > --- a/drivers/gpu/drm/drm_of.c
> > +++ b/drivers/gpu/drm/drm_of.c
> > @@ -239,9 +239,13 @@ int drm_of_find_panel_or_bridge(const struct 
> > device_node *np,
> > return -ENODEV;
> >  
> > if (panel) {
> > -   *panel = of_drm_find_panel(remote);
> > -   if (*panel)
> > +   struct drm_panel *tmp_panel;
> > +
> > +   tmp_panel = of_drm_find_panel(remote);
> > +   if (!IS_ERR(tmp_panel)) {
> > +   *panel = tmp_panel;
> > ret = 0;
> > +   }  
> 
> I think the introduction of this temporary variable makes the code hard
> to read and the diff difficult to understand. Why not just stick with
> the original style and make this:
> 
>   *panel = of_drm_find_panel(remote);
>   if (IS_ERR(*panel))
>   *p

Re: [PATCH v2 5/6] drm/vc4: Support the case where the DSI device is disabled

2018-05-04 Thread Boris Brezillon
On Fri, 4 May 2018 15:29:15 +0200
Thierry Reding <thierry.red...@gmail.com> wrote:

> On Fri, May 04, 2018 at 02:05:25PM +0200, Boris Brezillon wrote:
> > On Fri, 4 May 2018 12:28:33 +0200
> > Thierry Reding <thierry.red...@gmail.com> wrote:
> >   
> > > On Thu, May 03, 2018 at 06:40:08PM +0200, Boris Brezillon wrote:  
> > > > Having a device with a status property != "okay" in the DT is a valid
> > > > use case, and we should not prevent the registration of the DRM device
> > > > when the DSI device connected to the DSI controller is disabled.
> > > > 
> > > > Consider the ENODEV return code as a valid result and do not expose the
> > > > DSI encoder/connector when it happens.
> > > > 
> > > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > > > ---
> > > >  drivers/gpu/drm/vc4/vc4_dsi.c | 15 +--
> > > >  1 file changed, 13 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c 
> > > > b/drivers/gpu/drm/vc4/vc4_dsi.c
> > > > index 8aa897835118..db2f137f8b7b 100644
> > > > --- a/drivers/gpu/drm/vc4/vc4_dsi.c
> > > > +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
> > > > @@ -1606,8 +1606,18 @@ static int vc4_dsi_bind(struct device *dev, 
> > > > struct device *master, void *data)
> > > >  
> > > > ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> > > >   , >bridge);
> > > > -   if (ret)
> > > > +   if (ret) {
> > > > +   /* If the bridge or panel pointed by dev->of_node is not
> > > > +* enabled, just return 0 here so that we don't prevent 
> > > > the DRM
> > > > +* dev from being registered. Of course that means the 
> > > > DSI
> > > > +* encoder won't be exposed, but that's not a problem 
> > > > since
> > > > +* nothing is connected to it.
> > > > +*/
> > > > +   if (ret == -ENODEV)
> > > > +   return 0;
> > > > +
> > > > return ret;
> > > > +   }
> > > >  
> > > > if (panel) {
> > > > dsi->bridge = devm_drm_panel_bridge_add(dev, panel,
> > > > @@ -1652,7 +1662,8 @@ static void vc4_dsi_unbind(struct device *dev, 
> > > > struct device *master,
> > > > struct vc4_dev *vc4 = to_vc4_dev(drm);
> > > > struct vc4_dsi *dsi = dev_get_drvdata(dev);
> > > >  
> > > > -   pm_runtime_disable(dev);
> > > > +   if (dsi->bridge)
> > > > +   pm_runtime_disable(dev);
> > > 
> > > Is this safe? This uses component/master, so dsi->bridge is going to
> > > remain valid until the driver's ->remove() is called. So technically you
> > > could have a situation where drm_of_find_panel_or_bridge() returned some
> > > error code that remains stored in dsi->bridge and cause the above
> > > condition to be incorrectly true.  
> > 
> > No, because of_drm_find_bridge() (which is called from
> > drm_of_find_panel_or_bridge() returns either NULL or a valid bridge
> > pointer), so dsi->bridge either points to a valid bridge object or is
> > NULL. Am I missing something?  
> 
> The return value of devm_drm_panel_bridge_add() is also assigned to
> dsi->bridge later on (in the "if (panel)" conditional).

But then we return an error code if IS_ERR(dsi->bridge) [1], which
should prevent the unbind function from being called, right?

[1]https://elixir.bootlin.com/linux/v4.17-rc3/source/drivers/gpu/drm/vc4/vc4_dsi.c#L1610
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 6/6] drm/panel: rpi-touchscreen: Set status to "fail" when ->probe() fails

2018-05-04 Thread Boris Brezillon
Hi Rob,

On Thu, 3 May 2018 12:12:39 -0500
Rob Herring <robh...@kernel.org> wrote:

> On Thu, May 3, 2018 at 11:40 AM, Boris Brezillon
> <boris.brezil...@bootlin.com> wrote:
> > The device might be described in the device tree but not connected to
> > the I2C bus. Update the status property so that the DRM panel logic
> > returns -ENODEV when someone tries to get the panel attached to this
> > DT node.
> >
> > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > ---
> >  .../gpu/drm/panel/panel-raspberrypi-touchscreen.c  | 35 
> > ++
> >  1 file changed, 35 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
> > b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > index 2c9c9722734f..b8fcb1acef75 100644
> > --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > @@ -358,6 +358,39 @@ static const struct drm_panel_funcs 
> > rpi_touchscreen_funcs = {
> > .get_modes = rpi_touchscreen_get_modes,
> >  };
> >
> > +static void rpi_touchscreen_set_status_fail(struct i2c_client *i2c)
> > +{
> > +   struct property *newprop;
> > +
> > +   newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
> > +   if (!newprop)
> > +   return;
> > +
> > +   newprop->name = kstrdup("status", GFP_KERNEL);
> > +   if (!newprop->name)
> > +   goto err;
> > +
> > +   newprop->value = kstrdup("fail", GFP_KERNEL);
> > +   if (!newprop->value)
> > +   goto err;
> > +
> > +   newprop->length = sizeof("fail");
> > +
> > +   if (of_update_property(i2c->dev.of_node, newprop))
> > +   goto err;
> > +  
> 
> As I mentioned on irc, can you make this a common DT function.

Yep, will move that to drivers/of/base.c and make it generic.

> 
> I'm not sure if it matters that we set status to fail vs. disabled. I
> somewhat prefer the latter as we already have other cases and I'd
> rather the api not pass a string in. I can't think of any reason to
> distinguish the difference between fail and disabled.

Well, I just read the ePAPR doc pointed by Thierry [1] (section 2.3.4),
and "fail" seemed like a good match for what we are trying to express
here: "we failed to communicate with the device in the probe function
and want to mark it unusable", which is a bit different from "the
device was explicitly disabled by the user".

Anyway, if you think "disabled" is more appropriate, I'll use that.

> 
> > +   /* We intentionally leak the memory we allocate here, because the 
> > new
> > +* OF property might live longer than the underlying dev, so no way
> > +* we can use devm_kzalloc() here.
> > +*/
> > +   return;
> > +
> > +err:
> > +   kfree(newprop->value);
> > +   kfree(newprop->name);
> > +   kfree(newprop);
> > +}
> > +
> >  static int rpi_touchscreen_probe(struct i2c_client *i2c,
> >  const struct i2c_device_id *id)
> >  {
> > @@ -382,6 +415,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
> >
> > ver = rpi_touchscreen_i2c_read(ts, REG_ID);
> > if (ver < 0) {
> > +   rpi_touchscreen_set_status_fail(i2c);  
> 
> I've thought some more about this and I still think this should be
> handled in the driver core or i2c core.
> 
> The reason is simple. I think the state of the system should be the
> same after this as if you booted with 'status = "disabled"' for this
> node. And that means the device should be removed completely because
> we don't create struct device's for disabled nodes.

That was my feeling to when first discussing the issue with Daniel and
Thierry on IRC, but after digging a bit in the code I'm no longer sure
this is a good idea. At least, I don't think basing the decision to
disable the device (or mark it unusable) based on the return value of
the probe function is a good idea. What I can do is:

1/ provide a function to change the status prop in of.h
2/ let each driver call this function if they want to
3/ let the I2C core test the status prop again after the probe function
   has returned an error to determine whether the device (I mean struct
   i2c_client/device object) should be removed

Would that work for you?

Regards,

Boris

[1]https://elinux.org/images/c/cf/Power_ePAPR_APPROVED_v1.1.pdf
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 6/6] drm/panel: rpi-touchscreen: Set status to "fail" when ->probe() fails

2018-05-04 Thread Boris Brezillon
On Fri, 4 May 2018 16:20:17 +0200
Daniel Vetter <dan...@ffwll.ch> wrote:

> On Fri, May 04, 2018 at 02:17:49PM +0200, Boris Brezillon wrote:
> > On Fri, 4 May 2018 11:47:48 +0200
> > Thierry Reding <thierry.red...@gmail.com> wrote:
> >   
> > > On Fri, May 04, 2018 at 10:06:53AM +0200, Boris Brezillon wrote:  
> > > > Hi Rob,
> > > > 
> > > > On Thu, 3 May 2018 12:12:39 -0500
> > > > Rob Herring <robh...@kernel.org> wrote:
> > > > 
> > > > > On Thu, May 3, 2018 at 11:40 AM, Boris Brezillon
> > > > > <boris.brezil...@bootlin.com> wrote:
> > > > > > The device might be described in the device tree but not connected 
> > > > > > to
> > > > > > the I2C bus. Update the status property so that the DRM panel logic
> > > > > > returns -ENODEV when someone tries to get the panel attached to this
> > > > > > DT node.
> > > > > >
> > > > > > Signed-off-by: Boris Brezillon <boris.brezil...@bootlin.com>
> > > > > > ---
> > > > > >  .../gpu/drm/panel/panel-raspberrypi-touchscreen.c  | 35 
> > > > > > ++
> > > > > >  1 file changed, 35 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
> > > > > > b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > > > index 2c9c9722734f..b8fcb1acef75 100644
> > > > > > --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > > > +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> > > > > > @@ -358,6 +358,39 @@ static const struct drm_panel_funcs 
> > > > > > rpi_touchscreen_funcs = {
> > > > > > .get_modes = rpi_touchscreen_get_modes,
> > > > > >  };
> > > > > >
> > > > > > +static void rpi_touchscreen_set_status_fail(struct i2c_client *i2c)
> > > > > > +{
> > > > > > +   struct property *newprop;
> > > > > > +
> > > > > > +   newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
> > > > > > +   if (!newprop)
> > > > > > +   return;
> > > > > > +
> > > > > > +   newprop->name = kstrdup("status", GFP_KERNEL);
> > > > > > +   if (!newprop->name)
> > > > > > +   goto err;
> > > > > > +
> > > > > > +   newprop->value = kstrdup("fail", GFP_KERNEL);
> > > > > > +   if (!newprop->value)
> > > > > > +   goto err;
> > > > > > +
> > > > > > +   newprop->length = sizeof("fail");
> > > > > > +
> > > > > > +   if (of_update_property(i2c->dev.of_node, newprop))
> > > > > > +   goto err;
> > > > > > +  
> > > > > 
> > > > > As I mentioned on irc, can you make this a common DT function.
> > > > 
> > > > Yep, will move that to drivers/of/base.c and make it generic.
> > > > 
> > > > > 
> > > > > I'm not sure if it matters that we set status to fail vs. disabled. I
> > > > > somewhat prefer the latter as we already have other cases and I'd
> > > > > rather the api not pass a string in. I can't think of any reason to
> > > > > distinguish the difference between fail and disabled.
> > > > 
> > > > Well, I just read the ePAPR doc pointed by Thierry [1] (section 2.3.4),
> > > > and "fail" seemed like a good match for what we are trying to express
> > > > here: "we failed to communicate with the device in the probe function
> > > > and want to mark it unusable", which is a bit different from "the
> > > > device was explicitly disabled by the user".
> > > > 
> > > > Anyway, if you think "disabled" is more appropriate, I'll use that.
> > > > 
> > > > > 
> > > > > > +   /* We intentionally leak the memory we allocate here, 
> > > > > > because the new
> > > > > > +* OF property might live longer than the underlying dev, 
> > > > > > so no way
> 

Re: [PATCH v2] drm/atmel-hlcdc: check stride values in the first plane

2018-06-17 Thread Boris Brezillon
On Sun, 17 Jun 2018 10:48:22 +0200
Stefan Agner  wrote:

> The statement always evaluates to true since the struct fields
> are arrays. This has shown up as a warning when compiling with
> clang:
>   warning: address of array 'desc->layout.xstride' will always
>   evaluate to 'true' [-Wpointer-bool-conversion]
> 
> Check for values in the first plane instead.
> 
> Signed-off-by: Stefan Agner 

I'll add

Fixes: 1a396789f65a ("drm: add Atmel HLCDC Display Controller support")
Cc: sta...@vger.kernel.org

when applying.

Thanks,

Boris

> ---
> Changes in v2:
> - Check for first value instead of dropping if statement
>   (subject was: drm/atmel-hlcdc: remove unnecessary if statement)
> 
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 
> b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index 73c875db45f4..47e0992f3908 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -839,7 +839,7 @@ static int atmel_hlcdc_plane_init_properties(struct 
> atmel_hlcdc_plane *plane)
>   return ret;
>   }
>  
> - if (desc->layout.xstride && desc->layout.pstride) {
> + if (desc->layout.xstride[0] && desc->layout.pstride[0]) {
>   int ret;
>  
>   ret = drm_plane_create_rotation_property(>base,

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


Re: [PATCH] drm/atmel-hlcdc: remove unnecessary if statement

2018-06-17 Thread Boris Brezillon
On Sun, 17 Jun 2018 01:34:34 +0200
Stefan Agner  wrote:

> Boris, Maxime,
> 
> On 07.08.2017 08:26, Stefan Agner wrote:
> > The statement always evaluates to true since the struct fields
> > are arrays. This has shown up as a warning when compiling with
> > clang:
> >   warning: address of array 'desc->layout.xstride' will always
> >   evaluate to 'true' [-Wpointer-bool-conversion]  
> 
> It seems that this patch never made it upstream. It still produces a
> warning when building with clang. Maybe you could have a look and queue?

Oops, sorry, I missed that one.

> 
> --
> Stefan
> 
> > 
> > Signed-off-by: Stefan Agner 
> > ---
> >  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 21 +
> >  1 file changed, 9 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> > b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> > index 1124200bb280..9bd8c4888035 100644
> > --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> > +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> > @@ -854,24 +854,21 @@ static int
> > atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
> > struct atmel_hlcdc_plane_properties *props)
> >  {
> > const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> > +   int ret;
> >  
> > if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
> > desc->type == ATMEL_HLCDC_CURSOR_LAYER)
> > drm_object_attach_property(>base.base,
> >props->alpha, 255);
> >  
> > -   if (desc->layout.xstride && desc->layout.pstride) {

The test should be 

if (desc->layout.xstride[0] && desc->layout.pstride[0])

Can you send a new version with this change?

> > -   int ret;
> > -
> > -   ret = drm_plane_create_rotation_property(>base,
> > -DRM_MODE_ROTATE_0,
> > -DRM_MODE_ROTATE_0 |
> > -DRM_MODE_ROTATE_90 |
> > -DRM_MODE_ROTATE_180 |
> > -DRM_MODE_ROTATE_270);
> > -   if (ret)
> > -   return ret;
> > -   }
> > +   ret = drm_plane_create_rotation_property(>base,
> > +DRM_MODE_ROTATE_0,
> > +DRM_MODE_ROTATE_0 |
> > +DRM_MODE_ROTATE_90 |
> > +DRM_MODE_ROTATE_180 |
> > +DRM_MODE_ROTATE_270);
> > +   if (ret)
> > +   return ret;
> >  
> > if (desc->layout.csc) {
> > /*  

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


Re: [PATCH v2] drm/atmel-hlcdc: check stride values in the first plane

2018-06-17 Thread Boris Brezillon
On Sun, 17 Jun 2018 10:48:22 +0200
Stefan Agner  wrote:

> The statement always evaluates to true since the struct fields
> are arrays. This has shown up as a warning when compiling with
> clang:
>   warning: address of array 'desc->layout.xstride' will always
>   evaluate to 'true' [-Wpointer-bool-conversion]
> 
> Check for values in the first plane instead.
> 
> Signed-off-by: Stefan Agner 

Applied to drm-misc-fixes.

Thanks,

Boris

> ---
> Changes in v2:
> - Check for first value instead of dropping if statement
>   (subject was: drm/atmel-hlcdc: remove unnecessary if statement)
> 
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 
> b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index 73c875db45f4..47e0992f3908 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -839,7 +839,7 @@ static int atmel_hlcdc_plane_init_properties(struct 
> atmel_hlcdc_plane *plane)
>   return ret;
>   }
>  
> - if (desc->layout.xstride && desc->layout.pstride) {
> + if (desc->layout.xstride[0] && desc->layout.pstride[0]) {
>   int ret;
>  
>   ret = drm_plane_create_rotation_property(>base,

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


Re: [PATCH 8/8] drm/bridge: cdns: mark PM functions as __maybe_unused

2018-05-28 Thread Boris Brezillon
+Thierry

Hi Arnd,

On Fri, 25 May 2018 17:50:15 +0200
Arnd Bergmann  wrote:

> These two functions are unused in some configurations, and using 
> __maybe_unused
> is the easiest way to shut up the harmless warnings:
> 
> drivers/gpu/drm/bridge/cdns-dsi.c:1353:12: error: 'cdns_dsi_suspend' defined 
> but not used [-Werror=unused-function]
>  static int cdns_dsi_suspend(struct device *dev)
> ^~~~
> drivers/gpu/drm/bridge/cdns-dsi.c:1340:12: error: 'cdns_dsi_resume' defined 
> but not used [-Werror=unused-function]
>  static int cdns_dsi_resume(struct device *dev)
> 
> Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver")
> Signed-off-by: Arnd Bergmann 

Hm, I thought such a patch had already been applied by Thierry [1].

[1]https://www.spinics.net/lists/dri-devel/msg174363.html

> ---
>  drivers/gpu/drm/bridge/cdns-dsi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c 
> b/drivers/gpu/drm/bridge/cdns-dsi.c
> index c255fc3e1be5..f2d43f24acfb 100644
> --- a/drivers/gpu/drm/bridge/cdns-dsi.c
> +++ b/drivers/gpu/drm/bridge/cdns-dsi.c
> @@ -1337,7 +1337,7 @@ static const struct mipi_dsi_host_ops cdns_dsi_ops = {
>   .transfer = cdns_dsi_transfer,
>  };
>  
> -static int cdns_dsi_resume(struct device *dev)
> +static int __maybe_unused cdns_dsi_resume(struct device *dev)
>  {
>   struct cdns_dsi *dsi = dev_get_drvdata(dev);
>  
> @@ -1350,7 +1350,7 @@ static int cdns_dsi_resume(struct device *dev)
>   return 0;
>  }
>  
> -static int cdns_dsi_suspend(struct device *dev)
> +static int __maybe_unused cdns_dsi_suspend(struct device *dev)
>  {
>   struct cdns_dsi *dsi = dev_get_drvdata(dev);
>  

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


Re: [PATCH v2 7/8] drm/vc4: Add support for the transposer block

2018-07-02 Thread Boris Brezillon
Hi Eric,

On Fri, 29 Jun 2018 13:35:04 -0700
Eric Anholt  wrote:

> Boris Brezillon  writes:
> 
> > From: Boris Brezillon 
> >
> > The transposer block is providing support for mem-to-mem composition,
> > which is exposed as a drm_writeback connector in DRM.
> >
> > Add a driver to support this feature.
> >
> > Signed-off-by: Boris Brezillon   
> 
> > +static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> > +{
> > +   struct drm_device *dev = crtc->dev;
> > +   struct vc4_dev *vc4 = to_vc4_dev(dev);
> > +   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> > +   struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
> > +   struct drm_display_mode *mode = >state->adjusted_mode;
> > +   bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
> > +   bool debug_dump_regs = false;
> > +
> > +   if (debug_dump_regs) {
> > +   DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
> > +   vc4_crtc_dump_regs(vc4_crtc);
> > +   }
> > +
> > +   if (vc4_crtc->channel == 2) {
> > +   u32 dispctrl;
> > +   u32 dsp3_mux;
> > +
> > +   /*
> > +* SCALER_DISPCTRL_DSP3 = X, where X < 2 means 'connect DSP3 to
> > +* FIFO X'.
> > +* SCALER_DISPCTRL_DSP3 = 3 means 'disable DSP 3'.
> > +*
> > +* DSP3 is connected to FIFO2 unless the transposer is
> > +* enabled. In this case, FIFO 2 is directly accessed by the
> > +* TXP IP, and we need to prevent disable the  
> 
> s/prevent //
> 
> > +* FIFO2 -> pixelvalve1 route.
> > +*/
> > +   if (vc4_state->feed_txp)
> > +   dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX);
> > +   else
> > +   dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
> > +
> > +   /* Reconfigure the DSP3 mux if required. */
> > +   dispctrl = HVS_READ(SCALER_DISPCTRL);
> > +   if ((dispctrl & SCALER_DISPCTRL_DSP3_MUX_MASK) != dsp3_mux) {
> > +   dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK;
> > +   HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux);
> > +   }  
> 
> This is fine, but you could also skip the matching mux check here -- the
> read is the expensive part.
> 
> > +   }
> > +
> > +   if (!vc4_state->feed_txp)
> > +   vc4_crtc_config_pv(crtc);
> >  
> > HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
> >   SCALER_DISPBKGND_AUTOHS |
> > @@ -499,6 +539,13 @@ static void vc4_crtc_atomic_disable(struct drm_crtc 
> > *crtc,
> > }
> >  }
> >  
> > +void vc4_crtc_txp_armed(struct drm_crtc_state *state)
> > +{
> > +   struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
> > +
> > +   vc4_state->txp_armed = true;
> > +}
> > +
> >  static void vc4_crtc_update_dlist(struct drm_crtc *crtc)
> >  {
> > struct drm_device *dev = crtc->dev;
> > @@ -514,8 +561,11 @@ static void vc4_crtc_update_dlist(struct drm_crtc 
> > *crtc)
> > WARN_ON(drm_crtc_vblank_get(crtc) != 0);
> >  
> > spin_lock_irqsave(>event_lock, flags);
> > -   vc4_crtc->event = crtc->state->event;
> > -   crtc->state->event = NULL;
> > +
> > +   if (!vc4_state->feed_txp || vc4_state->txp_armed) {
> > +   vc4_crtc->event = crtc->state->event;
> > +   crtc->state->event = NULL;
> > +   }
> >  
> > HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
> >   vc4_state->mm.start);
> > @@ -533,8 +583,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc 
> > *crtc,
> > struct drm_device *dev = crtc->dev;
> > struct vc4_dev *vc4 = to_vc4_dev(dev);
> > struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> > -   struct drm_crtc_state *state = crtc->state;
> > -   struct drm_display_mode *mode = >adjusted_mode;
> > +   struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
> > +   struct drm_display_mode *mode = >state->adjusted_mode;
> >  
> > require_hvs_enabled(dev);
> >  
> > @@ -546,15 +596,21 @@ static void vc4_crtc_atomic_enable(struct drm_crtc 
> > *crtc,
> >  
> > /* Turn on the scaler, which will wait for vstart to start
> >  * composit

Re: [PATCH v2 0/8] drm/vc4: Add support for the transposer IP

2018-07-02 Thread Boris Brezillon
On Fri, 29 Jun 2018 12:40:45 +0100
Liviu Dudau  wrote:

> On Fri, Jun 29, 2018 at 01:17:22PM +0200, Boris Brezillon wrote:
> > Hello,
> > 
> > This is the second version of this series adding writeback support
> > to the VC4 display engine.
> > 
> > This version is based on drm-misc-next and include a bunch of
> > modifications to core that I had to add to make it work on VC4.
> > 
> > Feel free to comment on those modifications.
> > 
> > On the driver side, no much has changed except I modified a bit
> > the implementation to adjust the latest revision of the writeback
> > interface.  
> 
> This is a duplicate of the cover letter.

Yep, I forgot to clean the directory I used to generate my patches :-/

> 
> I've reviewed / checked patches 1-5 and 8, so you can add my Reviewed-by
> tag from me if you want.

Thanks for your review.

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


Re: [PATCH v2 2/8] drm/connector: Pass a drm_connector_state to ->atomic_commit()

2018-07-02 Thread Boris Brezillon
On Mon, 2 Jul 2018 12:14:20 +0100
Liviu Dudau  wrote:

> On Mon, Jul 02, 2018 at 11:49:11AM +0200, Boris Brezillon wrote:
> > On Mon, 2 Jul 2018 09:51:46 +0200
> > Daniel Vetter  wrote:
> >   
> > > On Fri, Jun 29, 2018 at 12:37:10PM +0100, Liviu Dudau wrote:  
> > > > On Fri, Jun 29, 2018 at 01:17:15PM +0200, Boris Brezillon wrote:
> > > > > Other atomic hooks are passed state objects, let's change this one to
> > > > > be consistent.
> > > > > 
> > > > > Signed-off-by: Boris Brezillon 
> > > > > ---
> > > > >  drivers/gpu/drm/drm_atomic_helper.c  | 2 +-
> > > > >  include/drm/drm_modeset_helper_vtables.h | 4 +++-
> > > > >  2 files changed, 4 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > > > > b/drivers/gpu/drm/drm_atomic_helper.c
> > > > > index 17baf5057132..69063bcf2334 100644
> > > > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > > > @@ -1187,7 +1187,7 @@ static void 
> > > > > drm_atomic_helper_commit_writebacks(struct drm_device *dev,
> > > > >  
> > > > >   if (new_conn_state->writeback_job && 
> > > > > new_conn_state->writeback_job->fb) {
> > > > >   WARN_ON(connector->connector_type != 
> > > > > DRM_MODE_CONNECTOR_WRITEBACK);
> > > > > - funcs->atomic_commit(connector, 
> > > > > new_conn_state->writeback_job);
> > > > > + funcs->atomic_commit(connector, 
> > > > > new_conn_state);
> > > > 
> > > > Forgot to add: I think it is worth adding a check here that the hook has
> > > > been implemented by the driver, AFAIK it is not a mandatory hook, even
> > > > for writeback enabled drivers.
> > 
> > I'm just curious, from where do you queue the writeback job if you don't
> > have a connector->atomic_commit() hook implemented? AFAICT, the
> > encoder->enable() method is only called when the encoder is being
> > enabled, and not every time you update the FB_ID prop of the writeback
> > connector. Am I missing something?  
> 
> In malidp_drv.c:malidp_atomic_commit_tail() we call
> malidp_mw_atomic_commit() after drm_atomic_helper_commit_planes(drm,
> state, DRM_PLANE_COMMIT_ACTIVE_ONLY).
> 
> malidp_mw_atomic_commit() then checks the writeback job and if it has an
> fb associated with it then it calls drm_writeback_queue_job() before
> enabling the memwrite hardware bits.

Okay. That's a good reason to make it optional.

Thanks,

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


Re: [PATCH v2 5/8] drm/atomic: Call drm_atomic_helper_fake_vblank() from the generic commit_tail() helpers

2018-07-02 Thread Boris Brezillon
On Mon, 2 Jul 2018 09:54:32 +0200
Daniel Vetter  wrote:

> On Fri, Jun 29, 2018 at 01:17:18PM +0200, Boris Brezillon wrote:
> > Now that we have a way to fake VBLANK events when requested by the CRTC
> > hook it up to the generic commit_tail() helpers.
> > 
> > Signed-off-by: Boris Brezillon   
> 
> I really don't like this. We've had epic amounts of bugs with atomic
> drivers failing to send out vblank events when they should, and I added a
> bunch of debug checks to make sure that doesn't happen anymore.
> 
> Now there's no way anymore for drivers to spot this until they have
> misrenderings on wayland and no idea why. Imo this should only be used by
> specific drivers, with a comment why exactly they need it.

Hm, that's not entirely true. Drivers have to explicitly set
->no_vblank to true for drm_atomic_helper_fake_vblank() to actually do
something, and I seriously hope drivers won't set that field randomly.
So, on all existing drivers but VC4 after the TXP patch, the behavior
will be unchanged, and the core will spot misbehaving drivers just like
before.

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index ca586993c2a2..1a088462bc42 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -1448,6 +1448,8 @@ void drm_atomic_helper_commit_tail(struct 
> > drm_atomic_state *old_state)
> >  
> > drm_atomic_helper_commit_modeset_enables(dev, old_state);
> >  
> > +   drm_atomic_helper_fake_vblank(old_state);
> > +
> > drm_atomic_helper_commit_hw_done(old_state);
> >  
> > drm_atomic_helper_wait_for_vblanks(dev, old_state);
> > @@ -1477,6 +1479,8 @@ void drm_atomic_helper_commit_tail_rpm(struct 
> > drm_atomic_state *old_state)
> > drm_atomic_helper_commit_planes(dev, old_state,
> > DRM_PLANE_COMMIT_ACTIVE_ONLY);
> >  
> > +   drm_atomic_helper_fake_vblank(old_state);
> > +
> > drm_atomic_helper_commit_hw_done(old_state);
> >  
> > drm_atomic_helper_wait_for_vblanks(dev, old_state);
> > -- 
> > 2.14.1
> >   
> 

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


Re: [PATCH v2 5/8] drm/atomic: Call drm_atomic_helper_fake_vblank() from the generic commit_tail() helpers

2018-07-02 Thread Boris Brezillon
On Mon, 2 Jul 2018 09:57:30 +0200
Daniel Vetter  wrote:

> On Mon, Jul 02, 2018 at 09:54:32AM +0200, Daniel Vetter wrote:
> > On Fri, Jun 29, 2018 at 01:17:18PM +0200, Boris Brezillon wrote:  
> > > Now that we have a way to fake VBLANK events when requested by the CRTC
> > > hook it up to the generic commit_tail() helpers.
> > > 
> > > Signed-off-by: Boris Brezillon   
> > 
> > I really don't like this. We've had epic amounts of bugs with atomic
> > drivers failing to send out vblank events when they should, and I added a
> > bunch of debug checks to make sure that doesn't happen anymore.
> > 
> > Now there's no way anymore for drivers to spot this until they have
> > misrenderings on wayland and no idea why. Imo this should only be used by
> > specific drivers, with a comment why exactly they need it.  
> 
> Meh I retract, you have the special no_vblank state flag to control this.
> Looks all good to me.

Hehe, just replied to your other email :-).

> 
> Reviewed-by: Daniel Vetter 
> 
> > -Daniel
> >   
> > > ---
> > >  drivers/gpu/drm/drm_atomic_helper.c | 4 
> > >  1 file changed, 4 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > > b/drivers/gpu/drm/drm_atomic_helper.c
> > > index ca586993c2a2..1a088462bc42 100644
> > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > @@ -1448,6 +1448,8 @@ void drm_atomic_helper_commit_tail(struct 
> > > drm_atomic_state *old_state)
> > >  
> > >   drm_atomic_helper_commit_modeset_enables(dev, old_state);
> > >  
> > > + drm_atomic_helper_fake_vblank(old_state);
> > > +
> > >   drm_atomic_helper_commit_hw_done(old_state);
> > >  
> > >   drm_atomic_helper_wait_for_vblanks(dev, old_state);
> > > @@ -1477,6 +1479,8 @@ void drm_atomic_helper_commit_tail_rpm(struct 
> > > drm_atomic_state *old_state)
> > >   drm_atomic_helper_commit_planes(dev, old_state,
> > >   DRM_PLANE_COMMIT_ACTIVE_ONLY);
> > >  
> > > + drm_atomic_helper_fake_vblank(old_state);
> > > +
> > >   drm_atomic_helper_commit_hw_done(old_state);
> > >  
> > >   drm_atomic_helper_wait_for_vblanks(dev, old_state);
> > > -- 
> > > 2.14.1
> > >   
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch  
> 

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


Re: [PATCH v2 4/8] drm/crtc: Add a generic infrastructure to fake VBLANK events

2018-07-02 Thread Boris Brezillon
On Mon, 2 Jul 2018 10:02:52 +0200
Daniel Vetter  wrote:

> On Fri, Jun 29, 2018 at 01:17:17PM +0200, Boris Brezillon wrote:
> > In some cases CRTCs are active but are not able to generating events, at
> > least not at every frame at it's expected to.
> > This is typically the case when the CRTC is feeding a writeback connector
> > that has no job queued. In this situation the CRTC is usually stopped
> > until a new job is queued, and this can lead to timeouts when part of
> > the pipeline is updated but no new jobs are queued to the active
> > writeback connector.
> > 
> > In order to solve that, we add a ->no_vblank flag to drm_crtc_state
> > and ask the CRTC drivers to set it to true when they know they're not
> > able to generate VBLANK events. The core drm_atomic_helper_fake_vblank()
> > helper can then be used to fake VBLANKs at commit time.
> > 
> > Signed-off-by: Boris Brezillon 
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c | 40 
> > +
> >  include/drm/drm_atomic_helper.h |  1 +
> >  include/drm/drm_crtc.h  | 15 ++
> >  3 files changed, 56 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 69063bcf2334..ca586993c2a2 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -2051,6 +2051,46 @@ void drm_atomic_helper_wait_for_dependencies(struct 
> > drm_atomic_state *old_state)
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
> >  
> > +/**
> > + * drm_atomic_helper_fake_vblank - fake VBLANK events if needed
> > + * @old_state: atomic state object with old state structures
> > + *
> > + * This function walks all CRTCs and fake VBLANK events on those with
> > + * _crtc_state.no_vblank set to true and _crtc_state.event != NULL.
> > + * The primary use of this function is writeback connectors working in 
> > oneshot
> > + * mode and faking VBLANK events. In this case they only fake the VBLANK 
> > event
> > + * when a job is queued, and any change to the pipeline that does not 
> > touch the
> > + * connector is leading to timeouts when calling
> > + * drm_atomic_helper_wait_for_vblanks() or
> > + * drm_atomic_helper_wait_for_flip_done().
> > + *
> > + * This is part of the atomic helper support for nonblocking commits, see
> > + * drm_atomic_helper_setup_commit() for an overview.
> > + */
> > +void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)
> > +{
> > +   struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> > +   struct drm_crtc *crtc;
> > +   int i;
> > +
> > +   for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state,
> > + new_crtc_state, i) {
> > +   unsigned long flags;
> > +
> > +   if (!new_crtc_state->no_vblank && !old_crtc_state->no_vblank)  
> 
> Uh, this essentially makes it impossible to reset no_vblank.

I don't want ->no_vblank to be reset by the core. It's up to the CRTC
driver to clear/set it when something changes in the pipeline.

> For control
> flow state bits we only check the new state for it (see e.g. the various
> *_changed or plane_bits or whatever).

I tried with !new_crtc_state->no_vblank only, but then it does not
handle the case where the CRTC and connector are being disabled, and I
end up with a timeout.

> 
> > +   continue;
> > +
> > +   spin_lock_irqsave(_state->dev->event_lock, flags);
> > +   if (new_crtc_state->event) {
> > +   drm_crtc_send_vblank_event(crtc,
> > +  new_crtc_state->event);
> > +   new_crtc_state->event = NULL;
> > +   }
> > +   spin_unlock_irqrestore(_state->dev->event_lock, flags);
> > +   }
> > +}
> > +EXPORT_SYMBOL(drm_atomic_helper_fake_vblank);
> > +
> >  /**
> >   * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit
> >   * @old_state: atomic state object with old state structures
> > diff --git a/include/drm/drm_atomic_helper.h 
> > b/include/drm/drm_atomic_helper.h
> > index 26aaba58d6ce..99e2a5297c69 100644
> > --- a/include/drm/drm_atomic_helper.h
> > +++ b/include/drm/drm_atomic_helper.h
> > @@ -100,6 +100,7 @@ int __must_check drm_atomic_helper_swap_state(struct 
> > drm_atomic_state *state,
> >  int drm_atomic_helper_setup_commit(struct

Re: [PATCH v2 4/8] drm/crtc: Add a generic infrastructure to fake VBLANK events

2018-07-02 Thread Boris Brezillon
On Mon, 2 Jul 2018 10:40:54 +0200
Daniel Vetter  wrote:

> > >   
> > > > + * Note that, even when no_blank is set to true, the CRTC driver 
> > > > can still
> > > > + * steal the _crtc_state.event object and send the event on 
> > > > its own.
> > > > + * That's usually what happens when a job is queued to the 
> > > > writeback
> > > > + * connector.
> > > 
> > > The last sentence is confusing imo. Just drop it?  
> > 
> > Yes, I know, but it's also important to state that the ->no_blank +
> > event == NULL is a valid combination, and just means that the driver
> > decided to generate the event (that happens when a new WB job is
> > queued).  
> 
> Then make it more explicit, as-is I had no idea what you meant exactly.
> What about

Your suggestion is missing :P.

> >   
> > > 
> > > Please use the inline comment style for struct members, and then also
> > > polish the formatting a bit (e.g. paragraph breaks, which are only
> > > possible with the inline style).  
> > 
> > I considered that, but the other fields were already documented in the
> > single block above the struct, so I thought keeping things consistent
> > was better. Should I just add this field doc inline and keep the other
> > ones where they are, or should I add a patch moving all docs inline?  
> 
> There's _lots_ of inline comments already, and all new ones should be
> inline. The only reason I haven't done the conversion to all of them is
> that it would be a nice opportunity to update/clean up the comments
> (often there's a lot more to say than what's captured in the single line),
> which is why it didn't happen yet. Just moving the comments without
> updating them seems less useful imo.
> 
> I'd just do the inline comment for this, that's what everyone else is
> doing too.

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


Re: [PATCH v2 4/8] drm/crtc: Add a generic infrastructure to fake VBLANK events

2018-07-02 Thread Boris Brezillon
On Mon, 2 Jul 2018 10:37:22 +0200
Daniel Vetter  wrote:

> On Mon, Jul 02, 2018 at 10:14:51AM +0200, Boris Brezillon wrote:
> > On Mon, 2 Jul 2018 10:02:52 +0200
> > Daniel Vetter  wrote:
> >   
> > > On Fri, Jun 29, 2018 at 01:17:17PM +0200, Boris Brezillon wrote:  
> > > > In some cases CRTCs are active but are not able to generating events, at
> > > > least not at every frame at it's expected to.
> > > > This is typically the case when the CRTC is feeding a writeback 
> > > > connector
> > > > that has no job queued. In this situation the CRTC is usually stopped
> > > > until a new job is queued, and this can lead to timeouts when part of
> > > > the pipeline is updated but no new jobs are queued to the active
> > > > writeback connector.
> > > > 
> > > > In order to solve that, we add a ->no_vblank flag to drm_crtc_state
> > > > and ask the CRTC drivers to set it to true when they know they're not
> > > > able to generate VBLANK events. The core drm_atomic_helper_fake_vblank()
> > > > helper can then be used to fake VBLANKs at commit time.
> > > > 
> > > > Signed-off-by: Boris Brezillon 
> > > > ---
> > > >  drivers/gpu/drm/drm_atomic_helper.c | 40 
> > > > +
> > > >  include/drm/drm_atomic_helper.h |  1 +
> > > >  include/drm/drm_crtc.h  | 15 ++
> > > >  3 files changed, 56 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > > > b/drivers/gpu/drm/drm_atomic_helper.c
> > > > index 69063bcf2334..ca586993c2a2 100644
> > > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > > @@ -2051,6 +2051,46 @@ void 
> > > > drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state 
> > > > *old_state)
> > > >  }
> > > >  EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
> > > >  
> > > > +/**
> > > > + * drm_atomic_helper_fake_vblank - fake VBLANK events if needed
> > > > + * @old_state: atomic state object with old state structures
> > > > + *
> > > > + * This function walks all CRTCs and fake VBLANK events on those with
> > > > + * _crtc_state.no_vblank set to true and _crtc_state.event != 
> > > > NULL.
> > > > + * The primary use of this function is writeback connectors working in 
> > > > oneshot
> > > > + * mode and faking VBLANK events. In this case they only fake the 
> > > > VBLANK event
> > > > + * when a job is queued, and any change to the pipeline that does not 
> > > > touch the
> > > > + * connector is leading to timeouts when calling
> > > > + * drm_atomic_helper_wait_for_vblanks() or
> > > > + * drm_atomic_helper_wait_for_flip_done().
> > > > + *
> > > > + * This is part of the atomic helper support for nonblocking commits, 
> > > > see
> > > > + * drm_atomic_helper_setup_commit() for an overview.
> > > > + */
> > > > +void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)
> > > > +{
> > > > +   struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> > > > +   struct drm_crtc *crtc;
> > > > +   int i;
> > > > +
> > > > +   for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state,
> > > > + new_crtc_state, i) {
> > > > +   unsigned long flags;
> > > > +
> > > > +   if (!new_crtc_state->no_vblank && 
> > > > !old_crtc_state->no_vblank)    
> > > 
> > > Uh, this essentially makes it impossible to reset no_vblank.  
> > 
> > I don't want ->no_vblank to be reset by the core. It's up to the CRTC
> > driver to clear/set it when something changes in the pipeline.
> >   
> > > For control
> > > flow state bits we only check the new state for it (see e.g. the various
> > > *_changed or plane_bits or whatever).  
> > 
> > I tried with !new_crtc_state->no_vblank only, but then it does not
> > handle the case where the CRTC and connector are being disabled, and I
> > end up with a timeout.  
> 
> Why that? You should have a new_crtc_state even when you disable the crtc,
> and you can set the ->no_vblank on that one too.

Hm, right. I'll have to check why I didn't have ->no_blank set to true
when I disable the CRTC. Probably a problem in vc4_crtc.c.


-- 
Boris Brezillon, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 2/8] drm/connector: Pass a drm_connector_state to ->atomic_commit()

2018-07-02 Thread Boris Brezillon
On Mon, 2 Jul 2018 09:51:46 +0200
Daniel Vetter  wrote:

> On Fri, Jun 29, 2018 at 12:37:10PM +0100, Liviu Dudau wrote:
> > On Fri, Jun 29, 2018 at 01:17:15PM +0200, Boris Brezillon wrote:  
> > > Other atomic hooks are passed state objects, let's change this one to
> > > be consistent.
> > > 
> > > Signed-off-by: Boris Brezillon 
> > > ---
> > >  drivers/gpu/drm/drm_atomic_helper.c  | 2 +-
> > >  include/drm/drm_modeset_helper_vtables.h | 4 +++-
> > >  2 files changed, 4 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > > b/drivers/gpu/drm/drm_atomic_helper.c
> > > index 17baf5057132..69063bcf2334 100644
> > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > @@ -1187,7 +1187,7 @@ static void 
> > > drm_atomic_helper_commit_writebacks(struct drm_device *dev,
> > >  
> > >   if (new_conn_state->writeback_job && 
> > > new_conn_state->writeback_job->fb) {
> > >   WARN_ON(connector->connector_type != 
> > > DRM_MODE_CONNECTOR_WRITEBACK);
> > > - funcs->atomic_commit(connector, 
> > > new_conn_state->writeback_job);
> > > + funcs->atomic_commit(connector, new_conn_state);  
> > 
> > Forgot to add: I think it is worth adding a check here that the hook has
> > been implemented by the driver, AFAIK it is not a mandatory hook, even
> > for writeback enabled drivers.  

I'm just curious, from where do you queue the writeback job if you don't
have a connector->atomic_commit() hook implemented? AFAICT, the
encoder->enable() method is only called when the encoder is being
enabled, and not every time you update the FB_ID prop of the writeback
connector. Am I missing something?

> 
> Either way this should be documented in the hook (atm it says nothing
> about whether it's mandatory/optional and for whom).

I'm fine making this hook optional. I'll update the code and the doc in
a separate commit.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 8/9] drm/vc4: Add support for the transposer block

2018-07-02 Thread Boris Brezillon
From: Boris Brezillon 

The transposer block is providing support for mem-to-mem composition,
which is exposed as a drm_writeback connector in DRM.

Add a driver to support this feature.

Signed-off-by: Boris Brezillon 
---
Changes in v3:
- Add Eric's R-b
- Fix the code updating ->no_blank so that it does not reset it to
  false when the CRTC is being disabled
- Use a table of txp formats instead of having a big switch-case block
- Fix typos in some comments
- Unconditionally update the DSP3 mux val
- Make sure we don't hang the system when TXP_BUSY is not cleared

Changes in v2:
- Rebased on top of drm-misc-next
---
 .../devicetree/bindings/display/brcm,bcm-vc4.txt   |   6 +
 drivers/gpu/drm/vc4/Makefile   |   1 +
 drivers/gpu/drm/vc4/vc4_crtc.c | 138 --
 drivers/gpu/drm/vc4/vc4_debugfs.c  |   1 +
 drivers/gpu/drm/vc4/vc4_drv.c  |   1 +
 drivers/gpu/drm/vc4/vc4_drv.h  |   7 +
 drivers/gpu/drm/vc4/vc4_txp.c  | 477 +
 7 files changed, 607 insertions(+), 24 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_txp.c

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt 
b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
index 284e2b14cfbe..26649b4c4dd8 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
+++ b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
@@ -74,6 +74,12 @@ Required properties for DSI:
The 3 clocks output from the DSI analog PHY: dsi[01]_byte,
dsi[01]_ddr2, and dsi[01]_ddr
 
+Required properties for the TXP (writeback) block:
+- compatible:  Should be "brcm,bcm2835-txp"
+- reg: Physical base address and length of the TXP block's registers
+- interrupts:  The interrupt number
+ See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+
 [1] Documentation/devicetree/bindings/media/video-interfaces.txt
 
 Example:
diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index 4a3a868235f8..b303703bc7f3 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -19,6 +19,7 @@ vc4-y := \
vc4_plane.o \
vc4_render_cl.o \
vc4_trace_points.o \
+   vc4_txp.o \
vc4_v3d.o \
vc4_validate.o \
vc4_validate_shaders.o
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index dcadf793ee80..96911a869cca 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -46,6 +46,8 @@ struct vc4_crtc_state {
struct drm_crtc_state base;
/* Dlist area for this CRTC configuration. */
struct drm_mm_node mm;
+   bool feed_txp;
+   bool txp_armed;
 };
 
 static inline struct vc4_crtc_state *
@@ -324,10 +326,8 @@ static struct drm_encoder *vc4_get_crtc_encoder(struct 
drm_crtc *crtc)
return NULL;
 }
 
-static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+static void vc4_crtc_config_pv(struct drm_crtc *crtc)
 {
-   struct drm_device *dev = crtc->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
@@ -338,12 +338,6 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
   vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
-   bool debug_dump_regs = false;
-
-   if (debug_dump_regs) {
-   DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
-   vc4_crtc_dump_regs(vc4_crtc);
-   }
 
/* Reset the PV fifo. */
CRTC_WRITE(PV_CONTROL, 0);
@@ -419,6 +413,49 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 PV_CONTROL_CLK_SELECT) |
   PV_CONTROL_FIFO_CLR |
   PV_CONTROL_EN);
+}
+
+static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+   struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+   struct drm_display_mode *mode = >state->adjusted_mode;
+   bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
+   bool debug_dump_regs = false;
+
+   if (debug_dump_regs) {
+   DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
+   vc4_crtc_dump_regs(vc4_crtc);
+   }
+
+   if (vc4_crtc->channel == 2) {
+   u32 dispctrl;
+   u32 dsp3_mux;
+
+   /*
+* SCALER_DISPCTRL_DSP3 =

[PATCH v3 7/9] drm/vc4: Call drm_atomic_helper_fake_vblank() in the commit path

2018-07-02 Thread Boris Brezillon
Mimic what is done in drm_atomic_commit_tail() and call
drm_atomic_helper_fake_vblank() so that VBLANK events are faked
when the drm_crtc_state.no_vblank is true. Will be needed when we'll
add support for the transposer block.

Signed-off-by: Boris Brezillon 
Reviewed-by: Eric Anholt 
---
Changes in v3:
- Add Eric's R-b

Changes in v2:
- New patch
---
 drivers/gpu/drm/vc4/vc4_kms.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 91239b0a4fa0..ca5aa7fba769 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -153,6 +153,8 @@ vc4_atomic_complete_commit(struct drm_atomic_state *state)
 
drm_atomic_helper_commit_modeset_enables(dev, state);
 
+   drm_atomic_helper_fake_vblank(state);
+
drm_atomic_helper_commit_hw_done(state);
 
drm_atomic_helper_wait_for_flip_done(dev, state);
-- 
2.14.1

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


[PATCH v3 5/9] drm/crtc: Add a generic infrastructure to fake VBLANK events

2018-07-02 Thread Boris Brezillon
In some cases CRTCs are active but are not able to generating events, at
least not at every frame at it's expected to.
This is typically the case when the CRTC is feeding a writeback connector
that has no job queued. In this situation the CRTC is usually stopped
until a new job is queued, and this can lead to timeouts when part of
the pipeline is updated but no new jobs are queued to the active
writeback connector.

In order to solve that, we add a ->no_vblank flag to drm_crtc_state
and ask the CRTC drivers to set it to true when they know they're not
able to generate VBLANK events. The core drm_atomic_helper_fake_vblank()
helper can then be used to fake VBLANKs at commit time.

Signed-off-by: Boris Brezillon 
Reviewed-by: Liviu Dudau 
Reviewed-by: Daniel Vetter 
---
Changes in v3:
- Use inline doc for @no_vblank
- Fix drm_atomic_helper_fake_vblank() to only check
  new_crtc_state->no_vblank
- Add R-b tags

Changes in v2:
- New patch
---
 drivers/gpu/drm/drm_atomic_helper.c | 39 +
 include/drm/drm_atomic_helper.h |  1 +
 include/drm/drm_crtc.h  | 23 ++
 3 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index ea19fcc252dc..fc5a4ad1e3b3 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2053,6 +2053,45 @@ void drm_atomic_helper_wait_for_dependencies(struct 
drm_atomic_state *old_state)
 }
 EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
 
+/**
+ * drm_atomic_helper_fake_vblank - fake VBLANK events if needed
+ * @old_state: atomic state object with old state structures
+ *
+ * This function walks all CRTCs and fake VBLANK events on those with
+ * _crtc_state.no_vblank set to true and _crtc_state.event != NULL.
+ * The primary use of this function is writeback connectors working in oneshot
+ * mode and faking VBLANK events. In this case they only fake the VBLANK event
+ * when a job is queued, and any change to the pipeline that does not touch the
+ * connector is leading to timeouts when calling
+ * drm_atomic_helper_wait_for_vblanks() or
+ * drm_atomic_helper_wait_for_flip_done().
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
+ */
+void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)
+{
+   struct drm_crtc_state *new_crtc_state;
+   struct drm_crtc *crtc;
+   int i;
+
+   for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+   unsigned long flags;
+
+   if (!new_crtc_state->no_vblank)
+   continue;
+
+   spin_lock_irqsave(_state->dev->event_lock, flags);
+   if (new_crtc_state->event) {
+   drm_crtc_send_vblank_event(crtc,
+  new_crtc_state->event);
+   new_crtc_state->event = NULL;
+   }
+   spin_unlock_irqrestore(_state->dev->event_lock, flags);
+   }
+}
+EXPORT_SYMBOL(drm_atomic_helper_fake_vblank);
+
 /**
  * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit
  * @old_state: atomic state object with old state structures
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 26aaba58d6ce..99e2a5297c69 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -100,6 +100,7 @@ int __must_check drm_atomic_helper_swap_state(struct 
drm_atomic_state *state,
 int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
   bool nonblock);
 void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
+void drm_atomic_helper_fake_vblank(struct drm_atomic_state *state);
 void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
 void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 23eddbccab10..17f4f93340b8 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -119,6 +119,29 @@ struct drm_crtc_state {
bool zpos_changed : 1;
bool color_mgmt_changed : 1;
 
+   /**
+* @no_vblank:
+*
+* Reflects the ability of a CRTC to send VBLANK events. This state
+* usually depends on the pipeline configuration, and the main usuage
+* is CRTCs feeding a writeback connector operating in oneshot mode.
+* In this case the VBLANK event is only generated when a job is queued
+* to the writeback connector, and we want the core to fake VBLANK
+* events when this part of the pipeline hasn't changed but others had
+* or when the CRTC and connectors are being disabled.
+*
+* __drm_atomic_helper_crtc_duplicate_state() will not reset the value
+* fr

[PATCH v3 4/9] drm/vc4: Use wait_for_flip_done() instead of wait_for_vblanks()

2018-07-02 Thread Boris Brezillon
drm_atomic_helper_wait_for_vblanks() assumes the CRTC will continuously
generate VBLANK events and the vblank counter will keep increasing.
While this work for a regular pipeline, it doesn't when you have the
CRTC is feeding the transposer block, because this block works in
oneshot mode, and, by the time we reach
drm_atomic_helper_wait_for_vblanks() the only VBLANK event might have
already been sent and the VBLANK counter will stay unchanged, thus
triggering a timeout.

Luckily, we can replace the drm_atomic_helper_wait_for_vblanks() call
by drm_atomic_helper_wait_for_flip_done() because the only thing we
want to check when calling drm_atomic_helper_wait_for_vblanks() from
vc4_atomic_complete_commit() is that new FBs are in use and the old
ones can be safely released.

Signed-off-by: Boris Brezillon 
Reviewed-by: Liviu Dudau 
Reviewed-by: Eric Anholt 
---
Changes in v3:
- Add Eric's and Liviu's R-b

Changes in v2:
- None
---
 drivers/gpu/drm/vc4/vc4_kms.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 8a411e5f8776..91239b0a4fa0 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -153,18 +153,9 @@ vc4_atomic_complete_commit(struct drm_atomic_state *state)
 
drm_atomic_helper_commit_modeset_enables(dev, state);
 
-   /* Make sure that drm_atomic_helper_wait_for_vblanks()
-* actually waits for vblank.  If we're doing a full atomic
-* modeset (as opposed to a vc4_update_plane() short circuit),
-* then we need to wait for scanout to be done with our
-* display lists before we free it and potentially reallocate
-* and overwrite the dlist memory with a new modeset.
-*/
-   state->legacy_cursor_update = false;
-
drm_atomic_helper_commit_hw_done(state);
 
-   drm_atomic_helper_wait_for_vblanks(dev, state);
+   drm_atomic_helper_wait_for_flip_done(dev, state);
 
drm_atomic_helper_cleanup_planes(dev, state);
 
-- 
2.14.1

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


[PATCH v3 9/9] ARM: dts: bcm283x: Add Transposer block

2018-07-02 Thread Boris Brezillon
From: Boris Brezillon 

The transposer block is allowing one to write the result of the VC4
composition back to memory instead of displaying it on a screen.

Signed-off-by: Boris Brezillon 
Reviewed-by: Liviu Dudau 
Reviewed-by: Eric Anholt 
---
Changes in v3:
- Add R-b tags

Changes in v2:
- None
---
 arch/arm/boot/dts/bcm283x.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index ac00e730f898..740870898b1e 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -66,6 +66,12 @@
clock-frequency = <100>;
};
 
+   txp@7e004000 {
+   compatible = "brcm,bcm2835-txp";
+   reg = <0x7e004000 0x20>;
+   interrupts = <1 11>;
+   };
+
dma: dma@7e007000 {
compatible = "brcm,bcm2835-dma";
reg = <0x7e007000 0xf00>;
-- 
2.14.1

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


<    3   4   5   6   7   8   9   10   11   12   >