From: Frank Li <Frank.li@nxp.com>
To: Alexander Stein <alexander.stein@ew.tq-group.com>
Cc: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Shawn Guo <shawnguo@kernel.org>,
Sascha Hauer <s.hauer@pengutronix.de>,
Pengutronix Kernel Team <kernel@pengutronix.de>,
Fabio Estevam <festevam@gmail.com>,
Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/4] nvmem: imx-ocotp: Support accessing controller for i.MX8M Nano
Date: Thu, 30 Jan 2025 11:42:32 -0500 [thread overview]
Message-ID: <Z5ur+NF9UlXJSWtL@lizhi-Precision-Tower-5810> (raw)
In-Reply-To: <20250130130101.1040824-4-alexander.stein@ew.tq-group.com>
On Thu, Jan 30, 2025 at 02:01:00PM +0100, Alexander Stein wrote:
> i.MX8M OCOTP supports a specific peripheral or function being fused
> which means disabled, so
> - Introduce disable_fuse for a list of possible fused peripherals.
> - Iterate all nodes to check accessing permission. If not
> allowed to be accessed, detach the node
>
> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> ---
> drivers/nvmem/Kconfig | 3 ++
> drivers/nvmem/imx-ocotp.c | 105 +++++++++++++++++++++++++++++++++++++-
> 2 files changed, 107 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 8671b7c974b93..ba5c928cab520 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -84,6 +84,9 @@ config NVMEM_IMX_OCOTP
> This driver can also be built as a module. If so, the module
> will be called nvmem-imx-ocotp.
>
> + If built as modules, any other driver relying on this working
> + as access controller also needs to be a module as well.
> +
> config NVMEM_IMX_OCOTP_ELE
> tristate "i.MX On-Chip OTP Controller support"
> depends on ARCH_MXC || COMPILE_TEST
> diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
> index c5086a16450ac..e3ea026a37d0d 100644
> --- a/drivers/nvmem/imx-ocotp.c
> +++ b/drivers/nvmem/imx-ocotp.c
> @@ -23,6 +23,7 @@
> #include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/slab.h>
> +#include <dt-bindings/nvmem/fsl,imx8mn-ocotp.h>
>
> #define IMX_OCOTP_OFFSET_B0W0 0x400 /* Offset from base address of the
> * OTP Bank0 Word0
> @@ -91,11 +92,20 @@ struct ocotp_ctrl_reg {
> u32 bm_rel_shadows;
> };
>
> +#define OCOTP_MAX_NUM_GATE_WORDS 4
> +
> +struct disable_fuse {
> + u32 fuse_addr;
> + u32 mask;
> +};
> +
> struct ocotp_params {
> unsigned int nregs;
> unsigned int bank_address_words;
> void (*set_timing)(struct ocotp_priv *priv);
> struct ocotp_ctrl_reg ctrl;
> + u32 num_disables;
> + struct disable_fuse *disables;
> };
>
> static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
> @@ -552,11 +562,25 @@ static const struct ocotp_params imx8mm_params = {
> .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
> };
>
> +struct disable_fuse imx8mn_disable_fuse[] = {
> + [IMX8MN_OCOTP_M7_DISABLE] = { .fuse_addr = 20, .mask = BIT(8) },
> + [IMX8MN_OCOTP_M7_MPU_DISABLE] = { .fuse_addr = 20, .mask = BIT(9) },
> + [IMX8MN_OCOTP_M7_FPU_DISABLE] = { .fuse_addr = 20, .mask = BIT(10) },
> + [IMX8MN_OCOTP_USB_OTG1_DISABLE] = { .fuse_addr = 20, .mask = BIT(11) },
> + [IMX8MN_OCOTP_GPU3D_DISABLE] = { .fuse_addr = 20, .mask = BIT(24) },
> + [IMX8MN_OCOTP_MIPI_DSI_DISABLE] = { .fuse_addr = 20, .mask = BIT(28) },
> + [IMX8MN_OCOTP_ENET_DISABLE] = { .fuse_addr = 20, .mask = BIT(29) },
> + [IMX8MN_OCOTP_MIPI_CSI_DISABLE] = { .fuse_addr = 20, .mask = BIT(30) },
> + [IMX8MN_OCOTP_ASRC_DISABLE] = { .fuse_addr = 20, .mask = BIT(31) },
> +};
Can we direct define IMX8MN_OCOTP_M7_DISABLE as BIT(8), so avoid this
map data?
> +
> static const struct ocotp_params imx8mn_params = {
> .nregs = 256,
> .bank_address_words = 0,
> .set_timing = imx_ocotp_set_imx6_timing,
> .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
> + .num_disables = ARRAY_SIZE(imx8mn_disable_fuse),
> + .disables = imx8mn_disable_fuse,
> };
>
> static const struct ocotp_params imx8mp_params = {
> @@ -589,6 +613,81 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
> cell->read_post_process = imx_ocotp_cell_pp;
> }
>
> +static int imx_ocotp_check_access(struct ocotp_priv *priv, u32 id)
> +{
> + u32 addr, mask, ret, val;
> +
> + if (id >= priv->params->num_disables) {
> + dev_err(priv->dev, "Index %d too large\n", id);
> + return -EACCES;
> + }
> +
> + addr = priv->params->disables[id].fuse_addr;
> + mask = priv->params->disables[id].mask;
> +
> + ret = imx_ocotp_read(priv, addr, &val, sizeof(val));
> + if (ret)
> + return ret;
> +
> + dev_dbg(priv->dev, "id:%d addr:%#x mask:0x%08x\n", id, addr, mask);
> + /* true means disabled */
> + if (val & mask)
> + return -EACCES;
> +
> + return 0;
> +}
> +
> +static int imx_ocotp_grant_access(struct ocotp_priv *priv, struct device_node *parent)
> +{
> + struct device *dev = priv->dev;
> +
> + for_each_available_child_of_node_scoped(parent, child) {
> + struct of_phandle_args args;
> + u32 id, idx = 0;
> +
> + while (!of_parse_phandle_with_args(child, "access-controllers",
> + "#access-controller-cells",
> + idx++, &args)) {
> + of_node_put(args.np);
> + if (args.np != dev->of_node)
> + continue;
> +
> + /* Only support one cell */
> + if (args.args_count != 1) {
> + dev_err(dev, "wrong args count\n");
> + continue;
> + }
> +
> + id = args.args[0];
> +
> + dev_dbg(dev, "Checking node: %pOF disable ID: %d\n", child, id);
> +
> + if (imx_ocotp_check_access(priv, id)) {
> + of_detach_node(child);
> + dev_info(dev, "%pOF: disabled by fuse, device driver will not be probed\n",
> + child);
> + }
> + }
> +
> + imx_ocotp_grant_access(priv, child);
> + }
> +
> + return 0;
> +}
Can we have one method to share above code logic to avoid copy-paste to
every ocotp driver? Anyway, we can improve that later.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> +
> +static int imx_ocotp_access_control(struct ocotp_priv *priv)
> +{
> + struct device_node *root __free(device_node) = of_find_node_by_path("/");
> +
> + if (!priv->params->disables)
> + return 0;
> +
> + if (WARN_ON(!root))
> + return -EINVAL;
> +
> + return imx_ocotp_grant_access(priv, root);
> +}
> +
> static int imx_ocotp_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> @@ -622,9 +721,13 @@ static int imx_ocotp_probe(struct platform_device *pdev)
> imx_ocotp_clr_err_if_set(priv);
> clk_disable_unprepare(priv->clk);
>
> + platform_set_drvdata(pdev, priv);
> +
> nvmem = devm_nvmem_register(dev, &imx_ocotp_nvmem_config);
> + if (IS_ERR(nvmem))
> + return PTR_ERR(nvmem);
>
> - return PTR_ERR_OR_ZERO(nvmem);
> + return imx_ocotp_access_control(priv);
> }
>
> static struct platform_driver imx_ocotp_driver = {
> --
> 2.34.1
>
next prev parent reply other threads:[~2025-01-30 16:42 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-30 13:00 [PATCH 0/4] Make i.MX8M Nano OCOTP work as accessing controller Alexander Stein
2025-01-30 13:00 ` [PATCH 1/4] dt-bindings: nvmem: imx-ocotp: Add i.MX8M Nano access controller definitions Alexander Stein
2025-01-30 16:32 ` Frank Li
2025-01-30 18:47 ` Conor Dooley
2025-01-30 13:00 ` [PATCH 2/4] nvmem: imx-ocotp: Sort header alphabetically Alexander Stein
2025-01-30 16:33 ` Frank Li
2025-01-30 13:01 ` [PATCH 3/4] nvmem: imx-ocotp: Support accessing controller for i.MX8M Nano Alexander Stein
2025-01-30 16:42 ` Frank Li [this message]
2025-01-31 13:54 ` Alexander Stein
2025-01-31 16:06 ` Frank Li
2025-02-05 6:51 ` Alexander Stein
2025-02-05 16:43 ` Frank Li
2025-02-05 17:02 ` Frank Li
2025-01-31 7:20 ` Krzysztof Kozlowski
2025-01-31 13:50 ` Alexander Stein
2025-01-31 14:07 ` Krzysztof Kozlowski
2025-01-30 13:01 ` [PATCH 4/4] arm64: dts: imx8mn: Add access-controller references Alexander Stein
2025-01-30 23:38 ` [PATCH 0/4] Make i.MX8M Nano OCOTP work as accessing controller Rob Herring (Arm)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z5ur+NF9UlXJSWtL@lizhi-Precision-Tower-5810 \
--to=frank.li@nxp.com \
--cc=alexander.stein@ew.tq-group.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=festevam@gmail.com \
--cc=imx@lists.linux.dev \
--cc=kernel@pengutronix.de \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=shawnguo@kernel.org \
--cc=srinivas.kandagatla@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.