blob: f64adaf74e8b78432ada38848e761ef4a49ca213 [file] [log] [blame]
Chia-Wei, Wang71140512020-12-14 13:54:26 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2020 ASPEED Technology Inc.
4 */
5
6#include <common.h>
7#include <dm.h>
8#include <log.h>
9#include <misc.h>
10#include <reset.h>
11#include <reset-uclass.h>
12#include <linux/err.h>
13#include <asm/io.h>
14#include <asm/arch/scu_ast2600.h>
15
16struct ast2600_reset_priv {
17 struct ast2600_scu *scu;
18};
19
20static int ast2600_reset_request(struct reset_ctl *reset_ctl)
21{
22 debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
23 reset_ctl->dev, reset_ctl->id);
24
25 return 0;
26}
27
28static int ast2600_reset_free(struct reset_ctl *reset_ctl)
29{
30 debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
31 reset_ctl->dev, reset_ctl->id);
32
33 return 0;
34}
35
36static int ast2600_reset_assert(struct reset_ctl *reset_ctl)
37{
38 struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev);
39 struct ast2600_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 writel(BIT(reset_ctl->id), scu->modrst_ctrl1);
45 else
46 writel(BIT(reset_ctl->id - 32), scu->modrst_ctrl2);
47
48 return 0;
49}
50
51static int ast2600_reset_deassert(struct reset_ctl *reset_ctl)
52{
53 struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev);
54 struct ast2600_scu *scu = priv->scu;
55
56 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
57
58 if (reset_ctl->id < 32)
59 writel(BIT(reset_ctl->id), scu->modrst_clr1);
60 else
61 writel(BIT(reset_ctl->id - 32), scu->modrst_clr2);
62
63 return 0;
64}
65
66static int ast2600_reset_probe(struct udevice *dev)
67{
68 int rc;
69 struct ast2600_reset_priv *priv = dev_get_priv(dev);
70 struct udevice *scu_dev;
71
72 /* get SCU base from clock device */
73 rc = uclass_get_device_by_driver(UCLASS_CLK,
74 DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev);
75 if (rc) {
76 debug("%s: clock device not found, rc=%d\n", __func__, rc);
77 return rc;
78 }
79
80 priv->scu = devfdt_get_addr_ptr(scu_dev);
81 if (IS_ERR_OR_NULL(priv->scu)) {
82 debug("%s: invalid SCU base pointer\n", __func__);
83 return PTR_ERR(priv->scu);
84 }
85
86 return 0;
87}
88
89static const struct udevice_id ast2600_reset_ids[] = {
90 { .compatible = "aspeed,ast2600-reset" },
91 { }
92};
93
94struct reset_ops ast2600_reset_ops = {
95 .request = ast2600_reset_request,
96 .rfree = ast2600_reset_free,
97 .rst_assert = ast2600_reset_assert,
98 .rst_deassert = ast2600_reset_deassert,
99};
100
101U_BOOT_DRIVER(ast2600_reset) = {
102 .name = "ast2600_reset",
103 .id = UCLASS_RESET,
104 .of_match = ast2600_reset_ids,
105 .probe = ast2600_reset_probe,
106 .ops = &ast2600_reset_ops,
107 .priv_auto = sizeof(struct ast2600_reset_priv),
108};