public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: maxime.ripard@free-electrons.com (Maxime Ripard)
To: linux-arm-kernel@lists.infradead.org
Subject: [linux-sunxi] [PATCH 13/15] drm/sun4i: Add HDMI support
Date: Wed, 26 Apr 2017 08:50:05 +0200	[thread overview]
Message-ID: <20170426065005.zoewz53q7l7r5e7p@lukather> (raw)
In-Reply-To: <CAGb2v66n6AXbOAh05V_Gv2UgRp=xEMG9qhJU8JSuy4-F-UOQQQ@mail.gmail.com>

Hi Chen-Yu,

On Fri, Apr 21, 2017 at 11:17:17PM +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> On Tue, Mar 7, 2017 at 4:56 PM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > The earlier Allwinner SoCs (A10, A10s, A20, A31) have an embedded HDMI
> > controller.
> >
> > That HDMI controller is able to do audio and CEC, but those have been left
> > out for now.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> >  drivers/gpu/drm/sun4i/Makefile              |   5 +-
> >  drivers/gpu/drm/sun4i/sun4i_hdmi.h          | 124 ++++++-
> >  drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c  | 128 ++++++-
> >  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c      | 449 +++++++++++++++++++++-
> >  drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 236 +++++++++++-
> >  5 files changed, 942 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi.h
> >  create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> >  create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> >  create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
> 
> Applying patch #9608371 using 'git am'
> Description: [13/15] drm/sun4i: Add HDMI support
> Applying: drm/sun4i: Add HDMI support
> .git/rebase-apply/patch:116: trailing whitespace.
> 
> .git/rebase-apply/patch:531: trailing whitespace.
> 
> .git/rebase-apply/patch:701: trailing whitespace.
> 
> warning: 3 lines add whitespace errors.

Fixed.

> > +int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
> > +{
> > +       struct clk_init_data init;
> > +       struct sun4i_ddc *ddc;
> > +       const char *parent_name;
> > +
> > +       parent_name = __clk_get_name(parent);
> > +       if (!parent_name)
> > +               return -ENODEV;
> > +
> > +       ddc = devm_kzalloc(hdmi->dev, sizeof(*ddc), GFP_KERNEL);
> > +       if (!ddc)
> > +               return -ENOMEM;
> > +
> > +       init.name = "hdmi-ddc";
> > +       init.ops = &sun4i_ddc_ops;
> > +       init.parent_names = &parent_name;
> > +       init.num_parents = 1;
> > +       init.flags = CLK_SET_RATE_PARENT;
> 
> I don't think this is really needed. It probably doesn't hurt though,
> since DDC is used when HDMI is not used for displaying, but it might
> affect any upstream PLLs, which theoretically may affect other users
> of said PLLs. The DDC clock is slow enough that we should be able to
> generate a usable clock rate anyway.

Good point, I removed it.

> > +       writel(SUN4I_HDMI_VID_TIMING_X(mode->hdisplay) |
> > +              SUN4I_HDMI_VID_TIMING_Y(mode->vdisplay),
> > +              hdmi->base + SUN4I_HDMI_VID_TIMING_ACT_REG);
> > +
> > +       x = mode->htotal - mode->hsync_start;
> > +       y = mode->vtotal - mode->vsync_start;
> 
> I'm a bit skeptical about this one. All the other parameters are not
> inclusive of other, why would this one be different? Shouldn't it
> be "Xtotal - Xsync_end" instead?

By the usual meaning of backporch, you're right. However, Allwinner's
seems to have it's own, which is actually the backporch + sync length.

We also have that on all the other connectors (and TCON), and this was
confirmed at the time using a scope on an RGB signal.

> 
> > +       writel(SUN4I_HDMI_VID_TIMING_X(x) | SUN4I_HDMI_VID_TIMING_Y(y),
> > +              hdmi->base + SUN4I_HDMI_VID_TIMING_BP_REG);
> > +
> > +       x = mode->hsync_start - mode->hdisplay;
> > +       y = mode->vsync_start - mode->vdisplay;
> > +       writel(SUN4I_HDMI_VID_TIMING_X(x) | SUN4I_HDMI_VID_TIMING_Y(y),
> > +              hdmi->base + SUN4I_HDMI_VID_TIMING_FP_REG);
> > +
> > +       x = mode->hsync_end - mode->hsync_start;
> > +       y = mode->vsync_end - mode->vsync_start;
> > +       writel(SUN4I_HDMI_VID_TIMING_X(x) | SUN4I_HDMI_VID_TIMING_Y(y),
> > +              hdmi->base + SUN4I_HDMI_VID_TIMING_SPW_REG);
> > +
> > +       val = SUN4I_HDMI_VID_TIMING_POL_TX_CLK;
> > +       if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> > +               val |= SUN4I_HDMI_VID_TIMING_POL_HSYNC;
> > +
> > +       if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> > +               val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC;
> > +
> > +       writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
> 
> You don't handle the interlaced video here, even though you set
> 
>     hdmi->connector.interlace_allowed = true
> 
> later.

I'll fix that.

> The double clock and double scan flags aren't handled either, though
> I don't understand which one is supposed to represent the need for the
> HDMI pixel repeater. AFAIK this is required for resolutions with pixel
> clocks lower than 25 MHz, the lower limit of HDMI's TMDS link.

I'm not sure about this one though. I'd like to keep things quite
simple for now and build up on that once the basis is working. Is it
common in the wild?

> > +              hdmi->base + SUN4I_HDMI_DDC_FIFO_CTRL_REG);
> > +       writel(SUN4I_HDMI_DDC_ADDR_SEGMENT(offset >> 8) |
> > +              SUN4I_HDMI_DDC_ADDR_EDDC(0x60) |
> > +              SUN4I_HDMI_DDC_ADDR_OFFSET(offset) |
> > +              SUN4I_HDMI_DDC_ADDR_SLAVE(0x50),
> 
> You can use DDC_ADDR from drm_edid.h.

Done.

> > +static enum drm_connector_status
> > +sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
> > +{
> > +       struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> > +       unsigned long reg;
> > +
> > +       if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg,
> > +                              reg & SUN4I_HDMI_HPD_HIGH,
> > +                              0, 500000))
> 
> We shouldn't need to do polling here. It should just return the status
> at the instance it's called. Instead we should have a worker that does
> polling to check if something is plugged or unplugged. I don't see any
> interrupt bits for this though. :(

As far as I know, polling in detect is okay. Why would you want to
remove it?

> > +       ret = drm_encoder_init(drm,
> > +                              &hdmi->encoder,
> > +                              &sun4i_hdmi_funcs,
> > +                              DRM_MODE_ENCODER_TMDS,
> > +                              NULL);
> > +       if (ret) {
> > +               dev_err(dev, "Couldn't initialise the HDMI encoder\n");
> > +               return ret;
> > +       }
> > +
> > +       hdmi->encoder.possible_crtcs = BIT(0);
> 
> You can use drm_of_find_possible_crtcs() now. See the TV encoder driver.

Ack.

> > +
> > +       drm_connector_helper_add(&hdmi->connector,
> > +                                &sun4i_hdmi_connector_helper_funcs);
> > +       ret = drm_connector_init(drm, &hdmi->connector,
> > +                                &sun4i_hdmi_connector_funcs,
> > +                                DRM_MODE_CONNECTOR_HDMIA);
> > +       if (ret) {
> > +               dev_err(dev,
> > +                       "Couldn't initialise the Composite connector\n");
> 
> Wrong connector.

Fixed.

> > +       ret = sun4i_ddc_create(hdmi, hdmi->tmds_clk);
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "Couldn't create the DDC clock\n");
> > +               return ret;
> > +       }
> 
> We do all this in the bind function for all the other components.
> Any particular reason to do it differently here?

Not really, I'll change it.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170426/8bb09588/attachment-0001.sig>

  reply	other threads:[~2017-04-26  6:50 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-07  8:56 [PATCH 0/15] drm: sun4i: Add support for the HDMI controller Maxime Ripard
2017-03-07  8:56 ` [PATCH 1/15] clk: divider: Make divider_round_rate take the parent clock Maxime Ripard
2017-03-07 14:11   ` Stephen Boyd
2017-03-09 10:55     ` Maxime Ripard
2017-03-07  8:56 ` [PATCH 2/15] clk: sunxi-ng: Pass the parent and a pointer to the clocks round rate Maxime Ripard
2017-03-07  8:56 ` [PATCH 3/15] clk: sunxi-ng: div: Switch to divider_round_rate Maxime Ripard
2017-03-07  8:56 ` [PATCH 4/15] clk: sunxi-ng: mux: Don't just rely on the parent for CLK_SET_RATE_PARENT Maxime Ripard
2017-03-07  8:56 ` [PATCH 5/15] clk: sunxi-ng: sun5i: Export video PLLs Maxime Ripard
2017-03-07 10:21   ` [linux-sunxi] " Julian Calaby
2017-03-08  8:58     ` Maxime Ripard
2017-03-07  8:56 ` [PATCH 6/15] dt-bindings: display: sun4i: Add HDMI display bindings Maxime Ripard
2017-03-08  3:39   ` Chen-Yu Tsai
2017-03-15 17:26   ` Rob Herring
2017-04-03 20:59     ` Maxime Ripard
2017-05-03  3:27   ` Chen-Yu Tsai
2017-03-07  8:56 ` [PATCH 7/15] dt-bindings: display: sun4i: Add allwinner, tcon-channel property Maxime Ripard
2017-03-08  3:38   ` Chen-Yu Tsai
2017-03-15 17:37   ` [PATCH 7/15] dt-bindings: display: sun4i: Add allwinner,tcon-channel property Rob Herring
2017-03-17  3:34     ` [PATCH 7/15] dt-bindings: display: sun4i: Add allwinner, tcon-channel property Chen-Yu Tsai
2017-03-26 21:11       ` [PATCH 7/15] dt-bindings: display: sun4i: Add allwinner,tcon-channel property Maxime Ripard
2017-03-07  8:56 ` [PATCH 8/15] drm/sun4i: tcon: Add channel debug Maxime Ripard
2017-03-08  3:37   ` Chen-Yu Tsai
2017-03-07  8:56 ` [PATCH 9/15] drm/sun4i: tcon: Pass the encoder to the mode set functions Maxime Ripard
2017-03-07  8:56 ` [PATCH 10/15] drm/sun4i: tcon: Switch mux on only for composite Maxime Ripard
2017-03-08  3:51   ` Chen-Yu Tsai
2017-03-08  4:16     ` Stefan Monnier
2017-03-09 10:58     ` Maxime Ripard
2017-03-09 11:31       ` [linux-sunxi] " Chen-Yu Tsai
2017-03-09 14:55         ` Maxime Ripard
2017-03-07  8:56 ` [PATCH 11/15] drm/sun4i: tcon: Fix tcon channel 1 backporch calculation Maxime Ripard
2017-03-08  4:25   ` Chen-Yu Tsai
2017-03-08  8:55     ` Maxime Ripard
2017-03-07  8:56 ` [PATCH 12/15] drm/sun4i: tcon: multiply the vtotal when not in interlace Maxime Ripard
2017-03-07 10:05   ` Chen-Yu Tsai
2017-03-09 10:54     ` Maxime Ripard
2017-03-07  8:56 ` [PATCH 13/15] drm/sun4i: Add HDMI support Maxime Ripard
2017-04-21 15:17   ` [linux-sunxi] " Chen-Yu Tsai
2017-04-26  6:50     ` Maxime Ripard [this message]
2017-04-26  7:59       ` Chen-Yu Tsai
2017-05-03  8:41         ` Maxime Ripard
2017-03-07  8:56 ` [PATCH 14/15] ARM: sun5i: a10s: Add the HDMI controller node Maxime Ripard
2017-03-08  3:35   ` [linux-sunxi] " Chen-Yu Tsai
2017-03-09 10:59     ` Maxime Ripard
2017-03-09 11:10       ` Chen-Yu Tsai
2017-03-07  8:56 ` [PATCH 15/15] ARM: sun5i: a10s-olinuxino: Enable HDMI Maxime Ripard
2017-03-08  3:36   ` Chen-Yu Tsai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170426065005.zoewz53q7l7r5e7p@lukather \
    --to=maxime.ripard@free-electrons.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox