Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/4] dt-bindings: rtc: update stm32-rtc documentation for st,syscfg property
From: Alexandre Torgue @ 2018-05-04  7:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180503205351.GE10960@piout.net>

Hi Alexandre,

On 05/03/2018 10:53 PM, Alexandre Belloni wrote:
> Amelie,
> 
> On 26/04/2018 21:58:03-0500, Rob Herring wrote:
>> On Thu, Apr 19, 2018 at 03:21:42PM +0200, Amelie Delaunay wrote:
>>> RTC driver should not be aware of the PWR registers offset and bits
>>> position. Furthermore, we can imagine that Disable Backup Protection (DBP)
>>> relative register and bit mask could change depending on the SoC. So this
>>> patch moves st,syscfg property from single pwrcfg phandle to pwrcfg
>>> phandle/offset/mask triplet.
>>>
>>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>>> ---
>>>   Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt | 10 ++++++----
>>>   1 file changed, 6 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>>> index a66692a..00f8b5d 100644
>>> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>>> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>>> @@ -14,8 +14,10 @@ Required properties:
>>>       It is required only on stm32h7.
>>>   - interrupt-parent: phandle for the interrupt controller.
>>>   - interrupts: rtc alarm interrupt.
>>> -- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
>>> -  (RTC registers) write protection.
>>> +- st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
>>> +  access control register at offset, and change the dbp (Disable Backup
>>> +  Protection) bit represented by the mask, mandatory to disable/enable backup
>>> +  domain (RTC registers) write protection.
>>
>> It's fine to add this, but you are breaking compatibility in the driver
>> with existing DTBs by requiring these new fields.
>>
> 
> I'm fine with that change but I would like confirmation that this has
> been well thought. Maybe Maxime or Alexandre could give their ack.
> 

It's a good thing to remove PWR registers information from RTC driver. 
My only concern was the compatibility with old DT but we can accept it. 
Indeed, Kernel will continue to boot fine, only RTC will not probe if we 
use old DT.

Acked-by: Alexandre TORGUE <alexandre.torgue@st.com>

Regards
alex

^ permalink raw reply

* [RFC PATCH] ARM: dts: imx: replace underscore with hyphen in aliases name
From: Gary Bisson @ 2018-05-04  7:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525399128-11587-1-git-send-email-shawnguo@kernel.org>

Hi Shawn,

On Fri, May 04, 2018 at 09:58:48AM +0800, Shawn Guo wrote:
> It replaces underscore with hyphen in aliases name to fix DTC
> alias_paths warning below, which is seen with various i.MX board dts
> files when W=1 switch is on.
> 
>  Warning (alias_paths): /aliases: aliases property name must include only lowercase and '-'
> 
> Cc: Lothar Wa?mann <LW@KARO-electronics.de>
> Cc: Gary Bisson <gary.bisson@boundarydevices.com>
> Signed-off-by: Shawn Guo <shawnguo@kernel.org>
> ---
> Hi Lothar, Gary,
> 
> Per my search on kernel code, this change will not break anything on
> kernel support.  But I'm not really sure about the case of bootloaders
> running on the boards.  That's why I'm sending it as RFC.
> 
> We really want i.MX to be the first-class citizen in the community.
> After a few cycles efforts on cleaning up DTC warnings, this alias_paths
> warning is the last one we see with i.MX dts files.  We really want to
> get rid of it and make i.MX dts be DTC warning free.
> 
> So please comment whether we can merge this patch.

Yes that is fine.
Reviewed-by: Gary Bisson <gary.bisson@boundarydevices.com>

Thanks,
Gary

^ permalink raw reply

* [PATCH] ARM: multi_v7_defconfig: enable STM32 analog & timer drivers
From: Alexandre Torgue @ 2018-05-04  7:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a0maxno4S-dXoT1O5zp3NgHP2LWuGhtVoqFMMEv-tm07Q@mail.gmail.com>



On 05/04/2018 12:12 AM, Arnd Bergmann wrote:
> On Thu, May 3, 2018 at 10:05 AM, Alexandre Torgue
> <alexandre.torgue@st.com> wrote:
>> Hi Fabrice,
>>
>> On 05/02/2018 05:24 PM, Fabrice Gasnier wrote:
>>>
>>> This enables drivers for STM32 timer, low power timer and analog hardware
>>> that can be used on STM32MP1 SoC:
>>> - Timer & LP Timer MFD core, PWM, trigger & encoder drivers
>>> - IIO ADC/DAC/DFSDM
>>> - vrefbuf regu driver (voltage reference buffer).
>>>
>>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>>> ---
>>>    arch/arm/configs/multi_v7_defconfig | 10 ++++++++++
>>>    1 file changed, 10 insertions(+)
>>>
>>
>> Applied on stm32-next.
>>
>> Arnd,
>> Do you agree if I take multi_v7_defconfig related patches in my stm32 pull
>> requests ?
> 
> Yes, just make sure that all drivers that can reasonably be loadable
> modules are configured that way rather than as built-in, so a defconfig
> build doesn't become too big.

Ok. You're right, this drivers could be configured as module. We just 
need to verify impact before send it.

Regards
alex

> 
>         Arnd
> 

^ permalink raw reply

* [PATCH V5 1/6] ARM: dts: imx6sx-sabreauto: add PMIC support
From: Shawn Guo @ 2018-05-04  7:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1524725898-27974-1-git-send-email-Anson.Huang@nxp.com>

On Thu, Apr 26, 2018 at 02:58:13PM +0800, Anson Huang wrote:
> Add pfuze100 support on i.MX6SX Sabre Auto board.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> no changes since V4.
>  arch/arm/boot/dts/imx6sx-sabreauto.dts | 117 +++++++++++++++++++++++++++++++++
>  1 file changed, 117 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> index 57d1ea0..2caca934 100644
> --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts
> +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> @@ -74,6 +74,14 @@
>  
>  &iomuxc {
>  	imx6x-sabreauto {
> +

Drop this newline.

> +		pinctrl_i2c2_1: i2c2grp-1 {

The suffix "1" doesn't make any sense now.

	pinctrl_i2c2: i2c2grp {

> +			fsl,pins = <
> +				MX6SX_PAD_GPIO1_IO03__I2C2_SDA          0x4001b8b1
> +				MX6SX_PAD_GPIO1_IO02__I2C2_SCL          0x4001b8b1
> +			>;
> +		};
> +
>  		pinctrl_uart1: uart1grp {
>  			fsl,pins = <
>  				MX6SX_PAD_GPIO1_IO04__UART1_TX		0x1b0b1
> @@ -148,3 +156,112 @@
>  		};
>  	};
>  };
> +
> +&i2c2 {
> +	clock-frequency = <100000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_i2c2_1>;
> +	status = "okay";
> +
> +	pmic: pfuze100 at 08 {

Use generic name for node, and specific name for label.  Also, drop the
leading zeros in unit-address.

	pfuze100: pmic at 8 {

Shawn

> +		compatible = "fsl,pfuze100";
> +		reg = <0x08>;
> +
> +		regulators {
> +			sw1a_reg: sw1ab {
> +				regulator-min-microvolt = <300000>;
> +				regulator-max-microvolt = <1875000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +				regulator-ramp-delay = <6250>;
> +			};
> +
> +			sw1c_reg: sw1c {
> +				regulator-min-microvolt = <300000>;
> +				regulator-max-microvolt = <1875000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +				regulator-ramp-delay = <6250>;
> +			};
> +
> +			sw2_reg: sw2 {
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			sw3a_reg: sw3a {
> +				regulator-min-microvolt = <400000>;
> +				regulator-max-microvolt = <1975000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			sw3b_reg: sw3b {
> +				regulator-min-microvolt = <400000>;
> +				regulator-max-microvolt = <1975000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			sw4_reg: sw4 {
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +			};
> +
> +			swbst_reg: swbst {
> +				regulator-min-microvolt = <5000000>;
> +				regulator-max-microvolt = <5150000>;
> +			};
> +
> +			snvs_reg: vsnvs {
> +				regulator-min-microvolt = <1000000>;
> +				regulator-max-microvolt = <3000000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			vref_reg: vrefddr {
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			vgen1_reg: vgen1 {
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <1550000>;
> +				regulator-always-on;
> +			};
> +
> +			vgen2_reg: vgen2 {
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <1550000>;
> +			};
> +
> +			vgen3_reg: vgen3 {
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +			};
> +
> +			vgen4_reg: vgen4 {
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +			};
> +
> +			vgen5_reg: vgen5 {
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +			};
> +
> +			vgen6_reg: vgen6 {
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +			};
> +		};
> +	};
> +};
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH V5 2/6] ARM: dts: imx6sx-sabreauto: add max7322 IO expander support
From: Shawn Guo @ 2018-05-04  7:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1524725898-27974-2-git-send-email-Anson.Huang@nxp.com>

On Thu, Apr 26, 2018 at 02:58:14PM +0800, Anson Huang wrote:
> Add MAX7322 IO expander support.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> no changes since V4.
>  arch/arm/boot/dts/imx6sx-sabreauto.dts | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> index 2caca934..d59084f 100644
> --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts
> +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> @@ -163,6 +163,13 @@
>  	pinctrl-0 = <&pinctrl_i2c2_1>;
>  	status = "okay";
>  
> +	max7322: gpio at 68 {
> +		compatible = "maxim,max7322";
> +		reg = <0x68>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +

For child nodes having unit-address ('reg' property), sort them in order
of unit-address.

Shawn

>  	pmic: pfuze100 at 08 {
>  		compatible = "fsl,pfuze100";
>  		reg = <0x08>;
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2 09/10] ARM: dts: sun7i-a20: Add Video Engine and reserved memory nodes
From: Paul Kocialkowski @ 2018-05-04  7:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180420073908.nkcbsdxibnzkqski@flea>

Hi,

On Fri, 2018-04-20 at 09:39 +0200, Maxime Ripard wrote:
> On Thu, Apr 19, 2018 at 05:45:35PM +0200, Paul Kocialkowski wrote:
> > This adds nodes for the Video Engine and the associated reserved
> > memory
> > for the Allwinner A20. Up to 96 MiB of memory are dedicated to the
> > VPU.
> > 
> > The VPU can only map the first 256 MiB of DRAM, so the reserved
> > memory
> > pool has to be located in that area. Following Allwinner's decision
> > in
> > downstream software, the last 96 MiB of the first 256 MiB of RAM are
> > reserved for this purpose.
> > 
> > Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> > ---
> >  arch/arm/boot/dts/sun7i-a20.dtsi | 31
> > +++++++++++++++++++++++++++++++
> >  1 file changed, 31 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi
> > b/arch/arm/boot/dts/sun7i-a20.dtsi
> > index bd0cd3204273..cb6d82065dcf 100644
> > --- a/arch/arm/boot/dts/sun7i-a20.dtsi
> > +++ b/arch/arm/boot/dts/sun7i-a20.dtsi
> > @@ -163,6 +163,20 @@
> >  		reg = <0x40000000 0x80000000>;
> >  	};
> >  
> > +	reserved-memory {
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		ranges;
> > +
> > +		/* Address must be kept in the lower 256 MiBs of
> > DRAM for VE. */
> > +		ve_memory: cma at 4a000000 {
> > +			compatible = "shared-dma-pool";
> > +			reg = <0x4a000000 0x6000000>;
> > +			no-map;
> 
> I'm not sure why no-map is needed.

In fact, having no-map here would lead to reserving the area as cache-
coherent instead of contiguous and thus prevented dmabuf support.
Replacing it by "resuable" allows proper CMA reservation.

> And I guess we could use alloc-ranges to make sure the region is in
> the proper memory range, instead of hardcoding it.

As far as I could understand from the documentation, "alloc-ranges" is
used for dynamic allocation while only "reg" is used for static
allocation. We are currently going with static allocation and thus
reserve the whole 96 MiB. Is using dynamic allocation instead desirable
here?

> > +			linux,cma-default;
> > +		};
> > +	};
> > +
> >  	timer {
> >  		compatible = "arm,armv7-timer";
> >  		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
> > IRQ_TYPE_LEVEL_LOW)>,
> > @@ -451,6 +465,23 @@
> >  			};
> >  		};
> >  
> > +		ve: video-engine at 1c0e000 {
> > +			compatible = "allwinner,sun4i-a10-video-
> > engine";
> 
> We should have an A20-specific compatible here, at least, so that we
> can deal with any quirk we might find down the road.

Yes that's a very good point.

> > +			reg = <0x01c0e000 0x1000>;
> > +			memory-region = <&ve_memory>;
> 
> Since you made the CMA region the default one, you don't need to tie
> it to that device in particular (and you can drop it being mandatory
> from your binding as well).

What if another driver (or the system) claims memory from that zone and
that the reserved memory ends up not being available for the VPU
anymore?

Acccording to the reserved-memory documentation, the reusable property
(that we need for dmabuf) puts a limitation that the device driver
owning the region must be able to reclaim it back.

How does that work out if the CMA region is not tied to a driver in
particular?

> > +
> > +			clocks = <&ccu CLK_AHB_VE>, <&ccu CLK_VE>,
> > +				 <&ccu CLK_DRAM_VE>;
> > +			clock-names = "ahb", "mod", "ram";
> > +
> > +			assigned-clocks = <&ccu CLK_VE>;
> > +			assigned-clock-rates = <320000000>;
> 
> This should be set from within the driver. If it's something that you
> absolutely needed for the device to operate, you have no guarantee
> that the clock rate won't change at any point in time after the device
> probe, so that's not a proper solution.
> 
> And if it's not needed and can be adjusted depending on the
> framerate/codec/resolution, then it shouldn't be in the DT either.

Yes, that makes sense.

> Don't you also need to map the SRAM on the A20?

That's a good point, there is currently no syscon handle for A20 (and
also A13). Maybe SRAM is muxed to the VE by default so it "just works"? 

I'll investigate on this side, also keeping in mind that the actual
solution is to use the SRAM controller driver (but that won't make it to
v3).

Cheers and thanks for the review!

-- 
Paul Kocialkowski, Bootlin (formerly Free Electrons)
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/62afecee/attachment.sig>

^ permalink raw reply

* [PATCH V5 3/6] ARM: dts: imx6sx-sabreauto: add IO expander max7310 support
From: Shawn Guo @ 2018-05-04  7:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1524725898-27974-3-git-send-email-Anson.Huang@nxp.com>

On Thu, Apr 26, 2018 at 02:58:15PM +0800, Anson Huang wrote:
> i.MX6SX Sabre Auto board has two max7310 IO expander
> on I2C3 bus, add support for them.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> no changes since V4.
>  arch/arm/boot/dts/imx6sx-sabreauto.dts | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> index d59084f..812f40b 100644
> --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts
> +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> @@ -82,6 +82,13 @@
>  			>;
>  		};
>  
> +		pinctrl_i2c3_2: i2c3grp-2 {

Drop suffix number '2'.

Shawn

> +			fsl,pins = <
> +				MX6SX_PAD_KEY_ROW4__I2C3_SDA            0x4001b8b1
> +				MX6SX_PAD_KEY_COL4__I2C3_SCL            0x4001b8b1
> +			>;
> +		};
> +
>  		pinctrl_uart1: uart1grp {
>  			fsl,pins = <
>  				MX6SX_PAD_GPIO1_IO04__UART1_TX		0x1b0b1
> @@ -272,3 +279,24 @@
>  		};
>  	};
>  };
> +
> +&i2c3 {
> +	clock-frequency = <100000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_i2c3_2>;
> +	status = "okay";
> +
> +	max7310_a: gpio at 30 {
> +		compatible = "maxim,max7310";
> +		reg = <0x30>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +
> +	max7310_b: gpio at 32 {
> +		compatible = "maxim,max7310";
> +		reg = <0x32>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +};
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 1/2] arm64: dts: renesas: r8a77980: add CAN-FD support
From: Geert Uytterhoeven @ 2018-05-04  7:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f07c00b3-228c-e0d2-f7fe-38b8e9f25a4d@cogentembedded.com>

Hi Sergei,

On Fri, Apr 27, 2018 at 9:12 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Define the generic R8A77980 part of the CAN-FD device node.
>
> Based on the original (and large) patch by Vladimir Barinov.
>
> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

Thanks for your patch!

> --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77980.dtsi
> +++ renesas/arch/arm64/boot/dts/renesas/r8a77980.dtsi
=
> @@ -170,6 +177,30 @@
>                         status = "disabled";
>                 };
>
> +               canfd: can at e66c0000 {
> +                       compatible = "renesas,r8a77980-canfd",
> +                                    "renesas,rcar-gen3-canfd";
> +                       reg = <0 0xe66c0000 0 0x8000>;
> +                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
> +                                    <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&cpg CPG_MOD 914>,
> +                                <&cpg CPG_CORE R8A77980_CLK_CANFD>,
> +                                <&can_clk>;
> +                       clock-names = "fck", "canfd", "can_clk";
> +                       assigned-clocks = <&cpg CPG_CORE R8A77980_CLK_CANFD>;
> +                       assigned-clock-rates = <40000000>;
> +                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;

You forgot the resets property.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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

* [PATCH v2 08/10] dt-bindings: media: Document bindings for the Sunxi-Cedrus VPU driver
From: Paul Kocialkowski @ 2018-05-04  7:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180427030436.3ptrb2ldhtnssipj@rob-hp-laptop>

Hi,

On Thu, 2018-04-26 at 22:04 -0500, Rob Herring wrote:
> On Fri, Apr 20, 2018 at 09:22:20AM +0200, Paul Kocialkowski wrote:
> > Hi and thanks for the review,
> > 
> > On Fri, 2018-04-20 at 01:31 +0000, Tomasz Figa wrote:
> > > Hi Paul, Philipp,
> > > 
> > > On Fri, Apr 20, 2018 at 1:04 AM Philipp Zabel <p.zabel@pengutronix
> > > .de>
> > > wrote:
> > > 
> > > > Hi Paul,
> > > > On Thu, 2018-04-19 at 17:45 +0200, Paul Kocialkowski wrote:
> > > > > This adds a device-tree binding document that specifies the
> > > > > properties
> > > > > used by the Sunxi-Cedurs VPU driver, as well as examples.
> > > > > 
> > > > > Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.co
> > > > > m>
> > > > > ---
> > > > >  .../devicetree/bindings/media/sunxi-cedrus.txt     | 50
> > > 
> > > ++++++++++++++++++++++
> > > > >  1 file changed, 50 insertions(+)
> > > > >  create mode 100644
> > > 
> > > Documentation/devicetree/bindings/media/sunxi-cedrus.txt
> > > > > 
> > > > > diff --git a/Documentation/devicetree/bindings/media/sunxi-
> > > > > cedrus.txt
> > > 
> > > b/Documentation/devicetree/bindings/media/sunxi-cedrus.txt
> > > > > new file mode 100644
> > > > > index 000000000000..71ad3f9c3352
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/media/sunxi-cedrus.txt
> > > > > @@ -0,0 +1,50 @@
> > > > > +Device-tree bindings for the VPU found in Allwinner SoCs,
> > > > > referred to
> > > 
> > > as the
> > > > > +Video Engine (VE) in Allwinner literature.
> > > > > +
> > > > > +The VPU can only access the first 256 MiB of DRAM, that are
> > > > > DMA-
> > > > > mapped
> > > 
> > > starting
> > > > > +from the DRAM base. This requires specific memory allocation
> > > > > and
> > > 
> > > handling.
> > > 
> > > And no IOMMU? Brings back memories.
> > 
> > Exactly, no IOMMU so we don't have much choice but cope with that
> > hardware limitation...
> > 
> > > > > +
> > > > > +Required properties:
> > > > > +- compatible         : "allwinner,sun4i-a10-video-engine";
> > > > > +- memory-region         : DMA pool for buffers allocation;
> > > > > +- clocks             : list of clock specifiers,
> > > > > corresponding to
> > > 
> > > entries in
> > > > > +                          the clock-names property;
> > > > > +- clock-names                : should contain "ahb", "mod"
> > > > > and
> > > > > "ram"
> > > 
> > > entries;
> > > > > +- assigned-clocks       : list of clocks assigned to the VE;
> > > > > +- assigned-clocks-rates : list of clock rates for the clocks
> > > > > assigned
> > > 
> > > to the VE;
> > > > > +- resets             : phandle for reset;
> > > > > +- interrupts         : should contain VE interrupt number;
> > > > > +- reg                        : should contain register base
> > > > > and
> > > > > length
> > > 
> > > of VE.
> > > > > +
> > > > > +Example:
> > > > > +
> > > > > +reserved-memory {
> > > > > +     #address-cells = <1>;
> > > > > +     #size-cells = <1>;
> > > > > +     ranges;
> > > > > +
> > > > > +     /* Address must be kept in the lower 256 MiBs of DRAM
> > > > > for
> > > > > VE. */
> > > > > +     ve_memory: cma at 4a000000 {
> > > > > +             compatible = "shared-dma-pool";
> > > > > +             reg = <0x4a000000 0x6000000>;
> > > > > +             no-map;
> > > > > +             linux,cma-default;
> > > > > +     };
> > > > > +};
> > > > > +
> > > > > +video-engine at 1c0e000 {
> > > > 
> > > > This is not really required by any specification, and not as
> > > > common
> > > > as
> > > > gpu at ..., but could this reasonably be called "vpu at 1c0e000" to
> > > > follow
> > > > somewhat-common practice?
> > > 
> > > AFAIR the name is supposed to be somewhat readable for someone
> > > that
> > > doesn't know the hardware. To me, "video-engine" sounds more
> > > obvious
> > > than "vpu", but we actually use "codec" already, in case of MFC
> > > and
> > > JPEG codec on Exynos. If encode/decode is the only functionality
> > > of
> > > this block, I'd personally go with "codec". If it can do other
> > > things,
> > > e.g. scaling/rotation without encode/decode, I'd probably call it
> > > "video-processor".
> > 
> > I agree that the term VPU is more commonly associated with video
> > decoding, while video engine could mean a number of things.
> > 
> > The reason I went with "video-engine" here (while still presenting
> > the
> > driver as a VPU driver) is that Video Engine is the term used in
> > Allwinner's litterature. Other nodes in Allwinner device-trees
> > generally
> > stick to these terms (for instance, we have "display-engine" nodes).
> > This also makes it easier to find the matching parts in the
> > documentation.
> 
> 'video-codec' is what is defined in the DT spec.

Is that an actively-enforced guideline or a suggestion? I'd like to keep
video-engine just to stick with the technical documentation wording and
my personal taste is also to prefer vpu over video-codec (in terms of
clarity/straightforwardness) as a second choice.

Still, if the choice isn't up to me, we can go with video-codec (or
vpu).

Cheers,

-- 
Paul Kocialkowski, Bootlin (formerly Free Electrons)
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/5bbb8dfd/attachment.sig>

^ permalink raw reply

* [PATCH v2 07/10] media: platform: Add Sunxi-Cedrus VPU decoder driver
From: Paul Kocialkowski @ 2018-05-04  7:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180424091328.jsqp36nxekuj23am@paasikivi.fi.intel.com>

Hi,

On Tue, 2018-04-24 at 12:13 +0300, Sakari Ailus wrote:
> Hi Paul
> 
> On Thu, Apr 19, 2018 at 05:45:33PM +0200, Paul Kocialkowski wrote:
> > This introduces the Sunxi-Cedrus VPU driver that supports the VPU
> > found
> > in Allwinner SoCs, also known as Video Engine. It is implemented
> > through
> > a v4l2 m2m decoder device and a media device (used for media
> > requests).
> > So far, it only supports MPEG2 decoding.
> > 
> > Since this VPU is stateless, synchronization with media requests is
> > required in order to ensure consistency between frame headers that
> > contain metadata about the frame to process and the raw slice data
> > that
> > is used to generate the frame.
> > 
> > This driver was made possible thanks to the long-standing effort
> > carried out by the linux-sunxi community in the interest of reverse
> > engineering, documenting and implementing support for Allwinner VPU.
> 
> No code review yet, but DT bindings precede the driver. Please also
> add the appropriate MAINTAINERS entries.

Thanks for the indication, will do in the next version(s).

Cheers,

-- 
Paul Kocialkowski, Bootlin (formerly Free Electrons)
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/acc41e91/attachment.sig>

^ permalink raw reply

* [PATCH v2 06/10] media: v4l: Add definition for Allwinner's MB32-tiled NV12 format
From: Paul Kocialkowski @ 2018-05-04  7:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <198e991c-1052-5bfb-f397-0e7d388b3c00@xs4all.nl>

Hi,

On Fri, 2018-04-20 at 15:59 +0200, Hans Verkuil wrote:
> On 04/19/18 17:45, Paul Kocialkowski wrote:
> > This introduces support for Allwinner's MB32-tiled NV12 format,
> > where
> > each plane is divided into macroblocks of 32x32 pixels. Hence, the
> > size
> > of each plane has to be aligned to 32 bytes. The pixels inside each
> > macroblock are coded as they would be if the macroblock was a single
> > plane, line after line.
> > 
> > The MB32-tiled NV12 format is used by the video engine on Allwinner
> > platforms: it is the default format for decoded frames (and the only
> > one
> > available in the oldest supported platforms).
> > 
> > Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> > ---
> >  include/uapi/linux/videodev2.h | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/include/uapi/linux/videodev2.h
> > b/include/uapi/linux/videodev2.h
> > index 4b8336f7bcf0..43993a116e2b 100644
> > --- a/include/uapi/linux/videodev2.h
> > +++ b/include/uapi/linux/videodev2.h
> > @@ -669,6 +669,7 @@ struct v4l2_pix_format {
> >  #define V4L2_PIX_FMT_Z16      v4l2_fourcc('Z', '1', '6', ' ') /*
> > Depth data 16-bit */
> >  #define V4L2_PIX_FMT_MT21C    v4l2_fourcc('M', 'T', '2', '1') /*
> > Mediatek compressed block mode  */
> >  #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /*
> > Intel Planar Greyscale 10-bit and Depth 16-bit */
> > +#define V4L2_PIX_FMT_MB32_NV12 v4l2_fourcc('M', 'N', '1', '2') /*
> > Allwinner NV12 in 32x32 macroblocks */
> >  
> >  /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6
> > bits unused */
> >  #define V4L2_PIX_FMT_IPU3_SBGGR10	v4l2_fourcc('i', 'p', '3',
> > 'b') /* IPU3 packed 10-bit BGGR bayer */
> > 
> 
> Add an entry for this to v4l_fill_fmtdesc() in v4l2-ioctl.c.
> 
> It also needs to be documented in the spec.

Noted, I will look in that direction for the future versions.

Cheers,

-- 
Paul Kocialkowski, Bootlin (formerly Free Electrons)
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/89c68886/attachment-0001.sig>

^ permalink raw reply

* [PATCH v2 02/10] media-request: Add a request complete operation to allow m2m scheduling
From: Paul Kocialkowski @ 2018-05-04  8:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180419154124.17512-3-paul.kocialkowski@bootlin.com>

Hi,

On Thu, 2018-04-19 at 17:41 +0200, Paul Kocialkowski wrote:
> When using the request API in the context of a m2m driver, the
> operations that come with a m2m run scheduling call in their
> (m2m-specific) ioctl handler are delayed until the request is queued
> (for instance, this includes queuing buffers and streamon).
> 
> Thus, the m2m run scheduling calls are not called in due time since
> the
> request AP's internal plumbing will (rightfully) use the relevant core
> functions directly instead of the ioctl handler.
> 
> This ends up in a situation where nothing happens if there is no
> run-scheduling ioctl called after queuing the request.
> 
> In order to circumvent the issue, a new media operation is introduced,
> called at the time of handling the media request queue ioctl. It gives
> m2m drivers a chance to schedule a m2m device run at that time.
> 
> The existing req_queue operation cannot be used for this purpose,
> since
> it is called with the request queue mutex held, that is eventually
> needed
> in the device_run call to apply relevant controls.

This patch will be dropped since it's no longer useful with the latest
version of the request API.

> Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> ---
>  drivers/media/media-request.c | 3 +++
>  include/media/media-device.h  | 2 ++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/drivers/media/media-request.c b/drivers/media/media-
> request.c
> index 415f7e31019d..28ac5ccfe6a2 100644
> --- a/drivers/media/media-request.c
> +++ b/drivers/media/media-request.c
> @@ -157,6 +157,9 @@ static long media_request_ioctl_queue(struct
> media_request *req)
>  		media_request_get(req);
>  	}
>  
> +	if (mdev->ops->req_complete)
> +		mdev->ops->req_complete(req);
> +
>  	return ret;
>  }
>  
> diff --git a/include/media/media-device.h b/include/media/media-
> device.h
> index 07e323c57202..c7dcf2079cc9 100644
> --- a/include/media/media-device.h
> +++ b/include/media/media-device.h
> @@ -55,6 +55,7 @@ struct media_entity_notify {
>   * @req_alloc: Allocate a request
>   * @req_free: Free a request
>   * @req_queue: Queue a request
> + * @req_complete: Complete a request
>   */
>  struct media_device_ops {
>  	int (*link_notify)(struct media_link *link, u32 flags,
> @@ -62,6 +63,7 @@ struct media_device_ops {
>  	struct media_request *(*req_alloc)(struct media_device
> *mdev);
>  	void (*req_free)(struct media_request *req);
>  	int (*req_queue)(struct media_request *req);
> +	void (*req_complete)(struct media_request *req);
>  };
>  
>  /**
-- 
Paul Kocialkowski, Bootlin (formerly Free Electrons)
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/d4d89b15/attachment.sig>

^ permalink raw reply

* [PATCH v2 03/10] videobuf2-core: Add helper to get buffer private data from media request
From: Paul Kocialkowski @ 2018-05-04  8:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180419154124.17512-4-paul.kocialkowski@bootlin.com>

Hi,

On Thu, 2018-04-19 at 17:41 +0200, Paul Kocialkowski wrote:
> When calling media operation driver callbacks related to media
> requests,
> only a pointer to the request itself is provided, which is
> insufficient
> to retrieve the driver's context. Since the driver context is usually
> set as vb2 queue private data and given that the core can determine
> which objects attached to the request are buffers, it is possible to
> extract the associated private data for the first buffer found.
> 
> This is required in order to access the current m2m context from m2m
> drivers' private data in the context of media request operation
> callbacks. More specifically, this allows scheduling m2m device runs
> from the newly-introduced request complete operation.

This patch too will be dropped since it's no longer useful with the
latest version of the request API.

> Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> ---
>  drivers/media/common/videobuf2/videobuf2-core.c | 15 +++++++++++++++
>  include/media/videobuf2-core.h                  |  1 +
>  2 files changed, 16 insertions(+)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c
> b/drivers/media/common/videobuf2/videobuf2-core.c
> index 13c9d9e243dd..6fa46bfc620f 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -1351,6 +1351,21 @@ bool vb2_core_request_has_buffers(struct
> media_request *req)
>  }
>  EXPORT_SYMBOL_GPL(vb2_core_request_has_buffers);
>  
> +void *vb2_core_request_find_buffer_priv(struct media_request *req)
> +{
> +	struct media_request_object *obj;
> +	struct vb2_buffer *vb;
> +
> +	obj = media_request_object_find(req, &vb2_core_req_ops,
> NULL);
> +	if (!obj)
> +		return NULL;
> +
> +	vb = container_of(obj, struct vb2_buffer, req_obj);
> +
> +	return vb2_get_drv_priv(vb->vb2_queue);
> +}
> +EXPORT_SYMBOL_GPL(vb2_core_request_find_buffer_priv);
> +
>  int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index,
> void *pb,
>  			 struct media_request *req)
>  {
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-
> core.h
> index 032bd1bec555..65c0cf6afb55 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -1153,4 +1153,5 @@ int vb2_verify_memory_type(struct vb2_queue *q,
>  		enum vb2_memory memory, unsigned int type);
>  
>  bool vb2_core_request_has_buffers(struct media_request *req);
> +void *vb2_core_request_find_buffer_priv(struct media_request *req);
>  #endif /* _MEDIA_VIDEOBUF2_CORE_H */
-- 
Paul Kocialkowski, Bootlin (formerly Free Electrons)
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/0d885d22/attachment.sig>

^ permalink raw reply

* [PATCH 7/7] ARM: dts: sun7i: Add dts file for the A20-linova1-7 HMI
From: Maxime Ripard @ 2018-05-04  8:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <839d2560-0250-9b3a-8019-4e83d9e931e2@micronovasrl.com>

Hi,

On Wed, May 02, 2018 at 06:41:34PM +0200, Giulio Benetti wrote:
> > > You don't have to handcode the fragments anymore with the new syntax,
> > > and U-Boot makes it really trivial to use if you use the FIT image
> > > format to have multiple overlays bundled in the same image. You can
> > > choose to apply them dynamically, for example based on an EEPROM or
> > > some other metric to see which combination you have.
> > 
> > Ah, this is interesting. I'm going to experiment with that.
> > 
> 
> I'm struggling against this, I don't really know how to proceed,
> except keeping monolithic dts files including other dtsi files.
> 
> About dt-overlays I've tried to look around lot of time,
> but the only thing I've found is this:
> https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/tree/arch/arm/boot/dts?h=topic/renesas-overlays
> 
> where they use .dtso tagging them as "/plugin/;"
> and compile all .dtso found in dts folder.
> Then they obtain .dtbo files that should be the dt-overlays we have spoken
> about right?

Yes. You don't have to do that though, you can just rely on dtc to
compile them, outside of the linux build system.

> What I can't understand is if there's a real standard at this time to
> follow, because on renesas-driver they use their way to handle all .dtso
> files, but on mainline there seems to be nothing about that.

I'm not sure what you mean here. It's just fragments of device tree,
that have to be compiled using dtc, that's it. You can use the Linux
build system infrastructure to do that, or you can build your own
simpler one. That's really up to you. See for example
https://github.com/NextThingCo/CHIP-dt-overlays/blob/master/Makefile

(even though the overlays themselves use the legacy syntax and
shouldn't really be used an examples)

> So at the moment I'm trying to compile dts tagged as /plugin/;
> but dtc gives me a lot of warnings.
> 
> dts:
> "
> /dts-v1/;
> /plugin/;
> 
> #include <dt-bindings/gpio/gpio.h>
> #include <dt-bindings/interrupt-controller/irq.h>
> 
> &i2c2 {
> 	pinctrl-names = "default";
> 	pinctrl-0 = <&i2c2_pins_a>;
> 	status = "okay";
> 
> 	ft5x {
> 		compatible = "edt,edt-ft5306";
> 		reg = <0x38>;
> 		interrupt-parent = <&pio>;
> 		interrupts = <7 2 IRQ_TYPE_EDGE_FALLING>; /* PH2 */
> 		reset-gpios = <&pio 7 3 GPIO_ACTIVE_LOW>; /* PH3 */
> 		touchscreen-size-x = <480>;
> 		touchscreen-size-y = <272>;
> 	};
> };
> "
> 
> Build output issuing make ARCH=arm CROSS_COMPILE=arm-linux- aaa.dtb (I use
> aaa.dts as source):
> "
> arch/arm/boot/dts/aaa.dtb: Warning (reg_format):
> /fragment at 0/__overlay__/ft5x:reg: property has invalid length (4 bytes)
> (#address-cells == 2, #size-cells == 1)
> arch/arm/boot/dts/aaa.dtb: Warning (pci_device_bus_num): Failed prerequisite
> 'reg_format'
> arch/arm/boot/dts/aaa.dtb: Warning (simple_bus_reg): Failed prerequisite
> 'reg_format'
> arch/arm/boot/dts/aaa.dtb: Warning (avoid_default_addr_size):
> /fragment at 0/__overlay__/ft5x: Relying on default #address-cells value
> arch/arm/boot/dts/aaa.dtb: Warning (avoid_default_addr_size):
> /fragment at 0/__overlay__/ft5x: Relying on default #size-cells value
> "

Yeah, your i2c node doesn't have the right address-cells and
size-cells properties value, like dtc is telling you.

> Then in uboot I'm trying to do as follows:
> # fdt addr 0x43000000 (where dtb is)
> # fdt resize 8192
> # fdt apply 0x430c0000 (where dtbo is)
> But it gives me "libfdt fdt_check_header(): FDT_ERR_BADMAGIC"
> (I was expecting some error)

It looks like your overlay hasn't been properly loaded.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/149226f9/attachment.sig>

^ permalink raw reply

* [PATCH] ARM: dts: da850-lcdk: increase the size of the u-boot nand partition
From: Bartosz Golaszewski @ 2018-05-04  8:08 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Current mainline u-boot builds images that are bigger than the 0x80000
bytes u-boot partition allocated from the NAND memory. Using the free
space partition results in an unbootable system. Increase the partition
size to 0xa0000 bytes.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/boot/dts/da850-lcdk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 7de302f890d7..fc8667445892 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -336,11 +336,11 @@
 				partition at 20000 {
 					/* The LCDK defaults to booting from this partition */
 					label = "u-boot";
-					reg = <0x020000 0x080000>;
+					reg = <0x020000 0x0a0000>;
 				};
 				partition at a0000 {
 					label = "free space";
-					reg = <0x0a0000 0>;
+					reg = <0x0c0000 0>;
 				};
 			};
 		};
-- 
2.17.0

^ permalink raw reply related

* [PATCH 1/4] drm/rockchip: add transfer function for cdn-dp
From: Lin Huang @ 2018-05-04  8:08 UTC (permalink / raw)
  To: linux-arm-kernel

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>
---
 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  | 66 +++++++++++++++++++++++++++++-----
 drivers/gpu/drm/rockchip/cdn-dp-reg.h  | 14 ++++++--
 4 files changed, 119 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..268c190 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_STAUS_ACK)
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+	else if (status == AUX_STAUS_NACK)
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK;
+	else if (status == AUX_STAUS_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..b2f532a 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -221,7 +221,11 @@ 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 not send success;
+ */
+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 +251,40 @@ 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 not send success;
+ * -EINVAL is return if get the wrong data size after message send.
+ */
+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 +297,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 +310,32 @@ 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..aedf2dc 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_STAUS_ACK			0
+#define AUX_STAUS_NACK			1
+#define AUX_STAUS_DEFER			2
+#define AUX_STAUS_SINK_ERROR		3
+#define AUX_STAUS_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

* [PATCH 2/4] phy: rockchip-typec: support variable phy config value
From: Lin Huang @ 2018-05-04  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525421338-1021-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>
---
 drivers/phy/rockchip/phy-rockchip-typec.c | 286 +++++++++++++++++++-----------
 include/soc/rockchip/rockchip_phy_typec.h |  72 ++++++++
 2 files changed, 259 insertions(+), 99 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..831a93b 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)
@@ -323,23 +324,31 @@
  * 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
+#define PHY_MODE_SET_TIMEOUT		1000000
 
 #define PIN_ASSIGN_C_E			0x51d9
 #define PIN_ASSIGN_D_F			0x5100
@@ -349,51 +358,7 @@
 #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;
-};
+#define DEFAULT_RATE			162000
 
 struct phy_reg {
 	u16 value;
@@ -417,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 },
@@ -436,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,
@@ -484,7 +492,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);
 }
 
@@ -498,17 +506,44 @@ 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 162000:
+		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;
+	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 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;
+	}
+
+	clk_ctrl |= DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE;
+	writel(clk_ctrl, tcphy->base + DP_CLK_CTL);
 
-	/* set the default mode to RBR */
-	writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR,
-	       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)
@@ -535,9 +570,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));
@@ -545,25 +581,31 @@ 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 162000:
+	case 270000:
+		val |= (6 << 12);
+		break;
+	case 540000:
+		val |= (4 << 12);
+		break;
+	}
+	writel(val, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
 }
 
 static inline int property_enable(struct rockchip_typec_phy *tcphy,
@@ -754,30 +796,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, DEFAULT_RATE);
 		for (i = 0; i < 4; i++)
-			tcphy_dp_cfg_lane(tcphy, i);
+			tcphy_dp_cfg_lane(tcphy, 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, 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, DEFAULT_RATE, 0, 0, 0);
+			tcphy_dp_cfg_lane(tcphy, 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, DEFAULT_RATE, 0, 0, 2);
+			tcphy_dp_cfg_lane(tcphy, 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);
 
@@ -990,7 +1035,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");
@@ -999,13 +1044,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;
 	}
@@ -1023,6 +1074,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);
 
@@ -1031,7 +1083,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);
@@ -1047,6 +1102,30 @@ static const struct phy_ops rockchip_dp_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static int type_c_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)
 {
@@ -1087,6 +1166,14 @@ static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
 		return PTR_ERR(tcphy->tcphy_rst);
 	}
 
+	/*
+	 * check if phy_config pass from dts, if yes,
+	 * need to use this phy config to do software training later
+	 */
+	if (!of_property_read_u32_array(dev->of_node, "rockchip,phy_config",
+		(u32 *)tcphy->config, sizeof(tcphy->config) / sizeof(u32)))
+		tcphy->need_software_training = 1;
+
 	return 0;
 }
 
@@ -1171,6 +1258,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		}
 	}
 
+	tcphy->typec_phy_config = type_c_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
new file mode 100644
index 0000000..e25840e
--- /dev/null
+++ b/include/soc/rockchip/rockchip_phy_typec.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang <hl@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+#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 phy_config {
+	int swing;
+	int pe;
+};
+
+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;
+	struct rockchip_usb3phy_port_cfg *port_cfgs;
+	/* mutex to protect access to individual PHYs */
+	struct mutex lock;
+	struct phy_config config[3][4];
+	u8 need_software_training;
+	bool flip;
+	u8 mode;
+	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 3/4] Documentation: bindings: add phy_config for Rockchip USB Type-C PHY
From: Lin Huang @ 2018-05-04  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525421338-1021-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>
---
 Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt | 4 +++-
 1 file changed, 3 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..eda26dd 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
@@ -17,7 +17,9 @@ Required properties:
 
 Optional properties:
  - extcon : extcon specifier for the Power Delivery
-
+ - rockchip,phy_config : That's phy voltage swing and pre_emphasis
+			 setting, if want to do dp training outside
+			 dp firmware, need to add these value.
 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:
-- 
2.7.4

^ permalink raw reply related

* [PATCH 4/4] drm/rockchip: support dp training outside dp firmware
From: Lin Huang @ 2018-05-04  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525421338-1021-1-git-send-email-hl@rock-chips.com>

DP firware use fix phy config value to do training, but some
board need to adjust these value to fit for their hardware design,
so we use new phy config to do training outside firmware to meet
this situation, if there have new phy config pass from dts, it will
use training outside firmware.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
 drivers/gpu/drm/rockchip/Makefile               |   3 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c          |  23 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.h          |   2 +
 drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 398 ++++++++++++++++++++++++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c           |  33 +-
 drivers/gpu/drm/rockchip/cdn-dp-reg.h           |  38 ++-
 6 files changed, 480 insertions(+), 17 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 268c190..a2a4208 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->sw_training_success == false) {
+		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,14 @@ 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->sw_training_success == false) {
+		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..c6050ab 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 sw_training_success;
 
 	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..558c945
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,398 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#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"
+
+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, link_config[2];
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	u32 voltage_tries, max_vswing_tries;
+	u32 rate, sink_max, source_max;
+	int 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);
+
+	/* 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);
+
+	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);
+
+	/* 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, cannot "
+				      "continue channel equalization\n");
+			break;
+		}
+
+		if (drm_dp_channel_eq_ok(link_status,  dp->link.num_lanes)) {
+			DRM_DEBUG_KMS("Channel EQ done. DP Training "
+				      "successful\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);
+}
+
+int cdn_dp_software_train_link(struct cdn_dp_device *dp)
+{
+	int ret, stop_err;
+
+	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;
+	}
+
+	ret = cdn_dp_link_training_clock_recovery(dp);
+	if (ret) {
+		DRM_ERROR("training clock recovery fail, error: %d\n", ret);
+		goto out;
+	}
+
+	ret = cdn_dp_link_training_channel_equalization(dp);
+	if (ret) {
+		DRM_ERROR("training channel equalization fail, error: %d\n",
+			  ret);
+		goto out;
+	}
+out:
+	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 b2f532a..72780f1 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];
 
@@ -605,22 +607,41 @@ static int cdn_dp_get_training_status(struct cdn_dp_device *dp)
 int cdn_dp_train_link(struct cdn_dp_device *dp)
 {
 	int ret;
+	struct cdn_dp_port *port = dp->port[dp->active_port];
+	struct rockchip_typec_phy *tcphy = phy_get_drvdata(port->phy);
 
+	/*
+	 * 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.
+	 */
+	if (tcphy->need_software_training) {
+		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;
+		}
+		cdn_dp_reg_write(dp, SOURCE_HDTX_CAR, 0xf);
+		dp->sw_training_success = true;
+		return 0;
+	}
+
+do_fw_training:
+	dp->sw_training_success = false;
 	ret = cdn_dp_training_start(dp);
 	if (ret) {
 		DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
 		return ret;
 	}
-
 	ret = cdn_dp_get_training_status(dp);
 	if (ret) {
 		DRM_DEV_ERROR(dp->dev, "Failed to get training stat %d\n", ret);
 		return ret;
 	}
-
-	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 aedf2dc..b60a6b2 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 GLOBAL_EN              (1 << 3)
+#define RG_EN                  (0 << 4)
+#define NO_VIDEO               (1 << 5)
+#define ENC_RST_DIS            (1 << 6)
+#define WR_VHSYNC_FALL         (1 << 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 v8 00/13] Support PPTT for ARM64
From: vkilari at codeaurora.org @ 2018-05-04  8:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180425233121.13270-1-jeremy.linton@arm.com>



> -----Original Message-----
> From: Jeremy Linton <jeremy.linton@arm.com>
> Sent: Thursday, April 26, 2018 5:01 AM
> To: linux-acpi at vger.kernel.org
> Cc: Sudeep.Holla at arm.com; linux-arm-kernel at lists.infradead.org;
> Lorenzo.Pieralisi at arm.com; hanjun.guo at linaro.org; rjw at rjwysocki.net;
> Will.Deacon at arm.com; Catalin.Marinas at arm.com;
> gregkh at linuxfoundation.org; Mark.Rutland at arm.com; linux-
> kernel at vger.kernel.org; linux-riscv at lists.infradead.org;
> wangxiongfeng2 at huawei.com; vkilari at codeaurora.org; ahs3 at redhat.com;
> Dietmar.Eggemann at arm.com; Morten.Rasmussen at arm.com;
> palmer at sifive.com; lenb at kernel.org; john.garry at huawei.com;
> austinwc at codeaurora.org; tnowicki at caviumnetworks.com;
> jhugo at qti.qualcomm.com; timur at qti.qualcomm.com;
> ard.biesheuvel at linaro.org; Jeremy Linton <jeremy.linton@arm.com>
> Subject: [PATCH v8 00/13] Support PPTT for ARM64
> 
> ACPI 6.2 adds the Processor Properties Topology Table (PPTT), which is
used to
> describe the processor and cache topology. Ideally it is used to
extend/override
> information provided by the hardware, but right now ARM64 is entirely
> dependent on firmware provided tables.
> 
> This patch parses the table for the cache topology and CPU topology.
> When we enable ACPI/PPTT for arm64 we map the package_id to the PPTT
> node flagged as the physical package by the firmware.
> This results in topologies that match what the remainder of the system
expects.
> Finally, we update the scheduler MC domain so that it generally reflects
the
> LLC unless the LLC is too large for the NUMA domain (or package).
> 
> For example on juno:
> [root at mammon-juno-rh topology]# lstopo-no-graphics
>   Package L#0
>     L2 L#0 (1024KB)
>       L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
>       L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1)
>       L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#2)
>       L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#3)
>     L2 L#1 (2048KB)
>       L1d L#4 (32KB) + L1i L#4 (48KB) + Core L#4 + PU L#4 (P#4)
>       L1d L#5 (32KB) + L1i L#5 (48KB) + Core L#5 + PU L#5 (P#5)
>   HostBridge L#0
>     PCIBridge
>       PCIBridge
>         PCIBridge
>           PCI 1095:3132
>             Block(Disk) L#0 "sda"
>         PCIBridge
>           PCI 1002:68f9
>             GPU L#1 "renderD128"
>             GPU L#2 "card0"
>             GPU L#3 "controlD64"
>         PCIBridge
>           PCI 11ab:4380
>             Net L#4 "enp8s0"
> 
> Git tree at:
> http://linux-arm.org/git?p=linux-jlinton.git
> branch: pptt_v8

Tested-by: Vijaya Kumar K <vkilari@codeaurora.org>

> 
> v7->v8:
> Modify the logic used to select the MC domain (the change
>   shouldn't modify the sched domains on any existing machines
>   compared to v7, only how they are built) Reduce the severity of some
parsing
> messages.
> Fix s390 link problem.
> Further checks to deal with broken PPTT tables.
> Various style tweaks, SPDX license addition, etc.
> 
> v6->v7:
> Add additional patch to use the last cache level within the NUMA
>   or socket as the MC domain. This assures the MC domain is
>   equal or smaller than the DIE.
> 
> Various formatting/etc review comments.
> 
> Rebase to 4.16rc2
> 
> v5->v6:
> Add additional patches which re-factor how the initial DT code sets
>   up the cacheinfo structure so that its not as dependent on the
>   of_node stored in that tree. Once that is done we rename it
>   for use with the ACPI code.
> 
> Additionally there were a fair number of minor name/location/etc
>   tweaks scattered about made in response to review comments.
> 
> v4->v5:
> Update the cache type from NOCACHE to UNIFIED when all the cache
>   attributes we update are valid. This fixes a problem where caches
>   which are entirely created by the PPTT don't show up in lstopo.
> 
> Give the PPTT its own firmware_node in the cache structure instead of
>   sharing it with the of_node.
> 
> Move some pieces around between patches.
> 
> (see previous cover letters for futher changes)
> 
> Jeremy Linton (13):
>   drivers: base: cacheinfo: move cache_setup_of_node()
>   drivers: base: cacheinfo: setup DT cache properties early
>   cacheinfo: rename of_node to fw_token
>   arm64/acpi: Create arch specific cpu to acpi id helper
>   ACPI/PPTT: Add Processor Properties Topology Table parsing
>   ACPI: Enable PPTT support on ARM64
>   drivers: base cacheinfo: Add support for ACPI based firmware tables
>   arm64: Add support for ACPI based firmware tables
>   ACPI/PPTT: Add topology parsing code
>   arm64: topology: rename cluster_id
>   arm64: topology: enable ACPI/PPTT based CPU topology
>   ACPI: Add PPTT to injectable table list
>   arm64: topology: divorce MC scheduling domain from core_siblings
> 
>  arch/arm64/Kconfig                |   1 +
>  arch/arm64/include/asm/acpi.h     |   4 +
>  arch/arm64/include/asm/topology.h |   6 +-
>  arch/arm64/kernel/cacheinfo.c     |  15 +-
>  arch/arm64/kernel/topology.c      | 103 +++++-
>  arch/riscv/kernel/cacheinfo.c     |   1 -
>  drivers/acpi/Kconfig              |   3 +
>  drivers/acpi/Makefile             |   1 +
>  drivers/acpi/pptt.c               | 678
> ++++++++++++++++++++++++++++++++++++++
>  drivers/acpi/tables.c             |   2 +-
>  drivers/base/cacheinfo.c          | 157 ++++-----
>  include/linux/acpi.h              |   4 +
>  include/linux/cacheinfo.h         |  18 +-
>  13 files changed, 886 insertions(+), 107 deletions(-)  create mode 100644
> drivers/acpi/pptt.c
> 
> --
> 2.13.6

^ permalink raw reply

* [PATCH v2 08/10] dt-bindings: media: Document bindings for the Sunxi-Cedrus VPU driver
From: Maxime Ripard @ 2018-05-04  8:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <ce85c790b639bf9101b8c33526bdf149070bcc03.camel@bootlin.com>

On Fri, May 04, 2018 at 09:56:20AM +0200, Paul Kocialkowski wrote:
> > > I agree that the term VPU is more commonly associated with video
> > > decoding, while video engine could mean a number of things.
> > > 
> > > The reason I went with "video-engine" here (while still presenting
> > > the
> > > driver as a VPU driver) is that Video Engine is the term used in
> > > Allwinner's litterature. Other nodes in Allwinner device-trees
> > > generally
> > > stick to these terms (for instance, we have "display-engine" nodes).
> > > This also makes it easier to find the matching parts in the
> > > documentation.
> > 
> > 'video-codec' is what is defined in the DT spec.
> 
> Is that an actively-enforced guideline or a suggestion? I'd like to keep
> video-engine just to stick with the technical documentation wording and
> my personal taste is also to prefer vpu over video-codec (in terms of
> clarity/straightforwardness) as a second choice.
> 
> Still, if the choice isn't up to me, we can go with video-codec (or
> vpu).

The unit-name is supposed to reflect the class of the device, and
nothing else. If there's already a pre-existing class name defined for
these kind of devices, then there's no point in choosing something
else.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/edc240ab/attachment.sig>

^ permalink raw reply

* [PATCH v2] tty/serial: atmel: use port->name as name in request_irq()
From: Sebastian Andrzej Siewior @ 2018-05-04  8:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <80203f75-f38e-6214-e9b6-8512c5941647@sorico.fr>

I was puzzled while looking at /proc/interrupts and random things showed
up between reboots. This occurred more often but I realised it later. The
"correct" output should be:
|38:      11861  atmel-aic5   2 Level     ttyS0

but I saw sometimes
|38:       6426  atmel-aic5   2 Level     tty1

and accounted it wrongly as correct. This is use after free and the
former example randomly got the "old" pointer which pointed to the same
content. With SLAB_FREELIST_RANDOM and HARDENED I even got
|38:       7067  atmel-aic5   2 Level     E=Started User Manager for UID 0

or other nonsense.
As it turns out the tty, pointer that is accessed in atmel_startup(), is
freed() before atmel_shutdown(). It seems to happen quite often that the
tty for ttyS0 is allocated and freed while ->shutdown is not invoked. I
don't do anything special - just a systemd boot :)

Use port->name as the IRQ name for request_irq(). This exists as long as
the driver is loaded so no use-after-free here.
For backports before v4.12 I suggest to use `"atmel_serial"' instead
`port->name' (that member was introduced in f7048b15900f ("tty: serial_core:
Add name field to uart_port struct").

Cc: stable at vger.kernel.org
Fixes: 761ed4a94582 ("tty: serial_core: convert uart_close to use tty_port_close")
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
v1?v2: - Bisected and added a Fixes tag
       - added a note for backporters to v4.9 ? v4.12 (pointed out by
	 Richard Genoud)

 drivers/tty/serial/atmel_serial.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index e287fe8f10fc..d3189816740e 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1757,7 +1757,6 @@ static int atmel_startup(struct uart_port *port)
 {
 	struct platform_device *pdev = to_platform_device(port->dev);
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-	struct tty_struct *tty = port->state->port.tty;
 	int retval;
 
 	/*
@@ -1772,8 +1771,7 @@ static int atmel_startup(struct uart_port *port)
 	 * Allocate the IRQ
 	 */
 	retval = request_irq(port->irq, atmel_interrupt,
-			IRQF_SHARED | IRQF_COND_SUSPEND,
-			tty ? tty->name : "atmel_serial", port);
+			     IRQF_SHARED | IRQF_COND_SUSPEND, port->name, port);
 	if (retval) {
 		dev_err(port->dev, "atmel_startup - Can't get irq\n");
 		return retval;
-- 
2.17.0

^ permalink raw reply related

* [RFC PATCH] ARM: dts: imx: replace underscore with hyphen in aliases name
From: Shawn Guo @ 2018-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180504085248.532c8a47@karo-electronics.de>

On Fri, May 04, 2018 at 08:52:48AM +0200, Lothar Wa?mann wrote:
> Hi,
> 
> On Fri,  4 May 2018 09:58:48 +0800 Shawn Guo wrote:
> > It replaces underscore with hyphen in aliases name to fix DTC
> > alias_paths warning below, which is seen with various i.MX board dts
> > files when W=1 switch is on.
> > 
> >  Warning (alias_paths): /aliases: aliases property name must include only lowercase and '-'
> > 
> > Cc: Lothar Wa?mann <LW@KARO-electronics.de>
> > Cc: Gary Bisson <gary.bisson@boundarydevices.com>
> > Signed-off-by: Shawn Guo <shawnguo@kernel.org>
> > ---
> > Hi Lothar, Gary,
> > 
> > Per my search on kernel code, this change will not break anything on
> > kernel support.  But I'm not really sure about the case of bootloaders
> > running on the boards.  That's why I'm sending it as RFC.
> > 
> > We really want i.MX to be the first-class citizen in the community.
> > After a few cycles efforts on cleaning up DTC warnings, this alias_paths
> > warning is the last one we see with i.MX dts files.  We really want to
> > get rid of it and make i.MX dts be DTC warning free.
> > 
> > So please comment whether we can merge this patch.
> > 
> This breaks our U-Boot which searches for the alias names with '_'.
> But I think it's not worth keeping the old names alive, since the
> problem can easily be fixed by adding the old alias name to the FDT
> on affected boards from within U-Boot, if necessary.
> 
> Alternatively we could add a:
> 	reg_can_xcvr = "reg-can-xcvr";
> [...]
> so that the respective aliases can be resolved using both names for a
> while.

Appreciate it.

> 
> So:
> Acked-By: Lothar Wa?mann <LW@KARO-electronics.de>

Thanks, Lothar.

Shawn

^ permalink raw reply

* [PATCH v1 03/13] drm/kms/mode/exynos-dsi: using helper func drm_display_mode_to_videomode for calculating timing parameters
From: Satendra Singh Thakur @ 2018-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <00b4a624-d2b6-dc6a-71c0-9c7642480a44@arm.com>

To avoid duplicate logic for the same

Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Satendra Singh Thakur <satendra.t@samsung.com>
Acked-by: Madhur Verma <madhur.verma@samsung.com>
Cc: Hemanshu Srivastava <hemanshu.s@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 7904ffa..7fe84fd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1490,17 +1490,8 @@ static void exynos_dsi_mode_set(struct drm_encoder *encoder,
 				struct drm_display_mode *adjusted_mode)
 {
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
-	struct videomode *vm = &dsi->vm;
-	struct drm_display_mode *m = adjusted_mode;
-
-	vm->hactive = m->hdisplay;
-	vm->vactive = m->vdisplay;
-	vm->vfront_porch = m->vsync_start - m->vdisplay;
-	vm->vback_porch = m->vtotal - m->vsync_end;
-	vm->vsync_len = m->vsync_end - m->vsync_start;
-	vm->hfront_porch = m->hsync_start - m->hdisplay;
-	vm->hback_porch = m->htotal - m->hsync_end;
-	vm->hsync_len = m->hsync_end - m->hsync_start;
+
+	drm_display_mode_to_videomode(adjusted_mode, &dsi->vm);
 }
 
 static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH] ARM: dts: imx: replace underscore with hyphen in aliases name
From: Shawn Guo @ 2018-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180504074025.GA11186@g751.home>

On Fri, May 04, 2018 at 09:40:25AM +0200, Gary Bisson wrote:
> Hi Shawn,
> 
> On Fri, May 04, 2018 at 09:58:48AM +0800, Shawn Guo wrote:
> > It replaces underscore with hyphen in aliases name to fix DTC
> > alias_paths warning below, which is seen with various i.MX board dts
> > files when W=1 switch is on.
> > 
> >  Warning (alias_paths): /aliases: aliases property name must include only lowercase and '-'
> > 
> > Cc: Lothar Wa?mann <LW@KARO-electronics.de>
> > Cc: Gary Bisson <gary.bisson@boundarydevices.com>
> > Signed-off-by: Shawn Guo <shawnguo@kernel.org>
> > ---
> > Hi Lothar, Gary,
> > 
> > Per my search on kernel code, this change will not break anything on
> > kernel support.  But I'm not really sure about the case of bootloaders
> > running on the boards.  That's why I'm sending it as RFC.
> > 
> > We really want i.MX to be the first-class citizen in the community.
> > After a few cycles efforts on cleaning up DTC warnings, this alias_paths
> > warning is the last one we see with i.MX dts files.  We really want to
> > get rid of it and make i.MX dts be DTC warning free.
> > 
> > So please comment whether we can merge this patch.
> 
> Yes that is fine.
> Reviewed-by: Gary Bisson <gary.bisson@boundarydevices.com>

Thanks, Gary.

Shawn

^ permalink raw reply


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