ARM: dts: npcm8xx: add npcm845 function node
[platform/kernel/u-boot.git] / drivers / reset / reset-ast2500.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2017 Google, Inc
4  * Copyright 2020 ASPEED Technology Inc.
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <log.h>
10 #include <misc.h>
11 #include <reset.h>
12 #include <reset-uclass.h>
13 #include <linux/err.h>
14 #include <asm/io.h>
15 #include <asm/arch/scu_ast2500.h>
16
17 struct ast2500_reset_priv {
18         struct ast2500_scu *scu;
19 };
20
21 static int ast2500_reset_assert(struct reset_ctl *reset_ctl)
22 {
23         struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
24         struct ast2500_scu *scu = priv->scu;
25
26         debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
27
28         if (reset_ctl->id < 32)
29                 setbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id));
30         else
31                 setbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32));
32
33         return 0;
34 }
35
36 static int ast2500_reset_deassert(struct reset_ctl *reset_ctl)
37 {
38         struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
39         struct ast2500_scu *scu = priv->scu;
40
41         debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
42
43         if (reset_ctl->id < 32)
44                 clrbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id));
45         else
46                 clrbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32));
47
48         return 0;
49 }
50
51 static int ast2500_reset_status(struct reset_ctl *reset_ctl)
52 {
53         struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
54         struct ast2500_scu *scu = priv->scu;
55         int status;
56
57         debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
58
59         if (reset_ctl->id < 32)
60                 status = BIT(reset_ctl->id) & readl(&scu->sysreset_ctrl1);
61         else
62                 status = BIT(reset_ctl->id - 32) & readl(&scu->sysreset_ctrl2);
63
64         return !!status;
65 }
66
67
68
69 static int ast2500_reset_probe(struct udevice *dev)
70 {
71         int rc;
72         struct ast2500_reset_priv *priv = dev_get_priv(dev);
73         struct udevice *scu_dev;
74
75         /* get SCU base from clock device */
76         rc = uclass_get_device_by_driver(UCLASS_CLK,
77                                          DM_DRIVER_GET(aspeed_ast2500_scu), &scu_dev);
78         if (rc) {
79                 debug("%s: clock device not found, rc=%d\n", __func__, rc);
80                 return rc;
81         }
82
83         priv->scu = devfdt_get_addr_ptr(scu_dev);
84         if (IS_ERR_OR_NULL(priv->scu)) {
85                 debug("%s: invalid SCU base pointer\n", __func__);
86                 return PTR_ERR(priv->scu);
87         }
88
89         return 0;
90 }
91
92 static const struct udevice_id ast2500_reset_ids[] = {
93         { .compatible = "aspeed,ast2500-reset" },
94         { }
95 };
96
97 struct reset_ops ast2500_reset_ops = {
98         .rst_assert = ast2500_reset_assert,
99         .rst_deassert = ast2500_reset_deassert,
100         .rst_status = ast2500_reset_status,
101 };
102
103 U_BOOT_DRIVER(ast2500_reset) = {
104         .name = "ast2500_reset",
105         .id = UCLASS_RESET,
106         .of_match = ast2500_reset_ids,
107         .probe = ast2500_reset_probe,
108         .ops = &ast2500_reset_ops,
109         .priv_auto      = sizeof(struct ast2500_reset_priv),
110 };