xref: /linux/drivers/reset/reset-th1520.c (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
4  * Author: Michal Wilczynski <m.wilczynski@samsung.com>
5  */
6 
7 #include <linux/of.h>
8 #include <linux/platform_device.h>
9 #include <linux/reset-controller.h>
10 #include <linux/regmap.h>
11 
12 #include <dt-bindings/reset/thead,th1520-reset.h>
13 
14  /* register offset in VOSYS_REGMAP */
15 #define TH1520_GPU_RST_CFG		0x0
16 #define TH1520_GPU_RST_CFG_MASK		GENMASK(1, 0)
17 
18 /* register values */
19 #define TH1520_GPU_SW_GPU_RST		BIT(0)
20 #define TH1520_GPU_SW_CLKGEN_RST	BIT(1)
21 
22 struct th1520_reset_priv {
23 	struct reset_controller_dev rcdev;
24 	struct regmap *map;
25 };
26 
27 struct th1520_reset_map {
28 	u32 bit;
29 	u32 reg;
30 };
31 
32 static const struct th1520_reset_map th1520_resets[] = {
33 	[TH1520_RESET_ID_GPU] = {
34 		.bit = TH1520_GPU_SW_GPU_RST,
35 		.reg = TH1520_GPU_RST_CFG,
36 	},
37 	[TH1520_RESET_ID_GPU_CLKGEN] = {
38 		.bit = TH1520_GPU_SW_CLKGEN_RST,
39 		.reg = TH1520_GPU_RST_CFG,
40 	}
41 };
42 
43 static inline struct th1520_reset_priv *
to_th1520_reset(struct reset_controller_dev * rcdev)44 to_th1520_reset(struct reset_controller_dev *rcdev)
45 {
46 	return container_of(rcdev, struct th1520_reset_priv, rcdev);
47 }
48 
th1520_reset_assert(struct reset_controller_dev * rcdev,unsigned long id)49 static int th1520_reset_assert(struct reset_controller_dev *rcdev,
50 			       unsigned long id)
51 {
52 	struct th1520_reset_priv *priv = to_th1520_reset(rcdev);
53 	const struct th1520_reset_map *reset;
54 
55 	reset = &th1520_resets[id];
56 
57 	return regmap_update_bits(priv->map, reset->reg, reset->bit, 0);
58 }
59 
th1520_reset_deassert(struct reset_controller_dev * rcdev,unsigned long id)60 static int th1520_reset_deassert(struct reset_controller_dev *rcdev,
61 				 unsigned long id)
62 {
63 	struct th1520_reset_priv *priv = to_th1520_reset(rcdev);
64 	const struct th1520_reset_map *reset;
65 
66 	reset = &th1520_resets[id];
67 
68 	return regmap_update_bits(priv->map, reset->reg, reset->bit,
69 				  reset->bit);
70 }
71 
72 static const struct reset_control_ops th1520_reset_ops = {
73 	.assert	= th1520_reset_assert,
74 	.deassert = th1520_reset_deassert,
75 };
76 
77 static const struct regmap_config th1520_reset_regmap_config = {
78 	.reg_bits = 32,
79 	.val_bits = 32,
80 	.reg_stride = 4,
81 	.fast_io = true,
82 };
83 
th1520_reset_probe(struct platform_device * pdev)84 static int th1520_reset_probe(struct platform_device *pdev)
85 {
86 	struct device *dev = &pdev->dev;
87 	struct th1520_reset_priv *priv;
88 	void __iomem *base;
89 	int ret;
90 
91 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
92 	if (!priv)
93 		return -ENOMEM;
94 
95 	base = devm_platform_ioremap_resource(pdev, 0);
96 	if (IS_ERR(base))
97 		return PTR_ERR(base);
98 
99 	priv->map = devm_regmap_init_mmio(dev, base,
100 					  &th1520_reset_regmap_config);
101 	if (IS_ERR(priv->map))
102 		return PTR_ERR(priv->map);
103 
104 	/* Initialize GPU resets to asserted state */
105 	ret = regmap_update_bits(priv->map, TH1520_GPU_RST_CFG,
106 				 TH1520_GPU_RST_CFG_MASK, 0);
107 	if (ret)
108 		return ret;
109 
110 	priv->rcdev.owner = THIS_MODULE;
111 	priv->rcdev.nr_resets = ARRAY_SIZE(th1520_resets);
112 	priv->rcdev.ops = &th1520_reset_ops;
113 	priv->rcdev.of_node = dev->of_node;
114 
115 	return devm_reset_controller_register(dev, &priv->rcdev);
116 }
117 
118 static const struct of_device_id th1520_reset_match[] = {
119 	{ .compatible = "thead,th1520-reset" },
120 	{ /* sentinel */ }
121 };
122 MODULE_DEVICE_TABLE(of, th1520_reset_match);
123 
124 static struct platform_driver th1520_reset_driver = {
125 	.driver = {
126 		.name = "th1520-reset",
127 		.of_match_table = th1520_reset_match,
128 	},
129 	.probe = th1520_reset_probe,
130 };
131 module_platform_driver(th1520_reset_driver);
132 
133 MODULE_AUTHOR("Michal Wilczynski <m.wilczynski@samsung.com>");
134 MODULE_DESCRIPTION("T-HEAD TH1520 SoC reset controller");
135 MODULE_LICENSE("GPL");
136