From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: jacopo mondi <jacopo@jmondi.org>
Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,
dri-devel@lists.freedesktop.org,
linux-renesas-soc@vger.kernel.org
Subject: Re: [PATCH 05/16] drm: rcar-du: lvds: D3/E3 support
Date: Fri, 14 Sep 2018 00:14:01 +0300 [thread overview]
Message-ID: <2103200.BD3voSUcdv@avalon> (raw)
In-Reply-To: <20180911132323.GN20333@w540>
Hi Jacopo,
On Tuesday, 11 September 2018 16:23:23 EEST jacopo mondi wrote:
> On Tue, Sep 04, 2018 at 03:10:16PM +0300, Laurent Pinchart wrote:
> > The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> > in the other R-Car Gen3 family members:
> >
> > - The LVDS PLL architecture is more complex and requires computing PLL
> > parameters manually.
> >
> > - The PLL uses external clocks as inputs, which need to be retrieved
> > from DT.
> >
> > - In addition to the different PLL setup, the startup sequence has
> > changed *again* (seems someone had trouble making his/her mind).
> >
> > Supporting all this requires DT bindings extensions for external clocks,
> > brand new PLL setup code, and a few quirks to handle the differences in
> > the startup sequence.
> >
> > The implementation doesn't support all hardware features yet, namely
> >
> > - Using the LV[01] clocks generated by the CPG as PLL input.
> > - Providing the LVDS PLL clock to the DU for use with the RGB output.
> >
> > Those features can be added later when the need will arise.
> >
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >
> > drivers/gpu/drm/rcar-du/rcar_lvds.c | 365 ++++++++++++++++++++++----
> > drivers/gpu/drm/rcar-du/rcar_lvds_regs.h | 43 +++-
> > 2 files changed, 361 insertions(+), 47 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > b/drivers/gpu/drm/rcar-du/rcar_lvds.c index ce0eb68c3416..aac4acbcfbfc
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
[snip]
> > +struct pll_info {
> > + struct clk *clk;
> > + unsigned long diff;
> > + unsigned int pll_m;
> > + unsigned int pll_n;
> > + unsigned int pll_e;
> > + unsigned int div;
> > +};
> > +
> > +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk
> > *clk,
> > + unsigned long target, struct pll_info *pll)
>
> Do you think it is worth mentioning d3_e3 in the function name? I know
> it's not a big deal, but in future generation this PLL circuit may be
> re-used.
How would you name it ? Other LVDS encoder instances have a different PLL, and
they are not named in the datasheet. I propose renaming it later if needed.
> > +{
> > + unsigned long fin;
> > + unsigned int m_min;
> > + unsigned int m_max;
> > + unsigned int m;
> > +
> > + if (!clk)
> > + return;
> > +
> > + /*
> > + * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
> > + * enough called M and N respectively), followed by a post-divider E.
> > + *
> > + * ,-----. ,-----. ,-----. ,-----.
> > + * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> > + * `-----' ,-> | | `-----' | `-----'
> > + * | `-----' |
> > + * | ,-----. |
> > + * `-------- | 1/N | <-------'
> > + * `-----'
> > + *
> > + * The clock output by the PLL is then further divided by a
programmable
> > + * divider DIV to achieve the desired target frequency. Finally, an
> > + * optional fixed /7 divider is used to convert the bit clock to a
pixel
> > + * clock (as LVDS transmits 7 bits per lane per clock sample).
> > + *
> > + * ,-------. ,-----. |\
> > + * Fout --> | 1/DIV | --> | 1/7 | --> | |
> > + * `-------' | `-----' | | --> dot clock
> > + * `------------> | |
> > + * |/
> > + *
> > + * The /7 divider is optional when the LVDS PLL is used to generate a
> > + * dot clock for the DU RGB output, without using the LVDS encoder. We
> > + * don't support this configuration yet.
> > + *
> > + * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> > + */
> > +
> > + fin = clk_get_rate(clk);
> > + if (fin < 12000000 || fin > 192000000)
> > + return;
> > +
> > + /*
> > + * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> > + * allowed values for the pre-divider M (normal range 1-8).
> > + *
> > + * Fpfd = Fin / M
> > + */
> > + m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> > + m_max = min_t(unsigned int, 8, fin / 12000000);
> > +
> > + for (m = m_min; m <= m_max; ++m) {
> > + unsigned long fpfd;
> > + unsigned int n_min;
> > + unsigned int n_max;
> > + unsigned int n;
> > +
> > + /*
> > + * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> > + * the allowed values for the multiplier N (normal range
> > + * 60-120).
> > + *
> > + * Fvco = Fin * N / M
> > + */
> > + fpfd = fin / m;
> > + n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> > + n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> > +
> > + for (n = n_min; n < n_max; ++n) {
> > + unsigned long fvco;
> > + unsigned int e_min;
> > + unsigned int e;
> > +
> > + /*
> > + * The output frequency is limited to 1039.5 MHz,
> > + * limiting again the allowed values for the
> > + * post-divider E (normal value 1, 2 or 4).
> > + *
> > + * Fout = Fvco / E
> > + */
> > + fvco = fpfd * n;
> > + e_min = fvco > 1039500000 ? 1 : 0;
> > +
> > + for (e = e_min; e < 3; ++e) {
> > + unsigned long fout;
> > + unsigned long diff;
> > + unsigned int div;
> > +
> > + /*
> > + * Finally we have a programable divider after
> > + * the PLL, followed by a an optional fixed /7
> > + * divider.
> > + */
> > + fout = fvco / (1 << e) / 7;
> > + div = DIV_ROUND_CLOSEST(fout, target);
> > + diff = abs(fout / div - target);
> > +
> > + if (diff < pll->diff) {
> > + pll->clk = clk;
> > + pll->diff = diff;
> > + pll->pll_m = m;
> > + pll->pll_n = n;
> > + pll->pll_e = e;
> > + pll->div = div;
> > +
> > + if (diff == 0)
> > + goto done;
> > + }
> > + }
> > + }
> > + }
>
> Very nice :)
Thanks :-)
> > +
> > +done:
> > +#if defined(CONFIG_DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
> > + {
> > + unsigned long output = fin * pll->pll_n / pll->pll_m
> > + / (1 << pll->pll_e) / 7 / pll->div;
> > + int error = (long)(output - target) * 10000 / (long)target;
> > +
> > + dev_dbg(lvds->dev,
> > + "%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL
> > M/N/E/DIV %u/%u/%u/%u\n", + clk, fin, output, target, error / 100,
> > + error < 0 ? -error % 100 : error % 100,
> > + pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> > + }
> > +#endif
>
> I know you know about this already, but
>
> ../drivers/gpu/drm/rcar-du/rcar_lvds.c:298:1: error: label at end of
> compound statement
>
> I'm still not sure what actually disturbs gcc here
Neither do I, but I've fixed it anyway.
> > }
> >
> > -static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
> > +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned
> > int freq)>
> > {
> >
> > - if (freq < 42000)
> > - return LVDPLLCR_PLLDIVCNT_42M;
> > - else if (freq < 85000)
> > - return LVDPLLCR_PLLDIVCNT_85M;
> > - else if (freq < 128000)
> > - return LVDPLLCR_PLLDIVCNT_128M;
> > + struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> > + struct pll_info pll = { .diff = (unsigned long)-1 };
> > + u32 lvdpllcr;
> > +
> > + if (lvds->clocks.dotclkin[0] || lvds->clocks.dotclkin[1]) {
> > + rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0],
> > + freq, &pll);
> > + rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1],
> > + freq, &pll);
> > + } else if (lvds->clocks.extal) {
> > + rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal,
> > + freq, &pll);
> > + }
>
> here it's either ((dotclkin[0] or dotclock[1]) or extal). Are they
> mutually exclusive? Can't we try all of them? The probe routine
> guarantees we have at least of of them...
I think you're right, I can't remember why I did it this way. I'll update the
code to try the three clocks.
> > +
> > + lvdpllcr = LVDPLLCR_PLLON | LVDPLLCR_CLKOUT
> > + | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> > +
> > + if (pll.clk == lvds->clocks.extal)
> > + lvdpllcr |= LVDPLLCR_CKSEL_EXTAL;
> > + else
> > + lvdpllcr |= LVDPLLCR_CKSEL_DU_DOTCLKIN(drm_crtc_index(crtc));
>
> Here you select du_clkin[0] or du_clkin[1] based on the DU index (btw,
> the drm_crtc_index() function is funny, it simply "crtc->index" no
> checks, no validation, what's the benefit of using it?).
See
commit 490d3d1b91201fd3d3d01d64e11df4eac1d92bd4
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri May 27 20:05:00 2016 +0100
drm: Store the plane's index
> Looking at the LVDS PLL block diagram for D3/E3 (Figure 37.3) I see
> that both clkin[0] and clkin[1] could be used independently from the du
> index. Shouldn't we use the one performing better? (now how to make
> sure it gets not selected twice in case of both DU0 and DU1 using the
> LVDS PLL it's another problem)
You're right again, I'll fix that.
> > +
> > + if (pll.pll_e > 0)
> > + lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> > + | LVDPLLCR_PLLE(pll.pll_e - 1);
> > +
> > + rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> > +
> > + if (pll.div > 1)
> > + rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> > + LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> > else
> > - return LVDPLLCR_PLLDIVCNT_148M;
> > + rcar_lvds_write(lvds, LVDDIV, 0);
> > }
[snip]
> > +static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char
> > *name,
> > + bool optional)
> > +{
> > + struct clk *clk;
> > +
> > + clk = devm_clk_get(lvds->dev, name);
>
> I wish we had clk_get_optional() as we have gpiod_get_optional().
> There are probably good reasons if it's not there though...
I don't know, given that this function is pretty much a clk_get_optional(), it
would seem useful to me. Feel free to propose it :-)
> > + if (!IS_ERR(clk))
> > + return clk;
> > +
> > + if (PTR_ERR(clk) == -ENOENT && optional)
> > + return NULL;
> > +
> > + if (PTR_ERR(clk) != -EPROBE_DEFER)
> > + dev_err(lvds->dev, "failed to get %s clock\n",
> > + name ? name : "module");
> > +
> > + return clk;
> > +}
[snip]
--
Regards,
Laurent Pinchart
WARNING: multiple messages have this Message-ID (diff)
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: jacopo mondi <jacopo@jmondi.org>
Cc: linux-renesas-soc@vger.kernel.org,
Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,
dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 05/16] drm: rcar-du: lvds: D3/E3 support
Date: Fri, 14 Sep 2018 00:14:01 +0300 [thread overview]
Message-ID: <2103200.BD3voSUcdv@avalon> (raw)
In-Reply-To: <20180911132323.GN20333@w540>
Hi Jacopo,
On Tuesday, 11 September 2018 16:23:23 EEST jacopo mondi wrote:
> On Tue, Sep 04, 2018 at 03:10:16PM +0300, Laurent Pinchart wrote:
> > The LVDS encoders in the D3 and E3 SoCs differ significantly from those
> > in the other R-Car Gen3 family members:
> >
> > - The LVDS PLL architecture is more complex and requires computing PLL
> > parameters manually.
> >
> > - The PLL uses external clocks as inputs, which need to be retrieved
> > from DT.
> >
> > - In addition to the different PLL setup, the startup sequence has
> > changed *again* (seems someone had trouble making his/her mind).
> >
> > Supporting all this requires DT bindings extensions for external clocks,
> > brand new PLL setup code, and a few quirks to handle the differences in
> > the startup sequence.
> >
> > The implementation doesn't support all hardware features yet, namely
> >
> > - Using the LV[01] clocks generated by the CPG as PLL input.
> > - Providing the LVDS PLL clock to the DU for use with the RGB output.
> >
> > Those features can be added later when the need will arise.
> >
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >
> > drivers/gpu/drm/rcar-du/rcar_lvds.c | 365 ++++++++++++++++++++++----
> > drivers/gpu/drm/rcar-du/rcar_lvds_regs.h | 43 +++-
> > 2 files changed, 361 insertions(+), 47 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > b/drivers/gpu/drm/rcar-du/rcar_lvds.c index ce0eb68c3416..aac4acbcfbfc
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
[snip]
> > +struct pll_info {
> > + struct clk *clk;
> > + unsigned long diff;
> > + unsigned int pll_m;
> > + unsigned int pll_n;
> > + unsigned int pll_e;
> > + unsigned int div;
> > +};
> > +
> > +static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk
> > *clk,
> > + unsigned long target, struct pll_info *pll)
>
> Do you think it is worth mentioning d3_e3 in the function name? I know
> it's not a big deal, but in future generation this PLL circuit may be
> re-used.
How would you name it ? Other LVDS encoder instances have a different PLL, and
they are not named in the datasheet. I propose renaming it later if needed.
> > +{
> > + unsigned long fin;
> > + unsigned int m_min;
> > + unsigned int m_max;
> > + unsigned int m;
> > +
> > + if (!clk)
> > + return;
> > +
> > + /*
> > + * The LVDS PLL is made of a pre-divider and a multiplier (strangerly
> > + * enough called M and N respectively), followed by a post-divider E.
> > + *
> > + * ,-----. ,-----. ,-----. ,-----.
> > + * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
> > + * `-----' ,-> | | `-----' | `-----'
> > + * | `-----' |
> > + * | ,-----. |
> > + * `-------- | 1/N | <-------'
> > + * `-----'
> > + *
> > + * The clock output by the PLL is then further divided by a
programmable
> > + * divider DIV to achieve the desired target frequency. Finally, an
> > + * optional fixed /7 divider is used to convert the bit clock to a
pixel
> > + * clock (as LVDS transmits 7 bits per lane per clock sample).
> > + *
> > + * ,-------. ,-----. |\
> > + * Fout --> | 1/DIV | --> | 1/7 | --> | |
> > + * `-------' | `-----' | | --> dot clock
> > + * `------------> | |
> > + * |/
> > + *
> > + * The /7 divider is optional when the LVDS PLL is used to generate a
> > + * dot clock for the DU RGB output, without using the LVDS encoder. We
> > + * don't support this configuration yet.
> > + *
> > + * The PLL allowed input frequency range is 12 MHz to 192 MHz.
> > + */
> > +
> > + fin = clk_get_rate(clk);
> > + if (fin < 12000000 || fin > 192000000)
> > + return;
> > +
> > + /*
> > + * The comparison frequency range is 12 MHz to 24 MHz, which limits the
> > + * allowed values for the pre-divider M (normal range 1-8).
> > + *
> > + * Fpfd = Fin / M
> > + */
> > + m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
> > + m_max = min_t(unsigned int, 8, fin / 12000000);
> > +
> > + for (m = m_min; m <= m_max; ++m) {
> > + unsigned long fpfd;
> > + unsigned int n_min;
> > + unsigned int n_max;
> > + unsigned int n;
> > +
> > + /*
> > + * The VCO operating range is 900 Mhz to 1800 MHz, which limits
> > + * the allowed values for the multiplier N (normal range
> > + * 60-120).
> > + *
> > + * Fvco = Fin * N / M
> > + */
> > + fpfd = fin / m;
> > + n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
> > + n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
> > +
> > + for (n = n_min; n < n_max; ++n) {
> > + unsigned long fvco;
> > + unsigned int e_min;
> > + unsigned int e;
> > +
> > + /*
> > + * The output frequency is limited to 1039.5 MHz,
> > + * limiting again the allowed values for the
> > + * post-divider E (normal value 1, 2 or 4).
> > + *
> > + * Fout = Fvco / E
> > + */
> > + fvco = fpfd * n;
> > + e_min = fvco > 1039500000 ? 1 : 0;
> > +
> > + for (e = e_min; e < 3; ++e) {
> > + unsigned long fout;
> > + unsigned long diff;
> > + unsigned int div;
> > +
> > + /*
> > + * Finally we have a programable divider after
> > + * the PLL, followed by a an optional fixed /7
> > + * divider.
> > + */
> > + fout = fvco / (1 << e) / 7;
> > + div = DIV_ROUND_CLOSEST(fout, target);
> > + diff = abs(fout / div - target);
> > +
> > + if (diff < pll->diff) {
> > + pll->clk = clk;
> > + pll->diff = diff;
> > + pll->pll_m = m;
> > + pll->pll_n = n;
> > + pll->pll_e = e;
> > + pll->div = div;
> > +
> > + if (diff == 0)
> > + goto done;
> > + }
> > + }
> > + }
> > + }
>
> Very nice :)
Thanks :-)
> > +
> > +done:
> > +#if defined(CONFIG_DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
> > + {
> > + unsigned long output = fin * pll->pll_n / pll->pll_m
> > + / (1 << pll->pll_e) / 7 / pll->div;
> > + int error = (long)(output - target) * 10000 / (long)target;
> > +
> > + dev_dbg(lvds->dev,
> > + "%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL
> > M/N/E/DIV %u/%u/%u/%u\n", + clk, fin, output, target, error / 100,
> > + error < 0 ? -error % 100 : error % 100,
> > + pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
> > + }
> > +#endif
>
> I know you know about this already, but
>
> ../drivers/gpu/drm/rcar-du/rcar_lvds.c:298:1: error: label at end of
> compound statement
>
> I'm still not sure what actually disturbs gcc here
Neither do I, but I've fixed it anyway.
> > }
> >
> > -static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq)
> > +static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned
> > int freq)>
> > {
> >
> > - if (freq < 42000)
> > - return LVDPLLCR_PLLDIVCNT_42M;
> > - else if (freq < 85000)
> > - return LVDPLLCR_PLLDIVCNT_85M;
> > - else if (freq < 128000)
> > - return LVDPLLCR_PLLDIVCNT_128M;
> > + struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
> > + struct pll_info pll = { .diff = (unsigned long)-1 };
> > + u32 lvdpllcr;
> > +
> > + if (lvds->clocks.dotclkin[0] || lvds->clocks.dotclkin[1]) {
> > + rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0],
> > + freq, &pll);
> > + rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1],
> > + freq, &pll);
> > + } else if (lvds->clocks.extal) {
> > + rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal,
> > + freq, &pll);
> > + }
>
> here it's either ((dotclkin[0] or dotclock[1]) or extal). Are they
> mutually exclusive? Can't we try all of them? The probe routine
> guarantees we have at least of of them...
I think you're right, I can't remember why I did it this way. I'll update the
code to try the three clocks.
> > +
> > + lvdpllcr = LVDPLLCR_PLLON | LVDPLLCR_CLKOUT
> > + | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
> > +
> > + if (pll.clk == lvds->clocks.extal)
> > + lvdpllcr |= LVDPLLCR_CKSEL_EXTAL;
> > + else
> > + lvdpllcr |= LVDPLLCR_CKSEL_DU_DOTCLKIN(drm_crtc_index(crtc));
>
> Here you select du_clkin[0] or du_clkin[1] based on the DU index (btw,
> the drm_crtc_index() function is funny, it simply "crtc->index" no
> checks, no validation, what's the benefit of using it?).
See
commit 490d3d1b91201fd3d3d01d64e11df4eac1d92bd4
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri May 27 20:05:00 2016 +0100
drm: Store the plane's index
> Looking at the LVDS PLL block diagram for D3/E3 (Figure 37.3) I see
> that both clkin[0] and clkin[1] could be used independently from the du
> index. Shouldn't we use the one performing better? (now how to make
> sure it gets not selected twice in case of both DU0 and DU1 using the
> LVDS PLL it's another problem)
You're right again, I'll fix that.
> > +
> > + if (pll.pll_e > 0)
> > + lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
> > + | LVDPLLCR_PLLE(pll.pll_e - 1);
> > +
> > + rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
> > +
> > + if (pll.div > 1)
> > + rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
> > + LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
> > else
> > - return LVDPLLCR_PLLDIVCNT_148M;
> > + rcar_lvds_write(lvds, LVDDIV, 0);
> > }
[snip]
> > +static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char
> > *name,
> > + bool optional)
> > +{
> > + struct clk *clk;
> > +
> > + clk = devm_clk_get(lvds->dev, name);
>
> I wish we had clk_get_optional() as we have gpiod_get_optional().
> There are probably good reasons if it's not there though...
I don't know, given that this function is pretty much a clk_get_optional(), it
would seem useful to me. Feel free to propose it :-)
> > + if (!IS_ERR(clk))
> > + return clk;
> > +
> > + if (PTR_ERR(clk) == -ENOENT && optional)
> > + return NULL;
> > +
> > + if (PTR_ERR(clk) != -EPROBE_DEFER)
> > + dev_err(lvds->dev, "failed to get %s clock\n",
> > + name ? name : "module");
> > +
> > + return clk;
> > +}
[snip]
--
Regards,
Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2018-09-14 2:25 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-04 12:10 [PATCH 00/16] R-Car D3/E3 display support (with LVDS PLL) Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 01/16] dt-bindings: display: renesas: du: Document r8a77990 bindings Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-14 7:56 ` jacopo mondi
2018-09-14 7:56 ` jacopo mondi
2018-09-17 5:44 ` Rob Herring
2018-09-04 12:10 ` [PATCH 02/16] dt-bindings: display: renesas: lvds: " Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-14 7:57 ` jacopo mondi
2018-09-14 7:57 ` jacopo mondi
2018-09-17 5:44 ` Rob Herring
2018-09-04 12:10 ` [PATCH 03/16] dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-14 8:00 ` jacopo mondi
2018-09-14 8:00 ` jacopo mondi
2018-09-14 8:24 ` Laurent Pinchart
2018-09-14 8:24 ` Laurent Pinchart
2018-09-14 8:35 ` jacopo mondi
2018-09-14 8:35 ` jacopo mondi
2018-09-04 12:10 ` [PATCH 04/16] drm: bridge: thc63: Restrict modes based on hardware operating frequency Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-11 13:31 ` jacopo mondi
2018-09-11 13:31 ` jacopo mondi
2018-09-13 21:08 ` Laurent Pinchart
2018-09-13 21:08 ` Laurent Pinchart
2018-09-13 12:36 ` Andrzej Hajda
2018-09-13 12:36 ` Andrzej Hajda
2018-09-04 12:10 ` [PATCH 05/16] drm: rcar-du: lvds: D3/E3 support Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 14:29 ` Geert Uytterhoeven
2018-09-04 14:29 ` Geert Uytterhoeven
2018-09-05 14:01 ` Laurent Pinchart
2018-09-05 14:01 ` Laurent Pinchart
2018-09-11 13:23 ` jacopo mondi
2018-09-11 13:23 ` jacopo mondi
2018-09-13 21:14 ` Laurent Pinchart [this message]
2018-09-13 21:14 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get() Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-07 18:19 ` jacopo mondi
2018-09-07 18:19 ` jacopo mondi
2018-09-09 16:44 ` Laurent Pinchart
2018-09-09 16:44 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 07/16] drm: rcar-du: Use LVDS PLL clock as dot clock when possible Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-11 14:59 ` jacopo mondi
2018-09-11 14:59 ` jacopo mondi
2018-09-13 21:17 ` Laurent Pinchart
2018-09-13 21:17 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 08/16] drm: rcar-du: Enable configurable DPAD0 routing on Gen3 Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-11 15:46 ` jacopo mondi
2018-09-11 15:46 ` jacopo mondi
2018-09-13 21:25 ` Laurent Pinchart
2018-09-13 21:25 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 09/16] drm: rcar-du: Cache DSYSR value to ensure known initial value Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 10/16] drm: rcar-du: Don't use TV sync mode when not supported by the hardware Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 11/16] drm: rcar-du: Add r8a77990 and r8a77995 device support Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 12/16] arm64: dts: renesas: r8a77990: Add I2C device nodes Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 14:32 ` Geert Uytterhoeven
2018-09-04 14:32 ` Geert Uytterhoeven
2018-09-04 14:49 ` jacopo mondi
2018-09-04 14:49 ` jacopo mondi
2018-09-05 13:53 ` Laurent Pinchart
2018-09-05 13:53 ` Laurent Pinchart
2018-09-06 9:26 ` Simon Horman
2018-09-06 9:26 ` Simon Horman
2018-09-06 9:48 ` Laurent Pinchart
2018-09-06 9:48 ` Laurent Pinchart
2018-09-05 13:52 ` Laurent Pinchart
2018-09-05 13:52 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 13/16] arm64: dts: renesas: r8a77990: Add display output support Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 14/16] arm64: dts: renesas: r8a77995: Add LVDS support Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 15/16] arm64: dts: renesas: r8a77990: ebisu: Enable VGA and HDMI outputs Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-04 12:10 ` [PATCH 16/16] arm64: dts: renesas: r8a77995: draak: Enable HDMI display output Laurent Pinchart
2018-09-04 12:10 ` Laurent Pinchart
2018-09-05 16:22 ` [PATCH 00/16] R-Car D3/E3 display support (with LVDS PLL) jacopo mondi
2018-09-05 16:22 ` jacopo mondi
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=2103200.BD3voSUcdv@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jacopo@jmondi.org \
--cc=laurent.pinchart+renesas@ideasonboard.com \
--cc=linux-renesas-soc@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.