[U-Boot] [PATCH v3 3/6] arm64: mvebu: pinctrl: Add pin control driver for A8K family

kostap at marvell.com kostap at marvell.com
Mon Dec 5 11:16:44 CET 2016


From: Konstantin Porotchkin <kostap at marvell.com>

Add a DM port of Marvell pin control driver.
The A8K SoC family contains several silicone dies interconnected
in a single package. Every die is normally equipped with its own
pin controller unit.
There are 2 pin controllers in A70x0 SoC and 3 in A80x0 SoC.

Changes for v3:
- Extend the Kconfig help for pin control driver

Signed-off-by: Konstantin Porotchkin <kostap at marvell.com>
Cc: Simon Glass <sjg at chromium.org>
Cc: Stefan Roese <sr at denx.de>
Cc: Nadav Haklai <nadavh at marvell.com>
Cc: Neta Zur Hershkovits <neta at marvell.com>
Cc: Omri Itach <omrii at marvell.com>
Cc: Igal Liberman <igall at marvell.com>
Cc: Haim Boot <hayim at marvell.com>
Cc: Hanna Hawa <hannah at marvell.com>
---
 arch/arm/include/asm/arch-armada8k/soc-info.h      |  17 ++
 .../pinctrl/marvell,armada-apn806-pinctrl.txt      |  25 ++
 .../pinctrl/marvell,armada-cp110-pinctrl.txt       | 270 +++++++++++++++++++++
 .../pinctrl/marvell,mvebu-pinctrl.txt              | 113 +++++++++
 drivers/pinctrl/Kconfig                            |   1 +
 drivers/pinctrl/Makefile                           |   1 +
 drivers/pinctrl/mvebu/Kconfig                      |  16 ++
 drivers/pinctrl/mvebu/Makefile                     |   7 +
 drivers/pinctrl/mvebu/pinctrl-mvebu.c              | 179 ++++++++++++++
 drivers/pinctrl/mvebu/pinctrl-mvebu.h              |  31 +++
 10 files changed, 660 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-armada8k/soc-info.h
 create mode 100644 doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt
 create mode 100644 doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt
 create mode 100644 doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt
 create mode 100644 drivers/pinctrl/mvebu/Kconfig
 create mode 100644 drivers/pinctrl/mvebu/Makefile
 create mode 100644 drivers/pinctrl/mvebu/pinctrl-mvebu.c
 create mode 100644 drivers/pinctrl/mvebu/pinctrl-mvebu.h

diff --git a/arch/arm/include/asm/arch-armada8k/soc-info.h b/arch/arm/include/asm/arch-armada8k/soc-info.h
new file mode 100644
index 0000000..bae3995
--- /dev/null
+++ b/arch/arm/include/asm/arch-armada8k/soc-info.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ * https://spdx.org/licenses
+ */
+
+#ifndef _SOC_INFO_H_
+#define _SOC_INFO_H_
+
+/* Pin Ctrl driver definitions */
+#define BITS_PER_PIN		4
+#define PIN_FUNC_MASK		((1 << BITS_PER_PIN) - 1)
+#define PIN_REG_SHIFT		3
+#define PIN_FIELD_MASK		((1 << PIN_REG_SHIFT) - 1)
+
+#endif	/* _SOC_INFO_H_ */
diff --git a/doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt
new file mode 100644
index 0000000..51f2f2c
--- /dev/null
+++ b/doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt
@@ -0,0 +1,25 @@
+	Functions of Armada APN806 pin controller
+	Function 0x0 for any MPP ID activates GPIO pin mode
+----------------------------------------------------------------------
+MPP#	0x1			0x2		0x3		0x4
+----------------------------------------------------------------------
+0	SDIO_CLK		-		SPI0_CLK 	-
+1	SDIO_CMD		-		SPI0_MISO	-
+2	SDIO_D[0]		-		SPI0_MOSI 	-
+3	SDIO_D[1]		-		SPI0_CS0n 	-
+4	SDIO_D[2]		-		I2C0_SDA	SPI0_CS1n
+5	SDIO_D[3]		-		I2C0_SCK	-
+6	SDIO_DS			-		-		-
+7	SDIO_D[4]		-		UART1_RXD	-
+8	SDIO_D[5]		-		UART1_TXD 	-
+9	SDIO_D[6]		-		SPI0_CS1n 	-
+10	SDIO_D[7]		-		-		-
+11	-			-		UART0_TXD 	-
+12	SDIO_CARD_PW_OFF 	SDIO_HW_RST 	-		-
+13	-			-		-		-
+14	-			-		-		-
+15	-			-		-		-
+16	-			-		-		-
+17	-			-		-		-
+18	-			-		-		-
+19	-			-		UART0_RXD	-
diff --git a/doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt
new file mode 100644
index 0000000..3adcf3a
--- /dev/null
+++ b/doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt
@@ -0,0 +1,270 @@
+	Functions of Armada CP110 pin controller
+	Function 0x0 for any MPP ID activates GPIO pin mode
+	Function 0xc for any MPP ID activates DEBUG_BUS pin mode
+-------------------------------------------------------------------------------
+MPP#	0x1			0x2		0x3		0x4
+-------------------------------------------------------------------------------
+0	DEV_ALE[1]		AU_I2SMCLK	GE0_RXD[3]	TDM_PCLK
+1	DEV_ALE[0]		AU_I2SDO_SPDIFO	GE0_RXD[2]	TDM_DRX
+2	DEV_AD[15]		AU_I2SEXTCLK	GE0_RXD[1]	TDM_DTX
+3	DEV_AD[14]		AU_I2SLRCLK	GE0_RXD[0]	TDM_FSYNC
+4	DEV_AD[13]		AU_I2SBCLK	GE0_RXCTL	TDM_RSTn
+5	DEV_AD[12]		AU_I2SDI	GE0_RXCLK	TDM_INTn
+6	DEV_AD[11]		-		GE0_TXD[3]	SPI0_CSn[2]
+7	DEV_AD[10]		-		GE0_TXD[2]	SPI0_CSn[1]
+8	DEV_AD[9]		-		GE0_TXD[1]	SPI0_CSn[0]
+9	DEV_AD[8]		-		GE0_TXD[0]	SPI0_MOSI
+10	DEV_READYn		-		GE0_TXCTL	SPI0_MISO
+11	DEV_WEn[1]		-		GE0_TXCLKOUT	SPI0_CLK
+12	DEV_CLK_OUT		NF_RBn[1]	SPI1_CSn[1]	GE0_RXCLK
+13	DEV_BURSTn		NF_RBn[0]	SPI1_MISO	GE0_RXCTL
+14	DEV_BOOTCSn		DEV_CSn[0]	SPI1_CSn[0]	SPI0_CSn[3]
+15	DEV_AD[7]		-		SPI1_MOSI	-
+16	DEV_AD[6]		-		SPI1_CLK	-
+17	DEV_AD[5]		-		-		GE0_TXD[3]
+18	DEV_AD[4]		-		-		GE0_TXD[2]
+19	DEV_AD[3]		-		-		GE0_TXD[1]
+20	DEV_AD[2]		-		-		GE0_TXD[0]
+21	DEV_AD[1]		-		-		GE0_TXCTL
+22	DEV_AD[0]		-		-		GE0_TXCLKOUT
+23	DEV_A[1]		-		-		-
+24	DEV_A[0]		-		-		-
+25	DEV_OEn	-		-		-		-
+26	DEV_WEn[0]		-		-		-
+27	DEV_CSn[0]		SPI1_MISO	MSS_GPIO[4]	GE0_RXD[3]
+28	DEV_CSn[1]		SPI1_CSn[0]	MSS_GPIO[5]	GE0_RXD[2]
+29	DEV_CSn[2]		SPI1_MOSI	MSS_GPIO[6]	GE0_RXD[1]
+30	DEV_CSn[3]		SPI1_CLK	MSS_GPIO[7]	GE0_RXD[0]
+31	DEV_A[2]		-		MSS_GPIO[4]	-
+32	MII_COL			MII_TXERR	MSS_SPI_MISO	TDM_DRX
+33	MII_TXCLK		SDIO_PWR1[0]	MSS_SPI_CSn	TDM_FSYNC
+34	MII_RXERR		SDIO_PWR1[1]	MSS_SPI_MOSI	TDM_DTX
+35	SATA1_PRESENT_ACTIVEn	TWSI1_SDA	MSS_SPI_CLK	TDM_PCLK
+36	SYNCE2_CLK		TWSI1_SCK	PTP_CLK		SYNCE1_CLK
+37	UART2_RXD		TWSI0_SCK	PTP_PCLK_OUT	TDM_INTn
+38	UART2_TXD		TWSI0_SDA	PTP_PULSE	TDM_RSTn
+39	SDIO_WR_PROTECT		-	-	AU_I2SBCLK	PTP_CLK
+40	SDIO_PWR1[1]		SYNCE1_CLK	MSS_TWSI_SDA	AU_I2SDO_SPDIFO
+41	SDIO_PWR1[0]		SDIO_BUS_PWR	MSS_TWSI_SCK	AU_I2SLRCLK
+42	SDIO_V18_EN		SDIO_WR_PROTECT	SYNCE2_CLK	AU_I2SMCLK
+43	SDIO_CARD_DETECT	-		SYNCE1_CLK	AU_I2SEXTCLK
+44	GE1_TXD[2]		-		-		-
+45	GE1_TXD[3]		-		-		-
+46	GE1_TXD[1]		-		-		-
+47	GE1_TXD[0]		-		-		-
+48	GE1_TXCTL_MII_TXEN	-		-		-
+49	GE1_TXCLKOUT		MII_CRS		-		-
+50	GE1_RXCLK		MSS_TWSI_SDA	-		-
+51	GE1_RXD[0]		MSS_TWSI_SCK	-		-
+52	GE1_RXD[1]		SYNCE1_CLK	-		SYNCE2_CLK
+53	GE1_RXD[2]		-		PTP_CLK		-
+54	GE1_RXD[3]		SYNCE2_CLK	PTP_PCLK_OUT	SYNCE1_CLK
+55	GE1_RXCTL_MII_RXDV	-		PTP_PULSE	-
+56	-			-		-		TDM_DRX
+57	-			MSS_TWSI_SDA	PTP_PCLK_OUT	TDM_INTn
+58	-			MSS_TWSI_SCK	PTP_CLK		TDM_RSTn
+59	MSS_GPIO[7]		SYNCE2_CLK	-		TDM_FSYNC
+60	MSS_GPIO[6]		-		PTP_PULSE	TDM_DTX
+61	MSS_GPIO[5]		-		PTP_CLK		TDM_PCLK
+62	MSS_GPIO[4]		SYNCE1_CLK	PTP_PCLK_OUT	-
+
+-------------------------------------------------------------------------------
+MPP#	0x5			0x6			0x7
+-------------------------------------------------------------------------------
+0	-			PTP_PULSE		MSS_TWSI_SDA
+1	-			PTP_CLK			MSS_TWSI_SCK
+2	MSS_UART_RXD		PTP_PCLK_OUT		TWSI1_SCK
+3	MSS_UART_TXD		PCIe_RSTOUTn		TWSI1_SDA
+4	MSS_UART_RXD		UART1_CTS		PCIe0_CLKREQ
+5	MSS_UART_TXD		UART1_RTS		PCIe1_CLKREQ
+6	AU_I2SEXTCLK		SATA1_PRESENT_ACTIVEn	PCIe2_CLKREQ
+7	SPI1_CSn[1]		SATA0_PRESENT_ACTIVEn	LED_DATA
+8	SPI1_CSn[0]		UART0_CTS		LED_STB
+9	SPI1_MOSI		-			PCIe_RSTOUTn
+10	SPI1_MISO		UART0_CTS		SATA1_PRESENT_ACTIVEn
+11	SPI1_CLK		UART0_RTS		LED_CLK
+12	-			-			-
+13	-			-			-
+14	AU_I2SEXTCLK		SPI0_MISO		SATA0_PRESENT_ACTIVEn
+15	-			SPI0_MOSI		-
+16	-			-			-
+17	-			-			-
+18	-			-			-
+19	-			-			-
+20	-			-			-
+21	-			-			-
+22	-			-			-
+23	AU_I2SMCLK		-			-
+24	AU_I2SLRCLK		-			-
+25	AU_I2SDO_SPDIFO		-			-
+26	AU_I2SBCLK		-			-
+27	SPI0_CSn[4]		-			-
+28	SPI0_CSn[5]		PCIe2_CLKREQ		PTP_PULSE
+29	SPI0_CSn[6]		PCIe1_CLKREQ		PTP_CLK
+30	SPI0_CSn[7]		PCIe0_CLKREQ		PTP_PCLK_OUT
+31	-			PCIe_RSTOUTn		-
+32	AU_I2SEXTCLK		AU_I2SDI		GE_MDIO
+33	AU_I2SMCLK		SDIO_BUS_PWR		-
+34	AU_I2SLRCLK		SDIO_WR_PROTECT		GE_MDC
+35	AU_I2SDO_SPDIFO		SDIO_CARD_DETECT	XG_MDIO
+36	AU_I2SBCLK		SATA0_PRESENT_ACTIVEn	XG_MDC
+37	MSS_TWSI_SCK		SATA1_PRESENT_ACTIVEn	GE_MDC
+38	MSS_TWSI_SDA		SATA0_PRESENT_ACTIVEn	GE_MDIO
+39	SPI0_CSn[1]		-			-
+40	PTP_PCLK_OUT		SPI0_CLK		UART1_TXD
+41	PTP_PULSE		SPI0_MOSI		UART1_RXD
+42	MSS_UART_TXD		SPI0_MISO		UART1_CTS
+43	MSS_UART_RXD		SPI0_CSn[0]		UART1_RTS
+44	-			-			UART0_RTS
+45	-			-			UART0_TXD
+46	-			-			UART1_RTS
+47	SPI1_CLK		-			UART1_TXD
+48	SPI1_MOSI		-			-
+49	SPI1_MISO		-			UART1_RXD
+50	SPI1_CSn[0]		UART2_TXD		UART0_RXD
+51	SPI1_CSn[1]		UART2_RXD		UART0_CTS
+52	SPI1_CSn[2]		-			UART1_CTS
+53	SPI1_CSn[3]		-			UART1_RXD
+54	-			-			-
+55	-			-			-
+56	AU_I2SDO_SPDIFO		SPI0_CLK		UART1_RXD
+57	AU_I2SBCLK		SPI0_MOSI		UART1_TXD
+58	AU_I2SDI		SPI0_MISO		UART1_CTS
+59	AU_I2SLRCLK		SPI0_CSn[0]		UART0_CTS
+60	AU_I2SMCLK		SPI0_CSn[1]		UART0_RTS
+61	AU_I2SEXTCLK		SPI0_CSn[2]		UART0_TXD
+62	SATA1_PRESENT_ACTIVEn	SPI0_CSn[3]		UART0_RXD
+
+-------------------------------------------------------------------------------
+MPP#	0x8			0x9			0xA
+-------------------------------------------------------------------------------
+0	UART0_RXD		SATA0_PRESENT_ACTIVEn	GE_MDIO
+1	UART0_TXD		SATA1_PRESENT_ACTIVEn	GE_MDC
+2	UART1_RXD		SATA0_PRESENT_ACTIVEn	XG_MDC
+3	UART1_TXD		SATA1_PRESENT_ACTIVEn	XG_MDIO
+4	UART3_RXD		-			GE_MDC
+5	UART3_TXD		-			GE_MDIO
+6	UART0_RXD		PTP_PULSE		-
+7	UART0_TXD		PTP_CLK			-
+8	UART2_RXD		PTP_PCLK_OUT		SYNCE1_CLK
+9	-			-			SYNCE2_CLK
+10	-			-			-
+11	UART2_TXD		SATA0_PRESENT_ACTIVEn	-
+12	-			-			-
+13	MSS_SPI_MISO		-			-
+14	MSS_SPI_CSn		-			-
+15	MSS_SPI_MOSI		-			-
+16	MSS_SPI_CLK		-			-
+17	-			-			-
+18	-			-			-
+19	-			-			-
+20	-			-			-
+21	-			-			-
+22	-			-			-
+23	-			-			-
+24	-			-			-
+25	-			-			-
+26	-			-			-
+27	GE_MDIO			SATA0_PRESENT_ACTIVEn	UART0_RTS
+28	GE_MDC			SATA1_PRESENT_ACTIVEn	UART0_CTS
+29	MSS_TWSI_SDA		SATA0_PRESENT_ACTIVEn	UART0_RXD
+30	MSS_TWSI_SCK		SATA1_PRESENT_ACTIVEn	UART0_TXD
+31	GE_MDC			-			-
+32	SDIO_V18_EN		PCIe1_CLKREQ		MSS_GPIO[0]
+33	XG_MDIO			PCIe2_CLKREQ		MSS_GPIO[1]
+34	-			PCIe0_CLKREQ		MSS_GPIO[2]
+35	GE_MDIO			PCIe_RSTOUTn		MSS_GPIO[3]
+36	GE_MDC			PCIe2_CLKREQ		MSS_GPIO[5]
+37	XG_MDC			PCIe1_CLKREQ		MSS_GPIO[6]
+38	XG_MDIO			AU_I2SEXTCLK		MSS_GPIO[7]
+39	SATA1_PRESENT_ACTIVEn				MSS_GPIO[0]
+40	GE_MDIO			SATA0_PRESENT_ACTIVEn	MSS_GPIO[1]
+41	GE_MDC			SATA1_PRESENT_ACTIVEn	MSS_GPIO[2]
+42	XG_MDC			SATA0_PRESENT_ACTIVEn	MSS_GPIO[4]
+43	XG_MDIO			SATA1_PRESENT_ACTIVEn	MSS_GPIO[5]
+44	-			-			-
+45	-			PCIe_RSTOUTn		-
+46	-			-			-
+47	GE_MDC			CLKOUT			-
+48	XG_MDC			-			-
+49	GE_MDIO			PCIe0_CLKREQ		SDIO_V18_EN
+50	XG_MDIO			-			SDIO_PWR1[1]
+51	-			-			SDIO_PWR1[0]
+52	LED_CLK			PCIe_RSTOUTn		PCIe0_CLKREQ
+53	LED_STB			-			-
+54	LED_DATA		-			SDIO_HW_RST
+55	-			-			SDIO_LED
+56	-			SATA1_PRESENT_ACTIVEn	-
+57	-			SATA0_PRESENT_ACTIVEn	-
+58	LED_CLK			-			-
+59	LED_STB			UART1_TXD		-
+60	LED_DATA		UART1_RXD		-
+61	UART2_TXD		SATA1_PRESENT_ACTIVEn	GE_MDIO
+62	UART2_RXD		SATA0_PRESENT_ACTIVEn	GE_MDC
+
+-------------------------------------------------------------------------------
+MPP#	0xB			0xD			0xE
+-------------------------------------------------------------------------------
+0	-			-			-
+1	-			-			-
+2	-			-			-
+3	-			-			-
+4	-			-			-
+5	-			-			-
+6	-			-			-
+7	-			-			-
+8	-			-			-
+9	-			-			-
+10	-			-			-
+11	-			CLKOUT_MPP_11		-
+12	-			-			-
+13	-			-			-
+14	-			-			-
+15	PTP_PULSE_CP2CP		SAR_IN[5]		-
+16	-			SAR_IN[3]		-
+17	-			SAR_IN[6]		-
+18	PTP_CLK_CP2CP		SAR_IN[11]		-
+19	WAKEUP_OUT_CP2CP	SAR_IN[7]		-
+20	-			SAR_IN[9]		-
+21	SEI_IN_CP2CP		SAR_IN[8]		-
+22	WAKEUP_IN_CP2CP		SAR_IN[10]		-
+23	LINK_RD_IN_CP2CP	SAR_IN[4]		-
+24	-			-			-
+25	-			CLKOUT_MPP_25		-
+26	-			SAR_IN[0]		-
+27	REI_IN_CP2CP		SAR_IN[1]		-
+28	LED_DATA		SAR_IN[2]		-
+29	LED_STB			AVS_FB_IN_CP2CP		-
+30	LED_CLK			SAR_IN[13]		-
+31	-			-			-
+32	-			SAR_CP2CP_OUT[0]	-
+33	-			SAR_CP2CP_OUT[1]	-
+34	-			SAR_CP2CP_OUT[2]	-
+35	-			SAR_CP2CP_OUT[3]	-
+36	-			CLKIN			-
+37	LINK_RD_OUT_CP2CP	SAR_CP2CP_OUT[4]	-
+38	PTP_PULSE_CP2CP		SAR_CP2CP_OUT[5]	-
+39	-			AVS_FB_OUT_CP2CP	-
+40	-			-			-
+41	REI_OUT_CP2CP		-			-
+42	-			SAR_CP2CP_OUT[9]	-
+43	WAKEUP_OUT_CP2CP	SAR_CP2CP_OUT[10]	-
+44	PTP_CLK_CP2CP		SAR_CP2CP_OUT[11]	-
+45	-			SAR_CP2CP_OUT[6]	-
+46	-			SAR_CP2CP_OUT[13]	-
+47	-			-			-
+48	WAKEUP_IN_CP2CP		SAR_CP2CP_OUT[7]	-
+49	SEI_OUT_CP2CP		SAR_CP2CP_OUT[8]	-
+50	-			-			-
+51	-			-			-
+52	-			-			-
+53	SDIO_LED		-			-
+54	SDIO_WR_PROTECT		-			-
+55	SDIO_CARD_DETECT	-			-
+56	-			-			SDIO0_CLK
+57	-			-			SDIO0_CMD
+58	-			-			SDIO0_D[0]
+59	-			-			SDIO0_D[1]
+60	-			-			SDIO0_D[2]
+61	-			-			SDIO0_D[3]
+62	-			-			-
diff --git a/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt
new file mode 100644
index 0000000..0973db8
--- /dev/null
+++ b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt
@@ -0,0 +1,113 @@
+The pinctrl driver enables Marvell Armada 8K SoCs to configure the multi-purpose
+pins (mpp) to a specific function.
+A Marvell SoC pin configuration node is a node of a group of pins which can
+be used for a specific device or function. Each node requires one or more
+mpp pins or group of pins and a mpp function common to all pins.
+
+Required properties for the pinctrl driver:
+- compatible:	"marvell,mvebu-pinctrl",
+		"marvell,armada-ap806-pinctrl",
+		"marvell,a70x0-pinctrl",
+		"marvell,a80x0-cp0-pinctrl",
+		"marvell,a80x0-cp1-pinctrl"
+- bank-name:	A string defining the pinc controller bank name
+- reg: 		A pair of values defining the pin controller base address
+		and the address space
+- pin-count:	Numeric value defining the amount of multi purpose pins
+		included in this bank
+- max-func:	Numeric value defining the maximum function value for
+		pins in this bank
+- pin-func:	Array of pin function values for every pin in the bank.
+		When the function value for a specific pin equal 0xFF,
+		the pin configuration is skipped and a default function
+		value is used for this pin.
+
+The A8K is a hybrid SoC that contains several silicon dies interconnected in
+a single package. Each such die may have a separate pin controller.
+
+Example:
+/ {
+	ap806 {
+		config-space {
+			pinctl: pinctl at 6F4000 {
+				compatible = "marvell,mvebu-pinctrl",
+					     "marvell,armada-ap806-pinctrl";
+				bank-name ="apn-806";
+				reg = <0x6F4000 0x10>;
+				pin-count = <20>;
+				max-func = <3>;
+				/* MPP Bus:
+					SPI0 [0-3]
+					I2C0 [4-5]
+					UART0 [11,19]
+				*/
+					  /* 0 1 2 3 4 5 6 7 8 9 */
+				pin-func = < 3 3 3 3 3 3 0 0 0 0
+					     0 3 0 0 0 0 0 0 0 3>;
+			};
+		};
+	};
+
+	cp110-master {
+		config-space {
+			cpm_pinctl: pinctl at 44000 {
+				compatible = "marvell,mvebu-pinctrl",
+					     "marvell,a70x0-pinctrl",
+					     "marvell,a80x0-cp0-pinctrl";
+				bank-name ="cp0-110";
+				reg = <0x440000 0x20>;
+				pin-count = <63>;
+				max-func = <0xf>;
+				/* MPP Bus:
+				   [0-31] = 0xff: Keep default CP0_shared_pins:
+				   [11] CLKOUT_MPP_11 (out)
+				   [23] LINK_RD_IN_CP2CP (in)
+				   [25] CLKOUT_MPP_25 (out)
+				   [29] AVS_FB_IN_CP2CP (in)
+				   [32,34] SMI
+				   [31]    GPIO: push button/Wake
+				   [35-36] GPIO
+				   [37-38] I2C
+				   [40-41] SATA[0/1]_PRESENT_ACTIVEn
+				   [42-43] XSMI
+				   [44-55] RGMII1
+				   [56-62] SD
+				*/
+					/*   0    1    2    3    4    5    6    7    8    9 */
+				pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+					     0xff 0    7    0    7    0    0    2    2    0
+					     0    0    8    8    1    1    1    1    1    1
+					     1    1    1    1    1    1    0xE  0xE  0xE  0xE
+					     0xE  0xE  0xE>;
+			};
+		};
+	};
+
+	cp110-slave {
+		config-space {
+			cps_pinctl: pinctl at 44000 {
+				compatible = "marvell,mvebu-pinctrl",
+					     "marvell,a80x0-cp1-pinctrl";
+				bank-name ="cp1-110";
+				reg = <0x440000 0x20>;
+				pin-count = <63>;
+				max-func = <0xf>;
+				/* MPP Bus:
+				   [0-11]  RGMII0
+				   [27,31] GE_MDIO/MDC
+				   [32-62] = 0xff: Keep default CP1_shared_pins:
+				*/
+					/*   0    1    2    3    4    5    6    7    8    9 */
+				pin-func = < 0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3
+					     0x3  0x3  0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8  0xff 0xff
+					     0xff 0x8  0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+					     0xff 0xff 0xff>;
+			};
+		};
+	};
+}
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 12be3cf..efcb4c0 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -181,5 +181,6 @@ source "drivers/pinctrl/meson/Kconfig"
 source "drivers/pinctrl/nxp/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
 source "drivers/pinctrl/exynos/Kconfig"
+source "drivers/pinctrl/mvebu/Kconfig"
 
 endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f28b5c1..512112a 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
 obj-$(CONFIG_PIC32_PINCTRL)	+= pinctrl_pic32.o
 obj-$(CONFIG_PINCTRL_EXYNOS)	+= exynos/
 obj-$(CONFIG_PINCTRL_MESON)	+= meson/
+obj-$(CONFIG_PINCTRL_MVEBU)	+= mvebu/
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig
new file mode 100644
index 0000000..39946a2
--- /dev/null
+++ b/drivers/pinctrl/mvebu/Kconfig
@@ -0,0 +1,16 @@
+config PINCTRL_MVEBU
+	depends on ARCH_MVEBU
+	bool
+	default y
+	help
+	   Support pin multiplexing and pin configuration control on
+	   Marvell's Armada-8K SoC. The pin control driver allows setting
+	   the pin mode (function) according to DTS configuration for every
+	   multi-purpose pin (MPP) that is connected to the SoC pin controllers,
+	   which are located on AP (north bridge with CPU cluster) or CP
+	   (south bridge with mode IO).
+	   For details about available pin function please refer to the
+	   documentation included in device-tree-binding/pinctrl folder.
+	   The driver allows all-pins configuration upon pin controller device
+	   probe and setting specific pin functions for enabling some interface
+	   functionality, for instance UART, SPI. I2C, etc.
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile
new file mode 100644
index 0000000..f4f7864
--- /dev/null
+++ b/drivers/pinctrl/mvebu/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2016 Marvell International Ltd.
+#
+# SPDX-License-Identifier:	GPL-2.0
+# https://spdx.org/licenses
+
+obj-$(CONFIG_PINCTRL_MVEBU)	+= pinctrl-mvebu.o
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
new file mode 100644
index 0000000..b077639
--- /dev/null
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ * https://spdx.org/licenses
+ */
+
+#include <common.h>
+#include <config.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/arch-armada8k/soc-info.h>
+#include "pinctrl-mvebu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * mvebu_pinctrl_set_state: configure pin functions.
+ * @dev: the pinctrl device to be configured.
+ * @config: the state to be configured.
+ * @return: 0 in success
+ */
+int mvebu_pinctrl_set_state(struct udevice *dev, struct udevice *config)
+{
+	const void *blob = gd->fdt_blob;
+	int node = config->of_offset;
+	struct mvebu_pinctrl_priv *priv;
+	u32 pin_arr[MVEBU_MAX_PINS_PER_BANK];
+	u32 function;
+	int i, pin_count;
+
+	priv = dev_get_priv(dev);
+
+	pin_count = fdtdec_get_int_array_count(blob, node,
+					       "marvell,pins",
+					       pin_arr,
+					       MVEBU_MAX_PINS_PER_BANK);
+	if (pin_count <= 0) {
+		debug("Failed reading pins array for pinconfig %s (%d)\n",
+		      config->name, pin_count);
+		return -EINVAL;
+	}
+
+	function = fdtdec_get_int(blob, node, "marvell,function", 0xff);
+
+	for (i = 0; i < pin_count; i++) {
+	int reg_offset;
+	int field_offset;
+		int pin = pin_arr[i];
+
+		if (function > priv->max_func) {
+			debug("Illegal function %d for pinconfig %s\n",
+			      function, config->name);
+			return -EINVAL;
+		}
+
+		/* Calculate register address and bit in register */
+		reg_offset   = priv->reg_direction * 4 *
+					(pin >> (PIN_REG_SHIFT));
+		field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK);
+
+		clrsetbits_le32(priv->base_reg + reg_offset,
+				PIN_FUNC_MASK << field_offset,
+				(function & PIN_FUNC_MASK) << field_offset);
+	}
+
+	return 0;
+}
+
+/*
+ * mvebu_pinctrl_set_state_all: configure the entire bank pin functions.
+ * @dev: the pinctrl device to be configured.
+ * @config: the state to be configured.
+ * @return: 0 in success
+ */
+static int mvebu_pinctrl_set_state_all(struct udevice *dev,
+				       struct udevice *config)
+{
+	const void *blob = gd->fdt_blob;
+	int node = config->of_offset;
+	struct mvebu_pinctrl_priv *priv;
+	u32 func_arr[MVEBU_MAX_PINS_PER_BANK];
+	int pin, err;
+
+	priv = dev_get_priv(dev);
+
+	err = fdtdec_get_int_array(blob, node, "pin-func",
+				   func_arr, priv->pin_cnt);
+	if (err) {
+		debug("Failed reading pin functions for bank %s\n",
+		      priv->bank_name);
+		return -EINVAL;
+	}
+
+	for (pin = 0; pin < priv->pin_cnt; pin++) {
+		int reg_offset;
+		int field_offset;
+		u32 func = func_arr[pin];
+
+		/* Bypass pins with function 0xFF */
+		if (func == 0xff) {
+			debug("Warning: pin %d value is not modified ", pin);
+			debug("(kept as default)\n");
+			continue;
+		} else if (func > priv->max_func) {
+			debug("Illegal function %d for pin %d\n", func, pin);
+			return -EINVAL;
+		}
+
+		/* Calculate register address and bit in register */
+		reg_offset   = priv->reg_direction * 4 *
+					(pin >> (PIN_REG_SHIFT));
+		field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK);
+
+		clrsetbits_le32(priv->base_reg + reg_offset,
+				PIN_FUNC_MASK << field_offset,
+				(func & PIN_FUNC_MASK) << field_offset);
+	}
+
+	return 0;
+}
+
+int mvebu_pinctl_probe(struct udevice *dev)
+{
+	const void *blob = gd->fdt_blob;
+	int node = dev->of_offset;
+	struct mvebu_pinctrl_priv *priv;
+
+	priv = dev_get_priv(dev);
+	if (!priv) {
+		debug("%s: Failed to get private\n", __func__);
+		return -EINVAL;
+	}
+
+	priv->base_reg = dev_get_addr_ptr(dev);
+	if (priv->base_reg == (void *)FDT_ADDR_T_NONE) {
+		debug("%s: Failed to get base address\n", __func__);
+		return -EINVAL;
+	}
+
+	priv->pin_cnt   = fdtdec_get_int(blob, node, "pin-count",
+					MVEBU_MAX_PINS_PER_BANK);
+	priv->max_func  = fdtdec_get_int(blob, node, "max-func",
+					 MVEBU_MAX_FUNC);
+	priv->bank_name = fdt_getprop(blob, node, "bank-name", NULL);
+
+	priv->reg_direction = 1;
+	if (fdtdec_get_bool(blob, node, "reverse-reg"))
+		priv->reg_direction = -1;
+
+	return mvebu_pinctrl_set_state_all(dev, dev);
+}
+
+static struct pinctrl_ops mvebu_pinctrl_ops = {
+	.set_state	= mvebu_pinctrl_set_state
+};
+
+static const struct udevice_id mvebu_pinctrl_ids[] = {
+	{ .compatible = "marvell,mvebu-pinctrl" },
+	{ .compatible = "marvell,armada-ap806-pinctrl" },
+	{ .compatible = "marvell,a70x0-pinctrl" },
+	{ .compatible = "marvell,a80x0-cp0-pinctrl" },
+	{ .compatible = "marvell,a80x0-cp1-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_mvebu) = {
+	.name		= "mvebu_pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= mvebu_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct mvebu_pinctrl_priv),
+	.ops		= &mvebu_pinctrl_ops,
+	.probe		= mvebu_pinctl_probe
+};
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
new file mode 100644
index 0000000..1a1d3ef
--- /dev/null
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ * https://spdx.org/licenses
+ */
+
+ #ifndef __PINCTRL_MVEBU_H_
+ #define __PINCTRL_MVEBU_H_
+
+ #define MVEBU_MAX_PINCTL_BANKS		4
+ #define MVEBU_MAX_PINS_PER_BANK	100
+ #define MVEBU_MAX_FUNC			0xF
+
+/*
+ * struct mvebu_pin_bank_data: mvebu-pinctrl bank data
+ * @base_reg: controller base address for this bank
+ * @pin_cnt:  number of pins included in this bank
+ * @max_func: maximum configurable function value for pins in this bank
+ * @reg_direction:
+ * @bank_name: the pin's bank name
+ */
+struct mvebu_pinctrl_priv {
+	void		*base_reg;
+	uint		pin_cnt;
+	uint		max_func;
+	int		reg_direction;
+	const char	*bank_name;
+};
+
+#endif /* __PINCTRL_MVEBU_H_ */
-- 
2.7.4



More information about the U-Boot mailing list