blob: 985235a3ac461f8394246c152de5b15be0f65b26 [file] [log] [blame]
Chia-Wei, Wang9fc21082020-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
Chia-Wei, Wang9fc21082020-12-14 13:54:26 +080020static int ast2600_reset_assert(struct reset_ctl *reset_ctl)
21{
22 struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev);
23 struct ast2600_scu *scu = priv->scu;
24
25 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
26
27 if (reset_ctl->id < 32)
Chia-Wei Wangbc7b3842021-07-20 15:01:36 +080028 writel(BIT(reset_ctl->id), &scu->modrst_ctrl1);
Chia-Wei, Wang9fc21082020-12-14 13:54:26 +080029 else
Chia-Wei Wangbc7b3842021-07-20 15:01:36 +080030 writel(BIT(reset_ctl->id - 32), &scu->modrst_ctrl2);
Chia-Wei, Wang9fc21082020-12-14 13:54:26 +080031
32 return 0;
33}
34
35static int ast2600_reset_deassert(struct reset_ctl *reset_ctl)
36{
37 struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev);
38 struct ast2600_scu *scu = priv->scu;
39
40 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
41
42 if (reset_ctl->id < 32)
Chia-Wei Wangbc7b3842021-07-20 15:01:36 +080043 writel(BIT(reset_ctl->id), &scu->modrst_clr1);
Chia-Wei, Wang9fc21082020-12-14 13:54:26 +080044 else
Chia-Wei Wangbc7b3842021-07-20 15:01:36 +080045 writel(BIT(reset_ctl->id - 32), &scu->modrst_clr2);
Chia-Wei, Wang9fc21082020-12-14 13:54:26 +080046
47 return 0;
48}
49
50static int ast2600_reset_probe(struct udevice *dev)
51{
52 int rc;
53 struct ast2600_reset_priv *priv = dev_get_priv(dev);
54 struct udevice *scu_dev;
55
56 /* get SCU base from clock device */
57 rc = uclass_get_device_by_driver(UCLASS_CLK,
58 DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev);
59 if (rc) {
60 debug("%s: clock device not found, rc=%d\n", __func__, rc);
61 return rc;
62 }
63
64 priv->scu = devfdt_get_addr_ptr(scu_dev);
65 if (IS_ERR_OR_NULL(priv->scu)) {
66 debug("%s: invalid SCU base pointer\n", __func__);
67 return PTR_ERR(priv->scu);
68 }
69
70 return 0;
71}
72
73static const struct udevice_id ast2600_reset_ids[] = {
74 { .compatible = "aspeed,ast2600-reset" },
75 { }
76};
77
78struct reset_ops ast2600_reset_ops = {
Chia-Wei, Wang9fc21082020-12-14 13:54:26 +080079 .rst_assert = ast2600_reset_assert,
80 .rst_deassert = ast2600_reset_deassert,
81};
82
83U_BOOT_DRIVER(ast2600_reset) = {
84 .name = "ast2600_reset",
85 .id = UCLASS_RESET,
86 .of_match = ast2600_reset_ids,
87 .probe = ast2600_reset_probe,
88 .ops = &ast2600_reset_ops,
89 .priv_auto = sizeof(struct ast2600_reset_priv),
90};