Linux-Aspeed Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ARM: dts: aspeed: Deprecate g[45]-style compatibles
From: Andrew Jeffery @ 2019-08-01  5:45 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <9d0f2b20-e6f6-419c-a866-c4a0dd92aa63@www.fastmail.com>



On Tue, 30 Jul 2019, at 10:27, Andrew Jeffery wrote:
> 
> 
> On Tue, 30 Jul 2019, at 07:23, Linus Walleij wrote:
> > On Wed, Jul 24, 2019 at 10:13 AM Andrew Jeffery <andrew@aj.id.au> wrote:
> > 
> > > It's probably best if we push the three patches all through one tree rather
> > > than fragmenting. Is everyone happy if Joel applies them to the aspeed tree?
> > 
> > If you are sure it will not collide with parallell work in the
> > pinctrl tree, yes.
> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
> > 
> > (If it does collide I'd prefer to take the pinctrl patches and fix the
> > conflicts in my tree.)
> 
> Fair enough, I don't know the answer so I'll poke around. I don't 
> really mind
> where the series goes in, I just want to avoid landing only part of it 
> if I split it up.

Okay, it currently conflicts with my cleanup-devicetree-warnings series.

Joel, do you mind if Linus takes this series through the pinctrl tree, given
the fix to the devicetrees is patch 1/3?

Andrew

^ permalink raw reply

* [PATCH net-next v2 4/4] net: ftgmac100: Select ASPEED MDIO driver for the AST2600
From: Andrew Lunn @ 2019-08-01  3:56 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-5-andrew@aj.id.au>

On Wed, Jul 31, 2019 at 03:09:59PM +0930, Andrew Jeffery wrote:
> Ensures we can talk to a PHY via MDIO on the AST2600, as the MDIO
> controller is now separate from the MAC.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* [PATCH net-next v2 3/4] net: ftgmac100: Add support for DT phy-handle property
From: Andrew Lunn @ 2019-08-01  3:55 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-4-andrew@aj.id.au>

On Wed, Jul 31, 2019 at 03:09:58PM +0930, Andrew Jeffery wrote:
> phy-handle is necessary for the AST2600 which separates the MDIO
> controllers from the MAC.
> 
> I've tried to minimise the intrusion of supporting the AST2600 to the
> FTGMAC100 by leaving in place the existing MDIO support for the embedded
> MDIO interface. The AST2400 and AST2500 continue to be supported this
> way, as it avoids breaking/reworking existing devicetrees.
> 
> The AST2600 support by contrast requires the presence of the phy-handle
> property in the MAC devicetree node to specify the appropriate PHY to
> associate with the MAC. In the event that someone wants to specify the
> MDIO bus topology under the MAC node on an AST2400 or AST2500, the
> current auto-probe approach is done conditional on the absence of an
> "mdio" child node of the MAC.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* [PATCH net-next v2 2/4] net: phy: Add mdio-aspeed
From: Andrew Lunn @ 2019-08-01  3:53 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-3-andrew@aj.id.au>

On Wed, Jul 31, 2019 at 03:09:57PM +0930, Andrew Jeffery wrote:
> The AST2600 design separates the MDIO controllers from the MAC, which is
> where they were placed in the AST2400 and AST2500. Further, the register
> interface is reworked again, so now we have three possible different
> interface implementations, however this driver only supports the
> interface provided by the AST2600. The AST2400 and AST2500 will continue
> to be supported by the MDIO support embedded in the FTGMAC100 driver.
> 
> The hardware supports both C22 and C45 mode, but for the moment only C22
> support is implemented.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* [PATCH v2 2/2] ARM: dts: aspeed: Add Mihawk BMC platform
From: Andrew Jeffery @ 2019-08-01  3:10 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731074742.23456-1-Ben_Pai@wistron.com>

Hi Ben,

Comments inline below. Also apologies for the IBM/IPS mixup in the previous
review, I've been corrected :)

On Wed, 31 Jul 2019, at 17:17, Ben Pai wrote:
> The Mihawk BMC is an ASPEED ast2500 based BMC that is part of an
> OpenPower Power9 server.
> 
> Signed-off-by: Ben Pai <Ben_Pai@wistron.com>
> ---
>  arch/arm/boot/dts/Makefile                  |   1 +
>  arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts | 907 ++++++++++++++++++++
>  2 files changed, 908 insertions(+)
>  create mode 100755 arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index eb6de52c1936..262345544359 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1281,5 +1281,6 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>  	aspeed-bmc-opp-vesnin.dtb \
>  	aspeed-bmc-opp-witherspoon.dtb \
>  	aspeed-bmc-opp-zaius.dtb \
> +	aspeed-bmc-opp-mihawk.dtb \

This is a sorted list, please put it in the right spot.

>  	aspeed-bmc-portwell-neptune.dtb \
>  	aspeed-bmc-quanta-q71l.dtb
> diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts 
> b/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
> new file mode 100755
> index 000000000000..913c94326f3f
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
> @@ -0,0 +1,907 @@
> +/dts-v1/;
> +
> +#include "aspeed-g5.dtsi"
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +#include <dt-bindings/leds/leds-pca955x.h>
> +
> +/ {
> +	model = "Mihawk BMC";
> +	compatible = "ibm,mihawk-bmc", "aspeed,ast2500";
> +
> +
> +	chosen {
> +		stdout-path = &uart5;
> +		bootargs = "console=ttyS4,115200 earlyprintk";
> +	};
> +
> +	memory at 80000000 {
> +		reg = <0x80000000 0x20000000>; /* address and size of RAM(512MB) */
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		flash_memory: region at 98000000 {
> +			no-map;
> +			reg = <0x98000000 0x04000000>; /* 64M */
> +		};
> +
> +		gfx_memory: framebuffer {
> +			size = <0x01000000>;
> +			alignment = <0x01000000>;
> +			compatible = "shared-dma-pool";
> +			reusable;
> +		};
> +
> +		video_engine_memory: jpegbuffer {
> +			size = <0x02000000>;	/* 32MM */
> +			alignment = <0x01000000>;
> +			compatible = "shared-dma-pool";
> +			reusable;
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		air-water {
> +			label = "air-water";
> +			gpios = <&gpio ASPEED_GPIO(F, 6) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(F, 6)>;
> +		};
> +
> +		checkstop {
> +			label = "checkstop";
> +			gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(J, 2)>;
> +		};
> +
> +		ps0-presence {
> +			label = "ps0-presence";
> +			gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(Z, 2)>;
> +		};
> +
> +		ps1-presence {
> +			label = "ps1-presence";
> +			gpios = <&gpio ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(Z, 0)>;
> +		};
> +		id-button {
> +			label = "id-button";
> +			gpios = <&gpio ASPEED_GPIO(F, 1) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(F, 1)>;
> +		};
> +	};
> +
> +	gpio-keys-polled {
> +		compatible = "gpio-keys-polled";
> +		#address-cells = <1>;

Delete the #address-cells property (both it and the #size-cells properties
are not needed for the gpio-keys-polled node).

> +		poll-interval = <1000>;
> +
> +		fan0-presence {
> +			label = "fan0-presence";
> +			gpios = <&pca9552 9 GPIO_ACTIVE_LOW>;
> +			linux,code = <9>;
> +		};
> +
> +		fan1-presence {
> +			label = "fan1-presence";
> +			gpios = <&pca9552 10 GPIO_ACTIVE_LOW>;
> +			linux,code = <10>;
> +		};
> +
> +		fan2-presence {
> +			label = "fan2-presence";
> +			gpios = <&pca9552 11 GPIO_ACTIVE_LOW>;
> +			linux,code = <11>;
> +		};
> +
> +		fan3-presence {
> +			label = "fan3-presence";
> +			gpios = <&pca9552 12 GPIO_ACTIVE_LOW>;
> +			linux,code = <12>;
> +		};
> +
> +		fan4-presence {
> +			label = "fan4-presence";
> +			gpios = <&pca9552 13 GPIO_ACTIVE_LOW>;
> +			linux,code = <13>;
> +		};
> +
> +		fan5-presence {
> +			label = "fan5-presence";
> +			gpios = <&pca9552 14 GPIO_ACTIVE_LOW>;
> +			linux,code = <14>;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		fault {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		power {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 1) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		rear-id {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		rear-g {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 4) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		rear-ok {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(Y, 0) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan0 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 0 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan1 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 1 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan2 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 2 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan3 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 3 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan4 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 4 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan5 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 5 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +
> +	fsi: gpio-fsi {
> +		compatible = "fsi-master-gpio", "fsi-master";
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +		no-gpio-delays;
> +
> +		clock-gpios = <&gpio ASPEED_GPIO(E, 6) GPIO_ACTIVE_HIGH>;
> +		data-gpios = <&gpio ASPEED_GPIO(E, 7) GPIO_ACTIVE_HIGH>;
> +		mux-gpios = <&gpio ASPEED_GPIO(E, 5) GPIO_ACTIVE_HIGH>;
> +		enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
> +		trans-gpios = <&gpio ASPEED_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
> +	};
> +	iio-hwmon-12v {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 0>;
> +	};
> +	
> +	iio-hwmon-5v {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 1>;
> +	};
> +	
> +	iio-hwmon-3v {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 2>;
> +	};
> +		
> +	iio-hwmon-vdd0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 3>;
> +	};
> +	
> +	iio-hwmon-vdd1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 4>;
> +	};
> +	
> +	iio-hwmon-vcs0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 5>;
> +	};
> +	
> +	iio-hwmon-vcs1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 6>;
> +	};
> +
> +	iio-hwmon-vdn0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 7>;
> +	};
> +	
> +	iio-hwmon-vdn1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 8>;
> +	};
> +	
> +	iio-hwmon-vio0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 9>;
> +	};
> +	
> +	iio-hwmon-vio1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 10>;
> +	};
> +	
> +	iio-hwmon-vddra {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 11>;
> +	};
> +	
> +	iio-hwmon-vddrb {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 13>;
> +	};
> +	
> +	iio-hwmon-vddrc {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 14>;
> +	};
> +	
> +	iio-hwmon-vddrd {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 15>;
> +	};
> +	
> +	iio-hwmon-battery {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 12>;
> +	};
> +};
> +
> +&pwm_tacho {
> +	status = "okay";
> +	/*compatible = "aspeed,ast2500-pwm-tacho";
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	reg = <0x1e786000 0x1000>;
> +	clocks = <&pwm_tacho_fixed_clk>;*/

I missed this commented block last time? Please remove it.

> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default
> +		&pinctrl_pwm2_default &pinctrl_pwm3_default
> +		&pinctrl_pwm4_default &pinctrl_pwm5_default>;
> +
> +	fan at 0 {
> +		reg = <0x00>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x00>;
> +	};
> +
> +	fan at 1 {
> +		reg = <0x01>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x01>;
> +	};
> +
> +	fan at 2 {
> +		reg = <0x02>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x02>;
> +	};
> +
> +	fan at 3 {
> +		reg = <0x03>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x03>;
> +	};
> +
> +	fan at 4 {
> +		reg = <0x04>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x04>;
> +	};
> +
> +	fan at 5 {
> +		reg = <0x05>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x05>;
> +	};
> +
> +	fan at 6 {
> +		reg = <0x00>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x06>;
> +	};
> +
> +	fan at 7 {
> +		reg = <0x01>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x07>;
> +	};
> +
> +	fan at 8 {
> +		reg = <0x02>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x08>;
> +	};
> +
> +	fan at 9 {
> +		reg = <0x03>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x09>;
> +	};
> +
> +	fan at 10 {
> +		reg = <0x04>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x0a>;
> +	};
> +
> +	fan at 11 {
> +		reg = <0x05>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x0b>;
> +	};
> +};
> +
> +&fmc {
> +	status = "okay";
> +	flash at 0 {
> +		status = "okay";
> +		label = "bmc";
> +		m25p,fast-read;
> +		spi-max-frequency = <50000000>;
> +		partitions {
> +			#address-cells = < 1 >;
> +			#size-cells = < 1 >;
> +			compatible = "fixed-partitions";
> +			u-boot at 0 {
> +				reg = < 0 0x60000 >;
> +				label = "u-boot";
> +			};
> +			u-boot-env at 60000 {
> +				reg = < 0x60000 0x20000 >;
> +				label = "u-boot-env";
> +			};
> +			obmc-ubi at 80000 {
> +				reg = < 0x80000 0x1F80000 >;
> +				label = "obmc-ubi";
> +			};
> +		};
> +	};
> +	flash at 1 {
> +		status = "okay";
> +		label = "alt-bmc";
> +		m25p,fast-read;
> +		spi-max-frequency = <50000000>;
> +		partitions {
> +			#address-cells = < 1 >;
> +			#size-cells = < 1 >;
> +			compatible = "fixed-partitions";
> +			u-boot at 0 {
> +				reg = < 0 0x60000 >;
> +				label = "alt-u-boot";
> +			};
> +			u-boot-env at 60000 {
> +				reg = < 0x60000 0x20000 >;
> +				label = "alt-u-boot-env";
> +			};
> +			obmc-ubi at 80000 {
> +				reg = < 0x80000 0x1F80000 >;
> +				label = "alt-obmc-ubi";
> +			};
> +		};
> +	};
> +};
> +
> +&spi1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_spi1_default>;
> +
> +	flash at 0 {
> +		status = "okay";
> +		label = "pnor";
> +		m25p,fast-read;
> +		spi-max-frequency = <100000000>;
> +	};
> +};
> +
> +&lpc_ctrl {
> +	status = "okay";
> +	memory-region = <&flash_memory>;
> +	flash = <&spi1>;
> +};
> +
> +&uart1 {
> +	/* Rear RS-232 connector */
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_txd1_default
> +			&pinctrl_rxd1_default
> +			&pinctrl_nrts1_default
> +			&pinctrl_ndtr1_default
> +			&pinctrl_ndsr1_default
> +			&pinctrl_ncts1_default
> +			&pinctrl_ndcd1_default
> +			&pinctrl_nri1_default>;
> +};
> +
> +&uart2 {
> +	/* APSS */
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>;
> +};
> +
> +&uart5 {
> +	status = "okay";
> +};
> +
> +&mac0 {
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rmii1_default>;
> +	use-ncsi;
> +};
> +
> +&mac1 {
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
> +};
> +
> +&i2c0 {
> +	status = "disabled";
> +};
> +
> +&i2c1 {
> +	status = "disabled";
> +};
> +
> +&i2c2 {
> +	status = "okay";
> +
> +	/* SAMTEC P0 */
> +	/* SAMTEC P1 */
> +	
> +};
> +
> +&i2c3 {
> +	status = "okay";
> +
> +	/* APSS */
> +	/* CPLD */
> +
> +	/* PCA9516 (repeater) ->
> +	 *    CLK Buffer 9FGS9092
> +	 *    CLK Buffer 9DBL0651BKILFT
> +	 *    CLK Buffer 9DBL0651BKILFT
> +	 *    Power Supply 0
> +	 *    Power Supply 1
> +	 *    PCA 9552 LED
> +	 */
> +	 
> +	power-supply at 58 {
> +		compatible = "ibm,cffps1";
> +		reg = <0x58>;
> +	};
> +
> +	power-supply at 5b {
> +		compatible = "ibm,cffps1";
> +		reg = <0x5b>;
> +	};
> +
> +	pca9552: pca9552 at 60 {
> +		compatible = "nxp,pca9552";
> +		reg = <0x60>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		gpio at 0 {
> +			reg = <0>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 1 {
> +			reg = <1>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 2 {
> +			reg = <2>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 3 {
> +			reg = <3>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 4 {
> +			reg = <4>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 5 {
> +			reg = <5>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 6 {
> +			reg = <6>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 7 {
> +			reg = <7>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 8 {
> +			reg = <8>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 9 {
> +			reg = <9>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 10 {
> +			reg = <10>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 11 {
> +			reg = <11>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 12 {
> +			reg = <12>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 13 {
> +			reg = <13>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 14 {
> +			reg = <14>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 15 {
> +			reg = <15>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +
> +	};
> +
> +};
> +
> +&i2c4 {
> +	status = "okay";
> +
> +	/* CP0 VDD & VCS : IR35221 */
> +	/* CP0 VDN : IR35221 */
> +	/* CP0 VIO : IR38064 */
> +        /* CP0 VDDR : PXM1330 */
> +
> +	ir35221 at 70 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x70>;
> +	};
> +
> +	ir35221 at 72 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x72>;
> +	};
> +
> +};
> +
> +&i2c5 {
> +	status = "okay";
> +	
> +	/* CP0 VDD & VCS : IR35221 */
> +	/* CP0 VDN : IR35221 */
> +	/* CP0 VIO : IR38064 */
> +        /* CP0 VDDR : PXM1330 */
> +
> +	ir35221 at 70 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x70>;
> +	};
> +
> +	ir35221 at 72 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x72>;
> +	};
> +	
> +};
> +
> +&i2c6 {
> +	status = "okay";
> +	
> +	/* pca9548 -> NVMe1 to 8 */
> +	
> +	pca9548 at 70 {
> +		compatible = "nxp,pca9548";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +	};
> +	
> +};
> +
> +&i2c7 {
> +	status = "okay";
> +	
> +	/* pca9548 -> NVMe9 to 16 */
> +	
> +	pca9548 at 70 {
> +		compatible = "nxp,pca9548";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +	};
> +	
> +};
> +
> +&i2c8 {
> +	status = "okay";
> +
> +	eeprom at 50 {
> +		compatible = "atmel,24c64";
> +		reg = <0x50>;
> +	};
> +};
> +
> +&i2c9 {
> +	status = "okay";
> +	
> +	/* pca9545 Riser -> 
> +	* 	PCIe x8  Slot3 
> +	* 	PCIe x16 slot4 
> +	* 	PCIe x8  slot5 
> +	* 	I2C BMC RISER PCA9554
> +	* 	BMC SCL/SDA PCA9554 
> +	* 	PCA9554
> +	*/
> +	
> +	/* pca9545 -> 
> +	* 	PCIe x16 Slot1 
> +	* 	PCIe x8  slot2 
> +	* 	PEX8748 
> +	*/
> +
> +	pca9545riser at 70 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +
> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +	
> +	pca9545 at 71 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x71>;
> +
> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;	
> +	};
> +};
> +
> +&i2c10 {
> +	status = "okay";
> +	
> +	/* pca9545 Riser -> 
> +	* 	PCIe x8  Slot8 
> +	* 	PCIe x16 slot9 
> +	* 	PCIe x8  slot10 
> +	* 	I2C BMC RISER PCA9554
> +	* 	BMC SCL/SDA PCA9554 
> +	* 	PCA9554
> +	*/
> +	
> +	/* pca9545 -> 
> +	* 	PCIe x16 Slot1 
> +	* 	PCIe x8  slot2 
> +	* 	PEX8748 
> +	*/
> +	
> +	pca9545riser at 70 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +
> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +	
> +	pca9545 at 71 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x71>;
> +
> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;	
> +	};
> +};
> +
> +&i2c11 {
> +	status = "okay";
> +	
> +	/* TPM */
> +	/* RTC RX8900CE */
> +	/* FPGA for power sequence */
> +	/* TMP275A */
> +	/* TMP275A */
> +	/* EMC1462 */
> +
> +	tpm at 57 {
> +		compatible = "infineon,slb9645tt";
> +		reg = <0x57>;
> +	};
> +	
> +	rtc at 32 {
> +		compatible = "epson,rx8900";
> +		reg = <0x32>;
> +	};
> +	
> +	tmp275 at 48 {
> +		compatible = "ti,tmp275";
> +		reg = <0x48>;
> +	};
> +	
> +	tmp275 at 49 {
> +		compatible = "ti,tmp275";
> +		reg = <0x49>;
> +	};
> +
> +	/* chip emc1462 use emc1403 driver */
> +	emc1403 at 4c {
> +        	compatible = "smsc,emc1403";
> +        	reg = <0x4c>;
> +    	};
> +
> +};
> +
> +&i2c12 {
> +	status = "okay";
> +
> +	/* pca9545 ->
> +	*	SAS BP1
> +	*	SAS BP2
> +	*	NVMe BP
> +	*	M.2 riser
> +	*/
> +	
> +	pca9545 at 70 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		
> +		i2c at 0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +			
> +			eeprom at 50 {
> +				compatible = "atmel,24c64";
> +				reg = <0x50>;
> +			};
> +		};
> +		
> +		i2c at 1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +			
> +			eeprom at 50 {
> +				compatible = "atmel,24c64";
> +				reg = <0x50>;
> +			};
> +		};
> +		
> +		i2c at 2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +			
> +			eeprom at 50 {
> +				compatible = "atmel,24c64";
> +				reg = <0x50>;
> +			};
> +		};
> +		
> +		i2c at 3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +			
> +			tmp275 at 48 {
> +				compatible = "ti,tmp275";
> +				reg = <0x48>;
> +			};
> +		};
> +		
> +	};
> +	
> +};
> +
> +&i2c13 {
> +	status = "okay";
> +	
> +	/* pca9548 ->
> +	*	NVMe BP
> +	*	NVMe HDD17 to 24
> +	*/
> +	
> +	pca9548 at 70 {
> +		compatible = "nxp,pca9548";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +	};	
> +};
> +
> +&vuart {
> +	status = "okay";
> +};
> +
> +&gfx {
> +	status = "okay";
> +	memory-region = <&gfx_memory>;
> +};
> +
> +&adc {
> +	status = "okay";

You're still missing the pinmux properties for the ADC lines being used.
Please add them.

Cheers,

Andrew

> +};
> +
> +&wdt1 {
> +	aspeed,reset-type = "none";
> +	aspeed,external-signal;
> +	aspeed,ext-push-pull;
> +	aspeed,ext-active-high;
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_wdtrst1_default>;
> +};
> +
> +&wdt2 {
> +	aspeed,alt-boot;
> +};
> +
> +&ibt {
> +	status = "okay";
> +};
> +
> +&vhub {
> +	status = "okay";
> +};
> +
> +&video {
> +	status = "okay";
> +	memory-region = <&video_engine_memory>;
> +};
> +
> +#include "ibm-power9-dual.dtsi"
> +
> -- 
> 2.17.1
> 
> 
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------
> This email contains confidential or legally privileged information and 
> is for the sole use of its intended recipient. 
> Any unauthorized review, use, copying or distribution of this email or 
> the content of this email is strictly prohibited.
> If you are not the intended recipient, you may reply to the sender and 
> should delete this e-mail immediately.
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------
>

^ permalink raw reply

* [v7 2/2] gpio: aspeed: Add SGPIO driver
From: Andrew Jeffery @ 2019-08-01  2:59 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <1564603297-1391-3-git-send-email-hongweiz@ami.com>



On Thu, 1 Aug 2019, at 05:32, Hongwei Zhang wrote:
> Add SGPIO driver support for Aspeed AST2500 SoC.
> 
> Signed-off-by: Hongwei Zhang <hongweiz@ami.com>
> Reviewed-by:   Andrew Jeffery <andrew@aj.id.au>

Adding my Reviewed-by tag is a bit keen, I only gave it for the bindings on v6.

However, having looked over the patch you've addressed all of the issues I've
found, so you can keep it.

Andrew

> ---
>  drivers/gpio/sgpio-aspeed.c | 530 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 530 insertions(+)
>  create mode 100644 drivers/gpio/sgpio-aspeed.c
> 
> diff --git a/drivers/gpio/sgpio-aspeed.c b/drivers/gpio/sgpio-aspeed.c
> new file mode 100644
> index 0000000..752efea
> --- /dev/null
> +++ b/drivers/gpio/sgpio-aspeed.c
> @@ -0,0 +1,530 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2019 American Megatrends International LLC.
> + *
> + * Author: Karthikeyan Mani <karthikeyanm@amiindia.co.in>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/hashtable.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/string.h>
> +
> +#define MAX_NR_SGPIO			80
> +
> +#define ASPEED_SGPIO_CTRL		0x54
> +
> +#define ASPEED_SGPIO_PINS_MASK		GENMASK(9, 6)
> +#define ASPEED_SGPIO_CLK_DIV_MASK	GENMASK(31, 16)
> +#define ASPEED_SGPIO_ENABLE		BIT(0)
> +
> +struct aspeed_sgpio {
> +	struct gpio_chip chip;
> +	struct clk *pclk;
> +	spinlock_t lock;
> +	void __iomem *base;
> +	uint32_t dir_in[3];
> +	int irq;
> +};
> +
> +struct aspeed_sgpio_bank {
> +	uint16_t    val_regs;
> +	uint16_t    rdata_reg;
> +	uint16_t    irq_regs;
> +	const char  names[4][3];
> +};
> +
> +/*
> + * Note: The "value" register returns the input value when the GPIO is
> + *	 configured as an input.
> + *
> + *	 The "rdata" register returns the output value when the GPIO is
> + *	 configured as an output.
> + */
> +static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = {
> +	{
> +		.val_regs = 0x0000,
> +		.rdata_reg = 0x0070,
> +		.irq_regs = 0x0004,
> +		.names = { "A", "B", "C", "D" },
> +	},
> +	{
> +		.val_regs = 0x001C,
> +		.rdata_reg = 0x0074,
> +		.irq_regs = 0x0020,
> +		.names = { "E", "F", "G", "H" },
> +	},
> +	{
> +		.val_regs = 0x0038,
> +		.rdata_reg = 0x0078,
> +		.irq_regs = 0x003C,
> +		.names = { "I", "J" },
> +	},
> +};
> +
> +enum aspeed_sgpio_reg {
> +	reg_val,
> +	reg_rdata,
> +	reg_irq_enable,
> +	reg_irq_type0,
> +	reg_irq_type1,
> +	reg_irq_type2,
> +	reg_irq_status,
> +};
> +
> +#define GPIO_VAL_VALUE      0x00
> +#define GPIO_IRQ_ENABLE     0x00
> +#define GPIO_IRQ_TYPE0      0x04
> +#define GPIO_IRQ_TYPE1      0x08
> +#define GPIO_IRQ_TYPE2      0x0C
> +#define GPIO_IRQ_STATUS     0x10
> +
> +static void __iomem *bank_reg(struct aspeed_sgpio *gpio,
> +				     const struct aspeed_sgpio_bank *bank,
> +				     const enum aspeed_sgpio_reg reg)
> +{
> +	switch (reg) {
> +	case reg_val:
> +		return gpio->base + bank->val_regs + GPIO_VAL_VALUE;
> +	case reg_rdata:
> +		return gpio->base + bank->rdata_reg;
> +	case reg_irq_enable:
> +		return gpio->base + bank->irq_regs + GPIO_IRQ_ENABLE;
> +	case reg_irq_type0:
> +		return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE0;
> +	case reg_irq_type1:
> +		return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE1;
> +	case reg_irq_type2:
> +		return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2;
> +	case reg_irq_status:
> +		return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS;
> +	default:
> +		/* acturally if code runs to here, it's an error case */
> +		BUG_ON(1);
> +	}
> +}
> +
> +#define GPIO_BANK(x)    ((x) >> 5)
> +#define GPIO_OFFSET(x)  ((x) & 0x1f)
> +#define GPIO_BIT(x)     BIT(GPIO_OFFSET(x))
> +
> +static const struct aspeed_sgpio_bank *to_bank(unsigned int offset)
> +{
> +	unsigned int bank = GPIO_BANK(offset);
> +
> +	WARN_ON(bank >= ARRAY_SIZE(aspeed_sgpio_banks));
> +	return &aspeed_sgpio_banks[bank];
> +}
> +
> +static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
> +{
> +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> +	const struct aspeed_sgpio_bank *bank = to_bank(offset);
> +	unsigned long flags;
> +	enum aspeed_sgpio_reg reg;
> +	bool is_input;
> +	int rc = 0;
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +
> +	is_input = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
> +	reg = is_input ? reg_val : reg_rdata;
> +	rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
> +
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +
> +	return rc;
> +}
> +
> +static void __aspeed_sgpio_set(struct gpio_chip *gc, unsigned int 
> offset, int val)
> +{
> +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> +	const struct aspeed_sgpio_bank *bank = to_bank(offset);
> +	void __iomem *addr;
> +	u32 reg = 0;
> +
> +	addr = bank_reg(gpio, bank, reg_val);
> +	reg = ioread32(addr);
> +
> +	if (val)
> +		reg |= GPIO_BIT(offset);
> +	else
> +		reg &= ~GPIO_BIT(offset);
> +
> +	iowrite32(reg, addr);
> +}
> +
> +static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int 
> offset, int val)
> +{
> +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +
> +	__aspeed_sgpio_set(gc, offset, val);
> +
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +}
> +
> +static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int 
> offset)
> +{
> +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +	gpio->dir_in[GPIO_BANK(offset)] |= GPIO_BIT(offset);
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int 
> offset, int val)
> +{
> +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +
> +	gpio->dir_in[GPIO_BANK(offset)] &= ~GPIO_BIT(offset);
> +	__aspeed_sgpio_set(gc, offset, val);
> +
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int aspeed_sgpio_get_direction(struct gpio_chip *gc, unsigned 
> int offset)
> +{
> +	int dir_status;
> +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +	dir_status = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +
> +	return dir_status;
> +
> +}
> +
> +static void irqd_to_aspeed_sgpio_data(struct irq_data *d,
> +					struct aspeed_sgpio **gpio,
> +					const struct aspeed_sgpio_bank **bank,
> +					u32 *bit, int *offset)
> +{
> +	struct aspeed_sgpio *internal;
> +
> +	*offset = irqd_to_hwirq(d);
> +	internal = irq_data_get_irq_chip_data(d);
> +	WARN_ON(!internal);
> +
> +	*gpio = internal;
> +	*bank = to_bank(*offset);
> +	*bit = GPIO_BIT(*offset);
> +}
> +
> +static void aspeed_sgpio_irq_ack(struct irq_data *d)
> +{
> +	const struct aspeed_sgpio_bank *bank;
> +	struct aspeed_sgpio *gpio;
> +	unsigned long flags;
> +	void __iomem *status_addr;
> +	int offset;
> +	u32 bit;
> +
> +	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
> +
> +	status_addr = bank_reg(gpio, bank, reg_irq_status);
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +
> +	iowrite32(bit, status_addr);
> +
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +}
> +
> +static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
> +{
> +	const struct aspeed_sgpio_bank *bank;
> +	struct aspeed_sgpio *gpio;
> +	unsigned long flags;
> +	u32 reg, bit;
> +	void __iomem *addr;
> +	int offset;
> +
> +	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
> +	addr = bank_reg(gpio, bank, reg_irq_enable);
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +
> +	reg = ioread32(addr);
> +	if (set)
> +		reg |= bit;
> +	else
> +		reg &= ~bit;
> +
> +	iowrite32(reg, addr);
> +
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +}
> +
> +static void aspeed_sgpio_irq_mask(struct irq_data *d)
> +{
> +	aspeed_sgpio_irq_set_mask(d, false);
> +}
> +
> +static void aspeed_sgpio_irq_unmask(struct irq_data *d)
> +{
> +	aspeed_sgpio_irq_set_mask(d, true);
> +}
> +
> +static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
> +{
> +	u32 type0 = 0;
> +	u32 type1 = 0;
> +	u32 type2 = 0;
> +	u32 bit, reg;
> +	const struct aspeed_sgpio_bank *bank;
> +	irq_flow_handler_t handler;
> +	struct aspeed_sgpio *gpio;
> +	unsigned long flags;
> +	void __iomem *addr;
> +	int offset;
> +
> +	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
> +
> +	switch (type & IRQ_TYPE_SENSE_MASK) {
> +	case IRQ_TYPE_EDGE_BOTH:
> +		type2 |= bit;
> +		/* fall through */
> +	case IRQ_TYPE_EDGE_RISING:
> +		type0 |= bit;
> +		/* fall through */
> +	case IRQ_TYPE_EDGE_FALLING:
> +		handler = handle_edge_irq;
> +		break;
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		type0 |= bit;
> +		/* fall through */
> +	case IRQ_TYPE_LEVEL_LOW:
> +		type1 |= bit;
> +		handler = handle_level_irq;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	spin_lock_irqsave(&gpio->lock, flags);
> +
> +	addr = bank_reg(gpio, bank, reg_irq_type0);
> +	reg = ioread32(addr);
> +	reg = (reg & ~bit) | type0;
> +	iowrite32(reg, addr);
> +
> +	addr = bank_reg(gpio, bank, reg_irq_type1);
> +	reg = ioread32(addr);
> +	reg = (reg & ~bit) | type1;
> +	iowrite32(reg, addr);
> +
> +	addr = bank_reg(gpio, bank, reg_irq_type2);
> +	reg = ioread32(addr);
> +	reg = (reg & ~bit) | type2;
> +	iowrite32(reg, addr);
> +
> +	spin_unlock_irqrestore(&gpio->lock, flags);
> +
> +	irq_set_handler_locked(d, handler);
> +
> +	return 0;
> +}
> +
> +static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
> +{
> +	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
> +	struct irq_chip *ic = irq_desc_get_chip(desc);
> +	struct aspeed_sgpio *data = gpiochip_get_data(gc);
> +	unsigned int i, p, girq;
> +	unsigned long reg;
> +
> +	chained_irq_enter(ic, desc);
> +
> +	for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
> +		const struct aspeed_sgpio_bank *bank = &aspeed_sgpio_banks[i];
> +
> +		reg = ioread32(bank_reg(data, bank, reg_irq_status));
> +
> +		for_each_set_bit(p, &reg, 32) {
> +			girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
> +			generic_handle_irq(girq);
> +		}
> +
> +	}
> +
> +	chained_irq_exit(ic, desc);
> +}
> +
> +static struct irq_chip aspeed_sgpio_irqchip = {
> +	.name       = "aspeed-sgpio",
> +	.irq_ack    = aspeed_sgpio_irq_ack,
> +	.irq_mask   = aspeed_sgpio_irq_mask,
> +	.irq_unmask = aspeed_sgpio_irq_unmask,
> +	.irq_set_type   = aspeed_sgpio_set_type,
> +};
> +
> +static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio,
> +				   struct platform_device *pdev)
> +{
> +	int rc, i;
> +	const struct aspeed_sgpio_bank *bank;
> +
> +	rc = platform_get_irq(pdev, 0);
> +	if (rc < 0)
> +		return rc;
> +
> +	gpio->irq = rc;
> +
> +	/* Disable IRQ and clear Interrupt status registers for all SPGIO 
> Pins. */
> +	for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
> +		bank =  &aspeed_sgpio_banks[i];
> +		/* disable irq enable bits */
> +		iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_enable));
> +		/* clear status bits */
> +		iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_status));
> +	}
> +
> +	rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_sgpio_irqchip,
> +				  0, handle_bad_irq, IRQ_TYPE_NONE);
> +	if (rc) {
> +		dev_info(&pdev->dev, "Could not add irqchip\n");
> +		return rc;
> +	}
> +
> +	gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_sgpio_irqchip,
> +				     gpio->irq, aspeed_sgpio_irq_handler);
> +
> +	/* set IRQ settings and Enable Interrupt */
> +	for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
> +		bank = &aspeed_sgpio_banks[i];
> +		/* set falling or level-low irq */
> +		iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type0));
> +		/* trigger type is edge */
> +		iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type1));
> +		/* dual edge trigger mode. */
> +		iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type2));
> +		/* enable irq */
> +		iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_enable));
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id aspeed_sgpio_of_table[] = {
> +	{ .compatible = "aspeed,ast2400-sgpio" },
> +	{ .compatible = "aspeed,ast2500-sgpio" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, aspeed_sgpio_of_table);
> +
> +static int __init aspeed_sgpio_probe(struct platform_device *pdev)
> +{
> +	struct aspeed_sgpio *gpio;
> +	u32 nr_gpios, sgpio_freq, sgpio_clk_div;
> +	int rc;
> +	unsigned long apb_freq;
> +
> +	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
> +	if (!gpio)
> +		return -ENOMEM;
> +
> +	gpio->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(gpio->base))
> +		return PTR_ERR(gpio->base);
> +
> +	rc = of_property_read_u32(pdev->dev.of_node, "ngpios", &nr_gpios);
> +	if (rc < 0) {
> +		dev_err(&pdev->dev, "Could not read ngpios property\n");
> +		return -EINVAL;
> +	} else if (nr_gpios > MAX_NR_SGPIO) {
> +		dev_err(&pdev->dev, "Number of GPIOs exceeds the maximum of %d: 
> %d\n",
> +			MAX_NR_SGPIO, nr_gpios);
> +		return -EINVAL;
> +	}
> +
> +	rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency", 
> &sgpio_freq);
> +	if (rc < 0) {
> +		dev_err(&pdev->dev, "Could not read bus-frequency property\n");
> +		return -EINVAL;
> +	}
> +
> +	gpio->pclk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(gpio->pclk)) {
> +		dev_err(&pdev->dev, "devm_clk_get failed\n");
> +		return PTR_ERR(gpio->pclk);
> +	}
> +
> +	apb_freq = clk_get_rate(gpio->pclk);
> +
> +	/*
> +	 * From the datasheet,
> +	 *	SGPIO period = 1/PCLK * 2 * (GPIO254[31:16] + 1)
> +	 *	period = 2 * (GPIO254[31:16] + 1) / PCLK
> +	 *	frequency = 1 / (2 * (GPIO254[31:16] + 1) / PCLK)
> +	 *	frequency = PCLK / (2 * (GPIO254[31:16] + 1))
> +	 *	frequency * 2 * (GPIO254[31:16] + 1) = PCLK
> +	 *	GPIO254[31:16] = PCLK / (frequency * 2) - 1
> +	 */
> +	if (sgpio_freq == 0)
> +		return -EINVAL;
> +
> +	sgpio_clk_div = (apb_freq / (sgpio_freq * 2)) - 1;
> +
> +	if (sgpio_clk_div > (1 << 16) - 1)
> +		return -EINVAL;
> +
> +	iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) |
> +		  FIELD_PREP(ASPEED_SGPIO_PINS_MASK, (nr_gpios / 8)) |
> +		  ASPEED_SGPIO_ENABLE,
> +		  gpio->base + ASPEED_SGPIO_CTRL);
> +
> +	spin_lock_init(&gpio->lock);
> +
> +	gpio->chip.parent = &pdev->dev;
> +	gpio->chip.ngpio = nr_gpios;
> +	gpio->chip.direction_input = aspeed_sgpio_dir_in;
> +	gpio->chip.direction_output = aspeed_sgpio_dir_out;
> +	gpio->chip.get_direction = aspeed_sgpio_get_direction;
> +	gpio->chip.request = NULL;
> +	gpio->chip.free = NULL;
> +	gpio->chip.get = aspeed_sgpio_get;
> +	gpio->chip.set = aspeed_sgpio_set;
> +	gpio->chip.set_config = NULL;
> +	gpio->chip.label = dev_name(&pdev->dev);
> +	gpio->chip.base = -1;
> +
> +	/* set all SGPIO pins as input (1). */
> +	memset(gpio->dir_in, 0xff, sizeof(gpio->dir_in));
> +
> +	rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
> +	if (rc < 0)
> +		return rc;
> +
> +	return aspeed_sgpio_setup_irqs(gpio, pdev);
> +}
> +
> +static struct platform_driver aspeed_sgpio_driver = {
> +	.driver = {
> +		.name = KBUILD_MODNAME,
> +		.of_match_table = aspeed_sgpio_of_table,
> +	},
> +};
> +
> +module_platform_driver_probe(aspeed_sgpio_driver, aspeed_sgpio_probe);
> +MODULE_DESCRIPTION("Aspeed Serial GPIO Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.7.4
> 
>

^ permalink raw reply

* [v6 2/2] gpio: aspeed: Add SGPIO driver
From: Hongwei Zhang @ 2019-07-31 20:25 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <1564500268-2627-3-git-send-email-hongweiz@ami.com>

Hello Andrew,
Thanks so much for your help.

> From:	Andrew Jeffery <andrew@aj.id.au>
> Sent:	Tuesday, July 30, 2019 8:19 PM
> To:	Hongwei Zhang; Linus Walleij; linux-gpio at vger.kernel.org
> Cc:	Joel Stanley; linux-aspeed at lists.ozlabs.org; Bartosz Golaszewski; linux-kernel at vger.kernel.org; 
> linux-arm-kernel at lists.infradead.org
> Subject:	Re: [v6 2/2] gpio: aspeed: Add SGPIO driver
> 
> 
> 
> On Wed, 31 Jul 2019, at 00:55, Hongwei Zhang wrote:
> > Add SGPIO driver support for Aspeed AST2500 SoC.
> > 
> > Signed-off-by: Hongwei Zhang <hongweiz@ami.com>
> > ---
> >  drivers/gpio/sgpio-aspeed.c | 521 
> > ++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 521 insertions(+)
> >  create mode 100644 drivers/gpio/sgpio-aspeed.c
> > 
> > diff --git a/drivers/gpio/sgpio-aspeed.c b/drivers/gpio/sgpio-aspeed.c 
> > new file mode 100644 index 0000000..9a17b1a
> > --- /dev/null
> > +++ b/drivers/gpio/sgpio-aspeed.c
> > @@ -0,0 +1,521 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright 2019 American Megatrends International LLC.
> > + *
> > + * Author: Karthikeyan Mani <karthikeyanm@amiindia.co.in>  */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/clk.h>
> > +#include <linux/gpio/driver.h>
> > +#include <linux/hashtable.h>
> > +#include <linux/init.h>
> > +
> > +static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int
> > offset, int val)
> > +{
> > +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> > +	const struct aspeed_sgpio_bank *bank = to_bank(offset);
> > +	unsigned long flags;
> > +	void __iomem *addr;
> > +	u32 reg = 0;
> > +
> > +	spin_lock_irqsave(&gpio->lock, flags);
> > +
> > +	addr = bank_reg(gpio, bank, reg_val);
> > +
> > +	if (val)
> > +		reg |= GPIO_BIT(offset);
> > +	else
> > +		reg &= ~GPIO_BIT(offset);
> 
> reg is zero-initialised above and you haven't read from addr to assign to reg, so the else branch is 
> redundant (reg is already zeroed). This path has a bug - you're clearing the state of all GPIOs associated 
> with addr rather than just the GPIO associated with offset.
> 

you're correct, this is fixed in v7.

> > +
> > +	iowrite32(reg, addr);
> > +
> > +	spin_unlock_irqrestore(&gpio->lock, flags); }
> > +
> > +
> > +static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int
> > offset, int val)
> > +{
> > +	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&gpio->lock, flags);
> > +	gpio->dir_in[GPIO_BANK(offset)] &= ~GPIO_BIT(offset);
> > +	spin_unlock_irqrestore(&gpio->lock, flags);
> > +
> > +	aspeed_sgpio_set(gc, offset, val);
> 
> In this case you should probably have an unlocked variant of aspeed_sgpio_set() so you can call it inside 
> the the critical section above instead of needing to acquire/release the lock twice (once above and again 
> in aspeed_sgpio_set() as it stands).
> 

moved _sgpio_set() so only one pair of acquire/release lock used.

> Cheers,
> 
> Andrew
> 

Thanks,
--Hongwei

> > +
> > +	return 0;
> > +}
> > +
> > --
> > 2.7.4
> > 
> >

^ permalink raw reply

* [v7 2/2] gpio: aspeed: Add SGPIO driver
From: Hongwei Zhang @ 2019-07-31 20:01 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <1564603297-1391-1-git-send-email-hongweiz@ami.com>

Add SGPIO driver support for Aspeed AST2500 SoC.

Signed-off-by: Hongwei Zhang <hongweiz@ami.com>
Reviewed-by:   Andrew Jeffery <andrew@aj.id.au>
---
 drivers/gpio/sgpio-aspeed.c | 530 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 530 insertions(+)
 create mode 100644 drivers/gpio/sgpio-aspeed.c

diff --git a/drivers/gpio/sgpio-aspeed.c b/drivers/gpio/sgpio-aspeed.c
new file mode 100644
index 0000000..752efea
--- /dev/null
+++ b/drivers/gpio/sgpio-aspeed.c
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2019 American Megatrends International LLC.
+ *
+ * Author: Karthikeyan Mani <karthikeyanm@amiindia.co.in>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/gpio/driver.h>
+#include <linux/hashtable.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+#define MAX_NR_SGPIO			80
+
+#define ASPEED_SGPIO_CTRL		0x54
+
+#define ASPEED_SGPIO_PINS_MASK		GENMASK(9, 6)
+#define ASPEED_SGPIO_CLK_DIV_MASK	GENMASK(31, 16)
+#define ASPEED_SGPIO_ENABLE		BIT(0)
+
+struct aspeed_sgpio {
+	struct gpio_chip chip;
+	struct clk *pclk;
+	spinlock_t lock;
+	void __iomem *base;
+	uint32_t dir_in[3];
+	int irq;
+};
+
+struct aspeed_sgpio_bank {
+	uint16_t    val_regs;
+	uint16_t    rdata_reg;
+	uint16_t    irq_regs;
+	const char  names[4][3];
+};
+
+/*
+ * Note: The "value" register returns the input value when the GPIO is
+ *	 configured as an input.
+ *
+ *	 The "rdata" register returns the output value when the GPIO is
+ *	 configured as an output.
+ */
+static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = {
+	{
+		.val_regs = 0x0000,
+		.rdata_reg = 0x0070,
+		.irq_regs = 0x0004,
+		.names = { "A", "B", "C", "D" },
+	},
+	{
+		.val_regs = 0x001C,
+		.rdata_reg = 0x0074,
+		.irq_regs = 0x0020,
+		.names = { "E", "F", "G", "H" },
+	},
+	{
+		.val_regs = 0x0038,
+		.rdata_reg = 0x0078,
+		.irq_regs = 0x003C,
+		.names = { "I", "J" },
+	},
+};
+
+enum aspeed_sgpio_reg {
+	reg_val,
+	reg_rdata,
+	reg_irq_enable,
+	reg_irq_type0,
+	reg_irq_type1,
+	reg_irq_type2,
+	reg_irq_status,
+};
+
+#define GPIO_VAL_VALUE      0x00
+#define GPIO_IRQ_ENABLE     0x00
+#define GPIO_IRQ_TYPE0      0x04
+#define GPIO_IRQ_TYPE1      0x08
+#define GPIO_IRQ_TYPE2      0x0C
+#define GPIO_IRQ_STATUS     0x10
+
+static void __iomem *bank_reg(struct aspeed_sgpio *gpio,
+				     const struct aspeed_sgpio_bank *bank,
+				     const enum aspeed_sgpio_reg reg)
+{
+	switch (reg) {
+	case reg_val:
+		return gpio->base + bank->val_regs + GPIO_VAL_VALUE;
+	case reg_rdata:
+		return gpio->base + bank->rdata_reg;
+	case reg_irq_enable:
+		return gpio->base + bank->irq_regs + GPIO_IRQ_ENABLE;
+	case reg_irq_type0:
+		return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE0;
+	case reg_irq_type1:
+		return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE1;
+	case reg_irq_type2:
+		return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2;
+	case reg_irq_status:
+		return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS;
+	default:
+		/* acturally if code runs to here, it's an error case */
+		BUG_ON(1);
+	}
+}
+
+#define GPIO_BANK(x)    ((x) >> 5)
+#define GPIO_OFFSET(x)  ((x) & 0x1f)
+#define GPIO_BIT(x)     BIT(GPIO_OFFSET(x))
+
+static const struct aspeed_sgpio_bank *to_bank(unsigned int offset)
+{
+	unsigned int bank = GPIO_BANK(offset);
+
+	WARN_ON(bank >= ARRAY_SIZE(aspeed_sgpio_banks));
+	return &aspeed_sgpio_banks[bank];
+}
+
+static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
+{
+	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+	const struct aspeed_sgpio_bank *bank = to_bank(offset);
+	unsigned long flags;
+	enum aspeed_sgpio_reg reg;
+	bool is_input;
+	int rc = 0;
+
+	spin_lock_irqsave(&gpio->lock, flags);
+
+	is_input = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
+	reg = is_input ? reg_val : reg_rdata;
+	rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
+
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return rc;
+}
+
+static void __aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
+{
+	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+	const struct aspeed_sgpio_bank *bank = to_bank(offset);
+	void __iomem *addr;
+	u32 reg = 0;
+
+	addr = bank_reg(gpio, bank, reg_val);
+	reg = ioread32(addr);
+
+	if (val)
+		reg |= GPIO_BIT(offset);
+	else
+		reg &= ~GPIO_BIT(offset);
+
+	iowrite32(reg, addr);
+}
+
+static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
+{
+	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio->lock, flags);
+
+	__aspeed_sgpio_set(gc, offset, val);
+
+	spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
+{
+	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio->lock, flags);
+	gpio->dir_in[GPIO_BANK(offset)] |= GPIO_BIT(offset);
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return 0;
+}
+
+static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int val)
+{
+	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio->lock, flags);
+
+	gpio->dir_in[GPIO_BANK(offset)] &= ~GPIO_BIT(offset);
+	__aspeed_sgpio_set(gc, offset, val);
+
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return 0;
+}
+
+static int aspeed_sgpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+	int dir_status;
+	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio->lock, flags);
+	dir_status = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return dir_status;
+
+}
+
+static void irqd_to_aspeed_sgpio_data(struct irq_data *d,
+					struct aspeed_sgpio **gpio,
+					const struct aspeed_sgpio_bank **bank,
+					u32 *bit, int *offset)
+{
+	struct aspeed_sgpio *internal;
+
+	*offset = irqd_to_hwirq(d);
+	internal = irq_data_get_irq_chip_data(d);
+	WARN_ON(!internal);
+
+	*gpio = internal;
+	*bank = to_bank(*offset);
+	*bit = GPIO_BIT(*offset);
+}
+
+static void aspeed_sgpio_irq_ack(struct irq_data *d)
+{
+	const struct aspeed_sgpio_bank *bank;
+	struct aspeed_sgpio *gpio;
+	unsigned long flags;
+	void __iomem *status_addr;
+	int offset;
+	u32 bit;
+
+	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
+
+	status_addr = bank_reg(gpio, bank, reg_irq_status);
+
+	spin_lock_irqsave(&gpio->lock, flags);
+
+	iowrite32(bit, status_addr);
+
+	spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
+{
+	const struct aspeed_sgpio_bank *bank;
+	struct aspeed_sgpio *gpio;
+	unsigned long flags;
+	u32 reg, bit;
+	void __iomem *addr;
+	int offset;
+
+	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
+	addr = bank_reg(gpio, bank, reg_irq_enable);
+
+	spin_lock_irqsave(&gpio->lock, flags);
+
+	reg = ioread32(addr);
+	if (set)
+		reg |= bit;
+	else
+		reg &= ~bit;
+
+	iowrite32(reg, addr);
+
+	spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static void aspeed_sgpio_irq_mask(struct irq_data *d)
+{
+	aspeed_sgpio_irq_set_mask(d, false);
+}
+
+static void aspeed_sgpio_irq_unmask(struct irq_data *d)
+{
+	aspeed_sgpio_irq_set_mask(d, true);
+}
+
+static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
+{
+	u32 type0 = 0;
+	u32 type1 = 0;
+	u32 type2 = 0;
+	u32 bit, reg;
+	const struct aspeed_sgpio_bank *bank;
+	irq_flow_handler_t handler;
+	struct aspeed_sgpio *gpio;
+	unsigned long flags;
+	void __iomem *addr;
+	int offset;
+
+	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
+
+	switch (type & IRQ_TYPE_SENSE_MASK) {
+	case IRQ_TYPE_EDGE_BOTH:
+		type2 |= bit;
+		/* fall through */
+	case IRQ_TYPE_EDGE_RISING:
+		type0 |= bit;
+		/* fall through */
+	case IRQ_TYPE_EDGE_FALLING:
+		handler = handle_edge_irq;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		type0 |= bit;
+		/* fall through */
+	case IRQ_TYPE_LEVEL_LOW:
+		type1 |= bit;
+		handler = handle_level_irq;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&gpio->lock, flags);
+
+	addr = bank_reg(gpio, bank, reg_irq_type0);
+	reg = ioread32(addr);
+	reg = (reg & ~bit) | type0;
+	iowrite32(reg, addr);
+
+	addr = bank_reg(gpio, bank, reg_irq_type1);
+	reg = ioread32(addr);
+	reg = (reg & ~bit) | type1;
+	iowrite32(reg, addr);
+
+	addr = bank_reg(gpio, bank, reg_irq_type2);
+	reg = ioread32(addr);
+	reg = (reg & ~bit) | type2;
+	iowrite32(reg, addr);
+
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	irq_set_handler_locked(d, handler);
+
+	return 0;
+}
+
+static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
+{
+	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+	struct irq_chip *ic = irq_desc_get_chip(desc);
+	struct aspeed_sgpio *data = gpiochip_get_data(gc);
+	unsigned int i, p, girq;
+	unsigned long reg;
+
+	chained_irq_enter(ic, desc);
+
+	for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
+		const struct aspeed_sgpio_bank *bank = &aspeed_sgpio_banks[i];
+
+		reg = ioread32(bank_reg(data, bank, reg_irq_status));
+
+		for_each_set_bit(p, &reg, 32) {
+			girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
+			generic_handle_irq(girq);
+		}
+
+	}
+
+	chained_irq_exit(ic, desc);
+}
+
+static struct irq_chip aspeed_sgpio_irqchip = {
+	.name       = "aspeed-sgpio",
+	.irq_ack    = aspeed_sgpio_irq_ack,
+	.irq_mask   = aspeed_sgpio_irq_mask,
+	.irq_unmask = aspeed_sgpio_irq_unmask,
+	.irq_set_type   = aspeed_sgpio_set_type,
+};
+
+static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio,
+				   struct platform_device *pdev)
+{
+	int rc, i;
+	const struct aspeed_sgpio_bank *bank;
+
+	rc = platform_get_irq(pdev, 0);
+	if (rc < 0)
+		return rc;
+
+	gpio->irq = rc;
+
+	/* Disable IRQ and clear Interrupt status registers for all SPGIO Pins. */
+	for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
+		bank =  &aspeed_sgpio_banks[i];
+		/* disable irq enable bits */
+		iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_enable));
+		/* clear status bits */
+		iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_status));
+	}
+
+	rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_sgpio_irqchip,
+				  0, handle_bad_irq, IRQ_TYPE_NONE);
+	if (rc) {
+		dev_info(&pdev->dev, "Could not add irqchip\n");
+		return rc;
+	}
+
+	gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_sgpio_irqchip,
+				     gpio->irq, aspeed_sgpio_irq_handler);
+
+	/* set IRQ settings and Enable Interrupt */
+	for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
+		bank = &aspeed_sgpio_banks[i];
+		/* set falling or level-low irq */
+		iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type0));
+		/* trigger type is edge */
+		iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type1));
+		/* dual edge trigger mode. */
+		iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type2));
+		/* enable irq */
+		iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_enable));
+	}
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_sgpio_of_table[] = {
+	{ .compatible = "aspeed,ast2400-sgpio" },
+	{ .compatible = "aspeed,ast2500-sgpio" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, aspeed_sgpio_of_table);
+
+static int __init aspeed_sgpio_probe(struct platform_device *pdev)
+{
+	struct aspeed_sgpio *gpio;
+	u32 nr_gpios, sgpio_freq, sgpio_clk_div;
+	int rc;
+	unsigned long apb_freq;
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+	if (!gpio)
+		return -ENOMEM;
+
+	gpio->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(gpio->base))
+		return PTR_ERR(gpio->base);
+
+	rc = of_property_read_u32(pdev->dev.of_node, "ngpios", &nr_gpios);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "Could not read ngpios property\n");
+		return -EINVAL;
+	} else if (nr_gpios > MAX_NR_SGPIO) {
+		dev_err(&pdev->dev, "Number of GPIOs exceeds the maximum of %d: %d\n",
+			MAX_NR_SGPIO, nr_gpios);
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency", &sgpio_freq);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "Could not read bus-frequency property\n");
+		return -EINVAL;
+	}
+
+	gpio->pclk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(gpio->pclk)) {
+		dev_err(&pdev->dev, "devm_clk_get failed\n");
+		return PTR_ERR(gpio->pclk);
+	}
+
+	apb_freq = clk_get_rate(gpio->pclk);
+
+	/*
+	 * From the datasheet,
+	 *	SGPIO period = 1/PCLK * 2 * (GPIO254[31:16] + 1)
+	 *	period = 2 * (GPIO254[31:16] + 1) / PCLK
+	 *	frequency = 1 / (2 * (GPIO254[31:16] + 1) / PCLK)
+	 *	frequency = PCLK / (2 * (GPIO254[31:16] + 1))
+	 *	frequency * 2 * (GPIO254[31:16] + 1) = PCLK
+	 *	GPIO254[31:16] = PCLK / (frequency * 2) - 1
+	 */
+	if (sgpio_freq == 0)
+		return -EINVAL;
+
+	sgpio_clk_div = (apb_freq / (sgpio_freq * 2)) - 1;
+
+	if (sgpio_clk_div > (1 << 16) - 1)
+		return -EINVAL;
+
+	iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) |
+		  FIELD_PREP(ASPEED_SGPIO_PINS_MASK, (nr_gpios / 8)) |
+		  ASPEED_SGPIO_ENABLE,
+		  gpio->base + ASPEED_SGPIO_CTRL);
+
+	spin_lock_init(&gpio->lock);
+
+	gpio->chip.parent = &pdev->dev;
+	gpio->chip.ngpio = nr_gpios;
+	gpio->chip.direction_input = aspeed_sgpio_dir_in;
+	gpio->chip.direction_output = aspeed_sgpio_dir_out;
+	gpio->chip.get_direction = aspeed_sgpio_get_direction;
+	gpio->chip.request = NULL;
+	gpio->chip.free = NULL;
+	gpio->chip.get = aspeed_sgpio_get;
+	gpio->chip.set = aspeed_sgpio_set;
+	gpio->chip.set_config = NULL;
+	gpio->chip.label = dev_name(&pdev->dev);
+	gpio->chip.base = -1;
+
+	/* set all SGPIO pins as input (1). */
+	memset(gpio->dir_in, 0xff, sizeof(gpio->dir_in));
+
+	rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
+	if (rc < 0)
+		return rc;
+
+	return aspeed_sgpio_setup_irqs(gpio, pdev);
+}
+
+static struct platform_driver aspeed_sgpio_driver = {
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.of_match_table = aspeed_sgpio_of_table,
+	},
+};
+
+module_platform_driver_probe(aspeed_sgpio_driver, aspeed_sgpio_probe);
+MODULE_DESCRIPTION("Aspeed Serial GPIO Driver");
+MODULE_LICENSE("GPL");
-- 
2.7.4


^ permalink raw reply related

* [v7 1/2] dt-bindings: gpio: aspeed: Add SGPIO support
From: Hongwei Zhang @ 2019-07-31 20:01 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <1564603297-1391-1-git-send-email-hongweiz@ami.com>

Add bindings to support SGPIO on AST2400 or AST2500.

Signed-off-by: Hongwei Zhang <hongweiz@ami.com>
Reviewed-by:   Andrew Jeffery <andrew@aj.id.au>
---
 .../devicetree/bindings/gpio/sgpio-aspeed.txt      | 55 ++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt

diff --git a/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
new file mode 100644
index 0000000..8545bbc
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
@@ -0,0 +1,55 @@
+Aspeed SGPIO controller Device Tree Bindings
+-------------------------------------------
+
+This SGPIO controller is for ASPEED AST2500 SoC, it supports up to 80 full 
+featured Serial GPIOs. Each of the Serial GPIO pins can be programmed to 
+support the following options:
+- Support interrupt option for each input port and various interrupt 
+  sensitivity option (level-high, level-low, edge-high, edge-low)
+- Support reset tolerance option for each output port
+- Directly connected to APB bus and its shift clock is from APB bus clock
+  divided by a programmable value.
+- Co-work with external signal-chained TTL components (74LV165/74LV595)
+
+
+Required properties:
+
+- compatible		: Either "aspeed,ast2400-sgpio" or "aspeed,ast2500-sgpio"
+
+- #gpio-cells 		: Should be two
+			  - First cell is the GPIO line number
+			  - Second cell is used to specify optional
+			    parameters (unused)
+
+- reg			: Address and length of the register set for the device
+- gpio-controller	: Marks the device node as a GPIO controller
+- interrupts		: Interrupt specifier (see interrupt bindings for
+			  details)
+
+- interrupt-controller	: Mark the GPIO controller as an interrupt-controller
+
+- ngpios		: number of GPIO pins to serialise. 
+			  (should be multiple of 8, up to 80 pins)
+
+- clocks                : A phandle to the APB clock for SGPM clock division
+
+- bus-frequency		: SGPM CLK frequency
+
+
+The sgpio and interrupt properties are further described in their respective bindings documentation:
+
+- Documentation/devicetree/bindings/gpio/gpio.txt
+- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+  Example:
+	sgpio: sgpio at 1e780200 {
+		#gpio-cells = <2>;
+		compatible = "aspeed,ast2500-sgpio";
+		gpio-controller;
+		interrupts = <40>;
+		reg = <0x1e780200 0x0100>;
+		clocks = <&syscon ASPEED_CLK_APB>;
+		interrupt-controller;
+		ngpios = <8>;
+		bus-frequency = <12000000>;
+	};
-- 
2.7.4


^ permalink raw reply related

* [v7 0/2] gpio: aspeed: Add SGPIO driver
From: Hongwei Zhang @ 2019-07-31 20:01 UTC (permalink / raw)
  To: linux-aspeed

Hello,

This short series introduce dt-binding document and a driver for the 
Aspeed AST2500 SGPIO controller. Please review.

[v7]:   Changes between v6 and v7:
        - fix missing variable 'reg' assign issue in aspeed_sgpio_set()
        - v6 feedback updates

[v6]:   Changes between v5 and v6:
        - fix a bug in aspeed_sgpio_dir_out()
        - v5 feedback updates, some comments cleanup

The related SGPM pinmux dt-binding document, dts, and pinctrl driver
updates have been accepted and merged:
_http://patchwork.ozlabs.org/patch/1110210/

Hongwei Zhang (2):
  dt-bindings: gpio: aspeed: Add SGPIO support
  gpio: aspeed: Add SGPIO driver

 .../devicetree/bindings/gpio/sgpio-aspeed.txt      |  55 +++
 drivers/gpio/sgpio-aspeed.c                        | 530 +++++++++++++++++++++
 2 files changed, 585 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
 create mode 100644 drivers/gpio/sgpio-aspeed.c

-- 
2.7.4


^ permalink raw reply

* [PATCH net-next v2 1/4] dt-bindings: net: Add aspeed, ast2600-mdio binding
From: Rob Herring @ 2019-07-31 18:00 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-2-andrew@aj.id.au>

On Tue, Jul 30, 2019 at 11:39 PM Andrew Jeffery <andrew@aj.id.au> wrote:
>
> The AST2600 splits out the MDIO bus controller from the MAC into its own
> IP block and rearranges the register layout. Add a new binding to
> describe the new hardware.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
>
> ---
> v2:
> * aspeed: Utilise mdio.yaml
> * aspeed: Drop status from example
> ---
>  .../bindings/net/aspeed,ast2600-mdio.yaml     | 45 +++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [patch v4 1/5] AST2500 DMA UART driver
From: Greg KH @ 2019-07-31 11:42 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <CAE-5=DQ8p9WAhjrmZ8ye8GjoHrcxkHkjJPRNRFtvgeF5SdqwVQ@mail.gmail.com>

On Wed, Jul 31, 2019 at 05:06:08PM +0530, sudheer v wrote:
> Hi  Greg,
>  After modifying [ patch v4 1/5 ] , should i submit whole patchset as  v5 ?

Yes please.

thanks,

greg k-h

^ permalink raw reply

* [patch v4 1/5] AST2500 DMA UART driver
From: sudheer v @ 2019-07-31 11:36 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190730154759.GA26425@kroah.com>

Hi  Greg,
 After modifying [ patch v4 1/5 ] , should i submit whole patchset as  v5 ?
 or replying  with this single patch modified will be enough?
 how is this done in linux community ?.

Regards
Sudheer

On Tue, Jul 30, 2019 at 9:18 PM Greg KH <gregkh@linuxfoundation.org> wrote:

> On Fri, Jul 26, 2019 at 06:57:16PM +0530, sudheer.v wrote:
> > From: sudheer veliseti <sudheer.open@gmail.com>
> >
> > UART driver for Aspeed's bmc chip AST2500
> >
> > Design approch:
> > AST2500 has dedicated Uart DMA controller which has 12 sets of Tx and RX
> channels
> > connected to UART controller directly.
> > Since the DMA controller have dedicated buffers and registers,
> > there would be little benifit in adding DMA framework overhead.
> > So the software for DMA controller is included within the UART driver
> itself.
> >
> > implementation details:
> > 'struct ast_uart_port' is populated and registered with uart_core.
> > code is organised into two layers UART-layer and DMA-Layer,both of them
> are
> > in the same file.UART-layer requests Rx and Tx dma channels
> > and registers callbacks with DMA controller software Layer
> > Interrupt service routine for DMA controller is the crucial one for
> Handling all
> > the tx and rx data. ISRs installed for individual uarts are just
> dummy,and are helpful
> > only to report any spurious interrupts in hardware.
> >
> >
> > Signed-off-by: sudheer veliseti <sudheer.open@gmail.com>
> > ---
> >
> > Changes from v3->v4:
> > - per port uart structures are registerd directly with uart core
> >   Instead of registering through 8250 Frame work,
> >   ast_uart_port is registered using uart_add_one_port
> > -SDMA_RX_FIX macro replaced with CONFIG_AST_UART_DMA_RX_INTERRUPT
> > -ast_uart_sdma_isr : DMA interrupt handler code is improvised
> > -replaced pr_debug with ftrace wherever appropriate
> > -dev_err is used in all error return cases
> > -uart driver structure ast25xx_uart_reg is modified
> > -driver name changed to ast2500-uart-dma-drv
> > -rx_timer initialisation and callback fn modified
> >
> > Changes from v2->v3:
> > -custom debug replaced by in kerenl dynamic debug: pr_debug
> > -change-logs added
> >
> >
> > .../tty/serial/8250/8250_ast2500_uart_dma.c   | 1901 +++++++++++++++++
> >  1 file changed, 1901 insertions(+)
> >  create mode 100644 drivers/tty/serial/8250/8250_ast2500_uart_dma.c
> >
> > diff --git a/drivers/tty/serial/8250/8250_ast2500_uart_dma.c
> b/drivers/tty/serial/8250/8250_ast2500_uart_dma.c
> > new file mode 100644
> > index 000000000000..bc830d605372
> > --- /dev/null
> > +++ b/drivers/tty/serial/8250/8250_ast2500_uart_dma.c
> > @@ -0,0 +1,1901 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + *  DMA UART Driver for ASPEED BMC chip: AST2500
> > + *
> > + *  Copyright (C) 2019 sudheer Kumar veliseti, Aspeed technology Inc.
> > + *  <open.sudheer@gmail.com>
>
> What was the copyright on the file you copied?  Please properly
> attribute that here.
>
>
> > + *
> > + */
> > +#include <linux/clk.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/tty.h>
> > +#include <linux/tty_flip.h>
> > +#include "8250.h"
> > +
> > +#define SERIAL8250_CONSOLE NULL
> > +#define TTY_AST_MAJOR 204
> > +#define TTY_AST_MINOR 68
>
> Where did you get this minor number from?
>
> > +
> > +#define DMA_BUFF_SIZE                0x1000
> > +#define SDMA_RX_BUFF_SIZE    0x10000
> > +#define PASS_LIMIT 256
> > +#define UART_DMA_NR CONFIG_AST_NR_DMA_UARTS
> > +#define AST_UART_SDMA_CH 12
> > +
> > +/* enum ast_uart_chan_op
> > + * operation codes passed to the DMA code by the user, and also used
> > + * to inform the current channel owner of any changes to the system
> state
> > + */
> > +enum ast_uart_chan_op {
> > +     AST_UART_DMAOP_TRIGGER,
> > +     AST_UART_DMAOP_STOP,
> > +     AST_UART_DMAOP_PAUSE,
> > +};
> > +
> > +/* ast_uart_dma_cbfn: buffer callback routinei type */
> > +typedef void (*ast_uart_dma_cbfn)(void *dev_id, u16 len);
> > +
> > +struct ast_sdma_info {
> > +     u8 ch_no;
> > +     u8 direction;
> > +     u8 enable;
> > +     void *priv;
> > +     char *sdma_virt_addr;
> > +     dma_addr_t dma_phy_addr;
> > +     /* cdriver callbacks */
> > +     ast_uart_dma_cbfn callback_fn; /* buffer done callback */
> > +};
> > +
> > +struct ast_sdma_ch {
> > +     struct ast_sdma_info tx_dma_info[AST_UART_SDMA_CH];
> > +     struct ast_sdma_info rx_dma_info[AST_UART_SDMA_CH];
> > +};
> > +
> > +struct ast_sdma {
> > +     void __iomem *reg_base;
> > +     int dma_irq;
> > +     struct ast_sdma_ch *dma_ch;
> > +     struct regmap *map;
> > +};
> > +
> > +#define UART_TX_SDMA_EN              0x00
> > +#define UART_RX_SDMA_EN              0x04
> > +#define UART_SDMA_CONF               0x08 /* Misc, Buffer size  */
> > +#define UART_SDMA_TIMER              0x0C
> > +#define UART_TX_SDMA_REST    0x20
> > +#define UART_RX_SDMA_REST    0x24
> > +#define UART_TX_SDMA_IER     0x30
> > +#define UART_TX_SDMA_ISR     0x34
> > +#define UART_RX_SDMA_IER     0x38
> > +#define UART_RX_SDMA_ISR     0x3C
> > +#define UART_TX_R_POINT(x)   (0x40 + ((x) * 0x20))
> > +#define UART_TX_W_POINT(x)   (0x44 + ((x) * 0x20))
> > +#define UART_TX_SDMA_ADDR(x) (0x48 + ((x) * 0x20))
> > +#define UART_RX_R_POINT(x)   (0x50 + ((x) * 0x20))
> > +#define UART_RX_W_POINT(x)   (0x54 + ((x) * 0x20))
> > +#define UART_RX_SDMA_ADDR(x) (0x58 + ((x) * 0x20))
> > +#define SDMA_CH_EN(x)                BIT(x)
> > +
> > +#define SDMA_TX_BUFF_SIZE_MASK       (0x3)
> > +#define SDMA_SET_TX_BUFF_SIZE(x)(x)
> > +#define SDMA_BUFF_SIZE_1KB   (0x0)
> > +#define SDMA_BUFF_SIZE_4KB   (0x1)
> > +#define SDMA_BUFF_SIZE_16KB  (0x2)
> > +#define SDMA_BUFF_SIZE_64KB  (0x3)
> > +#define SDMA_RX_BUFF_SIZE_MASK       (0x3 << 2)
> > +#define SDMA_SET_RX_BUFF_SIZE(x)((x) << 2)
> > +#define SDMA_TIMEOUT_DIS     BIT(4)
> > +
> > +#define UART_SDMA11_INT              BIT(11)
> > +#define UART_SDMA10_INT              BIT(10)
> > +#define UART_SDMA9_INT               BIT(9)
> > +#define UART_SDMA8_INT               BIT(8)
> > +#define UART_SDMA7_INT               BIT(7)
> > +#define UART_SDMA6_INT               BIT(6)
> > +#define UART_SDMA5_INT               BIT(5)
> > +#define UART_SDMA4_INT               BIT(4)
> > +#define UART_SDMA3_INT               BIT(3)
> > +#define UART_SDMA2_INT               BIT(2)
> > +#define UART_SDMA1_INT               BIT(1)
> > +#define UART_SDMA0_INT               BIT(0)
> > +
> > +/*
> > + * Configuration:
> > + *   share_irqs - whether we pass IRQF_SHARED to request_irq().
> > + *   This option is unsafe when used on edge-triggered interrupts.
> > + */
> > +static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
> > +
> > +static unsigned int nr_uarts = CONFIG_AST_RUNTIME_DMA_UARTS;
> > +
> > +struct ast_uart_port {
> > +     struct uart_port port;
> > +     unsigned short capabilities; /* port capabilities */
> > +     unsigned short bugs;         /* port bugs */
> > +     unsigned int tx_loadsz;      /* transmit fifo load size */
> > +     unsigned char acr;
> > +     unsigned char ier;
> > +     unsigned char lcr;
> > +     unsigned char mcr;
> > +     unsigned char mcr_mask;  /* mask of user bits */
> > +     unsigned char mcr_force; /* mask of forced bits */
> > +     struct circ_buf rx_dma_buf;
> > +     struct circ_buf tx_dma_buf;
> > +     unsigned char dma_channel;
> > +     dma_addr_t dma_rx_addr; /* Mapped ADMA descr. table */
> > +     dma_addr_t dma_tx_addr; /* Mapped ADMA descr. table */
> > +#ifdef CONFIG_AST_UART_DMA_RX_INTERRUPT
> > +     struct tasklet_struct rx_tasklet;
> > +#else
> > +     struct timer_list rx_timer;
> > +     unsigned int workaround;
> > +#endif
> > +     struct tasklet_struct tx_tasklet;
> > +     spinlock_t lock;
> > +     int tx_done;
> > +     int tx_count;
> > +     struct platform_device *ast_uart_pdev;
> > +/*
> > + * Some bits in registers are cleared on a read, so they must
> > + * be saved whenever the register is read but the bits will not
> > + * be immediately processed.
> > + */
> > +#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
> > +     unsigned char lsr_saved_flags;
> > +#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
> > +     unsigned char msr_saved_flags;
> > +
> > +     /*
> > +      * We provide a per-port pm hook.
> > +      */
> > +     void (*pm)(struct uart_port *port, unsigned int state,
> > +                                              unsigned int old);
> > +};
> > +
> > +static struct ast_uart_port ast_uart_ports[UART_DMA_NR];
> > +
> > +#define GET_DEV(ast_uart_port_priv_ptr)\
> > +             (ast_uart_port_priv_ptr->ast_uart_pdev->dev)
> > +
> > +static inline struct ast_uart_port *
> > +to_ast_dma_uart_port(struct uart_port *uart) {
> > +     return container_of(uart, struct ast_uart_port, port);
> > +}
> > +
> > +struct irq_info {
> > +     spinlock_t lock;
> > +     struct ast_uart_port *up;
> > +};
> > +
> > +static struct irq_info ast_uart_irq[1];
> > +static DEFINE_MUTEX(ast_uart_mutex);
> > +
> > +/*
> > + * Here we define the default xmit fifo size used for each type of UART.
> > + */
> > +static const struct serial8250_config uart_config[] = {
> > +     [PORT_UNKNOWN] = {
> > +             .name           = "unknown",
> > +             .fifo_size      = 1,
> > +             .tx_loadsz      = 1,
> > +     },
> > +     [PORT_8250] = {
> > +             .name           = "8250",
> > +             .fifo_size      = 1,
> > +             .tx_loadsz      = 1,
> > +     },
> > +     [PORT_16450] = {
> > +             .name           = "16450",
> > +             .fifo_size      = 1,
> > +             .tx_loadsz      = 1,
> > +     },
> > +     [PORT_16550] = {
> > +             .name           = "16550",
> > +             .fifo_size      = 1,
> > +             .tx_loadsz      = 1,
> > +     },
> > +     [PORT_16550A] = {
> > +             .name           = "16550A",
> > +             .fifo_size      = 16,
> > +             .tx_loadsz      = 16,
> > +             .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10
> > +                                                     |
> UART_FCR_DMA_SELECT,
> > +             .flags          = UART_CAP_FIFO,
> > +     },
> > +};
>
> I doubt you need all of these port types, right?  You only have one type
> of device, please strip out _ALL_ of the unneeded code in here.  You did
> a wholesale copy of the old driver, to get away with that you then need
> to customize it to work properly with your hardware _AND_ take away all
> code that is not needed for your hardware.
>
> Lots of this file can be removed, please do so.
>
> thanks,
>
> greg k-h
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linux-aspeed/attachments/20190731/1c453407/attachment-0001.htm>

^ permalink raw reply

* [PATCH v2 2/2] ARM: dts: aspeed: Add Mihawk BMC platform
From: Ben Pai @ 2019-07-31  7:47 UTC (permalink / raw)
  To: linux-aspeed

The Mihawk BMC is an ASPEED ast2500 based BMC that is part of an
OpenPower Power9 server.

Signed-off-by: Ben Pai <Ben_Pai@wistron.com>
---
 arch/arm/boot/dts/Makefile                  |   1 +
 arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts | 907 ++++++++++++++++++++
 2 files changed, 908 insertions(+)
 create mode 100755 arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index eb6de52c1936..262345544359 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1281,5 +1281,6 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-opp-vesnin.dtb \
 	aspeed-bmc-opp-witherspoon.dtb \
 	aspeed-bmc-opp-zaius.dtb \
+	aspeed-bmc-opp-mihawk.dtb \
 	aspeed-bmc-portwell-neptune.dtb \
 	aspeed-bmc-quanta-q71l.dtb
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts b/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
new file mode 100755
index 000000000000..913c94326f3f
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
@@ -0,0 +1,907 @@
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/leds/leds-pca955x.h>
+
+/ {
+	model = "Mihawk BMC";
+	compatible = "ibm,mihawk-bmc", "aspeed,ast2500";
+
+
+	chosen {
+		stdout-path = &uart5;
+		bootargs = "console=ttyS4,115200 earlyprintk";
+	};
+
+	memory at 80000000 {
+		reg = <0x80000000 0x20000000>; /* address and size of RAM(512MB) */
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		flash_memory: region at 98000000 {
+			no-map;
+			reg = <0x98000000 0x04000000>; /* 64M */
+		};
+
+		gfx_memory: framebuffer {
+			size = <0x01000000>;
+			alignment = <0x01000000>;
+			compatible = "shared-dma-pool";
+			reusable;
+		};
+
+		video_engine_memory: jpegbuffer {
+			size = <0x02000000>;	/* 32MM */
+			alignment = <0x01000000>;
+			compatible = "shared-dma-pool";
+			reusable;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		air-water {
+			label = "air-water";
+			gpios = <&gpio ASPEED_GPIO(F, 6) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(F, 6)>;
+		};
+
+		checkstop {
+			label = "checkstop";
+			gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(J, 2)>;
+		};
+
+		ps0-presence {
+			label = "ps0-presence";
+			gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(Z, 2)>;
+		};
+
+		ps1-presence {
+			label = "ps1-presence";
+			gpios = <&gpio ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(Z, 0)>;
+		};
+		id-button {
+			label = "id-button";
+			gpios = <&gpio ASPEED_GPIO(F, 1) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(F, 1)>;
+		};
+	};
+
+	gpio-keys-polled {
+		compatible = "gpio-keys-polled";
+		#address-cells = <1>;
+		poll-interval = <1000>;
+
+		fan0-presence {
+			label = "fan0-presence";
+			gpios = <&pca9552 9 GPIO_ACTIVE_LOW>;
+			linux,code = <9>;
+		};
+
+		fan1-presence {
+			label = "fan1-presence";
+			gpios = <&pca9552 10 GPIO_ACTIVE_LOW>;
+			linux,code = <10>;
+		};
+
+		fan2-presence {
+			label = "fan2-presence";
+			gpios = <&pca9552 11 GPIO_ACTIVE_LOW>;
+			linux,code = <11>;
+		};
+
+		fan3-presence {
+			label = "fan3-presence";
+			gpios = <&pca9552 12 GPIO_ACTIVE_LOW>;
+			linux,code = <12>;
+		};
+
+		fan4-presence {
+			label = "fan4-presence";
+			gpios = <&pca9552 13 GPIO_ACTIVE_LOW>;
+			linux,code = <13>;
+		};
+
+		fan5-presence {
+			label = "fan5-presence";
+			gpios = <&pca9552 14 GPIO_ACTIVE_LOW>;
+			linux,code = <14>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		fault {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&gpio ASPEED_GPIO(AA, 1) GPIO_ACTIVE_LOW>;
+		};
+
+		rear-id {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_LOW>;
+		};
+
+		rear-g {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&gpio ASPEED_GPIO(AA, 4) GPIO_ACTIVE_LOW>;
+		};
+
+		rear-ok {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&gpio ASPEED_GPIO(Y, 0) GPIO_ACTIVE_LOW>;
+		};
+
+		fan0 {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&pca9552 0 GPIO_ACTIVE_LOW>;
+		};
+
+		fan1 {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&pca9552 1 GPIO_ACTIVE_LOW>;
+		};
+
+		fan2 {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&pca9552 2 GPIO_ACTIVE_LOW>;
+		};
+
+		fan3 {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&pca9552 3 GPIO_ACTIVE_LOW>;
+		};
+
+		fan4 {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&pca9552 4 GPIO_ACTIVE_LOW>;
+		};
+
+		fan5 {
+			retain-state-shutdown;
+			default-state = "keep";
+			gpios = <&pca9552 5 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	fsi: gpio-fsi {
+		compatible = "fsi-master-gpio", "fsi-master";
+		#address-cells = <2>;
+		#size-cells = <0>;
+		no-gpio-delays;
+
+		clock-gpios = <&gpio ASPEED_GPIO(E, 6) GPIO_ACTIVE_HIGH>;
+		data-gpios = <&gpio ASPEED_GPIO(E, 7) GPIO_ACTIVE_HIGH>;
+		mux-gpios = <&gpio ASPEED_GPIO(E, 5) GPIO_ACTIVE_HIGH>;
+		enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
+		trans-gpios = <&gpio ASPEED_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
+	};
+	iio-hwmon-12v {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 0>;
+	};
+	
+	iio-hwmon-5v {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 1>;
+	};
+	
+	iio-hwmon-3v {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 2>;
+	};
+		
+	iio-hwmon-vdd0 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 3>;
+	};
+	
+	iio-hwmon-vdd1 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 4>;
+	};
+	
+	iio-hwmon-vcs0 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 5>;
+	};
+	
+	iio-hwmon-vcs1 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 6>;
+	};
+
+	iio-hwmon-vdn0 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 7>;
+	};
+	
+	iio-hwmon-vdn1 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 8>;
+	};
+	
+	iio-hwmon-vio0 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 9>;
+	};
+	
+	iio-hwmon-vio1 {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 10>;
+	};
+	
+	iio-hwmon-vddra {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 11>;
+	};
+	
+	iio-hwmon-vddrb {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 13>;
+	};
+	
+	iio-hwmon-vddrc {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 14>;
+	};
+	
+	iio-hwmon-vddrd {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 15>;
+	};
+	
+	iio-hwmon-battery {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 12>;
+	};
+};
+
+&pwm_tacho {
+	status = "okay";
+	/*compatible = "aspeed,ast2500-pwm-tacho";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	reg = <0x1e786000 0x1000>;
+	clocks = <&pwm_tacho_fixed_clk>;*/
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default
+		&pinctrl_pwm2_default &pinctrl_pwm3_default
+		&pinctrl_pwm4_default &pinctrl_pwm5_default>;
+
+	fan at 0 {
+		reg = <0x00>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+	};
+
+	fan at 1 {
+		reg = <0x01>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x01>;
+	};
+
+	fan at 2 {
+		reg = <0x02>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x02>;
+	};
+
+	fan at 3 {
+		reg = <0x03>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x03>;
+	};
+
+	fan at 4 {
+		reg = <0x04>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x04>;
+	};
+
+	fan at 5 {
+		reg = <0x05>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x05>;
+	};
+
+	fan at 6 {
+		reg = <0x00>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x06>;
+	};
+
+	fan at 7 {
+		reg = <0x01>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x07>;
+	};
+
+	fan at 8 {
+		reg = <0x02>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x08>;
+	};
+
+	fan at 9 {
+		reg = <0x03>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x09>;
+	};
+
+	fan at 10 {
+		reg = <0x04>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x0a>;
+	};
+
+	fan at 11 {
+		reg = <0x05>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x0b>;
+	};
+};
+
+&fmc {
+	status = "okay";
+	flash at 0 {
+		status = "okay";
+		label = "bmc";
+		m25p,fast-read;
+		spi-max-frequency = <50000000>;
+		partitions {
+			#address-cells = < 1 >;
+			#size-cells = < 1 >;
+			compatible = "fixed-partitions";
+			u-boot at 0 {
+				reg = < 0 0x60000 >;
+				label = "u-boot";
+			};
+			u-boot-env at 60000 {
+				reg = < 0x60000 0x20000 >;
+				label = "u-boot-env";
+			};
+			obmc-ubi at 80000 {
+				reg = < 0x80000 0x1F80000 >;
+				label = "obmc-ubi";
+			};
+		};
+	};
+	flash at 1 {
+		status = "okay";
+		label = "alt-bmc";
+		m25p,fast-read;
+		spi-max-frequency = <50000000>;
+		partitions {
+			#address-cells = < 1 >;
+			#size-cells = < 1 >;
+			compatible = "fixed-partitions";
+			u-boot at 0 {
+				reg = < 0 0x60000 >;
+				label = "alt-u-boot";
+			};
+			u-boot-env at 60000 {
+				reg = < 0x60000 0x20000 >;
+				label = "alt-u-boot-env";
+			};
+			obmc-ubi at 80000 {
+				reg = < 0x80000 0x1F80000 >;
+				label = "alt-obmc-ubi";
+			};
+		};
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+
+	flash at 0 {
+		status = "okay";
+		label = "pnor";
+		m25p,fast-read;
+		spi-max-frequency = <100000000>;
+	};
+};
+
+&lpc_ctrl {
+	status = "okay";
+	memory-region = <&flash_memory>;
+	flash = <&spi1>;
+};
+
+&uart1 {
+	/* Rear RS-232 connector */
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_txd1_default
+			&pinctrl_rxd1_default
+			&pinctrl_nrts1_default
+			&pinctrl_ndtr1_default
+			&pinctrl_ndsr1_default
+			&pinctrl_ncts1_default
+			&pinctrl_ndcd1_default
+			&pinctrl_nri1_default>;
+};
+
+&uart2 {
+	/* APSS */
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>;
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&mac0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii1_default>;
+	use-ncsi;
+};
+
+&mac1 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&i2c0 {
+	status = "disabled";
+};
+
+&i2c1 {
+	status = "disabled";
+};
+
+&i2c2 {
+	status = "okay";
+
+	/* SAMTEC P0 */
+	/* SAMTEC P1 */
+	
+};
+
+&i2c3 {
+	status = "okay";
+
+	/* APSS */
+	/* CPLD */
+
+	/* PCA9516 (repeater) ->
+	 *    CLK Buffer 9FGS9092
+	 *    CLK Buffer 9DBL0651BKILFT
+	 *    CLK Buffer 9DBL0651BKILFT
+	 *    Power Supply 0
+	 *    Power Supply 1
+	 *    PCA 9552 LED
+	 */
+	 
+	power-supply at 58 {
+		compatible = "ibm,cffps1";
+		reg = <0x58>;
+	};
+
+	power-supply at 5b {
+		compatible = "ibm,cffps1";
+		reg = <0x5b>;
+	};
+
+	pca9552: pca9552 at 60 {
+		compatible = "nxp,pca9552";
+		reg = <0x60>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio at 0 {
+			reg = <0>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 1 {
+			reg = <1>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 2 {
+			reg = <2>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 3 {
+			reg = <3>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 4 {
+			reg = <4>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 5 {
+			reg = <5>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 6 {
+			reg = <6>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 7 {
+			reg = <7>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 8 {
+			reg = <8>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 9 {
+			reg = <9>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 10 {
+			reg = <10>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 11 {
+			reg = <11>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 12 {
+			reg = <12>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 13 {
+			reg = <13>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 14 {
+			reg = <14>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+		gpio at 15 {
+			reg = <15>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+
+	};
+
+};
+
+&i2c4 {
+	status = "okay";
+
+	/* CP0 VDD & VCS : IR35221 */
+	/* CP0 VDN : IR35221 */
+	/* CP0 VIO : IR38064 */
+        /* CP0 VDDR : PXM1330 */
+
+	ir35221 at 70 {
+		compatible = "infineon,ir35221";
+		reg = <0x70>;
+	};
+
+	ir35221 at 72 {
+		compatible = "infineon,ir35221";
+		reg = <0x72>;
+	};
+
+};
+
+&i2c5 {
+	status = "okay";
+	
+	/* CP0 VDD & VCS : IR35221 */
+	/* CP0 VDN : IR35221 */
+	/* CP0 VIO : IR38064 */
+        /* CP0 VDDR : PXM1330 */
+
+	ir35221 at 70 {
+		compatible = "infineon,ir35221";
+		reg = <0x70>;
+	};
+
+	ir35221 at 72 {
+		compatible = "infineon,ir35221";
+		reg = <0x72>;
+	};
+	
+};
+
+&i2c6 {
+	status = "okay";
+	
+	/* pca9548 -> NVMe1 to 8 */
+	
+	pca9548 at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+	};
+	
+};
+
+&i2c7 {
+	status = "okay";
+	
+	/* pca9548 -> NVMe9 to 16 */
+	
+	pca9548 at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+	};
+	
+};
+
+&i2c8 {
+	status = "okay";
+
+	eeprom at 50 {
+		compatible = "atmel,24c64";
+		reg = <0x50>;
+	};
+};
+
+&i2c9 {
+	status = "okay";
+	
+	/* pca9545 Riser -> 
+	* 	PCIe x8  Slot3 
+	* 	PCIe x16 slot4 
+	* 	PCIe x8  slot5 
+	* 	I2C BMC RISER PCA9554
+	* 	BMC SCL/SDA PCA9554 
+	* 	PCA9554
+	*/
+	
+	/* pca9545 -> 
+	* 	PCIe x16 Slot1 
+	* 	PCIe x8  slot2 
+	* 	PEX8748 
+	*/
+
+	pca9545riser at 70 {
+		compatible = "nxp,pca9545";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		i2c-mux-idle-disconnect;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+	
+	pca9545 at 71 {
+		compatible = "nxp,pca9545";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		i2c-mux-idle-disconnect;
+		interrupt-controller;
+		#interrupt-cells = <2>;	
+	};
+};
+
+&i2c10 {
+	status = "okay";
+	
+	/* pca9545 Riser -> 
+	* 	PCIe x8  Slot8 
+	* 	PCIe x16 slot9 
+	* 	PCIe x8  slot10 
+	* 	I2C BMC RISER PCA9554
+	* 	BMC SCL/SDA PCA9554 
+	* 	PCA9554
+	*/
+	
+	/* pca9545 -> 
+	* 	PCIe x16 Slot1 
+	* 	PCIe x8  slot2 
+	* 	PEX8748 
+	*/
+	
+	pca9545riser at 70 {
+		compatible = "nxp,pca9545";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		i2c-mux-idle-disconnect;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+	
+	pca9545 at 71 {
+		compatible = "nxp,pca9545";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		i2c-mux-idle-disconnect;
+		interrupt-controller;
+		#interrupt-cells = <2>;	
+	};
+};
+
+&i2c11 {
+	status = "okay";
+	
+	/* TPM */
+	/* RTC RX8900CE */
+	/* FPGA for power sequence */
+	/* TMP275A */
+	/* TMP275A */
+	/* EMC1462 */
+
+	tpm at 57 {
+		compatible = "infineon,slb9645tt";
+		reg = <0x57>;
+	};
+	
+	rtc at 32 {
+		compatible = "epson,rx8900";
+		reg = <0x32>;
+	};
+	
+	tmp275 at 48 {
+		compatible = "ti,tmp275";
+		reg = <0x48>;
+	};
+	
+	tmp275 at 49 {
+		compatible = "ti,tmp275";
+		reg = <0x49>;
+	};
+
+	/* chip emc1462 use emc1403 driver */
+	emc1403 at 4c {
+        	compatible = "smsc,emc1403";
+        	reg = <0x4c>;
+    	};
+
+};
+
+&i2c12 {
+	status = "okay";
+
+	/* pca9545 ->
+	*	SAS BP1
+	*	SAS BP2
+	*	NVMe BP
+	*	M.2 riser
+	*/
+	
+	pca9545 at 70 {
+		compatible = "nxp,pca9545";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		
+		i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			
+			eeprom at 50 {
+				compatible = "atmel,24c64";
+				reg = <0x50>;
+			};
+		};
+		
+		i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			
+			eeprom at 50 {
+				compatible = "atmel,24c64";
+				reg = <0x50>;
+			};
+		};
+		
+		i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			
+			eeprom at 50 {
+				compatible = "atmel,24c64";
+				reg = <0x50>;
+			};
+		};
+		
+		i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			
+			tmp275 at 48 {
+				compatible = "ti,tmp275";
+				reg = <0x48>;
+			};
+		};
+		
+	};
+	
+};
+
+&i2c13 {
+	status = "okay";
+	
+	/* pca9548 ->
+	*	NVMe BP
+	*	NVMe HDD17 to 24
+	*/
+	
+	pca9548 at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+	};	
+};
+
+&vuart {
+	status = "okay";
+};
+
+&gfx {
+	status = "okay";
+	memory-region = <&gfx_memory>;
+};
+
+&adc {
+	status = "okay";
+};
+
+&wdt1 {
+	aspeed,reset-type = "none";
+	aspeed,external-signal;
+	aspeed,ext-push-pull;
+	aspeed,ext-active-high;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdtrst1_default>;
+};
+
+&wdt2 {
+	aspeed,alt-boot;
+};
+
+&ibt {
+	status = "okay";
+};
+
+&vhub {
+	status = "okay";
+};
+
+&video {
+	status = "okay";
+	memory-region = <&video_engine_memory>;
+};
+
+#include "ibm-power9-dual.dtsi"
+
-- 
2.17.1


---------------------------------------------------------------------------------------------------------------------------------------------------------------
This email contains confidential or legally privileged information and is for the sole use of its intended recipient. 
Any unauthorized review, use, copying or distribution of this email or the content of this email is strictly prohibited.
If you are not the intended recipient, you may reply to the sender and should delete this e-mail immediately.
---------------------------------------------------------------------------------------------------------------------------------------------------------------

^ permalink raw reply related

* [PATCH net-next v2 4/4] net: ftgmac100: Select ASPEED MDIO driver for the AST2600
From: Andrew Jeffery @ 2019-07-31  5:39 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-1-andrew@aj.id.au>

Ensures we can talk to a PHY via MDIO on the AST2600, as the MDIO
controller is now separate from the MAC.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 drivers/net/ethernet/faraday/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig
index a9b105803fb7..73e4f2648e49 100644
--- a/drivers/net/ethernet/faraday/Kconfig
+++ b/drivers/net/ethernet/faraday/Kconfig
@@ -32,6 +32,7 @@ config FTGMAC100
 	depends on ARM || NDS32 || COMPILE_TEST
 	depends on !64BIT || BROKEN
 	select PHYLIB
+	select MDIO_ASPEED if MACH_ASPEED_G6
 	---help---
 	  This driver supports the FTGMAC100 Gigabit Ethernet controller
 	  from Faraday. It is used on Faraday A369, Andes AG102 and some
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next v2 3/4] net: ftgmac100: Add support for DT phy-handle property
From: Andrew Jeffery @ 2019-07-31  5:39 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-1-andrew@aj.id.au>

phy-handle is necessary for the AST2600 which separates the MDIO
controllers from the MAC.

I've tried to minimise the intrusion of supporting the AST2600 to the
FTGMAC100 by leaving in place the existing MDIO support for the embedded
MDIO interface. The AST2400 and AST2500 continue to be supported this
way, as it avoids breaking/reworking existing devicetrees.

The AST2600 support by contrast requires the presence of the phy-handle
property in the MAC devicetree node to specify the appropriate PHY to
associate with the MAC. In the event that someone wants to specify the
MDIO bus topology under the MAC node on an AST2400 or AST2500, the
current auto-probe approach is done conditional on the absence of an
"mdio" child node of the MAC.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 drivers/net/ethernet/faraday/ftgmac100.c | 37 +++++++++++++++++++++---
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 030fed65393e..563384b788ab 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/of.h>
+#include <linux/of_mdio.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
@@ -1619,8 +1620,13 @@ static int ftgmac100_setup_mdio(struct net_device *netdev)
 	if (!priv->mii_bus)
 		return -EIO;
 
-	if (priv->is_aspeed) {
-		/* This driver supports the old MDIO interface */
+	if (of_device_is_compatible(np, "aspeed,ast2400-mac") ||
+	    of_device_is_compatible(np, "aspeed,ast2500-mac")) {
+		/* The AST2600 has a separate MDIO controller */
+
+		/* For the AST2400 and AST2500 this driver only supports the
+		 * old MDIO interface
+		 */
 		reg = ioread32(priv->base + FTGMAC100_OFFSET_REVR);
 		reg &= ~FTGMAC100_REVR_NEW_MDIO_INTERFACE;
 		iowrite32(reg, priv->base + FTGMAC100_OFFSET_REVR);
@@ -1797,7 +1803,8 @@ static int ftgmac100_probe(struct platform_device *pdev)
 
 	np = pdev->dev.of_node;
 	if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac") ||
-		   of_device_is_compatible(np, "aspeed,ast2500-mac"))) {
+		   of_device_is_compatible(np, "aspeed,ast2500-mac") ||
+		   of_device_is_compatible(np, "aspeed,ast2600-mac"))) {
 		priv->rxdes0_edorr_mask = BIT(30);
 		priv->txdes0_edotr_mask = BIT(30);
 		priv->is_aspeed = true;
@@ -1817,7 +1824,29 @@ static int ftgmac100_probe(struct platform_device *pdev)
 		priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler);
 		if (!priv->ndev)
 			goto err_ncsi_dev;
-	} else {
+	} else if (np && of_get_property(np, "phy-handle", NULL)) {
+		struct phy_device *phy;
+
+		phy = of_phy_get_and_connect(priv->netdev, np,
+					     &ftgmac100_adjust_link);
+		if (!phy) {
+			dev_err(&pdev->dev, "Failed to connect to phy\n");
+			goto err_setup_mdio;
+		}
+
+		/* Indicate that we support PAUSE frames (see comment in
+		 * Documentation/networking/phy.txt)
+		 */
+		phy_support_asym_pause(phy);
+
+		/* Display what we found */
+		phy_attached_info(phy);
+	} else if (np && !of_get_child_by_name(np, "mdio")) {
+		/* Support legacy ASPEED devicetree descriptions that decribe a
+		 * MAC with an embedded MDIO controller but have no "mdio"
+		 * child node. Automatically scan the MDIO bus for available
+		 * PHYs.
+		 */
 		priv->use_ncsi = false;
 		err = ftgmac100_setup_mdio(netdev);
 		if (err)
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next v2 2/4] net: phy: Add mdio-aspeed
From: Andrew Jeffery @ 2019-07-31  5:39 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-1-andrew@aj.id.au>

The AST2600 design separates the MDIO controllers from the MAC, which is
where they were placed in the AST2400 and AST2500. Further, the register
interface is reworked again, so now we have three possible different
interface implementations, however this driver only supports the
interface provided by the AST2600. The AST2400 and AST2500 will continue
to be supported by the MDIO support embedded in the FTGMAC100 driver.

The hardware supports both C22 and C45 mode, but for the moment only C22
support is implemented.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

---
v2:
* Use readl_poll_timeout() instead of open-coded loop
* Error on C45 accesses
---
 drivers/net/phy/Kconfig       |  13 +++
 drivers/net/phy/Makefile      |   1 +
 drivers/net/phy/mdio-aspeed.c | 157 ++++++++++++++++++++++++++++++++++
 3 files changed, 171 insertions(+)
 create mode 100644 drivers/net/phy/mdio-aspeed.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 20f14c5fbb7e..206d8650ee7f 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -21,6 +21,19 @@ config MDIO_BUS
 
 if MDIO_BUS
 
+config MDIO_ASPEED
+	tristate "ASPEED MDIO bus controller"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on OF_MDIO && HAS_IOMEM
+	help
+	  This module provides a driver for the independent MDIO bus
+	  controllers found in the ASPEED AST2600 SoC. This is a driver for the
+	  third revision of the ASPEED MDIO register interface - the first two
+	  revisions are the "old" and "new" interfaces found in the AST2400 and
+	  AST2500, embedded in the MAC. For legacy reasons, FTGMAC100 driver
+	  continues to drive the embedded MDIO controller for the AST2400 and
+	  AST2500 SoCs, so say N if AST2600 support is not required.
+
 config MDIO_BCM_IPROC
 	tristate "Broadcom iProc MDIO bus controller"
 	depends on ARCH_BCM_IPROC || COMPILE_TEST
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 839acb292c38..ba07c27e4208 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -22,6 +22,7 @@ libphy-$(CONFIG_LED_TRIGGER_PHY)	+= phy_led_triggers.o
 obj-$(CONFIG_PHYLINK)		+= phylink.o
 obj-$(CONFIG_PHYLIB)		+= libphy.o
 
+obj-$(CONFIG_MDIO_ASPEED)	+= mdio-aspeed.o
 obj-$(CONFIG_MDIO_BCM_IPROC)	+= mdio-bcm-iproc.o
 obj-$(CONFIG_MDIO_BCM_UNIMAC)	+= mdio-bcm-unimac.o
 obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
diff --git a/drivers/net/phy/mdio-aspeed.c b/drivers/net/phy/mdio-aspeed.c
new file mode 100644
index 000000000000..cad820568f75
--- /dev/null
+++ b/drivers/net/phy/mdio-aspeed.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (C) 2019 IBM Corp. */
+
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
+#define DRV_NAME "mdio-aspeed"
+
+#define ASPEED_MDIO_CTRL		0x0
+#define   ASPEED_MDIO_CTRL_FIRE		BIT(31)
+#define   ASPEED_MDIO_CTRL_ST		BIT(28)
+#define     ASPEED_MDIO_CTRL_ST_C45	0
+#define     ASPEED_MDIO_CTRL_ST_C22	1
+#define   ASPEED_MDIO_CTRL_OP		GENMASK(27, 26)
+#define     MDIO_C22_OP_WRITE		0b01
+#define     MDIO_C22_OP_READ		0b10
+#define   ASPEED_MDIO_CTRL_PHYAD	GENMASK(25, 21)
+#define   ASPEED_MDIO_CTRL_REGAD	GENMASK(20, 16)
+#define   ASPEED_MDIO_CTRL_MIIWDATA	GENMASK(15, 0)
+
+#define ASPEED_MDIO_DATA		0x4
+#define   ASPEED_MDIO_DATA_MDC_THRES	GENMASK(31, 24)
+#define   ASPEED_MDIO_DATA_MDIO_EDGE	BIT(23)
+#define   ASPEED_MDIO_DATA_MDIO_LATCH	GENMASK(22, 20)
+#define   ASPEED_MDIO_DATA_IDLE		BIT(16)
+#define   ASPEED_MDIO_DATA_MIIRDATA	GENMASK(15, 0)
+
+#define ASPEED_MDIO_INTERVAL_US		100
+#define ASPEED_MDIO_TIMEOUT_US		(ASPEED_MDIO_INTERVAL_US * 10)
+
+struct aspeed_mdio {
+	void __iomem *base;
+};
+
+static int aspeed_mdio_read(struct mii_bus *bus, int addr, int regnum)
+{
+	struct aspeed_mdio *ctx = bus->priv;
+	u32 ctrl;
+	u32 data;
+	int rc;
+
+	dev_dbg(&bus->dev, "%s: addr: %d, regnum: %d\n", __func__, addr,
+		regnum);
+
+	/* Just clause 22 for the moment */
+	if (regnum & MII_ADDR_C45)
+		return -EOPNOTSUPP;
+
+	ctrl = ASPEED_MDIO_CTRL_FIRE
+		| FIELD_PREP(ASPEED_MDIO_CTRL_ST, ASPEED_MDIO_CTRL_ST_C22)
+		| FIELD_PREP(ASPEED_MDIO_CTRL_OP, MDIO_C22_OP_READ)
+		| FIELD_PREP(ASPEED_MDIO_CTRL_PHYAD, addr)
+		| FIELD_PREP(ASPEED_MDIO_CTRL_REGAD, regnum);
+
+	iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL);
+
+	rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_DATA, data,
+				data & ASPEED_MDIO_DATA_IDLE,
+				ASPEED_MDIO_INTERVAL_US,
+				ASPEED_MDIO_TIMEOUT_US);
+	if (rc < 0)
+		return rc;
+
+	return FIELD_GET(ASPEED_MDIO_DATA_MIIRDATA, data);
+}
+
+static int aspeed_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
+{
+	struct aspeed_mdio *ctx = bus->priv;
+	u32 ctrl;
+
+	dev_dbg(&bus->dev, "%s: addr: %d, regnum: %d, val: 0x%x\n",
+		__func__, addr, regnum, val);
+
+	/* Just clause 22 for the moment */
+	if (regnum & MII_ADDR_C45)
+		return -EOPNOTSUPP;
+
+	ctrl = ASPEED_MDIO_CTRL_FIRE
+		| FIELD_PREP(ASPEED_MDIO_CTRL_ST, ASPEED_MDIO_CTRL_ST_C22)
+		| FIELD_PREP(ASPEED_MDIO_CTRL_OP, MDIO_C22_OP_WRITE)
+		| FIELD_PREP(ASPEED_MDIO_CTRL_PHYAD, addr)
+		| FIELD_PREP(ASPEED_MDIO_CTRL_REGAD, regnum)
+		| FIELD_PREP(ASPEED_MDIO_CTRL_MIIWDATA, val);
+
+	iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL);
+
+	return readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl,
+				  !(ctrl & ASPEED_MDIO_CTRL_FIRE),
+				  ASPEED_MDIO_INTERVAL_US,
+				  ASPEED_MDIO_TIMEOUT_US);
+}
+
+static int aspeed_mdio_probe(struct platform_device *pdev)
+{
+	struct aspeed_mdio *ctx;
+	struct mii_bus *bus;
+	int rc;
+
+	bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*ctx));
+	if (!bus)
+		return -ENOMEM;
+
+	ctx = bus->priv;
+	ctx->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(ctx->base))
+		return PTR_ERR(ctx->base);
+
+	bus->name = DRV_NAME;
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id);
+	bus->parent = &pdev->dev;
+	bus->read = aspeed_mdio_read;
+	bus->write = aspeed_mdio_write;
+
+	rc = of_mdiobus_register(bus, pdev->dev.of_node);
+	if (rc) {
+		dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
+		return rc;
+	}
+
+	platform_set_drvdata(pdev, bus);
+
+	return 0;
+}
+
+static int aspeed_mdio_remove(struct platform_device *pdev)
+{
+	mdiobus_unregister(platform_get_drvdata(pdev));
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_mdio_of_match[] = {
+	{ .compatible = "aspeed,ast2600-mdio", },
+	{ },
+};
+
+static struct platform_driver aspeed_mdio_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = aspeed_mdio_of_match,
+	},
+	.probe = aspeed_mdio_probe,
+	.remove = aspeed_mdio_remove,
+};
+
+module_platform_driver(aspeed_mdio_driver);
+
+MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
+MODULE_LICENSE("GPL");
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next v2 1/4] dt-bindings: net: Add aspeed, ast2600-mdio binding
From: Andrew Jeffery @ 2019-07-31  5:39 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731053959.16293-1-andrew@aj.id.au>

The AST2600 splits out the MDIO bus controller from the MAC into its own
IP block and rearranges the register layout. Add a new binding to
describe the new hardware.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

---
v2:
* aspeed: Utilise mdio.yaml
* aspeed: Drop status from example
---
 .../bindings/net/aspeed,ast2600-mdio.yaml     | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml

diff --git a/Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml b/Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml
new file mode 100644
index 000000000000..71808e78a495
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/aspeed,ast2600-mdio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2600 MDIO Controller
+
+maintainers:
+  - Andrew Jeffery <andrew@aj.id.au>
+
+description: |+
+  The ASPEED AST2600 MDIO controller is the third iteration of ASPEED's MDIO
+  bus register interface, this time also separating out the controller from the
+  MAC.
+
+allOf:
+  - $ref: "mdio.yaml#"
+
+properties:
+  compatible:
+    const: aspeed,ast2600-mdio
+  reg:
+    maxItems: 1
+    description: The register range of the MDIO controller instance
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+
+examples:
+  - |
+    mdio0: mdio at 1e650000 {
+            compatible = "aspeed,ast2600-mdio";
+            reg = <0x1e650000 0x8>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            ethphy0: ethernet-phy at 0 {
+                    compatible = "ethernet-phy-ieee802.3-c22";
+                    reg = <0>;
+            };
+    };
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next v2 0/4] net: phy: Add AST2600 MDIO support
From: Andrew Jeffery @ 2019-07-31  5:39 UTC (permalink / raw)
  To: linux-aspeed

Hello,

v2 of the ASPEED MDIO series addresses comments from Rob on the devicetree
bindings and Andrew on the driver itself.

v1 of the series can be found here:

http://patchwork.ozlabs.org/cover/1138140/

Please review!

Andrew

Andrew Jeffery (4):
  dt-bindings: net: Add aspeed,ast2600-mdio binding
  net: phy: Add mdio-aspeed
  net: ftgmac100: Add support for DT phy-handle property
  net: ftgmac100: Select ASPEED MDIO driver for the AST2600

 .../bindings/net/aspeed,ast2600-mdio.yaml     |  45 +++++
 drivers/net/ethernet/faraday/Kconfig          |   1 +
 drivers/net/ethernet/faraday/ftgmac100.c      |  37 ++++-
 drivers/net/phy/Kconfig                       |  13 ++
 drivers/net/phy/Makefile                      |   1 +
 drivers/net/phy/mdio-aspeed.c                 | 157 ++++++++++++++++++
 6 files changed, 250 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml
 create mode 100644 drivers/net/phy/mdio-aspeed.c

-- 
2.20.1


^ permalink raw reply

* Re: [PATCH v2 2/3] dt-bindings: serial: 8250: Add documentation for espi-enabled.
From: Andrew Jeffery @ 2019-07-31  3:12 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731013404.243755-2-osk@google.com>

Hi Oskar,

On Wed, 31 Jul 2019, at 11:04, Oskar Senft wrote:
> Add documentation for 8250_aspeed_vuart's espi-enabled property that
> enables to auto-configure the VUART's SIRQ polarity.
> 
> Signed-off-by: Oskar Senft <osk@google.com>
> ---
>  Documentation/devicetree/bindings/serial/8250.txt | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/serial/8250.txt 
> b/Documentation/devicetree/bindings/serial/8250.txt
> index 20d351f268ef..4b8b9e502179 100644
> --- a/Documentation/devicetree/bindings/serial/8250.txt
> +++ b/Documentation/devicetree/bindings/serial/8250.txt
> @@ -56,6 +56,11 @@ Optional properties:
>  - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for 
> RTS/CTS/DTR/DSR/RI/DCD
>    line respectively. It will use specified GPIO instead of the 
> peripheral
>    function pin for the UART feature. If unsure, don't specify this 
> property.
> +- espi-enabled: Only applicable to aspeed,ast2500-vuart.

Bit of a bikeshed, but:

Given it's ASPEED-specific I expect you should use a vendor prefix for the
property, e.g. aspeed,espi-enabled.

However, as I understand it you want to determine what polarity the SIRQ
should be regardless of which of eSPI or LPC are enabled, so I don't think
the property name should be an explicit statement about eSPI. Maybe
"aspeed,sirq-polarity-sense"? Anyway, see the point below:

Please use ./scripts/get_maintainer.pl to determine where to send the
series - Copying just the linux-aspeed@ list for upstream patches is not
enough. For instance the series needs to at least go via the linux-serial@
list given that's the affected subsystem, and you're adding to the
devicetree binding so you need to send to the devicetree@ list as well
(you'll need an ack from Rob Herring). The get_maintainer.pl script will
give you all the information you need.

Cheers,

Andrew

^ permalink raw reply

* [PATCH] drivers/tty/serial/8250: Make Aspeed VUART SIRQ polarity configurable
From: Oskar Senft @ 2019-07-31  1:36 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <53f2c3aa-9502-4989-9c22-1a7f1c74cf47@www.fastmail.com>

Done. I submitted just a v2 of the patch alongside the other bits and
pieces that are required to make this work.

Let me know if that works for you or if there's anything that should be
changed.

Oskar.

On Sun, Jul 28, 2019 at 11:02 PM Andrew Jeffery <andrew@aj.id.au> wrote:

>
>
> On Mon, 29 Jul 2019, at 11:51, Oskar Senft wrote:
> >
> > Hi Jeremy
> >
> > > Somewhat offtopic, but are you sure you want to enable the SuperIO
> > >  device?
> > No :-D I'm aware of CVE-2019-6260. I just listed it as a potential
> > source of SIRQs.
> > > > The VUART is covered by this code and we don't have a PUART driver
> > >  > yet.
> > >  >
> > >  > It might make sense to have this as a global setting which each
> driver
> > >  > could read. But wouldn't this be an exercise for the future where we
> > >  > actually have a second device? I don't think the Aspeed currently
> has
> > >  > any other devices that could generate a SIRQ (except for the PUART
> for
> > >  > which there's no driver).
> > >
> > >  We have a bunch of SIRQ sources that we use (on OpenPOWER platforms) -
> > >  the BT interface, the KCS interface, the UARTs, and the mbox hardware.
> > >  It's not just the VUART/PUART :)
> > Interesting. From what Aspeed explained, the SIRQ polarity for UARTs is
> > inverted to that for other devices. I haven't looked into how other
> > devices work, to be honest. Do we set the polarity there explicitly?
> > > > Having said that, ideally I'd like the SIRQ polarity to be auto-
> > >  > configured from the LPC/eSPI HW pin strap anyway. I have the code
> for
> > >  > that almost done. Maybe we shouldn't even have the sysfs interface
> for
> > >  > it and I should strip that out?
> > >
> > >  Yeah, I think I agree with that. The only downside is that the
> > >  individual drivers will now need to poke at the SCU to query the
> > >  LPC/eSPI configuration. If you can find a nice way to do that, then
> that
> > >  sounds like the best approach. Can you query it through the parent bus
> > >  perhaps?
> > I'm experimenting with this:
> > syscon_regmap_lookup_by_compatible("aspeed,ast2500-scu");
> >
> > I'll need to think on how to make this work on both ast2400 and
> > ast2500, though. I actually need to have a look at the ast2400 data
> > sheet wrt. VUART registers, too!
> >
> > The structure is this:
> > apb {
> >  syscon {
> >  ...
> >  }
> >  vuart {
> >  ...
> >  }
> > }
> >
> > So the vuart is a sibling of syscon, which holds the registers. I guess
> > I'll have to go with "by_compatible"?
>
> It might be better to add a property to the UART DT node that references
> the SCU syscon by phandle, that way you don't need to muck around
> with compatible names for the SCU syscon.
>
> Andrew
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linux-aspeed/attachments/20190730/a1c5c05f/attachment.htm>

^ permalink raw reply

* [PATCH v2 3/3] arm: dts: aspeed: Add vuart espi-enabled to aspeed-g5.dtsi
From: Oskar Senft @ 2019-07-31  1:34 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731013404.243755-1-osk@google.com>

Enable auto-configuration of VUART SIRQ polarity on AST2500.

Signed-off-by: Oskar Senft <osk@google.com>
---
 arch/arm/boot/dts/aspeed-g5.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 01ffe70f64d5..9e561504042a 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -351,6 +351,7 @@
 				interrupts = <8>;
 				clocks = <&syscon ASPEED_CLK_APB>;
 				no-loopback-test;
+				espi-enabled = <&syscon 0x70 25>;
 				status = "disabled";
 			};
 
-- 
2.22.0.709.g102302147b-goog


^ permalink raw reply related

* [PATCH v2 2/3] dt-bindings: serial: 8250: Add documentation for espi-enabled.
From: Oskar Senft @ 2019-07-31  1:34 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190731013404.243755-1-osk@google.com>

Add documentation for 8250_aspeed_vuart's espi-enabled property that
enables to auto-configure the VUART's SIRQ polarity.

Signed-off-by: Oskar Senft <osk@google.com>
---
 Documentation/devicetree/bindings/serial/8250.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
index 20d351f268ef..4b8b9e502179 100644
--- a/Documentation/devicetree/bindings/serial/8250.txt
+++ b/Documentation/devicetree/bindings/serial/8250.txt
@@ -56,6 +56,11 @@ Optional properties:
 - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
   line respectively. It will use specified GPIO instead of the peripheral
   function pin for the UART feature. If unsure, don't specify this property.
+- espi-enabled: Only applicable to aspeed,ast2500-vuart. Value is a phandle to
+  aspeed,ast2500-scu syscon alongside register offset and bit number to
+  identify whether the system is in eSPI mode. This is used to auto-configure
+  SIRQ polarity on the vuart.
+  Example: espi-enabled = <&syscon 0x70 25>
 
 Note:
 * fsl,ns16550:
-- 
2.22.0.709.g102302147b-goog


^ permalink raw reply related

* [PATCH v2 1/3] drivers/tty/serial/8250: Make Aspeed VUART SIRQ polarity configurable
From: Oskar Senft @ 2019-07-31  1:34 UTC (permalink / raw)
  To: linux-aspeed

Make the SIRQ polarity for Aspeed AST24xx/25xx VUART configurable via
sysfs. This setting need to be changed on specific host platforms
depending on the selected host interface (LPC / eSPI).

The setting is configurable via sysfs rather than device-tree to stay in
line with other related configurable settings.

On AST2500 the VUART SIRQ polarity can be auto-configured by reading the
LPC/eSPI interface configuration from the HW strap table.

Tested: Verified on TYAN S7106 mainboard.
Signed-off-by: Oskar Senft <osk@google.com>
---
 .../ABI/stable/sysfs-driver-aspeed-vuart      | 10 ++-
 drivers/tty/serial/8250/8250_aspeed_vuart.c   | 82 +++++++++++++++++++
 drivers/tty/serial/8250/Kconfig               |  1 +
 3 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/stable/sysfs-driver-aspeed-vuart b/Documentation/ABI/stable/sysfs-driver-aspeed-vuart
index 8062953ce77b..64fad87ad964 100644
--- a/Documentation/ABI/stable/sysfs-driver-aspeed-vuart
+++ b/Documentation/ABI/stable/sysfs-driver-aspeed-vuart
@@ -6,10 +6,18 @@ Description:	Configures which IO port the host side of the UART
 Users:		OpenBMC.  Proposed changes should be mailed to
 		openbmc at lists.ozlabs.org
 
-What:		/sys/bus/platform/drivers/aspeed-vuart*/sirq
+What:		/sys/bus/platform/drivers/aspeed-vuart/*/sirq
 Date:		April 2017
 Contact:	Jeremy Kerr <jk@ozlabs.org>
 Description:	Configures which interrupt number the host side of
 		the UART will appear on the host <-> BMC LPC bus.
 Users:		OpenBMC.  Proposed changes should be mailed to
 		openbmc at lists.ozlabs.org
+
+What:		/sys/bus/platform/drivers/aspeed-vuart/*/sirq_polarity
+Date:		July 2019
+Contact:	Oskar Senft <osk@google.com>
+Description:	Configures the polarity of the serial interrupt to the
+		host via the BMC LPC bus.
+Users:		OpenBMC.  Proposed changes should be mailed to
+		openbmc at lists.ozlabs.org
diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c
index 0438d9a905ce..e0e441c38541 100644
--- a/drivers/tty/serial/8250/8250_aspeed_vuart.c
+++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c
@@ -14,6 +14,8 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/clk.h>
@@ -22,6 +24,7 @@
 
 #define ASPEED_VUART_GCRA		0x20
 #define ASPEED_VUART_GCRA_VUART_EN		BIT(0)
+#define ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY	BIT(1)
 #define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5)
 #define ASPEED_VUART_GCRB		0x24
 #define ASPEED_VUART_GCRB_HOST_SIRQ_MASK	GENMASK(7, 4)
@@ -131,8 +134,53 @@ static ssize_t sirq_store(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR_RW(sirq);
 
+static ssize_t sirq_polarity_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct aspeed_vuart *vuart = dev_get_drvdata(dev);
+	u8 reg;
+
+	reg = readb(vuart->regs + ASPEED_VUART_GCRA);
+	reg &= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
+
+	return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg ? 1 : 0);
+}
+
+static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart,
+					   bool polarity)
+{
+	u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA);
+
+	if (polarity)
+		reg |= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
+	else
+		reg &= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
+
+	writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
+}
+
+static ssize_t sirq_polarity_store(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t count)
+{
+	struct aspeed_vuart *vuart = dev_get_drvdata(dev);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 0, &val);
+	if (err)
+		return err;
+
+	aspeed_vuart_set_sirq_polarity(vuart, val != 0);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(sirq_polarity);
+
 static struct attribute *aspeed_vuart_attrs[] = {
 	&dev_attr_sirq.attr,
+	&dev_attr_sirq_polarity.attr,
 	&dev_attr_lpc_address.attr,
 	NULL,
 };
@@ -302,6 +350,27 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
 	return 1;
 }
 
+static void aspeed_vuart_auto_configure_sirq_polarity(
+	struct aspeed_vuart *vuart, struct device_node *syscon_np,
+	u32 reg_offset, u32 reg_mask)
+{
+	struct regmap *regmap;
+	u32 value;
+
+	regmap = syscon_node_to_regmap(syscon_np);
+	if (IS_ERR(regmap)) {
+		dev_warn(vuart->dev,
+			 "could not get regmap for espi-enabled\n");
+		return;
+	}
+	if (regmap_read(regmap, reg_offset, &value)) {
+		dev_warn(vuart->dev, "could not read hw strap table\n");
+		return;
+	}
+
+	aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0);
+}
+
 static int aspeed_vuart_probe(struct platform_device *pdev)
 {
 	struct uart_8250_port port;
@@ -310,6 +379,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 	struct resource *res;
 	u32 clk, prop;
 	int rc;
+	struct of_phandle_args espi_enabled_args;
 
 	np = pdev->dev.of_node;
 
@@ -402,6 +472,18 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 
 	vuart->line = rc;
 
+	rc = of_parse_phandle_with_fixed_args(
+		np, "espi-enabled", 2, 0, &espi_enabled_args);
+	if (rc < 0) {
+		dev_warn(&pdev->dev, "espi-enabled property not found\n");
+	} else {
+		aspeed_vuart_auto_configure_sirq_polarity(
+			vuart, espi_enabled_args.np,
+			espi_enabled_args.args[0],
+			BIT(espi_enabled_args.args[1]));
+		of_node_put(espi_enabled_args.np);
+	}
+
 	aspeed_vuart_set_enabled(vuart, true);
 	aspeed_vuart_set_host_tx_discard(vuart, true);
 	platform_set_drvdata(pdev, vuart);
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 509f6a3bb9ff..98e25781a293 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -243,6 +243,7 @@ config SERIAL_8250_ASPEED_VUART
 	tristate "Aspeed Virtual UART"
 	depends on SERIAL_8250
 	depends on OF
+	depends on REGMAP && MFD_SYSCON
 	help
 	  If you want to use the virtual UART (VUART) device on Aspeed
 	  BMC platforms, enable this option. This enables the 16550A-
-- 
2.22.0.709.g102302147b-goog


^ permalink raw reply related

* [PATCH] ARM: dts: aspeed: Add Mihawk BMC platform
From: Andrew Jeffery @ 2019-07-31  0:51 UTC (permalink / raw)
  To: linux-aspeed
In-Reply-To: <20190730060029.25268-1-Ben_Pai@wistron.com>

Hello Ben,

Thanks for the patch! Some minor comments below.

On Tue, 30 Jul 2019, at 15:30, Ben Pai wrote:
> The Mihawk BMC is an ASPEED ast2500 based BMC that is part of an
> OpenPower Power9 server.
> 
> This adds the device tree description for most upstream components. It
> is a squashed commit from the OpenBMC kernel tree.

That it's a squashed commit isn't relevant, neither is the mention of the OpenBMC
kernel tree. I'd drop both from the commit message.

> 
> Signed-off-by: Ben Pai <Ben_Pai@wistron.com>
> ---
>  arch/arm/boot/dts/Makefile                  |   1 +
>  arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts | 922 ++++++++++++++++++++
>  2 files changed, 923 insertions(+)
>  create mode 100755 arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index eb6de52c1936..262345544359 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1281,5 +1281,6 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>  	aspeed-bmc-opp-vesnin.dtb \
>  	aspeed-bmc-opp-witherspoon.dtb \
>  	aspeed-bmc-opp-zaius.dtb \
> +	aspeed-bmc-opp-mihawk.dtb \
>  	aspeed-bmc-portwell-neptune.dtb \
>  	aspeed-bmc-quanta-q71l.dtb
> diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts 
> b/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
> new file mode 100755
> index 000000000000..cfa20e0b2939
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
> @@ -0,0 +1,922 @@
> +/dts-v1/;
> +
> +#include "aspeed-g5.dtsi"
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +#include <dt-bindings/leds/leds-pca955x.h>
> +
> +/ {
> +	model = "Mihawk BMC";
> +	compatible = "ibm,mihawk-bmc", "aspeed,ast2500";

I think this should be "ips,mihawk-bmc". You may also need to add "ips" to the
vendor-prefixes list. 

> +
> +
> +	chosen {
> +		stdout-path = &uart5;
> +		bootargs = "console=ttyS4,115200 earlyprintk";
> +	};
> +
> +	memory at 80000000 {
> +		reg = <0x80000000 0x20000000>; /* address and size of RAM(512MB) */
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		flash_memory: region at 98000000 {
> +			no-map;
> +			reg = <0x98000000 0x04000000>; /* 64M */
> +		};
> +
> +		gfx_memory: framebuffer {
> +			size = <0x01000000>;
> +			alignment = <0x01000000>;
> +			compatible = "shared-dma-pool";
> +			reusable;
> +		};
> +
> +		video_engine_memory: jpegbuffer {
> +			size = <0x02000000>;	/* 32MM */
> +			alignment = <0x01000000>;
> +			compatible = "shared-dma-pool";
> +			reusable;
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		air-water {
> +			label = "air-water";
> +			gpios = <&gpio ASPEED_GPIO(F, 6) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(F, 6)>;
> +		};
> +
> +		checkstop {
> +			label = "checkstop";
> +			gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(J, 2)>;
> +		};
> +
> +		ps0-presence {
> +			label = "ps0-presence";
> +			gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(Z, 2)>;
> +		};
> +
> +		ps1-presence {
> +			label = "ps1-presence";
> +			gpios = <&gpio ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(Z, 0)>;
> +		};
> +		id-button {
> +			label = "id-button";
> +			gpios = <&gpio ASPEED_GPIO(F, 1) GPIO_ACTIVE_LOW>;
> +			linux,code = <ASPEED_GPIO(F, 1)>;
> +		};
> +	};
> +
> +	gpio-keys-polled {
> +		compatible = "gpio-keys-polled";
> +		#address-cells = <1>;
> +		#size-cells = <0>;

Please remove the #address-cells and #size-cells properties, they aren't
relevant for gpio-keys-polled.

> +		poll-interval = <1000>;
> +
> +		fan0-presence {
> +			label = "fan0-presence";
> +			gpios = <&pca9552 9 GPIO_ACTIVE_LOW>;
> +			linux,code = <9>;
> +		};
> +
> +		fan1-presence {
> +			label = "fan1-presence";
> +			gpios = <&pca9552 10 GPIO_ACTIVE_LOW>;
> +			linux,code = <10>;
> +		};
> +
> +		fan2-presence {
> +			label = "fan2-presence";
> +			gpios = <&pca9552 11 GPIO_ACTIVE_LOW>;
> +			linux,code = <11>;
> +		};
> +
> +		fan3-presence {
> +			label = "fan3-presence";
> +			gpios = <&pca9552 12 GPIO_ACTIVE_LOW>;
> +			linux,code = <12>;
> +		};
> +
> +		fan4-presence {
> +			label = "fan4-presence";
> +			gpios = <&pca9552 13 GPIO_ACTIVE_LOW>;
> +			linux,code = <13>;
> +		};
> +
> +		fan5-presence {
> +			label = "fan5-presence";
> +			gpios = <&pca9552 14 GPIO_ACTIVE_LOW>;
> +			linux,code = <14>;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		fault {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		power {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 1) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		rear-id {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		rear-g {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(AA, 4) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		rear-ok {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&gpio ASPEED_GPIO(Y, 0) GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan0 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 0 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan1 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 1 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan2 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 2 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan3 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 3 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan4 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 4 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		fan5 {
> +			retain-state-shutdown;
> +			default-state = "keep";
> +			gpios = <&pca9552 5 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +
> +	fsi: gpio-fsi {
> +		compatible = "fsi-master-gpio", "fsi-master";
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +		no-gpio-delays;
> +
> +		clock-gpios = <&gpio ASPEED_GPIO(E, 6) GPIO_ACTIVE_HIGH>;
> +		data-gpios = <&gpio ASPEED_GPIO(E, 7) GPIO_ACTIVE_HIGH>;
> +		mux-gpios = <&gpio ASPEED_GPIO(E, 5) GPIO_ACTIVE_HIGH>;
> +		enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
> +		trans-gpios = <&gpio ASPEED_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
> +	};
> +	iio-hwmon-12v {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 0>;
> +	};
> +	
> +	iio-hwmon-5v {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 1>;
> +	};
> +	
> +	iio-hwmon-3v {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 2>;
> +	};
> +		
> +	iio-hwmon-vdd0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 3>;
> +	};
> +	
> +	iio-hwmon-vdd1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 4>;
> +	};
> +	
> +	iio-hwmon-vcs0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 5>;
> +	};
> +	
> +	iio-hwmon-vcs1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 6>;
> +	};
> +
> +	iio-hwmon-vdn0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 7>;
> +	};
> +	
> +	iio-hwmon-vdn1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 8>;
> +	};
> +	
> +	iio-hwmon-vio0 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 9>;
> +	};
> +	
> +	iio-hwmon-vio1 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 10>;
> +	};
> +	
> +	iio-hwmon-vddra {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 11>;
> +	};
> +	
> +	iio-hwmon-vddrb {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 13>;
> +	};
> +	
> +	iio-hwmon-vddrc {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 14>;
> +	};
> +	
> +	iio-hwmon-vddrd {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 15>;
> +	};
> +	
> +	iio-hwmon-battery {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc 12>;
> +	};
> +};
> +
> +&pwm_tacho {
> +	status = "okay";
> +	/*compatible = "aspeed,ast2500-pwm-tacho";
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	reg = <0x1e786000 0x1000>;
> +	clocks = <&pwm_tacho_fixed_clk>;*/
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default
> +		&pinctrl_pwm2_default &pinctrl_pwm3_default
> +		&pinctrl_pwm4_default &pinctrl_pwm5_default>;
> +
> +	fan at 0 {
> +		reg = <0x00>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x00>;
> +	};
> +
> +	fan at 1 {
> +		reg = <0x01>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x01>;
> +	};
> +
> +	fan at 2 {
> +		reg = <0x02>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x02>;
> +	};
> +
> +	fan at 3 {
> +		reg = <0x03>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x03>;
> +	};
> +
> +	fan at 4 {
> +		reg = <0x04>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x04>;
> +	};
> +
> +	fan at 5 {
> +		reg = <0x05>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x05>;
> +	};
> +
> +	fan at 6 {
> +		reg = <0x00>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x06>;
> +	};
> +
> +	fan at 7 {
> +		reg = <0x01>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x07>;
> +	};
> +
> +	fan at 8 {
> +		reg = <0x02>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x08>;
> +	};
> +
> +	fan at 9 {
> +		reg = <0x03>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x09>;
> +	};
> +
> +	fan at 10 {
> +		reg = <0x04>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x0a>;
> +	};
> +
> +	fan at 11 {
> +		reg = <0x05>;
> +		aspeed,fan-tach-ch = /bits/ 8 <0x0b>;
> +	};
> +};
> +
> +&fmc {
> +	status = "okay";
> +	flash at 0 {
> +		status = "okay";
> +		label = "bmc";
> +		m25p,fast-read;
> +		spi-max-frequency = <50000000>;
> +		partitions {
> +			#address-cells = < 1 >;
> +			#size-cells = < 1 >;
> +			compatible = "fixed-partitions";
> +			u-boot at 0 {
> +				reg = < 0 0x60000 >;
> +				label = "u-boot";
> +			};
> +			u-boot-env at 60000 {
> +				reg = < 0x60000 0x20000 >;
> +				label = "u-boot-env";
> +			};
> +			obmc-ubi at 80000 {
> +				reg = < 0x80000 0x1F80000 >;
> +				label = "obmc-ubi";
> +			};
> +		};
> +	};
> +	flash at 1 {
> +		status = "okay";
> +		label = "alt-bmc";
> +		m25p,fast-read;
> +		spi-max-frequency = <50000000>;
> +		partitions {
> +			#address-cells = < 1 >;
> +			#size-cells = < 1 >;
> +			compatible = "fixed-partitions";
> +			u-boot at 0 {
> +				reg = < 0 0x60000 >;
> +				label = "alt-u-boot";
> +			};
> +			u-boot-env at 60000 {
> +				reg = < 0x60000 0x20000 >;
> +				label = "alt-u-boot-env";
> +			};
> +			obmc-ubi at 80000 {
> +				reg = < 0x80000 0x1F80000 >;
> +				label = "alt-obmc-ubi";
> +			};
> +		};
> +	};
> +};
> +
> +&spi1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_spi1_default>;
> +
> +	flash at 0 {
> +		status = "okay";
> +		label = "pnor";
> +		m25p,fast-read;
> +		spi-max-frequency = <100000000>;
> +	};
> +};
> +
> +&lpc_ctrl {
> +	status = "okay";
> +	memory-region = <&flash_memory>;
> +	flash = <&spi1>;
> +};
> +
> +&uart1 {
> +	/* Rear RS-232 connector */
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_txd1_default
> +			&pinctrl_rxd1_default
> +			&pinctrl_nrts1_default
> +			&pinctrl_ndtr1_default
> +			&pinctrl_ndsr1_default
> +			&pinctrl_ncts1_default
> +			&pinctrl_ndcd1_default
> +			&pinctrl_nri1_default>;
> +};
> +
> +&uart2 {
> +	/* APSS */
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>;
> +};
> +
> +&uart5 {
> +	status = "okay";
> +};
> +
> +&mac0 {
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rmii1_default>;
> +	use-ncsi;
> +};
> +
> +&mac1 {
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
> +};
> +
> +&i2c0 {
> +	status = "disabled";
> +};
> +
> +&i2c1 {
> +	status = "disabled";
> +};
> +
> +&i2c2 {
> +	status = "okay";
> +
> +	/* SAMTEC P0 */
> +	/* SAMTEC P1 */
> +	
> +};
> +
> +&i2c3 {
> +	status = "okay";
> +
> +	/* APSS */
> +	/* CPLD */
> +
> +	/* PCA9516 (repeater) ->
> +	 *    CLK Buffer 9FGS9092
> +	 *    CLK Buffer 9DBL0651BKILFT
> +	 *    CLK Buffer 9DBL0651BKILFT
> +	 *    Power Supply 0
> +	 *    Power Supply 1
> +	 *    PCA 9552 LED
> +	 */
> +	 
> +	power-supply at 58 {
> +		compatible = "ibm,cffps1";
> +		reg = <0x58>;
> +	};
> +
> +	power-supply at 5b {
> +		compatible = "ibm,cffps1";
> +		reg = <0x5b>;
> +	};
> +
> +	pca9552: pca9552 at 60 {
> +		compatible = "nxp,pca9552";
> +		reg = <0x60>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		gpio at 0 {
> +			reg = <0>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 1 {
> +			reg = <1>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 2 {
> +			reg = <2>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 3 {
> +			reg = <3>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 4 {
> +			reg = <4>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 5 {
> +			reg = <5>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 6 {
> +			reg = <6>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 7 {
> +			reg = <7>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 8 {
> +			reg = <8>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 9 {
> +			reg = <9>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 10 {
> +			reg = <10>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 11 {
> +			reg = <11>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 12 {
> +			reg = <12>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 13 {
> +			reg = <13>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 14 {
> +			reg = <14>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +		gpio at 15 {
> +			reg = <15>;
> +			type = <PCA955X_TYPE_GPIO>;
> +		};
> +
> +	};
> +
> +};
> +
> +&i2c4 {
> +	status = "okay";
> +
> +	/* CP0 VDD & VCS : IR35221 */
> +	/* CP0 VDN : IR35221 */
> +	/* CP0 VIO : IR38064 */
> +        /* CP0 VDDR : PXM1330 */
> +
> +	ir35221 at 70 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x70>;
> +	};
> +
> +	ir35221 at 72 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x72>;
> +	};
> +
> +};
> +
> +&i2c5 {
> +	status = "okay";
> +	
> +	/* CP0 VDD & VCS : IR35221 */
> +	/* CP0 VDN : IR35221 */
> +	/* CP0 VIO : IR38064 */
> +        /* CP0 VDDR : PXM1330 */
> +
> +	ir35221 at 70 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x70>;
> +	};
> +
> +	ir35221 at 72 {
> +		compatible = "infineon,ir35221";
> +		reg = <0x72>;
> +	};
> +	
> +};
> +
> +&i2c6 {
> +	status = "okay";
> +	
> +	/* pca9548 -> NVMe1 to 8 */
> +	
> +	pca9548 at 70 {
> +		compatible = "nxp,pca9548";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +	};
> +	
> +};
> +
> +&i2c7 {
> +	status = "okay";
> +	
> +	/* pca9548 -> NVMe9 to 16 */
> +	
> +	pca9548 at 70 {
> +		compatible = "nxp,pca9548";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +	};
> +	
> +};
> +
> +&i2c8 {
> +	status = "okay";
> +
> +	/* FSI CLK/DAT */

This comment doesn't make sense?

> +	eeprom at 50 {
> +		compatible = "atmel,24c64";
> +		reg = <0x50>;
> +	};
> +};
> +
> +&i2c9 {
> +	status = "okay";
> +	
> +	/* pca9545 Riser -> 
> +	* 	PCIe x8  Slot3 
> +	* 	PCIe x16 slot4 
> +	* 	PCIe x8  slot5 
> +	* 	I2C BMC RISER PCA9554
> +	* 	BMC SCL/SDA PCA9554 
> +	* 	PCA9554
> +	*/
> +	
> +	/* pca9545 -> 
> +	* 	PCIe x16 Slot1 
> +	* 	PCIe x8  slot2 
> +	* 	PEX8748 
> +	*/
> +
> +	pca9545riser at 70 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +
> +		/*interrupt-parent = <&ipic>;*/
> +		/*interrupts = <17 IRQ_TYPE_LEVEL_LOW>;*/
> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +	
> +	pca9545 at 71 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x71>;
> +
> +		/*interrupt-parent = <&ipic>;*/
> +		/*interrupts = <17 IRQ_TYPE_LEVEL_LOW>;*/
> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;	
> +	};
> +};
> +
> +&i2c10 {
> +	status = "okay";
> +	
> +	/* pca9545 Riser -> 
> +	* 	PCIe x8  Slot8 
> +	* 	PCIe x16 slot9 
> +	* 	PCIe x8  slot10 
> +	* 	I2C BMC RISER PCA9554
> +	* 	BMC SCL/SDA PCA9554 
> +	* 	PCA9554
> +	*/
> +	
> +	/* pca9545 -> 
> +	* 	PCIe x16 Slot1 
> +	* 	PCIe x8  slot2 
> +	* 	PEX8748 
> +	*/
> +	
> +	pca9545riser at 70 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +
> +		/*interrupt-parent = <&ipic>;*/
> +		/*interrupts = <17 IRQ_TYPE_LEVEL_LOW>;*/

Remove the commented properties.

> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +	
> +	pca9545 at 71 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x71>;
> +
> +		/*interrupt-parent = <&ipic>;*/
> +		/*interrupts = <17 IRQ_TYPE_LEVEL_LOW>;*/

Again here.

> +		i2c-mux-idle-disconnect;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;	
> +	};
> +};
> +
> +&i2c11 {
> +	status = "okay";
> +	
> +	/* TPM */
> +	/* RTC RX8900CE */
> +	/* FPGA for power sequence */
> +	/* TMP275A */
> +	/* TMP275A */
> +	/* EMC1462 */
> +
> +	tpm at 57 {
> +		compatible = "infineon,slb9645tt";
> +		reg = <0x57>;
> +	};
> +	
> +	rtc at 32 {
> +		compatible = "epson,rx8900";
> +		reg = <0x32>;
> +	};
> +	
> +	tmp275 at 48 {
> +		compatible = "ti,tmp275";
> +		reg = <0x48>;
> +	};
> +	
> +	tmp275 at 49 {
> +		compatible = "ti,tmp275";
> +		reg = <0x49>;
> +	};
> +
> +    /* chip emc1462 use emc1403 driver */
> +    emc1403 at 4c {
> +        compatible = "smsc,emc1403";
> +        reg = <0x4c>;
> +    };
> +
> +};
> +
> +&i2c12 {
> +	status = "okay";
> +
> +	/* pca9545 ->
> +	*	SAS BP1
> +	*	SAS BP2
> +	*	NVMe BP
> +	*	M.2 riser
> +	*/
> +	
> +	pca9545 at 70 {
> +		compatible = "nxp,pca9545";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +
> +		/*interrupt-parent = <&ipic>;*/
> +		/*interrupts = <17 IRQ_TYPE_LEVEL_LOW>;*/
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		
> +		i2c at 0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +			
> +			eeprom at 50 {
> +				compatible = "atmel,24c64";
> +				reg = <0x50>;
> +			};
> +		};
> +		
> +		i2c at 1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +			
> +			eeprom at 50 {
> +				compatible = "atmel,24c64";
> +				reg = <0x50>;
> +			};
> +		};
> +		
> +		i2c at 2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +			
> +			eeprom at 50 {
> +				compatible = "atmel,24c64";
> +				reg = <0x50>;
> +			};
> +		};
> +		
> +		i2c at 3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +			
> +			tmp275 at 48 {
> +				compatible = "ti,tmp275";
> +				reg = <0x48>;
> +			};
> +		};
> +		
> +	};
> +	
> +};
> +
> +&i2c13 {
> +	status = "okay";
> +	
> +	/* pca9548 ->
> +	*	NVMe BP
> +	*	NVMe HDD17 to 24
> +	*/
> +	
> +	pca9548 at 70 {
> +		compatible = "nxp,pca9548";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <0x70>;
> +	};	
> +};
> +
> +&vuart {
> +	status = "okay";
> +};
> +
> +&gfx {
> +	status = "okay";
> +	memory-region = <&gfx_memory>;
> +};
> +
> +&pinctrl {
> +	aspeed,external-nodes = <&gfx &lhc>;

This is already provided by aspeed-g5.dtsi, please drop it.

> +};
> +
> +&adc {
> +	status = "okay";

Please add the pinmux properties to mux the ADC lines that you're using

> +};
> +
> +&wdt1 {
> +	aspeed,reset-type = "none";
> +	aspeed,external-signal;
> +	aspeed,ext-push-pull;
> +	aspeed,ext-active-high;
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_wdtrst1_default>;
> +};
> +
> +&wdt2 {
> +	aspeed,alt-boot;
> +};
> +
> +&ibt {
> +	status = "okay";
> +};
> +
> +&vhub {
> +	status = "okay";
> +};
> +
> +&video {
> +	status = "okay";
> +	memory-region = <&video_engine_memory>;
> +};
> +
> +#include "ibm-power9-dual.dtsi"
> \ No newline at end of file

Add a newline here to avoid the warning.

> -- 
> 2.17.1
> 
> 
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------
> This email contains confidential or legally privileged information and 
> is for the sole use of its intended recipient. 
> Any unauthorized review, use, copying or distribution of this email or 
> the content of this email is strictly prohibited.
> If you are not the intended recipient, you may reply to the sender and 
> should delete this e-mail immediately.
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------
>

Please try to avoid posting footers like this to public mailing lists.

Cheers,

Andrew

^ 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