1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Tero Kristo <t-kristo@ti.com>
9 #include <linux/kernel.h>
10 #include <linux/device.h>
12 #include <linux/iopoll.h>
14 #include <linux/of_device.h>
15 #include <linux/platform_device.h>
16 #include <linux/reset-controller.h>
17 #include <linux/delay.h>
19 #include <linux/platform_data/ti-prm.h>
26 struct omap_prm_data
{
29 const char *clkdm_name
;
32 const struct omap_rst_map
*rstmap
;
37 const struct omap_prm_data
*data
;
41 struct omap_reset_data
{
42 struct reset_controller_dev rcdev
;
46 struct clockdomain
*clkdm
;
50 #define to_omap_reset_data(p) container_of((p), struct omap_reset_data, rcdev)
52 #define OMAP_MAX_RESETS 8
53 #define OMAP_RESET_MAX_WAIT 10000
55 #define OMAP_PRM_HAS_RSTCTRL BIT(0)
56 #define OMAP_PRM_HAS_RSTST BIT(1)
57 #define OMAP_PRM_HAS_NO_CLKDM BIT(2)
59 #define OMAP_PRM_HAS_RESETS (OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_RSTST)
61 static const struct omap_rst_map rst_map_0
[] = {
62 { .rst
= 0, .st
= 0 },
66 static const struct omap_rst_map rst_map_01
[] = {
67 { .rst
= 0, .st
= 0 },
68 { .rst
= 1, .st
= 1 },
72 static const struct omap_rst_map rst_map_012
[] = {
73 { .rst
= 0, .st
= 0 },
74 { .rst
= 1, .st
= 1 },
75 { .rst
= 2, .st
= 2 },
79 static const struct omap_prm_data omap4_prm_data
[] = {
80 { .name
= "tesla", .base
= 0x4a306400, .rstctrl
= 0x10, .rstst
= 0x14, .rstmap
= rst_map_01
},
81 { .name
= "core", .base
= 0x4a306700, .rstctrl
= 0x210, .rstst
= 0x214, .clkdm_name
= "ducati", .rstmap
= rst_map_012
},
82 { .name
= "ivahd", .base
= 0x4a306f00, .rstctrl
= 0x10, .rstst
= 0x14, .rstmap
= rst_map_012
},
83 { .name
= "device", .base
= 0x4a307b00, .rstctrl
= 0x0, .rstst
= 0x4, .rstmap
= rst_map_01
, .flags
= OMAP_PRM_HAS_RSTCTRL
| OMAP_PRM_HAS_NO_CLKDM
},
87 static const struct omap_rst_map am3_per_rst_map
[] = {
92 static const struct omap_rst_map am3_wkup_rst_map
[] = {
93 { .rst
= 3, .st
= 5 },
97 static const struct omap_prm_data am3_prm_data
[] = {
98 { .name
= "per", .base
= 0x44e00c00, .rstctrl
= 0x0, .rstmap
= am3_per_rst_map
, .flags
= OMAP_PRM_HAS_RSTCTRL
, .clkdm_name
= "pruss_ocp" },
99 { .name
= "wkup", .base
= 0x44e00d00, .rstctrl
= 0x0, .rstst
= 0xc, .rstmap
= am3_wkup_rst_map
, .flags
= OMAP_PRM_HAS_RSTCTRL
| OMAP_PRM_HAS_NO_CLKDM
},
100 { .name
= "device", .base
= 0x44e00f00, .rstctrl
= 0x0, .rstst
= 0x8, .rstmap
= rst_map_01
, .flags
= OMAP_PRM_HAS_RSTCTRL
| OMAP_PRM_HAS_NO_CLKDM
},
101 { .name
= "gfx", .base
= 0x44e01100, .rstctrl
= 0x4, .rstst
= 0x14, .rstmap
= rst_map_0
, .clkdm_name
= "gfx_l3" },
105 static const struct of_device_id omap_prm_id_table
[] = {
106 { .compatible
= "ti,omap4-prm-inst", .data
= omap4_prm_data
},
107 { .compatible
= "ti,am3-prm-inst", .data
= am3_prm_data
},
111 static bool _is_valid_reset(struct omap_reset_data
*reset
, unsigned long id
)
113 if (reset
->mask
& BIT(id
))
119 static int omap_reset_get_st_bit(struct omap_reset_data
*reset
,
122 const struct omap_rst_map
*map
= reset
->prm
->data
->rstmap
;
124 while (map
->rst
>= 0) {
134 static int omap_reset_status(struct reset_controller_dev
*rcdev
,
137 struct omap_reset_data
*reset
= to_omap_reset_data(rcdev
);
139 int st_bit
= omap_reset_get_st_bit(reset
, id
);
140 bool has_rstst
= reset
->prm
->data
->rstst
||
141 (reset
->prm
->data
->flags
& OMAP_PRM_HAS_RSTST
);
143 /* Check if we have rstst */
147 /* Check if hw reset line is asserted */
148 v
= readl_relaxed(reset
->prm
->base
+ reset
->prm
->data
->rstctrl
);
153 * Check reset status, high value means reset sequence has been
154 * completed successfully so we can return 0 here (reset deasserted)
156 v
= readl_relaxed(reset
->prm
->base
+ reset
->prm
->data
->rstst
);
163 static int omap_reset_assert(struct reset_controller_dev
*rcdev
,
166 struct omap_reset_data
*reset
= to_omap_reset_data(rcdev
);
170 /* assert the reset control line */
171 spin_lock_irqsave(&reset
->lock
, flags
);
172 v
= readl_relaxed(reset
->prm
->base
+ reset
->prm
->data
->rstctrl
);
174 writel_relaxed(v
, reset
->prm
->base
+ reset
->prm
->data
->rstctrl
);
175 spin_unlock_irqrestore(&reset
->lock
, flags
);
180 static int omap_reset_deassert(struct reset_controller_dev
*rcdev
,
183 struct omap_reset_data
*reset
= to_omap_reset_data(rcdev
);
188 struct ti_prm_platform_data
*pdata
= dev_get_platdata(reset
->dev
);
191 has_rstst
= reset
->prm
->data
->rstst
||
192 (reset
->prm
->data
->flags
& OMAP_PRM_HAS_RSTST
);
195 st_bit
= omap_reset_get_st_bit(reset
, id
);
197 /* Clear the reset status by writing 1 to the status bit */
199 writel_relaxed(v
, reset
->prm
->base
+ reset
->prm
->data
->rstst
);
203 pdata
->clkdm_deny_idle(reset
->clkdm
);
205 /* de-assert the reset control line */
206 spin_lock_irqsave(&reset
->lock
, flags
);
207 v
= readl_relaxed(reset
->prm
->base
+ reset
->prm
->data
->rstctrl
);
209 writel_relaxed(v
, reset
->prm
->base
+ reset
->prm
->data
->rstctrl
);
210 spin_unlock_irqrestore(&reset
->lock
, flags
);
215 /* wait for the status to be set */
216 ret
= readl_relaxed_poll_timeout(reset
->prm
->base
+
217 reset
->prm
->data
->rstst
,
218 v
, v
& BIT(st_bit
), 1,
219 OMAP_RESET_MAX_WAIT
);
221 pr_err("%s: timedout waiting for %s:%lu\n", __func__
,
222 reset
->prm
->data
->name
, id
);
226 pdata
->clkdm_allow_idle(reset
->clkdm
);
231 static const struct reset_control_ops omap_reset_ops
= {
232 .assert = omap_reset_assert
,
233 .deassert
= omap_reset_deassert
,
234 .status
= omap_reset_status
,
237 static int omap_prm_reset_xlate(struct reset_controller_dev
*rcdev
,
238 const struct of_phandle_args
*reset_spec
)
240 struct omap_reset_data
*reset
= to_omap_reset_data(rcdev
);
242 if (!_is_valid_reset(reset
, reset_spec
->args
[0]))
245 return reset_spec
->args
[0];
248 static int omap_prm_reset_init(struct platform_device
*pdev
,
249 struct omap_prm
*prm
)
251 struct omap_reset_data
*reset
;
252 const struct omap_rst_map
*map
;
253 struct ti_prm_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
257 * Check if we have controllable resets. If either rstctrl is non-zero
258 * or OMAP_PRM_HAS_RSTCTRL flag is set, we have reset control register
261 if (!prm
->data
->rstctrl
&& !(prm
->data
->flags
& OMAP_PRM_HAS_RSTCTRL
))
264 /* Check if we have the pdata callbacks in place */
265 if (!pdata
|| !pdata
->clkdm_lookup
|| !pdata
->clkdm_deny_idle
||
266 !pdata
->clkdm_allow_idle
)
269 map
= prm
->data
->rstmap
;
273 reset
= devm_kzalloc(&pdev
->dev
, sizeof(*reset
), GFP_KERNEL
);
277 reset
->rcdev
.owner
= THIS_MODULE
;
278 reset
->rcdev
.ops
= &omap_reset_ops
;
279 reset
->rcdev
.of_node
= pdev
->dev
.of_node
;
280 reset
->rcdev
.nr_resets
= OMAP_MAX_RESETS
;
281 reset
->rcdev
.of_xlate
= omap_prm_reset_xlate
;
282 reset
->rcdev
.of_reset_n_cells
= 1;
283 reset
->dev
= &pdev
->dev
;
284 spin_lock_init(&reset
->lock
);
288 sprintf(buf
, "%s_clkdm", prm
->data
->clkdm_name
? prm
->data
->clkdm_name
:
291 if (!(prm
->data
->flags
& OMAP_PRM_HAS_NO_CLKDM
)) {
292 reset
->clkdm
= pdata
->clkdm_lookup(buf
);
297 while (map
->rst
>= 0) {
298 reset
->mask
|= BIT(map
->rst
);
302 return devm_reset_controller_register(&pdev
->dev
, &reset
->rcdev
);
305 static int omap_prm_probe(struct platform_device
*pdev
)
307 struct resource
*res
;
308 const struct omap_prm_data
*data
;
309 struct omap_prm
*prm
;
310 const struct of_device_id
*match
;
312 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
316 match
= of_match_device(omap_prm_id_table
, &pdev
->dev
);
320 prm
= devm_kzalloc(&pdev
->dev
, sizeof(*prm
), GFP_KERNEL
);
326 while (data
->base
!= res
->start
) {
334 prm
->base
= devm_ioremap_resource(&pdev
->dev
, res
);
338 return omap_prm_reset_init(pdev
, prm
);
341 static struct platform_driver omap_prm_driver
= {
342 .probe
= omap_prm_probe
,
344 .name
= KBUILD_MODNAME
,
345 .of_match_table
= omap_prm_id_table
,
348 builtin_platform_driver(omap_prm_driver
);