RE: [PATCH 3/3] pinctrl: pinctrl-zynqmp: Add support for Versal platform

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sai,

>-----Original Message-----
>From: Sai Krishna Potthuri <sai.krishna.potthuri@xxxxxxx>
>Sent: Thursday, July 11, 2024 4:03 PM
>To: Linus Walleij <linus.walleij@xxxxxxxxxx>; Simek, Michal
><michal.simek@xxxxxxx>; Rob Herring <robh+dt@xxxxxxxxxx>; Krzysztof
>Kozlowski <krzysztof.kozlowski+dt@xxxxxxxxxx>; Conor Dooley
><conor+dt@xxxxxxxxxx>; Buddhabhatti, Jay <jay.buddhabhatti@xxxxxxx>;
>Dhaval Shah <dhaval.r.shah@xxxxxxx>; Kundanala, Praveen Teja
><praveen.teja.kundanala@xxxxxxx>; Greg Kroah-Hartman
><gregkh@xxxxxxxxxxxxxxxxxxx>
>Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; linux-
>gpio@xxxxxxxxxxxxxxx; devicetree@xxxxxxxxxxxxxxx; saikrishna12468@xxxxxxxxx;
>git (AMD-Xilinx) <git@xxxxxxx>; Potthuri, Sai Krishna
><sai.krishna.potthuri@xxxxxxx>
>Subject: [PATCH 3/3] pinctrl: pinctrl-zynqmp: Add support for Versal platform
>
>Add Pinctrl support for Xilinx Versal platform.
>Driver checks for firmware support to retrieve the Pin information, if it
>is supported then proceed further otherwise it returns error saying
>operation not supported. Latest Xilinx Platform Management Firmware must
>be used to make use of the Pinctrl driver for Versal platform.
>
>Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@xxxxxxx>
>---
> drivers/pinctrl/pinctrl-zynqmp.c | 91 ++++++++++++++++++++++++++++++--
> 1 file changed, 86 insertions(+), 5 deletions(-)
>
>diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
>index 3c6d56fdb8c9..e2cfd3d512e8 100644
>--- a/drivers/pinctrl/pinctrl-zynqmp.c
>+++ b/drivers/pinctrl/pinctrl-zynqmp.c
>@@ -10,6 +10,7 @@
>
> #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
>
>+#include <linux/bitfield.h>
> #include <linux/bitmap.h>
> #include <linux/init.h>
> #include <linux/module.h>
>@@ -44,6 +45,12 @@
> #define DRIVE_STRENGTH_8MA	8
> #define DRIVE_STRENGTH_12MA	12
>
>+#define VERSAL_LPD_PIN_PREFIX		"LPD_MIO"
>+#define VERSAL_PMC_PIN_PREFIX		"PMC_MIO"
>+
>+#define VERSAL_PINCTRL_ATTR_NODETYPE_MASK	GENMASK(19, 14)
>+#define VERSAL_PINCTRL_NODETYPE_LPD_MIO		BIT(0)
>+
> /**
>  * struct zynqmp_pmux_function - a pinmux function
>  * @name:	Name of the pin mux function
>@@ -596,8 +603,12 @@ static int zynqmp_pinctrl_prepare_func_groups(struct
>device *dev, u32 fid,
> 			if (!groups[resp[i]].name)
> 				return -ENOMEM;
>
>-			for (pin = 0; pin < groups[resp[i]].npins; pin++)
>-				__set_bit(groups[resp[i]].pins[pin], used_pins);
>+			for (pin = 0; pin < groups[resp[i]].npins; pin++) {
>+				if (of_device_is_compatible(dev->of_node,
>"xlnx,zynqmp-pinctrl"))

Use zynqmp_pm_get_family_info() to distinguish ZynqMP or Versal platform instead of depending on compatible string.
Refer drivers/firmware/xilinx/zynqmp.c for more info.

>+					__set_bit(groups[resp[i]].pins[pin],
>used_pins);
>+				else
>+					__set_bit((u8)groups[resp[i]].pins[pin] -
>1, used_pins);
>+			}
> 		}
> 	}
> done:
>@@ -873,6 +884,70 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct
>device *dev,
> 	return 0;
> }
>
>+static int versal_pinctrl_get_attributes(u32 pin_idx, u32 *response)
>+{
>+	struct zynqmp_pm_query_data qdata = {0};
>+	u32 payload[PAYLOAD_ARG_CNT];
>+	int ret;
>+
>+	qdata.qid = PM_QID_PINCTRL_GET_ATTRIBUTES;
>+	qdata.arg1 = pin_idx;
>+
>+	ret = zynqmp_pm_query_data(qdata, payload);
>+	if (ret)
>+		return ret;
>+
>+	memcpy(response, &payload[1], sizeof(*response));
>+
>+	return 0;
>+}
>+
>+static int versal_pinctrl_prepare_pin_desc(struct device *dev,
>+					   const struct pinctrl_pin_desc
>**zynqmp_pins,
>+					   unsigned int *npins)
>+{
>+	u32 lpd_mio_pins = 0, attr, nodetype;
>+	struct pinctrl_pin_desc *pins, *pin;
>+	int ret, i;
>+
>+	ret = zynqmp_pm_is_function_supported(PM_QUERY_DATA,
>PM_QID_PINCTRL_GET_ATTRIBUTES);
>+	if (ret)
>+		return ret;
>+
>+	ret = zynqmp_pinctrl_get_num_pins(npins);
>+	if (ret)
>+		return ret;
>+
>+	pins = devm_kzalloc(dev, sizeof(*pins) * *npins, GFP_KERNEL);
>+	if (!pins)
>+		return -ENOMEM;
>+
>+	for (i = 0; i < *npins; i++) {
>+		ret = versal_pinctrl_get_attributes(i, &attr);
>+		if (ret)
>+			return ret;
>+
>+		pin = &pins[i];
>+		pin->number = attr;
>+		nodetype =
>FIELD_GET(VERSAL_PINCTRL_ATTR_NODETYPE_MASK, attr);
>+		if (nodetype == VERSAL_PINCTRL_NODETYPE_LPD_MIO) {
>+			pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d",
>+						   VERSAL_LPD_PIN_PREFIX, i);
>+			lpd_mio_pins++;
>+		} else {
>+			pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d",
>+						   VERSAL_PMC_PIN_PREFIX, i -
>lpd_mio_pins);
>+		}
>+
>+		if (!pin->name)
>+			return -ENOMEM;
>+	}
>+
>+	*zynqmp_pins = pins;
>+
>+	return 0;
>+}
>+
> static int zynqmp_pinctrl_probe(struct platform_device *pdev)
> {
> 	struct zynqmp_pinctrl *pctrl;
>@@ -882,9 +957,14 @@ static int zynqmp_pinctrl_probe(struct platform_device
>*pdev)
> 	if (!pctrl)
> 		return -ENOMEM;
>
>-	ret = zynqmp_pinctrl_prepare_pin_desc(&pdev->dev,
>-					      &zynqmp_desc.pins,
>-					      &zynqmp_desc.npins);
>+	if (of_device_is_compatible(pdev->dev.of_node, "xlnx,versal-pinctrl")) {

Same as above.

>+		ret = versal_pinctrl_prepare_pin_desc(&pdev->dev,
>&zynqmp_desc.pins,
>+						      &zynqmp_desc.npins);
>+	} else {
>+		ret = zynqmp_pinctrl_prepare_pin_desc(&pdev->dev,
>&zynqmp_desc.pins,
>+						      &zynqmp_desc.npins);
>+	}
>+
> 	if (ret) {
> 		dev_err(&pdev->dev, "pin desc prepare fail with %d\n", ret);
> 		return ret;
>@@ -907,6 +987,7 @@ static int zynqmp_pinctrl_probe(struct platform_device
>*pdev)
>
> static const struct of_device_id zynqmp_pinctrl_of_match[] = {
> 	{ .compatible = "xlnx,zynqmp-pinctrl" },
>+	{ .compatible = "xlnx,versal-pinctrl" },
> 	{ }
> };
> MODULE_DEVICE_TABLE(of, zynqmp_pinctrl_of_match);
>--
>2.25.1






[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux