Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v3] arm64: allwinner: a64: Add Amarula A64-Relic initial support
From: Maxime Ripard @ 2018-05-23  8:18 UTC (permalink / raw)
  To: Jagan Teki
  Cc: Chen-Yu Tsai, Michael Trimarchi, Icenowy Zheng, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi
In-Reply-To: <CAMty3ZD3JT-ToGAUHN_uj7uVK-jkyAwfEdTBCmJSj34bACFpYQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1081 bytes --]

On Wed, May 23, 2018 at 11:44:56AM +0530, Jagan Teki wrote:
> On Tue, May 22, 2018 at 8:00 PM, Maxime Ripard
> <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org> wrote:
> > On Tue, May 22, 2018 at 06:52:28PM +0530, Jagan Teki wrote:
> >> Amarula A64-Relic is Allwinner A64 based IoT device, which support
> >> - Allwinner A64 Cortex-A53
> >> - Mali-400MP2 GPU
> >> - AXP803 PMIC
> >> - 1GB DDR3 RAM
> >> - 8GB eMMC
> >> - AP6330 Wifi/BLE
> >> - MIPI-DSI
> >> - CSI: OV5640 sensor
> >> - USB OTG
> >
> > You claim that this is doing OTG...
> >
> > [..]
> >
> >> +&usb_otg {
> >> +     dr_mode = "peripheral";
> >> +     status = "okay";
> >> +};
> >
> > ... and yet you're setting it as peripheral...
> 
> Though it claims OTG, board doesn't have any USB ports to operate(not
> even Mini-AB) the only way to use the board as peripheral to transfer
> images from host.

I'm not sure what you mean here. If there's no USB connector, why do
you even enable it?

maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: [PATCH v6 2/6] dt-bindings: Add the rzn1-clocks.h file
From: M P @ 2018-05-23  8:17 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: michel.pollet, linux-renesas-soc, Simon Horman, Phil Edworthy,
	buserror+upstream, Magnus Damm, robh+dt, mark.rutland,
	Michael Turquette, sboyd, geert+renesas, devicetree, linux-kernel,
	linux-clk
In-Reply-To: <CAMuHMdWAU9wZkA+Z0BNAGrLV1WrCO3PgCTo2p=q3Mq9Tm6JBGA@mail.gmail.com>

Morning Geert,

On Wed, 23 May 2018 at 08:26, Geert Uytterhoeven <geert@linux-m68k.org>
wrote:

> Hi Michel,

> On Wed, May 23, 2018 at 8:44 AM, M P <buserror@gmail.com> wrote:
> > On Tue, 22 May 2018 at 19:44, Geert Uytterhoeven <geert@linux-m68k.org>
> > wrote:
> >> On Tue, May 22, 2018 at 12:01 PM, Michel Pollet
> >> <michel.pollet@bp.renesas.com> wrote:
> >> > This adds the constants necessary to use the renesas,rzn1-clocks
driver.
> >> >
> >> > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>

> >> > --- /dev/null
> >> > +++ b/include/dt-bindings/clock/rzn1-clocks.h
> >
> >> Given this is part of the DT ABI, and there exist multiple different
RZ/N1
> >> SoCs (and there are probably planned more), I wouldn't call this header
> >> file "rzn1-clocks.h", but e.g. "r9a06g032-clocks.h".
> >
> > Actually, no, there already are two r906g03X devices that will work
> > perfectly fine with this driver. We had that discussion before, and you
> > insist and me removing mentions of the rzn1 everywhere, however, this
> > applies to *two* devices already, and I'm supposed to upstream support
for
> > them. I can't rename r9g06g032 because it is *inexact* that's why it's

> My worry is not that there are two r906g03X devices that will work fine
> with this driver, but that there will be other "rzn1" devices that will
not
> work with these bindings (the header file is part of the bindings).
> Besides, RZ/N1D and RZ/N1S (Which apparently differ in packaging only?
> Oh no, RZ/N1D (the larger package) has less QSPI channels than RZ/N1S
> (the smaller package)), there's also (at least) RZ/N1L.

> > called rzn1. So unless you let me call it r9a06g0xx-clocks.h (which i
know
> > you won't as per multiple previous discussions) this can't be called
> > r9a06g032 because it won't be fit for my purpose when I try to bring
back
> > the RZ/N1S into the picture.

> You can add r9a06g033-clocks.h when adding support for RZ/N1S.

So it is now acceptable to duplicate a huge amount of code, and constants
when in fact there differences are so minor they would require minimal
amount of code to take care of them? That just flies straight against my
30+ years of programming -- We're going to have twice the *identical* code,
twice the header, and completely incompatible device tree files -- I mean,
*right now* our rzn1.dtsi works *as is* on the 1D and 1S, we've got ONE
file to maintain, and you can switch your CPU board from 1D to 1S and your
'board file' can stay the same.

Wasn't it the idea of that stuff in the first place? Isn't it in the
customer/engineer interest to be able to cross grade from one
manufacturer's device *in the same series* to another without having to
duplicate his whole board file?

> > There are minor difference to clocking,

> Aha?

Sure, 1S doesn't' have DDR, 1D doesn't have the second QSPI. That's about
it (I lie, theres a few other bits I'm sure). It's not like it won't even
*work* or anything, the registers are there, the bit positions are there,
all is the same, I'm *sure* that's what the compatible="" thing were
supposed to be used for, isn't it? Heck, I'm pretty sure there's a register
in sysctrl, that tells me that anyway, so I wouldn't even have to have a
special compatible= -- I didn't do it since the driver is already so big.


> > I don't know if Renesas plans to release any more rzn1's in this series,
> > but my little finger tells me this isn't the case. But regardless of
what

> We thought the same thing when the first RZ member (RZ/A1H) showed up.
> Did we know this was not going to be the first SoC of a new RZ family, but
> the first SoC of the first subfamily (RZ/A) of the RZ family... And the
> various subfamilies bear not much similarity.

> > we plan, Marketing will screw it up.

> Correct. And to mitigate that, we have no other choice than to use the
real
> part numbers to differentiate. Once bitten, twice shy.

It's not mitigation from where I stand -- it's a gigantic kludge; To handle
one exception, you throw away the baby with the bathwater. From where I
sit, it's like having to a different screwdriver for the screws on the left
of a panel vs the right of the panel.

Sorry to come out as pretty miffed -- I've just spent weeks polishing up a
driver to make it more or less similar to what they were 10 years ago (whoo
look a platform file with a big table in it!), after throwing away all the
work I had done to make it all device-tree based and make the code as
agnostic as we could -- and now it turns out we need to make it even worse
by throwing away the fact it actually *does* work on two SoC -- and that
just because... because what, again?

What about *making up names* -- The 'family names' can/will change -- the
part numbers are *too limited in scope* -- why not just make up names? does
it matter as long as it's close to reality and are documented? I dunno,
"rzn1_18" or "rzn1_mk1" and so we have a way out when they release a new
one next year? It seems to be working fine for cars "I got a 2018's
<Manufacturer> <series>"...

Cheers,
Michel



> Gr{oetje,eeting}s,

>                          Geert

> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 --
geert@linux-m68k.org

> In personal conversations with technical people, I call myself a hacker.
But
> when I'm talking to journalists I just say "programmer" or something like
that.
>                                  -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v3 5/6] spi: at91-usart: add driver for at91-usart as spi
From: Radu Pirea @ 2018-05-23  8:10 UTC (permalink / raw)
  To: Mark Brown
  Cc: devicetree, linux-serial, linux-kernel, linux-arm-kernel,
	linux-spi, mark.rutland, robh+dt, lee.jones, gregkh, jslaby,
	richard.genoud, alexandre.belloni, nicolas.ferre
In-Reply-To: <20180517050406.GF20254@sirena.org.uk>



On 05/17/2018 08:04 AM, Mark Brown wrote:
> On Fri, May 11, 2018 at 01:38:21PM +0300, Radu Pirea wrote:
> 
>> +config SPI_AT91_USART
>> +        tristate "Atmel USART Controller as SPI"
>> +	depends on HAS_DMA
>> +	depends on (ARCH_AT91 || COMPILE_TEST)
>> +        select MFD_AT91_USART
>> +	help
>> +	  This selects a driver for the AT91 USART Controller as SPI Master,
>> +	  present on AT91 and SAMA5 SoC series.
>> +
> 
> This looks like there's some tab/space mixing going on here.
> 
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Driver for AT91 USART Controllers as SPI
>> + *
>> + * Copyright (C) 2018 Microchip Technology Inc.
> 
> Make the entire block a C++ comment so it looks more intentional rather
> tha mixing C and C++.

Hi Mark,

I know it's ugly, but SPDX license identifier must be in a separate 
comment block.

> 
>> +static inline void at91_usart_spi_tx(struct at91_usart_spi *aus)
>> +{
>> +	unsigned int len = aus->current_transfer->len;
>> +	unsigned int remaining = aus->current_tx_remaining_bytes;
>> +	const u8  *tx_buf = aus->current_transfer->tx_buf;
>> +
>> +	if (tx_buf && remaining) {
>> +		if (at91_usart_spi_tx_ready(aus))
>> +			spi_writel(aus, THR, tx_buf[len - remaining]);
>> +			aus->current_tx_remaining_bytes--;
> 
> Missing braces here - we only write to the FIFO if there's space but we
> unconditionally decrement the counter.
> 

Thanks. I will fix it.

>> +	} else {
>> +		if (at91_usart_spi_tx_ready(aus))
>> +			spi_writel(aus, THR, US_DUMMY_TX);
>> +	}
>> +}
> 
> This looks like you're open coding SPI_CONTROLLER_MUST_TX
> 
>> +	int len = aus->current_transfer->len;
>> +	int remaining = aus->current_rx_remaining_bytes;
>> +	u8  *rx_buf = aus->current_transfer->rx_buf;
>> +
>> +	if (aus->current_rx_remaining_bytes) {
>> +		rx_buf[len - remaining] = spi_readb(aus, RHR);
>> +		aus->current_rx_remaining_bytes--;
>> +	} else {
>> +		spi_readb(aus, RHR);
>> +	}
> 
> Similarly for _MUST_RX.
> 
>> +	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
> 
> You're actually setting both flags...  this means that the handling for
> cases with missing TX or RX buffers can't happen.

Sorry. My mistake. I will remove unnecessary code.

^ permalink raw reply

* Re: [PATCH] dt-bindings: gpio: rcar: Add support for r8a77990
From: Linus Walleij @ 2018-05-23  8:05 UTC (permalink / raw)
  To: Yoshihiro Shimoda
  Cc: Rob Herring, Mark Rutland, Linux-Renesas,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
In-Reply-To: <1526008386-26420-1-git-send-email-yoshihiro.shimoda.uh@renesas.com>

On Fri, May 11, 2018 at 5:13 AM, Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com> wrote:

> Add compatible string for R-Car E3 (r8a77990) in gpio-rcar.
>
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Quite uncontroversial so, patch applied with Simon's
ACK.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH] ARM: dts: vexpress: Replace '_' with '-' in node names
From: Linus Walleij @ 2018-05-23  8:02 UTC (permalink / raw)
  To: Rob Herring
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Liviu Dudau,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Sudeep Holla
In-Reply-To: <CAL_Jsq+VNuvbxgFTFVouJF-_yMS90u0fd8jaXnYtKwogOP5rww@mail.gmail.com>

On Wed, May 9, 2018 at 11:14 PM, Rob Herring <robh+dt@kernel.org> wrote:
> On Wed, May 9, 2018 at 11:48 AM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>> The latest DTC throws warnings for character '_' in the node names.
>>
>> Warning (node_name_chars_strict): /sysreg@10000/sys_led: Character '_' not recommended in node name
>> Warning (node_name_chars_strict): /sysreg@10000/sys_mci: Character '_' not recommended in node name
>> Warning (node_name_chars_strict): /sysreg@10000/sys_flash: Character '_' not recommended in node name
>>
>> The general recommendation is to use character '-' for all the node names.
>> This patch fixes the warnings following the recommendation.
>>
>> Cc: Liviu Dudau <liviu.dudau@arm.com>
>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
>> ---
>>  arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
>> index 7b8ff5b3b912..58e73131ecef 100644
>> --- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
>> +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
>> @@ -77,19 +77,19 @@
>>                                         compatible = "arm,vexpress-sysreg";
>>                                         reg = <0x010000 0x1000>;
>>
>> -                                       v2m_led_gpios: sys_led {
>> +                                       v2m_led_gpios: sys-led {
>
> Except this is a gpio-controller so it should have 'gpio' for its node
> name. (I have a dtc check written for that, but there are too many
> false positives.)
>
> But then you have 3 of them and no addressing, so you need to add reg
> property (with the register's offset and size) and unit-address.
>
> I'm surprised Linus W accepted these a GPIO when they are not really
> general purpose, but then lots of things slip in.

I guess is was back in this day when we had a finger constantly
on the fastforward button for DT conversion, and a few not so
elegant things slipped in.

I was annoyed by this thing later, especially since others started
to use it as a consistency argument "well you allowed this so
now allow this other crazy thing that looks the same" :D

I suspect I either was not CC:ed or I just sucked at shepherding
this, I try to do better these days.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH 3/3] arm64: dts: juno/rtsm: re-structure motherboard includes
From: Linus Walleij @ 2018-05-23  7:59 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, Liviu Dudau, Linux ARM
In-Reply-To: <1525884291-18851-3-git-send-email-sudeep.holla@arm.com>

On Wed, May 9, 2018 at 6:44 PM, Sudeep Holla <sudeep.holla@arm.com> wrote:

> It is a bit unorthodox to just include a file in the middle of a another
> DTS file, it breaks the pattern from other device trees and also makes
> it really hard to reference things across the files with phandles.
>
> Restructure the include for the Juno/RTSM motherboards to happen at the
> top of the file, reference the target nodes directly, and indent the
> motherboard .dtsi files to reflect their actual depth in the hierarchy.
>
> This is a purely syntactic change that result in the same DTB files from
> the DTS/DTSI files. This is based on similar patch from Linus Walleij
> for ARM Vexpress platforms.
>
> Cc: Liviu Dudau <liviu.dudau@arm.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Thanks for doing this, it is much more readable for me now.

Sorry for slow review :/

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH V2 3/3] ARM: dts: imx7: correct enet ipg clock
From: Stefan Agner @ 2018-05-23  7:58 UTC (permalink / raw)
  To: Anson Huang
  Cc: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland,
	mturquette, sboyd, adriana.reus, rui.silva, Linux-imx,
	linux-arm-kernel, devicetree, linux-kernel, linux-clk
In-Reply-To: <1526605266-18464-3-git-send-email-Anson.Huang@nxp.com>

On 18.05.2018 03:01, Anson Huang wrote:
> ENET "ipg" clock should be IMX7D_ENETx_IPG_ROOT_CLK
> rather than IMX7D_ENET_AXI_ROOT_CLK which is for ENET bus
> clock.
> 
> Based on Andy Duan's patch from the NXP kernel tree.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>

Reviewed-by: Stefan Agner <stefan@agner.ch>

--
Stefan

> ---
>  arch/arm/boot/dts/imx7d.dtsi | 2 +-
>  arch/arm/boot/dts/imx7s.dtsi | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
> index 200714e..d74dd7f 100644
> --- a/arch/arm/boot/dts/imx7d.dtsi
> +++ b/arch/arm/boot/dts/imx7d.dtsi
> @@ -120,7 +120,7 @@
>  			<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
>  			<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
>  			<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> -		clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
> +		clocks = <&clks IMX7D_ENET2_IPG_ROOT_CLK>,
>  			<&clks IMX7D_ENET_AXI_ROOT_CLK>,
>  			<&clks IMX7D_ENET2_TIME_ROOT_CLK>,
>  			<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
> diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
> index 4d42335..b90769d 100644
> --- a/arch/arm/boot/dts/imx7s.dtsi
> +++ b/arch/arm/boot/dts/imx7s.dtsi
> @@ -1091,7 +1091,7 @@
>  					<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
>  					<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
>  					<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
> -				clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
> +				clocks = <&clks IMX7D_ENET1_IPG_ROOT_CLK>,
>  					<&clks IMX7D_ENET_AXI_ROOT_CLK>,
>  					<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
>  					<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,

^ permalink raw reply

* Re: [PATCH 3/5] watchdog: sp805: set WDOG_HW_RUNNING when appropriate
From: Scott Branden @ 2018-05-23  7:52 UTC (permalink / raw)
  To: Ray Jui, Guenter Roeck
  Cc: Wim Van Sebroeck, Rob Herring, Mark Rutland, Frank Rowand,
	Catalin Marinas, Will Deacon, linux-watchdog, devicetree,
	linux-arm-kernel, linux-kernel, bcm-kernel-feedback-list
In-Reply-To: <0d92b9e9-a3d1-6e91-8371-b5ed3a83e399@broadcom.com>



On 18-05-22 04:24 PM, Ray Jui wrote:
> Hi Guenter,
>
> On 5/22/2018 1:54 PM, Guenter Roeck wrote:
>> On Tue, May 22, 2018 at 11:47:18AM -0700, Ray Jui wrote:
>>> If the watchdog hardware is already enabled during the boot process,
>>> when the Linux watchdog driver loads, it should reset the watchdog and
>>> tell the watchdog framework. As a result, ping can be generated from
>>> the watchdog framework, until the userspace watchdog daemon takes over
>>> control
>>>
>>> Signed-off-by: Ray Jui <ray.jui@broadcom.com>
>>> Reviewed-by: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com>
>>> Reviewed-by: Scott Branden <scott.branden@broadcom.com>
>>> ---
>>>   drivers/watchdog/sp805_wdt.c | 22 ++++++++++++++++++++++
>>>   1 file changed, 22 insertions(+)
>>>
>>> diff --git a/drivers/watchdog/sp805_wdt.c 
>>> b/drivers/watchdog/sp805_wdt.c
>>> index 1484609..408ffbe 100644
>>> --- a/drivers/watchdog/sp805_wdt.c
>>> +++ b/drivers/watchdog/sp805_wdt.c
>>> @@ -42,6 +42,7 @@
>>>       /* control register masks */
>>>       #define    INT_ENABLE    (1 << 0)
>>>       #define    RESET_ENABLE    (1 << 1)
>>> +    #define    ENABLE_MASK    (INT_ENABLE | RESET_ENABLE)
>>>   #define WDTINTCLR        0x00C
>>>   #define WDTRIS            0x010
>>>   #define WDTMIS            0x014
>>> @@ -74,6 +75,18 @@ module_param(nowayout, bool, 0);
>>>   MODULE_PARM_DESC(nowayout,
>>>           "Set to 1 to keep watchdog running after device release");
>>>   +/* returns true if wdt is running; otherwise returns false */
>>> +static bool wdt_is_running(struct watchdog_device *wdd)
>>> +{
>>> +    struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
>>> +
>>> +    if ((readl_relaxed(wdt->base + WDTCONTROL) & ENABLE_MASK) ==
>>> +        ENABLE_MASK)
>>> +        return true;
>>> +    else
>>> +        return false;
>>
>>     return !!(readl_relaxed(wdt->base + WDTCONTROL) & ENABLE_MASK));
>>
>
> Note ENABLE_MASK contains two bits (INT_ENABLE and RESET_ENABLE); 
> therefore, a simple !!(expression) would not work? That is, the masked 
> result needs to be compared against the mask again to ensure both bits 
> are set, right?
Ray - your original code looks correct to me.  Easier to read and less 
prone to errors as shown in the attempted translation to a single statement.
>
> Thanks,
>
> Ray

^ permalink raw reply

* [PATCH v7 5/5] drm/rockchip: support dp training outside dp firmware
From: Lin Huang @ 2018-05-23  7:42 UTC (permalink / raw)
  To: seanpaul, airlied, zyw, kishon
  Cc: dianders, briannorris, linux-rockchip, heiko, daniel.vetter,
	dri-devel, linux-arm-kernel, linux-kernel, eballetbo, robh+dt,
	devicetree, Lin Huang
In-Reply-To: <1527061353-16902-1-git-send-email-hl@rock-chips.com>

DP firmware uses fixed phy config values to do training, but some
boards need to adjust these values to fit for their unique hardware
design. So get phy config values from dts and use software link training
instead of relying on firmware, if software training fail, keep firmware
training as a fallback if sw training fails.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Signed-off-by: Lin Huang <hl@rock-chips.com>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- use variable fw_training instead sw_training_success
- base on DP SPCE, if training fail use lower link rate to retry training
Changes in v4:
- improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() follow Sean suggest
Changes in v5:
- fix some whitespcae issue
Changes in v6:
- None
Changes in v7:
- None

 drivers/gpu/drm/rockchip/Makefile               |   3 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c          |  24 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.h          |   2 +
 drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 ++++++++++++++++++++++++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c           |  31 +-
 drivers/gpu/drm/rockchip/cdn-dp-reg.h           |  38 ++-
 6 files changed, 505 insertions(+), 13 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
 
 rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
-rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
+rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+					cdn-dp-link-training.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
 rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index cce64c1..783d57a 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 			goto out;
 		}
 	}
-
-	ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-	if (ret) {
-		DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-		goto out;
+	if (dp->use_fw_training) {
+		ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+		if (ret) {
+			DRM_DEV_ERROR(dp->dev,
+				      "Failed to idle video %d\n", ret);
+			goto out;
+		}
 	}
 
 	ret = cdn_dp_config_video(dp);
@@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 		goto out;
 	}
 
-	ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
-	if (ret) {
-		DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
-		goto out;
+	if (dp->use_fw_training) {
+		ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+		if (ret) {
+			DRM_DEV_ERROR(dp->dev,
+				"Failed to valid video %d\n", ret);
+			goto out;
+		}
 	}
+
 out:
 	mutex_unlock(&dp->lock);
 }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..77a9793 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
 	bool connected;
 	bool active;
 	bool suspended;
+	bool use_fw_training;
 
 	const struct firmware *fw;	/* cdn dp firmware */
 	unsigned int fw_version;	/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
 	u8 ports;
 	u8 lanes;
 	int active_port;
+	u8 train_set[4];
 
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
 	bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 0000000..73c3290
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ */
+
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/phy/phy.h>
+#include <soc/rockchip/rockchip_phy_typec.h>
+
+#include "cdn-dp-core.h"
+#include "cdn-dp-reg.h"
+
+static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp)
+{
+	struct cdn_dp_port *port = dp->port[dp->active_port];
+	struct rockchip_typec_phy *tcphy = phy_get_drvdata(port->phy);
+
+	int rate = drm_dp_bw_code_to_link_rate(dp->link.rate);
+	u8 swing = (dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) >>
+		   DP_TRAIN_VOLTAGE_SWING_SHIFT;
+	u8 pre_emphasis = (dp->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
+			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+	tcphy->typec_phy_config(port->phy, rate, dp->link.num_lanes,
+				swing, pre_emphasis);
+}
+
+static int cdn_dp_set_pattern(struct cdn_dp_device *dp, uint8_t dp_train_pat)
+{
+	u32 phy_config, global_config;
+	int ret;
+	uint8_t pattern = dp_train_pat & DP_TRAINING_PATTERN_MASK;
+
+	global_config = NUM_LANES(dp->link.num_lanes - 1) | SST_MODE |
+			GLOBAL_EN | RG_EN | ENC_RST_DIS | WR_VHSYNC_FALL;
+
+	phy_config = DP_TX_PHY_ENCODER_BYPASS(0) |
+		     DP_TX_PHY_SKEW_BYPASS(0) |
+		     DP_TX_PHY_DISPARITY_RST(0) |
+		     DP_TX_PHY_LANE0_SKEW(0) |
+		     DP_TX_PHY_LANE1_SKEW(1) |
+		     DP_TX_PHY_LANE2_SKEW(2) |
+		     DP_TX_PHY_LANE3_SKEW(3) |
+		     DP_TX_PHY_10BIT_ENABLE(0);
+
+	if (pattern != DP_TRAINING_PATTERN_DISABLE) {
+		global_config |= NO_VIDEO;
+		phy_config |= DP_TX_PHY_TRAINING_ENABLE(1) |
+			      DP_TX_PHY_SCRAMBLER_BYPASS(1) |
+			      DP_TX_PHY_TRAINING_PATTERN(pattern);
+	}
+
+	ret = cdn_dp_reg_write(dp, DP_FRAMER_GLOBAL_CONFIG, global_config);
+	if (ret) {
+		DRM_ERROR("fail to set DP_FRAMER_GLOBAL_CONFIG, error: %d\n",
+			  ret);
+		return ret;
+	}
+
+	ret = cdn_dp_reg_write(dp, DP_TX_PHY_CONFIG_REG, phy_config);
+	if (ret) {
+		DRM_ERROR("fail to set DP_TX_PHY_CONFIG_REG, error: %d\n",
+			  ret);
+		return ret;
+	}
+
+	ret = cdn_dp_reg_write(dp, DPTX_LANE_EN, BIT(dp->link.num_lanes) - 1);
+	if (ret) {
+		DRM_ERROR("fail to set DPTX_LANE_EN, error: %d\n", ret);
+		return ret;
+	}
+
+	if (drm_dp_enhanced_frame_cap(dp->dpcd))
+		ret = cdn_dp_reg_write(dp, DPTX_ENHNCD, 1);
+	else
+		ret = cdn_dp_reg_write(dp, DPTX_ENHNCD, 0);
+	if (ret)
+		DRM_ERROR("failed to set DPTX_ENHNCD, error: %x\n", ret);
+
+	return ret;
+}
+
+static u8 cdn_dp_pre_emphasis_max(u8 voltage_swing)
+{
+	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+		return DP_TRAIN_PRE_EMPH_LEVEL_3;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+		return DP_TRAIN_PRE_EMPH_LEVEL_2;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+		return DP_TRAIN_PRE_EMPH_LEVEL_1;
+	default:
+		return DP_TRAIN_PRE_EMPH_LEVEL_0;
+	}
+}
+
+static void cdn_dp_get_adjust_train(struct cdn_dp_device *dp,
+				    uint8_t link_status[DP_LINK_STATUS_SIZE])
+{
+	int i;
+	uint8_t v = 0, p = 0;
+	uint8_t preemph_max;
+
+	for (i = 0; i < dp->link.num_lanes; i++) {
+		v = max(v, drm_dp_get_adjust_request_voltage(link_status, i));
+		p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status,
+								  i));
+	}
+
+	if (v >= VOLTAGE_LEVEL_2)
+		v = VOLTAGE_LEVEL_2 | DP_TRAIN_MAX_SWING_REACHED;
+
+	preemph_max = cdn_dp_pre_emphasis_max(v);
+	if (p >= preemph_max)
+		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+	for (i = 0; i < dp->link.num_lanes; i++)
+		dp->train_set[i] = v | p;
+}
+
+/*
+ * Pick training pattern for channel equalization. Training Pattern 3 for HBR2
+ * or 1.2 devices that support it, Training Pattern 2 otherwise.
+ */
+static u32 cdn_dp_select_chaneq_pattern(struct cdn_dp_device *dp)
+{
+	u32 training_pattern = DP_TRAINING_PATTERN_2;
+
+	/*
+	 * cdn dp support HBR2 also support TPS3. TPS3 support is also mandatory
+	 * for downstream devices that support HBR2. However, not all sinks
+	 * follow the spec.
+	 */
+	if (drm_dp_tps3_supported(dp->dpcd))
+		training_pattern = DP_TRAINING_PATTERN_3;
+	else
+		DRM_DEBUG_KMS("5.4 Gbps link rate without sink TPS3 support\n");
+
+	return training_pattern;
+}
+
+
+static bool cdn_dp_link_max_vswing_reached(struct cdn_dp_device *dp)
+{
+	int lane;
+
+	for (lane = 0; lane < dp->link.num_lanes; lane++)
+		if ((dp->train_set[lane] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+			return false;
+
+	return true;
+}
+
+static int cdn_dp_update_link_train(struct cdn_dp_device *dp)
+{
+	int ret;
+
+	cdn_dp_set_signal_levels(dp);
+
+	ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
+				dp->train_set, dp->link.num_lanes);
+	if (ret != dp->link.num_lanes)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cdn_dp_set_link_train(struct cdn_dp_device *dp,
+				  uint8_t dp_train_pat)
+{
+	uint8_t buf[sizeof(dp->train_set) + 1];
+	int ret, len;
+
+	buf[0] = dp_train_pat;
+	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
+	    DP_TRAINING_PATTERN_DISABLE) {
+		/* don't write DP_TRAINING_LANEx_SET on disable */
+		len = 1;
+	} else {
+		/* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */
+		memcpy(buf + 1, dp->train_set, dp->link.num_lanes);
+		len = dp->link.num_lanes + 1;
+	}
+
+	ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_PATTERN_SET,
+				buf, len);
+	if (ret != len)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cdn_dp_reset_link_train(struct cdn_dp_device *dp,
+				    uint8_t dp_train_pat)
+{
+	int ret;
+
+	memset(dp->train_set, 0, sizeof(dp->train_set));
+
+	cdn_dp_set_signal_levels(dp);
+
+	ret = cdn_dp_set_pattern(dp, dp_train_pat);
+	if (ret)
+		return ret;
+
+	return cdn_dp_set_link_train(dp, dp_train_pat);
+}
+
+/* Enable corresponding port and start training pattern 1 */
+static int cdn_dp_link_training_clock_recovery(struct cdn_dp_device *dp)
+{
+	u8 voltage;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	u32 voltage_tries, max_vswing_tries;
+	int ret;
+
+	/* clock recovery */
+	ret = cdn_dp_reset_link_train(dp, DP_TRAINING_PATTERN_1 |
+					  DP_LINK_SCRAMBLING_DISABLE);
+	if (ret) {
+		DRM_ERROR("failed to start link train\n");
+		return ret;
+	}
+
+	voltage_tries = 1;
+	max_vswing_tries = 0;
+	for (;;) {
+		drm_dp_link_train_clock_recovery_delay(dp->dpcd);
+		if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) !=
+		    DP_LINK_STATUS_SIZE) {
+			DRM_ERROR("failed to get link status\n");
+			return -EINVAL;
+		}
+
+		if (drm_dp_clock_recovery_ok(link_status, dp->link.num_lanes)) {
+			DRM_DEBUG_KMS("clock recovery OK\n");
+			return 0;
+		}
+
+		if (voltage_tries >= 5) {
+			DRM_DEBUG_KMS("Same voltage tried 5 times\n");
+			return -EINVAL;
+		}
+
+		if (max_vswing_tries >= 1) {
+			DRM_DEBUG_KMS("Max Voltage Swing reached\n");
+			return -EINVAL;
+		}
+
+		voltage = dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+		/* Update training set as requested by target */
+		cdn_dp_get_adjust_train(dp, link_status);
+		if (cdn_dp_update_link_train(dp)) {
+			DRM_ERROR("failed to update link training\n");
+			return -EINVAL;
+		}
+
+		if ((dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) ==
+		    voltage)
+			++voltage_tries;
+		else
+			voltage_tries = 1;
+
+		if (cdn_dp_link_max_vswing_reached(dp))
+			++max_vswing_tries;
+	}
+}
+
+static int cdn_dp_link_training_channel_equalization(struct cdn_dp_device *dp)
+{
+	int tries, ret;
+	u32 training_pattern;
+	uint8_t link_status[DP_LINK_STATUS_SIZE];
+
+	training_pattern = cdn_dp_select_chaneq_pattern(dp);
+	training_pattern |= DP_LINK_SCRAMBLING_DISABLE;
+
+	ret = cdn_dp_set_pattern(dp, training_pattern);
+	if (ret)
+		return ret;
+
+	ret = cdn_dp_set_link_train(dp, training_pattern);
+	if (ret) {
+		DRM_ERROR("failed to start channel equalization\n");
+		return ret;
+	}
+
+	for (tries = 0; tries < 5; tries++) {
+		drm_dp_link_train_channel_eq_delay(dp->dpcd);
+		if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) !=
+		    DP_LINK_STATUS_SIZE) {
+			DRM_ERROR("failed to get link status\n");
+			break;
+		}
+
+		/* Make sure clock is still ok */
+		if (!drm_dp_clock_recovery_ok(link_status,
+					      dp->link.num_lanes)) {
+			DRM_DEBUG_KMS("Clock recovery check failed\n");
+			break;
+		}
+
+		if (drm_dp_channel_eq_ok(link_status,  dp->link.num_lanes)) {
+			DRM_DEBUG_KMS("Channel EQ done\n");
+			return 0;
+		}
+
+		/* Update training set as requested by target */
+		cdn_dp_get_adjust_train(dp, link_status);
+		if (cdn_dp_update_link_train(dp)) {
+			DRM_ERROR("failed to update link training\n");
+			break;
+		}
+	}
+
+	/* Try 5 times, else fail and try at lower BW */
+	if (tries == 5)
+		DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
+
+	return -EINVAL;
+}
+
+static int cdn_dp_stop_link_train(struct cdn_dp_device *dp)
+{
+	int ret = cdn_dp_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE);
+
+	if (ret)
+		return ret;
+
+	return cdn_dp_set_link_train(dp, DP_TRAINING_PATTERN_DISABLE);
+}
+
+static int cdn_dp_get_lower_link_rate(struct cdn_dp_device *dp)
+{
+	switch (dp->link.rate) {
+	case DP_LINK_BW_1_62:
+		return -EINVAL;
+	case DP_LINK_BW_2_7:
+		dp->link.rate = DP_LINK_BW_1_62;
+		break;
+	case DP_LINK_BW_5_4:
+		dp->link.rate = DP_LINK_BW_2_7;
+		break;
+	default:
+		dp->link.rate = DP_LINK_BW_5_4;
+		break;
+	}
+
+	return 0;
+}
+
+int cdn_dp_software_train_link(struct cdn_dp_device *dp)
+{
+	int ret, stop_err;
+	u8 link_config[2];
+	u32 rate, sink_max, source_max;
+
+	ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd,
+			       sizeof(dp->dpcd));
+	if (ret < 0) {
+		DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
+		return ret;
+	}
+
+	source_max = dp->lanes;
+	sink_max = drm_dp_max_lane_count(dp->dpcd);
+	dp->link.num_lanes = min(source_max, sink_max);
+
+	source_max = drm_dp_bw_code_to_link_rate(CDN_DP_MAX_LINK_RATE);
+	sink_max = drm_dp_max_link_rate(dp->dpcd);
+	rate = min(source_max, sink_max);
+	dp->link.rate = drm_dp_link_rate_to_bw_code(rate);
+
+	link_config[0] = 0;
+	link_config[1] = 0;
+	if (dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & 0x01)
+		link_config[1] = DP_SET_ANSI_8B10B;
+	drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
+
+	while (true) {
+
+		/* Write the link configuration data */
+		link_config[0] = dp->link.rate;
+		link_config[1] = dp->link.num_lanes;
+		if (drm_dp_enhanced_frame_cap(dp->dpcd))
+			link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+		drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, link_config, 2);
+
+		ret = cdn_dp_link_training_clock_recovery(dp);
+		if (ret) {
+			if (!cdn_dp_get_lower_link_rate(dp))
+				continue;
+
+			DRM_ERROR("training clock recovery failed: %d\n", ret);
+			break;
+		}
+
+		ret = cdn_dp_link_training_channel_equalization(dp);
+		if (ret) {
+			if (!cdn_dp_get_lower_link_rate(dp))
+				continue;
+
+			DRM_ERROR("training channel eq failed: %d\n", ret);
+			break;
+		}
+
+		break;
+	}
+
+	stop_err = cdn_dp_stop_link_train(dp);
+	if (stop_err) {
+		DRM_ERROR("stop training fail, error: %d\n", stop_err);
+		return stop_err;
+	}
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
index 979355d..e1273e6 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -17,7 +17,9 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/phy/phy.h>
 #include <linux/reset.h>
+#include <soc/rockchip/rockchip_phy_typec.h>
 
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
@@ -189,7 +191,7 @@ static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
 	return 0;
 }
 
-static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
+int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
 {
 	u8 msg[6];
 
@@ -609,6 +611,31 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
 {
 	int ret;
 
+	/*
+	 * DP firmware uses fixed phy config values to do training, but some
+	 * boards need to adjust these values to fit for their unique hardware
+	 * design. So if the phy is using custom config values, do software
+	 * link training instead of relying on firmware, if software training
+	 * fail, keep firmware training as a fallback if sw training fails.
+	 */
+	ret = cdn_dp_software_train_link(dp);
+	if (ret) {
+		DRM_DEV_ERROR(dp->dev,
+			"Failed to do software training %d\n", ret);
+		goto do_fw_training;
+	}
+	ret = cdn_dp_reg_write(dp, SOURCE_HDTX_CAR, 0xf);
+	if (ret) {
+		DRM_DEV_ERROR(dp->dev,
+		"Failed to write SOURCE_HDTX_CAR register %d\n", ret);
+		goto do_fw_training;
+	}
+	dp->use_fw_training = false;
+	return 0;
+
+do_fw_training:
+	dp->use_fw_training = true;
+	DRM_DEV_DEBUG_KMS(dp->dev, "use fw training\n");
 	ret = cdn_dp_training_start(dp);
 	if (ret) {
 		DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
@@ -623,7 +650,7 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
 
 	DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
 			  dp->link.num_lanes);
-	return ret;
+	return 0;
 }
 
 int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
index 6580b11..3420771 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
@@ -137,7 +137,7 @@
 #define HPD_EVENT_MASK			0x211c
 #define HPD_EVENT_DET			0x2120
 
-/* dpyx framer addr */
+/* dptx framer addr */
 #define DP_FRAMER_GLOBAL_CONFIG		0x2200
 #define DP_SW_RESET			0x2204
 #define DP_FRAMER_TU			0x2208
@@ -431,6 +431,40 @@
 /* Reference cycles when using lane clock as reference */
 #define LANE_REF_CYC				0x8000
 
+/* register CM_VID_CTRL */
+#define LANE_VID_REF_CYC(x)                    (((x) & (BIT(24) - 1)) << 0)
+#define NMVID_MEAS_TOLERANCE(x)                        (((x) & 0xf) << 24)
+
+/* register DP_TX_PHY_CONFIG_REG */
+#define DP_TX_PHY_TRAINING_ENABLE(x)           ((x) & 1)
+#define DP_TX_PHY_TRAINING_TYPE_PRBS7          (0 << 1)
+#define DP_TX_PHY_TRAINING_TYPE_TPS1           (1 << 1)
+#define DP_TX_PHY_TRAINING_TYPE_TPS2           (2 << 1)
+#define DP_TX_PHY_TRAINING_TYPE_TPS3           (3 << 1)
+#define DP_TX_PHY_TRAINING_TYPE_TPS4           (4 << 1)
+#define DP_TX_PHY_TRAINING_TYPE_PLTPAT         (5 << 1)
+#define DP_TX_PHY_TRAINING_TYPE_D10_2          (6 << 1)
+#define DP_TX_PHY_TRAINING_TYPE_HBR2CPAT       (8 << 1)
+#define DP_TX_PHY_TRAINING_PATTERN(x)          ((x) << 1)
+#define DP_TX_PHY_SCRAMBLER_BYPASS(x)          (((x) & 1) << 5)
+#define DP_TX_PHY_ENCODER_BYPASS(x)            (((x) & 1) << 6)
+#define DP_TX_PHY_SKEW_BYPASS(x)               (((x) & 1) << 7)
+#define DP_TX_PHY_DISPARITY_RST(x)             (((x) & 1) << 8)
+#define DP_TX_PHY_LANE0_SKEW(x)                (((x) & 7) << 9)
+#define DP_TX_PHY_LANE1_SKEW(x)                (((x) & 7) << 12)
+#define DP_TX_PHY_LANE2_SKEW(x)                (((x) & 7) << 15)
+#define DP_TX_PHY_LANE3_SKEW(x)                (((x) & 7) << 18)
+#define DP_TX_PHY_10BIT_ENABLE(x)              (((x) & 1) << 21)
+
+/* register DP_FRAMER_GLOBAL_CONFIG */
+#define NUM_LANES(x)           ((x) & 3)
+#define SST_MODE               (0 << 2)
+#define RG_EN                  (0 << 4)
+#define GLOBAL_EN              BIT(3)
+#define NO_VIDEO               BIT(5)
+#define ENC_RST_DIS            BIT(6)
+#define WR_VHSYNC_FALL         BIT(7)
+
 enum voltage_swing_level {
 	VOLTAGE_LEVEL_0,
 	VOLTAGE_LEVEL_1,
@@ -476,6 +510,7 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip);
 int cdn_dp_event_config(struct cdn_dp_device *dp);
 u32 cdn_dp_get_event(struct cdn_dp_device *dp);
 int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
+int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val);
 ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
 			  u8 *data, u16 len);
 ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
@@ -489,4 +524,5 @@ int cdn_dp_config_video(struct cdn_dp_device *dp);
 int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
 int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
 int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
+int cdn_dp_software_train_link(struct cdn_dp_device *dp);
 #endif /* _CDN_DP_REG_H */
-- 
2.7.4

^ permalink raw reply related

* [PATCH v7 4/5] phy: rockchip-typec: support variable phy config value
From: Lin Huang @ 2018-05-23  7:42 UTC (permalink / raw)
  To: seanpaul, airlied, zyw, kishon
  Cc: dianders, briannorris, linux-rockchip, heiko, daniel.vetter,
	dri-devel, linux-arm-kernel, linux-kernel, eballetbo, robh+dt,
	devicetree, Lin Huang
In-Reply-To: <1527061353-16902-1-git-send-email-hl@rock-chips.com>

the phy config values used to fix in dp firmware, but some boards
need change these values to do training and get the better eye diagram
result. So support that in phy driver.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- delete need_software_training variable
- add default phy config value, if dts do not define phy config value, use these value
Changes in v4:
- rename variable config to tcphy_default_config
Changes in v5:
- None
Changes in v6:
- split the header file to new patch
Changes in v7:
- add default case when check link rate
- move struct rockchip_typec_phy new element to this patch

 drivers/phy/rockchip/phy-rockchip-typec.c | 263 ++++++++++++++++++++++++------
 include/soc/rockchip/rockchip_phy_typec.h |   8 +
 2 files changed, 218 insertions(+), 53 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 795055f..69af90e 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -324,21 +324,29 @@
  * clock 0: PLL 0 div 1
  * clock 1: PLL 1 div 2
  */
-#define CLK_PLL_CONFIG			0X30
+#define CLK_PLL1_DIV1			0x20
+#define CLK_PLL1_DIV2			0x30
 #define CLK_PLL_MASK			0x33
 
 #define CMN_READY			BIT(0)
 
+#define DP_PLL_CLOCK_ENABLE_ACK		BIT(3)
 #define DP_PLL_CLOCK_ENABLE		BIT(2)
+#define DP_PLL_ENABLE_ACK		BIT(1)
 #define DP_PLL_ENABLE			BIT(0)
 #define DP_PLL_DATA_RATE_RBR		((2 << 12) | (4 << 8))
 #define DP_PLL_DATA_RATE_HBR		((2 << 12) | (4 << 8))
 #define DP_PLL_DATA_RATE_HBR2		((1 << 12) | (2 << 8))
+#define DP_PLL_DATA_RATE_MASK		0xff00
 
-#define DP_MODE_A0			BIT(4)
-#define DP_MODE_A2			BIT(6)
-#define DP_MODE_ENTER_A0		0xc101
-#define DP_MODE_ENTER_A2		0xc104
+#define DP_MODE_MASK			0xf
+#define DP_MODE_ENTER_A0		BIT(0)
+#define DP_MODE_ENTER_A2		BIT(2)
+#define DP_MODE_ENTER_A3		BIT(3)
+#define DP_MODE_A0_ACK			BIT(4)
+#define DP_MODE_A2_ACK			BIT(6)
+#define DP_MODE_A3_ACK			BIT(7)
+#define DP_LINK_RESET_DEASSERTED	BIT(8)
 
 #define PHY_MODE_SET_TIMEOUT		100000
 
@@ -350,6 +358,8 @@
 #define MODE_DFP_USB			BIT(1)
 #define MODE_DFP_DP			BIT(2)
 
+#define DP_DEFAULT_RATE		162000
+
 struct phy_reg {
 	u16 value;
 	u32 addr;
@@ -372,15 +382,15 @@ struct phy_reg usb3_pll_cfg[] = {
 	{ 0x8,		CMN_DIAG_PLL0_LF_PROG },
 };
 
-struct phy_reg dp_pll_cfg[] = {
+struct phy_reg dp_pll_rbr_cfg[] = {
 	{ 0xf0,		CMN_PLL1_VCOCAL_INIT },
 	{ 0x18,		CMN_PLL1_VCOCAL_ITER },
 	{ 0x30b9,	CMN_PLL1_VCOCAL_START },
-	{ 0x21c,	CMN_PLL1_INTDIV },
+	{ 0x87,		CMN_PLL1_INTDIV },
 	{ 0,		CMN_PLL1_FRACDIV },
-	{ 0x5,		CMN_PLL1_HIGH_THR },
-	{ 0x35,		CMN_PLL1_SS_CTRL1 },
-	{ 0x7f1e,	CMN_PLL1_SS_CTRL2 },
+	{ 0x22,		CMN_PLL1_HIGH_THR },
+	{ 0x8000,	CMN_PLL1_SS_CTRL1 },
+	{ 0,		CMN_PLL1_SS_CTRL2 },
 	{ 0x20,		CMN_PLL1_DSM_DIAG },
 	{ 0,		CMN_PLLSM1_USER_DEF_CTRL },
 	{ 0,		CMN_DIAG_PLL1_OVRD },
@@ -391,9 +401,52 @@ struct phy_reg dp_pll_cfg[] = {
 	{ 0x8,		CMN_DIAG_PLL1_LF_PROG },
 	{ 0x100,	CMN_DIAG_PLL1_PTATIS_TUNE1 },
 	{ 0x7,		CMN_DIAG_PLL1_PTATIS_TUNE2 },
-	{ 0x4,		CMN_DIAG_PLL1_INCLK_CTRL },
+	{ 0x1,		CMN_DIAG_PLL1_INCLK_CTRL },
 };
 
+struct phy_reg dp_pll_hbr_cfg[] = {
+	{ 0xf0,		CMN_PLL1_VCOCAL_INIT },
+	{ 0x18,		CMN_PLL1_VCOCAL_ITER },
+	{ 0x30b4,	CMN_PLL1_VCOCAL_START },
+	{ 0xe1,		CMN_PLL1_INTDIV },
+	{ 0,		CMN_PLL1_FRACDIV },
+	{ 0x5,		CMN_PLL1_HIGH_THR },
+	{ 0x8000,	CMN_PLL1_SS_CTRL1 },
+	{ 0,		CMN_PLL1_SS_CTRL2 },
+	{ 0x20,		CMN_PLL1_DSM_DIAG },
+	{ 0x1000,	CMN_PLLSM1_USER_DEF_CTRL },
+	{ 0,		CMN_DIAG_PLL1_OVRD },
+	{ 0,		CMN_DIAG_PLL1_FBH_OVRD },
+	{ 0,		CMN_DIAG_PLL1_FBL_OVRD },
+	{ 0x7,		CMN_DIAG_PLL1_V2I_TUNE },
+	{ 0x45,		CMN_DIAG_PLL1_CP_TUNE },
+	{ 0x8,		CMN_DIAG_PLL1_LF_PROG },
+	{ 0x1,		CMN_DIAG_PLL1_PTATIS_TUNE1 },
+	{ 0x1,		CMN_DIAG_PLL1_PTATIS_TUNE2 },
+	{ 0x1,		CMN_DIAG_PLL1_INCLK_CTRL },
+};
+
+struct phy_reg dp_pll_hbr2_cfg[] = {
+	{ 0xf0,		CMN_PLL1_VCOCAL_INIT },
+	{ 0x18,		CMN_PLL1_VCOCAL_ITER },
+	{ 0x30b4,	CMN_PLL1_VCOCAL_START },
+	{ 0xe1,		CMN_PLL1_INTDIV },
+	{ 0,		CMN_PLL1_FRACDIV },
+	{ 0x5,		CMN_PLL1_HIGH_THR },
+	{ 0x8000,	CMN_PLL1_SS_CTRL1 },
+	{ 0,		CMN_PLL1_SS_CTRL2 },
+	{ 0x20,		CMN_PLL1_DSM_DIAG },
+	{ 0x1000,	CMN_PLLSM1_USER_DEF_CTRL },
+	{ 0,		CMN_DIAG_PLL1_OVRD },
+	{ 0,		CMN_DIAG_PLL1_FBH_OVRD },
+	{ 0,		CMN_DIAG_PLL1_FBL_OVRD },
+	{ 0x7,		CMN_DIAG_PLL1_V2I_TUNE },
+	{ 0x45,		CMN_DIAG_PLL1_CP_TUNE },
+	{ 0x8,		CMN_DIAG_PLL1_LF_PROG },
+	{ 0x1,		CMN_DIAG_PLL1_PTATIS_TUNE1 },
+	{ 0x1,		CMN_DIAG_PLL1_PTATIS_TUNE2 },
+	{ 0x1,		CMN_DIAG_PLL1_INCLK_CTRL },
+};
 static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
 	{
 		.reg = 0xff7c0000,
@@ -418,6 +471,24 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+/* default phy config */
+static const struct phy_config tcphy_default_config[3][4] = {
+	{{ .swing = 0x2a, .pe = 0x00 },
+	 { .swing = 0x1f, .pe = 0x15 },
+	 { .swing = 0x14, .pe = 0x22 },
+	 { .swing = 0x02, .pe = 0x2b } },
+
+	{{ .swing = 0x21, .pe = 0x00 },
+	 { .swing = 0x12, .pe = 0x15 },
+	 { .swing = 0x02, .pe = 0x22 },
+	 { .swing = 0,    .pe = 0 } },
+
+	{{ .swing = 0x15, .pe = 0x00 },
+	 { .swing = 0x00, .pe = 0x15 },
+	 { .swing = 0,    .pe = 0 },
+	 { .swing = 0,    .pe = 0 } },
+};
+
 static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
 {
 	u32 i, rdata;
@@ -439,7 +510,7 @@ static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
 
 	rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
 	rdata &= ~CLK_PLL_MASK;
-	rdata |= CLK_PLL_CONFIG;
+	rdata |= CLK_PLL1_DIV2;
 	writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL);
 }
 
@@ -453,17 +524,45 @@ static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy)
 		       tcphy->base + usb3_pll_cfg[i].addr);
 }
 
-static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy)
+static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy, int link_rate)
 {
-	u32 i;
+	struct phy_reg *phy_cfg;
+	u32 clk_ctrl;
+	u32 i, cfg_size, hsclk_sel;
+
+	hsclk_sel = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
+	hsclk_sel &= ~CLK_PLL_MASK;
+
+	switch (link_rate) {
+	case 540000:
+		clk_ctrl = DP_PLL_DATA_RATE_HBR2;
+		hsclk_sel |= CLK_PLL1_DIV1;
+		phy_cfg = dp_pll_hbr2_cfg;
+		cfg_size = ARRAY_SIZE(dp_pll_hbr2_cfg);
+		break;
+	case 270000:
+		clk_ctrl = DP_PLL_DATA_RATE_HBR;
+		hsclk_sel |= CLK_PLL1_DIV2;
+		phy_cfg = dp_pll_hbr_cfg;
+		cfg_size = ARRAY_SIZE(dp_pll_hbr_cfg);
+		break;
+	case 162000:
+	default:
+		clk_ctrl = DP_PLL_DATA_RATE_RBR;
+		hsclk_sel |= CLK_PLL1_DIV2;
+		phy_cfg = dp_pll_rbr_cfg;
+		cfg_size = ARRAY_SIZE(dp_pll_rbr_cfg);
+		break;
+	}
 
-	/* set the default mode to RBR */
-	writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR,
-	       tcphy->base + DP_CLK_CTL);
+	clk_ctrl |= DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE;
+	writel(clk_ctrl, tcphy->base + DP_CLK_CTL);
+
+	writel(hsclk_sel, tcphy->base + CMN_DIAG_HSCLK_SEL);
 
 	/* load the configuration of PLL1 */
-	for (i = 0; i < ARRAY_SIZE(dp_pll_cfg); i++)
-		writel(dp_pll_cfg[i].value, tcphy->base + dp_pll_cfg[i].addr);
+	for (i = 0; i < cfg_size; i++)
+		writel(phy_cfg[i].value, tcphy->base + phy_cfg[i].addr);
 }
 
 static void tcphy_tx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
@@ -490,9 +589,10 @@ static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
 	writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane));
 }
 
-static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
+static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, int link_rate,
+			      u8 swing, u8 pre_emp, u32 lane)
 {
-	u16 rdata;
+	u16 val;
 
 	writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane));
 	writel(0x6799, tcphy->base + TX_PSC_A0(lane));
@@ -500,25 +600,32 @@ static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
 	writel(0x98, tcphy->base + TX_PSC_A2(lane));
 	writel(0x98, tcphy->base + TX_PSC_A3(lane));
 
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_001(lane));
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_010(lane));
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_011(lane));
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_100(lane));
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_101(lane));
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_110(lane));
-	writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_111(lane));
-	writel(0, tcphy->base + TX_TXCC_CPOST_MULT_10(lane));
-	writel(0, tcphy->base + TX_TXCC_CPOST_MULT_01(lane));
-	writel(0, tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
-	writel(0, tcphy->base + TX_TXCC_CPOST_MULT_11(lane));
-
-	writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
-	writel(0x400, tcphy->base + TX_DIAG_TX_DRV(lane));
-
-	rdata = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
-	rdata = (rdata & 0x8fff) | 0x6000;
-	writel(rdata, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
+	writel(tcphy->config[swing][pre_emp].swing,
+	       tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
+	writel(tcphy->config[swing][pre_emp].pe,
+	       tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
+
+	if (swing == 2 && pre_emp == 0 && link_rate != 540000) {
+		writel(0x700, tcphy->base + TX_DIAG_TX_DRV(lane));
+		writel(0x13c, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
+	} else {
+		writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
+		writel(0x0400, tcphy->base + TX_DIAG_TX_DRV(lane));
+	}
+
+	val = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
+	val = val & 0x8fff;
+	switch (link_rate) {
+	case 540000:
+		val |= (4 << 12);
+		break;
+	case 162000:
+	case 270000:
+	default:
+		val |= (6 << 12);
+		break;
+	}
+	writel(val, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
 }
 
 static inline int property_enable(struct rockchip_typec_phy *tcphy,
@@ -709,30 +816,33 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
 	tcphy_cfg_24m(tcphy);
 
 	if (mode == MODE_DFP_DP) {
-		tcphy_cfg_dp_pll(tcphy);
+		tcphy_cfg_dp_pll(tcphy, DP_DEFAULT_RATE);
 		for (i = 0; i < 4; i++)
-			tcphy_dp_cfg_lane(tcphy, i);
+			tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, i);
 
 		writel(PIN_ASSIGN_C_E, tcphy->base + PMA_LANE_CFG);
 	} else {
 		tcphy_cfg_usb3_pll(tcphy);
-		tcphy_cfg_dp_pll(tcphy);
+		tcphy_cfg_dp_pll(tcphy, DP_DEFAULT_RATE);
 		if (tcphy->flip) {
 			tcphy_tx_usb3_cfg_lane(tcphy, 3);
 			tcphy_rx_usb3_cfg_lane(tcphy, 2);
-			tcphy_dp_cfg_lane(tcphy, 0);
-			tcphy_dp_cfg_lane(tcphy, 1);
+			tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 0);
+			tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 1);
 		} else {
 			tcphy_tx_usb3_cfg_lane(tcphy, 0);
 			tcphy_rx_usb3_cfg_lane(tcphy, 1);
-			tcphy_dp_cfg_lane(tcphy, 2);
-			tcphy_dp_cfg_lane(tcphy, 3);
+			tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 2);
+			tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 3);
 		}
 
 		writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
 	}
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	val = readl(tcphy->base + DP_MODE_CTL);
+	val &= ~DP_MODE_MASK;
+	val |= DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED;
+	writel(val, tcphy->base + DP_MODE_CTL);
 
 	reset_control_deassert(tcphy->uphy_rst);
 
@@ -945,7 +1055,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 	property_enable(tcphy, &cfg->uphy_dp_sel, 1);
 
 	ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
-				 val, val & DP_MODE_A2, 1000,
+				 val, val & DP_MODE_A2_ACK, 1000,
 				 PHY_MODE_SET_TIMEOUT);
 	if (ret < 0) {
 		dev_err(tcphy->dev, "failed to wait TCPHY enter A2\n");
@@ -954,13 +1064,19 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 
 	tcphy_dp_aux_calibration(tcphy);
 
-	writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
+	/* enter A0 mode */
+	val = readl(tcphy->base + DP_MODE_CTL);
+	val &= ~DP_MODE_MASK;
+	val |= DP_MODE_ENTER_A0;
+	writel(val, tcphy->base + DP_MODE_CTL);
 
 	ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
-				 val, val & DP_MODE_A0, 1000,
+				 val, val & DP_MODE_A0_ACK, 1000,
 				 PHY_MODE_SET_TIMEOUT);
 	if (ret < 0) {
-		writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+		val &= ~DP_MODE_MASK;
+		val |= DP_MODE_ENTER_A2;
+		writel(val, tcphy->base + DP_MODE_CTL);
 		dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
 		goto power_on_finish;
 	}
@@ -978,6 +1094,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 static int rockchip_dp_phy_power_off(struct phy *phy)
 {
 	struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
+	u32 val;
 
 	mutex_lock(&tcphy->lock);
 
@@ -986,7 +1103,10 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
 
 	tcphy->mode &= ~MODE_DFP_DP;
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	val = readl(tcphy->base + DP_MODE_CTL);
+	val &= ~DP_MODE_MASK;
+	val |= DP_MODE_ENTER_A2;
+	writel(val, tcphy->base + DP_MODE_CTL);
 
 	if (tcphy->mode == MODE_DISCONNECT)
 		tcphy_phy_deinit(tcphy);
@@ -1002,9 +1122,35 @@ static const struct phy_ops rockchip_dp_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static int typec_dp_phy_config(struct phy *phy, int link_rate,
+			 int lanes, u8 swing, u8 pre_emp)
+{
+	struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
+	u8 i;
+
+	tcphy_cfg_dp_pll(tcphy, link_rate);
+
+	if (tcphy->mode == MODE_DFP_DP) {
+		for (i = 0; i < 4; i++)
+			tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, i);
+	} else {
+		if (tcphy->flip) {
+			tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 0);
+			tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 1);
+		} else {
+			tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 2);
+			tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 3);
+		}
+	}
+
+	return 0;
+}
+
 static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
 			  struct device *dev)
 {
+	int ret;
+
 	tcphy->grf_regs = syscon_regmap_lookup_by_phandle(dev->of_node,
 							  "rockchip,grf");
 	if (IS_ERR(tcphy->grf_regs)) {
@@ -1042,6 +1188,16 @@ static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
 		return PTR_ERR(tcphy->tcphy_rst);
 	}
 
+	/*
+	 * check if phy_config pass from dts, if no,
+	 * use default phy config value.
+	 */
+	ret = of_property_read_u32_array(dev->of_node, "rockchip,phy-config",
+		(u32 *)tcphy->config, sizeof(tcphy->config) / sizeof(u32));
+	if (ret)
+		memcpy(tcphy->config, tcphy_default_config,
+		       sizeof(tcphy->config));
+
 	return 0;
 }
 
@@ -1126,6 +1282,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		}
 	}
 
+	tcphy->typec_phy_config = typec_dp_phy_config;
 	pm_runtime_enable(dev);
 
 	for_each_available_child_of_node(np, child_np) {
diff --git a/include/soc/rockchip/rockchip_phy_typec.h b/include/soc/rockchip/rockchip_phy_typec.h
index 4afe039..8e45c4d 100644
--- a/include/soc/rockchip/rockchip_phy_typec.h
+++ b/include/soc/rockchip/rockchip_phy_typec.h
@@ -35,6 +35,11 @@ struct rockchip_usb3phy_port_cfg {
 	struct usb3phy_reg uphy_dp_sel;
 };
 
+struct phy_config {
+	int swing;
+	int pe;
+};
+
 struct rockchip_typec_phy {
 	struct device *dev;
 	void __iomem *base;
@@ -50,6 +55,9 @@ struct rockchip_typec_phy {
 	struct mutex lock;
 	bool flip;
 	u8 mode;
+	struct phy_config config[3][4];
+	int (*typec_phy_config)(struct phy *phy, int link_rate,
+				int lanes, u8 swing, u8 pre_emp);
 };
 
 #endif
-- 
2.7.4

^ permalink raw reply related

* [PATCH v7 3/5] soc: rockchip: split rockchip_typec_phy struct to separate header
From: Lin Huang @ 2018-05-23  7:42 UTC (permalink / raw)
  To: seanpaul, airlied, zyw, kishon
  Cc: dianders, briannorris, linux-rockchip, heiko, daniel.vetter,
	dri-devel, linux-arm-kernel, linux-kernel, eballetbo, robh+dt,
	devicetree, Lin Huang
In-Reply-To: <1527061353-16902-1-git-send-email-hl@rock-chips.com>

we may use rockchip_phy_typec struct in other driver, so split
it to separate header.

Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v2:
- None
Changes in v3:
- None
Changes in v4:
- None
Changes in v5:
- None
Changes in v6:
- new patch here
Changes in v7:
- move new element to next patch

 drivers/phy/rockchip/phy-rockchip-typec.c | 47 +-------------------------
 include/soc/rockchip/rockchip_phy_typec.h | 55 +++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 46 deletions(-)
 create mode 100644 include/soc/rockchip/rockchip_phy_typec.h

diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 76a4b58..795055f 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -63,6 +63,7 @@
 
 #include <linux/mfd/syscon.h>
 #include <linux/phy/phy.h>
+#include <soc/rockchip/rockchip_phy_typec.h>
 
 #define CMN_SSM_BANDGAP			(0x21 << 2)
 #define CMN_SSM_BIAS			(0x22 << 2)
@@ -349,52 +350,6 @@
 #define MODE_DFP_USB			BIT(1)
 #define MODE_DFP_DP			BIT(2)
 
-struct usb3phy_reg {
-	u32 offset;
-	u32 enable_bit;
-	u32 write_enable;
-};
-
-/**
- * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
- * @reg: the base address for usb3-phy config.
- * @typec_conn_dir: the register of type-c connector direction.
- * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
- * @external_psm: the register of type-c phy external psm clock.
- * @pipe_status: the register of type-c phy pipe status.
- * @usb3_host_disable: the register of type-c usb3 host disable.
- * @usb3_host_port: the register of type-c usb3 host port.
- * @uphy_dp_sel: the register of type-c phy DP select control.
- */
-struct rockchip_usb3phy_port_cfg {
-	unsigned int reg;
-	struct usb3phy_reg typec_conn_dir;
-	struct usb3phy_reg usb3tousb2_en;
-	struct usb3phy_reg external_psm;
-	struct usb3phy_reg pipe_status;
-	struct usb3phy_reg usb3_host_disable;
-	struct usb3phy_reg usb3_host_port;
-	struct usb3phy_reg uphy_dp_sel;
-};
-
-struct rockchip_typec_phy {
-	struct device *dev;
-	void __iomem *base;
-	struct extcon_dev *extcon;
-	struct regmap *grf_regs;
-	struct clk *clk_core;
-	struct clk *clk_ref;
-	struct reset_control *uphy_rst;
-	struct reset_control *pipe_rst;
-	struct reset_control *tcphy_rst;
-	const struct rockchip_usb3phy_port_cfg *port_cfgs;
-	/* mutex to protect access to individual PHYs */
-	struct mutex lock;
-
-	bool flip;
-	u8 mode;
-};
-
 struct phy_reg {
 	u16 value;
 	u32 addr;
diff --git a/include/soc/rockchip/rockchip_phy_typec.h b/include/soc/rockchip/rockchip_phy_typec.h
new file mode 100644
index 0000000..4afe039
--- /dev/null
+++ b/include/soc/rockchip/rockchip_phy_typec.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Lin Huang <hl@rock-chips.com>
+ */
+
+#ifndef __SOC_ROCKCHIP_PHY_TYPEC_H
+#define __SOC_ROCKCHIP_PHY_TYPEC_H
+
+struct usb3phy_reg {
+	u32 offset;
+	u32 enable_bit;
+	u32 write_enable;
+};
+
+/**
+ * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
+ * @reg: the base address for usb3-phy config.
+ * @typec_conn_dir: the register of type-c connector direction.
+ * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
+ * @external_psm: the register of type-c phy external psm clock.
+ * @pipe_status: the register of type-c phy pipe status.
+ * @usb3_host_disable: the register of type-c usb3 host disable.
+ * @usb3_host_port: the register of type-c usb3 host port.
+ * @uphy_dp_sel: the register of type-c phy DP select control.
+ */
+struct rockchip_usb3phy_port_cfg {
+	unsigned int reg;
+	struct usb3phy_reg typec_conn_dir;
+	struct usb3phy_reg usb3tousb2_en;
+	struct usb3phy_reg external_psm;
+	struct usb3phy_reg pipe_status;
+	struct usb3phy_reg usb3_host_disable;
+	struct usb3phy_reg usb3_host_port;
+	struct usb3phy_reg uphy_dp_sel;
+};
+
+struct rockchip_typec_phy {
+	struct device *dev;
+	void __iomem *base;
+	struct extcon_dev *extcon;
+	struct regmap *grf_regs;
+	struct clk *clk_core;
+	struct clk *clk_ref;
+	struct reset_control *uphy_rst;
+	struct reset_control *pipe_rst;
+	struct reset_control *tcphy_rst;
+	const struct rockchip_usb3phy_port_cfg *port_cfgs;
+	/* mutex to protect access to individual PHYs */
+	struct mutex lock;
+	bool flip;
+	u8 mode;
+};
+
+#endif
-- 
2.7.4

^ permalink raw reply related

* [PATCH v7 2/5] Documentation: dt-bindings: phy: add phy_config for Rockchip USB Type-C PHY
From: Lin Huang @ 2018-05-23  7:42 UTC (permalink / raw)
  To: seanpaul, airlied, zyw, kishon
  Cc: dianders, briannorris, linux-rockchip, heiko, daniel.vetter,
	dri-devel, linux-arm-kernel, linux-kernel, eballetbo, robh+dt,
	devicetree, Lin Huang
In-Reply-To: <1527061353-16902-1-git-send-email-hl@rock-chips.com>

If want to do training outside DP Firmware, need phy voltage swing
and pre_emphasis value.

Signed-off-by: Lin Huang <hl@rock-chips.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changes in v2:
- None 
Changes in v3:
- modify property description and add this property to Example
Changes in v4:
- None
Changes in v5:
- None
Changes in v6:
- change rockchip,phy_config to rockchip,phy-config and descript it in detail.
Changes in v7:
- None

 .../devicetree/bindings/phy/phy-rockchip-typec.txt | 36 +++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
index 960da7f..40d5e7a 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
@@ -17,7 +17,11 @@ Required properties:
 
 Optional properties:
  - extcon : extcon specifier for the Power Delivery
-
+ - rockchip,phy-config : A list of voltage swing(mV) and pre-emphasis
+			(dB) pairs. They are 3 blocks of 4 entries and
+			correspond to s0p0 ~ s0p3, s1p0 ~ s1p3,
+			s2p0 ~ s2p3, s3p0 ~ s2p3 swing and pre-emphasis
+			values.
 Required nodes : a sub-node is required for each port the phy provides.
 		 The sub-node name is used to identify dp or usb3 port,
 		 and shall be the following entries:
@@ -50,6 +54,21 @@ Example:
 			 <&cru SRST_P_UPHY0_TCPHY>;
 		reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
 
+		rockchip,phy-config = <0x2a 0x00>,
+			<0x1f 0x15>,
+			<0x14 0x22>,
+			<0x02 0x2b>,
+
+			<0x21 0x00>,
+			<0x12 0x15>,
+			<0x02 0x22>,
+			<0 0>,
+
+			<0x15 0x00>,
+			<0x00 0x15>,
+			<0 0>,
+			<0 0>;
+
 		tcphy0_dp: dp-port {
 			#phy-cells = <0>;
 		};
@@ -74,6 +93,21 @@ Example:
 			 <&cru SRST_P_UPHY1_TCPHY>;
 		reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
 
+		rockchip,phy-config = <0x2a 0x00>,
+			<0x1f 0x15>,
+			<0x14 0x22>,
+			<0x02 0x2b>,
+
+			<0x21 0x00>,
+			<0x12 0x15>,
+			<0x02 0x22>,
+			<0 0>,
+
+			<0x15 0x00>,
+			<0x00 0x15>,
+			<0 0>,
+			<0 0>;
+
 		tcphy1_dp: dp-port {
 			#phy-cells = <0>;
 		};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v7 1/5] drm/rockchip: add transfer function for cdn-dp
From: Lin Huang @ 2018-05-23  7:42 UTC (permalink / raw)
  To: seanpaul, airlied, zyw, kishon
  Cc: dianders, briannorris, linux-rockchip, heiko, daniel.vetter,
	dri-devel, linux-arm-kernel, linux-kernel, eballetbo, robh+dt,
	devicetree, Lin Huang

From: Chris Zhong <zyw@rock-chips.com>

We may support training outside firmware, so we need support
dpcd read/write to get the message or do some setting with
display.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Signed-off-by: Lin Huang <hl@rock-chips.com>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Enric Balletbo <enric.balletbo@collabora.com>
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- None
Changes in v4:
- None
Changes in v5:
- None
Changes in v6:
- None
Changes in v7:
- None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 55 +++++++++++++++++++++++----
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
 drivers/gpu/drm/rockchip/cdn-dp-reg.c  | 69 ++++++++++++++++++++++++++++++----
 drivers/gpu/drm/rockchip/cdn-dp-reg.h  | 14 ++++++-
 4 files changed, 122 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index c6fbdcd..cce64c1 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -176,8 +176,8 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
 	u8 value;
 
 	*sink_count = 0;
-	ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, &value, 1);
-	if (ret)
+	ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, &value, 1);
+	if (ret < 0)
 		return ret;
 
 	*sink_count = DP_GET_SINK_COUNT(value);
@@ -374,9 +374,9 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
 	if (!cdn_dp_check_sink_connection(dp))
 		return -ENODEV;
 
-	ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
-			       DP_RECEIVER_CAP_SIZE);
-	if (ret) {
+	ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd,
+			       sizeof(dp->dpcd));
+	if (ret < 0) {
 		DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
 		return ret;
 	}
@@ -582,8 +582,8 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
 	if (!port || !dp->link.rate || !dp->link.num_lanes)
 		return false;
 
-	if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
-			     DP_LINK_STATUS_SIZE)) {
+	if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) !=
+	    DP_LINK_STATUS_SIZE) {
 		DRM_ERROR("Failed to get link status\n");
 		return false;
 	}
@@ -1012,6 +1012,40 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
 	return NOTIFY_DONE;
 }
 
+static ssize_t cdn_dp_aux_transfer(struct drm_dp_aux *aux,
+				   struct drm_dp_aux_msg *msg)
+{
+	struct cdn_dp_device *dp = container_of(aux, struct cdn_dp_device, aux);
+	int ret;
+	u8 status;
+
+	switch (msg->request & ~DP_AUX_I2C_MOT) {
+	case DP_AUX_NATIVE_WRITE:
+	case DP_AUX_I2C_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+		ret = cdn_dp_dpcd_write(dp, msg->address, msg->buffer,
+					msg->size);
+		break;
+	case DP_AUX_NATIVE_READ:
+	case DP_AUX_I2C_READ:
+		ret = cdn_dp_dpcd_read(dp, msg->address, msg->buffer,
+				       msg->size);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	status = cdn_dp_get_aux_status(dp);
+	if (status == AUX_STATUS_ACK)
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+	else if (status == AUX_STATUS_NACK)
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK;
+	else if (status == AUX_STATUS_DEFER)
+		msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
+
+	return ret;
+}
+
 static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 {
 	struct cdn_dp_device *dp = dev_get_drvdata(dev);
@@ -1030,6 +1064,13 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 	dp->active = false;
 	dp->active_port = -1;
 	dp->fw_loaded = false;
+	dp->aux.name = "DP-AUX";
+	dp->aux.transfer = cdn_dp_aux_transfer;
+	dp->aux.dev = dev;
+
+	ret = drm_dp_aux_register(&dp->aux);
+	if (ret)
+		return ret;
 
 	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
 
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index f57e296..46159b2 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -78,6 +78,7 @@ struct cdn_dp_device {
 	struct platform_device *audio_pdev;
 	struct work_struct event_work;
 	struct edid *edid;
+	struct drm_dp_aux aux;
 
 	struct mutex lock;
 	bool connected;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
index eb3042c..979355d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -221,7 +221,12 @@ static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr,
 				   sizeof(field), field);
 }
 
-int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
+/*
+ * Returns the number of bytes transferred on success, or a negative
+ * error code on failure. -ETIMEDOUT is returned if mailbox message was
+ * not send successfully;
+ */
+ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
 {
 	u8 msg[5], reg[5];
 	int ret;
@@ -247,24 +252,41 @@ int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
 		goto err_dpcd_read;
 
 	ret = cdn_dp_mailbox_read_receive(dp, data, len);
+	if (!ret)
+		return len;
 
 err_dpcd_read:
+	DRM_DEV_ERROR(dp->dev, "dpcd read failed: %d\n", ret);
 	return ret;
 }
 
-int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
+#define CDN_AUX_HEADER_SIZE	5
+#define CDN_AUX_MSG_SIZE	20
+/*
+ * Returns the number of bytes transferred on success, or a negative error
+ * code on failure. -ETIMEDOUT is returned if mailbox message was not send
+ * success; -EINVAL is returned if get the wrong data size after message
+ * is sent
+ */
+ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
 {
-	u8 msg[6], reg[5];
+	u8 msg[CDN_AUX_MSG_SIZE + CDN_AUX_HEADER_SIZE];
+	u8 reg[CDN_AUX_HEADER_SIZE];
 	int ret;
 
-	msg[0] = 0;
-	msg[1] = 1;
+	if (WARN_ON(len > CDN_AUX_MSG_SIZE) || WARN_ON(len <= 0))
+		return -EINVAL;
+
+	msg[0] = (len >> 8) & 0xff;
+	msg[1] = len & 0xff;
 	msg[2] = (addr >> 16) & 0xff;
 	msg[3] = (addr >> 8) & 0xff;
 	msg[4] = addr & 0xff;
-	msg[5] = value;
+
+	memcpy(msg + CDN_AUX_HEADER_SIZE, data, len);
+
 	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
-				  sizeof(msg), msg);
+				  CDN_AUX_HEADER_SIZE + len, msg);
 	if (ret)
 		goto err_dpcd_write;
 
@@ -277,8 +299,12 @@ int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
 	if (ret)
 		goto err_dpcd_write;
 
-	if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
+	if ((len != (reg[0] << 8 | reg[1])) ||
+	    (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))) {
 		ret = -EINVAL;
+	} else {
+		return len;
+	}
 
 err_dpcd_write:
 	if (ret)
@@ -286,6 +312,33 @@ int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
 	return ret;
 }
 
+int cdn_dp_get_aux_status(struct cdn_dp_device *dp)
+{
+	u8 status;
+	int ret;
+
+	ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
+				  DPTX_GET_LAST_AUX_STAUS, 0, NULL);
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
+					      DPTX_GET_LAST_AUX_STAUS,
+					      sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	return status;
+
+err_get_hpd:
+	DRM_DEV_ERROR(dp->dev, "get aux status failed: %d\n", ret);
+	return ret;
+}
+
 int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
 			 u32 i_size, const u32 *d_mem, u32 d_size)
 {
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
index c4bbb4a83..6580b11 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
@@ -328,6 +328,13 @@
 #define GENERAL_BUS_SETTINGS            0x03
 #define GENERAL_TEST_ACCESS             0x04
 
+/* AUX status*/
+#define AUX_STATUS_ACK			0
+#define AUX_STATUS_NACK			1
+#define AUX_STATUS_DEFER			2
+#define AUX_STATUS_SINK_ERROR		3
+#define AUX_STATUS_BUS_ERROR		4
+
 #define DPTX_SET_POWER_MNG			0x00
 #define DPTX_SET_HOST_CAPABILITIES		0x01
 #define DPTX_GET_EDID				0x02
@@ -469,8 +476,11 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip);
 int cdn_dp_event_config(struct cdn_dp_device *dp);
 u32 cdn_dp_get_event(struct cdn_dp_device *dp);
 int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
-int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value);
-int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len);
+ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
+			  u8 *data, u16 len);
+ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
+			 u8 *data, u16 len);
+int cdn_dp_get_aux_status(struct cdn_dp_device *dp);
 int cdn_dp_get_edid_block(void *dp, u8 *edid,
 			  unsigned int block, size_t length);
 int cdn_dp_train_link(struct cdn_dp_device *dp);
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH v2 02/16] arm64: dts: marvell: fix CP110 ICU node size
From: Gregory CLEMENT @ 2018-05-23  7:36 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Thomas Gleixner, Jason Cooper, Marc Zyngier, Catalin Marinas,
	Will Deacon, Andrew Lunn, Sebastian Hesselbarth, Rob Herring,
	Mark Rutland, devicetree, linux-arm-kernel, Thomas Petazzoni,
	Antoine Tenart, Maxime Chevallier, Nadav Haklai, Haim Boot,
	Hanna Hawa, linux-kernel, stable
In-Reply-To: <20180522094042.24770-3-miquel.raynal@bootlin.com>

Hi Miquel,
 
 On mar., mai 22 2018, Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> ICU size in CP110 is not 0x10 but at least 0x440 bytes long (from the
> specification).
>
> Fixes: 6ef84a827c37 ("arm64: dts: marvell: enable GICP and ICU on Armada 7K/8K")
> Cc: stable@vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Reviewed-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>

Applied on mvebu/fixes

Thanks,

Gregory

> ---
>  arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
> index 48cad7919efa..9fa41c54f69c 100644
> --- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
> @@ -146,7 +146,7 @@
>  
>  		CP110_LABEL(icu): interrupt-controller@1e0000 {
>  			compatible = "marvell,cp110-icu";
> -			reg = <0x1e0000 0x10>;
> +			reg = <0x1e0000 0x440>;
>  			#interrupt-cells = <3>;
>  			interrupt-controller;
>  			msi-parent = <&gicp>;
> -- 
> 2.14.1
>

-- 
Gregory Clement, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com

^ permalink raw reply

* Re: [PATCH v6 2/6] dt-bindings: Add the rzn1-clocks.h file
From: Geert Uytterhoeven @ 2018-05-23  7:26 UTC (permalink / raw)
  To: M P
  Cc: Michel Pollet, Linux-Renesas, Simon Horman, Phil Edworthy,
	Michel Pollet, Magnus Damm, Rob Herring, Mark Rutland,
	Michael Turquette, Stephen Boyd, Geert Uytterhoeven,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Kernel Mailing List, linux-clk
In-Reply-To: <CAMMfpEyTORirKiE417AQzCLzxDTKmy83bwivpfJaHQsKUKMc_w@mail.gmail.com>

Hi Michel,

On Wed, May 23, 2018 at 8:44 AM, M P <buserror@gmail.com> wrote:
> On Tue, 22 May 2018 at 19:44, Geert Uytterhoeven <geert@linux-m68k.org>
> wrote:
>> On Tue, May 22, 2018 at 12:01 PM, Michel Pollet
>> <michel.pollet@bp.renesas.com> wrote:
>> > This adds the constants necessary to use the renesas,rzn1-clocks driver.
>> >
>> > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>

>> > --- /dev/null
>> > +++ b/include/dt-bindings/clock/rzn1-clocks.h
>
>> Given this is part of the DT ABI, and there exist multiple different RZ/N1
>> SoCs (and there are probably planned more), I wouldn't call this header
>> file "rzn1-clocks.h", but e.g. "r9a06g032-clocks.h".
>
> Actually, no, there already are two r906g03X devices that will work
> perfectly fine with this driver. We had that discussion before, and you
> insist and me removing mentions of the rzn1 everywhere, however, this
> applies to *two* devices already, and I'm supposed to upstream support for
> them. I can't rename r9g06g032 because it is *inexact* that's why it's

My worry is not that there are two r906g03X devices that will work fine
with this driver, but that there will be other "rzn1" devices that will not
work with these bindings (the header file is part of the bindings).
Besides, RZ/N1D and RZ/N1S (Which apparently differ in packaging only?
Oh no, RZ/N1D (the larger package) has less QSPI channels than RZ/N1S
(the smaller package)), there's also (at least) RZ/N1L.

> called rzn1. So unless you let me call it r9a06g0xx-clocks.h (which i know
> you won't as per multiple previous discussions) this can't be called
> r9a06g032 because it won't be fit for my purpose when I try to bring back
> the RZ/N1S into the picture.

You can add r9a06g033-clocks.h when adding support for RZ/N1S.

> There are minor difference to clocking,

Aha?

> I don't know if Renesas plans to release any more rzn1's in this series,
> but my little finger tells me this isn't the case. But regardless of what

We thought the same thing when the first RZ member (RZ/A1H) showed up.
Did we know this was not going to be the first SoC of a new RZ family, but
the first SoC of the first subfamily (RZ/A) of the RZ family... And the
various subfamilies bear not much similarity.

> we plan, Marketing will screw it up.

Correct. And to mitigate that, we have no other choice than to use the real
part numbers to differentiate. Once bitten, twice shy.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v4 2/2] iio: dac: Add support for external reference voltage through the regulator framework.
From: Silvan Murer @ 2018-05-23  7:19 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: lars, linux-iio, devicetree
In-Reply-To: <20180522182553.2b3ab124@archlinux>

Thank you Jonathan

On Die, 2018-05-22 at 18:25 +0100, Jonathan Cameron wrote:
> On Mon, 21 May 2018 14:21:28 +0200
> Silvan Murer <silvan.murer@gmail.com> wrote:
> 
> > 
> > Signed-off-by: Silvan Murer <silvan.murer@gmail.com>
> > Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
> Applied to the togreg branch of iio.git and pushed out as testing
> for the autobuilders to play with it.
> 
> Thanks,
> 
> Jonathan
> 
> > 
> > ---
> >  .../devicetree/bindings/iio/dac/ltc2632.txt        | 14 +++++
> >  drivers/iio/dac/ltc2632.c                          | 70
> > +++++++++++++++++++---
> >  2 files changed, 75 insertions(+), 9 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > index eb911e5..e0d5fea 100644
> > --- a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > +++ b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt
> > @@ -12,12 +12,26 @@ Required properties:
> >  Property rules described in
> > Documentation/devicetree/bindings/spi/spi-bus.txt
> >  apply. In particular, "reg" and "spi-max-frequency" properties
> > must be given.
> >  
> > +Optional properties:
> > +	- vref-supply: Phandle to the external reference voltage
> > supply. This should
> > +	  only be set if there is an external reference voltage
> > connected to the VREF
> > +	  pin. If the property is not set the internal reference
> > is used.
> > +
> >  Example:
> >  
> > +	vref: regulator-vref {
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "vref-ltc2632";
> > +		regulator-min-microvolt = <1250000>;
> > +		regulator-max-microvolt = <1250000>;
> > +		regulator-always-on;
> > +	};
> > +
> >  	spi_master {
> >  		dac: ltc2632@0 {
> >  			compatible = "lltc,ltc2632-l12";
> >  			reg = <0>; /* CS0 */
> >  			spi-max-frequency = <1000000>;
> > +			vref-supply = <&vref>; /* optional */
> >  		};
> >  	};
> > diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c
> > index d322b78..9551156 100644
> > --- a/drivers/iio/dac/ltc2632.c
> > +++ b/drivers/iio/dac/ltc2632.c
> > @@ -2,6 +2,7 @@
> >   * LTC2632 Digital to analog convertors spi driver
> >   *
> >   * Copyright 2017 Maxime Roussin-B_langer
> > + * expanded by Silvan Murer <silvan.murer@gmail.com>
> >   *
> >   * Licensed under the GPL-2.
> >   */
> > @@ -10,6 +11,7 @@
> >  #include <linux/spi/spi.h>
> >  #include <linux/module.h>
> >  #include <linux/iio/iio.h>
> > +#include <linux/regulator/consumer.h>
> >  
> >  #define LTC2632_DAC_CHANNELS                    2
> >  
> > @@ -28,7 +30,7 @@
> >  /**
> >   * struct ltc2632_chip_info - chip specific information
> >   * @channels:		channel spec for the DAC
> > - * @vref_mv:		reference voltage
> > + * @vref_mv:		internal reference voltage
> >   */
> >  struct ltc2632_chip_info {
> >  	const struct iio_chan_spec *channels;
> > @@ -39,10 +41,14 @@ struct ltc2632_chip_info {
> >   * struct ltc2632_state - driver instance specific data
> >   * @spi_dev:			pointer to the spi_device
> > struct
> >   * @powerdown_cache_mask	used to show current channel
> > powerdown state
> > + * @vref_mv			used reference voltage
> > (internal or external)
> > + * @vref_reg		regulator for the reference voltage
> >   */
> >  struct ltc2632_state {
> >  	struct spi_device *spi_dev;
> >  	unsigned int powerdown_cache_mask;
> > +	int vref_mv;
> > +	struct regulator *vref_reg;
> >  };
> >  
> >  enum ltc2632_supported_device_ids {
> > @@ -90,7 +96,7 @@ static int ltc2632_read_raw(struct iio_dev
> > *indio_dev,
> >  
> >  	switch (m) {
> >  	case IIO_CHAN_INFO_SCALE:
> > -		*val = chip_info->vref_mv;
> > +		*val = st->vref_mv;
> >  		*val2 = chan->scan_type.realbits;
> >  		return IIO_VAL_FRACTIONAL_LOG2;
> >  	}
> > @@ -247,6 +253,45 @@ static int ltc2632_probe(struct spi_device
> > *spi)
> >  	chip_info = (struct ltc2632_chip_info *)
> >  			spi_get_device_id(spi)->driver_data;
> >  
> > +	st->vref_reg = devm_regulator_get_optional(&spi->dev,
> > "vref");
> > +	if (PTR_ERR(st->vref_reg) == -ENODEV) {
> > +		/* use internal reference voltage */
> > +		st->vref_reg = NULL;
> > +		st->vref_mv = chip_info->vref_mv;
> > +
> > +		ret = ltc2632_spi_write(spi,
> > LTC2632_CMD_INTERNAL_REFER,
> > +				0, 0, 0);
> > +		if (ret) {
> > +			dev_err(&spi->dev,
> > +				"Set internal reference command
> > failed, %d\n",
> > +				ret);
> > +			return ret;
> > +		}
> > +	} else if (IS_ERR(st->vref_reg)) {
> > +		dev_err(&spi->dev,
> > +				"Error getting voltage reference
> > regulator\n");
> > +		return PTR_ERR(st->vref_reg);
> > +	} else {
> > +		/* use external reference voltage */
> > +		ret = regulator_enable(st->vref_reg);
> > +		if (ret) {
> > +			dev_err(&spi->dev,
> > +				"enable reference regulator
> > failed, %d\n",
> > +				ret);
> > +			return ret;
> > +		}
> > +		st->vref_mv = regulator_get_voltage(st->vref_reg)
> > / 1000;
> > +
> > +		ret = ltc2632_spi_write(spi,
> > LTC2632_CMD_EXTERNAL_REFER,
> > +				0, 0, 0);
> > +		if (ret) {
> > +			dev_err(&spi->dev,
> > +				"Set external reference command
> > failed, %d\n",
> > +				ret);
> > +			return ret;
> > +		}
> > +	}
> > +
> >  	indio_dev->dev.parent = &spi->dev;
> >  	indio_dev->name = dev_of_node(&spi->dev) ?
> > dev_of_node(&spi->dev)->name
> >  						 :
> > spi_get_device_id(spi)->name;
> > @@ -255,14 +300,20 @@ static int ltc2632_probe(struct spi_device
> > *spi)
> >  	indio_dev->channels = chip_info->channels;
> >  	indio_dev->num_channels = LTC2632_DAC_CHANNELS;
> >  
> > -	ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER,
> > 0, 0, 0);
> > -	if (ret) {
> > -		dev_err(&spi->dev,
> > -			"Set internal reference command failed,
> > %d\n", ret);
> > -		return ret;
> > -	}
> > +	return iio_device_register(indio_dev);
> > +}
> > +
> > +static int ltc2632_remove(struct spi_device *spi)
> > +{
> > +	struct iio_dev *indio_dev = spi_get_drvdata(spi);
> > +	struct ltc2632_state *st = iio_priv(indio_dev);
> > +
> > +	iio_device_unregister(indio_dev);
> > +
> > +	if (st->vref_reg)
> > +		regulator_disable(st->vref_reg);
> >  
> > -	return devm_iio_device_register(&spi->dev, indio_dev);
> > +	return 0;
> >  }
> >  
> >  static const struct spi_device_id ltc2632_id[] = {
> > @@ -306,6 +357,7 @@ static struct spi_driver ltc2632_driver = {
> >  		.of_match_table = of_match_ptr(ltc2632_of_match),
> >  	},
> >  	.probe		= ltc2632_probe,
> > +	.remove		= ltc2632_remove,
> >  	.id_table	= ltc2632_id,
> >  };
> >  module_spi_driver(ltc2632_driver);

^ permalink raw reply

* Re: [PATCH v3] iio: dac: Add support for external reference voltage through the regulator framework.
From: Silvan Murer @ 2018-05-23  7:17 UTC (permalink / raw)
  To: Rob Herring; +Cc: lars, jic23, linux-iio, devicetree
In-Reply-To: <20180522171903.GA24256@rob-hp-laptop>

Thanks Rob for the review and the feedback!
In the next patches, I split the bindings to a separate patch.

On Die, 2018-05-22 at 12:19 -0500, Rob Herring wrote:
> On Sun, May 20, 2018 at 02:19:17AM +0200, Silvan Murer wrote:
> > 
> > Add support for external reference voltage through the regulator
> > framework.
> > 
> > Signed-off-by: Silvan Murer <silvan.murer@gmail.com>
> > Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
> > ---
> > Changes in v3:
> > 	- remove extra spaces and tab
> > Changes in v2:
> > 	- Add 'optional properties' documentation
> > 	- Return an error when a regulator is specified
> > 	- Use internal reference when no regulator is specified
> > 	- Use iio_device_register instead of devm_iio_device_register
> > 
> >  .../devicetree/bindings/iio/dac/ltc2632.txt        | 14 +++++
> Reviewed-by: Rob Herring <robh@kernel.org>
> 
> In the future, please split bindings to separate patch.
> 
> > 
> >  drivers/iio/dac/ltc2632.c                          | 70
> > +++++++++++++++++++---
> >  2 files changed, 75 insertions(+), 9 deletions(-)

^ permalink raw reply

* Re: [PATCH v5 1/3] ARM: dts: tegra: Remove skeleton.dtsi and fix DTC warnings for /memory
From: Krzysztof Kozlowski @ 2018-05-23  7:05 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
	devicetree, linux-tegra, linux-kernel, Marcel Ziswiler,
	Lucas Stach
In-Reply-To: <cbcc6f929d2bd912c11530391d03cdf3@agner.ch>

On Thu, May 17, 2018 at 1:39 PM, Stefan Agner <stefan@agner.ch> wrote:
> On 17.05.2018 09:45, Krzysztof Kozlowski wrote:
>> Remove the usage of skeleton.dtsi and add necessary properties to /memory
>> node to fix the DTC warnings:
>>
>>     arch/arm/boot/dts/tegra20-harmony.dtb: Warning (unit_address_vs_reg):
>>         /memory: node has a reg or ranges property, but no unit name
>>
>> The DTB after the change is the same as before except adding
>> unit-address to /memory node.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
>>
>> ---
>>
>> Changes since v4:
>> 1. None
>> ---
>>  arch/arm/boot/dts/tegra114-dalmore.dts      | 3 ++-
>>  arch/arm/boot/dts/tegra114-roth.dts         | 3 ++-
>>  arch/arm/boot/dts/tegra114-tn7.dts          | 3 ++-
>>  arch/arm/boot/dts/tegra114.dtsi             | 4 ++--
>>  arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi | 3 ++-
>>  arch/arm/boot/dts/tegra124-apalis.dtsi      | 3 ++-
>>  arch/arm/boot/dts/tegra124-jetson-tk1.dts   | 3 ++-
>>  arch/arm/boot/dts/tegra124-nyan.dtsi        | 3 ++-
>>  arch/arm/boot/dts/tegra124-venice2.dts      | 3 ++-
>>  arch/arm/boot/dts/tegra124.dtsi             | 2 --
>>  arch/arm/boot/dts/tegra20-colibri-512.dtsi  | 3 ++-
>>  arch/arm/boot/dts/tegra20-harmony.dts       | 3 ++-
>>  arch/arm/boot/dts/tegra20-paz00.dts         | 3 ++-
>>  arch/arm/boot/dts/tegra20-seaboard.dts      | 3 ++-
>>  arch/arm/boot/dts/tegra20-tamonten.dtsi     | 3 ++-
>>  arch/arm/boot/dts/tegra20-trimslice.dts     | 3 ++-
>>  arch/arm/boot/dts/tegra20-ventana.dts       | 3 ++-
>>  arch/arm/boot/dts/tegra20.dtsi              | 7 +++++--
>>  arch/arm/boot/dts/tegra30-apalis.dtsi       | 5 +++++
>>  arch/arm/boot/dts/tegra30-beaver.dts        | 3 ++-
>>  arch/arm/boot/dts/tegra30-cardhu.dtsi       | 3 ++-
>>  arch/arm/boot/dts/tegra30-colibri.dtsi      | 3 ++-
>>  arch/arm/boot/dts/tegra30.dtsi              | 7 +++++--
>>  23 files changed, 53 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts
>> b/arch/arm/boot/dts/tegra114-dalmore.dts
>> index eafff16765b4..5cdcedfc19cb 100644
>> --- a/arch/arm/boot/dts/tegra114-dalmore.dts
>> +++ b/arch/arm/boot/dts/tegra114-dalmore.dts
>> @@ -23,7 +23,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@80000000 {
>> +             device_type = "memory";
>>               reg = <0x80000000 0x40000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra114-roth.dts
>> b/arch/arm/boot/dts/tegra114-roth.dts
>> index 7ed7370ee67a..b4f329a07c60 100644
>> --- a/arch/arm/boot/dts/tegra114-roth.dts
>> +++ b/arch/arm/boot/dts/tegra114-roth.dts
>> @@ -28,7 +28,8 @@
>>               };
>>       };
>>
>> -     memory {
>> +     memory@80000000 {
>> +             device_type = "memory";
>>               /* memory >= 0x79600000 is reserved for firmware usage */
>>               reg = <0x80000000 0x79600000>;
>>       };
>> diff --git a/arch/arm/boot/dts/tegra114-tn7.dts
>> b/arch/arm/boot/dts/tegra114-tn7.dts
>> index 7fc4a8b31e45..12092d344ce8 100644
>> --- a/arch/arm/boot/dts/tegra114-tn7.dts
>> +++ b/arch/arm/boot/dts/tegra114-tn7.dts
>> @@ -28,7 +28,8 @@
>>               };
>>       };
>>
>> -     memory {
>> +     memory@80000000 {
>> +             device_type = "memory";
>>               /* memory >= 0x37e00000 is reserved for firmware usage */
>>               reg = <0x80000000 0x37e00000>;
>>       };
>> diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
>> index 0e4a13295d8a..b917784d3f97 100644
>> --- a/arch/arm/boot/dts/tegra114.dtsi
>> +++ b/arch/arm/boot/dts/tegra114.dtsi
>> @@ -5,11 +5,11 @@
>>  #include <dt-bindings/pinctrl/pinctrl-tegra.h>
>>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>>
>> -#include "skeleton.dtsi"
>> -
>>  / {
>>       compatible = "nvidia,tegra114";
>>       interrupt-parent = <&lic>;
>> +     #address-cells = <1>;
>> +     #size-cells = <1>;
>>
>>       host1x@50000000 {
>>               compatible = "nvidia,tegra114-host1x", "simple-bus";
>> diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
>> b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
>> index bb67edb016c5..80b52c612891 100644
>> --- a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
>> +++ b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
>> @@ -15,7 +15,8 @@
>>       compatible = "toradex,apalis-tk1-v1.2", "toradex,apalis-tk1",
>>                    "nvidia,tegra124";
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x0 0x80000000 0x0 0x80000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra124-apalis.dtsi
>> b/arch/arm/boot/dts/tegra124-apalis.dtsi
>> index 65a2161b9b8e..3ca7601cafe9 100644
>> --- a/arch/arm/boot/dts/tegra124-apalis.dtsi
>> +++ b/arch/arm/boot/dts/tegra124-apalis.dtsi
>> @@ -50,7 +50,8 @@
>>       model = "Toradex Apalis TK1";
>>       compatible = "toradex,apalis-tk1", "nvidia,tegra124";
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x0 0x80000000 0x0 0x80000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
>> b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
>> index 6dbcf84dafbc..8d9e6ee6c6a7 100644
>> --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
>> +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
>> @@ -24,7 +24,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x0 0x80000000 0x0 0x80000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi
>> b/arch/arm/boot/dts/tegra124-nyan.dtsi
>> index 3609367037a6..15a2b0e3237e 100644
>> --- a/arch/arm/boot/dts/tegra124-nyan.dtsi
>> +++ b/arch/arm/boot/dts/tegra124-nyan.dtsi
>> @@ -13,7 +13,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x0 0x80000000 0x0 0x80000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra124-venice2.dts
>> b/arch/arm/boot/dts/tegra124-venice2.dts
>> index 89bcc178994d..241cdc4b6600 100644
>> --- a/arch/arm/boot/dts/tegra124-venice2.dts
>> +++ b/arch/arm/boot/dts/tegra124-venice2.dts
>> @@ -18,7 +18,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x0 0x80000000 0x0 0x80000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
>> index 174092bfac90..df1642876a4c 100644
>> --- a/arch/arm/boot/dts/tegra124.dtsi
>> +++ b/arch/arm/boot/dts/tegra124.dtsi
>> @@ -7,8 +7,6 @@
>>  #include <dt-bindings/reset/tegra124-car.h>
>>  #include <dt-bindings/thermal/tegra124-soctherm.h>
>>
>> -#include "skeleton.dtsi"
>> -
>>  / {
>>       compatible = "nvidia,tegra124";
>>       interrupt-parent = <&lic>;
>> diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
>> b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
>> index 5c202b3e3bb1..305efb275b48 100644
>> --- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
>> +++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
>> @@ -10,7 +10,8 @@
>>               rtc1 = "/rtc@7000e000";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x00000000 0x20000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra20-harmony.dts
>> b/arch/arm/boot/dts/tegra20-harmony.dts
>> index 628a55a9318b..5009a55ae15c 100644
>> --- a/arch/arm/boot/dts/tegra20-harmony.dts
>> +++ b/arch/arm/boot/dts/tegra20-harmony.dts
>> @@ -18,7 +18,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x00000000 0x40000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra20-paz00.dts
>> b/arch/arm/boot/dts/tegra20-paz00.dts
>> index 30436969adc0..e794ac5442ef 100644
>> --- a/arch/arm/boot/dts/tegra20-paz00.dts
>> +++ b/arch/arm/boot/dts/tegra20-paz00.dts
>> @@ -19,7 +19,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x00000000 0x20000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts
>> b/arch/arm/boot/dts/tegra20-seaboard.dts
>> index 284aae351ff2..6cb832cfa4f3 100644
>> --- a/arch/arm/boot/dts/tegra20-seaboard.dts
>> +++ b/arch/arm/boot/dts/tegra20-seaboard.dts
>> @@ -18,7 +18,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x00000000 0x40000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi
>> b/arch/arm/boot/dts/tegra20-tamonten.dtsi
>> index 872046d48709..6ceb1228fed3 100644
>> --- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
>> +++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
>> @@ -15,7 +15,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x00000000 0x20000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts
>> b/arch/arm/boot/dts/tegra20-trimslice.dts
>> index d55c6b240a30..3f94be3da9e5 100644
>> --- a/arch/arm/boot/dts/tegra20-trimslice.dts
>> +++ b/arch/arm/boot/dts/tegra20-trimslice.dts
>> @@ -18,7 +18,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x00000000 0x40000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra20-ventana.dts
>> b/arch/arm/boot/dts/tegra20-ventana.dts
>> index ee3fbf941e79..c897a90289bc 100644
>> --- a/arch/arm/boot/dts/tegra20-ventana.dts
>> +++ b/arch/arm/boot/dts/tegra20-ventana.dts
>> @@ -18,7 +18,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@0 {
>> +             device_type = "memory";
>>               reg = <0x00000000 0x40000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
>> index 0a7136462a1a..290ebbeb210f 100644
>> --- a/arch/arm/boot/dts/tegra20.dtsi
>> +++ b/arch/arm/boot/dts/tegra20.dtsi
>> @@ -4,11 +4,14 @@
>>  #include <dt-bindings/pinctrl/pinctrl-tegra.h>
>>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>>
>> -#include "skeleton.dtsi"
>> -
>>  / {
>>       compatible = "nvidia,tegra20";
>>       interrupt-parent = <&lic>;
>> +     #address-cells = <1>;
>> +     #size-cells = <1>;
>> +
>> +     chosen { };
>> +     aliases { };
>>
>>       iram@40000000 {
>>               compatible = "mmio-sram";
>> diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi
>> b/arch/arm/boot/dts/tegra30-apalis.dtsi
>> index d1d21ec2a844..184f60c720fa 100644
>> --- a/arch/arm/boot/dts/tegra30-apalis.dtsi
>> +++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
>> @@ -10,6 +10,11 @@
>>       model = "Toradex Apalis T30";
>>       compatible = "toradex,apalis_t30", "nvidia,tegra30";
>>
>> +     memory@0 {
>> +             device_type = "memory";
>> +             reg = <0 0>;
>> +     };
>> +
>>       pcie@3000 {
>>               avdd-pexa-supply = <&vdd2_reg>;
>>               vdd-pexa-supply = <&vdd2_reg>;
>> diff --git a/arch/arm/boot/dts/tegra30-beaver.dts
>> b/arch/arm/boot/dts/tegra30-beaver.dts
>> index ae52a5039506..72369877d284 100644
>> --- a/arch/arm/boot/dts/tegra30-beaver.dts
>> +++ b/arch/arm/boot/dts/tegra30-beaver.dts
>> @@ -17,7 +17,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@80000000 {
>> +             device_type = "memory";
>>               reg = <0x80000000 0x7ff00000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi
>> b/arch/arm/boot/dts/tegra30-cardhu.dtsi
>> index 92a9740c533f..24c04d4c335d 100644
>> --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
>> +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
>> @@ -40,7 +40,8 @@
>>               stdout-path = "serial0:115200n8";
>>       };
>>
>> -     memory {
>> +     memory@80000000 {
>> +             device_type = "memory";
>>               reg = <0x80000000 0x40000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi
>> b/arch/arm/boot/dts/tegra30-colibri.dtsi
>> index c44d8c40c410..cc46cedf80b9 100644
>> --- a/arch/arm/boot/dts/tegra30-colibri.dtsi
>> +++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
>> @@ -10,7 +10,8 @@
>>       model = "Toradex Colibri T30";
>>       compatible = "toradex,colibri_t30", "nvidia,tegra30";
>>
>> -     memory {
>> +     memory@80000000 {
>> +             device_type = "memory";
>>               reg = <0x80000000 0x40000000>;
>>       };
>>
>> diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
>> index a110cf84d85f..4383f0fd789d 100644
>> --- a/arch/arm/boot/dts/tegra30.dtsi
>> +++ b/arch/arm/boot/dts/tegra30.dtsi
>> @@ -5,11 +5,14 @@
>>  #include <dt-bindings/pinctrl/pinctrl-tegra.h>
>>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>>
>> -#include "skeleton.dtsi"
>> -
>>  / {
>>       compatible = "nvidia,tegra30";
>>       interrupt-parent = <&lic>;
>> +     #address-cells = <1>;
>> +     #size-cells = <1>;
>> +
>> +     chosen { };
>> +     aliases { };
>
> Could we not add
>
>         memory { device_type = "memory"; };
>
> in the SoC level device trees?
>
> This would save device_type in all other instances.
>
> That is also how it is done in other places, e.g.
> arch/arm/boot/dts/imx6qdl.dtsi

Not really because the unit address will not match between different
boards. The imx6qdl, as I see, has the same issue:
 - imx6qdl.dtsi defines "memory" node
 - imx6dl-apf6dev.dts includes the previous and defines "memory@10000000"

This is wrong - two memory nodes.

> Also, could we maybe split this in two?
>
> ARM: dts: tegra: Remove skeleton.dtsi
> ARM: dts: tegra: fix DTC warnings for /memory

It is possible to split it but this really won't bring any benefit
because the removal of skeleton.dtsi is the way to fix the errors. Or
saying it differently - the warnings are the reason to remove the
skeleton.dtsi. If you split them, what is the reason to remove the
skeleton.dtsi? (Theoretically it was deprecated so this could be
explanation).

If you wish, I can prepare something like:
1. Remove skeleton.dtsi and add everywhere 'device_type = "memory"'.
All the warnings will stay but the end DTB should be equal between
changes.
2. Fix warnings.

> The first would only touch SoC level dts.

No, because device_type has to be added everywhere. And because of
warnings (explained before) it cannot be added to SoC DTSI.

Best regards,
Krzysztof

>
> The second then would fix DTC warnings by adding the address to the
> memory nodes in all board files.
>
> --
> Stefan
>
>>
>>       pcie@3000 {
>>               compatible = "nvidia,tegra30-pcie";

^ permalink raw reply

* [PATCH v3 13/13] soc: rockchip: power-domain: add power domain support for px30
From: Elaine Zhang @ 2018-05-23  6:53 UTC (permalink / raw)
  To: heiko, robh+dt, mark.rutland
  Cc: devicetree, rjw, khilman, ulf.hansson, linux-pm, linux-arm-kernel,
	linux-rockchip, linux-kernel, wxt, xxx, xf, huangtao, Finley Xiao,
	Elaine Zhang
In-Reply-To: <1527058129-10260-1-git-send-email-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao@rock-chips.com>

This driver is modified to support PX30 SoC.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 drivers/soc/rockchip/pm_domains.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index 90dcd5e21ae6..d0c5615132e3 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -18,6 +18,7 @@
 #include <linux/clk.h>
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
+#include <dt-bindings/power/px30-power.h>
 #include <dt-bindings/power/rk3036-power.h>
 #include <dt-bindings/power/rk3128-power.h>
 #include <dt-bindings/power/rk3228-power.h>
@@ -114,6 +115,9 @@ struct rockchip_pmu {
 	.active_wakeup = wakeup,			\
 }
 
+#define DOMAIN_PX30(pwr, status, req, wakeup)		\
+	DOMAIN_M(pwr, status, req, (req) + 16, req, wakeup)
+
 #define DOMAIN_RK3288(pwr, status, req, wakeup)		\
 	DOMAIN(pwr, status, req, req, (req) + 16, wakeup)
 
@@ -712,6 +716,17 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
 	return error;
 }
 
+static const struct rockchip_domain_info px30_pm_domains[] = {
+	[PX30_PD_USB]		= DOMAIN_PX30(5, 5, 10, false),
+	[PX30_PD_SDCARD]	= DOMAIN_PX30(8, 8, 9, false),
+	[PX30_PD_GMAC]		= DOMAIN_PX30(10, 10, 6, false),
+	[PX30_PD_MMC_NAND]	= DOMAIN_PX30(11, 11, 5, false),
+	[PX30_PD_VPU]		= DOMAIN_PX30(12, 12, 14, false),
+	[PX30_PD_VO]		= DOMAIN_PX30(13, 13, 7, false),
+	[PX30_PD_VI]		= DOMAIN_PX30(14, 14, 8, false),
+	[PX30_PD_GPU]		= DOMAIN_PX30(15, 15, 2, false),
+};
+
 static const struct rockchip_domain_info rk3036_pm_domains[] = {
 	[RK3036_PD_MSCH]	= DOMAIN_RK3036(14, 23, 30, true),
 	[RK3036_PD_CORE]	= DOMAIN_RK3036(13, 17, 24, false),
@@ -811,6 +826,17 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
 	[RK3399_PD_SDIOAUDIO]	= DOMAIN_RK3399(31, 31, 29, true),
 };
 
+static const struct rockchip_pmu_info px30_pmu = {
+	.pwr_offset = 0x18,
+	.status_offset = 0x20,
+	.req_offset = 0x64,
+	.idle_offset = 0x6c,
+	.ack_offset = 0x6c,
+
+	.num_domains = ARRAY_SIZE(px30_pm_domains),
+	.domain_info = px30_pm_domains,
+};
+
 static const struct rockchip_pmu_info rk3036_pmu = {
 	.req_offset = 0x148,
 	.idle_offset = 0x14c,
@@ -915,6 +941,10 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
 
 static const struct of_device_id rockchip_pm_domain_dt_match[] = {
 	{
+		.compatible = "rockchip,px30-power-controller",
+		.data = (void *)&px30_pmu,
+	},
+	{
 		.compatible = "rockchip,rk3036-power-controller",
 		.data = (void *)&rk3036_pmu,
 	},
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 12/13] dt-bindings: add binding for px30 power domains
From: Elaine Zhang @ 2018-05-23  6:52 UTC (permalink / raw)
  To: heiko, robh+dt, mark.rutland
  Cc: devicetree, rjw, khilman, ulf.hansson, linux-pm, linux-arm-kernel,
	linux-rockchip, linux-kernel, wxt, xxx, xf, huangtao, Finley Xiao,
	Elaine Zhang
In-Reply-To: <1527058129-10260-1-git-send-email-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao@rock-chips.com>

Add binding documentation for the power domains
found on Rockchip PX30 SoCs.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 Documentation/devicetree/bindings/soc/rockchip/power_domain.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
index affe36dcfa17..5d49d0a2ff29 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
+++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
@@ -5,6 +5,7 @@ powered up/down by software based on different application scenes to save power.
 
 Required properties for power domain controller:
 - compatible: Should be one of the following.
+	"rockchip,px30-power-controller" - for PX30 SoCs.
 	"rockchip,rk3036-power-controller" - for RK3036 SoCs.
 	"rockchip,rk3128-power-controller" - for RK3128 SoCs.
 	"rockchip,rk3228-power-controller" - for RK3228 SoCs.
@@ -20,6 +21,7 @@ Required properties for power domain controller:
 
 Required properties for power domain sub nodes:
 - reg: index of the power domain, should use macros in:
+	"include/dt-bindings/power/px30-power.h" - for PX30 type power domain.
 	"include/dt-bindings/power/rk3036-power.h" - for RK3036 type power domain.
 	"include/dt-bindings/power/rk3128-power.h" - for RK3128 type power domain.
 	"include/dt-bindings/power/rk3228-power.h" - for RK3228 type power domain.
@@ -99,6 +101,7 @@ Node of a device using power domains must have a power-domains property,
 containing a phandle to the power device node and an index specifying which
 power domain to use.
 The index should use macros in:
+	"include/dt-bindings/power/px30-power.h" - for px30 type power domain.
 	"include/dt-bindings/power/rk3036-power.h" - for rk3036 type power domain.
 	"include/dt-bindings/power/rk3128-power.h" - for rk3128 type power domain.
 	"include/dt-bindings/power/rk3128-power.h" - for rk3228 type power domain.
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v6 3/6] dt-bindings: clock: renesas,rzn1-clocks: document RZ/N1 clock driver
From: M P @ 2018-05-23  6:52 UTC (permalink / raw)
  To: robh
  Cc: michel.pollet, linux-renesas-soc, horms, Phil Edworthy,
	buserror+upstream, magnus.damm, mark.rutland, mturquette, sboyd,
	geert+renesas, devicetree, linux-kernel, linux-clk
In-Reply-To: <20180522160913.GA7755@rob-hp-laptop>

Hi Rob,

On Tue, 22 May 2018 at 17:09, Rob Herring <robh@kernel.org> wrote:

> On Tue, May 22, 2018 at 11:01:23AM +0100, Michel Pollet wrote:
> > The Renesas RZ/N1 Family (Part #R9A06G0xx) requires a driver
> > to provide the SoC clock infrastructure for Linux.
> >
> > This documents the driver bindings.
> >
> > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
> > ---
> >  .../bindings/clock/renesas,rzn1-clocks.txt         | 44
++++++++++++++++++++++
> >  1 file changed, 44 insertions(+)
> >  create mode 100644
Documentation/devicetree/bindings/clock/renesas,rzn1-clocks.txt
> >
> > diff --git
a/Documentation/devicetree/bindings/clock/renesas,rzn1-clocks.txt
b/Documentation/devicetree/bindings/clock/renesas,rzn1-clocks.txt
> > new file mode 100644
> > index 0000000..0c41137
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/renesas,rzn1-clocks.txt
> > @@ -0,0 +1,44 @@
> > +* Renesas RZ/N1 Clock Driver
> > +
> > +This driver provides the clock infrastructure used by all the other
drivers.

> Bindings document h/w not drivers.

> > +
> > +One of the 'special' feature of this infrastructure is that Linux
doesn't

> Bindings are not just for Linux.

> > +necessary 'own' all the clocks on the SoC, some other OS runs on
> > +the Cortex-M3 core and that OS can access and claim it's own clocks.

> How is this relevant to the binding?

Well you just said it, if the binding is not just for linux, it's probably
a good idea to mention it somewhere since I can promise you it's *not*
documented in the hardware manual. Whatever this binding is for, it's
relevant to point out it is different from the other clock drivers in the
same directory... ?


> > +
> > +Required Properties:
> > +
> > +  - compatible: Must be
> > +    - "renesas,r9a06g032-clocks" for the RZ/N1D
> > +    and "renesas,rzn1-clocks" as a fallback.

> Is "clocks" how the chip reference manual refers to this block?

No, the block is called 'sysctrl' and has tons of other stuff in there.
I've tried multiple times to get a 'sysctrl' driver in the previous
versions of the patch, in various shape or form, and I can't because I'd be
supposed to 'document' binding for stuff that has no code, no purpose, no
testing, and have all wildly different topics. So, after some more
lengthily discussion with Geert, we've decided to make the 'primary'
feature of that block (clocks) as a driver, and see from there onward.

Thanks for all the other comments, all taken onboard for next version!
Michel


> > +  - reg: Base address and length of the memory resource used by the
driver
> > +  - #clock-cells: Must be 1
> > +
> > +Examples
> > +--------
> > +
> > +  - Clock driver device node:
> > +
> > +     clock: clocks@4000c000 {

> clock-controller@...

> > +             compatible = "renesas,r9a06g032-clocks",
> > +                             "renesas,rzn1-clocks";
> > +             reg = <0x4000c000 0x1000>;
> > +             status = "okay";

> Don't show status in examples. (Plus, I doubt you ever want to have this
> disabled, so you don't need the property in your dts files either).

> > +             #clock-cells = <1>;
> > +     };
> > +
> > +
> > +  - Other drivers can use the clocks as in:

> s/drivers/nodes/

> > +
> > +     uart0: serial@40060000 {
> > +             compatible = "snps,dw-apb-uart";
> > +             reg = <0x40060000 0x400>;
> > +             interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
> > +             reg-shift = <2>;
> > +             reg-io-width = <4>;
> > +             clocks = <&clock RZN1_CLK_UART0>;
> > +             clock-names = "baudclk";
> > +     };
> > +    Note the use of RZN1_CLK_UART0 -- these constants are declared in
> > +    the rzn1-clocks.h header file. These are not hardware based
constants
> > +    and are Linux specific.

> No, they are not Linux specific. They are part of the DT ABI.

> While it is not a requirement to base them on some h/w numbering, it is
> preferred if you can. That usually only works if you can base them on
> bit positions or register offsets.

> Rob

^ permalink raw reply

* [PATCH v3 11/13] dt-bindings: power: add PX30 SoCs header for power-domain
From: Elaine Zhang @ 2018-05-23  6:52 UTC (permalink / raw)
  To: heiko, robh+dt, mark.rutland
  Cc: devicetree, rjw, khilman, ulf.hansson, linux-pm, linux-arm-kernel,
	linux-rockchip, linux-kernel, wxt, xxx, xf, huangtao, Finley Xiao,
	Elaine Zhang
In-Reply-To: <1527058129-10260-1-git-send-email-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao@rock-chips.com>

According to a description from TRM, add all the power domains.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 include/dt-bindings/power/px30-power.h | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 include/dt-bindings/power/px30-power.h

diff --git a/include/dt-bindings/power/px30-power.h b/include/dt-bindings/power/px30-power.h
new file mode 100644
index 000000000000..30917a99ad20
--- /dev/null
+++ b/include/dt-bindings/power/px30-power.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__
+#define __DT_BINDINGS_POWER_PX30_POWER_H__
+
+/* VD_CORE */
+#define PX30_PD_A35_0		0
+#define PX30_PD_A35_1		1
+#define PX30_PD_A35_2		2
+#define PX30_PD_A35_3		3
+#define PX30_PD_SCU		4
+
+/* VD_LOGIC */
+#define PX30_PD_USB		5
+#define PX30_PD_DDR		6
+#define PX30_PD_SDCARD		7
+#define PX30_PD_CRYPTO		8
+#define PX30_PD_GMAC		9
+#define PX30_PD_MMC_NAND	10
+#define PX30_PD_VPU		11
+#define PX30_PD_VO		12
+#define PX30_PD_VI		13
+#define PX30_PD_GPU		14
+
+/* VD_PMU */
+#define PX30_PD_PMU		15
+
+#endif
-- 
1.9.1

^ permalink raw reply related

* RE: [PATCH/RFC v4 2/4] usb: gadget: udc: renesas_usb3: Add register of usb role switch
From: Yoshihiro Shimoda @ 2018-05-23  6:52 UTC (permalink / raw)
  To: Rob Herring
  Cc: gregkh@linuxfoundation.org, mark.rutland@arm.com,
	heikki.krogerus@linux.intel.com, hdegoede@redhat.com,
	andy.shevchenko@gmail.com, linux-usb@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <20180522171302.GA21363@rob-hp-laptop>

Hi Rob,

Thank you for the review!

> From: Rob Herring, Sent: Wednesday, May 23, 2018 2:13 AM
> 
> On Tue, May 22, 2018 at 09:01:07PM +0900, Yoshihiro Shimoda wrote:
> > This patch adds role switch support for R-Car SoCs into the USB 3.0
> > peripheral driver. Some R-Car SoCs (e.g. R-Car H3) have USB 3.0
> > dual-role device controller which has the USB 3.0 xHCI host and
> > Renesas USB 3.0 peripheral.
> >
> > Unfortunately, the mode change register contains the USB 3.0 peripheral
> > controller side only. So, the USB 3.0 peripheral driver (renesas_usb3)
> > manages this register now. However, in peripheral mode, the host
> > should stop. Also the host hardware needs to reinitialize its own
> > registers when the mode changes from peripheral to host mode.
> > Otherwise, the host cannot work correctly (e.g. detect a device as
> > high-speed).
> >
> > To achieve this by a driver, this role switch driver manages
> > the mode change register and attach/release the xhci-plat driver.
> >
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> > ---
> >  .../devicetree/bindings/usb/renesas_usb3.txt       | 15 ++++
> 
> Please split bindings to a separate patch.

Oops. I got it.

> >  drivers/usb/gadget/udc/Kconfig                     |  1 +
> >  drivers/usb/gadget/udc/renesas_usb3.c              | 82 ++++++++++++++++++++++
> >  3 files changed, 98 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/usb/renesas_usb3.txt
> b/Documentation/devicetree/bindings/usb/renesas_usb3.txt
> > index 2c071bb5..f6105aa 100644
> > --- a/Documentation/devicetree/bindings/usb/renesas_usb3.txt
> > +++ b/Documentation/devicetree/bindings/usb/renesas_usb3.txt
> > @@ -19,6 +19,9 @@ Required properties:
> >  Optional properties:
> >    - phys: phandle + phy specifier pair
> >    - phy-names: must be "usb"
> > +  - The connection to a usb3.0 host node needs by using OF graph bindings for
> > +    usb role switch.
> > +   - port@0 = USB3.0 host port.
> 
> On the host side, this might conflict with the USB connector binding.
> 
> I would either make sure this can work with the connector binding by
> having 2 endpoints on the HS or SS port or just use the 'companion'
> property defined in usb-generic.txt.

I don't understand the first one now... This means the renesas_usb3 should follow
USB connector binding and have 2 endpoints for the usb role switch to avoid
the conflict like below?
 - port1@0: Super Speed (SS), present in SS capable connectors (from usb-connector.txt).
 - port1@1: USB3.0 host port.

About the 'companion' in usb-generic.txt, the property intends to be used for EHCI or host side
like the commit log [1]. If there is accept to use 'companion' for this patch, I think it will
be simple to achieve this role switch feature. However, in last month, I submitted a similar patch [2]
that has "renesas,host" property, but I got reply from Andy [3] and Heikki [4]. So, I'm
trying to improve the device connection framework [5] now.

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/Documentation/devicetree/bindings/usb/generic.txt?h=v4.17-rc6&id=5095cb89c62acc78b4cfaeb9a4072979d010510a

[2]
https://www.spinics.net/lists/linux-usb/msg167773.html

[3]
https://www.spinics.net/lists/linux-usb/msg167780.html

[4]
https://www.spinics.net/lists/linux-usb/msg167806.html

[5]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/driver-api/device_connection.rst

Best regards,
Yoshihiro Shimoda

> Rob

^ permalink raw reply

* [PATCH v3 10/13] soc: rockchip: power-domain: add power domain support for rk3228
From: Elaine Zhang @ 2018-05-23  6:52 UTC (permalink / raw)
  To: heiko, robh+dt, mark.rutland
  Cc: devicetree, rjw, khilman, ulf.hansson, linux-pm, linux-arm-kernel,
	linux-rockchip, linux-kernel, wxt, xxx, xf, huangtao,
	Elaine Zhang
In-Reply-To: <1527058129-10260-1-git-send-email-zhangqing@rock-chips.com>

This driver is modified to support RK3228 SoC.

Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 drivers/soc/rockchip/pm_domains.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index 99a2dd8a7801..90dcd5e21ae6 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -20,6 +20,7 @@
 #include <linux/mfd/syscon.h>
 #include <dt-bindings/power/rk3036-power.h>
 #include <dt-bindings/power/rk3128-power.h>
+#include <dt-bindings/power/rk3228-power.h>
 #include <dt-bindings/power/rk3288-power.h>
 #include <dt-bindings/power/rk3328-power.h>
 #include <dt-bindings/power/rk3366-power.h>
@@ -729,6 +730,20 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
 	[RK3128_PD_GPU]		= DOMAIN_RK3288(1, 1, 3, false),
 };
 
+static const struct rockchip_domain_info rk3228_pm_domains[] = {
+	[RK3228_PD_CORE]	= DOMAIN_RK3036(0, 0, 16, true),
+	[RK3228_PD_MSCH]	= DOMAIN_RK3036(1, 1, 17, true),
+	[RK3228_PD_BUS]		= DOMAIN_RK3036(2, 2, 18, true),
+	[RK3228_PD_SYS]		= DOMAIN_RK3036(3, 3, 19, true),
+	[RK3228_PD_VIO]		= DOMAIN_RK3036(4, 4, 20, false),
+	[RK3228_PD_VOP]		= DOMAIN_RK3036(5, 5, 21, false),
+	[RK3228_PD_VPU]		= DOMAIN_RK3036(6, 6, 22, false),
+	[RK3228_PD_RKVDEC]	= DOMAIN_RK3036(7, 7, 23, false),
+	[RK3228_PD_GPU]		= DOMAIN_RK3036(8, 8, 24, false),
+	[RK3228_PD_PERI]	= DOMAIN_RK3036(9, 9, 25, true),
+	[RK3228_PD_GMAC]	= DOMAIN_RK3036(10, 10, 26, false),
+};
+
 static const struct rockchip_domain_info rk3288_pm_domains[] = {
 	[RK3288_PD_VIO]		= DOMAIN_RK3288(7, 7, 4, false),
 	[RK3288_PD_HEVC]	= DOMAIN_RK3288(14, 10, 9, false),
@@ -816,6 +831,15 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
 	.domain_info = rk3128_pm_domains,
 };
 
+static const struct rockchip_pmu_info rk3228_pmu = {
+	.req_offset = 0x40c,
+	.idle_offset = 0x488,
+	.ack_offset = 0x488,
+
+	.num_domains = ARRAY_SIZE(rk3228_pm_domains),
+	.domain_info = rk3228_pm_domains,
+};
+
 static const struct rockchip_pmu_info rk3288_pmu = {
 	.pwr_offset = 0x08,
 	.status_offset = 0x0c,
@@ -899,6 +923,10 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
 		.data = (void *)&rk3128_pmu,
 	},
 	{
+		.compatible = "rockchip,rk3228-power-controller",
+		.data = (void *)&rk3228_pmu,
+	},
+	{
 		.compatible = "rockchip,rk3288-power-controller",
 		.data = (void *)&rk3288_pmu,
 	},
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 09/13] dt-bindings: add binding for rk3228 power domains
From: Elaine Zhang @ 2018-05-23  6:51 UTC (permalink / raw)
  To: heiko, robh+dt, mark.rutland
  Cc: devicetree, rjw, khilman, ulf.hansson, linux-pm, linux-arm-kernel,
	linux-rockchip, linux-kernel, wxt, xxx, xf, huangtao,
	Elaine Zhang
In-Reply-To: <1527058129-10260-1-git-send-email-zhangqing@rock-chips.com>

Add binding documentation for the power domains
found on Rockchip RK3228 SoCs.

Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/soc/rockchip/power_domain.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
index 9a3f5fd36a80..affe36dcfa17 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
+++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
@@ -7,6 +7,7 @@ Required properties for power domain controller:
 - compatible: Should be one of the following.
 	"rockchip,rk3036-power-controller" - for RK3036 SoCs.
 	"rockchip,rk3128-power-controller" - for RK3128 SoCs.
+	"rockchip,rk3228-power-controller" - for RK3228 SoCs.
 	"rockchip,rk3288-power-controller" - for RK3288 SoCs.
 	"rockchip,rk3328-power-controller" - for RK3328 SoCs.
 	"rockchip,rk3366-power-controller" - for RK3366 SoCs.
@@ -21,6 +22,7 @@ Required properties for power domain sub nodes:
 - reg: index of the power domain, should use macros in:
 	"include/dt-bindings/power/rk3036-power.h" - for RK3036 type power domain.
 	"include/dt-bindings/power/rk3128-power.h" - for RK3128 type power domain.
+	"include/dt-bindings/power/rk3228-power.h" - for RK3228 type power domain.
 	"include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
 	"include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain.
 	"include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain.
@@ -99,6 +101,7 @@ power domain to use.
 The index should use macros in:
 	"include/dt-bindings/power/rk3036-power.h" - for rk3036 type power domain.
 	"include/dt-bindings/power/rk3128-power.h" - for rk3128 type power domain.
+	"include/dt-bindings/power/rk3128-power.h" - for rk3228 type power domain.
 	"include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain.
 	"include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain.
 	"include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain.
-- 
1.9.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox