Skip to content

Commit 6b64fde

Browse files
nxpfranklipH5
authored andcommitted
reset: imx: Add SCU reset driver for i.MX8QXP and i.MX8QM
Add System Controller Firmware(SCU) reset driver for i.MX8QM and i.MX8QXP. SCU Manage resets for peripherals such as MIPI CSI. Currently, support two reset sources: IMX_SC_R_CSI_0 and IMX_SC_R_CSI_1. Signed-off-by: Frank Li <Frank.Li@nxp.com> Link: https://lore.kernel.org/r/20250210-8qxp_camera-v3-2-324f5105accc@nxp.com Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
1 parent 7787527 commit 6b64fde

3 files changed

Lines changed: 109 additions & 0 deletions

File tree

drivers/reset/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ config RESET_HSDK
9696
help
9797
This enables the reset controller driver for HSDK board.
9898

99+
config RESET_IMX_SCU
100+
tristate "i.MX8Q Reset Driver"
101+
depends on IMX_SCU && HAVE_ARM_SMCCC
102+
depends on (ARM64 && ARCH_MXC) || COMPILE_TEST
103+
help
104+
This enables the reset controller driver for i.MX8QM/i.MX8QXP
105+
99106
config RESET_IMX7
100107
tristate "i.MX7/8 Reset Driver"
101108
depends on HAS_IOMEM

drivers/reset/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
1515
obj-$(CONFIG_RESET_EYEQ) += reset-eyeq.o
1616
obj-$(CONFIG_RESET_GPIO) += reset-gpio.o
1717
obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
18+
obj-$(CONFIG_RESET_IMX_SCU) += reset-imx-scu.o
1819
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
1920
obj-$(CONFIG_RESET_IMX8MP_AUDIOMIX) += reset-imx8mp-audiomix.o
2021
obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o

drivers/reset/reset-imx-scu.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Copyright 2025 NXP
4+
* Frank Li <Frank.Li@nxp.com>
5+
*/
6+
#include <linux/firmware/imx/svc/misc.h>
7+
#include <linux/kernel.h>
8+
#include <linux/module.h>
9+
#include <linux/of.h>
10+
#include <linux/platform_device.h>
11+
#include <linux/reset-controller.h>
12+
13+
#include <dt-bindings/firmware/imx/rsrc.h>
14+
15+
struct imx_scu_reset {
16+
struct reset_controller_dev rc;
17+
struct imx_sc_ipc *ipc_handle;
18+
};
19+
20+
static struct imx_scu_reset *to_imx_scu(struct reset_controller_dev *rc)
21+
{
22+
return container_of(rc, struct imx_scu_reset, rc);
23+
}
24+
25+
struct imx_scu_id_map {
26+
u32 resource_id;
27+
u32 command_id;
28+
};
29+
30+
static const struct imx_scu_id_map imx_scu_id_map[] = {
31+
{ IMX_SC_R_CSI_0, IMX_SC_C_MIPI_RESET },
32+
{ IMX_SC_R_CSI_1, IMX_SC_C_MIPI_RESET },
33+
};
34+
35+
static int imx_scu_reset_assert(struct reset_controller_dev *rc, unsigned long id)
36+
{
37+
struct imx_scu_reset *priv = to_imx_scu(rc);
38+
39+
return imx_sc_misc_set_control(priv->ipc_handle, imx_scu_id_map[id].resource_id,
40+
imx_scu_id_map[id].command_id, true);
41+
}
42+
43+
static const struct reset_control_ops imx_scu_reset_ops = {
44+
.assert = imx_scu_reset_assert,
45+
};
46+
47+
static int imx_scu_xlate(struct reset_controller_dev *rc, const struct of_phandle_args *reset_spec)
48+
{
49+
int i;
50+
51+
for (i = 0; i < rc->nr_resets; i++)
52+
if (reset_spec->args[0] == imx_scu_id_map[i].resource_id)
53+
return i;
54+
55+
return -EINVAL;
56+
}
57+
58+
static int imx_scu_reset_probe(struct platform_device *pdev)
59+
{
60+
struct device *dev = &pdev->dev;
61+
struct imx_scu_reset *priv;
62+
int ret;
63+
64+
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
65+
if (!priv)
66+
return -ENOMEM;
67+
68+
platform_set_drvdata(pdev, &priv->rc);
69+
70+
ret = imx_scu_get_handle(&priv->ipc_handle);
71+
if (ret)
72+
return dev_err_probe(dev, ret, "sc_misc_MIPI get ipc handle failed!\n");
73+
74+
priv->rc.ops = &imx_scu_reset_ops;
75+
priv->rc.owner = THIS_MODULE;
76+
priv->rc.of_node = dev->of_node;
77+
priv->rc.of_reset_n_cells = 1;
78+
priv->rc.of_xlate = imx_scu_xlate;
79+
priv->rc.nr_resets = ARRAY_SIZE(imx_scu_id_map);
80+
81+
return devm_reset_controller_register(dev, &priv->rc);
82+
}
83+
84+
static const struct of_device_id imx_scu_reset_ids[] = {
85+
{ .compatible = "fsl,imx-scu-reset", },
86+
{}
87+
};
88+
MODULE_DEVICE_TABLE(platform, imx_scu_reset_ids);
89+
90+
static struct platform_driver imx_scu_reset_driver = {
91+
.probe = imx_scu_reset_probe,
92+
.driver = {
93+
.name = "scu-reset",
94+
.of_match_table = imx_scu_reset_ids,
95+
},
96+
};
97+
module_platform_driver(imx_scu_reset_driver);
98+
99+
MODULE_AUTHOR("Frank Li <Frank.Li@nxp.com>");
100+
MODULE_DESCRIPTION("i.MX scu reset driver");
101+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)