2018-09-04 09:54:13

by Nava kishore Manne

[permalink] [raw]
Subject: [RFC PATCH v2 0/3] Add nvmem driver support for ZynqMP

This series of patches are created On top of the
below series of patches.
https://lkml.org/lkml/2018/8/3/687

Nava kishore Manne (3):
fairmware: xilinx: Add zynqmp_pm_get_chipid() API
dt-bindings: fpga: Add bindings for ZynqMP nvmem driver
nvmem: zynqmp: Added zynqmp nvmem firmware driver

.../firmware/xilinx/xlnx,zynqmp-firmware.txt | 35 +++++++++
drivers/firmware/xilinx/zynqmp.c | 24 +++++++
drivers/nvmem/Kconfig | 10 +++
drivers/nvmem/Makefile | 2 +
drivers/nvmem/zynqmp_nvmem.c | 84 ++++++++++++++++++++++
include/linux/firmware/xlnx-zynqmp.h | 2 +
6 files changed, 157 insertions(+)
create mode 100644 drivers/nvmem/zynqmp_nvmem.c

--
2.7.4



2018-09-04 09:54:25

by Nava kishore Manne

[permalink] [raw]
Subject: [RFC PATCH v2 2/3] dt-bindings: fpga: Add bindings for ZynqMP nvmem driver

Add documentation to describe Xilinx ZynqMP nvmem driver
bindings.

Signed-off-by: Nava kishore Manne <[email protected]>
---
Changes for v2:
-Moved nvmem_firmware node as a child to
firwmare node.

.../firmware/xilinx/xlnx,zynqmp-firmware.txt | 35 ++++++++++++++++++++++
1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
index 1b431d9..4b95fcc 100644
--- a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
+++ b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
@@ -17,6 +17,19 @@ Required properties:
- "smc" : SMC #0, following the SMCCC
- "hvc" : HVC #0, following the SMCCC

+--------------------------------------------------------------------------
+= Zynq UltraScale+ MPSoC nvmem firmware driver binding =
+--------------------------------------------------------------------------
+The nvmem_firmware node provides access to the hardware related data
+like soc revision, IDCODE... etc, By using the firmware interface.
+
+Required properties:
+- compatible: should be "xlnx,zynqmp-nvmem-fw"
+
+= Data cells =
+Are child nodes of silicon id, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
-------
Example
-------
@@ -25,5 +38,27 @@ firmware {
zynqmp_firmware: zynqmp-firmware {
compatible = "xlnx,zynqmp-firmware";
method = "smc";
+ nvmem_firmware {
+ compatible = "xlnx,zynqmp-nvmem-fw";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* Data cells */
+ soc_revision: soc_revision {
+ reg = <0x0 0x4>;
+ };
+ };
};
};
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+ pcap {
+ ...
+ nvmem-cells = <&soc_revision>;
+ nvmem-cell-names = "soc_revision";
+ };
+
--
2.7.4


2018-09-04 09:54:31

by Nava kishore Manne

[permalink] [raw]
Subject: [RFC PATCH v2 1/3] fairmware: xilinx: Add zynqmp_pm_get_chipid() API

This patch adds a new API to provide access to the
hardware related data like soc revision, IDCODE... etc.

Signed-off-by: Nava kishore Manne <[email protected]>
---
Changes for v2:
-New Patch.

drivers/firmware/xilinx/zynqmp.c | 24 ++++++++++++++++++++++++
include/linux/firmware/xlnx-zynqmp.h | 2 ++
2 files changed, 26 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 7ccedf0..7a33f93 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -447,8 +447,32 @@ static int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id)
return ret;
}

+/**
+ * zynqmp_pm_get_chipid - Get silicon ID registers
+ * @idcode: IDCODE register
+ * @version: version register
+ *
+ * Return: Returns the status of the operation and the idcode and version
+ * registers in @idcode and @version.
+ */
+static int zynqmp_pm_get_chipid(u32 *idcode, u32 *version)
+{
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ if (!idcode || !version)
+ return -EINVAL;
+
+ ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
+ *idcode = ret_payload[1];
+ *version = ret_payload[2];
+
+ return ret;
+}
+
static const struct zynqmp_eemi_ops eemi_ops = {
.get_api_version = zynqmp_pm_get_api_version,
+ .get_chipid = zynqmp_pm_get_chipid,
.ioctl = zynqmp_pm_ioctl,
.query_data = zynqmp_pm_query_data,
.clock_enable = zynqmp_pm_clock_enable,
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 58a7478..5a49d6f 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -34,6 +34,7 @@

enum pm_api_id {
PM_GET_API_VERSION = 1,
+ PM_GET_CHIPID = 22,
PM_IOCTL = 34,
PM_QUERY_DATA,
PM_CLOCK_ENABLE,
@@ -90,6 +91,7 @@ struct zynqmp_pm_query_data {

struct zynqmp_eemi_ops {
int (*get_api_version)(u32 *version);
+ int (*get_chipid)(u32 *idcode, u32 *version);
int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out);
int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out);
int (*clock_enable)(u32 clock_id);
--
2.7.4


2018-09-04 09:54:42

by Nava kishore Manne

[permalink] [raw]
Subject: [RFC PATCH v2 3/3] nvmem: zynqmp: Added zynqmp nvmem firmware driver

This patch adds zynqmp nvmem firmware driver to access the
SoC revision information from the hardware register.

Signed-off-by: Nava kishore Manne <[email protected]>
---
Changes for v2:
-None.

drivers/nvmem/Kconfig | 10 ++++++
drivers/nvmem/Makefile | 2 ++
drivers/nvmem/zynqmp_nvmem.c | 84 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 96 insertions(+)
create mode 100644 drivers/nvmem/zynqmp_nvmem.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 54a3c29..2edb142 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -181,4 +181,14 @@ config RAVE_SP_EEPROM
help
Say y here to enable Rave SP EEPROM support.

+config NVMEM_ZYNQMP
+ bool "Xilinx ZYNQMP SoC nvmem firmware support"
+ depends on ARCH_ZYNQMP
+ help
+ This is a driver to access hardware related data like
+ soc revision, IDCODE... etc by using the firmware
+ interface.
+
+ If sure, say yes. If unsure, say no.
+
endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 27e96a8..0b3abd7 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -39,4 +39,6 @@ obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o
nvmem_snvs_lpgpr-y := snvs_lpgpr.o
obj-$(CONFIG_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
+obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
+nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o

diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
new file mode 100644
index 0000000..e377900
--- /dev/null
+++ b/drivers/nvmem/zynqmp_nvmem.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Xilinx, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+
+#define SILICON_REVISION_MASK 0xF
+
+static int zynqmp_nvmem_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+{
+ int ret;
+ int idcode, version;
+ const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+ if (!eemi_ops || !eemi_ops->get_chipid)
+ return -ENXIO;
+
+ ret = eemi_ops->get_chipid(&idcode, &version);
+ if (ret < 0)
+ return ret;
+
+ pr_debug("Read chipid val %x %x\n", idcode, version);
+ *(int *)val = version & SILICON_REVISION_MASK;
+
+ return 0;
+}
+
+static struct nvmem_config econfig = {
+ .name = "zynqmp-nvmem",
+ .owner = THIS_MODULE,
+ .word_size = 1,
+ .size = 1,
+ .read_only = true,
+};
+
+static const struct of_device_id zynqmp_nvmem_match[] = {
+ { .compatible = "xlnx,zynqmp-nvmem-fw", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, zynqmp_nvmem_match);
+
+static int zynqmp_nvmem_probe(struct platform_device *pdev)
+{
+ struct nvmem_device *nvmem;
+
+ econfig.dev = &pdev->dev;
+ econfig.reg_read = zynqmp_nvmem_read;
+
+ nvmem = nvmem_register(&econfig);
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+
+ platform_set_drvdata(pdev, nvmem);
+
+ return 0;
+}
+
+static int zynqmp_nvmem_remove(struct platform_device *pdev)
+{
+ struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+ return nvmem_unregister(nvmem);
+}
+
+static struct platform_driver zynqmp_nvmem_driver = {
+ .probe = zynqmp_nvmem_probe,
+ .remove = zynqmp_nvmem_remove,
+ .driver = {
+ .name = "zynqmp-nvmem",
+ .of_match_table = zynqmp_nvmem_match,
+ },
+};
+
+module_platform_driver(zynqmp_nvmem_driver);
+
+MODULE_AUTHOR("Michal Simek <[email protected]>, Nava kishore Manne <[email protected]>");
+MODULE_DESCRIPTION("ZynqMP NVMEM driver");
+MODULE_LICENSE("GPL");
--
2.7.4


2018-09-16 14:11:02

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [RFC PATCH v2 2/3] dt-bindings: fpga: Add bindings for ZynqMP nvmem driver

Hi Rob,

Do you have any comments on the bindings side of it.

I would like to queue this for next release..


On 04/09/18 10:52, Nava kishore Manne wrote:
> Add documentation to describe Xilinx ZynqMP nvmem driver
> bindings.
>
> Signed-off-by: Nava kishore Manne <[email protected]>
> ---
> Changes for v2:
> -Moved nvmem_firmware node as a child to
> firwmare node.
>
> .../firmware/xilinx/xlnx,zynqmp-firmware.txt | 35 ++++++++++++++++++++++
> 1 file changed, 35 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
> index 1b431d9..4b95fcc 100644
> --- a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
> +++ b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
> @@ -17,6 +17,19 @@ Required properties:
> - "smc" : SMC #0, following the SMCCC
> - "hvc" : HVC #0, following the SMCCC
>
> +--------------------------------------------------------------------------
> += Zynq UltraScale+ MPSoC nvmem firmware driver binding =
> +--------------------------------------------------------------------------
> +The nvmem_firmware node provides access to the hardware related data
> +like soc revision, IDCODE... etc, By using the firmware interface.
> +
> +Required properties:
> +- compatible: should be "xlnx,zynqmp-nvmem-fw"
> +
> += Data cells =
> +Are child nodes of silicon id, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> -------
> Example
> -------
> @@ -25,5 +38,27 @@ firmware {
> zynqmp_firmware: zynqmp-firmware {
> compatible = "xlnx,zynqmp-firmware";
> method = "smc";
> + nvmem_firmware {
> + compatible = "xlnx,zynqmp-nvmem-fw";
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + /* Data cells */
> + soc_revision: soc_revision {
> + reg = <0x0 0x4>;
> + };
> + };
> };
> };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> + pcap {
> + ...
> + nvmem-cells = <&soc_revision>;
> + nvmem-cell-names = "soc_revision";
> + };
> +
>
Thanks,
srni

2018-09-16 14:11:22

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/3] nvmem: zynqmp: Added zynqmp nvmem firmware driver

Few minor Nits...

I remember asking about this in the last review!

On 04/09/18 10:52, Nava kishore Manne wrote:
> This patch adds zynqmp nvmem firmware driver to access the
> SoC revision information from the hardware register.
>
> Signed-off-by: Nava kishore Manne <[email protected]>
> ---
> diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
> new file mode 100644
> index 0000000..e377900
> --- /dev/null
> +++ b/drivers/nvmem/zynqmp_nvmem.c
> @@ -0,0 +1,84 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Xilinx, Inc.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/firmware/xlnx-zynqmp.h>
> +
> +#define SILICON_REVISION_MASK 0xF
> +
> +static int zynqmp_nvmem_read(void *context, unsigned int offset,
> + void *val, size_t bytes)
> +{
> + int ret;
> + int idcode, version;
> + const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
> +
> + if (!eemi_ops || !eemi_ops->get_chipid)
> + return -ENXIO;
> +
> + ret = eemi_ops->get_chipid(&idcode, &version);
> + if (ret < 0)
> + return ret;
> +
> + pr_debug("Read chipid val %x %x\n", idcode, version);
> + *(int *)val = version & SILICON_REVISION_MASK;

Use dev_dbg here.
> +
> + return 0;
> +}
> +
> +static struct nvmem_config econfig = {
> + .name = "zynqmp-nvmem",
> + .owner = THIS_MODULE,
> + .word_size = 1,
> + .size = 1,
> + .read_only = true,
> +};
> +
> +static const struct of_device_id zynqmp_nvmem_match[] = {
> + { .compatible = "xlnx,zynqmp-nvmem-fw", },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, zynqmp_nvmem_match);
> +
> +static int zynqmp_nvmem_probe(struct platform_device *pdev)
> +{
> + struct nvmem_device *nvmem;
> +
> + econfig.dev = &pdev->dev;
> + econfig.reg_read = zynqmp_nvmem_read;
> +
> + nvmem = nvmem_register(&econfig);
You can use devm_ variant and remove the zynqmp_nvmem_remove() totally

> + if (IS_ERR(nvmem))
> + return PTR_ERR(nvmem);
> +
> + platform_set_drvdata(pdev, nvmem);
> +
> + return 0;
> +}
> +
> +static int zynqmp_nvmem_remove(struct platform_device *pdev)
> +{
> + struct nvmem_device *nvmem = platform_get_drvdata(pdev);
> +
> + return nvmem_unregister(nvmem);
> +}
> +

2018-09-17 03:16:40

by Nava kishore Manne

[permalink] [raw]
Subject: RE: [RFC PATCH v2 3/3] nvmem: zynqmp: Added zynqmp nvmem firmware driver

Hi Srinivas,

Thansks for providing the comments..
Please find my repsonce inline...

> -----Original Message-----
> From: Srinivas Kandagatla [mailto:[email protected]]
> Sent: Sunday, September 16, 2018 7:41 PM
> To: Nava kishore Manne <[email protected]>; [email protected];
> [email protected]; Michal Simek <[email protected]>; Rajan Vaja
> <[email protected]>; Jolly Shah <[email protected]>;
> [email protected]; [email protected]; linux-
> [email protected]
> Subject: Re: [RFC PATCH v2 3/3] nvmem: zynqmp: Added zynqmp nvmem
> firmware driver
>
> Few minor Nits...
>
> I remember asking about this in the last review!
>
> On 04/09/18 10:52, Nava kishore Manne wrote:
> > This patch adds zynqmp nvmem firmware driver to access the SoC
> > revision information from the hardware register.
> >
> > Signed-off-by: Nava kishore Manne <[email protected]>
> > ---
> > diff --git a/drivers/nvmem/zynqmp_nvmem.c
> > b/drivers/nvmem/zynqmp_nvmem.c new file mode 100644 index
> > 0000000..e377900
> > --- /dev/null
> > +++ b/drivers/nvmem/zynqmp_nvmem.c
> > @@ -0,0 +1,84 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2018 Xilinx, Inc.
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/nvmem-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/firmware/xlnx-zynqmp.h>
> > +
> > +#define SILICON_REVISION_MASK 0xF
> > +
> > +static int zynqmp_nvmem_read(void *context, unsigned int offset,
> > + void *val, size_t bytes)
> > +{
> > + int ret;
> > + int idcode, version;
> > + const struct zynqmp_eemi_ops *eemi_ops =
> zynqmp_pm_get_eemi_ops();
> > +
> > + if (!eemi_ops || !eemi_ops->get_chipid)
> > + return -ENXIO;
> > +
> > + ret = eemi_ops->get_chipid(&idcode, &version);
> > + if (ret < 0)
> > + return ret;
> > +
> > + pr_debug("Read chipid val %x %x\n", idcode, version);
> > + *(int *)val = version & SILICON_REVISION_MASK;
>
> Use dev_dbg here.

Will fix in the next version..

> > +
> > + return 0;
> > +}
> > +
> > +static struct nvmem_config econfig = {
> > + .name = "zynqmp-nvmem",
> > + .owner = THIS_MODULE,
> > + .word_size = 1,
> > + .size = 1,
> > + .read_only = true,
> > +};
> > +
> > +static const struct of_device_id zynqmp_nvmem_match[] = {
> > + { .compatible = "xlnx,zynqmp-nvmem-fw", },
> > + { /* sentinel */ },
> > +};
> > +MODULE_DEVICE_TABLE(of, zynqmp_nvmem_match);
> > +
> > +static int zynqmp_nvmem_probe(struct platform_device *pdev) {
> > + struct nvmem_device *nvmem;
> > +
> > + econfig.dev = &pdev->dev;
> > + econfig.reg_read = zynqmp_nvmem_read;
> > +
> > + nvmem = nvmem_register(&econfig);
> You can use devm_ variant and remove the zynqmp_nvmem_remove() totally
>
Will fix in the next version...

Regards,
Navakishore.