arm64: mvebu: pinctrl: Add pin control driver for A8K family
authorKonstantin Porotchkin <kostap@marvell.com>
Thu, 8 Dec 2016 10:22:29 +0000 (12:22 +0200)
committerStefan Roese <sr@denx.de>
Mon, 12 Dec 2016 08:04:52 +0000 (09:04 +0100)
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.

Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Stefan Roese <sr@denx.de>
Cc: Nadav Haklai <nadavh@marvell.com>
Cc: Neta Zur Hershkovits <neta@marvell.com>
Cc: Omri Itach <omrii@marvell.com>
Cc: Igal Liberman <igall@marvell.com>
Cc: Haim Boot <hayim@marvell.com>
Cc: Hanna Hawa <hannah@marvell.com>
Signed-off-by: Stefan Roese <sr@denx.de>
arch/arm/include/asm/arch-armada8k/soc-info.h [new file with mode: 0644]
doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt [new file with mode: 0644]
doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt [new file with mode: 0644]
doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt [new file with mode: 0644]
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/mvebu/Kconfig [new file with mode: 0644]
drivers/pinctrl/mvebu/Makefile [new file with mode: 0644]
drivers/pinctrl/mvebu/pinctrl-mvebu.c [new file with mode: 0644]
drivers/pinctrl/mvebu/pinctrl-mvebu.h [new file with mode: 0644]

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 (file)
index 0000000..bae3995
--- /dev/null
@@ -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 (file)
index 0000000..51f2f2c
--- /dev/null
@@ -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 (file)
index 0000000..3adcf3a
--- /dev/null
@@ -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 (file)
index 0000000..0973db8
--- /dev/null
@@ -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@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@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@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>;
+                       };
+               };
+       };
+}
index 12be3cf..efcb4c0 100644 (file)
@@ -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
index f28b5c1..512112a 100644 (file)
@@ -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 (file)
index 0000000..cf9c299
--- /dev/null
@@ -0,0 +1,7 @@
+config PINCTRL_MVEBU
+       depends on ARCH_MVEBU
+       bool
+       default y
+       help
+          Support pin multiplexing and pin configuration control on
+          Marvell's Armada-8K SoC.
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile
new file mode 100644 (file)
index 0000000..f4f7864
--- /dev/null
@@ -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 (file)
index 0000000..b077639
--- /dev/null
@@ -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 (file)
index 0000000..1a1d3ef
--- /dev/null
@@ -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_ */