nvmem: add i.MX7 support to snvs-lpgpr
authorAndrey Yurovsky <yurovsky@gmail.com>
Fri, 9 Mar 2018 14:47:16 +0000 (14:47 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Mar 2018 18:28:14 +0000 (19:28 +0100)
The i.MX7 family has similar SNVS hardware so make the snvs-lpgpr
support it along with the i.MX6 family. The register interface is the
same except for the number and offset of the general purpose registers.

Signed-off-by: Andrey Yurovsky <yurovsky@gmail.com>
Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt
drivers/nvmem/Kconfig
drivers/nvmem/snvs_lpgpr.c

index 20bc49b..3cb1708 100644 (file)
@@ -1,5 +1,5 @@
 Device tree bindings for Low Power General Purpose Register found in i.MX6Q/D
-Secure Non-Volatile Storage.
+and i.MX7 Secure Non-Volatile Storage.
 
 This DT node should be represented as a sub-node of a "syscon",
 "simple-mfd" node.
@@ -8,6 +8,7 @@ Required properties:
 - compatible: should be one of the fallowing variants:
        "fsl,imx6q-snvs-lpgpr" for Freescale i.MX6Q/D/DL/S
        "fsl,imx6ul-snvs-lpgpr" for Freescale i.MX6UL
+       "fsl,imx7d-snvs-lpgpr" for Freescale i.MX7D/S
 
 Example:
 snvs: snvs@020cc000 {
index ff505af..5f9bc78 100644 (file)
@@ -167,10 +167,10 @@ config MESON_MX_EFUSE
 
 config NVMEM_SNVS_LPGPR
        tristate "Support for Low Power General Purpose Register"
-       depends on SOC_IMX6 || COMPILE_TEST
+       depends on SOC_IMX6 || SOC_IMX7D || COMPILE_TEST
        help
          This is a driver for Low Power General Purpose Register (LPGPR) available on
-         i.MX6 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.
+         i.MX6 and i.MX7 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.
 
          This driver can also be built as a module. If so, the module
          will be called nvmem-snvs-lpgpr.
index 92e1e41..c050a23 100644 (file)
 #include <linux/regmap.h>
 
 #define IMX6Q_SNVS_HPLR                0x00
-#define IMX6Q_GPR_SL           BIT(5)
 #define IMX6Q_SNVS_LPLR                0x34
-#define IMX6Q_GPR_HL           BIT(5)
 #define IMX6Q_SNVS_LPGPR       0x68
 
+#define IMX7D_SNVS_HPLR                0x00
+#define IMX7D_SNVS_LPLR                0x34
+#define IMX7D_SNVS_LPGPR       0x90
+
+#define IMX_GPR_SL             BIT(5)
+#define IMX_GPR_HL             BIT(5)
+
 struct snvs_lpgpr_cfg {
        int offset;
        int offset_hplr;
        int offset_lplr;
+       int size;
 };
 
 struct snvs_lpgpr_priv {
@@ -36,6 +42,14 @@ static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx6q = {
        .offset         = IMX6Q_SNVS_LPGPR,
        .offset_hplr    = IMX6Q_SNVS_HPLR,
        .offset_lplr    = IMX6Q_SNVS_LPLR,
+       .size           = 4,
+};
+
+static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx7d = {
+       .offset         = IMX7D_SNVS_LPGPR,
+       .offset_hplr    = IMX7D_SNVS_HPLR,
+       .offset_lplr    = IMX7D_SNVS_LPLR,
+       .size           = 16,
 };
 
 static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
@@ -50,14 +64,14 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
        if (ret < 0)
                return ret;
 
-       if (lock_reg & IMX6Q_GPR_SL)
+       if (lock_reg & IMX_GPR_SL)
                return -EPERM;
 
        ret = regmap_read(priv->regmap, dcfg->offset_lplr, &lock_reg);
        if (ret < 0)
                return ret;
 
-       if (lock_reg & IMX6Q_GPR_HL)
+       if (lock_reg & IMX_GPR_HL)
                return -EPERM;
 
        return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
@@ -112,7 +126,7 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
        cfg->dev = dev;
        cfg->stride = 4;
        cfg->word_size = 4;
-       cfg->size = 4;
+       cfg->size = dcfg->size,
        cfg->owner = THIS_MODULE;
        cfg->reg_read  = snvs_lpgpr_read;
        cfg->reg_write = snvs_lpgpr_write;
@@ -126,6 +140,7 @@ static const struct of_device_id snvs_lpgpr_dt_ids[] = {
        { .compatible = "fsl,imx6q-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx6q },
        { .compatible = "fsl,imx6ul-snvs-lpgpr",
          .data = &snvs_lpgpr_cfg_imx6q },
+       { .compatible = "fsl,imx7d-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx7d },
        { },
 };
 MODULE_DEVICE_TABLE(of, snvs_lpgpr_dt_ids);
@@ -140,5 +155,5 @@ static struct platform_driver snvs_lpgpr_driver = {
 module_platform_driver(snvs_lpgpr_driver);
 
 MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
-MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 Secure Non-Volatile Storage");
+MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 and i.MX7 Secure Non-Volatile Storage");
 MODULE_LICENSE("GPL v2");