Skip to content

Commit

Permalink
nvmem: zynqmp: Added zynqmp nvmem firmware driver
Browse files Browse the repository at this point in the history
This patch adds zynqmp nvmem firmware driver to access the
SoC revision information from the hardware register.

Signed-off-by: Nava kishore Manne <nava.manne@xilinx.com>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
  • Loading branch information
Nava kishore Manne authored and Michal Simek committed Feb 5, 2019
1 parent 940c236 commit 4640fa1
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/nvmem/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,14 @@ config SC27XX_EFUSE
This driver can also be built as a module. If so, the module
will be called nvmem-sc27xx-efuse.

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
2 changes: 2 additions & 0 deletions drivers/nvmem/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ obj-$(CONFIG_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
obj-$(CONFIG_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o
nvmem-sc27xx-efuse-y := sc27xx-efuse.o
obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
86 changes: 86 additions & 0 deletions drivers/nvmem/zynqmp_nvmem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 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

struct zynqmp_nvmem_data {
struct device *dev;
struct nvmem_device *nvmem;
};

static int zynqmp_nvmem_read(void *context, unsigned int offset,
void *val, size_t bytes)
{
int ret;
int idcode, version;
struct zynqmp_nvmem_data *priv = context;

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;

dev_dbg(priv->dev, "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 device *dev = &pdev->dev;
struct zynqmp_nvmem_data *priv;

priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
if (!priv)
return -ENOMEM;

priv->dev = dev;
econfig.dev = dev;
econfig.reg_read = zynqmp_nvmem_read;
econfig.priv = priv;

priv->nvmem = devm_nvmem_register(dev, &econfig);

return PTR_ERR_OR_ZERO(priv->nvmem);
}

static struct platform_driver zynqmp_nvmem_driver = {
.probe = zynqmp_nvmem_probe,
.driver = {
.name = "zynqmp-nvmem",
.of_match_table = zynqmp_nvmem_match,
},
};

module_platform_driver(zynqmp_nvmem_driver);

MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>, Nava kishore Manne <navam@xilinx.com>");
MODULE_DESCRIPTION("ZynqMP NVMEM driver");
MODULE_LICENSE("GPL");

0 comments on commit 4640fa1

Please sign in to comment.