diff mbox series

[v3,2/4] pinctrl: mvebu: pinctrl driver for 98DX2530 SoC

Message ID 20220406032158.1449049-3-chris.packham@alliedtelesis.co.nz
State New
Headers show
Series arm64: mvebu: Support for Marvell 98DX2530 (and variants) | expand

Commit Message

Chris Packham April 6, 2022, 3:21 a.m. UTC
This pinctrl driver supports the 98DX25xx and 98DX35xx family of chips
from Marvell. It is based on the Marvell SDK with additions for various
(non-gpio) pin configurations based on the datasheet.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---

Notes:
    Changes in v3:
    - Use mmio instead of syscon
    - Add addtional functions based on the datasheet
    Changes in v2:
    - Make pinctrl a child of a syscon node like the armada-7k-pinctrl

 drivers/pinctrl/mvebu/Kconfig       |   4 +
 drivers/pinctrl/mvebu/Makefile      |   1 +
 drivers/pinctrl/mvebu/pinctrl-ac5.c | 261 ++++++++++++++++++++++++++++
 3 files changed, 266 insertions(+)
 create mode 100644 drivers/pinctrl/mvebu/pinctrl-ac5.c

Comments

Andrew Lunn April 6, 2022, 12:36 p.m. UTC | #1
On Wed, Apr 06, 2022 at 03:21:56PM +1200, Chris Packham wrote:
> This pinctrl driver supports the 98DX25xx and 98DX35xx family of chips
> from Marvell. It is based on the Marvell SDK with additions for various
> (non-gpio) pin configurations based on the datasheet.
> 
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> ---
> 
> Notes:
>     Changes in v3:
>     - Use mmio instead of syscon

Hi Chris

syscon is used when the register space is shared with other
devices. Is that not the case here? You can share mmio spaces, but you
have to use the correct call to reserve it, so that the system knows
it is to be shared. Or are all the pinctl registers contiguous and you
are only reserve just the registers you need, leaving other drivers
fee to take what they need?

I'm just trying to ensure you are not going to have trouble later when
you add other drivers.

    Andrew
Chris Packham April 6, 2022, 9:51 p.m. UTC | #2
Hi Andrew,

On 7/04/22 00:36, Andrew Lunn wrote:
> On Wed, Apr 06, 2022 at 03:21:56PM +1200, Chris Packham wrote:
>> This pinctrl driver supports the 98DX25xx and 98DX35xx family of chips
>> from Marvell. It is based on the Marvell SDK with additions for various
>> (non-gpio) pin configurations based on the datasheet.
>>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
>> ---
>>
>> Notes:
>>      Changes in v3:
>>      - Use mmio instead of syscon
> Hi Chris
>
> syscon is used when the register space is shared with other
> devices. Is that not the case here? You can share mmio spaces, but you
> have to use the correct call to reserve it, so that the system knows
> it is to be shared. Or are all the pinctl registers contiguous and you
> are only reserve just the registers you need, leaving other drivers
> fee to take what they need?
>
> I'm just trying to ensure you are not going to have trouble later when
> you add other drivers.

The pinctrl registers that are used are all continguous (0x80020100 -- 
0x8002011c) . There is a block called the "CnM RFU" which is near the 
pinctrl registers (but a different section in the datasheet) which has 
some peripheral controls. There is also some odd registers (eMMC PHY and 
RFU interrupts) in the MPP section of the document but outside the range 
that this driver uses. I can't tell if this is similar to the RFU block 
on the discrete Armada 64 SoCs, the integrated SoC/Switch chips tend to 
be a bit of a frankenstiens monster of IP blocks.

I really wish I could just share the datasheet but you know how hardware 
vendors like their NDAs.

>
>      Andrew
Andrew Lunn April 6, 2022, 11:17 p.m. UTC | #3
> The pinctrl registers that are used are all continguous (0x80020100 -- 
> 0x8002011c) .

Great. So long at the DT only has that register range, what you have
should be good.

       Andrew
diff mbox series

Patch

diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig
index 0d12894d3ee1..aa5883f09d7b 100644
--- a/drivers/pinctrl/mvebu/Kconfig
+++ b/drivers/pinctrl/mvebu/Kconfig
@@ -45,6 +45,10 @@  config PINCTRL_ORION
 	bool
 	select PINCTRL_MVEBU
 
+config PINCTRL_AC5
+	bool
+	select PINCTRL_MVEBU
+
 config PINCTRL_ARMADA_37XX
 	bool
 	select GENERIC_PINCONF
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile
index cd082dca4482..23458ab17c53 100644
--- a/drivers/pinctrl/mvebu/Makefile
+++ b/drivers/pinctrl/mvebu/Makefile
@@ -11,3 +11,4 @@  obj-$(CONFIG_PINCTRL_ARMADA_CP110) += pinctrl-armada-cp110.o
 obj-$(CONFIG_PINCTRL_ARMADA_XP)  += pinctrl-armada-xp.o
 obj-$(CONFIG_PINCTRL_ARMADA_37XX)  += pinctrl-armada-37xx.o
 obj-$(CONFIG_PINCTRL_ORION)  += pinctrl-orion.o
+obj-$(CONFIG_PINCTRL_AC5) += pinctrl-ac5.o
diff --git a/drivers/pinctrl/mvebu/pinctrl-ac5.c b/drivers/pinctrl/mvebu/pinctrl-ac5.c
new file mode 100644
index 000000000000..292633e61129
--- /dev/null
+++ b/drivers/pinctrl/mvebu/pinctrl-ac5.c
@@ -0,0 +1,261 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Marvell ac5 pinctrl driver based on mvebu pinctrl core
+ *
+ * Copyright (C) 2021 Marvell
+ *
+ * Noam Liron <lnoam@marvell.com>
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-mvebu.h"
+
+static struct mvebu_mpp_mode ac5_mpp_modes[] = {
+	MPP_MODE(0,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d0"),
+		 MPP_FUNCTION(2, "nand",  "io4")),
+	MPP_MODE(1,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d1"),
+		 MPP_FUNCTION(2, "nand",  "io3")),
+	MPP_MODE(2,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d2"),
+		 MPP_FUNCTION(2, "nand",  "io2")),
+	MPP_MODE(3,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d3"),
+		 MPP_FUNCTION(2, "nand",  "io7")),
+	MPP_MODE(4,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d4"),
+		 MPP_FUNCTION(2, "nand",  "io6"),
+		 MPP_FUNCTION(3, "uart3", "txd"),
+		 MPP_FUNCTION(4, "uart2", "txd")),
+	MPP_MODE(5,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d5"),
+		 MPP_FUNCTION(2, "nand",  "io5"),
+		 MPP_FUNCTION(3, "uart3", "rxd"),
+		 MPP_FUNCTION(4, "uart2", "rxd")),
+	MPP_MODE(6,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d6"),
+		 MPP_FUNCTION(2, "nand",  "io0"),
+		 MPP_FUNCTION(3, "i2c1",  "sck")),
+	MPP_MODE(7,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "d7"),
+		 MPP_FUNCTION(2, "nand",  "io1"),
+		 MPP_FUNCTION(3, "i2c1",  "sda")),
+	MPP_MODE(8,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "clk"),
+		 MPP_FUNCTION(2, "nand",  "wen")),
+	MPP_MODE(9,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "cmd"),
+		 MPP_FUNCTION(2, "nand",  "ale")),
+	MPP_MODE(10,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "ds"),
+		 MPP_FUNCTION(2, "nand",  "cle")),
+	MPP_MODE(11,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "sdio",  "rst"),
+		 MPP_FUNCTION(2, "nand",  "cen")),
+	MPP_MODE(12,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "spi0",  "clk")),
+	MPP_MODE(13,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "spi0",  "csn")),
+	MPP_MODE(14,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "spi0",  "mosi")),
+	MPP_MODE(15,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "spi0",  "miso")),
+	MPP_MODE(16,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "spi0",  "wpn"),
+		 MPP_FUNCTION(2, "nand",  "ren"),
+		 MPP_FUNCTION(3, "uart1", "txd")),
+	MPP_MODE(17,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "spi0",  "hold"),
+		 MPP_FUNCTION(2, "nand",  "rb"),
+		 MPP_FUNCTION(3, "uart1", "rxd")),
+	MPP_MODE(18,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "tsen_int", NULL),
+		 MPP_FUNCTION(2, "uart2", "rxd"),
+		 MPP_FUNCTION(3, "wd_int", NULL)),
+	MPP_MODE(19,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "dev_init_done", NULL),
+		 MPP_FUNCTION(2, "uart2", "txd")),
+	MPP_MODE(20,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(2, "i2c1",  "sck"),
+		 MPP_FUNCTION(3, "spi1",  "clk"),
+		 MPP_FUNCTION(4, "uart3", "txd")),
+	MPP_MODE(21,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(2, "i2c1",  "sda"),
+		 MPP_FUNCTION(3, "spi1",  "csn"),
+		 MPP_FUNCTION(4, "uart3", "rxd")),
+	MPP_MODE(22,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(3, "spi1",  "mosi")),
+	MPP_MODE(23,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(3, "spi1",  "miso")),
+	MPP_MODE(24,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "wd_int", NULL),
+		 MPP_FUNCTION(2, "uart2", "txd"),
+		 MPP_FUNCTION(3, "uartsd", "txd")),
+	MPP_MODE(25,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "int_out", NULL),
+		 MPP_FUNCTION(2, "uart2", "rxd"),
+		 MPP_FUNCTION(3, "uartsd", "rxd")),
+	MPP_MODE(26,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "i2c0",  "sck"),
+		 MPP_FUNCTION(2, "ptp", "clk1"),
+		 MPP_FUNCTION(3, "uart3", "txd")),
+	MPP_MODE(27,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "i2c0",  "sda"),
+		 MPP_FUNCTION(2, "ptp", "pulse"),
+		 MPP_FUNCTION(3, "uart3", "rxd")),
+	MPP_MODE(28,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "xg", "mdio"),
+		 MPP_FUNCTION(2, "ge", "mdio"),
+		 MPP_FUNCTION(3, "uart3", "txd")),
+	MPP_MODE(29,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "xg", "mdio"),
+		 MPP_FUNCTION(2, "ge", "mdio"),
+		 MPP_FUNCTION(3, "uart3", "rxd")),
+	MPP_MODE(30,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "xg", "mdio"),
+		 MPP_FUNCTION(2, "ge", "mdio"),
+		 MPP_FUNCTION(3, "ge", "mdio")),
+	MPP_MODE(31,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "xg", "mdio"),
+		 MPP_FUNCTION(2, "ge", "mdio"),
+		 MPP_FUNCTION(3, "ge", "mdio")),
+	MPP_MODE(32,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "uart0", "txd")),
+	MPP_MODE(33,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "uart0", "rxd"),
+		 MPP_FUNCTION(2, "ptp", "clk1"),
+		 MPP_FUNCTION(3, "ptp", "pulse")),
+	MPP_MODE(34,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "ge", "mdio"),
+		 MPP_FUNCTION(2, "uart3", "rxd")),
+	MPP_MODE(35,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "ge", "mdio"),
+		 MPP_FUNCTION(2, "uart3", "txd"),
+		 MPP_FUNCTION(3, "pcie", "rstoutn")),
+	MPP_MODE(36,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "ptp", "clk0_tp"),
+		 MPP_FUNCTION(2, "ptp", "clk1_tp")),
+	MPP_MODE(37,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "ptp", "pulse_tp"),
+		 MPP_FUNCTION(2, "wd_int", NULL)),
+	MPP_MODE(38,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "synce", "clk_out0")),
+	MPP_MODE(39,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "synce", "clk_out1")),
+	MPP_MODE(40,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "ptp", "pclk_out0"),
+		 MPP_FUNCTION(2, "ptp", "pclk_out1")),
+	MPP_MODE(41,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "ptp", "ref_clk"),
+		 MPP_FUNCTION(2, "ptp", "clk1"),
+		 MPP_FUNCTION(3, "ptp", "pulse"),
+		 MPP_FUNCTION(4, "uart2", "txd"),
+		 MPP_FUNCTION(5, "i2c1",  "sck")),
+	MPP_MODE(42,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "ptp", "clk0"),
+		 MPP_FUNCTION(2, "ptp", "clk1"),
+		 MPP_FUNCTION(3, "ptp", "pulse"),
+		 MPP_FUNCTION(4, "uart2", "rxd"),
+		 MPP_FUNCTION(5, "i2c1",  "sda")),
+	MPP_MODE(43,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "led", "clk")),
+	MPP_MODE(44,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "led", "stb")),
+	MPP_MODE(45,
+		 MPP_FUNCTION(0, "gpio",  NULL),
+		 MPP_FUNCTION(1, "led", "data")),
+};
+
+static struct mvebu_pinctrl_soc_info ac5_pinctrl_info;
+
+static const struct of_device_id ac5_pinctrl_of_match[] = {
+	{
+		.compatible = "marvell,ac5-pinctrl",
+	},
+	{ },
+};
+
+static const struct mvebu_mpp_ctrl ac5_mpp_controls[] = {
+	MPP_FUNC_CTRL(0, 45, NULL, mvebu_mmio_mpp_ctrl), };
+
+static struct pinctrl_gpio_range ac5_mpp_gpio_ranges[] = {
+	MPP_GPIO_RANGE(0,   0,  0, 46), };
+
+static int ac5_pinctrl_probe(struct platform_device *pdev)
+{
+	struct mvebu_pinctrl_soc_info *soc = &ac5_pinctrl_info;
+
+	soc->variant = 0; /* no variants for ac5 */
+	soc->controls = ac5_mpp_controls;
+	soc->ncontrols = ARRAY_SIZE(ac5_mpp_controls);
+	soc->gpioranges = ac5_mpp_gpio_ranges;
+	soc->ngpioranges = ARRAY_SIZE(ac5_mpp_gpio_ranges);
+	soc->modes = ac5_mpp_modes;
+	soc->nmodes = ac5_mpp_controls[0].npins;
+
+	pdev->dev.platform_data = soc;
+
+	return mvebu_pinctrl_simple_mmio_probe(pdev);
+}
+
+static struct platform_driver ac5_pinctrl_driver = {
+	.driver = {
+		.name = "ac5-pinctrl",
+		.of_match_table = of_match_ptr(ac5_pinctrl_of_match),
+	},
+	.probe = ac5_pinctrl_probe,
+};
+builtin_platform_driver(ac5_pinctrl_driver);