Re: [PATCH v2 14/15] ARM: dts: bcm2711: Add the BSC interrupt controller

2021-02-10 Thread Dave Stevenson
Hi Marc.

On Wed, 10 Feb 2021 at 15:30, Marc Zyngier  wrote:
>
> Hi Maxime,
>
> On 2021-02-10 14:40, Maxime Ripard wrote:
> > Hi Dave,
> >
> > On Tue, Feb 09, 2021 at 09:49:05AM +, Dave Stevenson wrote:
> >> On Mon, 11 Jan 2021 at 14:23, Maxime Ripard  wrote:
> >> >
> >> > The BSC controllers used for the HDMI DDC have an interrupt controller
> >> > shared between both instances. Let's add it to avoid polling.
> >>
> >> This seems to have unintended side effects.
> >> GIC interrupt 117 is shared between the standard I2C controllers
> >> (i2c-bcm2835) and the l2-intc block handling the HDMI I2C interrupts.
> >>
> >> Whilst i2c-bcm2835 requests the interrupt with IRQF_SHARED, that
> >> doesn't appear to be an option for l2-intc registering as an interrupt
> >> controller. i2c-bcm2835 therefore loses out and fails to register for
> >> the interrupt.
> >>
> >> Is there an equivalent flag that an interrupt controller can add to
> >> say that the parent interrupt is shared? Is that even supported?
> >
> > Indeed, it looks like setting an equivalent to IRQF_SHARED would be the
> > solution, but I couldn't find anything that would allow us to in the
> > irqchip code.
> >
> > Marc, Thomas, is it something that is allowed?
>
> No, not really. That's because the chained handler is actually an
> interrupt flow, and not a normal handler. IRQF_SHARED acts at the wrong
> level for that.
>
> I can see two possibilities:
>
> - the l2-intc gets turned into a normal handler, and does the demux
>from there. Horrible stuff.
>
> - the i2c controller gets parented to the l2c-int as a fake interrupt,
>and gets called from there. Horrible stuff.
>
> Pick your poison... :-/

Thanks for the info.

Option 3 - remove l2-intc and drop back to polling the i2c-brcmstb
blocks (which the driver supports anyway).
HDMI I2C generally isn't heavily used once displays are connected, so
I'd be OK with that.

(We can keep the l2-intc that handles CEC and HPD as that is on a
unique GIC interrupt).

  Dave


Re: [PATCH v2 14/15] ARM: dts: bcm2711: Add the BSC interrupt controller

2021-02-09 Thread Dave Stevenson
Hi Maxime

On Mon, 11 Jan 2021 at 14:23, Maxime Ripard  wrote:
>
> The BSC controllers used for the HDMI DDC have an interrupt controller
> shared between both instances. Let's add it to avoid polling.

This seems to have unintended side effects.
GIC interrupt 117 is shared between the standard I2C controllers
(i2c-bcm2835) and the l2-intc block handling the HDMI I2C interrupts.

Whilst i2c-bcm2835 requests the interrupt with IRQF_SHARED, that
doesn't appear to be an option for l2-intc registering as an interrupt
controller. i2c-bcm2835 therefore loses out and fails to register for
the interrupt.

Is there an equivalent flag that an interrupt controller can add to
say that the parent interrupt is shared? Is that even supported?

Thanks
  Dave

> Reviewed-by: Florian Fainelli 
> Signed-off-by: Maxime Ripard 
> ---
>  arch/arm/boot/dts/bcm2711.dtsi | 12 
>  1 file changed, 12 insertions(+)
>
> diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
> index 4847dd305317..8bb46ae76a92 100644
> --- a/arch/arm/boot/dts/bcm2711.dtsi
> +++ b/arch/arm/boot/dts/bcm2711.dtsi
> @@ -308,6 +308,14 @@ dvp: clock@7ef0 {
> #reset-cells = <1>;
> };
>
> +   bsc_intr: interrupt-controller@7ef00040 {
> +   compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
> +   reg = <0x7ef00040 0x30>;
> +   interrupts = ;
> +   interrupt-controller;
> +   #interrupt-cells = <1>;
> +   };
> +
> hdmi0: hdmi@7ef00700 {
> compatible = "brcm,bcm2711-hdmi0";
> reg = <0x7ef00700 0x300>,
> @@ -341,6 +349,8 @@ ddc0: i2c@7ef04500 {
> reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>;
> reg-names = "bsc", "auto-i2c";
> clock-frequency = <97500>;
> +   interrupt-parent = <_intr>;
> +   interrupts = <0>;
> status = "disabled";
> };
>
> @@ -377,6 +387,8 @@ ddc1: i2c@7ef09500 {
> reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>;
> reg-names = "bsc", "auto-i2c";
> clock-frequency = <97500>;
> +   interrupt-parent = <_intr>;
> +   interrupts = <1>;
> status = "disabled";
> };
> };
> --
> 2.29.2
>


Re: [PATCH] media: i2c: imx219: Implement V4L2_CID_LINK_FREQ control

2021-01-27 Thread Dave Stevenson
Hi Andrey

On Tue, 26 Jan 2021 at 15:55, Andrey Konovalov
 wrote:
>
> Hi Dave,
>
> On 26.01.2021 16:01, Dave Stevenson wrote:
> > Hi Andrey
> >
> > On Tue, 26 Jan 2021 at 07:50, Andrey Konovalov
> >  wrote:
> >>
> >> This control is needed for imx219 driver, as the link frequency
> >> is independent from the pixel rate in this case, and can't be
> >> calculated from the pixel rate.
> >>
> >> Signed-off-by: Andrey Konovalov 
> >> ---
> >>   drivers/media/i2c/imx219.c | 15 ++-
> >>   1 file changed, 14 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> >> index 92a8d52776b8..6e3382b85a90 100644
> >> --- a/drivers/media/i2c/imx219.c
> >> +++ b/drivers/media/i2c/imx219.c
> >> @@ -390,6 +390,10 @@ static const struct imx219_reg raw10_framefmt_regs[] 
> >> = {
> >>  {0x0309, 0x0a},
> >>   };
> >>
> >> +static const s64 imx219_link_freq_menu[] = {
> >> +   IMX219_DEFAULT_LINK_FREQ,
> >
> > Link frequency is one of the parameters that is largely irrelevant on
> > the Pi, so I've partially ignored it.
>
> I faced a problem with the imx219 8-bit modes not working with the camss 
> driver
> (drivers/media/platform/qcom/camss), as based on the link frequency calculated
> from the pixel rate the driver sets the csiphy clock to 100MHz which is too 
> low
> for the actual link frequency (4 * 100MHz < 456MHz), and the captured image
> becomes garbage.
>
> > Is the link frequency really the same for all modes? Even 8 bit vs 10
> > bit readout?
>
> Yes, this is exactly the case.
>
> > The pixel rate is constant at 182.4Mpix/s for all modes.
>
> Right.
>
> > Switching to 8 bit changes register 0x0309 (op_pix_clk_div) from 10 to 8.
> > Figure 43 "Clock System Block Diagram" in the datasheet I have says
> > this reduces the divider to the FIFO between the pipeline and MIPI. As
> > we haven't changed PLL2 or Pre-div2 I'd expect the link frequency to
> > stay the same,
>
> That's true.
>
> > but that leaves me confused over that FIFO clock as
> > it'll go UP in frequency. I can't quite see how that works, but it
> > clearly does.
>
> Yes, the FIFO makes it possible for the different write and read rates to 
> work.
> There are few words regarding this in the datasheet, but this isn't enough
> to fully understand how it works:
> "If, Pix Rate of PLL1 domain < Data Rate of PLL2 domain, data is always
> correctly output from the sensor" (page 81)
>
> If I read the datasheet right, for 10-bit modes the both rates are the same
> (91.2 MHz). In the 8-bit modes the "Data Rate" increases to 114 MHz while
> the "Pix Rate" remains at 91.2 MHz.

There looks to be some magic in there. Without knowing the details of
the size of the FIFO and when it triggers the output stage to start
sending data, it's hard to say exactly what is going on.
I'm guessing that it has to be large enough to take a whole line, and
triggers when the line is complete. The CSI2 bus can then run at the
frequency defined, independent of pixel rate or bit depth.

> > Both 8 and 10 bit modes do read out at the same frame / pixel rate,
> > therefore that bit is correct, but that leaves me puzzling over link
> > frequency. I have no information on how big that FIFO is, or how it's
> > clocked on input and output.
> >
> > Simplest option is that as I need to go into the office in the next
> > day or so I'll pop into the lab and measure it in each mode.
>
> That would be nice!
> In my home "office" I only have a small piece of hardware which claims
> to be able to deal with 2 signals up to 72MHz each, which is not enough
> for such kind of measurements.

My home "office" is likewise compromised, but the work office is still
available and has suitable equipment :-)

I can't be that precise as I'm not bothering to get differential
probes out and the like, but it does appear that the clock lane is
running at the same speed for both 8 and 10 bit.
I measured (cursors off the scope, measured over 4 cycles) 2.21ns for
8 bit, and 2.18ns for 10 bit, corresponding to 452 and 458MHz
respectively. Those are well within the experimental error of my setup
to be the 456MHz defined in the driver.

Based on that I'm happy.

Reviewed-by: Dave Stevenson 

> > Otherwise I have no issues with the implementation of the patch.
> >
> >Dave
>
> Thanks,
> Andrey
>
> >> +};
> >> +
> >>   static const char * const imx219_test_pattern

Re: [PATCH] media: i2c: imx219: Implement V4L2_CID_LINK_FREQ control

2021-01-26 Thread Dave Stevenson
Hi Andrey

On Tue, 26 Jan 2021 at 07:50, Andrey Konovalov
 wrote:
>
> This control is needed for imx219 driver, as the link frequency
> is independent from the pixel rate in this case, and can't be
> calculated from the pixel rate.
>
> Signed-off-by: Andrey Konovalov 
> ---
>  drivers/media/i2c/imx219.c | 15 ++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> index 92a8d52776b8..6e3382b85a90 100644
> --- a/drivers/media/i2c/imx219.c
> +++ b/drivers/media/i2c/imx219.c
> @@ -390,6 +390,10 @@ static const struct imx219_reg raw10_framefmt_regs[] = {
> {0x0309, 0x0a},
>  };
>
> +static const s64 imx219_link_freq_menu[] = {
> +   IMX219_DEFAULT_LINK_FREQ,

Link frequency is one of the parameters that is largely irrelevant on
the Pi, so I've partially ignored it.

Is the link frequency really the same for all modes? Even 8 bit vs 10
bit readout?

The pixel rate is constant at 182.4Mpix/s for all modes.
Switching to 8 bit changes register 0x0309 (op_pix_clk_div) from 10 to 8.
Figure 43 "Clock System Block Diagram" in the datasheet I have says
this reduces the divider to the FIFO between the pipeline and MIPI. As
we haven't changed PLL2 or Pre-div2 I'd expect the link frequency to
stay the same, but that leaves me confused over that FIFO clock as
it'll go UP in frequency. I can't quite see how that works, but it
clearly does.

Both 8 and 10 bit modes do read out at the same frame / pixel rate,
therefore that bit is correct, but that leaves me puzzling over link
frequency. I have no information on how big that FIFO is, or how it's
clocked on input and output.

Simplest option is that as I need to go into the office in the next
day or so I'll pop into the lab and measure it in each mode.

Otherwise I have no issues with the implementation of the patch.

  Dave

> +};
> +
>  static const char * const imx219_test_pattern_menu[] = {
> "Disabled",
> "Color Bars",
> @@ -547,6 +551,7 @@ struct imx219 {
> struct v4l2_ctrl_handler ctrl_handler;
> /* V4L2 Controls */
> struct v4l2_ctrl *pixel_rate;
> +   struct v4l2_ctrl *link_freq;
> struct v4l2_ctrl *exposure;
> struct v4l2_ctrl *vflip;
> struct v4l2_ctrl *hflip;
> @@ -1269,7 +1274,7 @@ static int imx219_init_controls(struct imx219 *imx219)
> int i, ret;
>
> ctrl_hdlr = >ctrl_handler;
> -   ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
> +   ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
> if (ret)
> return ret;
>
> @@ -1283,6 +1288,14 @@ static int imx219_init_controls(struct imx219 *imx219)
>IMX219_PIXEL_RATE, 1,
>IMX219_PIXEL_RATE);
>
> +   imx219->link_freq =
> +   v4l2_ctrl_new_int_menu(ctrl_hdlr, _ctrl_ops,
> +  V4L2_CID_LINK_FREQ,
> +  ARRAY_SIZE(imx219_link_freq_menu) - 1, 
> 0,
> +  imx219_link_freq_menu);
> +   if (imx219->link_freq)
> +   imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> /* Initial vblank/hblank/exposure parameters based on current mode */
> imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, _ctrl_ops,
>V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
> --
> 2.17.1
>


Re: [PATCH v2 13/15] dt-binding: display: bcm2711-hdmi: Add CEC and hotplug interrupts

2021-01-22 Thread Dave Stevenson
Hi Maxime

On Mon, 11 Jan 2021 at 14:23, Maxime Ripard  wrote:
>
> The CEC and hotplug interrupts were missing when that binding was
> introduced, let's add them in now that we've figured out how it works.
>
> Signed-off-by: Maxime Ripard 

Looks reasonable to me, but I'm not a DT bindings expert

Acked-by: Dave Stevenson 

> ---
>  .../bindings/display/brcm,bcm2711-hdmi.yaml   | 20 ++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml 
> b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> index 7ce06f9f9f8e..6e8ac910bdd8 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> @@ -53,6 +53,24 @@ properties:
>- const: audio
>- const: cec
>
> +  interrupts:
> +items:
> +  - description: CEC TX interrupt
> +  - description: CEC RX interrupt
> +  - description: CEC stuck at low interrupt
> +  - description: Wake-up interrupt
> +  - description: Hotplug connected interrupt
> +  - description: Hotplug removed interrupt
> +
> +  interrupt-names:
> +items:
> +  - const: cec-tx
> +  - const: cec-rx
> +  - const: cec-low
> +  - const: wakeup
> +  - const: hpd-connected
> +  - const: hpd-removed
> +
>ddc:
>  allOf:
>- $ref: /schemas/types.yaml#/definitions/phandle
> @@ -90,7 +108,7 @@ required:
>- resets
>- ddc
>
> -additionalProperties: false
> +unevaluatedProperties: false
>
>  examples:
>- |
> --
> 2.29.2
>


Re: [PATCH v2 10/15] drm/vc4: hdmi: Support BCM2711 CEC interrupt setup

2021-01-22 Thread Dave Stevenson
Hi Maxime

On Mon, 11 Jan 2021 at 14:23, Maxime Ripard  wrote:
>
> The HDMI controller found in the BCM2711 has an external interrupt
> controller for the CEC and hotplug interrupt shared between the two
> instances.
>
> Let's add a variant flag to register a single interrupt handler and
> deals with the interrupt handler setup, or two interrupt handlers
> relying on an external irqchip.
>
> Signed-off-by: Maxime Ripard 

Looks good

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 42 ++
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  7 ++
>  2 files changed, 39 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 12ca5f3084af..d116ecfd8cf7 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1605,9 +1605,11 @@ static int vc4_hdmi_cec_adap_enable(struct cec_adapter 
> *adap, bool enable)
>((3600 / usecs) << 
> VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
>((3500 / usecs) << 
> VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
>
> -   HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
> +   if (!vc4_hdmi->variant->external_irq_controller)
> +   HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
> } else {
> -   HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
> +   if (!vc4_hdmi->variant->external_irq_controller)
> +   HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
> HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
>VC4_HDMI_CEC_TX_SW_RESET | 
> VC4_HDMI_CEC_RX_SW_RESET);
> }
> @@ -1682,8 +1684,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
> cec_fill_conn_info_from_drm(_info, _hdmi->connector);
> cec_s_conn_info(vc4_hdmi->cec_adap, _info);
>
> -   HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0x);
> -
> value = HDMI_READ(HDMI_CEC_CNTRL_1);
> /* Set the logical address to Unregistered */
> value |= VC4_HDMI_CEC_ADDR_MASK;
> @@ -1691,12 +1691,32 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi 
> *vc4_hdmi)
>
> vc4_hdmi_cec_update_clk_div(vc4_hdmi);
>
> -   ret = devm_request_threaded_irq(>dev, platform_get_irq(pdev, 0),
> -   vc4_cec_irq_handler,
> -   vc4_cec_irq_handler_thread, 0,
> -   "vc4 hdmi cec", vc4_hdmi);
> -   if (ret)
> -   goto err_delete_cec_adap;
> +   if (vc4_hdmi->variant->external_irq_controller) {
> +   ret = devm_request_threaded_irq(>dev,
> +   platform_get_irq_byname(pdev, 
> "cec-rx"),
> +   vc4_cec_irq_handler_rx_bare,
> +   
> vc4_cec_irq_handler_rx_thread, 0,
> +   "vc4 hdmi cec rx", vc4_hdmi);
> +   if (ret)
> +   goto err_delete_cec_adap;
> +
> +   ret = devm_request_threaded_irq(>dev,
> +   platform_get_irq_byname(pdev, 
> "cec-tx"),
> +   vc4_cec_irq_handler_tx_bare,
> +   
> vc4_cec_irq_handler_tx_thread, 0,
> +   "vc4 hdmi cec tx", vc4_hdmi);
> +   if (ret)
> +   goto err_delete_cec_adap;
> +   } else {
> +   HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0x);
> +
> +   ret = devm_request_threaded_irq(>dev, 
> platform_get_irq(pdev, 0),
> +   vc4_cec_irq_handler,
> +   vc4_cec_irq_handler_thread, 0,
> +   "vc4 hdmi cec", vc4_hdmi);
> +   if (ret)
> +   goto err_delete_cec_adap;
> +   }
>
> ret = cec_register_adapter(vc4_hdmi->cec_adap, >dev);
> if (ret < 0)
> @@ -2095,6 +2115,7 @@ static const struct vc4_hdmi_variant 
> bcm2711_hdmi0_variant = {
> PHY_LANE_CK,
> },
> .unsupported_odd_h_timings  = true,
> +   .external_irq_controller= true,
>
> .init_resources = vc5_hdmi_init_resources,
> .csc_setup  = vc5_hdmi_csc_setup,
&g

Re: [PATCH v2 09/15] drm/vc4: hdmi: Split the interrupt handlers

2021-01-22 Thread Dave Stevenson
Hi Maxime

On Mon, 11 Jan 2021 at 14:23, Maxime Ripard  wrote:
>
> The BCM2711 has two different interrupt sources to transmit and receive
> CEC messages, provided through an external interrupt chip shared between
> the two HDMI interrupt controllers.
>
> The rest of the CEC controller is identical though so we need to change
> a bit the code organisation to share the code as much as possible, yet
> still allowing to register independant handlers.

s/independant/independent

>
> Signed-off-by: Maxime Ripard 

With that
Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 86 +-
>  1 file changed, 65 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 7b5c92df8f1b..12ca5f3084af 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1454,15 +1454,22 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi 
> *vc4_hdmi)
>  }
>
>  #ifdef CONFIG_DRM_VC4_HDMI_CEC
> -static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
> +static irqreturn_t vc4_cec_irq_handler_rx_thread(int irq, void *priv)
>  {
> struct vc4_hdmi *vc4_hdmi = priv;
>
> -   if (vc4_hdmi->cec_irq_was_rx) {
> -   if (vc4_hdmi->cec_rx_msg.len)
> -   cec_received_msg(vc4_hdmi->cec_adap,
> -_hdmi->cec_rx_msg);
> -   } else if (vc4_hdmi->cec_tx_ok) {
> +   if (vc4_hdmi->cec_rx_msg.len)
> +   cec_received_msg(vc4_hdmi->cec_adap,
> +_hdmi->cec_rx_msg);
> +
> +   return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t vc4_cec_irq_handler_tx_thread(int irq, void *priv)
> +{
> +   struct vc4_hdmi *vc4_hdmi = priv;
> +
> +   if (vc4_hdmi->cec_tx_ok) {
> cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_OK,
>   0, 0, 0, 0);
> } else {
> @@ -1476,6 +1483,19 @@ static irqreturn_t vc4_cec_irq_handler_thread(int irq, 
> void *priv)
> return IRQ_HANDLED;
>  }
>
> +static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
> +{
> +   struct vc4_hdmi *vc4_hdmi = priv;
> +   irqreturn_t ret;
> +
> +   if (vc4_hdmi->cec_irq_was_rx)
> +   ret = vc4_cec_irq_handler_rx_thread(irq, priv);
> +   else
> +   ret = vc4_cec_irq_handler_tx_thread(irq, priv);
> +
> +   return ret;
> +}
> +
>  static void vc4_cec_read_msg(struct vc4_hdmi *vc4_hdmi, u32 cntrl1)
>  {
> struct drm_device *dev = vc4_hdmi->connector.dev;
> @@ -1500,31 +1520,55 @@ static void vc4_cec_read_msg(struct vc4_hdmi 
> *vc4_hdmi, u32 cntrl1)
> }
>  }
>
> +static irqreturn_t vc4_cec_irq_handler_tx_bare(int irq, void *priv)
> +{
> +   struct vc4_hdmi *vc4_hdmi = priv;
> +   u32 cntrl1;
> +
> +   cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1);
> +   vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
> +   cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
> +   HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
> +
> +   return IRQ_WAKE_THREAD;
> +}
> +
> +static irqreturn_t vc4_cec_irq_handler_rx_bare(int irq, void *priv)
> +{
> +   struct vc4_hdmi *vc4_hdmi = priv;
> +   u32 cntrl1;
> +
> +   vc4_hdmi->cec_rx_msg.len = 0;
> +   cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1);
> +   vc4_cec_read_msg(vc4_hdmi, cntrl1);
> +   cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
> +   HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
> +   cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
> +
> +   HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
> +
> +   return IRQ_WAKE_THREAD;
> +}
> +
>  static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
>  {
> struct vc4_hdmi *vc4_hdmi = priv;
> u32 stat = HDMI_READ(HDMI_CEC_CPU_STATUS);
> -   u32 cntrl1, cntrl5;
> +   irqreturn_t ret;
> +   u32 cntrl5;
>
> if (!(stat & VC4_HDMI_CPU_CEC))
> return IRQ_NONE;
> -   vc4_hdmi->cec_rx_msg.len = 0;
> -   cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1);
> +
> cntrl5 = HDMI_READ(HDMI_CEC_CNTRL_5);
> vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
> -   if (vc4_hdmi->cec_irq_was_rx) {
> -   vc4_cec_read_msg(vc4_hdmi, cntrl1);
> -   cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
> -   HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
> -   cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
> -   } else {
> -   vc4_hdmi->cec_tx_ok = cntrl1 

Re: [PATCH v2 05/15] drm/vc4: hdmi: Restore cec physical address on reconnect

2021-01-22 Thread Dave Stevenson
Hi Maxime

Sorry for the slow reply on these patches.

On Mon, 11 Jan 2021 at 14:23, Maxime Ripard  wrote:
>
> From: Dom Cobley 
>
> Currently we call cec_phys_addr_invalidate on a hotplug deassert.
> That may be due to a TV power cycling, or an AVR being switched
> on (and switching edid).
>
> This makes CEC unusable since our controller wouldn't have a physical
> address anymore.
>
> Set it back up again on the hotplug assert.
>
> Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support")
> Signed-off-by: Dom Cobley 
> Signed-off-by: Maxime Ripard 

I follow the logic, and trust Dom that it works, but I don't know if
that is the correct thing within CEC.
Ideally Hans will comment as the original author of the CEC code - I
believe he's testing the series anyway.

Acked-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 24 ++--
>  1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 7945dbcee78c..c3a301396aad 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -136,20 +136,32 @@ static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> +   bool connected = false;
>
> if (vc4_hdmi->hpd_gpio) {
> if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
> vc4_hdmi->hpd_active_low)
> -   return connector_status_connected;
> -   cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> -   return connector_status_disconnected;
> +   connected = true;
> +   } else if (drm_probe_ddc(vc4_hdmi->ddc)) {
> +   connected = true;
> +   } else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) {
> +   connected = true;
> }
>
> -   if (drm_probe_ddc(vc4_hdmi->ddc))
> -   return connector_status_connected;
> +   if (connected) {
> +   if (connector->status != connector_status_connected) {
> +   struct edid *edid = drm_get_edid(connector, 
> vc4_hdmi->ddc);
> +
> +   if (edid) {
> +   cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, 
> edid);
> +   vc4_hdmi->encoder.hdmi_monitor = 
> drm_detect_hdmi_monitor(edid);
> +   kfree(edid);
> +   }
> +   }
>
> -   if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
> return connector_status_connected;
> +   }
> +
> cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> return connector_status_disconnected;
>  }
> --
> 2.29.2
>


Re: [PATCH] media: i2c: imx219: Rewrite tables and implement more modes

2021-01-17 Thread Dave Stevenson
Hi Angelo

On Sun, 17 Jan 2021 at 17:33, AngeloGioacchino Del Regno
 wrote:
>
> Il 17/01/21 00:13, Sakari Ailus ha scritto:
> > Hi AngeloGioacchino,
> >
> > On Fri, Jan 15, 2021 at 07:52:33PM +0100, AngeloGioacchino Del Regno wrote:
> >> Enhance the feature set for this camera sensor by in rewriting the
> >> entire tables (as they were just meaningless magic register writes)
> >> in a similar form, but giving some names to the actual registers
> >> we write to, separating common sequences and reusing them for the
> >> various configuration variations that are now supported, hence
> >> implementing support for:
> >> - 8MHz XCLK, as used by (and not only) some Sony Xperia smartphones
> >> - 4-Lane Mode in both 24MHz and 8MHz XCLK configuration
> >> - High Frame Rate output modes support on 4-Lane operation, up to
> >>1000FPS (also on 2-Lane but, being bandwidth-constrained, the
> >>maximum achievable frame rate gets lower there)
> >
> > That's a lot of changes for a single patch. Could you split each of these
> > into separate patches, please?
> >
>
> Sure! I agree with you, let's split them for the V2 patch series!
>
> >> - Frame Bank Control Groups, in order to support a fast output
> >>resolution switch, without resetting the entire sensor during
> >>a streaming session: here the new mode gets configured on the
> >>secondary (or primary, read: "the other") bank and the sensor
> >>will be able to switch to it at the end of the "current frame".
> >
> > You basically need to stop streaming to reconfigure the sensor; V4L2
> > currently does not doing this on the fly.
> >
> > There's no need to rest the sensor though, and I don't think the driver did
> > that before either.
> >
>
> If V4L2 needs to stop streaming, then the sensor is "put to rest".
> By the way... okay, I can remove the implementation to fast-switch
> between the frame banks, but the registers are still laid out in frame
> banks in hardware so, in my opinion, the "new" layout should be kept.
>
> I wrote something more about this in reply to D. Stevenson so, please,
> for more information, look at my reply to him.
> Copy-pasting should not be necessary. Thank you!
>
> >>
> >> Please note: an unknown register write sequence was found in both
> >> the Raspberry Pi and a Sony Xperia smartphone i2c dump, but this
> >> seems to do literally nothing, as the sensor seems to work
> >> in the exact same way when sending and when not sending this
> >> write sequence, which is undocumented in the datasheet.
> >>
> >> Both the authentication and magic sequences were left in the
> >> driver with a big comment explaining what's going on so that,
> >> in the event that someone discovers the meaning of it (or
> >> Sony distributes documentation for that), it'll be pretty
> >> straightforward to insert them when needed.
> >>
> >> All the modes that got implemented in this commit have been tested
> >> with all combinations of 24/8MHz, 2/4Lane, all resolutions, on the
> >> following smartphones:
> >> - Sony Xperia XA2 (SDM630)
> >> - Sony Xperia XA2 Ultra (SDM630)
> >>
> >> Signed-off-by: AngeloGioacchino Del Regno 
> >> 
> >> ---
> >>   drivers/media/i2c/imx219.c | 884 -
> >>   1 file changed, 580 insertions(+), 304 deletions(-)
> >>
> >> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> >> index 92a8d52776b8..360730d5b81c 100644
> >> --- a/drivers/media/i2c/imx219.c
> >> +++ b/drivers/media/i2c/imx219.c
> >> @@ -12,6 +12,10 @@
> >>* Flip handling taken from the Sony IMX319 driver.
> >>* Copyright (C) 2018 Intel Corporation
> >>*
> >> + * 8MHz, 4-Lane, High Frame Rate modes, Frame Bank Control groups,
> >> + * fast mode switching
> >> + * Copyright (C) 2020, AngeloGioacchino Del Regno
> >> + * 
> >>*/
> >>
> >>   #include 
> >> @@ -35,24 +39,93 @@
> >>   #define IMX219_MODE_STANDBY0x00
> >>   #define IMX219_MODE_STREAMING  0x01
> >>
> >> +#define IMX219_REG_SW_RESET 0x0103
> >> +
> >> +/* Output Set-up */
> >> +#define IMX219_REG_CSI_LANE_MODE0x0114
> >> +#define IMX219_CSI_LANE_MODE_2LANE  BIT(0)
> >> +#define IMX219_CSI_LANE_MODE_4LANE  (BIT(0) | BIT(1))
> >> +
> >> +#define IMX219_REG_DPHY_CTRL0x0128
> >> +#define IMX219_DPHY_CTRL_AUTO   0
> >> +#define IMX219_DPHY_CTRL_MANUAL 1
> >> +
> >> +/* Use as 16-bits reg */
> >> +#define IMX219_REG_EXCK_FREQ_MHZ0x012A
> >> +#define IMX219_EXCK_FREQ_MHZ_MIN6
> >> +#define IMX219_EXCK_FREQ_MHZ_MAX27
> >> +
> >> +/* Frame Bank Control Registers*/
> >> +#define IMX219_REG_FRAME_BANK_CTRL  0x0150
> >> +#define IMX219_FRAME_BANK_EN_SHIFT  BIT(0)
> >> +#define IMX219_FRAME_BANK_STAT_SHIFTBIT(1)
> >> +
> >> +#define IMX219_REG_FRAME_COUNT  0x0151
> >> +#define IMX219_REG_FRAME_FAST_TRACKING  0x0152
> >> +
> >> +/* Frame Bank  0: Group "A" - 1: Group "B" */
> >> +#define 

Re: [PATCH] media: i2c: imx219: Rewrite tables and implement more modes

2021-01-17 Thread Dave Stevenson
Hi AngeloGioacchino

Thanks for the patch.

On Fri, 15 Jan 2021 at 18:52, AngeloGioacchino Del Regno
 wrote:
>
> Enhance the feature set for this camera sensor by in rewriting the
> entire tables (as they were just meaningless magic register writes)
> in a similar form, but giving some names to the actual registers
> we write to, separating common sequences and reusing them for the
> various configuration variations that are now supported, hence
> implementing support for:
> - 8MHz XCLK, as used by (and not only) some Sony Xperia smartphones
> - 4-Lane Mode in both 24MHz and 8MHz XCLK configuration
> - High Frame Rate output modes support on 4-Lane operation, up to
>   1000FPS (also on 2-Lane but, being bandwidth-constrained, the
>   maximum achievable frame rate gets lower there)
> - Frame Bank Control Groups, in order to support a fast output
>   resolution switch, without resetting the entire sensor during
>   a streaming session: here the new mode gets configured on the
>   secondary (or primary, read: "the other") bank and the sensor
>   will be able to switch to it at the end of the "current frame".

This is at least 5 changes, each of which should be a separate patch:
- Add support for 8MHz XCLK
- Add support for 4 lane mode
- Add 1000fps mode
- Bank control
- Restructuring the register sequences (and ideally that should be
switching to defined register names, and then restructuring).

At the moment this is a huge single patch with several intertwined
changes. It needs to be split to be properly reviewable.

> Please note: an unknown register write sequence was found in both
> the Raspberry Pi and a Sony Xperia smartphone i2c dump, but this
> seems to do literally nothing, as the sensor seems to work
> in the exact same way when sending and when not sending this
> write sequence, which is undocumented in the datasheet.
>
> Both the authentication and magic sequences were left in the
> driver with a big comment explaining what's going on so that,
> in the event that someone discovers the meaning of it (or
> Sony distributes documentation for that), it'll be pretty
> straightforward to insert them when needed.
>
> All the modes that got implemented in this commit have been tested
> with all combinations of 24/8MHz, 2/4Lane, all resolutions, on the
> following smartphones:
> - Sony Xperia XA2 (SDM630)
> - Sony Xperia XA2 Ultra (SDM630)
>
> Signed-off-by: AngeloGioacchino Del Regno 
> 
> ---
>  drivers/media/i2c/imx219.c | 884 -
>  1 file changed, 580 insertions(+), 304 deletions(-)
>
> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> index 92a8d52776b8..360730d5b81c 100644
> --- a/drivers/media/i2c/imx219.c
> +++ b/drivers/media/i2c/imx219.c
> @@ -12,6 +12,10 @@
>   * Flip handling taken from the Sony IMX319 driver.
>   * Copyright (C) 2018 Intel Corporation
>   *
> + * 8MHz, 4-Lane, High Frame Rate modes, Frame Bank Control groups,
> + * fast mode switching
> + * Copyright (C) 2020, AngeloGioacchino Del Regno
> + * 

It's now 2021.

>   */
>
>  #include 
> @@ -35,24 +39,93 @@
>  #define IMX219_MODE_STANDBY0x00
>  #define IMX219_MODE_STREAMING  0x01
>
> +#define IMX219_REG_SW_RESET0x0103
> +
> +/* Output Set-up */
> +#define IMX219_REG_CSI_LANE_MODE   0x0114
> +#define IMX219_CSI_LANE_MODE_2LANE BIT(0)
> +#define IMX219_CSI_LANE_MODE_4LANE (BIT(0) | BIT(1))
> +
> +#define IMX219_REG_DPHY_CTRL   0x0128
> +#define IMX219_DPHY_CTRL_AUTO  0
> +#define IMX219_DPHY_CTRL_MANUAL1
> +
> +/* Use as 16-bits reg */
> +#define IMX219_REG_EXCK_FREQ_MHZ   0x012A
> +#define IMX219_EXCK_FREQ_MHZ_MIN   6
> +#define IMX219_EXCK_FREQ_MHZ_MAX   27
> +
> +/* Frame Bank Control Registers*/
> +#define IMX219_REG_FRAME_BANK_CTRL 0x0150
> +#define IMX219_FRAME_BANK_EN_SHIFT BIT(0)
> +#define IMX219_FRAME_BANK_STAT_SHIFT   BIT(1)
> +
> +#define IMX219_REG_FRAME_COUNT 0x0151
> +#define IMX219_REG_FRAME_FAST_TRACKING 0x0152
> +
> +/* Frame Bank  0: Group "A" - 1: Group "B" */
> +#define IMX219_REG_FRAME_BANK_BASE(x)  ((0x100 * x) + 0x154)
> +#define IMX219_REG_ANALOG_GAIN 0x03
> +#define IMX219_REG_DIGITAL_GAIN0x04
> +#define IMX219_REG_EXPOSURE0x06
> +#define IMX219_REG_FRAME_LEN_LINES 0x0c
> +#define IMX219_REG_LINE_LEN_PCK0x0e
> +#define IMX219_REG_X_ADDR_START0x10
> +#define IMX219_REG_X_ADDR_END  0x12
> +#define IMX219_REG_Y_ADDR_START0x14
> +#define IMX219_REG_Y_ADDR_END  0x16
> +#define IMX219_REG_X_OUTPUT_SIZE   0x18
> +#define IMX219_REG_Y_OUTPUT_SIZE   0x1a
> +#define IMX219_REG_X_ODD_INC   0x1c
> +#define IMX219_REG_Y_ODD_INC   0x1d
> +#define IMX219_REG_ORIENTATION 0x1e
> +#define IMX219_REG_BINNING_MODE_H  0x20
> +#define IMX219_REG_BINNING_MODE_V  0x21
> +#define IMX219_REG_BINNING_CAL_H   

Re: [PATCH 05/15] drm/vc4: hdmi: Restore cec physical address on reconnect

2020-12-18 Thread Dave Stevenson
On Fri, 18 Dec 2020 at 14:21, Dave Stevenson
 wrote:
>
> Hi  Maxime & Dom
>
> On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
> >
> > From: Dom Cobley 
> >
> > Currently we call cec_phys_addr_invalidate on a hotplug deassert.
> > That may be due to a TV power cycling, or an AVR being switched
> > on (and switching edid).
> >
> > This makes CEC unusable since our controller wouldn't have a physical
> > address anymore.
> >
> > Set it back up again on the hotplug assert.
> >
> > Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support")
> > Signed-off-by: Dom Cobley 
> > Signed-off-by: Maxime Ripard 
> > ---
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +
> >  1 file changed, 17 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index 28b78ea885ea..eff3bac562c6 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -136,20 +136,29 @@ static enum drm_connector_status
> >  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
> >  {
> > struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> > +   bool connected = false;
> >
> > if (vc4_hdmi->hpd_gpio) {
> > if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
> > vc4_hdmi->hpd_active_low)
> > -   return connector_status_connected;
> > -   cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> > -   return connector_status_disconnected;
> > -   }
> > -
> > -   if (drm_probe_ddc(vc4_hdmi->ddc))
> > -   return connector_status_connected;
> > -
> > +   connected = true;
> > +   } else if (drm_probe_ddc(vc4_hdmi->ddc))
> > +   connected = true;
> > if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
>
> This needs to become an "else if(...".
> It used to be that all the other paths would return, so were mutually
> exclusive to this. Now they set a thing and keep going we need to
> avoid reading the register should there be a HPD gpio or the ddc probe
> succeeds.
> Memory says that otherwise Pi3 always reports connected.
>
> I fixed this in a downstream patch already -
> https://github.com/raspberrypi/linux/commit/d345caec1e9b2317b9cd7eb5b92ae453a0d3e98c
>
> Otherwise fine.
>
>   Dave
>
> > +   connected = true;
> > +   if (connected) {
> > +   if (connector->status != connector_status_connected) {
> > +   struct edid *edid = drm_get_edid(connector, 
> > vc4_hdmi->ddc);
> > +
> > +   if (edid) {
> > +   
> > cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
> > +   vc4_hdmi->encoder.hdmi_monitor = 
> > drm_detect_hdmi_monitor(edid);
> > +   
> > drm_connector_update_edid_property(connector, edid);

Actually looking at this again in the context of the other changes, do
we need to call drm_connector_update_edid_property() here?

We've just called drm_get_edid() to get the edid, and that calls
drm_connector_update_edid_property() as well [1]
Updating vc4_hdmi->encoder.hdmi_monitor may be necessary. It's
otherwise done in vc4_hdmi_connector_get_modes, which I sort of expect
to be called almost immediately by the framework when connector_detect
returns "connected". I haven't checked if that is guaranteed though.

vc4_hdmi_connector_get_modes also includes a manual call to
drm_connector_update_edid_property after having just called
drm_get_edid, so that one feels redundant too.

  Dave

[1] 
https://elixir.bootlin.com/linux/v5.10/source/drivers/gpu/drm/drm_edid.c#L2059

> > +   kfree(edid);
> > +   }
> > +   }
> > return connector_status_connected;
> > +   }
> > cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> > return connector_status_disconnected;
> >  }
> > --
> > 2.28.0
> >


Re: [PATCH 11/15] drm/vc4: hdmi: Remove cec_available flag

2020-12-18 Thread Dave Stevenson
Hi Dom & Maxime

On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
>
> From: Dom Cobley 
>
> Now that our HDMI controller supports CEC for the BCM2711, let's remove
> that flag.
>
> Signed-off-by: Dom Cobley 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 4 
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 3 ---
>  2 files changed, 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index d208b7d1d937..327638d93032 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1658,9 +1658,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
> u32 value;
> int ret;
>
> -   if (!vc4_hdmi->variant->cec_available)
> -   return 0;
> -
> vc4_hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
>   vc4_hdmi, "vc4",
>   CEC_CAP_DEFAULTS |
> @@ -2074,7 +2071,6 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
> .debugfs_name   = "hdmi_regs",
> .card_name  = "vc4-hdmi",
> .max_pixel_clock= 16200,
> -   .cec_available  = true,
> .registers  = vc4_hdmi_fields,
> .num_registers  = ARRAY_SIZE(vc4_hdmi_fields),
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 27352827f70c..c93ada62f429 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -42,9 +42,6 @@ struct vc4_hdmi_variant {
> /* Filename to expose the registers in debugfs */
> const char *debugfs_name;
>
> -   /* Set to true when the CEC support is available */
> -   bool cec_available;
> -
> /* Maximum pixel clock supported by the controller (in Hz) */
> unsigned long long max_pixel_clock;
>
> --
> 2.28.0
>


Re: [PATCH 12/15] drm/vc4: hdmi: Don't register the CEC adapter if there's no interrupts

2020-12-18 Thread Dave Stevenson
On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
>
> We introduced the BCM2711 support to the vc4 HDMI controller with 5.10,
> but this was lacking any of the interrupts of the CEC controller so we
> have to deal with the backward compatibility.
>
> Do so by simply ignoring the CEC setup if the DT doesn't have the
> interrupts property.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 327638d93032..69217c68d3a4 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1655,9 +1655,15 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
>  {
> struct cec_connector_info conn_info;
> struct platform_device *pdev = vc4_hdmi->pdev;
> +   struct device *dev = >dev;
> u32 value;
> int ret;
>
> +   if (!of_find_property(dev->of_node, "interrupts", NULL)) {
> +   dev_warn(dev, "'interrupts' DT property is missing, no 
> CEC\n");
> +   return 0;
> +   }
> +
> vc4_hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
>   vc4_hdmi, "vc4",
>   CEC_CAP_DEFAULTS |
> --
> 2.28.0
>


Re: [PATCH 07/15] drm/vc4: hdmi: Update the CEC clock divider on HSM rate change

2020-12-18 Thread Dave Stevenson
Hi Maxime

On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
>
> As part of the enable sequence we might change the HSM clock rate if the
> pixel rate is different than the one we were already dealing with.
>
> On the BCM2835 however, the CEC clock derives from the HSM clock so any
> rate change will need to be reflected in the CEC clock divider to output
> 40kHz.
>
> Fixes: cd4cb49dc5bb ("drm/vc4: hdmi: Adjust HSM clock rate depending on pixel 
> rate")
> Signed-off-by: Maxime Ripard 

I thought we'd got a duplicate patch here, but it's moving code that
was changed in patch 6/15 so it can be called from
vc4_hdmi_encoder_pre_crtc_configure too. Good for confusing me!

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 39 +-
>  1 file changed, 29 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 0c53d7427d15..b93ee3e26e2b 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -132,6 +132,27 @@ static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
>HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
>  }
>
> +#ifdef CONFIG_DRM_VC4_HDMI_CEC
> +static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi)
> +{
> +   u16 clk_cnt;
> +   u32 value;
> +
> +   value = HDMI_READ(HDMI_CEC_CNTRL_1);
> +   value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
> +
> +   /*
> +* Set the clock divider: the hsm_clock rate and this divider
> +* setting will give a 40 kHz CEC clock.
> +*/
> +   clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ;
> +   value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT;
> +   HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
> +}
> +#else
> +static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {}
> +#endif
> +
>  static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -761,6 +782,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct 
> drm_encoder *encoder,
> return;
> }
>
> +   vc4_hdmi_cec_update_clk_div(vc4_hdmi);
> +
> /*
>  * FIXME: When the pixel freq is 594MHz (4k60), this needs to be setup
>  * at 300MHz.
> @@ -1586,7 +1609,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
>  {
> struct cec_connector_info conn_info;
> struct platform_device *pdev = vc4_hdmi->pdev;
> -   u16 clk_cnt;
> u32 value;
> int ret;
>
> @@ -1605,17 +1627,14 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi 
> *vc4_hdmi)
> cec_s_conn_info(vc4_hdmi->cec_adap, _info);
>
> HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0x);
> +
> value = HDMI_READ(HDMI_CEC_CNTRL_1);
> -   value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
> -   /*
> -* Set the logical address to Unregistered and set the clock
> -* divider: the hsm_clock rate and this divider setting will
> -* give a 40 kHz CEC clock.
> -*/
> -   clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ;
> -   value |= VC4_HDMI_CEC_ADDR_MASK |
> -(clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
> +   /* Set the logical address to Unregistered */
> +   value |= VC4_HDMI_CEC_ADDR_MASK;
> HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
> +
> +   vc4_hdmi_cec_update_clk_div(vc4_hdmi);
> +
> ret = devm_request_threaded_irq(>dev, platform_get_irq(pdev, 0),
> vc4_cec_irq_handler,
> vc4_cec_irq_handler_thread, 0,
> --
> 2.28.0
>


Re: [PATCH 05/15] drm/vc4: hdmi: Restore cec physical address on reconnect

2020-12-18 Thread Dave Stevenson
Hi  Maxime & Dom

On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
>
> From: Dom Cobley 
>
> Currently we call cec_phys_addr_invalidate on a hotplug deassert.
> That may be due to a TV power cycling, or an AVR being switched
> on (and switching edid).
>
> This makes CEC unusable since our controller wouldn't have a physical
> address anymore.
>
> Set it back up again on the hotplug assert.
>
> Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support")
> Signed-off-by: Dom Cobley 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +
>  1 file changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 28b78ea885ea..eff3bac562c6 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -136,20 +136,29 @@ static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> +   bool connected = false;
>
> if (vc4_hdmi->hpd_gpio) {
> if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
> vc4_hdmi->hpd_active_low)
> -   return connector_status_connected;
> -   cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> -   return connector_status_disconnected;
> -   }
> -
> -   if (drm_probe_ddc(vc4_hdmi->ddc))
> -   return connector_status_connected;
> -
> +   connected = true;
> +   } else if (drm_probe_ddc(vc4_hdmi->ddc))
> +   connected = true;
> if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)

This needs to become an "else if(...".
It used to be that all the other paths would return, so were mutually
exclusive to this. Now they set a thing and keep going we need to
avoid reading the register should there be a HPD gpio or the ddc probe
succeeds.
Memory says that otherwise Pi3 always reports connected.

I fixed this in a downstream patch already -
https://github.com/raspberrypi/linux/commit/d345caec1e9b2317b9cd7eb5b92ae453a0d3e98c

Otherwise fine.

  Dave

> +   connected = true;
> +   if (connected) {
> +   if (connector->status != connector_status_connected) {
> +   struct edid *edid = drm_get_edid(connector, 
> vc4_hdmi->ddc);
> +
> +   if (edid) {
> +   cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, 
> edid);
> +   vc4_hdmi->encoder.hdmi_monitor = 
> drm_detect_hdmi_monitor(edid);
> +   drm_connector_update_edid_property(connector, 
> edid);
> +   kfree(edid);
> +   }
> +   }
> return connector_status_connected;
> +   }
> cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> return connector_status_disconnected;
>  }
> --
> 2.28.0
>


Re: [PATCH 08/15] drm/vc4: hdmi: Introduce a CEC clock

2020-12-18 Thread Dave Stevenson
On Fri, 18 Dec 2020 at 12:23, Maxime Ripard  wrote:
>
> Hi Dave,
>
> On Fri, Dec 18, 2020 at 11:37:50AM +, Dave Stevenson wrote:
> > Hi Maxime
> >
> > On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
> > >
> > > While the BCM2835 had the CEC clock derived from the HSM clock, the
> > > BCM2711 has a dedicated parent clock for it.
> > >
> > > Let's introduce a separate clock for it so that we can handle both
> > > cases.
> > >
> > > Signed-off-by: Maxime Ripard 
> > > ---
> > >  drivers/gpu/drm/vc4/vc4_hdmi.c | 9 -
> > >  drivers/gpu/drm/vc4/vc4_hdmi.h | 1 +
> > >  2 files changed, 9 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c 
> > > b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > index b93ee3e26e2b..0debd22bc992 100644
> > > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > @@ -145,7 +145,7 @@ static void vc4_hdmi_cec_update_clk_div(struct 
> > > vc4_hdmi *vc4_hdmi)
> > >  * Set the clock divider: the hsm_clock rate and this divider
> > >  * setting will give a 40 kHz CEC clock.
> > >  */
> > > -   clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ;
> > > +   clk_cnt = clk_get_rate(vc4_hdmi->cec_clock) / CEC_CLOCK_FREQ;
> > > value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT;
> > > HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
> > >  }
> > > @@ -1740,6 +1740,7 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi 
> > > *vc4_hdmi)
> > > return PTR_ERR(vc4_hdmi->hsm_clock);
> > > }
> > > vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock;
> > > +   vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock;
> > >
> > > return 0;
> > >  }
> > > @@ -1833,6 +1834,12 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi 
> > > *vc4_hdmi)
> > > return PTR_ERR(vc4_hdmi->audio_clock);
> > > }
> > >
> > > +   vc4_hdmi->cec_clock = devm_clk_get(dev, "cec");
> > > +   if (IS_ERR(vc4_hdmi->cec_clock)) {
> > > +   DRM_ERROR("Failed to get CEC clock\n");
> > > +   return PTR_ERR(vc4_hdmi->cec_clock);
> > > +   }
> >
> > Aren't we adding to the DT binding here and breaking backwards 
> > compatibility?
> > Admittedly CEC didn't work before (and was masked out) for vc5, but do
> > we need to worry about those with existing DT files that currently
> > work happily?
>
> The DT compatibility is not a worry here: I made sure the CEC clock and
> range were part of the binding since it's been introduced:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2e3725b05b785e73482a194b99bff3d5a1c85140
>
> So we were not using it so far, but it was in the DT all along

I guess I should have read it then :-)
In which case
Reviewed-by: Dave Stevenson 


Re: [PATCH 08/15] drm/vc4: hdmi: Introduce a CEC clock

2020-12-18 Thread Dave Stevenson
Hi Maxime

On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
>
> While the BCM2835 had the CEC clock derived from the HSM clock, the
> BCM2711 has a dedicated parent clock for it.
>
> Let's introduce a separate clock for it so that we can handle both
> cases.
>
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 9 -
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 1 +
>  2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index b93ee3e26e2b..0debd22bc992 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -145,7 +145,7 @@ static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi 
> *vc4_hdmi)
>  * Set the clock divider: the hsm_clock rate and this divider
>  * setting will give a 40 kHz CEC clock.
>  */
> -   clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ;
> +   clk_cnt = clk_get_rate(vc4_hdmi->cec_clock) / CEC_CLOCK_FREQ;
> value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT;
> HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
>  }
> @@ -1740,6 +1740,7 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi 
> *vc4_hdmi)
> return PTR_ERR(vc4_hdmi->hsm_clock);
> }
> vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock;
> +   vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock;
>
> return 0;
>  }
> @@ -1833,6 +1834,12 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi 
> *vc4_hdmi)
> return PTR_ERR(vc4_hdmi->audio_clock);
> }
>
> +   vc4_hdmi->cec_clock = devm_clk_get(dev, "cec");
> +   if (IS_ERR(vc4_hdmi->cec_clock)) {
> +   DRM_ERROR("Failed to get CEC clock\n");
> +   return PTR_ERR(vc4_hdmi->cec_clock);
> +   }

Aren't we adding to the DT binding here and breaking backwards compatibility?
Admittedly CEC didn't work before (and was masked out) for vc5, but do
we need to worry about those with existing DT files that currently
work happily?

Otherwise I'm happy with the patch.

  Dave

> +
> vc4_hdmi->reset = devm_reset_control_get(dev, NULL);
> if (IS_ERR(vc4_hdmi->reset)) {
> DRM_ERROR("Failed to get HDMI reset line\n");
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 720914761261..adc4bf33ff15 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -155,6 +155,7 @@ struct vc4_hdmi {
> bool cec_tx_ok;
> bool cec_irq_was_rx;
>
> +   struct clk *cec_clock;
> struct clk *pixel_clock;
> struct clk *hsm_clock;
> struct clk *audio_clock;
> --
> 2.28.0
>


Re: [PATCH 06/15] drm/vc4: hdmi: Compute the CEC clock divider from the clock rate

2020-12-18 Thread Dave Stevenson
Hi Maxime

On Thu, 10 Dec 2020 at 13:47, Maxime Ripard  wrote:
>
> The CEC clock divider needs to output a frequency of 40kHz from the HSM
> rate on the BCM2835. The driver used to have a fixed frequency for it,
> but that changed and we now need to compute it dynamically to maintain
> the proper rate.
>
> Fixes: cd4cb49dc5bb ("drm/vc4: hdmi: Adjust HSM clock rate depending on pixel 
> rate")
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

(To be a total pedant it's still a fixed frequency on vc4, but it's
configurable via the variant entry).

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index eff3bac562c6..0c53d7427d15 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1586,6 +1586,7 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
>  {
> struct cec_connector_info conn_info;
> struct platform_device *pdev = vc4_hdmi->pdev;
> +   u16 clk_cnt;
> u32 value;
> int ret;
>
> @@ -1611,8 +1612,9 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
>  * divider: the hsm_clock rate and this divider setting will
>  * give a 40 kHz CEC clock.
>  */
> +   clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ;
> value |= VC4_HDMI_CEC_ADDR_MASK |
> -(4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
> +(clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
> HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
> ret = devm_request_threaded_irq(>dev, platform_get_irq(pdev, 0),
> vc4_cec_irq_handler,
> --
> 2.28.0
>


Re: [PATCH 04/15] drm/vc4: hdmi: Fix up CEC registers

2020-12-18 Thread Dave Stevenson
Hi Maxime & Dom

On Thu, 10 Dec 2020 at 13:46, Maxime Ripard  wrote:
>
> From: Dom Cobley 
>
> The commit 311e305fdb4e ("drm/vc4: hdmi: Implement a register layout
> abstraction") forgot one CEC register, and made a copy and paste mistake
> for another one. Fix those mistakes.
>
> Fixes: 311e305fdb4e ("drm/vc4: hdmi: Implement a register layout abstraction")
> Signed-off-by: Dom Cobley 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h 
> b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> index 013fd57febd8..20a1438a72cb 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> @@ -29,6 +29,7 @@ enum vc4_hdmi_field {
> HDMI_CEC_CPU_MASK_SET,
> HDMI_CEC_CPU_MASK_STATUS,
> HDMI_CEC_CPU_STATUS,
> +   HDMI_CEC_CPU_SET,
>
> /*
>  * Transmit data, first byte is low byte of the 32-bit reg.
> @@ -199,9 +200,10 @@ static const struct vc4_hdmi_register vc4_hdmi_fields[] 
> = {
> VC4_HDMI_REG(HDMI_TX_PHY_RESET_CTL, 0x02c0),
> VC4_HDMI_REG(HDMI_TX_PHY_CTL_0, 0x02c4),
> VC4_HDMI_REG(HDMI_CEC_CPU_STATUS, 0x0340),
> +   VC4_HDMI_REG(HDMI_CEC_CPU_SET, 0x0344),
> VC4_HDMI_REG(HDMI_CEC_CPU_CLEAR, 0x0348),
> VC4_HDMI_REG(HDMI_CEC_CPU_MASK_STATUS, 0x034c),
> -   VC4_HDMI_REG(HDMI_CEC_CPU_MASK_SET, 0x034c),
> +   VC4_HDMI_REG(HDMI_CEC_CPU_MASK_SET, 0x0350),
> VC4_HDMI_REG(HDMI_CEC_CPU_MASK_CLEAR, 0x0354),
> VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400),
>  };
> --
> 2.28.0
>


Re: [PATCH 02/15] drm/vc4: hdmi: Move hdmi reset to bind

2020-12-18 Thread Dave Stevenson
Hi Maxime & Dom

On Thu, 10 Dec 2020 at 13:46, Maxime Ripard  wrote:
>
> From: Dom Cobley 
>
> The hdmi reset got moved to a later point in the commit 9045e91a476b
> ("drm/vc4: hdmi: Add reset callback").
>
> However, the reset now occurs after vc4_hdmi_cec_init and so tramples
> the setup of registers like HDMI_CEC_CNTRL_1
>
> This only affects pi0-3 as on pi4 the cec registers are in a separate
> block

It does mean that this reset only happens once on bind rather than on
every pre_crtc_configure, but as this really is the big reset the
entire block I don't see it needing to be triggered on every
configure.

> Fixes: 9045e91a476b ("drm/vc4: hdmi: Add reset callback")
> Signed-off-by: Dom Cobley 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 8006bddc8fbb..3df1747dd917 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -773,9 +773,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct 
> drm_encoder *encoder,
> return;
> }
>
> -   if (vc4_hdmi->variant->reset)
> -   vc4_hdmi->variant->reset(vc4_hdmi);
> -
> if (vc4_hdmi->variant->phy_init)
> vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state);
>
> @@ -1865,6 +1862,9 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> vc4_hdmi->disable_wifi_frequencies =
> of_property_read_bool(dev->of_node, 
> "wifi-2.4ghz-coexistence");
>
> +   if (vc4_hdmi->variant->reset)
> +   vc4_hdmi->variant->reset(vc4_hdmi);
> +
> pm_runtime_enable(dev);
>
> drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
> --
> 2.28.0
>


Re: [PATCH 03/15] drm/vc4: hdmi: Fix register offset with longer CEC messages

2020-12-15 Thread Dave Stevenson
Hi Dom & Maxime

On Thu, 10 Dec 2020 at 13:46, Maxime Ripard  wrote:
>
> From: Dom Cobley 
>
> The code prior to 311e305fdb4e ("drm/vc4: hdmi: Implement a register
> layout abstraction") was relying on the fact that the register offset
> was incremented by 4 for each readl call. That worked since the register
> width is 4 bytes.
>
> However, since that commit the HDMI_READ macro is now taking an enum,
> and the offset doesn't increment by 4 but 1 now. Divide the index by 4
> to fix this.
>
> Fixes: 311e305fdb4e ("drm/vc4: hdmi: Implement a register layout abstraction")
> Signed-off-by: Dom Cobley 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 17 +++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 3df1747dd917..28b78ea885ea 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1434,13 +1434,20 @@ static irqreturn_t vc4_cec_irq_handler_thread(int 
> irq, void *priv)
>
>  static void vc4_cec_read_msg(struct vc4_hdmi *vc4_hdmi, u32 cntrl1)
>  {
> +   struct drm_device *dev = vc4_hdmi->connector.dev;
> struct cec_msg *msg = _hdmi->cec_rx_msg;
> unsigned int i;
>
> msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
> VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
> +
> +   if (msg->len > 16) {
> +   drm_err(dev, "Attempting to read too much data (%d)\n", 
> msg->len);
> +   return;
> +   }
> +
> for (i = 0; i < msg->len; i += 4) {
> -   u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + i);
> +   u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + (i >> 2));
>
> msg->msg[i] = val & 0xff;
> msg->msg[i + 1] = (val >> 8) & 0xff;
> @@ -1533,11 +1540,17 @@ static int vc4_hdmi_cec_adap_transmit(struct 
> cec_adapter *adap, u8 attempts,
>   u32 signal_free_time, struct cec_msg 
> *msg)
>  {
> struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
> +   struct drm_device *dev = vc4_hdmi->connector.dev;
> u32 val;
> unsigned int i;
>
> +   if (msg->len > 16) {
> +   drm_err(dev, "Attempting to transmit too much data (%d)\n", 
> msg->len);
> +   return -ENOMEM;
> +   }
> +
> for (i = 0; i < msg->len; i += 4)
> -   HDMI_WRITE(HDMI_CEC_TX_DATA_1 + i,
> +   HDMI_WRITE(HDMI_CEC_TX_DATA_1 + (i >> 2),
>(msg->msg[i]) |
>(msg->msg[i + 1] << 8) |
>(msg->msg[i + 2] << 16) |
> --
> 2.28.0
>


Re: [PATCH] drm/vc4: hdmi: Add a name to the codec DAI component

2020-10-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 15:46, Maxime Ripard  wrote:
>
> Since the components for a given device in ASoC are identified by their
> name, it makes sense to add one even though it's not strictly necessary.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 15a11cd4de25..a057db0d9baa 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -983,6 +983,7 @@ static const struct snd_soc_dapm_route 
> vc4_hdmi_audio_routes[] = {
>  };
>
>  static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = {
> +   .name   = "vc4-hdmi-codec-dai-component",
> .controls   = vc4_hdmi_audio_controls,
> .num_controls   = ARRAY_SIZE(vc4_hdmi_audio_controls),
> .dapm_widgets   = vc4_hdmi_audio_widgets,
> --
> 2.26.2
>


Re: [PATCH v5 80/80] ARM: dts: bcm2711: Enable the display pipeline

2020-10-06 Thread Dave Stevenson
Hi Maxime

On Tue, 6 Oct 2020 at 16:26, Maxime Ripard  wrote:
>
> Hi Dave,
>
> On Fri, Oct 02, 2020 at 04:57:05PM +0100, Dave Stevenson wrote:
> > Hi Maxime
> >
> > On Fri, 2 Oct 2020 at 16:19, Maxime Ripard  wrote:
> > >
> > > Hi Tim,
> > >
> > > On Thu, Oct 01, 2020 at 11:15:46AM +0100, Tim Gover wrote:
> > > > hdmi_enable_4k60=1 causes the firmware to select 3.3 GHz for the PLLC
> > > > VCO to support a core-frequency of 550 MHz which is the minimum
> > > > frequency required by the HVS at 4Kp60. The side effect is that if the
> > > > display clock requirements are lower than 4Kp60 then you will see
> > > > different core frequencies selected by DVFS.
> > > >
> > > > If enable_uart=1 and the mini-uart is selected (default unless
> > > > bluetooth is disabled) then the firmware will pin the core-frequency
> > > > to either core_freq max (500 or 550). Although, I think there is a way
> > > > of pinning it to a lower fixed frequency.
> > > >
> > > > The table in overclocking.md defines options for setting the maximum
> > > > core frequency but unless core_freq_min is specified DVFS will
> > > > automatically pick the lowest idle frequency required by the display
> > > > resolution.
> > >
> > > I'm wondering if there's some way to detect this from Linux? I guess it
> > > would be nice to be able to at least detect a broken config to warn /
> > > prevent an user that their situation is not going to be reliable / work
> > > really well (like if they have a 4k display without hdmi_enable_4kp60
> > > set, or the issue we're discussing here)
> >
> > The main filter in the firmware is the parameter
> > hdmi_pixel_freq_limit. That can either be set manually from
> > config.txt, or defaults appropriately based on hdmi_enable_4kp60.
> > Under firmware_kms [1] I read back those values to use as a filter
> > within crtc_mode_valid[2].
> > I can't think of a nice way of exposing that without the vc4 driver
> > gaining a DT link to the firmware, and that starts to get ugly.
>
> I had in mind something like if the clock driver can infer that somehow
> through some the boundaries reported by the firmware maybe? IIRC,
> hdmi_enable_4kp60 will already change the max frequency reported to
> 550MHz instead of 500MHz

Yes, that's plausible, but I don't know enough about the clock
infrastructure for advertising limits to know what works there.
Tell me what you need from the mailbox service and I'll see what I can do.

We do already have RPI_FIRMWARE_GET_MAX_CLOCK_RATE and
RPI_FIRMWARE_GET_MIN_CLOCK_RATE. It'd take a few minutes of staring at
the code (or a quick test) to confirm if they definitely are changed
for CORE clock by hdmi_enable_4kp60 - I think it does.

  Dave


Re: [PATCH v5 80/80] ARM: dts: bcm2711: Enable the display pipeline

2020-10-02 Thread Dave Stevenson
Hi Maxime

On Fri, 2 Oct 2020 at 16:19, Maxime Ripard  wrote:
>
> Hi Tim,
>
> On Thu, Oct 01, 2020 at 11:15:46AM +0100, Tim Gover wrote:
> > hdmi_enable_4k60=1 causes the firmware to select 3.3 GHz for the PLLC
> > VCO to support a core-frequency of 550 MHz which is the minimum
> > frequency required by the HVS at 4Kp60. The side effect is that if the
> > display clock requirements are lower than 4Kp60 then you will see
> > different core frequencies selected by DVFS.
> >
> > If enable_uart=1 and the mini-uart is selected (default unless
> > bluetooth is disabled) then the firmware will pin the core-frequency
> > to either core_freq max (500 or 550). Although, I think there is a way
> > of pinning it to a lower fixed frequency.
> >
> > The table in overclocking.md defines options for setting the maximum
> > core frequency but unless core_freq_min is specified DVFS will
> > automatically pick the lowest idle frequency required by the display
> > resolution.
>
> I'm wondering if there's some way to detect this from Linux? I guess it
> would be nice to be able to at least detect a broken config to warn /
> prevent an user that their situation is not going to be reliable / work
> really well (like if they have a 4k display without hdmi_enable_4kp60
> set, or the issue we're discussing here)

The main filter in the firmware is the parameter
hdmi_pixel_freq_limit. That can either be set manually from
config.txt, or defaults appropriately based on hdmi_enable_4kp60.
Under firmware_kms [1] I read back those values to use as a filter
within crtc_mode_valid[2].
I can't think of a nice way of exposing that without the vc4 driver
gaining a DT link to the firmware, and that starts to get ugly.

  Dave

[1] 
https://github.com/raspberrypi/linux/blob/rpi-5.9.y/drivers/gpu/drm/vc4/vc4_firmware_kms.c#L1859
[2] 
https://github.com/raspberrypi/linux/blob/rpi-5.9.y/drivers/gpu/drm/vc4/vc4_firmware_kms.c#L1077


Re: [PATCH -next] drm/v3d: Remove set but not used variable

2020-09-23 Thread Dave Stevenson
Hi

On Wed, 23 Sep 2020 at 08:53, Li Heng  wrote:
>
> This addresses the following gcc warning with "make W=1":
>
> drivers/gpu/drm/v3d/v3d_drv.c:73:32: warning:
> ‘v3d_v3d_pm_ops’ defined but not used [-Wunused-const-variable=]
>
> Reported-by: Hulk Robot 
> Signed-off-by: Li Heng 
> ---
>  drivers/gpu/drm/v3d/v3d_drv.c | 4 
>  1 file changed, 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
> index 9f7c261..05140db 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.c
> +++ b/drivers/gpu/drm/v3d/v3d_drv.c
> @@ -70,10 +70,6 @@ static int v3d_runtime_resume(struct device *dev)
>  }
>  #endif
>
> -static const struct dev_pm_ops v3d_v3d_pm_ops = {
> -   SET_RUNTIME_PM_OPS(v3d_runtime_suspend, v3d_runtime_resume, NULL)
> -};
> -

This looks to be the wrong approach, and I think a patch has got
dropped somewhere.

On our Raspberry Pi downstream vendor tree we have a patch [1] from
Eric that renames v3d_v3d_pm_ops to v3d_pm_ops (don't need the
duplicated suffix), and adds it to v3d_platform_driver. Why that never
made it through the mainline trees I don't know.

Eric: How good's your memory on this one?

Thanks
  Dave

[1] 
https://github.com/raspberrypi/linux/commit/fddfb26f6503835a3c6f7ca0175ce2260f60f67c

>  static int v3d_get_param_ioctl(struct drm_device *dev, void *data,
>struct drm_file *file_priv)
>  {
> --
> 2.7.4
>
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v5 79/80] drm/vc4: drv: Support BCM2711

2020-09-04 Thread Dave Stevenson
Hi Maxime

On Thu, 3 Sep 2020 at 09:03, Maxime Ripard  wrote:
>
> The BCM2711 has a reworked display pipeline, and the load tracker needs
> some adjustment to operate properly. Let's add a compatible for BCM2711
> and disable the load tracker until properly supported.
>
> Tested-by: Chanwoo Choi 
> Tested-by: Hoegeun Kwon 
> Tested-by: Stefan Wahren 
> Signed-off-by: Maxime Ripard 

I'm happy with this.
Potentially a case for having split it into two patches (make the load
tracker optional, and then use that option for the new compatible),
but I'm not convinced, so:

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_drv.c   |  1 +-
>  drivers/gpu/drm/vc4/vc4_drv.h   |  3 ++-
>  drivers/gpu/drm/vc4/vc4_kms.c   | 44 +++---
>  drivers/gpu/drm/vc4/vc4_plane.c |  5 -
>  4 files changed, 40 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index 9567d1019212..f1a5fd5dab6f 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -372,6 +372,7 @@ static int vc4_platform_drm_remove(struct platform_device 
> *pdev)
>  }
>
>  static const struct of_device_id vc4_of_match[] = {
> +   { .compatible = "brcm,bcm2711-vc5", },
> { .compatible = "brcm,bcm2835-vc4", },
> { .compatible = "brcm,cygnus-vc4", },
> {},
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 501a48a714d3..8c8d96b6289f 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -200,6 +200,9 @@ struct vc4_dev {
>
> int power_refcount;
>
> +   /* Set to true when the load tracker is supported. */
> +   bool load_tracker_available;
> +
> /* Set to true when the load tracker is active. */
> bool load_tracker_enabled;
>
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> index bfc7ddd49ac5..16e233e1406e 100644
> --- a/drivers/gpu/drm/vc4/vc4_kms.c
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -536,6 +536,9 @@ static int vc4_load_tracker_atomic_check(struct 
> drm_atomic_state *state)
> struct drm_plane *plane;
> int i;
>
> +   if (!vc4->load_tracker_available)
> +   return 0;
> +
> priv_state = drm_atomic_get_private_obj_state(state,
>   >load_tracker);
> if (IS_ERR(priv_state))
> @@ -683,12 +686,18 @@ int vc4_kms_load(struct drm_device *dev)
> struct vc4_dev *vc4 = to_vc4_dev(dev);
> struct vc4_ctm_state *ctm_state;
> struct vc4_load_tracker_state *load_state;
> +   bool is_vc5 = of_device_is_compatible(dev->dev->of_node,
> + "brcm,bcm2711-vc5");
> int ret;
>
> -   /* Start with the load tracker enabled. Can be disabled through the
> -* debugfs load_tracker file.
> -*/
> -   vc4->load_tracker_enabled = true;
> +   if (!is_vc5) {
> +   vc4->load_tracker_available = true;
> +
> +   /* Start with the load tracker enabled. Can be
> +* disabled through the debugfs load_tracker file.
> +*/
> +   vc4->load_tracker_enabled = true;
> +   }
>
> sema_init(>async_modeset, 1);
>
> @@ -702,8 +711,14 @@ int vc4_kms_load(struct drm_device *dev)
> return ret;
> }
>
> -   dev->mode_config.max_width = 2048;
> -   dev->mode_config.max_height = 2048;
> +   if (is_vc5) {
> +   dev->mode_config.max_width = 7680;
> +   dev->mode_config.max_height = 7680;
> +   } else {
> +   dev->mode_config.max_width = 2048;
> +   dev->mode_config.max_height = 2048;
> +   }
> +
> dev->mode_config.funcs = _mode_funcs;
> dev->mode_config.preferred_depth = 24;
> dev->mode_config.async_page_flip = true;
> @@ -718,14 +733,17 @@ int vc4_kms_load(struct drm_device *dev)
> drm_atomic_private_obj_init(dev, >ctm_manager, _state->base,
> _ctm_state_funcs);
>
> -   load_state = kzalloc(sizeof(*load_state), GFP_KERNEL);
> -   if (!load_state) {
> -   drm_atomic_private_obj_fini(>ctm_manager);
> -   return -ENOMEM;
> -   }
> +   if (vc4->load_tracker_available) {
> +   load_state = kzalloc(sizeof(*load_state), GFP_KERNEL);
> +   if (!load_state) {
> +   drm_atomi

Re: [PATCH v5 56/80] drm/vc4: hdmi: Add a set_timings callback

2020-09-04 Thread Dave Stevenson
Hi Maxime

On Thu, 3 Sep 2020 at 09:03, Maxime Ripard  wrote:
>
> Similarly to the previous patches, the timings setup in the HDMI controller
> of the BCM2711 is slightly different, mostly because it supports higher
> resolutions and thus needed more spaces for the various timings, resulting
> in the register layout changing.
>
> Let's add a callback for that as well.
>
> Tested-by: Chanwoo Choi 
> Tested-by: Hoegeun Kwon 
> Tested-by: Stefan Wahren 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 72 +++
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  4 ++-
>  2 files changed, 44 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 532618e02399..9e2bc6cb690e 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -369,12 +369,9 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi 
> *vc4_hdmi, bool enable)
> HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
>  }
>
> -static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
> +struct drm_display_mode *mode)
>  {
> -   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> -   struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> -   struct vc4_hdmi_encoder *vc4_encoder = _hdmi->encoder;
> -   bool debug_dump_regs = false;
> bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
> bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
> bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> @@ -392,6 +389,41 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> mode->crtc_vsync_end -
> interlaced,
> VC4_HDMI_VERTB_VBP));
> +
> +   HDMI_WRITE(HDMI_HORZA,
> +  (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
> +  (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
> +  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
> +VC4_HDMI_HORZA_HAP));
> +
> +   HDMI_WRITE(HDMI_HORZB,
> +  VC4_SET_FIELD((mode->htotal -
> + mode->hsync_end) * pixel_rep,
> +VC4_HDMI_HORZB_HBP) |
> +  VC4_SET_FIELD((mode->hsync_end -
> + mode->hsync_start) * pixel_rep,
> +VC4_HDMI_HORZB_HSP) |
> +  VC4_SET_FIELD((mode->hsync_start -
> + mode->hdisplay) * pixel_rep,
> +VC4_HDMI_HORZB_HFP));
> +
> +   HDMI_WRITE(HDMI_VERTA0, verta);
> +   HDMI_WRITE(HDMI_VERTA1, verta);
> +
> +   HDMI_WRITE(HDMI_VERTB0, vertb_even);
> +   HDMI_WRITE(HDMI_VERTB1, vertb);
> +
> +   HDMI_WRITE(HDMI_VID_CTL,
> +  (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
> +  (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
> +}
> +
> +static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +{
> +   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> +   struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> +   struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +   bool debug_dump_regs = false;
> int ret;
>
> ret = pm_runtime_get_sync(_hdmi->pdev->dev);
> @@ -435,33 +467,8 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
>VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
>VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
>
> -   HDMI_WRITE(HDMI_HORZA,
> -  (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
> -  (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
> -  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
> -VC4_HDMI_HORZA_HAP));
> -
> -   HDMI_WRITE(HDMI_HORZB,
> -  VC4_SET_FIELD((mode->htotal -
> - mode->hsync_end) * pixel_rep,
> -VC4_HDMI_HORZB_HBP) |
> -  VC4_SET_FIELD((mode->hsync_end -
> - mode->hsync_start) * pixel_rep,
> -VC4_HDMI_HORZB_HSP) |
> -  VC4_SET_FIELD((mode->hsync_start -
> - mode->hdisplay) * pixel_rep,
> -  

Re: [PATCH v5 55/80] drm/vc4: hdmi: Add a CSC setup callback

2020-09-04 Thread Dave Stevenson
Hi Maxime

On Thu, 3 Sep 2020 at 09:03, Maxime Ripard  wrote:
>
> Similarly to the previous patches, the CSC setup is slightly different in
> the BCM2711 than in the previous generations. Let's add a callback for it.
>
> Tested-by: Chanwoo Choi 
> Tested-by: Hoegeun Kwon 
> Tested-by: Stefan Wahren 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 70 +--
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  3 ++-
>  2 files changed, 45 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index c29376c3fd8a..532618e02399 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -334,6 +334,41 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder 
> *encoder)
> DRM_ERROR("Failed to release power domain: %d\n", ret);
>  }
>
> +static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
> +{
> +   u32 csc_ctl;
> +
> +   csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
> +   VC4_HD_CSC_CTL_ORDER);
> +
> +   if (enable) {
> +   /* CEA VICs other than #1 requre limited range RGB
> +* output unless overridden by an AVI infoframe.
> +* Apply a colorspace conversion to squash 0-255 down
> +* to 16-235.  The matrix here is:
> +*
> +* [ 0  0  0.8594 16]
> +* [ 0  0.8594 0  16]
> +* [ 0.8594 0  0  16]
> +* [ 0  0  0   1]
> +*/
> +   csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
> +   csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
> +   csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
> +VC4_HD_CSC_CTL_MODE);
> +
> +   HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
> +   HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
> +   HDMI_WRITE(HDMI_CSC_22_21, (0x6e0 << 16) | 0x000);
> +   HDMI_WRITE(HDMI_CSC_24_23, (0x100 << 16) | 0x000);
> +   HDMI_WRITE(HDMI_CSC_32_31, (0x000 << 16) | 0x6e0);
> +   HDMI_WRITE(HDMI_CSC_34_33, (0x100 << 16) | 0x000);
> +   }
> +
> +   /* The RGB order applies even when CSC is disabled. */
> +   HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
> +}
> +
>  static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
>  {
> struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> @@ -357,7 +392,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> mode->crtc_vsync_end -
> interlaced,
> VC4_HDMI_VERTB_VBP));
> -   u32 csc_ctl;
> int ret;
>
> ret = pm_runtime_get_sync(_hdmi->pdev->dev);
> @@ -428,41 +462,20 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
>(vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
>(hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
>
> -   csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
> -   VC4_HD_CSC_CTL_ORDER);
>
> if (vc4_encoder->hdmi_monitor &&
> -   drm_default_rgb_quant_range(mode) ==
> -   HDMI_QUANTIZATION_RANGE_LIMITED) {
> -   /* CEA VICs other than #1 requre limited range RGB
> -* output unless overridden by an AVI infoframe.
> -* Apply a colorspace conversion to squash 0-255 down
> -* to 16-235.  The matrix here is:
> -*
> -* [ 0  0  0.8594 16]
> -* [ 0  0.8594 0  16]
> -* [ 0.8594 0  0  16]
> -* [ 0  0  0   1]
> -*/
> -   csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
> -   csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
> -   csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
> -VC4_HD_CSC_CTL_MODE);
> +   drm_default_rgb_quant_range(mode) == 
> HDMI_QUANTIZATION_RANGE_LIMITED) {
> +   if (vc4_hdmi->variant->csc_setup)
> +   vc4_hdmi->variant->csc_setup(vc4_hdmi, true);
>
> -   HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
> -   HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
> -   HDMI_WRITE(HDMI_CSC_22_2

Re: [PATCH v5 13/80] drm/vc4: kms: Convert to for_each_new_crtc_state

2020-09-04 Thread Dave Stevenson
Hi Maxime

On Thu, 3 Sep 2020 at 09:02, Maxime Ripard  wrote:
>
> The vc4 atomic commit loop has an handrolled loop that is basically
> identical to for_each_new_crtc_state, let's convert it to that helper.
>
> Tested-by: Chanwoo Choi 
> Tested-by: Hoegeun Kwon 
> Tested-by: Stefan Wahren 
> Signed-off-by: Maxime Ripard 

Based on your comment to the previous revision, I'm happy.

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_kms.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> index 210cc2408087..a41d105d4e3c 100644
> --- a/drivers/gpu/drm/vc4/vc4_kms.c
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -152,14 +152,16 @@ vc4_atomic_complete_commit(struct drm_atomic_state 
> *state)
> struct drm_device *dev = state->dev;
> struct vc4_dev *vc4 = to_vc4_dev(dev);
> struct vc4_hvs *hvs = vc4->hvs;
> -   struct vc4_crtc *vc4_crtc;
> +   struct drm_crtc_state *new_crtc_state;
> +   struct drm_crtc *crtc;
> int i;
>
> -   for (i = 0; i < dev->mode_config.num_crtc; i++) {
> -   if (!state->crtcs[i].ptr || !state->crtcs[i].commit)
> +   for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
> +   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +
> +   if (!new_crtc_state->commit)
> continue;
>
> -   vc4_crtc = to_vc4_crtc(state->crtcs[i].ptr);
> vc4_hvs_mask_underrun(dev, vc4_crtc->channel);
> }
>
> --
> git-series 0.9.1


Re: [PATCH v5 75/80] drm/vc4: hdmi: Add pixel BVB clock control

2020-09-04 Thread Dave Stevenson
Hi Maxime

On Thu, 3 Sep 2020 at 09:03, Maxime Ripard  wrote:
>
> From: Hoegeun Kwon 
>
> The BCM2711 has another clock that needs to be ramped up depending on the
> pixel rate: the pixel BVB clock. Add the code to adjust that clock when
> changing the mode.
>
> Signed-off-by: Hoegeun Kwon 
> [Maxime: Changed the commit log, used clk_set_min_rate]
> Signed-off-by: Maxime Ripard 
> Link: 
> https://lore.kernel.org/r/20200901040759.29992-3-hoegeun.k...@samsung.com
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 23 +++
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  1 +
>  2 files changed, 24 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index ab7abb409de2..39508107dafd 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -54,6 +54,7 @@
>  #include "vc4_regs.h"
>
>  #define CEC_CLOCK_FREQ 4
> +#define VC4_HSM_MID_CLOCK 149985000

I didn't flag it earlier, but this is a bit of a weird name for the
define. I know it wants to be concise, but it made me do a double take
as to what it is for.
I'm currently applying all these patches to our Raspberry Pi tree and
actually CEC needs a fixed HSM on Pi0-3 to avoid recomputing all the
timings. So I have a VC4_HSM_CLOCK define which is the fixed clock
rate for Pi 0-3.
This one is more a threshold for HSM to control BVB, and my brain
starts to hurt over what it should be called.

Unless there are other comments around this patchset (and I hope to
read through the remaining ones today), then I don't consider it a
blocker, but we can probably do better as and when we add the next
threshold for 4k60.
My current understanding is that the clock has to be an integer divide
of 600MHz, and at least the pixel rate / 2, so the only link to HSM is
due to HSM being 101% of pixel rate, but I will try to find
confirmation of that.

>
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
>  {
> @@ -344,6 +345,7 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct 
> drm_encoder *encoder)
> HDMI_WRITE(HDMI_VID_CTL,
>HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
>
> +   clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
> clk_disable_unprepare(vc4_hdmi->hsm_clock);
> clk_disable_unprepare(vc4_hdmi->pixel_clock);
>
> @@ -516,6 +518,27 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct 
> drm_encoder *encoder)
> return;
> }
>
> +   /*
> +* FIXME: When the pixel freq is 594MHz (4k60), this needs to be setup
> +* at 150MHz.
> +*/

Typo here. For 4k60 we need 300MHz (pixel clock / 2)

Otherwise
Reviewed-by: Dave Stevenson 

> +   ret = clk_set_min_rate(vc4_hdmi->pixel_bvb_clock,
> +  (hsm_rate > VC4_HSM_MID_CLOCK ? 15000 : 
> 7500));
> +   if (ret) {
> +   DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret);
> +   clk_disable_unprepare(vc4_hdmi->hsm_clock);
> +   clk_disable_unprepare(vc4_hdmi->pixel_clock);
> +   return;
> +   }
> +
> +   ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
> +   if (ret) {
> +   DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret);
> +   clk_disable_unprepare(vc4_hdmi->hsm_clock);
> +   clk_disable_unprepare(vc4_hdmi->pixel_clock);
> +   return;
> +   }
> +
> if (vc4_hdmi->variant->reset)
> vc4_hdmi->variant->reset(vc4_hdmi);
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 34138e0dd4a6..59639b405b7f 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -119,6 +119,7 @@ struct vc4_hdmi {
> struct clk *pixel_clock;
> struct clk *hsm_clock;
> struct clk *audio_clock;
> +   struct clk *pixel_bvb_clock;
>
> struct debugfs_regset32 hdmi_regset;
> struct debugfs_regset32 hd_regset;
> --
> git-series 0.9.1


Re: [PATCH 3/3] drm/vc4: hdmi: Add pixel bvb clock control

2020-08-28 Thread Dave Stevenson
Hi Maxime, Stefan, and Hoegeun

On Fri, 28 Aug 2020 at 16:25, Maxime Ripard  wrote:
>
> Hi,
>
> On Fri, Aug 28, 2020 at 02:45:49PM +0200, Stefan Wahren wrote:
> > Am 28.08.20 um 08:30 schrieb Hoegeun Kwon:
> > > On 8/27/20 6:49 PM, Stefan Wahren wrote:
> > >> Am 27.08.20 um 06:35 schrieb Hoegeun Kwon:
> > >>> Hi Stefan,
> > >>>
> > >>> Thank you for your review.
> > >>>
> > >>>
> > >>> On 8/26/20 7:04 PM, Stefan Wahren wrote:
> >  Hi Hoeguen,
> > 
> >  Am 21.08.20 um 09:10 schrieb Hoegeun Kwon:
> > > There is a problem that the output does not work at a resolution
> > > exceeding FHD. To solve this, we need to adjust the bvb clock at a
> > > resolution exceeding FHD.
> >  this patch introduces a mandatory clock, please update
> >  brcm,bcm2835-hdmi.yaml first.
> > 
> >  Is this clock physically available on BCM283x or only on BCM2711?
> > >>> As far as I know, BCM2711 raspberry pi 4 supports 4k,
> > >>>
> > >>> don't supported on pi 3 and pi 3+.
> > >>>
> > >>> Since 4k is not supported in versions prior to Raspberry Pi 4,
> > >>>
> > >>> I don't think we need to modify the bvb clock.
> > >>>
> > >>>
> > >>> So I think it is better to update 'brcm,bcm2711-hdmi.yaml'
> > >>>
> > >>> instead of 'brcm,bcm2835-hdmi.yaml'.
> > >> You are correct please update only brcm,bcm2711-hdmi.yaml.
> > >>
> > >> My concern was that the function vc4_hdmi_encoder_pre_crtc_configure()
> > >> is called on a non-bcm2711 platform or on a Raspberry Pi 4 with an older
> > >> DTB. So making the BVB clock optional might be better?
> > > You are right, if use old dtb, we have a problem with the hdmi driver.
> > >
> > > So how about modifying it like this?
> > >
> > > @@ -1614,8 +1614,8 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi
> > > *vc4_hdmi)
> > >
> > >  vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb");
> > >  if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) {
> > > -   DRM_ERROR("Failed to get pixel bvb clock\n");
> > > -   return PTR_ERR(vc4_hdmi->pixel_bvb_clock);
> > > +   DRM_WARN("Failed to get pixel bvb clock\n");
> > > +   vc4_hdmi->pixel_bvb_clock = NULL;
> > >  }
> >
> > i think the better solution would be devm_clk_get_optional(), which
> > return NULL in case the clock doesn't exist.
>
> It's not really optional though. BCM2711 will require it in order to run
> properly (as Hoegeun experienced), and the previous SoCs won't.
>
> If we use clk_get_optional and that the DT is missing the clock on the
> BCM2711, we will silently ignore it which doesn't sound great.

Am I missing something here? (I know I missed this earlier)
We're in vc5_hdmi_init_resources, which is inherently bcm2711 only.
bcm283x will go through vc4_hdmi_init_resources.

As long as vc4_hdmi_init_resources has left vc4_hdmi->pixel_bvb_clock
at NULL, then the clock framework will be happy to do a nop.

For BCM2711 an old DT would have issues, but, as Maxime has stated, no
binding or upstream DTB has been merged yet, so it can be made
mandatory.
Making it optional drops you back on whatever the firmware might have
set it to, which may be sufficient for some resolutions but not
others.

  Dave


Re: [PATCH 3/3] drm/vc4: hdmi: Add pixel bvb clock control

2020-08-28 Thread Dave Stevenson
Hi Stefan & Hoegeun

On Wed, 26 Aug 2020 at 11:04, Stefan Wahren  wrote:
>
> Hi Hoeguen,
>
> Am 21.08.20 um 09:10 schrieb Hoegeun Kwon:
> > There is a problem that the output does not work at a resolution
> > exceeding FHD. To solve this, we need to adjust the bvb clock at a
> > resolution exceeding FHD.
>
> this patch introduces a mandatory clock, please update
> brcm,bcm2835-hdmi.yaml first.
>
> Is this clock physically available on BCM283x or only on BCM2711?
>
> I'm a little bit afraid, this change could break with older firmware
> versions on BCM283x.

Thanks for your keen eye on these things.

BVB only exists on 2711, not 283x.

It runs at 2 pixels/clock, must be an integer divider of I believe
600MHz, and between 75 and 300MHz.
This aim of this patch is fine as we currently only go up to 4k30, but
for 4k60 the BVB will need to be set to 300MHz.

Thanks
  Dave

> Best regards
> Stefan
>
> >
> > Signed-off-by: Hoegeun Kwon 
> > ---
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +
> >  drivers/gpu/drm/vc4/vc4_hdmi.h |  1 +
> >  2 files changed, 26 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index 95ec5eedea39..eb3192d1fd86 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -80,6 +80,7 @@
> >  # define VC4_HD_M_ENABLE BIT(0)
> >
> >  #define CEC_CLOCK_FREQ 4
> > +#define VC4_HSM_MID_CLOCK 149985000
> >
> >  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> >  {
> > @@ -380,6 +381,7 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct 
> > drm_encoder *encoder)
> >   HDMI_WRITE(HDMI_VID_CTL,
> >  HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
> >
> > + clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
> >   clk_disable_unprepare(vc4_hdmi->hsm_clock);
> >   clk_disable_unprepare(vc4_hdmi->pixel_clock);
> >
> > @@ -638,6 +640,23 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct 
> > drm_encoder *encoder)
> >   return;
> >   }
> >
> > + ret = clk_set_rate(vc4_hdmi->pixel_bvb_clock,
> > + (hsm_rate > VC4_HSM_MID_CLOCK ? 15000 : 
> > 7500));
> > + if (ret) {
> > + DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret);
> > + clk_disable_unprepare(vc4_hdmi->hsm_clock);
> > + clk_disable_unprepare(vc4_hdmi->pixel_clock);
> > + return;
> > + }
> > +
> > + ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
> > + if (ret) {
> > + DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret);
> > + clk_disable_unprepare(vc4_hdmi->hsm_clock);
> > + clk_disable_unprepare(vc4_hdmi->pixel_clock);
> > + return;
> > + }
> > +
> >   if (vc4_hdmi->variant->reset)
> >   vc4_hdmi->variant->reset(vc4_hdmi);
> >
> > @@ -1593,6 +1612,12 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi 
> > *vc4_hdmi)
> >   return PTR_ERR(vc4_hdmi->audio_clock);
> >   }
> >
> > + vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb");
> > + if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) {
> > + DRM_ERROR("Failed to get pixel bvb clock\n");
> > + return PTR_ERR(vc4_hdmi->pixel_bvb_clock);
> > + }
> > +
> >   vc4_hdmi->reset = devm_reset_control_get(dev, NULL);
> >   if (IS_ERR(vc4_hdmi->reset)) {
> >   DRM_ERROR("Failed to get HDMI reset line\n");
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> > index 0806c6d9f24e..63c6f8bddf1d 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> > @@ -147,6 +147,7 @@ struct vc4_hdmi {
> >   struct clk *pixel_clock;
> >   struct clk *hsm_clock;
> >   struct clk *audio_clock;
> > + struct clk *pixel_bvb_clock;
> >
> >   struct reset_control *reset;
> >
>


Re: [PATCH v4 13/78] drm/vc4: kms: Convert to for_each_new_crtc_state

2020-07-29 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:42, Maxime Ripard  wrote:
>
> The vc4 atomic commit loop has an handrolled loop that is basically
> identical to for_each_new_crtc_state, let's convert it to that helper.
>
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/vc4_kms.c |  9 -
>  1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> index 210cc2408087..717673b18132 100644
> --- a/drivers/gpu/drm/vc4/vc4_kms.c
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -152,14 +152,13 @@ vc4_atomic_complete_commit(struct drm_atomic_state 
> *state)
> struct drm_device *dev = state->dev;
> struct vc4_dev *vc4 = to_vc4_dev(dev);
> struct vc4_hvs *hvs = vc4->hvs;
> -   struct vc4_crtc *vc4_crtc;
> +   struct drm_crtc_state *new_crtc_state;
> +   struct drm_crtc *crtc;
> int i;
>
> -   for (i = 0; i < dev->mode_config.num_crtc; i++) {
> -   if (!state->crtcs[i].ptr || !state->crtcs[i].commit)
> -   continue;
> +   for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
> +   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);

for_each_new_crtc_in_state doesn't check !state->crtcs[i].commit as
the hand rolled loop did. Sorry, this is my lack of knowledge, but
does that actually make any real difference?

I see nothing wrong in calling vc4_hvs_mask_underrun multiple times
anyway, so it's most likely going to be harmless anyway, but wanted to
query it.

  Dave

>
> -   vc4_crtc = to_vc4_crtc(state->crtcs[i].ptr);
> vc4_hvs_mask_underrun(dev, vc4_crtc->channel);
> }
>
> --
> git-series 0.9.1


Re: [PATCH v4 29/78] drm/vc4: crtc: Add a delay after disabling the PixelValve output

2020-07-29 Thread Dave Stevenson
On Wed, 29 Jul 2020 at 15:42, Maxime Ripard  wrote:
>
> Hi,
>
> On Wed, Jul 29, 2020 at 03:09:21PM +0100, Dave Stevenson wrote:
> > On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
> > >
> > > In order to avoid pixels getting stuck in the (unflushable) FIFO between
> > > the HVS and the PV, we need to add some delay after disabling the PV 
> > > output
> > > and before disabling the HDMI controller. 20ms seems to be good enough so
> > > let's use that.
> > >
> > > Signed-off-by: Maxime Ripard 
> > > ---
> > >  drivers/gpu/drm/vc4/vc4_crtc.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c 
> > > b/drivers/gpu/drm/vc4/vc4_crtc.c
> > > index d0b326e1df0a..7b178d67187f 100644
> > > --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> > > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> > > @@ -403,6 +403,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc 
> > > *crtc,
> > > ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
> > > WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
> > >
> > > +   mdelay(20);
> >
> > mdelay for 20ms seems a touch unfriendly as it's a busy wait. Can we
> > not msleep instead?
>
> Since the timing was fairly critical, sleeping didn't seem like a good
> solution since there's definitely some chance you overshoot and end up
> with a higher time than the one you targeted.

Fair enough. I know timing is "entertaining" around some of the 2711
pipeline setup.

Reviewed-by: Dave Stevenson 


Re: [PATCH v4 23/78] drm/vc4: crtc: Move the HVS gamma LUT setup to our init function

2020-07-29 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> Since most of the HVS channel is setup in the init function, let's move the
> gamma setup there too. As this makes the HVS mode_set function empty, let's
> remove it in the process.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c |  2 +-
>  drivers/gpu/drm/vc4/vc4_drv.h  |  1 +-
>  drivers/gpu/drm/vc4/vc4_hvs.c  | 59 +--
>  drivers/gpu/drm/vc4/vc4_txp.c  |  1 +-
>  4 files changed, 16 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 181d3fd57bc7..284a85b9d7d4 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -379,8 +379,6 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
>  static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
>  {
> vc4_crtc_config_pv(crtc);
> -
> -   vc4_hvs_mode_set_nofb(crtc);
>  }
>
>  static void require_hvs_enabled(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 4126506b3a69..dfcc684f5d28 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -904,7 +904,6 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct 
> drm_crtc_state *state);
>  void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state 
> *old_state);
>  void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state 
> *old_state);
>  void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state 
> *state);
> -void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc);
>  void vc4_hvs_dump_state(struct drm_device *dev);
>  void vc4_hvs_unmask_underrun(struct drm_device *dev, int channel);
>  void vc4_hvs_mask_underrun(struct drm_device *dev, int channel);
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> index 78bb1c0b0b76..c7de77afbf0a 100644
> --- a/drivers/gpu/drm/vc4/vc4_hvs.c
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -201,6 +201,8 @@ static int vc4_hvs_init_channel(struct vc4_dev *vc4, 
> struct drm_crtc *crtc,
>  {
> struct vc4_crtc_state *vc4_crtc_state = 
> to_vc4_crtc_state(crtc->state);
> unsigned int chan = vc4_crtc_state->assigned_channel;
> +   bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
> +   u32 dispbkgndx;
> u32 dispctrl;
>
> /* Turn on the scaler, which will wait for vstart to start
> @@ -225,6 +227,20 @@ static int vc4_hvs_init_channel(struct vc4_dev *vc4, 
> struct drm_crtc *crtc,
>
> HVS_WRITE(SCALER_DISPCTRLX(chan), dispctrl);
>
> +   dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(chan));
> +   dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
> +   dispbkgndx &= ~SCALER_DISPBKGND_INTERLACE;
> +
> +   HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx |
> + SCALER_DISPBKGND_AUTOHS |
> + ((!vc4->hvs->hvs5) ? SCALER_DISPBKGND_GAMMA : 0) |
> + (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
> +
> +   /* Reload the LUT, since the SRAMs would have been disabled if
> +* all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
> +*/
> +   vc4_hvs_lut_load(crtc);
> +
> return 0;
>  }
>
> @@ -421,49 +437,6 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
> }
>  }
>
> -void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc)
> -{
> -   struct drm_device *dev = crtc->dev;
> -   struct vc4_dev *vc4 = to_vc4_dev(dev);
> -   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;
> -
> -   if (vc4_state->assigned_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 disable the 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)

Re: [PATCH v4 14/78] drm/vc4: crtc: Assign output to channel automatically

2020-07-29 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:42, Maxime Ripard  wrote:
>
> The HVS found in the BCM2711 has 6 outputs and 3 FIFOs, with each output
> being connected to a pixelvalve, and some muxing between the FIFOs and
> outputs.
>
> Any output cannot feed from any FIFO though, and they all have a bunch of
> constraints.
>
> In order to support this, let's store the possible FIFOs each output can be
> assigned to in the vc4_crtc_data, and use that information at atomic_check
> time to iterate over all the CRTCs enabled and assign them FIFOs.
>
> The channel assigned is then set in the vc4_crtc_state so that the rest of
> the driver can use it.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c |  12 +-
>  drivers/gpu/drm/vc4/vc4_drv.h  |   7 +-
>  drivers/gpu/drm/vc4/vc4_hvs.c  |  28 ++
>  drivers/gpu/drm/vc4/vc4_kms.c  | 167 +-
>  drivers/gpu/drm/vc4/vc4_regs.h |  10 ++-
>  drivers/gpu/drm/vc4/vc4_txp.c  |   1 +-
>  6 files changed, 199 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index fe2e5675aed4..b7e47ce1476c 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -88,6 +88,7 @@ static bool vc4_crtc_get_scanout_position(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_crtc_state = 
> to_vc4_crtc_state(crtc->state);
> unsigned int cob_size;
> u32 val;
> int fifo_lines;
> @@ -104,7 +105,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc 
> *crtc,
>  * Read vertical scanline which is currently composed for our
>  * pixelvalve by the HVS, and also the scaler status.
>  */
> -   val = HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel));
> +   val = HVS_READ(SCALER_DISPSTATX(vc4_crtc_state->assigned_channel));
>
> /* Get optional system timestamp after query. */
> if (etime)
> @@ -124,7 +125,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc 
> *crtc,
> *hpos += mode->crtc_htotal / 2;
> }
>
> -   cob_size = vc4_crtc_get_cob_allocation(vc4, vc4_crtc->channel);
> +   cob_size = vc4_crtc_get_cob_allocation(vc4, 
> vc4_crtc_state->assigned_channel);
> /* This is the offset we need for translating hvs -> pv scanout pos. 
> */
> fifo_lines = cob_size / mode->crtc_hdisplay;
>
> @@ -520,7 +521,7 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc 
> *vc4_crtc)
> struct drm_device *dev = crtc->dev;
> struct vc4_dev *vc4 = to_vc4_dev(dev);
> struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
> -   u32 chan = vc4_crtc->channel;
> +   u32 chan = vc4_state->assigned_channel;
> unsigned long flags;
>
> spin_lock_irqsave(>event_lock, flags);
> @@ -719,6 +720,7 @@ struct drm_crtc_state *vc4_crtc_duplicate_state(struct 
> drm_crtc *crtc)
> old_vc4_state = to_vc4_crtc_state(crtc->state);
> vc4_state->feed_txp = old_vc4_state->feed_txp;
> vc4_state->margins = old_vc4_state->margins;
> +   vc4_state->assigned_channel = old_vc4_state->assigned_channel;
>
> __drm_atomic_helper_crtc_duplicate_state(crtc, _state->base);
> return _state->base;
> @@ -779,6 +781,7 @@ static const struct drm_crtc_helper_funcs 
> vc4_crtc_helper_funcs = {
>
>  static const struct vc4_pv_data bcm2835_pv0_data = {
> .base = {
> +   .hvs_available_channels = BIT(0),
> .hvs_output = 0,
> },
> .debugfs_name = "crtc0_regs",
> @@ -791,6 +794,7 @@ static const struct vc4_pv_data bcm2835_pv0_data = {
>
>  static const struct vc4_pv_data bcm2835_pv1_data = {
> .base = {
> +   .hvs_available_channels = BIT(2),
> .hvs_output = 2,
> },
> .debugfs_name = "crtc1_regs",
> @@ -803,6 +807,7 @@ static const struct vc4_pv_data bcm2835_pv1_data = {
>
>  static const struct vc4_pv_data bcm2835_pv2_data = {
> .base = {
> +   .hvs_available_channels = BIT(1),
> .hvs_output = 1,
> },
> .debugfs_name = "crtc2_regs",
> @@ -866,7 +871,6 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
> *vc4_crtc,
> drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
> 

Re: [PATCH v4 29/78] drm/vc4: crtc: Add a delay after disabling the PixelValve output

2020-07-29 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> In order to avoid pixels getting stuck in the (unflushable) FIFO between
> the HVS and the PV, we need to add some delay after disabling the PV output
> and before disabling the HDMI controller. 20ms seems to be good enough so
> let's use that.
>
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index d0b326e1df0a..7b178d67187f 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -403,6 +403,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
> ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
> WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
>
> +   mdelay(20);

mdelay for 20ms seems a touch unfriendly as it's a busy wait. Can we
not msleep instead?

  Dave

> +
> if (vc4_encoder->post_crtc_disable)
> vc4_encoder->post_crtc_disable(encoder);
>
> --
> git-series 0.9.1


Re: [PATCH v4 78/78] ARM: dts: bcm2711: Enable the display pipeline

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> Now that all the drivers have been adjusted for it, let's bring in the
> necessary device tree changes.

Possibly a comment to say that the VEC and PV3 are deliberately NOT
enabled as the VEC requires further very specific clock setup changes?

> Signed-off-by: Maxime Ripard 

Otherwise
Reviewed-by: Dave Stevenson 

> ---
>  arch/arm/boot/dts/bcm2711-rpi-4-b.dts |  46 +++-
>  arch/arm/boot/dts/bcm2711.dtsi| 115 ++-
>  2 files changed, 160 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts 
> b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
> index 222d7825e1ab..b93eb30e1ddb 100644
> --- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
> +++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
> @@ -68,6 +68,14 @@
> };
>  };
>
> + {
> +   status = "okay";
> +};
> +
> + {
> +   status = "okay";
> +};
> +
>   {
> firmware_clocks: clocks {
> compatible = "raspberrypi,firmware-clocks";
> @@ -163,6 +171,36 @@
>   "RGMII_TXD3";
>  };
>
> + {
> +   clocks = <_clocks 13>, < 0>;
> +   status = "okay";
> +};
> +
> + {
> +   clocks = <_clocks 13>, < 1>;
> +   status = "okay";
> +};
> +
> + {
> +   clocks = <_clocks 4>;
> +};
> +
> + {
> +   status = "okay";
> +};
> +
> + {
> +   status = "okay";
> +};
> +
> + {
> +   status = "okay";
> +};
> +
> + {
> +   status = "okay";
> +};
> +
>   {
> pinctrl-names = "default";
> pinctrl-0 = <_0_gpio40 _1_gpio41>;
> @@ -231,3 +269,11 @@
>   {
> interrupts = ;
>  };
> +
> + {
> +   status = "okay";
> +};
> +
> + {
> +   status = "disabled";
> +};
> diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
> index 00bcaed1be32..e637378650f6 100644
> --- a/arch/arm/boot/dts/bcm2711.dtsi
> +++ b/arch/arm/boot/dts/bcm2711.dtsi
> @@ -12,6 +12,11 @@
>
> interrupt-parent = <>;
>
> +   vc4: gpu {
> +   compatible = "brcm,bcm2711-vc5";
> +   status = "disabled";
> +   };
> +
> clk_108MHz: clk-108M {
> #clock-cells = <0>;
> compatible = "fixed-clock";
> @@ -238,6 +243,27 @@
> status = "disabled";
> };
>
> +   pixelvalve0: pixelvalve@7e206000 {
> +   compatible = "brcm,bcm2711-pixelvalve0";
> +   reg = <0x7e206000 0x100>;
> +   interrupts = ;
> +   status = "disabled";
> +   };
> +
> +   pixelvalve1: pixelvalve@7e207000 {
> +   compatible = "brcm,bcm2711-pixelvalve1";
> +   reg = <0x7e207000 0x100>;
> +   interrupts = ;
> +   status = "disabled";
> +   };
> +
> +   pixelvalve2: pixelvalve@7e20a000 {
> +   compatible = "brcm,bcm2711-pixelvalve2";
> +   reg = <0x7e20a000 0x100>;
> +   interrupts = ;
> +   status = "disabled";
> +   };
> +
> pwm1: pwm@7e20c800 {
> compatible = "brcm,bcm2835-pwm";
> reg = <0x7e20c800 0x28>;
> @@ -248,10 +274,25 @@
> status = "disabled";
> };
>
> -   hvs@7e40 {
> +   pixelvalve4: pixelvalve@7e216000 {
> +   compatible = "brcm,bcm2711-pixelvalve4";
> +   reg = <0x7e216000 0x100>;
> +   interrupts = ;
> +   status = "disabled";
> +   };
> +
> +   hvs: hvs@7e40 {
> +   compatible = "brcm,bcm2711-hvs";
> interrupts = ;
> };
>
> +   pixelvalve3: pixelvalve@7ec12000 {
> +   compatible = "brcm,bcm2711-pixelvalve3";
> +   reg = <0x7ec12000 0x100>;
> +   interrupts = ;
> +   status = "disabled";
> +  

Re: [PATCH v4 77/78] drm/vc4: drv: Support BCM2711

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The BCM2711 has a reworked display pipeline, and the load tracker needs
> some adjustement to operate properly. Let's add a compatible for BCM2711

s/adjustement/adjustment

> and disable the load tracker until properly supported.
>
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/vc4_drv.c   |  1 +-
>  drivers/gpu/drm/vc4/vc4_drv.h   |  3 ++-
>  drivers/gpu/drm/vc4/vc4_kms.c   | 42 +++---
>  drivers/gpu/drm/vc4/vc4_plane.c |  5 -
>  4 files changed, 38 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index 9567d1019212..f1a5fd5dab6f 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -372,6 +372,7 @@ static int vc4_platform_drm_remove(struct platform_device 
> *pdev)
>  }
>
>  static const struct of_device_id vc4_of_match[] = {
> +   { .compatible = "brcm,bcm2711-vc5", },
> { .compatible = "brcm,bcm2835-vc4", },
> { .compatible = "brcm,cygnus-vc4", },
> {},
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 501a48a714d3..8c8d96b6289f 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -200,6 +200,9 @@ struct vc4_dev {
>
> int power_refcount;
>
> +   /* Set to true when the load tracker is supported. */
> +   bool load_tracker_available;
> +
> /* Set to true when the load tracker is active. */
> bool load_tracker_enabled;
>
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> index 7c8a87339959..ae479f988666 100644
> --- a/drivers/gpu/drm/vc4/vc4_kms.c
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -532,6 +532,9 @@ static int vc4_load_tracker_atomic_check(struct 
> drm_atomic_state *state)
> struct drm_plane *plane;
> int i;
>
> +   if (!vc4->load_tracker_available)
> +   return 0;
> +
> priv_state = drm_atomic_get_private_obj_state(state,
>   >load_tracker);
> if (IS_ERR(priv_state))
> @@ -681,10 +684,14 @@ int vc4_kms_load(struct drm_device *dev)
> struct vc4_load_tracker_state *load_state;
> int ret;
>
> -   /* Start with the load tracker enabled. Can be disabled through the
> -* debugfs load_tracker file.
> -*/
> -   vc4->load_tracker_enabled = true;
> +   if (!of_device_is_compatible(dev->dev->of_node, "brcm,bcm2711-vc5")) {

Is it better to look up the compatible string, or pass something via
the .data element of the of_device_id table? Probably down to personal
preference?

> +   vc4->load_tracker_available = true;
> +
> +   /* Start with the load tracker enabled. Can be
> +* disabled through the debugfs load_tracker file.
> +*/
> +   vc4->load_tracker_enabled = true;
> +   }
>
> sema_init(>async_modeset, 1);
>
> @@ -698,8 +705,14 @@ int vc4_kms_load(struct drm_device *dev)
> return ret;
> }
>
> -   dev->mode_config.max_width = 2048;
> -   dev->mode_config.max_height = 2048;
> +   if (of_device_is_compatible(dev->dev->of_node, "brcm,bcm2711-vc5")) {

We're making the same of_device_is_compatible call twice within
vc4_kms_load. Set a flag based on it and check that instead?

  Dave

> +   dev->mode_config.max_width = 7680;
> +   dev->mode_config.max_height = 7680;
> +   } else {
> +   dev->mode_config.max_width = 2048;
> +   dev->mode_config.max_height = 2048;
> +   }
> +
> dev->mode_config.funcs = _mode_funcs;
> dev->mode_config.preferred_depth = 24;
> dev->mode_config.async_page_flip = true;
> @@ -714,14 +727,17 @@ int vc4_kms_load(struct drm_device *dev)
> drm_atomic_private_obj_init(dev, >ctm_manager, _state->base,
> _ctm_state_funcs);
>
> -   load_state = kzalloc(sizeof(*load_state), GFP_KERNEL);
> -   if (!load_state) {
> -   drm_atomic_private_obj_fini(>ctm_manager);
> -   return -ENOMEM;
> -   }
> +   if (vc4->load_tracker_available) {
> +   load_state = kzalloc(sizeof(*load_state), GFP_KERNEL);
> +   if (!load_state) {
> +   drm_atomic_private_obj_fini(>ctm_manager);
> +   return -ENOMEM;
> +   }
>
> -   drm_atomic_private_obj_init(dev, >load_tracker, 
> _state->base,
> -   _load_tracker_state_funcs);
> +   drm_atomic_private_obj_init(dev, >load_tracker,
> +   _state->base,
> +   _load_tracker_state_funcs);
> +   }
>
> drm_mode_config_reset(dev);
>
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c 

Re: [PATCH v4 74/78] drm/vc4: hdmi: Support the BCM2711 HDMI controllers

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> Now that the driver is ready for it, let's bring in the HDMI controllers
> variants for the BCM2711.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c  | 278 +-
>  drivers/gpu/drm/vc4/vc4_hdmi.h  |  36 ++-
>  drivers/gpu/drm/vc4/vc4_hdmi_phy.c  | 480 +-
>  drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 201 -
>  drivers/gpu/drm/vc4/vc4_regs.h  |   2 +-
>  5 files changed, 997 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 37463b016b47..d5ba0b1b73a9 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -43,6 +43,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -53,6 +54,31 @@
>  #include "vc4_hdmi_regs.h"
>  #include "vc4_regs.h"
>
> +#define VC5_HDMI_HORZA_HFP_SHIFT   16
> +#define VC5_HDMI_HORZA_HFP_MASKVC4_MASK(28, 16)
> +#define VC5_HDMI_HORZA_VPOSBIT(15)
> +#define VC5_HDMI_HORZA_HPOSBIT(14)
> +#define VC5_HDMI_HORZA_HAP_SHIFT   0
> +#define VC5_HDMI_HORZA_HAP_MASKVC4_MASK(13, 0)
> +
> +#define VC5_HDMI_HORZB_HBP_SHIFT   16
> +#define VC5_HDMI_HORZB_HBP_MASKVC4_MASK(26, 16)
> +#define VC5_HDMI_HORZB_HSP_SHIFT   0
> +#define VC5_HDMI_HORZB_HSP_MASKVC4_MASK(10, 0)
> +
> +#define VC5_HDMI_VERTA_VSP_SHIFT   24
> +#define VC5_HDMI_VERTA_VSP_MASKVC4_MASK(28, 24)
> +#define VC5_HDMI_VERTA_VFP_SHIFT   16
> +#define VC5_HDMI_VERTA_VFP_MASKVC4_MASK(22, 16)
> +#define VC5_HDMI_VERTA_VAL_SHIFT   0
> +#define VC5_HDMI_VERTA_VAL_MASKVC4_MASK(12, 0)
> +
> +#define VC5_HDMI_VERTB_VSPO_SHIFT  16
> +#define VC5_HDMI_VERTB_VSPO_MASK   VC4_MASK(29, 16)
> +
> +# define VC4_HD_M_SW_RST   BIT(2)
> +# define VC4_HD_M_ENABLE   BIT(0)
> +
>  #define CEC_CLOCK_FREQ 4
>
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> @@ -82,6 +108,16 @@ static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
> HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
>  }
>
> +static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
> +{
> +   reset_control_reset(vc4_hdmi->reset);
> +
> +   HDMI_WRITE(HDMI_DVP_CTL, 0);
> +
> +   HDMI_WRITE(HDMI_CLOCK_STOP,
> +  HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
> +}
> +
>  static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -391,6 +427,45 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi 
> *vc4_hdmi, bool enable)
> HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
>  }
>
> +static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
> +{
> +   u32 csc_ctl;
> +
> +   csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || 
> USE_RGB_TO_YCBCR */
> +
> +   if (enable) {
> +   /* CEA VICs other than #1 requre limited range RGB
> +* output unless overridden by an AVI infoframe.
> +* Apply a colorspace conversion to squash 0-255 down
> +* to 16-235.  The matrix here is:
> +*
> +* [ 0.8594 0  0  16]
> +* [ 0  0.8594 0  16]
> +* [ 0  0  0.8594 16]
> +* [ 0  0  0   1]
> +* Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +*/
> +   HDMI_WRITE(HDMI_CSC_12_11, (0x << 16) | 0x1b80);
> +   HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x);
> +   HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x);
> +   HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x);
> +   HDMI_WRITE(HDMI_CSC_32_31, (0x << 16) | 0x);
> +   HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
> +   } else {
> +   /* Still use the matrix for full range, but make it unity.
> +* Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +*/
> +   HDMI_WRITE(HDMI_CSC_12_11, (0x << 16) | 0x2000);
> +   HDMI_WRITE(HDMI_CSC_14_13, (0x << 16) | 0x);
> +

Re: [PATCH v4 73/78] drm/vc4: hdmi: Switch to blank pixels when disabled

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> In order to avoid pixels getting stuck in an unflushable FIFO, we need when
> we disable the HDMI controller to switch away from getting our pixels from
> the pixelvalve and instead use blank pixels, and switch back to the
> pixelvalve when we enable the HDMI controller.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c |  9 +
>  drivers/gpu/drm/vc4/vc4_regs.h |  3 +++
>  2 files changed, 12 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index f56a718a3643..37463b016b47 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -325,6 +325,12 @@ static void vc4_hdmi_encoder_post_crtc_disable(struct 
> drm_encoder *encoder)
> struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
>
> HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
> +
> +   HDMI_WRITE(HDMI_VID_CTL, HDMI_READ(HDMI_VID_CTL) |
> +  VC4_HD_VID_CTL_CLRRGB | VC4_HD_VID_CTL_CLRSYNC);
> +
> +   HDMI_WRITE(HDMI_VID_CTL,
> +  HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_BLANKPIX);
>  }
>
>  static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder)
> @@ -563,6 +569,9 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct 
> drm_encoder *encoder)
>(vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
>(hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
>
> +   HDMI_WRITE(HDMI_VID_CTL,
> +  HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_BLANKPIX);
> +
> if (vc4_encoder->hdmi_monitor) {
> HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
>HDMI_READ(HDMI_SCHEDULER_CONTROL) |
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> index d1e8961edaa0..30af52b406f1 100644
> --- a/drivers/gpu/drm/vc4/vc4_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -723,6 +723,9 @@
>  # define VC4_HD_VID_CTL_FRAME_COUNTER_RESETBIT(29)
>  # define VC4_HD_VID_CTL_VSYNC_LOW  BIT(28)
>  # define VC4_HD_VID_CTL_HSYNC_LOW  BIT(27)
> +# define VC4_HD_VID_CTL_CLRSYNCBIT(24)
> +# define VC4_HD_VID_CTL_CLRRGB BIT(23)
> +# define VC4_HD_VID_CTL_BLANKPIX   BIT(18)
>
>  # define VC4_HD_CSC_CTL_ORDER_MASK VC4_MASK(7, 5)
>  # define VC4_HD_CSC_CTL_ORDER_SHIFT5
> --
> git-series 0.9.1


Re: [PATCH v4 72/78] drm/vc4: hdmi: Do the VID_CTL configuration at once

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The VID_CTL setup is done in several places in the driver even though it's
> not really required. Let's simplify it a bit to do the configuration in one
> go.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 14 ++
>  1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index bbe521ab000b..f56a718a3643 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -428,10 +428,6 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi 
> *vc4_hdmi,
>
> HDMI_WRITE(HDMI_VERTB0, vertb_even);
> HDMI_WRITE(HDMI_VERTB1, vertb);
> -
> -   HDMI_WRITE(HDMI_VID_CTL,
> -  (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
> -  (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
>  }
>
>  static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
> @@ -520,8 +516,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct 
> drm_encoder *encoder)
> if (vc4_hdmi->variant->phy_init)
> vc4_hdmi->variant->phy_init(vc4_hdmi, mode);
>
> -   HDMI_WRITE(HDMI_VID_CTL, 0);
> -
> HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
>HDMI_READ(HDMI_SCHEDULER_CONTROL) |
>VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
> @@ -555,15 +549,19 @@ static void vc4_hdmi_encoder_pre_crtc_enable(struct 
> drm_encoder *encoder)
>
>  static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder)
>  {
> +   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +   bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
> +   bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
> int ret;
>
> HDMI_WRITE(HDMI_VID_CTL,
> -  HDMI_READ(HDMI_VID_CTL) |
>VC4_HD_VID_CTL_ENABLE |
>VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
> -  VC4_HD_VID_CTL_FRAME_COUNTER_RESET);
> +  VC4_HD_VID_CTL_FRAME_COUNTER_RESET |
> +  (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
> +  (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
>
> if (vc4_encoder->hdmi_monitor) {
> HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
> --
> git-series 0.9.1


Re: [PATCH v4 71/78] drm/vc4: hdmi: Implement finer-grained hooks

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> In order to prevent some pixels getting stuck in an unflushable FIFO on
> bcm2711, we need to enable the HVS, the pixelvalve (the CRTC) and the HDMI
> controller (the encoder) in an intertwined way, and with tight delays.
>
> However, the atomic callbacks don't really provide a way to work with
> either constraints, so we need to roll our own callbacks so that we can
> provide those guarantees.
>
> Since those callbacks have been implemented and called in the CRTC code, we
> can just implement them in the HDMI driver now.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 39 +++
>  1 file changed, 35 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 00592c1ada73..bbe521ab000b 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -320,12 +320,17 @@ static void vc4_hdmi_set_infoframes(struct drm_encoder 
> *encoder)
> vc4_hdmi_set_audio_infoframe(encoder);
>  }
>
> -static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
> +static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder)
>  {
> struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> -   int ret;
>
> HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
> +}
> +
> +static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder)
> +{
> +   struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> +   int ret;
>
> if (vc4_hdmi->variant->phy_disable)
> vc4_hdmi->variant->phy_disable(vc4_hdmi);
> @@ -341,6 +346,10 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder 
> *encoder)
> DRM_ERROR("Failed to release power domain: %d\n", ret);
>  }
>
> +static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
> +{
> +}
> +
>  static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
>  {
> u32 csc_ctl;
> @@ -449,11 +458,10 @@ static void vc4_hdmi_recenter_fifo(struct vc4_hdmi 
> *vc4_hdmi)
>   "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
>  }
>
> -static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder)
>  {
> struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> -   struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> unsigned long pixel_rate, hsm_rate;
> int ret;
>
> @@ -521,6 +529,13 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
>
> if (vc4_hdmi->variant->set_timings)
> vc4_hdmi->variant->set_timings(vc4_hdmi, mode);
> +}
> +
> +static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder)
> +{
> +   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> +   struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +   struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
>
> if (vc4_encoder->hdmi_monitor &&
> drm_default_rgb_quant_range(mode) == 
> HDMI_QUANTIZATION_RANGE_LIMITED) {
> @@ -536,6 +551,13 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> }
>
> HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
> +}
> +
> +static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder)
> +{
> +   struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> +   struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +   int ret;
>
> HDMI_WRITE(HDMI_VID_CTL,
>HDMI_READ(HDMI_VID_CTL) |
> @@ -582,6 +604,10 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> vc4_hdmi_recenter_fifo(vc4_hdmi);
>  }
>
> +static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +{
> +}
> +
>  static enum drm_mode_status
>  vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
> const struct drm_display_mode *mode)
> @@ -1362,6 +1388,11 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> dev_set_drvdata(dev, vc4_hdmi);
> encoder = _hdmi->encoder.base.base;
> vc4_hdmi->encoder.base.type = variant->encoder_type;
> +   vc4_hdmi->encoder.base.pre_crtc_configure = 
> vc4_hdmi_encode

Re: [PATCH v4 70/78] drm/vc4: hdmi: Always recenter the HDMI FIFO

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> In order to avoid a pixel getting stuck in an unflushable FIFO, we need to
> recenter the FIFO every time we're doing a modeset and not only if we're
> connected to an HDMI monitor.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 46 +++
>  1 file changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 4058985940e6..00592c1ada73 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -425,6 +425,30 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi 
> *vc4_hdmi,
>(hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
>  }
>
> +static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
> +{
> +   u32 drift;
> +   int ret;
> +
> +   drift = HDMI_READ(HDMI_FIFO_CTL);
> +   drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
> +
> +   HDMI_WRITE(HDMI_FIFO_CTL,
> +  drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> +   HDMI_WRITE(HDMI_FIFO_CTL,
> +  drift | VC4_HDMI_FIFO_CTL_RECENTER);
> +   usleep_range(1000, 1100);
> +   HDMI_WRITE(HDMI_FIFO_CTL,
> +  drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> +   HDMI_WRITE(HDMI_FIFO_CTL,
> +  drift | VC4_HDMI_FIFO_CTL_RECENTER);
> +
> +   ret = wait_for(HDMI_READ(HDMI_FIFO_CTL) &
> +  VC4_HDMI_FIFO_CTL_RECENTER_DONE, 1);
> +   WARN_ONCE(ret, "Timeout waiting for "
> + "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
> +}
> +
>  static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
>  {
> struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> @@ -543,8 +567,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> }
>
> if (vc4_encoder->hdmi_monitor) {
> -   u32 drift;
> -
> WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
>   VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
> HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
> @@ -555,25 +577,9 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
>VC4_HDMI_RAM_PACKET_ENABLE);
>
> vc4_hdmi_set_infoframes(encoder);
> -
> -   drift = HDMI_READ(HDMI_FIFO_CTL);
> -   drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
> -
> -   HDMI_WRITE(HDMI_FIFO_CTL,
> -  drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> -   HDMI_WRITE(HDMI_FIFO_CTL,
> -  drift | VC4_HDMI_FIFO_CTL_RECENTER);
> -   usleep_range(1000, 1100);
> -   HDMI_WRITE(HDMI_FIFO_CTL,
> -  drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> -   HDMI_WRITE(HDMI_FIFO_CTL,
> -  drift | VC4_HDMI_FIFO_CTL_RECENTER);
> -
> -   ret = wait_for(HDMI_READ(HDMI_FIFO_CTL) &
> -  VC4_HDMI_FIFO_CTL_RECENTER_DONE, 1);
> -   WARN_ONCE(ret, "Timeout waiting for "
> - "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
> }
> +
> +   vc4_hdmi_recenter_fifo(vc4_hdmi);
>  }
>
>  static enum drm_mode_status
> --
> git-series 0.9.1


Re: [PATCH v4 69/78] drm/vc4: hdmi: Remove register dumps in enable

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The current code has some logic, disabled by default, to dump the register
> setup in the HDMI controller.
>
> However, since we're going to split those functions in multiple, shorter,
> functions that only make sense where they are called in sequence, keeping
> the register dump makes little sense.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 17 -
>  1 file changed, 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 0a9a323e03d8..4058985940e6 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -430,7 +430,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> -   bool debug_dump_regs = false;
> unsigned long pixel_rate, hsm_rate;
> int ret;
>
> @@ -489,14 +488,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> if (vc4_hdmi->variant->phy_init)
> vc4_hdmi->variant->phy_init(vc4_hdmi, mode);
>
> -   if (debug_dump_regs) {
> -   struct drm_printer p = drm_info_printer(_hdmi->pdev->dev);
> -
> -   dev_info(_hdmi->pdev->dev, "HDMI regs before:\n");
> -   drm_print_regset32(, _hdmi->hdmi_regset);
> -   drm_print_regset32(, _hdmi->hd_regset);
> -   }
> -
> HDMI_WRITE(HDMI_VID_CTL, 0);
>
> HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
> @@ -522,14 +513,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
>
> HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
>
> -   if (debug_dump_regs) {
> -   struct drm_printer p = drm_info_printer(_hdmi->pdev->dev);
> -
> -   dev_info(_hdmi->pdev->dev, "HDMI regs after:\n");
> -   drm_print_regset32(, _hdmi->hdmi_regset);
> -   drm_print_regset32(, _hdmi->hd_regset);
> -   }
> -
> HDMI_WRITE(HDMI_VID_CTL,
>HDMI_READ(HDMI_VID_CTL) |
>VC4_HD_VID_CTL_ENABLE |
> --
> git-series 0.9.1


Re: [PATCH v4 68/78] drm/vc4: hdmi: Deal with multiple ALSA cards

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The HDMI driver was registering a single ALSA card so far with the name
> vc4-hdmi.
>
> Obviously, this is not going to work anymore when will have multiple HDMI

s/will/we

> controllers since we will end up trying to register two files with the same
> name.
>
> Let's use the variant to avoid that name conflict.
>
> Signed-off-by: Maxime Ripard 

With that change
Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++-
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 3 +++
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 1b6f51849d6c..0a9a323e03d8 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1044,7 +1044,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi 
> *vc4_hdmi)
>
> card->dai_link = dai_link;
> card->num_links = 1;
> -   card->name = "vc4-hdmi";
> +   card->name = vc4_hdmi->variant->card_name;
> card->dev = dev;
>
> /*
> @@ -1503,6 +1503,7 @@ static int vc4_hdmi_dev_remove(struct platform_device 
> *pdev)
>  static const struct vc4_hdmi_variant bcm2835_variant = {
> .encoder_type   = VC4_ENCODER_TYPE_HDMI0,
> .debugfs_name   = "hdmi_regs",
> +   .card_name  = "vc4-hdmi",
> .max_pixel_clock= 16200,
> .cec_available  = true,
> .registers  = vc4_hdmi_fields,
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 4aea5ee8a91d..34138e0dd4a6 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -30,6 +30,9 @@ struct vc4_hdmi_variant {
> /* Encoder Type for that controller */
> enum vc4_encoder_type encoder_type;
>
> +   /* ALSA card name */
> +   const char *card_name;
> +
> /* Filename to expose the registers in debugfs */
> const char *debugfs_name;
>
> --
> git-series 0.9.1


Re: [PATCH v4 63/78] drm/vc4: hdmi: Use clk_set_min_rate instead

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The HSM clock needs to be running at 101% the pixel clock of the HDMI
> controller, however it's shared between the two HDMI controllers, which
> means that if the resolutions are different between the two HDMI
> controllers, and the lowest resolution is on the second (in enable order)
> controller, the first HDMI controller will end up with a smaller than
> expected clock rate.
>
> Since we don't really need an exact frequency there, we can simply change
> the minimum rate we expect instead.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 9f30fab744f2..d99188c90ff9 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -462,7 +462,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
>  * pixel clock, but HSM ends up being the limiting factor.
>  */
> hsm_rate = max_t(unsigned long, 12000, (pixel_rate / 100) * 101);
> -   ret = clk_set_rate(vc4_hdmi->hsm_clock, hsm_rate);
> +   ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate);
> if (ret) {
> DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
> return;
> --
> git-series 0.9.1


Re: [PATCH v4 62/78] drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The HSM clock needs to be setup at around 101% of the pixel rate. This
> was done previously by setting the clock rate to 163.7MHz at probe time and
> only check in mode_valid whether the mode pixel clock was under the pixel
> clock +1% or not.
>
> However, with 4k we need to change that frequency to a higher frequency
> than 163.7MHz, and yet want to have the lowest clock as possible to have a
> decent power saving.
>
> Let's change that logic a bit by setting the clock rate of the HSM clock
> to the pixel rate at encoder_enable time. This would work for the
> BCM2711 that support 4k resolutions and has a clock that can provide it,
> but we still have to take care of a 4k panel plugged on a BCM283x SoCs
> that wouldn't be able to use those modes, so let's define the limit in
> the variant.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 79 ---
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  3 +-
>  2 files changed, 41 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 17797b14cde4..9f30fab744f2 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -53,7 +53,6 @@
>  #include "vc4_hdmi_regs.h"
>  #include "vc4_regs.h"
>
> -#define HSM_CLOCK_FREQ 163682864
>  #define CEC_CLOCK_FREQ 4
>
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> @@ -326,6 +325,7 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder 
> *encoder)
> HDMI_WRITE(HDMI_VID_CTL,
>HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
>
> +   clk_disable_unprepare(vc4_hdmi->hsm_clock);
> clk_disable_unprepare(vc4_hdmi->pixel_clock);
>
> ret = pm_runtime_put(_hdmi->pdev->dev);
> @@ -423,6 +423,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> bool debug_dump_regs = false;
> +   unsigned long pixel_rate, hsm_rate;
> int ret;
>
> ret = pm_runtime_get_sync(_hdmi->pdev->dev);
> @@ -431,9 +432,8 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> return;
> }
>
> -   ret = clk_set_rate(vc4_hdmi->pixel_clock,
> -  mode->clock * 1000 *
> -  ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
> +   pixel_rate = mode->clock * 1000 * ((mode->flags & 
> DRM_MODE_FLAG_DBLCLK) ? 2 : 1);
> +   ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
> if (ret) {
> DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
> return;
> @@ -445,6 +445,36 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> return;
> }
>
> +   /*
> +* As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock 
> must
> +* be faster than pixel clock, infinitesimally faster, tested in
> +* simulation. Otherwise, exact value is unimportant for HDMI
> +* operation." This conflicts with bcm2835's vc4 documentation, which
> +* states HSM's clock has to be at least 108% of the pixel clock.
> +*
> +* Real life tests reveal that vc4's firmware statement holds up, and
> +* users are able to use pixel clocks closer to HSM's, namely for
> +* 1920x1200@60Hz. So it was decided to have leave a 1% margin between
> +* both clocks. Which, for RPi0-3 implies a maximum pixel clock of
> +* 162MHz.
> +*
> +* Additionally, the AXI clock needs to be at least 25% of
> +* pixel clock, but HSM ends up being the limiting factor.
> +*/
> +   hsm_rate = max_t(unsigned long, 12000, (pixel_rate / 100) * 101);
> +   ret = clk_set_rate(vc4_hdmi->hsm_clock, hsm_rate);
> +   if (ret) {
> +   DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
> +   return;
> +   }
> +
> +   ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
> +   if (ret) {
> +   DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
> +   clk_disable_unprepare(vc4_hdmi->pixel_clock);
> +   return;
> +   }
> +
> if (vc4_hdmi->variant->reset)
> vc4_hdmi->variant->re

Re: [PATCH v4 61/78] drm/vc4: hdmi: Rename drm_encoder pointer in mode_valid

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The mode_valid hook on the encoder uses a pointer to a drm_encoder called
> crtc, which is pretty confusing. Let's rename it to encoder to make it
> clear what it is.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index a01562a49bf0..17797b14cde4 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -556,7 +556,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
>  }
>
>  static enum drm_mode_status
> -vc4_hdmi_encoder_mode_valid(struct drm_encoder *crtc,
> +vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
> const struct drm_display_mode *mode)
>  {
> /*
> --
> git-series 0.9.1


Re: [PATCH v4 60/78] drm/vc4: hdmi: Remove unused CEC_CLOCK_DIV define

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard  wrote:
>
> The CEC_CLOCK_DIV define is not used anywhere in the driver, let's remove
> it.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 86e21de6c578..a01562a49bf0 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -55,7 +55,6 @@
>
>  #define HSM_CLOCK_FREQ 163682864
>  #define CEC_CLOCK_FREQ 4
> -#define CEC_CLOCK_DIV  (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
>
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
>  {
> --
> git-series 0.9.1


Re: [PATCH v4 59/78] drm/vc4: hdmi: Add CEC support flag

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> Similarly to the audio support, CEC support is not there yet for the
> BCM2711, so let's skip entirely the CEC initialization through a variant
> flag.

CEC is sorted now, but it's easier & cleaner to keep this patch and
add a new patchset that enables CEC at a later date.

> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 4 
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 3 +++
>  2 files changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 8cd08b541c14..86e21de6c578 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1179,6 +1179,9 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
> u32 value;
> int ret;
>
> +   if (!vc4_hdmi->variant->cec_available)
> +   return 0;
> +
> vc4_hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
>   vc4_hdmi, "vc4",
>   CEC_CAP_DEFAULTS |
> @@ -1477,6 +1480,7 @@ static int vc4_hdmi_dev_remove(struct platform_device 
> *pdev)
>  static const struct vc4_hdmi_variant bcm2835_variant = {
> .encoder_type   = VC4_ENCODER_TYPE_HDMI0,
> .debugfs_name   = "hdmi_regs",
> +   .cec_available  = true,
> .registers  = vc4_hdmi_fields,
> .num_registers  = ARRAY_SIZE(vc4_hdmi_fields),
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 794216f3228d..3f07aebe89f1 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -33,6 +33,9 @@ struct vc4_hdmi_variant {
> /* Filename to expose the registers in debugfs */
> const char *debugfs_name;
>
> +   /* Set to true when the CEC support is available */
> +   bool cec_available;
> +
> /* List of the registers available on that variant */
> const struct vc4_hdmi_register *registers;
>
> --
> git-series 0.9.1


Re: [PATCH v4 58/78] drm/vc4: hdmi: Move CEC init to its own function

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The CEC init code was put directly into the bind function, which was quite
> inconsistent with how the audio support was done, and would prevent us from
> further changes to skip that initialisation entirely.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 108 +-
>  1 file changed, 67 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index ef51eedaf75a..8cd08b541c14 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1171,6 +1171,67 @@ static const struct cec_adap_ops vc4_hdmi_cec_adap_ops 
> = {
> .adap_log_addr = vc4_hdmi_cec_adap_log_addr,
> .adap_transmit = vc4_hdmi_cec_adap_transmit,
>  };
> +
> +static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
> +{
> +   struct cec_connector_info conn_info;
> +   struct platform_device *pdev = vc4_hdmi->pdev;
> +   u32 value;
> +   int ret;
> +
> +   vc4_hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
> + vc4_hdmi, "vc4",
> + CEC_CAP_DEFAULTS |
> + CEC_CAP_CONNECTOR_INFO, 1);
> +   ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
> +   if (ret < 0)
> +   return ret;
> +
> +   cec_fill_conn_info_from_drm(_info, _hdmi->connector);
> +   cec_s_conn_info(vc4_hdmi->cec_adap, _info);
> +
> +   HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0x);
> +   value = HDMI_READ(HDMI_CEC_CNTRL_1);
> +   value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
> +   /*
> +* Set the logical address to Unregistered and set the clock
> +* divider: the hsm_clock rate and this divider setting will
> +* give a 40 kHz CEC clock.
> +*/
> +   value |= VC4_HDMI_CEC_ADDR_MASK |
> +(4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
> +   HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
> +   ret = devm_request_threaded_irq(>dev, platform_get_irq(pdev, 0),
> +   vc4_cec_irq_handler,
> +   vc4_cec_irq_handler_thread, 0,
> +   "vc4 hdmi cec", vc4_hdmi);
> +   if (ret)
> +   goto err_delete_cec_adap;
> +
> +   ret = cec_register_adapter(vc4_hdmi->cec_adap, >dev);
> +   if (ret < 0)
> +   goto err_delete_cec_adap;
> +
> +   return 0;
> +
> +err_delete_cec_adap:
> +   cec_delete_adapter(vc4_hdmi->cec_adap);
> +
> +   return ret;
> +}
> +
> +static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi)
> +{
> +   cec_unregister_adapter(vc4_hdmi->cec_adap);
> +}
> +#else
> +static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
> +{
> +   return 0;
> +}
> +
> +static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {};
> +
>  #endif
>
>  static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi,
> @@ -1250,9 +1311,6 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi 
> *vc4_hdmi)
>
>  static int vc4_hdmi_bind(struct device *dev, struct device *master, void 
> *data)
>  {
> -#ifdef CONFIG_DRM_VC4_HDMI_CEC
> -   struct cec_connector_info conn_info;
> -#endif
> const struct vc4_hdmi_variant *variant = 
> of_device_get_match_data(dev);
> struct platform_device *pdev = to_platform_device(dev);
> struct drm_device *drm = dev_get_drvdata(master);
> @@ -1332,43 +1390,13 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> if (ret)
> goto err_destroy_encoder;
>
> -#ifdef CONFIG_DRM_VC4_HDMI_CEC
> -   vc4_hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
> - vc4_hdmi, "vc4",
> - CEC_CAP_DEFAULTS |
> - CEC_CAP_CONNECTOR_INFO, 1);
> -   ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
> -   if (ret < 0)
> -   goto err_destroy_conn;
> -
> -   cec_fill_conn_info_from_drm(_info, _hdmi->connector);
> -   cec_s_conn_info(vc4_hdmi->cec_adap, _info);
> -
> -   HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0x);
> -   value = HDMI_READ(HDMI_CEC_CNTRL_1);
> -   value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
> -   /*
> -* Set the logical add

Re: [PATCH v4 57/78] drm/vc4: hdmi: Deal with multiple debugfs files

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The HDMI driver was registering a single debugfs file so far with the name
> hdmi_regs.
>
> Obviously, this is not going to work anymore when will have multiple HDMI
> controllers since we will end up trying to register two files with the same
> name.
>
> Let's use the variant to avoid that name conflict.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 5 -
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 3 +++
>  2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index c50241170d7e..ef51eedaf75a 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1370,7 +1370,9 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> if (ret)
> goto err_destroy_encoder;
>
> -   vc4_debugfs_add_file(drm, "hdmi_regs", vc4_hdmi_debugfs_regs, 
> vc4_hdmi);
> +   vc4_debugfs_add_file(drm, variant->debugfs_name,
> +vc4_hdmi_debugfs_regs,
> +vc4_hdmi);
>
> return 0;
>
> @@ -1448,6 +1450,7 @@ static int vc4_hdmi_dev_remove(struct platform_device 
> *pdev)
>
>  static const struct vc4_hdmi_variant bcm2835_variant = {
> .encoder_type   = VC4_ENCODER_TYPE_HDMI0,
> +   .debugfs_name   = "hdmi_regs",
> .registers  = vc4_hdmi_fields,
> .num_registers  = ARRAY_SIZE(vc4_hdmi_fields),
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 0d529db4b3ab..794216f3228d 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -30,6 +30,9 @@ struct vc4_hdmi_variant {
> /* Encoder Type for that controller */
> enum vc4_encoder_type encoder_type;
>
> +   /* Filename to expose the registers in debugfs */
> +   const char *debugfs_name;
> +
> /* List of the registers available on that variant */
> const struct vc4_hdmi_register *registers;
>
> --
> git-series 0.9.1


Re: [PATCH v4 56/78] drm/vc4: hdmi: Store the encoder type in the variant structure

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The vc4 CRTC will use the encoder type to control its output clock
> muxing. However, this will be different from HDMI0 to HDMI1, so let's
> store our type in the variant structure so that we can support multiple
> controllers later on.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++-
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 3 +++
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index a50220bfd5dd..c50241170d7e 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1268,7 +1268,7 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
>
> dev_set_drvdata(dev, vc4_hdmi);
> encoder = _hdmi->encoder.base.base;
> -   vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
> +   vc4_hdmi->encoder.base.type = variant->encoder_type;
> vc4_hdmi->pdev = pdev;
> vc4_hdmi->variant = variant;
>
> @@ -1447,6 +1447,7 @@ static int vc4_hdmi_dev_remove(struct platform_device 
> *pdev)
>  }
>
>  static const struct vc4_hdmi_variant bcm2835_variant = {
> +   .encoder_type   = VC4_ENCODER_TYPE_HDMI0,
> .registers  = vc4_hdmi_fields,
> .num_registers  = ARRAY_SIZE(vc4_hdmi_fields),
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 0c32dc46d289..0d529db4b3ab 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -27,6 +27,9 @@ struct vc4_hdmi;
>  struct vc4_hdmi_register;
>
>  struct vc4_hdmi_variant {
> +   /* Encoder Type for that controller */
> +   enum vc4_encoder_type encoder_type;
> +
> /* List of the registers available on that variant */
> const struct vc4_hdmi_register *registers;
>
> --
> git-series 0.9.1


Re: [PATCH v4 55/78] drm/vc4: hdmi: Add a CSC setup callback

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> Similarly to the previous patches, the CSC setup is slightly different in
> the BCM2711 than in the previous generations. Let's add a callback for it.

We've gained the set_timings callback in this patch as well as
csc_setup. Was that an accidental squash as we had them as independent
commits in v1.

  Dave

> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 142 +++---
>  drivers/gpu/drm/vc4/vc4_hdmi.h |   7 ++-
>  2 files changed, 89 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 19897d6525ac..a50220bfd5dd 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -334,12 +334,44 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder 
> *encoder)
> DRM_ERROR("Failed to release power domain: %d\n", ret);
>  }
>
> -static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
> +{
> +   u32 csc_ctl;
> +
> +   csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
> +   VC4_HD_CSC_CTL_ORDER);
> +
> +   if (enable) {
> +   /* CEA VICs other than #1 requre limited range RGB
> +* output unless overridden by an AVI infoframe.
> +* Apply a colorspace conversion to squash 0-255 down
> +* to 16-235.  The matrix here is:
> +*
> +* [ 0  0  0.8594 16]
> +* [ 0  0.8594 0  16]
> +* [ 0.8594 0  0  16]
> +* [ 0  0  0   1]
> +*/
> +   csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
> +   csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
> +   csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
> +VC4_HD_CSC_CTL_MODE);
> +
> +   HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
> +   HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
> +   HDMI_WRITE(HDMI_CSC_22_21, (0x6e0 << 16) | 0x000);
> +   HDMI_WRITE(HDMI_CSC_24_23, (0x100 << 16) | 0x000);
> +   HDMI_WRITE(HDMI_CSC_32_31, (0x000 << 16) | 0x6e0);
> +   HDMI_WRITE(HDMI_CSC_34_33, (0x100 << 16) | 0x000);
> +   }
> +
> +   /* The RGB order applies even when CSC is disabled. */
> +   HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
> +}
> +
> +static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
> +struct drm_display_mode *mode)
>  {
> -   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> -   struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> -   struct vc4_hdmi_encoder *vc4_encoder = _hdmi->encoder;
> -   bool debug_dump_regs = false;
> bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
> bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
> bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> @@ -357,7 +389,41 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> mode->crtc_vsync_end -
> interlaced,
> VC4_HDMI_VERTB_VBP));
> -   u32 csc_ctl;
> +
> +   HDMI_WRITE(HDMI_HORZA,
> +  (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
> +  (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
> +  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
> +VC4_HDMI_HORZA_HAP));
> +
> +   HDMI_WRITE(HDMI_HORZB,
> +  VC4_SET_FIELD((mode->htotal -
> + mode->hsync_end) * pixel_rep,
> +VC4_HDMI_HORZB_HBP) |
> +  VC4_SET_FIELD((mode->hsync_end -
> + mode->hsync_start) * pixel_rep,
> +VC4_HDMI_HORZB_HSP) |
> +  VC4_SET_FIELD((mode->hsync_start -
> + mode->hdisplay) * pixel_rep,
> +VC4_HDMI_HORZB_HFP));
> +
> +   HDMI_WRITE(HDMI_VERTA0, verta);
> +   HDMI_WRITE(HDMI_VERTA1, verta);
> +
> +   HDMI_WRITE(HDMI_VERTB0, vertb_even);
> +   HDMI_WRITE(HDMI_VERTB1, vertb);
> +
> +   HDMI_WRITE(HDMI_VID_CTL,
> +  (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
> +  (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
> +}
> +
> +static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +{
> +   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> +   struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> +   struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +   bool debug_dump_regs = false;
> int ret;
>

Re: [PATCH v4 54/78] drm/vc4: hdmi: Add PHY RNG enable / disable function

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> Let's continue the implementation of hooks for the parts that change in the
> BCM2711 SoC with the PHY RNG setup.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 15 +--
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  8 
>  drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 15 +++
>  3 files changed, 32 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 068041145d1c..19897d6525ac 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -762,9 +762,9 @@ static int vc4_hdmi_audio_trigger(struct 
> snd_pcm_substream *substream, int cmd,
> switch (cmd) {
> case SNDRV_PCM_TRIGGER_START:
> vc4_hdmi_set_audio_infoframe(encoder);
> -   HDMI_WRITE(HDMI_TX_PHY_CTL_0,
> -  HDMI_READ(HDMI_TX_PHY_CTL_0) &
> -  ~VC4_HDMI_TX_PHY_RNG_PWRDN);
> +
> +   if (vc4_hdmi->variant->phy_rng_enable)
> +   vc4_hdmi->variant->phy_rng_enable(vc4_hdmi);
>
> HDMI_WRITE(HDMI_MAI_CTL,
>VC4_SET_FIELD(vc4_hdmi->audio.channels,
> @@ -776,9 +776,10 @@ static int vc4_hdmi_audio_trigger(struct 
> snd_pcm_substream *substream, int cmd,
>VC4_HD_MAI_CTL_DLATE |
>VC4_HD_MAI_CTL_ERRORE |
>VC4_HD_MAI_CTL_ERRORF);
> -   HDMI_WRITE(HDMI_TX_PHY_CTL_0,
> -  HDMI_READ(HDMI_TX_PHY_CTL_0) |
> -  VC4_HDMI_TX_PHY_RNG_PWRDN);
> +
> +   if (vc4_hdmi->variant->phy_rng_disable)
> +   vc4_hdmi->variant->phy_rng_disable(vc4_hdmi);
> +
> break;
> default:
> break;
> @@ -1433,6 +1434,8 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
> .reset  = vc4_hdmi_reset,
> .phy_init   = vc4_hdmi_phy_init,
> .phy_disable= vc4_hdmi_phy_disable,
> +   .phy_rng_enable = vc4_hdmi_phy_rng_enable,
> +   .phy_rng_disable= vc4_hdmi_phy_rng_disable,
>  };
>
>  static const struct of_device_id vc4_hdmi_dt_match[] = {
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 32c80161c786..950accbc44e4 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -47,6 +47,12 @@ struct vc4_hdmi_variant {
>
> /* Callback to disable the PHY */
> void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
> +
> +   /* Callback to enable the RNG in the PHY */
> +   void (*phy_rng_enable)(struct vc4_hdmi *vc4_hdmi);
> +
> +   /* Callback to disable the RNG in the PHY */
> +   void (*phy_rng_disable)(struct vc4_hdmi *vc4_hdmi);
>  };
>
>  /* HDMI audio information */
> @@ -107,5 +113,7 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
>  void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
>struct drm_display_mode *mode);
>  void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
> +void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
> +void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
>
>  #endif /* _VC4_HDMI_H_ */
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c 
> b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> index 5a1746877bb5..93287e24d7d1 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> @@ -7,6 +7,7 @@
>   */
>
>  #include "vc4_hdmi.h"
> +#include "vc4_regs.h"
>  #include "vc4_hdmi_regs.h"
>
>  void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode 
> *mode)
> @@ -23,3 +24,17 @@ void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
>  {
> HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
>  }
> +
> +void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
> +{
> +   HDMI_WRITE(HDMI_TX_PHY_CTL_0,
> +  HDMI_READ(HDMI_TX_PHY_CTL_0) &
> +  ~VC4_HDMI_TX_PHY_RNG_PWRDN);
> +}
> +
> +void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
> +{
> +   HDMI_WRITE(HDMI_TX_PHY_CTL_0,
> +  HDMI_READ(HDMI_TX_PHY_CTL_0) |
> +  VC4_HDMI_TX_PHY_RNG_PWRDN);
> +}
> --
> git-series 0.9.1


Re: [PATCH v4 53/78] drm/vc4: hdmi: Add PHY init and disable function

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The HDMI PHY in the BCM2711 HDMI controller is significantly more
> complicated to setup than in the older BCM283x SoCs.
>
> Let's add hooks to enable and disable the PHY.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/Makefile   |  1 +
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 14 +++---
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 13 +
>  drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 25 +
>  4 files changed, 46 insertions(+), 7 deletions(-)
>  create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi_phy.c
>
> diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
> index b303703bc7f3..d0163e18e9ca 100644
> --- a/drivers/gpu/drm/vc4/Makefile
> +++ b/drivers/gpu/drm/vc4/Makefile
> @@ -12,6 +12,7 @@ vc4-y := \
> vc4_kms.o \
> vc4_gem.o \
> vc4_hdmi.o \
> +   vc4_hdmi_phy.o \
> vc4_vec.o \
> vc4_hvs.o \
> vc4_irq.o \
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 80bc3dd9d4a8..068041145d1c 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -321,7 +321,9 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder 
> *encoder)
>
> HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
>
> -   HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
> +   if (vc4_hdmi->variant->phy_disable)
> +   vc4_hdmi->variant->phy_disable(vc4_hdmi);
> +
> HDMI_WRITE(HDMI_VID_CTL,
>HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
>
> @@ -381,12 +383,8 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> if (vc4_hdmi->variant->reset)
> vc4_hdmi->variant->reset(vc4_hdmi);
>
> -   /* PHY should be in reset, like
> -* vc4_hdmi_encoder_disable() does.
> -*/
> -   HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
> -
> -   HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
> +   if (vc4_hdmi->variant->phy_init)
> +   vc4_hdmi->variant->phy_init(vc4_hdmi, mode);
>
> if (debug_dump_regs) {
> struct drm_printer p = drm_info_printer(_hdmi->pdev->dev);
> @@ -1433,6 +1431,8 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
>
> .init_resources = vc4_hdmi_init_resources,
> .reset  = vc4_hdmi_reset,
> +   .phy_init   = vc4_hdmi_phy_init,
> +   .phy_disable= vc4_hdmi_phy_disable,
>  };
>
>  static const struct of_device_id vc4_hdmi_dt_match[] = {
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 17a30589f39c..32c80161c786 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -21,6 +21,8 @@ to_vc4_hdmi_encoder(struct drm_encoder *encoder)
> return container_of(encoder, struct vc4_hdmi_encoder, base.base);
>  }
>
> +struct drm_display_mode;
> +
>  struct vc4_hdmi;
>  struct vc4_hdmi_register;
>
> @@ -38,6 +40,13 @@ struct vc4_hdmi_variant {
>
> /* Callback to reset the HDMI block */
> void (*reset)(struct vc4_hdmi *vc4_hdmi);
> +
> +   /* Callback to initialize the PHY according to the mode */
> +   void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
> +struct drm_display_mode *mode);
> +
> +   /* Callback to disable the PHY */
> +   void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
>  };
>
>  /* HDMI audio information */
> @@ -95,4 +104,8 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
> return container_of(_encoder, struct vc4_hdmi, encoder);
>  }
>
> +void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
> +  struct drm_display_mode *mode);
> +void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
> +
>  #endif /* _VC4_HDMI_H_ */
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c 
> b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> new file mode 100644
> index ..5a1746877bb5
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2015 Broadcom
> + * Copyright (c) 2014 The Linux Foundation. All rights reserved.
> + * Copyright (C) 2013 Red Hat
> + * Author: Rob Clark 
> + */
> +
> +#include "vc4_hdmi.h"
> +#include "vc4_hdmi_regs.h"
> +
> +void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode 
> *mode)
> +{
> +   /* PHY should be in reset, like
> +* vc4_hdmi_encoder_disable() does.
> +*/
> +
> +   HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
> +   HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
> +}
> +
> +void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
> +{
> +   HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
> +}
> --
> git-series 0.9.1


Re: [PATCH v4 52/78] drm/vc4: hdmi: Add reset callback

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The BCM2711 and BCM283x HDMI controllers use a slightly different reset
> sequence, so let's add a callback to reset the controller.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 31 ++-
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  3 +++
>  2 files changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index a4fed1439bf3..80bc3dd9d4a8 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -69,6 +69,21 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void 
> *unused)
> return 0;
>  }
>
> +static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
> +{
> +   HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_SW_RST);
> +   udelay(1);
> +   HDMI_WRITE(HDMI_M_CTL, 0);
> +
> +   HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_ENABLE);
> +
> +   HDMI_WRITE(HDMI_SW_RESET_CONTROL,
> +  VC4_HDMI_SW_RESET_HDMI |
> +  VC4_HDMI_SW_RESET_FORMAT_DETECT);
> +
> +   HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
> +}
> +
>  static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -363,11 +378,8 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
> *encoder)
> return;
> }
>
> -   HDMI_WRITE(HDMI_SW_RESET_CONTROL,
> -  VC4_HDMI_SW_RESET_HDMI |
> -  VC4_HDMI_SW_RESET_FORMAT_DETECT);
> -
> -   HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
> +   if (vc4_hdmi->variant->reset)
> +   vc4_hdmi->variant->reset(vc4_hdmi);
>
> /* PHY should be in reset, like
>  * vc4_hdmi_encoder_disable() does.
> @@ -1292,14 +1304,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> vc4_hdmi->hpd_active_low = hpd_gpio_flags & 
> OF_GPIO_ACTIVE_LOW;
> }
>
> -   /* HDMI core must be enabled. */
> -   if (!(HDMI_READ(HDMI_M_CTL) & VC4_HD_M_ENABLE)) {
> -   HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_SW_RST);
> -   udelay(1);
> -   HDMI_WRITE(HDMI_M_CTL, 0);
> -
> -   HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_ENABLE);
> -   }
> pm_runtime_enable(dev);
>
> drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
> @@ -1428,6 +1432,7 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
> .num_registers  = ARRAY_SIZE(vc4_hdmi_fields),
>
> .init_resources = vc4_hdmi_init_resources,
> +   .reset  = vc4_hdmi_reset,
>  };
>
>  static const struct of_device_id vc4_hdmi_dt_match[] = {
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index b36e0210671f..17a30589f39c 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -35,6 +35,9 @@ struct vc4_hdmi_variant {
>  * clocks, etc) for that variant.
>  */
> int (*init_resources)(struct vc4_hdmi *vc4_hdmi);
> +
> +   /* Callback to reset the HDMI block */
> +   void (*reset)(struct vc4_hdmi *vc4_hdmi);
>  };
>
>  /* HDMI audio information */
> --
> git-series 0.9.1


Re: [PATCH v4 51/78] drm/vc4: hdmi: Implement a register layout abstraction

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The HDMI controllers found in the BCM2711 have most of the registers
> reorganized in multiple registers areas and at different offsets than
> previously found.
>
> The logic however remains pretty much the same, so it doesn't really make
> sense to create a whole new driver and we should share the code as much as
> possible.
>
> Let's implement some indirection to wrap around a register and depending on
> the variant will lookup the associated register on that particular variant.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c  | 427 ++---
>  drivers/gpu/drm/vc4/vc4_hdmi.h  |  12 +-
>  drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 241 -
>  drivers/gpu/drm/vc4/vc4_regs.h  |  92 +--
>  4 files changed, 464 insertions(+), 308 deletions(-)
>  create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi_regs.h
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index ac021e07a8cb..a4fed1439bf3 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -50,62 +50,13 @@
>  #include "media/cec.h"
>  #include "vc4_drv.h"
>  #include "vc4_hdmi.h"
> +#include "vc4_hdmi_regs.h"
>  #include "vc4_regs.h"
>
>  #define HSM_CLOCK_FREQ 163682864
>  #define CEC_CLOCK_FREQ 4
>  #define CEC_CLOCK_DIV  (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
>
> -static const struct debugfs_reg32 hdmi_regs[] = {
> -   VC4_REG32(VC4_HDMI_CORE_REV),
> -   VC4_REG32(VC4_HDMI_SW_RESET_CONTROL),
> -   VC4_REG32(VC4_HDMI_HOTPLUG_INT),
> -   VC4_REG32(VC4_HDMI_HOTPLUG),
> -   VC4_REG32(VC4_HDMI_MAI_CHANNEL_MAP),
> -   VC4_REG32(VC4_HDMI_MAI_CONFIG),
> -   VC4_REG32(VC4_HDMI_MAI_FORMAT),
> -   VC4_REG32(VC4_HDMI_AUDIO_PACKET_CONFIG),
> -   VC4_REG32(VC4_HDMI_RAM_PACKET_CONFIG),
> -   VC4_REG32(VC4_HDMI_HORZA),
> -   VC4_REG32(VC4_HDMI_HORZB),
> -   VC4_REG32(VC4_HDMI_FIFO_CTL),
> -   VC4_REG32(VC4_HDMI_SCHEDULER_CONTROL),
> -   VC4_REG32(VC4_HDMI_VERTA0),
> -   VC4_REG32(VC4_HDMI_VERTA1),
> -   VC4_REG32(VC4_HDMI_VERTB0),
> -   VC4_REG32(VC4_HDMI_VERTB1),
> -   VC4_REG32(VC4_HDMI_TX_PHY_RESET_CTL),
> -   VC4_REG32(VC4_HDMI_TX_PHY_CTL0),
> -
> -   VC4_REG32(VC4_HDMI_CEC_CNTRL_1),
> -   VC4_REG32(VC4_HDMI_CEC_CNTRL_2),
> -   VC4_REG32(VC4_HDMI_CEC_CNTRL_3),
> -   VC4_REG32(VC4_HDMI_CEC_CNTRL_4),
> -   VC4_REG32(VC4_HDMI_CEC_CNTRL_5),
> -   VC4_REG32(VC4_HDMI_CPU_STATUS),
> -   VC4_REG32(VC4_HDMI_CPU_MASK_STATUS),
> -
> -   VC4_REG32(VC4_HDMI_CEC_RX_DATA_1),
> -   VC4_REG32(VC4_HDMI_CEC_RX_DATA_2),
> -   VC4_REG32(VC4_HDMI_CEC_RX_DATA_3),
> -   VC4_REG32(VC4_HDMI_CEC_RX_DATA_4),
> -   VC4_REG32(VC4_HDMI_CEC_TX_DATA_1),
> -   VC4_REG32(VC4_HDMI_CEC_TX_DATA_2),
> -   VC4_REG32(VC4_HDMI_CEC_TX_DATA_3),
> -   VC4_REG32(VC4_HDMI_CEC_TX_DATA_4),
> -};
> -
> -static const struct debugfs_reg32 hd_regs[] = {
> -   VC4_REG32(VC4_HD_M_CTL),
> -   VC4_REG32(VC4_HD_MAI_CTL),
> -   VC4_REG32(VC4_HD_MAI_THR),
> -   VC4_REG32(VC4_HD_MAI_FMT),
> -   VC4_REG32(VC4_HD_MAI_SMP),
> -   VC4_REG32(VC4_HD_VID_CTL),
> -   VC4_REG32(VC4_HD_CSC_CTL),
> -   VC4_REG32(VC4_HD_FRAME_COUNT),
> -};
> -
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
>  {
> struct drm_info_node *node = (struct drm_info_node *)m->private;
> @@ -134,7 +85,7 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, 
> bool force)
> if (drm_probe_ddc(vc4_hdmi->ddc))
> return connector_status_connected;
>
> -   if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
> +   if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
> return connector_status_connected;
> cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> return connector_status_disconnected;
> @@ -223,10 +174,10 @@ static int vc4_hdmi_stop_packet(struct drm_encoder 
> *encoder,
> struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
> u32 packet_id = type - 0x80;
>
> -   HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
> -  HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
> +   HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
> +  HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
>
> -   return wait_for(!(HDMI_READ(VC4_HDMI_RAM_PACKET_STATUS) &
> +   return wait_for(!(HDMI_READ(HDMI_

Re: [PATCH v4 50/78] drm/vc4: hdmi: Introduce resource init and variant

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The HDMI controllers found in the BCM2711 has a pretty different clock and
> registers areas than found in the older BCM283x SoCs.
>
> Let's create a variant structure to store the various adjustments we'll
> need later on, and a function to get the resources needed for one
> particular version.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 61 +++
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 10 ++-
>  2 files changed, 51 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index ec7710dfd04e..ac021e07a8cb 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1179,28 +1179,12 @@ static const struct cec_adap_ops 
> vc4_hdmi_cec_adap_ops = {
>  };
>  #endif
>
> -static int vc4_hdmi_bind(struct device *dev, struct device *master, void 
> *data)
> +static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
>  {
> -#ifdef CONFIG_DRM_VC4_HDMI_CEC
> -   struct cec_connector_info conn_info;
> -#endif
> -   struct platform_device *pdev = to_platform_device(dev);
> -   struct drm_device *drm = dev_get_drvdata(master);
> -   struct vc4_hdmi *vc4_hdmi;
> -   struct drm_encoder *encoder;
> -   struct device_node *ddc_node;
> -   u32 value;
> +   struct platform_device *pdev = vc4_hdmi->pdev;
> +   struct device *dev = >dev;
> int ret;
>
> -   vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
> -   if (!vc4_hdmi)
> -   return -ENOMEM;
> -
> -   dev_set_drvdata(dev, vc4_hdmi);
> -   encoder = _hdmi->encoder.base.base;
> -   vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
> -   vc4_hdmi->pdev = pdev;
> -
> vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
> if (IS_ERR(vc4_hdmi->hdmicore_regs))
> return PTR_ERR(vc4_hdmi->hdmicore_regs);
> @@ -1212,6 +1196,7 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> vc4_hdmi->hdmi_regset.base = vc4_hdmi->hdmicore_regs;
> vc4_hdmi->hdmi_regset.regs = hdmi_regs;
> vc4_hdmi->hdmi_regset.nregs = ARRAY_SIZE(hdmi_regs);
> +
> vc4_hdmi->hd_regset.base = vc4_hdmi->hd_regs;
> vc4_hdmi->hd_regset.regs = hd_regs;
> vc4_hdmi->hd_regset.nregs = ARRAY_SIZE(hd_regs);
> @@ -1223,12 +1208,44 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> DRM_ERROR("Failed to get pixel clock\n");
> return ret;
> }
> +
> vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
> if (IS_ERR(vc4_hdmi->hsm_clock)) {
> DRM_ERROR("Failed to get HDMI state machine clock\n");
> return PTR_ERR(vc4_hdmi->hsm_clock);
> }
>
> +   return 0;
> +}
> +
> +static int vc4_hdmi_bind(struct device *dev, struct device *master, void 
> *data)
> +{
> +#ifdef CONFIG_DRM_VC4_HDMI_CEC
> +   struct cec_connector_info conn_info;
> +#endif
> +   const struct vc4_hdmi_variant *variant = 
> of_device_get_match_data(dev);
> +   struct platform_device *pdev = to_platform_device(dev);
> +   struct drm_device *drm = dev_get_drvdata(master);
> +   struct vc4_hdmi *vc4_hdmi;
> +   struct drm_encoder *encoder;
> +   struct device_node *ddc_node;
> +   u32 value;
> +   int ret;
> +
> +   vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
> +   if (!vc4_hdmi)
> +   return -ENOMEM;
> +
> +   dev_set_drvdata(dev, vc4_hdmi);
> +   encoder = _hdmi->encoder.base.base;
> +   vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
> +   vc4_hdmi->pdev = pdev;
> +   vc4_hdmi->variant = variant;
> +
> +   ret = variant->init_resources(vc4_hdmi);
> +   if (ret)
> +   return ret;
> +
> ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
> if (!ddc_node) {
> DRM_ERROR("Failed to find ddc node in device tree\n");
> @@ -1404,8 +1421,12 @@ static int vc4_hdmi_dev_remove(struct platform_device 
> *pdev)
> return 0;
>  }
>
> +static const struct vc4_hdmi_variant bcm2835_variant = {
> +   .init_resources = vc4_hdmi_init_resources,
> +};
> +
>  static const struct of_device_id vc4_hdmi_dt_match[] = {
> -   { .compatible = "brcm,

Re: [PATCH v4 47/78] drm/vc4: hdmi: Retrieve the vc4_hdmi at unbind using our device

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> The unbind function needs to retrieve a vc4_hdmi structure pointer through
> the struct device that we're given since we want to support multiple HDMI
> controllers.
>
> However, our optional ASoC support doesn't make that trivial since it will
> overwrite the device drvdata if we use it, but obviously won't if we don't
> use it.
>
> Let's make sure the fields are at the proper offset to be able to cast
> between the snd_soc_card structure and the vc4_hdmi structure
> transparently so we can support both cases.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 24 +++-
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  4 ++--
>  2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 09b297a1b39d..7cd1394c10fa 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1200,6 +1200,7 @@ static int vc4_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
> if (!vc4_hdmi)
> return -ENOMEM;
>
> +   dev_set_drvdata(dev, vc4_hdmi);
> encoder = _hdmi->encoder.base.base;
> vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
> vc4_hdmi->pdev = pdev;
> @@ -1362,7 +1363,28 @@ static void vc4_hdmi_unbind(struct device *dev, struct 
> device *master,
>  {
> struct drm_device *drm = dev_get_drvdata(master);
> struct vc4_dev *vc4 = drm->dev_private;
> -   struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
> +   struct vc4_hdmi *vc4_hdmi;
> +
> +   /*
> +* ASoC makes it a bit hard to retrieve a pointer to the
> +* vc4_hdmi structure. Registering the card will overwrite our
> +* device drvdata with a pointer to the snd_soc_card structure,
> +* which can then be used to retrieve whatever drvdata we want
> +* to associate.
> +*
> +* However, that doesn't fly in the case where we wouldn't
> +* register an ASoC card (because of an old DT that is missing
> +* the dmas properties for example), then the card isn't
> +* registered and the device drvdata wouldn't be set.
> +*
> +* We can deal with both cases by making sure a snd_soc_card
> +* pointer and a vc4_hdmi structure are pointing to the same
> +* memory address, so we can treat them indistinctly without any
> +* issue.
> +*/
> +   BUILD_BUG_ON(offsetof(struct vc4_hdmi_audio, card) != 0);
> +   BUILD_BUG_ON(offsetof(struct vc4_hdmi, audio) != 0);
> +   vc4_hdmi = dev_get_drvdata(dev);
>
> cec_unregister_adapter(vc4_hdmi->cec_adap);
> vc4_hdmi_connector_destroy(_hdmi->connector.base);
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 749a807cd1f3..d43462789450 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -53,13 +53,13 @@ struct vc4_hdmi_audio {
>
>  /* General HDMI hardware state. */
>  struct vc4_hdmi {
> +   struct vc4_hdmi_audio audio;
> +
> struct platform_device *pdev;
>
> struct vc4_hdmi_encoder encoder;
> struct vc4_hdmi_connector connector;
>
> -   struct vc4_hdmi_audio audio;
> -
> struct i2c_adapter *ddc;
> void __iomem *hdmicore_regs;
> void __iomem *hd_regs;
> --
> git-series 0.9.1


Re: [PATCH v4 40/78] drm/vc4: hdmi: rework connectors and encoders

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> the vc4_hdmi driver has some custom structures to hold the data it needs to
> associate with the drm_encoder and drm_connector structures.
>
> However, it allocates them separately from the vc4_hdmi structure which
> makes it more complicated than it needs to be.
>
> Move those structures to be contained by vc4_hdmi and update the code
> accordingly.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 87 ---
>  drivers/gpu/drm/vc4/vc4_hdmi.h | 64 +-
>  2 files changed, 72 insertions(+), 79 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index db79e0d88625..1e2214f24ed7 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -191,20 +191,15 @@ static const struct drm_connector_helper_funcs 
> vc4_hdmi_connector_helper_funcs =
> .get_modes = vc4_hdmi_connector_get_modes,
>  };
>
> -static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
> -struct drm_encoder 
> *encoder,
> -struct i2c_adapter *ddc)
> +static int vc4_hdmi_connector_init(struct drm_device *dev,
> +  struct vc4_hdmi *vc4_hdmi,
> +  struct i2c_adapter *ddc)
>  {
> -   struct drm_connector *connector;
> -   struct vc4_hdmi_connector *hdmi_connector;
> +   struct vc4_hdmi_connector *hdmi_connector = _hdmi->connector;
> +   struct drm_connector *connector = _connector->base;
> +   struct drm_encoder *encoder = _hdmi->encoder.base.base;
> int ret;
>
> -   hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
> - GFP_KERNEL);
> -   if (!hdmi_connector)
> -   return ERR_PTR(-ENOMEM);
> -   connector = _connector->base;
> -
> hdmi_connector->encoder = encoder;
>
> drm_connector_init_with_ddc(dev, connector,
> @@ -216,7 +211,7 @@ static struct drm_connector 
> *vc4_hdmi_connector_init(struct drm_device *dev,
> /* Create and attach TV margin props to this connector. */
> ret = drm_mode_create_tv_margin_properties(dev);
> if (ret)
> -   return ERR_PTR(ret);
> +   return ret;
>
> drm_connector_attach_tv_margin_properties(connector);
>
> @@ -228,7 +223,7 @@ static struct drm_connector 
> *vc4_hdmi_connector_init(struct drm_device *dev,
>
> drm_connector_attach_encoder(connector, encoder);
>
> -   return connector;
> +   return 0;
>  }
>
>  static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
> @@ -298,21 +293,22 @@ 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_connector *connector = >connector.base;
> +   struct drm_connector_state *cstate = connector->state;
> struct drm_crtc *crtc = encoder->crtc;
> const struct drm_display_mode *mode = >state->adjusted_mode;
> union hdmi_infoframe frame;
> int ret;
>
> ret = drm_hdmi_avi_infoframe_from_display_mode(,
> -  hdmi->connector, mode);
> +  connector, mode);
> if (ret < 0) {
> DRM_ERROR("couldn't fill AVI infoframe\n");
> return;
> }
>
> drm_hdmi_avi_infoframe_quant_range(,
> -  hdmi->connector, mode,
> +  connector, mode,
>vc4_encoder->limited_rgb_range ?
>HDMI_QUANTIZATION_RANGE_LIMITED :
>HDMI_QUANTIZATION_RANGE_FULL);
> @@ -628,7 +624,8 @@ static const struct drm_encoder_helper_funcs 
> vc4_hdmi_encoder_helper_funcs = {
>  /* HDMI audio codec callbacks */
>  static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
>  {
> -   struct drm_device *drm = hdmi->encoder->dev;
> +   struct drm_encoder *encoder = >encoder.base.base;
> +   struct drm_device *drm = enco

Re: [PATCH v4 31/78] drm/vc4: crtc: Clear the PixelValve FIFO during configuration

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> Even though it's not really clear why we need to flush the PV FIFO during
> the configuration even though we started by flushing it, experience shows
> that without it we get a stale pixel stuck in the FIFO between the HVS and
> the PV.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 13fe0e370fb3..25a77cd46b28 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -358,7 +358,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
> if (is_dsi)
> CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
>
> -   CRTC_WRITE(PV_CONTROL,
> +   CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR |
>vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) |
>VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
>VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
> --
> git-series 0.9.1


Re: [PATCH v4 30/78] drm/vc4: crtc: Clear the PixelValve FIFO on disable

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> In order to avoid a stale pixel getting stuck on mode change or a disable
> / enable cycle, we need to make sure to flush the PV FIFO on disable.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 7b178d67187f..13fe0e370fb3 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -408,8 +408,7 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
> if (vc4_encoder->post_crtc_disable)
> vc4_encoder->post_crtc_disable(encoder);
>
> -   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
> -
> +   vc4_crtc_pixelvalve_reset(crtc);
> vc4_hvs_atomic_disable(crtc, old_state);
>
> if (vc4_encoder->post_crtc_powerdown)
> --
> git-series 0.9.1


Re: [PATCH v4 28/78] drm/vc4: encoder: Add finer-grained encoder callbacks

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> In the BCM2711, the setup of the HVS, pixelvalve and HDMI controller
> requires very precise ordering and timing that the regular atomic callbacks
> don't provide. Let's add new callbacks on top of the regular ones to be
> able to split the configuration as needed.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 19 +++
>  drivers/gpu/drm/vc4/vc4_drv.h  |  7 +++
>  2 files changed, 26 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index b7b0e19e2fe1..d0b326e1df0a 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -389,6 +389,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
>  {
> struct drm_device *dev = crtc->dev;
> struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +   struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
> +   struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
> int ret;
>
> require_hvs_enabled(dev);
> @@ -401,10 +403,16 @@ static void vc4_crtc_atomic_disable(struct drm_crtc 
> *crtc,
> ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
> WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
>
> +   if (vc4_encoder->post_crtc_disable)
> +   vc4_encoder->post_crtc_disable(encoder);
> +
> CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
>
> vc4_hvs_atomic_disable(crtc, old_state);
>
> +   if (vc4_encoder->post_crtc_powerdown)
> +   vc4_encoder->post_crtc_powerdown(encoder);
> +
> /*
>  * Make sure we issue a vblank event after disabling the CRTC if
>  * someone was waiting it.
> @@ -424,6 +432,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
>  {
> struct drm_device *dev = crtc->dev;
> struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +   struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
> +   struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
>
> require_hvs_enabled(dev);
>
> @@ -434,15 +444,24 @@ static void vc4_crtc_atomic_enable(struct drm_crtc 
> *crtc,
>
> vc4_hvs_atomic_enable(crtc, old_state);
>
> +   if (vc4_encoder->pre_crtc_configure)
> +   vc4_encoder->pre_crtc_configure(encoder);
> +
> vc4_crtc_config_pv(crtc);
>
> CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
>
> +   if (vc4_encoder->pre_crtc_enable)
> +   vc4_encoder->pre_crtc_enable(encoder);
> +
> /* When feeding the transposer block the pixelvalve is unneeded and
>  * should not be enabled.
>  */
> CRTC_WRITE(PV_V_CONTROL,
>CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
> +
> +   if (vc4_encoder->post_crtc_enable)
> +   vc4_encoder->post_crtc_enable(encoder);
>  }
>
>  static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index dfcc684f5d28..251fcc35530c 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -439,6 +439,13 @@ struct vc4_encoder {
> struct drm_encoder base;
> enum vc4_encoder_type type;
> u32 clock_select;
> +
> +   void (*pre_crtc_configure)(struct drm_encoder *encoder);
> +   void (*pre_crtc_enable)(struct drm_encoder *encoder);
> +   void (*post_crtc_enable)(struct drm_encoder *encoder);
> +
> +   void (*post_crtc_disable)(struct drm_encoder *encoder);
> +   void (*post_crtc_powerdown)(struct drm_encoder *encoder);
>  };
>
>  static inline struct vc4_encoder *
> --
> git-series 0.9.1


Re: [PATCH v4 27/78] drm/vc4: crtc: Move HVS channel init before the PV initialisation

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> In order to avoid stale pixels getting stuck in an intermediate FIFO
> between the HVS and the pixelvalve on BCM2711, we need to configure the HVS
> channel before the pixelvalve is reset and configured.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 2c5ff45dc315..b7b0e19e2fe1 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -427,10 +427,6 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
>
> require_hvs_enabled(dev);
>
> -   vc4_crtc_config_pv(crtc);
> -
> -   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
> -
> /* Enable vblank irq handling before crtc is started otherwise
>  * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().
>  */
> @@ -438,6 +434,10 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
>
> vc4_hvs_atomic_enable(crtc, old_state);
>
> +   vc4_crtc_config_pv(crtc);
> +
> +   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
> +
> /* When feeding the transposer block the pixelvalve is unneeded and
>  * should not be enabled.
>  */
> --
> git-series 0.9.1


Re: [PATCH v4 26/78] drm/vc4: crtc: Remove redundant pixelvalve reset

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> Since we moved the pixelvalve configuration to atomic_enable, we're now
> first calling the function that resets the pixelvalve and then the one that
> configures it.
>
> However, the first thing the latter is doing is calling the reset function,
> meaning that we reset twice our pixelvalve. Let's remove the first call.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 2eda2e6429ec..2c5ff45dc315 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -427,7 +427,6 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
>
> require_hvs_enabled(dev);
>
> -   vc4_crtc_pixelvalve_reset(crtc);
> vc4_crtc_config_pv(crtc);
>
> CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
> --
> git-series 0.9.1


Re: [PATCH v4 25/78] drm/vc4: crtc: Remove mode_set_nofb

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> On BCM2711 to avoid stale pixels getting stuck in intermediate FIFOs, the
> pixelvalve needs to be setup each time there's a mode change or enable /
> disable sequence.
>
> Therefore, we can't really use mode_set_nofb anymore to configure it, but
> we need to move it to atomic_enable.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 284a85b9d7d4..2eda2e6429ec 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -376,11 +376,6 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
> }
>  }
>
> -static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> -{
> -   vc4_crtc_config_pv(crtc);
> -}
> -
>  static void require_hvs_enabled(struct drm_device *dev)
>  {
> struct vc4_dev *vc4 = to_vc4_dev(dev);
> @@ -433,6 +428,7 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
> require_hvs_enabled(dev);
>
> vc4_crtc_pixelvalve_reset(crtc);
> +   vc4_crtc_config_pv(crtc);
>
> CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
>
> @@ -791,7 +787,6 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = {
>  };
>
>  static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
> -   .mode_set_nofb = vc4_crtc_mode_set_nofb,
> .mode_valid = vc4_crtc_mode_valid,
> .atomic_check = vc4_crtc_atomic_check,
> .atomic_flush = vc4_hvs_atomic_flush,
> --
> git-series 0.9.1


Re: [PATCH v4 24/78] drm/vc4: hvs: Make sure our channel is reset

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> In order to clear our intermediate FIFOs that might end up with a stale
> pixel, let's make sure our FIFO channel is reset everytime our channel is
> setup.

Minor nit pick: s/everytime/every time

> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hvs.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> index c7de77afbf0a..64b9d72471ef 100644
> --- a/drivers/gpu/drm/vc4/vc4_hvs.c
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -205,6 +205,10 @@ static int vc4_hvs_init_channel(struct vc4_dev *vc4, 
> struct drm_crtc *crtc,
> u32 dispbkgndx;
> u32 dispctrl;
>
> +   HVS_WRITE(SCALER_DISPCTRLX(chan), 0);
> +   HVS_WRITE(SCALER_DISPCTRLX(chan), SCALER_DISPCTRLX_RESET);
> +   HVS_WRITE(SCALER_DISPCTRLX(chan), 0);
> +
> /* Turn on the scaler, which will wait for vstart to start
>  * compositing.
>  * When feeding the transposer, we should operate in oneshot
> --
> git-series 0.9.1


Re: [PATCH v4 22/78] drm/vc4: crtc: Move HVS init and close to a function

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> In order to make further refactoring easier, let's move the HVS channel
> setup / teardown to their own function.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_hvs.c | 104 +++
>  1 file changed, 58 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> index 50f9a9674a7e..78bb1c0b0b76 100644
> --- a/drivers/gpu/drm/vc4/vc4_hvs.c
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -196,6 +196,62 @@ static void vc4_hvs_update_gamma_lut(struct drm_crtc 
> *crtc)
> vc4_hvs_lut_load(crtc);
>  }
>
> +static int vc4_hvs_init_channel(struct vc4_dev *vc4, struct drm_crtc *crtc,
> +   struct drm_display_mode *mode, bool oneshot)
> +{
> +   struct vc4_crtc_state *vc4_crtc_state = 
> to_vc4_crtc_state(crtc->state);
> +   unsigned int chan = vc4_crtc_state->assigned_channel;
> +   u32 dispctrl;
> +
> +   /* Turn on the scaler, which will wait for vstart to start
> +* compositing.
> +* When feeding the transposer, we should operate in oneshot
> +* mode.
> +*/
> +   dispctrl = SCALER_DISPCTRLX_ENABLE;
> +
> +   if (!vc4->hvs->hvs5)
> +   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
> + SCALER_DISPCTRLX_WIDTH) |
> +   VC4_SET_FIELD(mode->vdisplay,
> + SCALER_DISPCTRLX_HEIGHT) |
> +   (oneshot ? SCALER_DISPCTRLX_ONESHOT : 0);
> +   else
> +   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
> + SCALER5_DISPCTRLX_WIDTH) |
> +   VC4_SET_FIELD(mode->vdisplay,
> + SCALER5_DISPCTRLX_HEIGHT) |
> +   (oneshot ? SCALER5_DISPCTRLX_ONESHOT : 0);
> +
> +   HVS_WRITE(SCALER_DISPCTRLX(chan), dispctrl);
> +
> +   return 0;
> +}
> +
> +static void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int chan)
> +{
> +   struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +   if (HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE)
> +   return;
> +
> +   HVS_WRITE(SCALER_DISPCTRLX(chan),
> + HVS_READ(SCALER_DISPCTRLX(chan)) | SCALER_DISPCTRLX_RESET);
> +   HVS_WRITE(SCALER_DISPCTRLX(chan),
> + HVS_READ(SCALER_DISPCTRLX(chan)) & 
> ~SCALER_DISPCTRLX_ENABLE);
> +
> +   /* Once we leave, the scaler should be disabled and its fifo empty. */
> +   WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & 
> SCALER_DISPCTRLX_RESET);
> +
> +   WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(chan)),
> +  SCALER_DISPSTATX_MODE) !=
> +SCALER_DISPSTATX_MODE_DISABLED);
> +
> +   WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) &
> + (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
> +SCALER_DISPSTATX_EMPTY);
> +}
> +
>  int vc4_hvs_atomic_check(struct drm_crtc *crtc,
>  struct drm_crtc_state *state)
>  {
> @@ -268,63 +324,19 @@ void vc4_hvs_atomic_enable(struct drm_crtc *crtc,
> struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
> struct drm_display_mode *mode = >state->adjusted_mode;
> bool oneshot = vc4_state->feed_txp;
> -   u32 dispctrl;
>
> vc4_hvs_update_dlist(crtc);
> -
> -   /* Turn on the scaler, which will wait for vstart to start
> -* compositing.
> -* When feeding the transposer, we should operate in oneshot
> -* mode.
> -*/
> -   dispctrl = SCALER_DISPCTRLX_ENABLE;
> -
> -   if (!vc4->hvs->hvs5)
> -   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
> - SCALER_DISPCTRLX_WIDTH) |
> -   VC4_SET_FIELD(mode->vdisplay,
> - SCALER_DISPCTRLX_HEIGHT) |
> -   (oneshot ? SCALER_DISPCTRLX_ONESHOT : 0);
> -   else
> -   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
> - SCALER5_DISPCTRLX_WIDTH) |
> -   VC4_SET_FIELD(mode->vdisplay,
> - SCALER5_DISPCTRLX_HEIGHT) |
> -   (oneshot ? SCALER5_DISPCTRLX_ONESHOT : 0);
> -
> -   HVS_WRITE(SCALER

Re: [PATCH v4 21/78] drm/vc4: crtc: Move PV dump to config_pv

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> Now that we only configure the PixelValve in vc4_crtc_config_pv, it doesn't
> really make much sense to dump its register content in its caller.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 26 --
>  1 file changed, 12 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index c2ab907611e3..181d3fd57bc7 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -290,6 +290,14 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
>vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
> u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : 
> PV_CONTROL_FORMAT_24;
> u8 ppc = pv_data->pixels_per_clock;
> +   bool debug_dump_regs = false;
> +
> +   if (debug_dump_regs) {
> +   struct drm_printer p = drm_info_printer(_crtc->pdev->dev);
> +   dev_info(_crtc->pdev->dev, "CRTC %d regs before:\n",
> +drm_crtc_index(crtc));
> +   drm_print_regset32(, _crtc->regset);
> +   }
>
> vc4_crtc_pixelvalve_reset(crtc);
>
> @@ -359,30 +367,20 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
>PV_CONTROL_WAIT_HSTART |
>VC4_SET_FIELD(vc4_encoder->clock_select,
>  PV_CONTROL_CLK_SELECT));
> -}
> -
> -static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> -{
> -   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> -   bool debug_dump_regs = false;
>
> if (debug_dump_regs) {
> struct drm_printer p = drm_info_printer(_crtc->pdev->dev);
> -   dev_info(_crtc->pdev->dev, "CRTC %d regs before:\n",
> +   dev_info(_crtc->pdev->dev, "CRTC %d regs after:\n",
>  drm_crtc_index(crtc));
> drm_print_regset32(, _crtc->regset);
> }
> +}
>
> +static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> +{
> vc4_crtc_config_pv(crtc);
>
> vc4_hvs_mode_set_nofb(crtc);
> -
> -   if (debug_dump_regs) {
> -   struct drm_printer p = drm_info_printer(_crtc->pdev->dev);
> -   dev_info(_crtc->pdev->dev, "CRTC %d regs after:\n",
> -drm_crtc_index(crtc));
> -   drm_print_regset32(, _crtc->regset);
> -   }
>  }
>
>  static void require_hvs_enabled(struct drm_device *dev)
> --
> git-series 0.9.1


Re: [PATCH v4 12/78] drm/vc4: crtc: Enable and disable the PV in atomic_enable / disable

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:42, Maxime Ripard  wrote:
>
> The VIDEN bit in the pixelvalve currently being used to enable or disable
> the pixelvalve seems to not be enough in some situations, which whill end
> up with the pixelvalve stalling.
>
> In such a case, even re-enabling VIDEN doesn't bring it back and we need to
> clear the FIFO. This can only be done if the pixelvalve is disabled though.
>
> In order to overcome this, we can configure the pixelvalve during
> mode_set_no_fb, but only enable it in atomic_enable and flush the FIFO
> there, and in atomic_disable disable the pixelvalve again.

Very minor nitpick: the configure is in vc4_crtc_config_pv, but that
is called from mode_set_no_fb. The comment is correct from a DRM
overview perspective, but not from the actual code. Describing the DRM
call is probably the better approach, but it looks odd when compared
to the code.

> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index cdeaa0cd981f..fe2e5675aed4 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -332,9 +332,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
>PV_CONTROL_TRIGGER_UNDERFLOW |
>PV_CONTROL_WAIT_HSTART |
>VC4_SET_FIELD(vc4_encoder->clock_select,
> -PV_CONTROL_CLK_SELECT) |
> -  PV_CONTROL_FIFO_CLR |
> -  PV_CONTROL_EN);
> +PV_CONTROL_CLK_SELECT));
>  }
>
>  static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> @@ -386,6 +384,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
> ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
> WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
>
> +   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
> +
> vc4_hvs_atomic_disable(crtc, old_state);
>
> /*
> @@ -410,6 +410,10 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
>
> require_hvs_enabled(dev);
>
> +   /* Reset the PV fifo. */
> +   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) |
> +  PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
> +
> /* Enable vblank irq handling before crtc is started otherwise
>  * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().
>  */
> --
> git-series 0.9.1


Re: [PATCH v4 11/78] drm/vc4: crtc: Use local chan variable

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:42, Maxime Ripard  wrote:
>
> The vc4_crtc_handle_page_flip already has a local variable holding the
> value of vc4_crtc->channel, so let's use it instead.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index d3126fe04d9a..cdeaa0cd981f 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -533,7 +533,7 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc 
> *vc4_crtc)
>  * the CRTC and encoder already reconfigured, leading to
>  * underruns. This can be seen when reconfiguring the CRTC.
>  */
> -   vc4_hvs_unmask_underrun(dev, vc4_crtc->channel);
> +   vc4_hvs_unmask_underrun(dev, chan);
> }
> spin_unlock_irqrestore(>event_lock, flags);
>  }
> --
> git-series 0.9.1


Re: [PATCH v4 10/78] drm/vc4: crtc: Rename HVS channel to output

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:42, Maxime Ripard  wrote:
>
> In vc5, the HVS has 6 outputs and 3 FIFOs (or channels), with
> pixelvalves each being assigned to a given output, but each output can
> then be muxed to feed from multiple FIFOs.
>
> Since vc4 had that entirely static, both were probably equivalent, but
> since that changes, let's rename hvs_channel to hvs_output in the
> vc4_crtc_data, since a pixelvalve is really connected to an output, and
> not to a FIFO.
>
> Signed-off-by: Maxime Ripard 

Reviewed-by: Dave Stevenson 

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 8 
>  drivers/gpu/drm/vc4/vc4_drv.h  | 4 ++--
>  drivers/gpu/drm/vc4/vc4_hvs.c  | 2 +-
>  drivers/gpu/drm/vc4/vc4_txp.c  | 2 +-
>  4 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index fdecaba77836..d3126fe04d9a 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -775,7 +775,7 @@ static const struct drm_crtc_helper_funcs 
> vc4_crtc_helper_funcs = {
>
>  static const struct vc4_pv_data bcm2835_pv0_data = {
> .base = {
> -   .hvs_channel = 0,
> +   .hvs_output = 0,
> },
> .debugfs_name = "crtc0_regs",
> .pixels_per_clock = 1,
> @@ -787,7 +787,7 @@ static const struct vc4_pv_data bcm2835_pv0_data = {
>
>  static const struct vc4_pv_data bcm2835_pv1_data = {
> .base = {
> -   .hvs_channel = 2,
> +   .hvs_output = 2,
> },
> .debugfs_name = "crtc1_regs",
> .pixels_per_clock = 1,
> @@ -799,7 +799,7 @@ static const struct vc4_pv_data bcm2835_pv1_data = {
>
>  static const struct vc4_pv_data bcm2835_pv2_data = {
> .base = {
> -   .hvs_channel = 1,
> +   .hvs_output = 1,
> },
> .debugfs_name = "crtc2_regs",
> .pixels_per_clock = 1,
> @@ -862,7 +862,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
> *vc4_crtc,
> drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
>   crtc_funcs, NULL);
> drm_crtc_helper_add(crtc, crtc_helper_funcs);
> -   vc4_crtc->channel = vc4_crtc->data->hvs_channel;
> +   vc4_crtc->channel = vc4_crtc->data->hvs_output;
> drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
> drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
>
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index d80fc3bbb450..d1cf4c038180 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -447,8 +447,8 @@ to_vc4_encoder(struct drm_encoder *encoder)
>  }
>
>  struct vc4_crtc_data {
> -   /* Which channel of the HVS this pixelvalve sources from. */
> -   int hvs_channel;
> +   /* Which output of the HVS this pixelvalve sources from. */
> +   int hvs_output;
>  };
>
>  struct vc4_pv_data {
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> index 091fdf4908aa..6fd9de1dc65a 100644
> --- a/drivers/gpu/drm/vc4/vc4_hvs.c
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -419,7 +419,7 @@ void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc)
> struct drm_display_mode *mode = >state->adjusted_mode;
> bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
>
> -   if (vc4_crtc->data->hvs_channel == 2) {
> +   if (vc4_crtc->data->hvs_output == 2) {
> u32 dispctrl;
> u32 dsp3_mux;
>
> diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
> index a7c3af0005a0..f39d9900d027 100644
> --- a/drivers/gpu/drm/vc4/vc4_txp.c
> +++ b/drivers/gpu/drm/vc4/vc4_txp.c
> @@ -452,7 +452,7 @@ static irqreturn_t vc4_txp_interrupt(int irq, void *data)
>  }
>
>  static const struct vc4_crtc_data vc4_txp_crtc_data = {
> -   .hvs_channel = 2,
> +   .hvs_output = 2,
>  };
>
>  static int vc4_txp_bind(struct device *dev, struct device *master, void 
> *data)
> --
> git-series 0.9.1


Re: [PATCH v3 032/105] drm/vc4: crtc: Enable and disable the PV in atomic_enable / disable

2020-06-02 Thread Dave Stevenson
Hi Maxime and Eric

On Tue, 2 Jun 2020 at 15:12, Maxime Ripard  wrote:
>
> Hi Eric
>
> On Wed, May 27, 2020 at 09:54:44AM -0700, Eric Anholt wrote:
> > On Wed, May 27, 2020 at 8:50 AM Maxime Ripard  wrote:
> > >
> > > The VIDEN bit in the pixelvalve currently being used to enable or disable
> > > the pixelvalve seems to not be enough in some situations, which whill end
> > > up with the pixelvalve stalling.
> > >
> > > In such a case, even re-enabling VIDEN doesn't bring it back and we need 
> > > to
> > > clear the FIFO. This can only be done if the pixelvalve is disabled 
> > > though.
> > >
> > > In order to overcome this, we can configure the pixelvalve during
> > > mode_set_no_fb, but only enable it in atomic_enable and flush the FIFO
> > > there, and in atomic_disable disable the pixelvalve again.
> >
> > What displays has this been tested with?  Getting this sequencing
> > right is so painful, and things like DSI are tricky to get to light
> > up.
>
> That FIFO is between the HVS and the HDMI PVs, so this was obviously
> tested against that. Dave also tested the DSI output IIRC, so we should
> be covered here.

DSI wasn't working on the first patch set that Maxime sent - I haven't
tested this one as yet but will do so.
DPI was working early on to both an Adafruit 800x480 DPI panel, and
via a VGA666 as VGA.
HDMI is obviously working.
VEC is being ignored now. The clock structure is more restricted than
earlier chips, so to get the required clocks for the VEC without using
fractional divides it compromises the clock that other parts of the
system can run at (IIRC including the ARM). That's why the VEC has to
be explicitly enabled for the firmware to enable it as the only
output. It's annoying, but that's just a restriction of the chip.

  Dave


Re: [PATCH v3 07/10] media: i2c: imx290: Add RAW12 mode support

2020-05-26 Thread Dave Stevenson
Hi Andrey

Thanks for the patch.

On Sun, 24 May 2020 at 20:26, Andrey Konovalov
 wrote:
>
> From: Manivannan Sadhasivam 
>
> IMX290 is capable of outputting frames in both Raw Bayer (packed) 10 and
> 12 bit formats. Since the driver already supports RAW10 mode, let's add
> the missing RAW12 mode as well.
>
> Signed-off-by: Manivannan Sadhasivam 
> Signed-off-by: Andrey Konovalov 
> ---
>  drivers/media/i2c/imx290.c | 36 +---
>  1 file changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
> index 162c345fffac..6e70ff22bc5f 100644
> --- a/drivers/media/i2c/imx290.c
> +++ b/drivers/media/i2c/imx290.c
> @@ -71,6 +71,7 @@ struct imx290 {
> struct clk *xclk;
> struct regmap *regmap;
> u8 nlanes;
> +   u8 bpp;
>
> struct v4l2_subdev sd;
> struct v4l2_fwnode_endpoint ep;
> @@ -90,10 +91,12 @@ struct imx290 {
>
>  struct imx290_pixfmt {
> u32 code;
> +   u8 bpp;
>  };
>
>  static const struct imx290_pixfmt imx290_formats[] = {
> -   { MEDIA_BUS_FMT_SRGGB10_1X10 },
> +   { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
> +   { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
>  };
>
>  static const struct regmap_config imx290_regmap_config = {
> @@ -261,6 +264,18 @@ static const struct imx290_regval 
> imx290_10bit_settings[] = {
> { 0x300b, 0x00},
>  };
>
> +static const struct imx290_regval imx290_12bit_settings[] = {
> +   { 0x3005, 0x01 },
> +   { 0x3046, 0x01 },
> +   { 0x3129, 0x00 },
> +   { 0x317c, 0x00 },
> +   { 0x31ec, 0x0e },
> +   { 0x3441, 0x0c },
> +   { 0x3442, 0x0c },
> +   { 0x300a, 0xf0 },
> +   { 0x300b, 0x00 },
> +};
> +
>  /* supported link frequencies */
>  static const s64 imx290_link_freq_2lanes[] = {
> 89100, /* 1920x1080 -  2 lane */
> @@ -421,7 +436,12 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl)
> } else {
> imx290_write_reg(imx290, IMX290_PGCTRL, 0x00);
> msleep(10);
> -   imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x3c);
> +   if (imx290->bpp == 10)
> +   imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW,
> +0x3c);
> +   else /* 12 bits per pixel */
> +   imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW,
> +0xf0);
> imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00);
> }
> break;
> @@ -496,7 +516,7 @@ static u64 imx290_calc_pixel_rate(struct imx290 *imx290)
> u8 nlanes = imx290->nlanes;
>
> /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
> -   return (link_freq * 2 * nlanes / 10);
> +   return (link_freq * 2 * nlanes / imx290->bpp);

This doesn't link on a 32bit system as it's a 64bit divide:
ERROR: "__aeabi_ldivmod" [drivers/media/i2c/imx290.ko] undefined!
It ought to be using do_div().

Admittedly it didn't compile before as you still had a s64 divide by
10, but I hadn't tried that :-)

  Dave

>  }
>
>  static int imx290_set_fmt(struct v4l2_subdev *sd,
> @@ -533,6 +553,7 @@ static int imx290_set_fmt(struct v4l2_subdev *sd,
> } else {
> format = >current_format;
> imx290->current_mode = mode;
> +   imx290->bpp = imx290_formats[i].bpp;
>
> if (imx290->link_freq)
> __v4l2_ctrl_s_ctrl(imx290->link_freq,
> @@ -577,6 +598,15 @@ static int imx290_write_current_format(struct imx290 
> *imx290)
> return ret;
> }
> break;
> +   case MEDIA_BUS_FMT_SRGGB12_1X12:
> +   ret = imx290_set_register_array(imx290, imx290_12bit_settings,
> +   ARRAY_SIZE(
> +   
> imx290_12bit_settings));
> +   if (ret < 0) {
> +   dev_err(imx290->dev, "Could not set format 
> registers\n");
> +   return ret;
> +   }
> +   break;
> default:
> dev_err(imx290->dev, "Unknown pixel format\n");
> return -EINVAL;
> --
> 2.17.1
>


Re: [PATCH v2 79/91] drm/vc4: hdmi: Deal with multiple debugfs files

2020-04-28 Thread Dave Stevenson
Hi Stefan and Maxime

On Tue, 28 Apr 2020 at 16:57, Maxime Ripard  wrote:
>
> Hi Stefan,
>
> On Sat, Apr 25, 2020 at 11:26:31PM +0200, Stefan Wahren wrote:
> > Am 24.04.20 um 17:35 schrieb Maxime Ripard:
> > > The HDMI driver was registering a single debugfs file so far with the name
> > > hdmi_regs.
> > >
> > > Obviously, this is not going to work anymore when will have multiple HDMI
> > > controllers since we will end up trying to register two files with the 
> > > same
> > > name.
> > >
> > > Let's use the ID to avoid that name conflict.
> >
> > even with this patch there is a name conflict in debugfs using Linux
> > 5.7-rc1. Dave Stevenson addressed this by using different card names
> > [1]. Since this patch won't apply anymore here is my suggestion:
> >
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index 29287ab..7209397 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -1181,9 +1181,14 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi
> > *vc4_hdmi)
> >
> >  card->dai_link = dai_link;
> >  card->num_links = 1;
> > -card->name = "vc4-hdmi";
> >  card->dev = dev;
> >
> > +if (vc4_hdmi->variant->encoder_type == VC4_ENCODER_TYPE_HDMI1) {
> > +card->name = "vc4-hdmi1";
> > +} else {
> > +card->name = "vc4-hdmi";
> > +}
> > +
>
> Thinking about this some more, we don't really need VC4_ENCODER_TYPE_HDMI0 and
> HDMI1, and it can all work with the same encoder type for both, so I'll drop
> them.
>
> To address this issue though, we can add a card name string to the variant, 
> like
> I did for debugfs. Is that alright for you?

My patch doesn't fix everything with the audio debugfs entries anyway.
I'm working against 5.4 on our downstream tree, and even with my patch
I get
[7.459508] debugfs: Directory 'fef00700.hdmi' with parent
'vc4-hdmi' already present!
[7.511017] debugfs: Directory 'fef05700.hdmi' with parent
'vc4-hdmi1' already present!
I seem to recall I reduced the number of complaints over 'vc4-hdmi',
but internal to sound/soc-core the node is still registered twice.

There was discussion about this a few months back.
https://lore.kernel.org/lkml/1jblpvraho@starbuckisacylon.baylibre.com/
seemed to conclude that it wasn't totally trivial to solve.

Regards,
  Dave


Re: [PATCH] media: i2c: imx219: remove redundant writes

2020-04-28 Thread Dave Stevenson
Hi Sameer

Thanks for the patch.

On Mon, 13 Apr 2020 at 16:51, Sameer Puri  wrote:
>
> These writes to 0x162, 0x163 already appear earlier in the struct for
> the 1920x1080 mode and do not need to be repeated.
>
> Signed-off-by: Sameer Puri 

Reviewed-by: Dave Stevenson 

If I was going to be fussy, it would be nice to have the writes to
0x162/0x163 in a consistent place in the table, which is generally the
end (I'm aware that the 640x480 mode has it in the middle). Personally
I'm not overly worried, but others may prefer it.

> ---
>  drivers/media/i2c/imx219.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> index cb03bdec1f9c..53dafb7f5f2c 100644
> --- a/drivers/media/i2c/imx219.c
> +++ b/drivers/media/i2c/imx219.c
> @@ -253,8 +253,6 @@ static const struct imx219_reg mode_1920_1080_regs[] = {
> {0x4793, 0x10},
> {0x4797, 0x0e},
> {0x479b, 0x0e},
> -   {0x0162, 0x0d},
> -   {0x0163, 0x78},
>  };
>
>  static const struct imx219_reg mode_1640_1232_regs[] = {
>
> base-commit: 8f3d9f354286745c751374f5f1fcafee6b3f3136
> --
> 2.26.0
>
>


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-29 Thread Dave Stevenson
Hi Stefan

On Sun, 28 Oct 2018 at 08:31, Stefan Wahren  wrote:
>
> Hi Dave,
>
> > Dave Stevenson  hat am 26. Oktober 2018 um 
> > 19:15 geschrieben:
> >
> >
> > Thanks Stefan.
> > I've picked up your latest patches which mean I can get the driver
> > loaded via the (almost) approved method.
> > I do seem to still have issues with not getting the expected address
> > ranges, so the driver/VPU was trying to map cached alias memory. As
> > your patches only came through yesterday I haven't had a chance to dig
> > through why yet. I've done a temporary hack to ensure we always map
> > the uncached alias, but that can't persist.
>
> does it mean with DT probing it worked before and with platform change it's 
> broken?
> Or anything else cause this regression in 4.19?

Yes, probing via DT with the node under soc gave me the correct DMA
addresses (uncached alias). With the platform changes I get the cached
alias.
Both were under 4.14. I'll try again on a later branch.

> > The networking issue has been resolved :-)
> >
> > I've pushed where I've got to to
> > https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2b
> > It's a touch messy due to integrating in your patches in the last 24
> > hours. It needs a full rebase so that my changes are on top of yours
> > rather than haphazard.
> > As we're moving to 4.19 fairly soon I may well abandon my 4.14 tree
> > and jump to either that or directly on staging. I'll see where I get
> > to early next week.
>
> Sorry, but there is no need for a quick shot against a downstream 4.14. I 
> assumed you make your changes against upstream linux-next + Phil's and my 
> patches.
>
> You can use https://github.com/anholt/linux/commits/bcm2835-audio until 
> 4.20-rc1 is out.
> Using 4.14 or 4.19 doesn't make any sense to me.

As an employee of Raspberry Pi Trading my first responsibilty is to
them, and that means LTS releases feeding in to the downstream kernel.
If these drivers can be pushed upstream then that's a win as it avoids
divergence, but it is not my main goal. At least 4.19 and 4.20 aren't
far apart so there are likely to be fewer differences.

I had it all working on 4.14, therefore it made sense to see whether
your changes allowed me to load as a platform driver. It did, but with
this little niggle over cache aliases. I'll try again on a later
kernel and try to get some more info.

  Dave


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-29 Thread Dave Stevenson
Hi Stefan

On Sun, 28 Oct 2018 at 08:31, Stefan Wahren  wrote:
>
> Hi Dave,
>
> > Dave Stevenson  hat am 26. Oktober 2018 um 
> > 19:15 geschrieben:
> >
> >
> > Thanks Stefan.
> > I've picked up your latest patches which mean I can get the driver
> > loaded via the (almost) approved method.
> > I do seem to still have issues with not getting the expected address
> > ranges, so the driver/VPU was trying to map cached alias memory. As
> > your patches only came through yesterday I haven't had a chance to dig
> > through why yet. I've done a temporary hack to ensure we always map
> > the uncached alias, but that can't persist.
>
> does it mean with DT probing it worked before and with platform change it's 
> broken?
> Or anything else cause this regression in 4.19?

Yes, probing via DT with the node under soc gave me the correct DMA
addresses (uncached alias). With the platform changes I get the cached
alias.
Both were under 4.14. I'll try again on a later branch.

> > The networking issue has been resolved :-)
> >
> > I've pushed where I've got to to
> > https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2b
> > It's a touch messy due to integrating in your patches in the last 24
> > hours. It needs a full rebase so that my changes are on top of yours
> > rather than haphazard.
> > As we're moving to 4.19 fairly soon I may well abandon my 4.14 tree
> > and jump to either that or directly on staging. I'll see where I get
> > to early next week.
>
> Sorry, but there is no need for a quick shot against a downstream 4.14. I 
> assumed you make your changes against upstream linux-next + Phil's and my 
> patches.
>
> You can use https://github.com/anholt/linux/commits/bcm2835-audio until 
> 4.20-rc1 is out.
> Using 4.14 or 4.19 doesn't make any sense to me.

As an employee of Raspberry Pi Trading my first responsibilty is to
them, and that means LTS releases feeding in to the downstream kernel.
If these drivers can be pushed upstream then that's a win as it avoids
divergence, but it is not my main goal. At least 4.19 and 4.20 aren't
far apart so there are likely to be fewer differences.

I had it all working on 4.14, therefore it made sense to see whether
your changes allowed me to load as a platform driver. It did, but with
this little niggle over cache aliases. I'll try again on a later
kernel and try to get some more info.

  Dave


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-26 Thread Dave Stevenson
On Thu, 18 Oct 2018 at 10:38, Stefan Wahren  wrote:
>
> Am 18.10.2018 um 11:22 schrieb Dave Stevenson:
> > On Wed, 17 Oct 2018 at 17:51, Peter Robinson  wrote:
> >>>>>> Drop various pieces of dead code from here and there to get rid of
> >>>>>> the remaining users of VCHI_CONNECTION_T. After that we get to drop
> >>>>>> entire header files worth of unused code.
> >>>>>>
> >>>>>> I've tested on a Raspberry Pi Model B (bcm2835_defconfig) that
> >>>>>> snd-bcm2835 can still play analog audio just fine.
> >>>>>>
> >>>>> thanks and i'm fine with your patch series:
> >>>>>
> >>>>> Acked-by: Stefan Wahren 
> >>>>>
> >>>>> Unfortunately this would break compilation of the downstream vchi
> >>>>> drivers like vcsm [1]. Personally i don't want to maintain another
> >>>>> one, because i cannot see the gain of the resulting effort.
> >>>>>
> >>>>> [1] - 
> >>>>> https://github.com/raspberrypi/linux/tree/rpi-4.14.y/drivers/char/broadcom/vc_sm
> >>>>
> >>>> I feel like everyone else already knows the answer but why don't we just
> >>>> merge that code into staging?
> >>> Dave's been working on a new VCSM service where the firmware can call
> >>> back into Linux to allocate (instead of just having a permanent carveout
> >>> of system memory that the firmware allocates from), and lets us make
> >>> dma-bufs out of those buffers.  That driver makes a no-copies v4l2 media
> >>> decode driver possible, which would then let Kodi and similar projects
> >>> switch from downstream kernels with closed graphics to upstream kernels
> >>> with open graphics.
> >>>
> >>> Given that the new VCSM service is a rewrite, it's not clear to me that
> >>> importing the old VCSM driver is a win.  But maybe we should go raid
> >>> https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2a and grab
> >>> the new drivers.  Upstreaming the VCHI audio driver to staging has
> >>> clearly been a win for it, so maybe other eyes on the new v4l2 codec
> >>> could help Dave along in stabilizing it.
> >> I think that makes sense as long as the firmware side changes are in
> >> place so it can actually be used.
> > The firmware has supported the necessary for dmabuf import since Sept 2017.
> >
> > The new vcsm driver currently only supports importing from other
> > kernel modules as I cut it back to the bare minimum to ease
> > upstreaming. To be a complete replacement of the existing then it
> > needs to support userspace alloc/free/import/mmap. I did have most of
> > that working, but will add it in stages.
> > The codec code is working for decode but something is off for setting
> > formats on encode.
> > Both drivers are loading through DT at the moment as I couldn't get
> > Eric's platform driver stuff working. IIRC A combination of modules
> > not getting loaded and getting the appropriate coherent DMA mask set
> > (being under soc in DT gives the correct mappings, but being a
> > platform driver didn't).
>
> I'm working on these issues and i will post a proper solution soon.
>
> In case you need a hack in order to test your stuff, i can prepare a
> branch for you.

Thanks Stefan.
I've picked up your latest patches which mean I can get the driver
loaded via the (almost) approved method.
I do seem to still have issues with not getting the expected address
ranges, so the driver/VPU was trying to map cached alias memory. As
your patches only came through yesterday I haven't had a chance to dig
through why yet. I've done a temporary hack to ensure we always map
the uncached alias, but that can't persist.

> >
> > I'm fire-fighting a networking issue at the moment, but hope to be
> > back on codecs next week.
> > Could you hold off raiding my trees until say Fri 26th Oct so I can
> > ensure they are fully up to date? If I get a chance then I'll start
> > the work of porting into staging before then.
>
> The merge window will open soon, so i don't see the need to hurry.

The networking issue has been resolved :-)

I've pushed where I've got to to
https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2b
It's a touch messy due to integrating in your patches in the last 24
hours. It needs a full rebase so that my changes are on top of yours
rather than haphazard.
As we're moving to 4.19 fairly soon I may well abandon my 4.14 tree
and jump to either that or directly on staging. I'll see where I get
to early next week.

  Dave


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-26 Thread Dave Stevenson
On Thu, 18 Oct 2018 at 10:38, Stefan Wahren  wrote:
>
> Am 18.10.2018 um 11:22 schrieb Dave Stevenson:
> > On Wed, 17 Oct 2018 at 17:51, Peter Robinson  wrote:
> >>>>>> Drop various pieces of dead code from here and there to get rid of
> >>>>>> the remaining users of VCHI_CONNECTION_T. After that we get to drop
> >>>>>> entire header files worth of unused code.
> >>>>>>
> >>>>>> I've tested on a Raspberry Pi Model B (bcm2835_defconfig) that
> >>>>>> snd-bcm2835 can still play analog audio just fine.
> >>>>>>
> >>>>> thanks and i'm fine with your patch series:
> >>>>>
> >>>>> Acked-by: Stefan Wahren 
> >>>>>
> >>>>> Unfortunately this would break compilation of the downstream vchi
> >>>>> drivers like vcsm [1]. Personally i don't want to maintain another
> >>>>> one, because i cannot see the gain of the resulting effort.
> >>>>>
> >>>>> [1] - 
> >>>>> https://github.com/raspberrypi/linux/tree/rpi-4.14.y/drivers/char/broadcom/vc_sm
> >>>>
> >>>> I feel like everyone else already knows the answer but why don't we just
> >>>> merge that code into staging?
> >>> Dave's been working on a new VCSM service where the firmware can call
> >>> back into Linux to allocate (instead of just having a permanent carveout
> >>> of system memory that the firmware allocates from), and lets us make
> >>> dma-bufs out of those buffers.  That driver makes a no-copies v4l2 media
> >>> decode driver possible, which would then let Kodi and similar projects
> >>> switch from downstream kernels with closed graphics to upstream kernels
> >>> with open graphics.
> >>>
> >>> Given that the new VCSM service is a rewrite, it's not clear to me that
> >>> importing the old VCSM driver is a win.  But maybe we should go raid
> >>> https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2a and grab
> >>> the new drivers.  Upstreaming the VCHI audio driver to staging has
> >>> clearly been a win for it, so maybe other eyes on the new v4l2 codec
> >>> could help Dave along in stabilizing it.
> >> I think that makes sense as long as the firmware side changes are in
> >> place so it can actually be used.
> > The firmware has supported the necessary for dmabuf import since Sept 2017.
> >
> > The new vcsm driver currently only supports importing from other
> > kernel modules as I cut it back to the bare minimum to ease
> > upstreaming. To be a complete replacement of the existing then it
> > needs to support userspace alloc/free/import/mmap. I did have most of
> > that working, but will add it in stages.
> > The codec code is working for decode but something is off for setting
> > formats on encode.
> > Both drivers are loading through DT at the moment as I couldn't get
> > Eric's platform driver stuff working. IIRC A combination of modules
> > not getting loaded and getting the appropriate coherent DMA mask set
> > (being under soc in DT gives the correct mappings, but being a
> > platform driver didn't).
>
> I'm working on these issues and i will post a proper solution soon.
>
> In case you need a hack in order to test your stuff, i can prepare a
> branch for you.

Thanks Stefan.
I've picked up your latest patches which mean I can get the driver
loaded via the (almost) approved method.
I do seem to still have issues with not getting the expected address
ranges, so the driver/VPU was trying to map cached alias memory. As
your patches only came through yesterday I haven't had a chance to dig
through why yet. I've done a temporary hack to ensure we always map
the uncached alias, but that can't persist.

> >
> > I'm fire-fighting a networking issue at the moment, but hope to be
> > back on codecs next week.
> > Could you hold off raiding my trees until say Fri 26th Oct so I can
> > ensure they are fully up to date? If I get a chance then I'll start
> > the work of porting into staging before then.
>
> The merge window will open soon, so i don't see the need to hurry.

The networking issue has been resolved :-)

I've pushed where I've got to to
https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2b
It's a touch messy due to integrating in your patches in the last 24
hours. It needs a full rebase so that my changes are on top of yours
rather than haphazard.
As we're moving to 4.19 fairly soon I may well abandon my 4.14 tree
and jump to either that or directly on staging. I'll see where I get
to early next week.

  Dave


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-18 Thread Dave Stevenson
On Wed, 17 Oct 2018 at 17:51, Peter Robinson  wrote:
>
> > >> > Drop various pieces of dead code from here and there to get rid of
> > >> > the remaining users of VCHI_CONNECTION_T. After that we get to drop
> > >> > entire header files worth of unused code.
> > >> >
> > >> > I've tested on a Raspberry Pi Model B (bcm2835_defconfig) that
> > >> > snd-bcm2835 can still play analog audio just fine.
> > >> >
> > >>
> > >> thanks and i'm fine with your patch series:
> > >>
> > >> Acked-by: Stefan Wahren 
> > >>
> > >> Unfortunately this would break compilation of the downstream vchi
> > >> drivers like vcsm [1]. Personally i don't want to maintain another
> > >> one, because i cannot see the gain of the resulting effort.
> > >>
> > >> [1] - 
> > >> https://github.com/raspberrypi/linux/tree/rpi-4.14.y/drivers/char/broadcom/vc_sm
> > >
> > >
> > > I feel like everyone else already knows the answer but why don't we just
> > > merge that code into staging?
> >
> > Dave's been working on a new VCSM service where the firmware can call
> > back into Linux to allocate (instead of just having a permanent carveout
> > of system memory that the firmware allocates from), and lets us make
> > dma-bufs out of those buffers.  That driver makes a no-copies v4l2 media
> > decode driver possible, which would then let Kodi and similar projects
> > switch from downstream kernels with closed graphics to upstream kernels
> > with open graphics.
> >
> > Given that the new VCSM service is a rewrite, it's not clear to me that
> > importing the old VCSM driver is a win.  But maybe we should go raid
> > https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2a and grab
> > the new drivers.  Upstreaming the VCHI audio driver to staging has
> > clearly been a win for it, so maybe other eyes on the new v4l2 codec
> > could help Dave along in stabilizing it.
>
> I think that makes sense as long as the firmware side changes are in
> place so it can actually be used.

The firmware has supported the necessary for dmabuf import since Sept 2017.

The new vcsm driver currently only supports importing from other
kernel modules as I cut it back to the bare minimum to ease
upstreaming. To be a complete replacement of the existing then it
needs to support userspace alloc/free/import/mmap. I did have most of
that working, but will add it in stages.
The codec code is working for decode but something is off for setting
formats on encode.
Both drivers are loading through DT at the moment as I couldn't get
Eric's platform driver stuff working. IIRC A combination of modules
not getting loaded and getting the appropriate coherent DMA mask set
(being under soc in DT gives the correct mappings, but being a
platform driver didn't).

I'm fire-fighting a networking issue at the moment, but hope to be
back on codecs next week.
Could you hold off raiding my trees until say Fri 26th Oct so I can
ensure they are fully up to date? If I get a chance then I'll start
the work of porting into staging before then.

  Dave


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-18 Thread Dave Stevenson
On Wed, 17 Oct 2018 at 17:51, Peter Robinson  wrote:
>
> > >> > Drop various pieces of dead code from here and there to get rid of
> > >> > the remaining users of VCHI_CONNECTION_T. After that we get to drop
> > >> > entire header files worth of unused code.
> > >> >
> > >> > I've tested on a Raspberry Pi Model B (bcm2835_defconfig) that
> > >> > snd-bcm2835 can still play analog audio just fine.
> > >> >
> > >>
> > >> thanks and i'm fine with your patch series:
> > >>
> > >> Acked-by: Stefan Wahren 
> > >>
> > >> Unfortunately this would break compilation of the downstream vchi
> > >> drivers like vcsm [1]. Personally i don't want to maintain another
> > >> one, because i cannot see the gain of the resulting effort.
> > >>
> > >> [1] - 
> > >> https://github.com/raspberrypi/linux/tree/rpi-4.14.y/drivers/char/broadcom/vc_sm
> > >
> > >
> > > I feel like everyone else already knows the answer but why don't we just
> > > merge that code into staging?
> >
> > Dave's been working on a new VCSM service where the firmware can call
> > back into Linux to allocate (instead of just having a permanent carveout
> > of system memory that the firmware allocates from), and lets us make
> > dma-bufs out of those buffers.  That driver makes a no-copies v4l2 media
> > decode driver possible, which would then let Kodi and similar projects
> > switch from downstream kernels with closed graphics to upstream kernels
> > with open graphics.
> >
> > Given that the new VCSM service is a rewrite, it's not clear to me that
> > importing the old VCSM driver is a win.  But maybe we should go raid
> > https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push-pt2a and grab
> > the new drivers.  Upstreaming the VCHI audio driver to staging has
> > clearly been a win for it, so maybe other eyes on the new v4l2 codec
> > could help Dave along in stabilizing it.
>
> I think that makes sense as long as the firmware side changes are in
> place so it can actually be used.

The firmware has supported the necessary for dmabuf import since Sept 2017.

The new vcsm driver currently only supports importing from other
kernel modules as I cut it back to the bare minimum to ease
upstreaming. To be a complete replacement of the existing then it
needs to support userspace alloc/free/import/mmap. I did have most of
that working, but will add it in stages.
The codec code is working for decode but something is off for setting
formats on encode.
Both drivers are loading through DT at the moment as I couldn't get
Eric's platform driver stuff working. IIRC A combination of modules
not getting loaded and getting the appropriate coherent DMA mask set
(being under soc in DT gives the correct mappings, but being a
platform driver didn't).

I'm fire-fighting a networking issue at the moment, but hope to be
back on codecs next week.
Could you hold off raiding my trees until say Fri 26th Oct so I can
ensure they are fully up to date? If I get a chance then I'll start
the work of porting into staging before then.

  Dave


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-17 Thread Dave Stevenson
On Mon, 15 Oct 2018 at 17:27, Eric Anholt  wrote:
>
> Stefan Wahren  writes:
>
> > Hi Tuomas,
> >
> >> Tuomas Tynkkynen  hat am 4. Oktober 2018 um 11:37 
> >> geschrieben:
> >>
> >>
> >> Drop various pieces of dead code from here and there to get rid of
> >> the remaining users of VCHI_CONNECTION_T. After that we get to drop
> >> entire header files worth of unused code.
> >>
> >> I've tested on a Raspberry Pi Model B (bcm2835_defconfig) that
> >> snd-bcm2835 can still play analog audio just fine.
> >>
> >
> > thanks and i'm fine with your patch series:
> >
> > Acked-by: Stefan Wahren 
> >
> > Unfortunately this would break compilation of the downstream vchi
> > drivers like vcsm [1]. Personally i don't want to maintain another
> > one, because i cannot see the gain of the resulting effort.
> >
> > [1] - 
> > https://github.com/raspberrypi/linux/tree/rpi-4.14.y/drivers/char/broadcom/vc_sm

I'm happy enough to work around these changes. Once the change is in a
released kernel we can merge a modified version of vc_sm into the
downstream kernel branch. It's not as if it requires big changes.

> I think the main concern would be if we removed things necessary for
> 6by9's new vcsm (the one that will let us do dma-buf sharing between
> media decode and DRM).

The new vcsm uses the same VCHI service as the existing downstream vc_sm driver.
The video codec driver don't use any VCHI functionality over and above
the camera. It goes via a slightly extended version of the
mmal-vchiq.c, which I have split out into a shared module.

> On the other hand, git revert is a thing, so it's not like we actually
> lose anything.

:-)

  Dave


Re: [PATCH 0/7] staging: vc04_services: Some dead code removal

2018-10-17 Thread Dave Stevenson
On Mon, 15 Oct 2018 at 17:27, Eric Anholt  wrote:
>
> Stefan Wahren  writes:
>
> > Hi Tuomas,
> >
> >> Tuomas Tynkkynen  hat am 4. Oktober 2018 um 11:37 
> >> geschrieben:
> >>
> >>
> >> Drop various pieces of dead code from here and there to get rid of
> >> the remaining users of VCHI_CONNECTION_T. After that we get to drop
> >> entire header files worth of unused code.
> >>
> >> I've tested on a Raspberry Pi Model B (bcm2835_defconfig) that
> >> snd-bcm2835 can still play analog audio just fine.
> >>
> >
> > thanks and i'm fine with your patch series:
> >
> > Acked-by: Stefan Wahren 
> >
> > Unfortunately this would break compilation of the downstream vchi
> > drivers like vcsm [1]. Personally i don't want to maintain another
> > one, because i cannot see the gain of the resulting effort.
> >
> > [1] - 
> > https://github.com/raspberrypi/linux/tree/rpi-4.14.y/drivers/char/broadcom/vc_sm

I'm happy enough to work around these changes. Once the change is in a
released kernel we can merge a modified version of vc_sm into the
downstream kernel branch. It's not as if it requires big changes.

> I think the main concern would be if we removed things necessary for
> 6by9's new vcsm (the one that will let us do dma-buf sharing between
> media decode and DRM).

The new vcsm uses the same VCHI service as the existing downstream vc_sm driver.
The video codec driver don't use any VCHI functionality over and above
the camera. It goes via a slightly extended version of the
mmal-vchiq.c, which I have split out into a shared module.

> On the other hand, git revert is a thing, so it's not like we actually
> lose anything.

:-)

  Dave


Re: [PATCH] staging: bcm2835-camera: remove extraneous setting of dev->colourfx.enable

2018-10-08 Thread Dave Stevenson
 Hi Stefan.

Thanks for forwarding as the linux-rpi-kernel list hasn't sent it to me as yet.

On Mon, 8 Oct 2018 at 16:48, Stefan Wahren  wrote:
>
> Hi Colin,
>
> Am 08.10.2018 um 16:50 schrieb Colin King:
> > From: Colin Ian King 
> >
> > Currently dev->colourfx.enable is being set twice, hence the first
> > occurrance is redundant and can be removed, so remove it. This minor
> > issue was introduced by commit 7b3ad5abf027 ("staging: Import the
> > BCM2835 MMAL-based V4L2 camera driver.").
> >
> > Detected by CoverityScan CID#1419711 ("Unused value")
> >
> > Signed-off-by: Colin Ian King 
> > ---
> >  drivers/staging/vc04_services/bcm2835-camera/controls.c | 1 -
> >  1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c 
> > b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > index a2c55cb2192a..99831dd4365d 100644
> > --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > @@ -588,7 +588,6 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev *dev,
> >
> >   control = >component[MMAL_COMPONENT_CAMERA]->control;
> >
> > - dev->colourfx.enable = (ctrl->val & 0xff00) >> 8;
> >   dev->colourfx.enable = ctrl->val & 0xff;
> >
> >   ret = vchiq_mmal_port_parameter_set(dev->instance, control,
>
> as long as the current behavior is correct, i'm okay with this patch.
> But the byte masking looks suspicious, so i hope Dave can clarify that.

It's writing to the wrong structure member.
The function is used on the V4L2 control V4L2_CID_COLORFX_CBCR, which
is defined as:
V4L2_CID_COLORFX_CBCR (integer)
Determines the Cb and Cr coefficients for V4L2_COLORFX_SET_CBCR color
effect. Bits [7:0] of the supplied 32 bit value are interpreted as Cr
component, bits [15:8] as Cb component and bits [31:16] must be zero.

ctrl->val should therefore be setting dev->colourfx.u and
dev->colourfx.v with those masks. dev->colourfx.enable field should
have been set when going through ctrl_set_image_effect for contol
V4L2_CID_COLORFX set to V4L2_COLORFX_SET_CBCR.

I've confirmed with qv4l2 that that is what is wrong. That's only been
lurking there for almost 5 years - shows how often these weirder
effects get used.
I don't mind whether Colin's patch gets merged and then fixed up, or
drop Colin's patch and apply the correct logic via a new patch.

  Dave


Re: [PATCH] staging: bcm2835-camera: remove extraneous setting of dev->colourfx.enable

2018-10-08 Thread Dave Stevenson
 Hi Stefan.

Thanks for forwarding as the linux-rpi-kernel list hasn't sent it to me as yet.

On Mon, 8 Oct 2018 at 16:48, Stefan Wahren  wrote:
>
> Hi Colin,
>
> Am 08.10.2018 um 16:50 schrieb Colin King:
> > From: Colin Ian King 
> >
> > Currently dev->colourfx.enable is being set twice, hence the first
> > occurrance is redundant and can be removed, so remove it. This minor
> > issue was introduced by commit 7b3ad5abf027 ("staging: Import the
> > BCM2835 MMAL-based V4L2 camera driver.").
> >
> > Detected by CoverityScan CID#1419711 ("Unused value")
> >
> > Signed-off-by: Colin Ian King 
> > ---
> >  drivers/staging/vc04_services/bcm2835-camera/controls.c | 1 -
> >  1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c 
> > b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > index a2c55cb2192a..99831dd4365d 100644
> > --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > @@ -588,7 +588,6 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev *dev,
> >
> >   control = >component[MMAL_COMPONENT_CAMERA]->control;
> >
> > - dev->colourfx.enable = (ctrl->val & 0xff00) >> 8;
> >   dev->colourfx.enable = ctrl->val & 0xff;
> >
> >   ret = vchiq_mmal_port_parameter_set(dev->instance, control,
>
> as long as the current behavior is correct, i'm okay with this patch.
> But the byte masking looks suspicious, so i hope Dave can clarify that.

It's writing to the wrong structure member.
The function is used on the V4L2 control V4L2_CID_COLORFX_CBCR, which
is defined as:
V4L2_CID_COLORFX_CBCR (integer)
Determines the Cb and Cr coefficients for V4L2_COLORFX_SET_CBCR color
effect. Bits [7:0] of the supplied 32 bit value are interpreted as Cr
component, bits [15:8] as Cb component and bits [31:16] must be zero.

ctrl->val should therefore be setting dev->colourfx.u and
dev->colourfx.v with those masks. dev->colourfx.enable field should
have been set when going through ctrl_set_image_effect for contol
V4L2_CID_COLORFX set to V4L2_COLORFX_SET_CBCR.

I've confirmed with qv4l2 that that is what is wrong. That's only been
lurking there for almost 5 years - shows how often these weirder
effects get used.
I don't mind whether Colin's patch gets merged and then fixed up, or
drop Colin's patch and apply the correct logic via a new patch.

  Dave


Re: [PATCH] staging: bcm2835-camera: remove extraneous setting of dev->colourfx.enable

2018-10-08 Thread Dave Stevenson
On Mon, 8 Oct 2018 at 18:09, Stefan Wahren  wrote:
>
> Hi Dave,
>
> > Dave Stevenson  hat am 8. Oktober 2018 um 
> > 18:51 geschrieben:
> >
> >
> >  Hi Stefan.
> >
> > Thanks for forwarding as the linux-rpi-kernel list hasn't sent it to me as 
> > yet.
>
> AFAIK every mail with more than 5 recipients will be delayed.
>
> >
> > On Mon, 8 Oct 2018 at 16:48, Stefan Wahren  wrote:
> > >
> > > Hi Colin,
> > >
> > > Am 08.10.2018 um 16:50 schrieb Colin King:
> > > > From: Colin Ian King 
> > > >
> > > > Currently dev->colourfx.enable is being set twice, hence the first
> > > > occurrance is redundant and can be removed, so remove it. This minor
> > > > issue was introduced by commit 7b3ad5abf027 ("staging: Import the
> > > > BCM2835 MMAL-based V4L2 camera driver.").
> > > >
> > > > Detected by CoverityScan CID#1419711 ("Unused value")
> > > >
> > > > Signed-off-by: Colin Ian King 
> > > > ---
> > > >  drivers/staging/vc04_services/bcm2835-camera/controls.c | 1 -
> > > >  1 file changed, 1 deletion(-)
> > > >
> > > > diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c 
> > > > b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > > > index a2c55cb2192a..99831dd4365d 100644
> > > > --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > > > +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > > > @@ -588,7 +588,6 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev 
> > > > *dev,
> > > >
> > > >   control = >component[MMAL_COMPONENT_CAMERA]->control;
> > > >
> > > > - dev->colourfx.enable = (ctrl->val & 0xff00) >> 8;
> > > >   dev->colourfx.enable = ctrl->val & 0xff;
> > > >
> > > >   ret = vchiq_mmal_port_parameter_set(dev->instance, control,
> > >
> > > as long as the current behavior is correct, i'm okay with this patch.
> > > But the byte masking looks suspicious, so i hope Dave can clarify that.
> >
> > It's writing to the wrong structure member.
> > The function is used on the V4L2 control V4L2_CID_COLORFX_CBCR, which
> > is defined as:
> > V4L2_CID_COLORFX_CBCR (integer)
> > Determines the Cb and Cr coefficients for V4L2_COLORFX_SET_CBCR color
> > effect. Bits [7:0] of the supplied 32 bit value are interpreted as Cr
> > component, bits [15:8] as Cb component and bits [31:16] must be zero.
> >
> > ctrl->val should therefore be setting dev->colourfx.u and
> > dev->colourfx.v with those masks. dev->colourfx.enable field should
> > have been set when going through ctrl_set_image_effect for contol
> > V4L2_CID_COLORFX set to V4L2_COLORFX_SET_CBCR.
> >
> > I've confirmed with qv4l2 that that is what is wrong. That's only been
> > lurking there for almost 5 years - shows how often these weirder
> > effects get used.
> > I don't mind whether Colin's patch gets merged and then fixed up, or
> > drop Colin's patch and apply the correct logic via a new patch.
>
> no this patch shouldn't be applied. Does it mean you want to send the proper 
> one?

Want to - not really. Ought to - I guess so.
I've got a bunch of checkpatch and other fixes to come too, so once
I've got a mainline kernel build back up and running I'll roll them
all up and blitz the list.

  Dave


Re: [PATCH] staging: bcm2835-camera: remove extraneous setting of dev->colourfx.enable

2018-10-08 Thread Dave Stevenson
On Mon, 8 Oct 2018 at 18:09, Stefan Wahren  wrote:
>
> Hi Dave,
>
> > Dave Stevenson  hat am 8. Oktober 2018 um 
> > 18:51 geschrieben:
> >
> >
> >  Hi Stefan.
> >
> > Thanks for forwarding as the linux-rpi-kernel list hasn't sent it to me as 
> > yet.
>
> AFAIK every mail with more than 5 recipients will be delayed.
>
> >
> > On Mon, 8 Oct 2018 at 16:48, Stefan Wahren  wrote:
> > >
> > > Hi Colin,
> > >
> > > Am 08.10.2018 um 16:50 schrieb Colin King:
> > > > From: Colin Ian King 
> > > >
> > > > Currently dev->colourfx.enable is being set twice, hence the first
> > > > occurrance is redundant and can be removed, so remove it. This minor
> > > > issue was introduced by commit 7b3ad5abf027 ("staging: Import the
> > > > BCM2835 MMAL-based V4L2 camera driver.").
> > > >
> > > > Detected by CoverityScan CID#1419711 ("Unused value")
> > > >
> > > > Signed-off-by: Colin Ian King 
> > > > ---
> > > >  drivers/staging/vc04_services/bcm2835-camera/controls.c | 1 -
> > > >  1 file changed, 1 deletion(-)
> > > >
> > > > diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c 
> > > > b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > > > index a2c55cb2192a..99831dd4365d 100644
> > > > --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > > > +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> > > > @@ -588,7 +588,6 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev 
> > > > *dev,
> > > >
> > > >   control = >component[MMAL_COMPONENT_CAMERA]->control;
> > > >
> > > > - dev->colourfx.enable = (ctrl->val & 0xff00) >> 8;
> > > >   dev->colourfx.enable = ctrl->val & 0xff;
> > > >
> > > >   ret = vchiq_mmal_port_parameter_set(dev->instance, control,
> > >
> > > as long as the current behavior is correct, i'm okay with this patch.
> > > But the byte masking looks suspicious, so i hope Dave can clarify that.
> >
> > It's writing to the wrong structure member.
> > The function is used on the V4L2 control V4L2_CID_COLORFX_CBCR, which
> > is defined as:
> > V4L2_CID_COLORFX_CBCR (integer)
> > Determines the Cb and Cr coefficients for V4L2_COLORFX_SET_CBCR color
> > effect. Bits [7:0] of the supplied 32 bit value are interpreted as Cr
> > component, bits [15:8] as Cb component and bits [31:16] must be zero.
> >
> > ctrl->val should therefore be setting dev->colourfx.u and
> > dev->colourfx.v with those masks. dev->colourfx.enable field should
> > have been set when going through ctrl_set_image_effect for contol
> > V4L2_CID_COLORFX set to V4L2_COLORFX_SET_CBCR.
> >
> > I've confirmed with qv4l2 that that is what is wrong. That's only been
> > lurking there for almost 5 years - shows how often these weirder
> > effects get used.
> > I don't mind whether Colin's patch gets merged and then fixed up, or
> > drop Colin's patch and apply the correct logic via a new patch.
>
> no this patch shouldn't be applied. Does it mean you want to send the proper 
> one?

Want to - not really. Ought to - I guess so.
I've got a bunch of checkpatch and other fixes to come too, so once
I've got a mainline kernel build back up and running I'll roll them
all up and blitz the list.

  Dave


Re: [PATCH] staging: bcm2835-camera: Avoid unneeded internal declaration warning

2018-09-28 Thread Dave Stevenson
Hi Nate

Thanks for the patch.

On Fri, 28 Sep 2018 at 01:53, Nathan Chancellor
 wrote:
>
> Clang warns:
>
> drivers/staging/vc04_services/bcm2835-camera/controls.c:59:18: warning:
> variable 'mains_freq_qmenu' is not needed and will not be emitted
> [-Wunneeded-internal-declaration]
> static const s64 mains_freq_qmenu[] = {
>  ^
> 1 warning generated.
>
> This is because mains_freq_qmenu is currently only used in an ARRAY_SIZE
> macro, which is a compile time evaluation in this case. Avoid this by
> adding mains_freq_qmenu as the imenu member of this structure, which
> matches all other controls that uses the ARRAY_SIZE macro in v4l2_ctrls.
> This turns out to be a no-op because V4L2_CID_MPEG_VIDEO_BITRATE_MODE is
> defined as a MMAL_CONTROL_TYPE_STD_MENU, which does not pass the imenu
> definition along to v4l2_ctrl_new in bm2835_mmal_init_controls.

There's a slight confusion betwen V4L2_CID_MPEG_VIDEO_BITRATE_MODE and
V4L2_CID_POWER_LINE_FREQUENCY in your description.

However you're right that MMAL_CONTROL_TYPE_STD_MENU calls
v4l2_ctrl_new_std_menu which doesn't need a menu array (it's
v4l2_ctrl_new_int_menu that does). That means the correct fix is to
define the max value using the relevant enum (in this case
V4L2_CID_POWER_LINE_FREQUENCY_AUTO) and remove the array.

The same is true for V4L2_CID_MPEG_VIDEO_BITRATE_MODE - max should be
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, and remove the bitrate_mode_qmenu
array.

Thanks,
  Dave

> Link: https://github.com/ClangBuiltLinux/linux/issues/122
> Signed-off-by: Nathan Chancellor 
> ---
>  drivers/staging/vc04_services/bcm2835-camera/controls.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c 
> b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> index cff7b1e07153..a2c55cb2192a 100644
> --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
> +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> @@ -1106,7 +1106,7 @@ static const struct bm2835_mmal_v4l2_ctrl 
> v4l2_ctrls[V4L2_CTRL_COUNT] = {
> {
> V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU,
> 0, ARRAY_SIZE(mains_freq_qmenu) - 1,
> -   1, 1, NULL,
> +   1, 1, mains_freq_qmenu,
> MMAL_PARAMETER_FLICKER_AVOID,
> _set_flicker_avoidance,
> false
> --
> 2.19.0
>
>
> ___
> linux-rpi-kernel mailing list
> linux-rpi-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rpi-kernel


Re: [PATCH] staging: bcm2835-camera: Avoid unneeded internal declaration warning

2018-09-28 Thread Dave Stevenson
Hi Nate

Thanks for the patch.

On Fri, 28 Sep 2018 at 01:53, Nathan Chancellor
 wrote:
>
> Clang warns:
>
> drivers/staging/vc04_services/bcm2835-camera/controls.c:59:18: warning:
> variable 'mains_freq_qmenu' is not needed and will not be emitted
> [-Wunneeded-internal-declaration]
> static const s64 mains_freq_qmenu[] = {
>  ^
> 1 warning generated.
>
> This is because mains_freq_qmenu is currently only used in an ARRAY_SIZE
> macro, which is a compile time evaluation in this case. Avoid this by
> adding mains_freq_qmenu as the imenu member of this structure, which
> matches all other controls that uses the ARRAY_SIZE macro in v4l2_ctrls.
> This turns out to be a no-op because V4L2_CID_MPEG_VIDEO_BITRATE_MODE is
> defined as a MMAL_CONTROL_TYPE_STD_MENU, which does not pass the imenu
> definition along to v4l2_ctrl_new in bm2835_mmal_init_controls.

There's a slight confusion betwen V4L2_CID_MPEG_VIDEO_BITRATE_MODE and
V4L2_CID_POWER_LINE_FREQUENCY in your description.

However you're right that MMAL_CONTROL_TYPE_STD_MENU calls
v4l2_ctrl_new_std_menu which doesn't need a menu array (it's
v4l2_ctrl_new_int_menu that does). That means the correct fix is to
define the max value using the relevant enum (in this case
V4L2_CID_POWER_LINE_FREQUENCY_AUTO) and remove the array.

The same is true for V4L2_CID_MPEG_VIDEO_BITRATE_MODE - max should be
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, and remove the bitrate_mode_qmenu
array.

Thanks,
  Dave

> Link: https://github.com/ClangBuiltLinux/linux/issues/122
> Signed-off-by: Nathan Chancellor 
> ---
>  drivers/staging/vc04_services/bcm2835-camera/controls.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c 
> b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> index cff7b1e07153..a2c55cb2192a 100644
> --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
> +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
> @@ -1106,7 +1106,7 @@ static const struct bm2835_mmal_v4l2_ctrl 
> v4l2_ctrls[V4L2_CTRL_COUNT] = {
> {
> V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU,
> 0, ARRAY_SIZE(mains_freq_qmenu) - 1,
> -   1, 1, NULL,
> +   1, 1, mains_freq_qmenu,
> MMAL_PARAMETER_FLICKER_AVOID,
> _set_flicker_avoidance,
> false
> --
> 2.19.0
>
>
> ___
> linux-rpi-kernel mailing list
> linux-rpi-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rpi-kernel


Re: [PATCH] staging: bcm2835-camera: Add TODO for removing overlay support

2018-05-11 Thread Dave Stevenson
On 11 May 2018 at 00:12, Stefan Schake  wrote:
> The overlay code is non-functional since it relies on firmware control
> of the HVS.
>
> Signed-off-by: Stefan Schake 
> ---
> Dave, does this match your understanding?

Yes, the overlay only works if you are not running the vc4 driver,
therefore dropping it is sensible for the mainline kernel.

>  drivers/staging/vc04_services/bcm2835-camera/TODO | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/staging/vc04_services/bcm2835-camera/TODO 
> b/drivers/staging/vc04_services/bcm2835-camera/TODO
> index 0ab9e88..770fea6 100644
> --- a/drivers/staging/vc04_services/bcm2835-camera/TODO
> +++ b/drivers/staging/vc04_services/bcm2835-camera/TODO
> @@ -32,3 +32,11 @@ We should have VCHI create a platform device once it's 
> initialized,
>  and have this driver bind to it, so that we automatically load the
>  v4l2 module after VCHI loads.
>
> +5) Remove overlay support.
> +
> +We advertise support for a V4L2 overlay implemented through the
> +ril.video_render component. This component is non-functional with an
> +upstream kernel since the VC4 DRM driver controls the HVS, not the
> +firmware. Once we have dma-buf support, the same functionality with
> +improved control can be achieved through the DRM interface. We should
> +therefore remove all V4L2 overlay functionality from the driver.
> --
> 2.7.4
>


Re: [PATCH] staging: bcm2835-camera: Add TODO for removing overlay support

2018-05-11 Thread Dave Stevenson
On 11 May 2018 at 00:12, Stefan Schake  wrote:
> The overlay code is non-functional since it relies on firmware control
> of the HVS.
>
> Signed-off-by: Stefan Schake 
> ---
> Dave, does this match your understanding?

Yes, the overlay only works if you are not running the vc4 driver,
therefore dropping it is sensible for the mainline kernel.

>  drivers/staging/vc04_services/bcm2835-camera/TODO | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/staging/vc04_services/bcm2835-camera/TODO 
> b/drivers/staging/vc04_services/bcm2835-camera/TODO
> index 0ab9e88..770fea6 100644
> --- a/drivers/staging/vc04_services/bcm2835-camera/TODO
> +++ b/drivers/staging/vc04_services/bcm2835-camera/TODO
> @@ -32,3 +32,11 @@ We should have VCHI create a platform device once it's 
> initialized,
>  and have this driver bind to it, so that we automatically load the
>  v4l2 module after VCHI loads.
>
> +5) Remove overlay support.
> +
> +We advertise support for a V4L2 overlay implemented through the
> +ril.video_render component. This component is non-functional with an
> +upstream kernel since the VC4 DRM driver controls the HVS, not the
> +firmware. Once we have dma-buf support, the same functionality with
> +improved control can be achieved through the DRM interface. We should
> +therefore remove all V4L2 overlay functionality from the driver.
> --
> 2.7.4
>


Re: [PATCH 1/6] staging: Import the BCM2835 MMAL-based V4L2 camera driver.

2017-02-06 Thread Dave Stevenson

Hi Hans.

On 06/02/17 12:58, Hans Verkuil wrote:

On 02/06/2017 12:37 PM, Dave Stevenson wrote:

Hi Hans.

On 06/02/17 09:08, Hans Verkuil wrote:

Hi Eric,

Great to see this driver appearing for upstream merging!

See below for my review comments, focusing mostly on V4L2 specifics.






+   f->fmt.pix.pixelformat = dev->capture.fmt->fourcc;
+   f->fmt.pix.bytesperline = dev->capture.stride;
+   f->fmt.pix.sizeimage = dev->capture.buffersize;
+
+   if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_RGB24)
+   f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
+   else if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_JPEG)
+   f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+   else
+   f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;


Colorspace has nothing to do with the pixel format. It should come from the
sensor/video receiver.

If this information is not available, then COLORSPACE_SRGB is generally a
good fallback.


I would if I could, but then I fail v4l2-compliance on V4L2_PIX_FMT_JPEG
https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-compliance/v4l2-test-formats.cpp#n329
The special case for JPEG therefore has to remain.


Correct. Sorry, my fault, I forgot about that.



It looks like I tripped over the subtlety between V4L2_COLORSPACE_,
V4L2_XFER_FUNC_, V4L2_YCBCR_ENC_, and V4L2_QUANTIZATION_, and Y'CbCr
encoding vs colourspace.

The ISP coefficients are set up for BT601 limited range, and any
conversion back to RGB is done based on that. That seemed to fit
SMPTE170M rather than SRGB.


Colorspace refers to the primary colors + whitepoint that are used to
create the colors (basically this answers the question to which colors
R, G and B exactly refer to). The SMPTE170M has different primaries
compared to sRGB (and a different default transfer function as well).

RGB vs Y'CbCr is just an encoding and it doesn't change the underlying
colorspace. Unfortunately, the term 'colorspace' is often abused to just
refer to RGB vs Y'CbCr.

If the colorspace is SRGB, then when the pixelformat is a Y'CbCr encoding,
then the BT601 limited range encoding is implied, unless overridden via
the ycbcr_enc and/or quantization fields in struct v4l2_pix_format.

In other words, this does already the right thing.


https://linuxtv.org/downloads/v4l-dvb-apis-new/uapi/v4l/pixfmt-007.html#colorspace-srgb-v4l2-colorspace-srgb
"The default transfer function is V4L2_XFER_FUNC_SRGB. The default 
Y’CbCr encoding is V4L2_YCBCR_ENC_601. The default Y’CbCr quantization 
is full range."

So full range or limited?


The JPEG colorspace is a short-hand for V4L2_COLORSPACE_SRGB, V4L2_YCBCR_ENC_601
and V4L2_QUANTIZATION_FULL_RANGE. It's historical that this colorspace exists.

If I would redesign this this JPEG colorspace would be dropped.

For a lot more colorspace information see:

https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces.html



I do note that as there is now support for more RGB formats (BGR24 and
BGR32) the first "if" needs extending to cover those. Or I don't care
and only special case JPEG with all others just reporting SRGB.



Only special case JPEG.

But as I said, this information really needs to come from the sensor or
video receiver since this driver has no knowledge of this.


OK.






This is IMHO unnecessarily complex.

My recommendation is that controls are added with a set of v4l2_ctrl_new_std* 
calls
or if you really want to by walking a struct v4l2_ctrl_config array and adding 
controls
via v4l2_ctrl_new_custom.

The s_ctrl is a switch that calls the 'setter' function.

No need for arrays, callbacks, etc. Just keep it simple.


I can look into that, but I'm not sure I fully follow what you are
suggesting.

In the current implementation things like V4L2_CID_SATURATION,
V4L2_CID_SHARPNESS, V4L2_CID_CONTRAST, and V4L2_CID_BRIGHTNESS all use
the one common ctrl_set_rational setter function because the only thing
different in setting is the MMAL_PARAMETER_xxx value. I guess that could
move into the common setter based on V4L2_CID_xxx, but then the control
configuration is split between multiple places which feels less well
contained.


See e.g. samples/v4l/v4l2-pci-skeleton.c: in the probe function (or in a
function called from there if there are a lot of controls) you add the
controls, and in s_ctrl you handle them.

But this is just my preference.

So in s_ctrl you would see something like this:

switch (ctrl->id) {
case V4L2_CID_SATURATION:
ctrl_set_rational(ctrl->val, MMAL_PARAMETER_SAT);
break;
case V4L2_CID_BRIGHTNESS:
ctrl_set_rational(ctrl->val, MMAL_PARAMETER_BRIGHTNESS);
break;
...
}


OK, thanks for the clarification. That can be done.






Final question: did you run v4l2-compliance over this driver? Before this 
driver can
be moved out of staging it should pass the compliance tests. Note: always 
compile
this test from the main r

Re: [PATCH 1/6] staging: Import the BCM2835 MMAL-based V4L2 camera driver.

2017-02-06 Thread Dave Stevenson

Hi Hans.

On 06/02/17 12:58, Hans Verkuil wrote:

On 02/06/2017 12:37 PM, Dave Stevenson wrote:

Hi Hans.

On 06/02/17 09:08, Hans Verkuil wrote:

Hi Eric,

Great to see this driver appearing for upstream merging!

See below for my review comments, focusing mostly on V4L2 specifics.






+   f->fmt.pix.pixelformat = dev->capture.fmt->fourcc;
+   f->fmt.pix.bytesperline = dev->capture.stride;
+   f->fmt.pix.sizeimage = dev->capture.buffersize;
+
+   if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_RGB24)
+   f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
+   else if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_JPEG)
+   f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+   else
+   f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;


Colorspace has nothing to do with the pixel format. It should come from the
sensor/video receiver.

If this information is not available, then COLORSPACE_SRGB is generally a
good fallback.


I would if I could, but then I fail v4l2-compliance on V4L2_PIX_FMT_JPEG
https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-compliance/v4l2-test-formats.cpp#n329
The special case for JPEG therefore has to remain.


Correct. Sorry, my fault, I forgot about that.



It looks like I tripped over the subtlety between V4L2_COLORSPACE_,
V4L2_XFER_FUNC_, V4L2_YCBCR_ENC_, and V4L2_QUANTIZATION_, and Y'CbCr
encoding vs colourspace.

The ISP coefficients are set up for BT601 limited range, and any
conversion back to RGB is done based on that. That seemed to fit
SMPTE170M rather than SRGB.


Colorspace refers to the primary colors + whitepoint that are used to
create the colors (basically this answers the question to which colors
R, G and B exactly refer to). The SMPTE170M has different primaries
compared to sRGB (and a different default transfer function as well).

RGB vs Y'CbCr is just an encoding and it doesn't change the underlying
colorspace. Unfortunately, the term 'colorspace' is often abused to just
refer to RGB vs Y'CbCr.

If the colorspace is SRGB, then when the pixelformat is a Y'CbCr encoding,
then the BT601 limited range encoding is implied, unless overridden via
the ycbcr_enc and/or quantization fields in struct v4l2_pix_format.

In other words, this does already the right thing.


https://linuxtv.org/downloads/v4l-dvb-apis-new/uapi/v4l/pixfmt-007.html#colorspace-srgb-v4l2-colorspace-srgb
"The default transfer function is V4L2_XFER_FUNC_SRGB. The default 
Y’CbCr encoding is V4L2_YCBCR_ENC_601. The default Y’CbCr quantization 
is full range."

So full range or limited?


The JPEG colorspace is a short-hand for V4L2_COLORSPACE_SRGB, V4L2_YCBCR_ENC_601
and V4L2_QUANTIZATION_FULL_RANGE. It's historical that this colorspace exists.

If I would redesign this this JPEG colorspace would be dropped.

For a lot more colorspace information see:

https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces.html



I do note that as there is now support for more RGB formats (BGR24 and
BGR32) the first "if" needs extending to cover those. Or I don't care
and only special case JPEG with all others just reporting SRGB.



Only special case JPEG.

But as I said, this information really needs to come from the sensor or
video receiver since this driver has no knowledge of this.


OK.






This is IMHO unnecessarily complex.

My recommendation is that controls are added with a set of v4l2_ctrl_new_std* 
calls
or if you really want to by walking a struct v4l2_ctrl_config array and adding 
controls
via v4l2_ctrl_new_custom.

The s_ctrl is a switch that calls the 'setter' function.

No need for arrays, callbacks, etc. Just keep it simple.


I can look into that, but I'm not sure I fully follow what you are
suggesting.

In the current implementation things like V4L2_CID_SATURATION,
V4L2_CID_SHARPNESS, V4L2_CID_CONTRAST, and V4L2_CID_BRIGHTNESS all use
the one common ctrl_set_rational setter function because the only thing
different in setting is the MMAL_PARAMETER_xxx value. I guess that could
move into the common setter based on V4L2_CID_xxx, but then the control
configuration is split between multiple places which feels less well
contained.


See e.g. samples/v4l/v4l2-pci-skeleton.c: in the probe function (or in a
function called from there if there are a lot of controls) you add the
controls, and in s_ctrl you handle them.

But this is just my preference.

So in s_ctrl you would see something like this:

switch (ctrl->id) {
case V4L2_CID_SATURATION:
ctrl_set_rational(ctrl->val, MMAL_PARAMETER_SAT);
break;
case V4L2_CID_BRIGHTNESS:
ctrl_set_rational(ctrl->val, MMAL_PARAMETER_BRIGHTNESS);
break;
...
}


OK, thanks for the clarification. That can be done.






Final question: did you run v4l2-compliance over this driver? Before this 
driver can
be moved out of staging it should pass the compliance tests. Note: always 
compile
this test from the main r

Re: [PATCH 1/6] staging: Import the BCM2835 MMAL-based V4L2 camera driver.

2017-02-06 Thread Dave Stevenson

Hi Mauro.

Can I just say that I'm not attempting to upstream this, others are. 
I've just answered questions raised.


On 06/02/17 12:37, Mauro Carvalho Chehab wrote:

Em Sun, 5 Feb 2017 22:15:21 +
Dave Stevenson <linux-me...@destevenson.freeserve.co.uk> escreveu:


If the goal was to protect some IP related to the sensors, I guess
this is not going to protect anything, as there are recent driver
submissions on linux-media for the ov5647 driver:

https://patchwork.kernel.org/patch/9472441/

There are also open source drivers for the Sony imx219 camera
floating around for android and chromeOS:


https://chromium.googlesource.com/chromiumos/third_party/kernel/+/factory-ryu-6486.14.B-chromeos-3.14/drivers/media/i2c/soc_camera/imx219.c

https://android.googlesource.com/kernel/bcm/+/android-bcm-tetra-3.10-lollipop-wear-release/drivers/media/video/imx219.c

Plus, there's a datasheet (with another driver) available at:
https://github.com/rellimmot/Sony-IMX219-Raspberry-Pi-V2-CMOS

So, you're not really protecting IP here.


None of the ISP processing, control loops, or tuning are open.
Yes there are kernel drivers kicking around for OV5647 and IMX219 now, 
but very little will consume raw Bayer.

That is also Omnivision or Sony IP, not Broadcom IP.


If the goal is to protect some proprietary algorithm meant to enhance
the camera captured streams, doing things like (auto-focus, auto-white
adjustments, scaling, etc), and/or implementing codec encoders, you should,
instead, restructure such codecs as mem2mem V4L2 drivers. There are a bunch
of such codecs already for other SoC where such functions are implemented
on GPU.

If you add DMABUF capabilities and media controller to the capture
driver and to the mem2mem drivers, userspace can use the V4L2 APIs
to use those modules using the arrangements they need, without
performance impacts.

So, by obfuscating the code, you're not protecting anything. Just making
harder for RPi customers to use, as you're providing a driver that is
limited.








Greg was kick on merging it on staging ;) Anyway, the real review
will happen when the driver becomes ready to be promoted out of
staging. When you address the existing issues and get it ready to
merge, please send the patch with such changes to linux-media ML.
I'll do a full review on it by then.


Is that even likely given the dependence on VCHI? I wasn't expecting
VCHI to leave staging, which would force this to remain too.


I didn't analyze the VCHI driver. As I said before, if you rewrite
the driver in a way that the Kernel can actually see the sensors
via an I2C interface, you probably can get rid of the VCHI interface
for the capture part.

You could take a look on the other mem2mem drivers and see if are
there some way to provide an interface for the GPU encoders in a
similar way to what those drivers do.


I will be looking at a sub dev driver for just the CCP2/CSI1/CSI2 
receiver as Broadcom did manage to release (probably unintentionally) a 
bastardised soc-camera driver for it and therefore the info is in the 
public domain.


It would be possible to write a second sub dev driver that was similar 
to this in using VCHI/MMAL to create another mem2mem device to wrap the 
ISP, but that would just be an image processing pipe - control loops 
would all be elsewhere (userspace).
I haven't seen a sensible mechanism within V4L2 for exporting image 
statistics for AE, AWB, AF, or histograms to userspace so that 
appropriate algorithms can be run there. Have I missed them, or do they 
not exist?






That seems a terrible hack! let the user specify the resolution via
modprobe parameter... That should depend on the hardware capabilities
instead.


This is sitting on top of an OpenMaxIL style camera component (though
accessed via MMAL - long story, but basically MMAL removed a bundle of
the ugly/annoying parts of IL).
It has the extension above V1.1.2 that you have a preview port, video
capture port, and stills capture port. Stills captures have additional
processing stages to improve image quality, whilst video has to maintain
framerate.


I see.


If you're asked for YUV or RGB frame, how do you choose between video or
stills? That's what is being set with these parameters, not the sensor
resolution. Having independent stills and video processing options
doesn't appear to be something that is supported in V4L2, but I'm open
to suggestions.


At the capture stage:

Assuming that the user wants to use different resolutions for video and
stills (for example, you're seeing a real time video, then you "click"
to capture a still image), you can create two buffer groups, one for
low-res video and another one for high-res image. When the button is
clicked, it will stop the low-res stream, set the parameters for the
high-res image and capture it.

For post-processing stage:

Switch the media pipeline via the media controller adding the post
processing codecs that will enhance t

Re: [PATCH 1/6] staging: Import the BCM2835 MMAL-based V4L2 camera driver.

2017-02-06 Thread Dave Stevenson

Hi Mauro.

Can I just say that I'm not attempting to upstream this, others are. 
I've just answered questions raised.


On 06/02/17 12:37, Mauro Carvalho Chehab wrote:

Em Sun, 5 Feb 2017 22:15:21 +
Dave Stevenson  escreveu:


If the goal was to protect some IP related to the sensors, I guess
this is not going to protect anything, as there are recent driver
submissions on linux-media for the ov5647 driver:

https://patchwork.kernel.org/patch/9472441/

There are also open source drivers for the Sony imx219 camera
floating around for android and chromeOS:


https://chromium.googlesource.com/chromiumos/third_party/kernel/+/factory-ryu-6486.14.B-chromeos-3.14/drivers/media/i2c/soc_camera/imx219.c

https://android.googlesource.com/kernel/bcm/+/android-bcm-tetra-3.10-lollipop-wear-release/drivers/media/video/imx219.c

Plus, there's a datasheet (with another driver) available at:
https://github.com/rellimmot/Sony-IMX219-Raspberry-Pi-V2-CMOS

So, you're not really protecting IP here.


None of the ISP processing, control loops, or tuning are open.
Yes there are kernel drivers kicking around for OV5647 and IMX219 now, 
but very little will consume raw Bayer.

That is also Omnivision or Sony IP, not Broadcom IP.


If the goal is to protect some proprietary algorithm meant to enhance
the camera captured streams, doing things like (auto-focus, auto-white
adjustments, scaling, etc), and/or implementing codec encoders, you should,
instead, restructure such codecs as mem2mem V4L2 drivers. There are a bunch
of such codecs already for other SoC where such functions are implemented
on GPU.

If you add DMABUF capabilities and media controller to the capture
driver and to the mem2mem drivers, userspace can use the V4L2 APIs
to use those modules using the arrangements they need, without
performance impacts.

So, by obfuscating the code, you're not protecting anything. Just making
harder for RPi customers to use, as you're providing a driver that is
limited.








Greg was kick on merging it on staging ;) Anyway, the real review
will happen when the driver becomes ready to be promoted out of
staging. When you address the existing issues and get it ready to
merge, please send the patch with such changes to linux-media ML.
I'll do a full review on it by then.


Is that even likely given the dependence on VCHI? I wasn't expecting
VCHI to leave staging, which would force this to remain too.


I didn't analyze the VCHI driver. As I said before, if you rewrite
the driver in a way that the Kernel can actually see the sensors
via an I2C interface, you probably can get rid of the VCHI interface
for the capture part.

You could take a look on the other mem2mem drivers and see if are
there some way to provide an interface for the GPU encoders in a
similar way to what those drivers do.


I will be looking at a sub dev driver for just the CCP2/CSI1/CSI2 
receiver as Broadcom did manage to release (probably unintentionally) a 
bastardised soc-camera driver for it and therefore the info is in the 
public domain.


It would be possible to write a second sub dev driver that was similar 
to this in using VCHI/MMAL to create another mem2mem device to wrap the 
ISP, but that would just be an image processing pipe - control loops 
would all be elsewhere (userspace).
I haven't seen a sensible mechanism within V4L2 for exporting image 
statistics for AE, AWB, AF, or histograms to userspace so that 
appropriate algorithms can be run there. Have I missed them, or do they 
not exist?






That seems a terrible hack! let the user specify the resolution via
modprobe parameter... That should depend on the hardware capabilities
instead.


This is sitting on top of an OpenMaxIL style camera component (though
accessed via MMAL - long story, but basically MMAL removed a bundle of
the ugly/annoying parts of IL).
It has the extension above V1.1.2 that you have a preview port, video
capture port, and stills capture port. Stills captures have additional
processing stages to improve image quality, whilst video has to maintain
framerate.


I see.


If you're asked for YUV or RGB frame, how do you choose between video or
stills? That's what is being set with these parameters, not the sensor
resolution. Having independent stills and video processing options
doesn't appear to be something that is supported in V4L2, but I'm open
to suggestions.


At the capture stage:

Assuming that the user wants to use different resolutions for video and
stills (for example, you're seeing a real time video, then you "click"
to capture a still image), you can create two buffer groups, one for
low-res video and another one for high-res image. When the button is
clicked, it will stop the low-res stream, set the parameters for the
high-res image and capture it.

For post-processing stage:

Switch the media pipeline via the media controller adding the post
processing codecs that will enhance the image.

We're discussing for a while (and there a

Re: [PATCH 1/6] staging: Import the BCM2835 MMAL-based V4L2 camera driver.

2017-02-06 Thread Dave Stevenson

Hi Hans.

On 06/02/17 09:08, Hans Verkuil wrote:

Hi Eric,

Great to see this driver appearing for upstream merging!

See below for my review comments, focusing mostly on V4L2 specifics.

On 01/27/2017 10:54 PM, Eric Anholt wrote:

- Supports raw YUV capture, preview, JPEG and H264.
- Uses videobuf2 for data transfer, using dma_buf.
- Uses 3.6.10 timestamping
- Camera power based on use
- Uses immutable input mode on video encoder

This code comes from the Raspberry Pi kernel tree (rpi-4.9.y) as of
a15ba877dab4e61ea3fc7b006e2a73828b083c52.

Signed-off-by: Eric Anholt 
---
 .../media/platform/bcm2835/bcm2835-camera.c| 2016 
 .../media/platform/bcm2835/bcm2835-camera.h|  145 ++
 drivers/staging/media/platform/bcm2835/controls.c  | 1345 +
 .../staging/media/platform/bcm2835/mmal-common.h   |   53 +
 .../media/platform/bcm2835/mmal-encodings.h|  127 ++
 .../media/platform/bcm2835/mmal-msg-common.h   |   50 +
 .../media/platform/bcm2835/mmal-msg-format.h   |   81 +
 .../staging/media/platform/bcm2835/mmal-msg-port.h |  107 ++
 drivers/staging/media/platform/bcm2835/mmal-msg.h  |  404 
 .../media/platform/bcm2835/mmal-parameters.h   |  689 +++
 .../staging/media/platform/bcm2835/mmal-vchiq.c| 1916 +++
 .../staging/media/platform/bcm2835/mmal-vchiq.h|  178 ++
 12 files changed, 7111 insertions(+)
 create mode 100644 drivers/staging/media/platform/bcm2835/bcm2835-camera.c
 create mode 100644 drivers/staging/media/platform/bcm2835/bcm2835-camera.h
 create mode 100644 drivers/staging/media/platform/bcm2835/controls.c
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-common.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-encodings.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg-common.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg-format.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg-port.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-parameters.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-vchiq.c
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-vchiq.h

diff --git a/drivers/staging/media/platform/bcm2835/bcm2835-camera.c 
b/drivers/staging/media/platform/bcm2835/bcm2835-camera.c
new file mode 100644
index ..4f03949aecf3
--- /dev/null
+++ b/drivers/staging/media/platform/bcm2835/bcm2835-camera.c
@@ -0,0 +1,2016 @@





+static int start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+   struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
+   int ret;
+   int parameter_size;
+
+   v4l2_dbg(1, bcm2835_v4l2_debug, >v4l2_dev, "%s: dev:%p\n",
+__func__, dev);
+
+   /* ensure a format has actually been set */
+   if (dev->capture.port == NULL)
+   return -EINVAL;


Standard mistake. If start_streaming returns an error, then it should call 
vb2_buffer_done
for all queued buffers with state VB2_BUF_STATE_QUEUED. Otherwise the buffer 
administration
gets unbalanced.


OK.
This is an error path that I'm not convinced can ever be followed, just 
defensive programming. It may be a candidate for just removing, but yes 
otherwise it needs to be fixed to do the right thing.



+
+   if (enable_camera(dev) < 0) {
+   v4l2_err(>v4l2_dev, "Failed to enable camera\n");
+   return -EINVAL;
+   }
+
+   /*init_completion(>capture.frame_cmplt); */
+
+   /* enable frame capture */
+   dev->capture.frame_count = 1;
+
+   /* if the preview is not already running, wait for a few frames for AGC
+* to settle down.
+*/
+   if (!dev->component[MMAL_COMPONENT_PREVIEW]->enabled)
+   msleep(300);
+
+   /* enable the connection from camera to encoder (if applicable) */
+   if (dev->capture.camera_port != dev->capture.port
+   && dev->capture.camera_port) {
+   ret = vchiq_mmal_port_enable(dev->instance,
+dev->capture.camera_port, NULL);
+   if (ret) {
+   v4l2_err(>v4l2_dev,
+"Failed to enable encode tunnel - error %d\n",
+ret);
+   return -1;


Use a proper error, not -1.


+   }
+   }
+
+   /* Get VC timestamp at this point in time */
+   parameter_size = sizeof(dev->capture.vc_start_timestamp);
+   if (vchiq_mmal_port_parameter_get(dev->instance,
+ dev->capture.camera_port,
+ MMAL_PARAMETER_SYSTEM_TIME,
+ >capture.vc_start_timestamp,
+ _size)) {
+   v4l2_err(>v4l2_dev,
+

Re: [PATCH 1/6] staging: Import the BCM2835 MMAL-based V4L2 camera driver.

2017-02-06 Thread Dave Stevenson

Hi Hans.

On 06/02/17 09:08, Hans Verkuil wrote:

Hi Eric,

Great to see this driver appearing for upstream merging!

See below for my review comments, focusing mostly on V4L2 specifics.

On 01/27/2017 10:54 PM, Eric Anholt wrote:

- Supports raw YUV capture, preview, JPEG and H264.
- Uses videobuf2 for data transfer, using dma_buf.
- Uses 3.6.10 timestamping
- Camera power based on use
- Uses immutable input mode on video encoder

This code comes from the Raspberry Pi kernel tree (rpi-4.9.y) as of
a15ba877dab4e61ea3fc7b006e2a73828b083c52.

Signed-off-by: Eric Anholt 
---
 .../media/platform/bcm2835/bcm2835-camera.c| 2016 
 .../media/platform/bcm2835/bcm2835-camera.h|  145 ++
 drivers/staging/media/platform/bcm2835/controls.c  | 1345 +
 .../staging/media/platform/bcm2835/mmal-common.h   |   53 +
 .../media/platform/bcm2835/mmal-encodings.h|  127 ++
 .../media/platform/bcm2835/mmal-msg-common.h   |   50 +
 .../media/platform/bcm2835/mmal-msg-format.h   |   81 +
 .../staging/media/platform/bcm2835/mmal-msg-port.h |  107 ++
 drivers/staging/media/platform/bcm2835/mmal-msg.h  |  404 
 .../media/platform/bcm2835/mmal-parameters.h   |  689 +++
 .../staging/media/platform/bcm2835/mmal-vchiq.c| 1916 +++
 .../staging/media/platform/bcm2835/mmal-vchiq.h|  178 ++
 12 files changed, 7111 insertions(+)
 create mode 100644 drivers/staging/media/platform/bcm2835/bcm2835-camera.c
 create mode 100644 drivers/staging/media/platform/bcm2835/bcm2835-camera.h
 create mode 100644 drivers/staging/media/platform/bcm2835/controls.c
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-common.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-encodings.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg-common.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg-format.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg-port.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-msg.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-parameters.h
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-vchiq.c
 create mode 100644 drivers/staging/media/platform/bcm2835/mmal-vchiq.h

diff --git a/drivers/staging/media/platform/bcm2835/bcm2835-camera.c 
b/drivers/staging/media/platform/bcm2835/bcm2835-camera.c
new file mode 100644
index ..4f03949aecf3
--- /dev/null
+++ b/drivers/staging/media/platform/bcm2835/bcm2835-camera.c
@@ -0,0 +1,2016 @@





+static int start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+   struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
+   int ret;
+   int parameter_size;
+
+   v4l2_dbg(1, bcm2835_v4l2_debug, >v4l2_dev, "%s: dev:%p\n",
+__func__, dev);
+
+   /* ensure a format has actually been set */
+   if (dev->capture.port == NULL)
+   return -EINVAL;


Standard mistake. If start_streaming returns an error, then it should call 
vb2_buffer_done
for all queued buffers with state VB2_BUF_STATE_QUEUED. Otherwise the buffer 
administration
gets unbalanced.


OK.
This is an error path that I'm not convinced can ever be followed, just 
defensive programming. It may be a candidate for just removing, but yes 
otherwise it needs to be fixed to do the right thing.



+
+   if (enable_camera(dev) < 0) {
+   v4l2_err(>v4l2_dev, "Failed to enable camera\n");
+   return -EINVAL;
+   }
+
+   /*init_completion(>capture.frame_cmplt); */
+
+   /* enable frame capture */
+   dev->capture.frame_count = 1;
+
+   /* if the preview is not already running, wait for a few frames for AGC
+* to settle down.
+*/
+   if (!dev->component[MMAL_COMPONENT_PREVIEW]->enabled)
+   msleep(300);
+
+   /* enable the connection from camera to encoder (if applicable) */
+   if (dev->capture.camera_port != dev->capture.port
+   && dev->capture.camera_port) {
+   ret = vchiq_mmal_port_enable(dev->instance,
+dev->capture.camera_port, NULL);
+   if (ret) {
+   v4l2_err(>v4l2_dev,
+"Failed to enable encode tunnel - error %d\n",
+ret);
+   return -1;


Use a proper error, not -1.


+   }
+   }
+
+   /* Get VC timestamp at this point in time */
+   parameter_size = sizeof(dev->capture.vc_start_timestamp);
+   if (vchiq_mmal_port_parameter_get(dev->instance,
+ dev->capture.camera_port,
+ MMAL_PARAMETER_SYSTEM_TIME,
+ >capture.vc_start_timestamp,
+ _size)) {
+   v4l2_err(>v4l2_dev,
+

  1   2   >