blob: ec7b9b6625dc5bb910a0dbd0bf08f45f8e36f32c [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
Chia-Wei, Wang71140512020-12-14 13:54:26 +08006#include <dm.h>
7#include <log.h>
8#include <misc.h>
9#include <reset.h>
10#include <reset-uclass.h>
11#include <linux/err.h>
12#include <asm/io.h>
13#include <asm/arch/scu_ast2600.h>
14
15struct ast2600_reset_priv {
16 struct ast2600_scu *scu;
17};
18
Chia-Wei, Wang71140512020-12-14 13:54:26 +080019static int ast2600_reset_assert(struct reset_ctl *reset_ctl)
20{
21 struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev);
22 struct ast2600_scu *scu = priv->scu;
23
24 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
25
26 if (reset_ctl->id < 32)
Chia-Wei Wang39c11062021-07-20 15:01:36 +080027 writel(BIT(reset_ctl->id), &scu->modrst_ctrl1);
Chia-Wei, Wang71140512020-12-14 13:54:26 +080028 else
Chia-Wei Wang39c11062021-07-20 15:01:36 +080029 writel(BIT(reset_ctl->id - 32), &scu->modrst_ctrl2);
Chia-Wei, Wang71140512020-12-14 13:54:26 +080030
31 return 0;
32}
33
34static int ast2600_reset_deassert(struct reset_ctl *reset_ctl)
35{
36 struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev);
37 struct ast2600_scu *scu = priv->scu;
38
39 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
40
41 if (reset_ctl->id < 32)
Chia-Wei Wang39c11062021-07-20 15:01:36 +080042 writel(BIT(reset_ctl->id), &scu->modrst_clr1);
Chia-Wei, Wang71140512020-12-14 13:54:26 +080043 else
Chia-Wei Wang39c11062021-07-20 15:01:36 +080044 writel(BIT(reset_ctl->id - 32), &scu->modrst_clr2);
Chia-Wei, Wang71140512020-12-14 13:54:26 +080045
46 return 0;
47}
48
Joel Stanley09df10d2022-06-23 14:40:37 +093049static int ast2600_reset_status(struct reset_ctl *reset_ctl)
50{
51 struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev);
52 struct ast2600_scu *scu = priv->scu;
53 int status;
54
55 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
56
57 if (reset_ctl->id < 32)
58 status = BIT(reset_ctl->id) & readl(&scu->modrst_ctrl1);
59 else
60 status = BIT(reset_ctl->id - 32) & readl(&scu->modrst_ctrl2);
61
62 return !!status;
63}
64
Chia-Wei, Wang71140512020-12-14 13:54:26 +080065static int ast2600_reset_probe(struct udevice *dev)
66{
67 int rc;
68 struct ast2600_reset_priv *priv = dev_get_priv(dev);
69 struct udevice *scu_dev;
70
71 /* get SCU base from clock device */
72 rc = uclass_get_device_by_driver(UCLASS_CLK,
73 DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev);
74 if (rc) {
75 debug("%s: clock device not found, rc=%d\n", __func__, rc);
76 return rc;
77 }
78
79 priv->scu = devfdt_get_addr_ptr(scu_dev);
80 if (IS_ERR_OR_NULL(priv->scu)) {
81 debug("%s: invalid SCU base pointer\n", __func__);
82 return PTR_ERR(priv->scu);
83 }
84
85 return 0;
86}
87
88static const struct udevice_id ast2600_reset_ids[] = {
89 { .compatible = "aspeed,ast2600-reset" },
90 { }
91};
92
93struct reset_ops ast2600_reset_ops = {
Chia-Wei, Wang71140512020-12-14 13:54:26 +080094 .rst_assert = ast2600_reset_assert,
95 .rst_deassert = ast2600_reset_deassert,
Joel Stanley09df10d2022-06-23 14:40:37 +093096 .rst_status = ast2600_reset_status,
Chia-Wei, Wang71140512020-12-14 13:54:26 +080097};
98
99U_BOOT_DRIVER(ast2600_reset) = {
100 .name = "ast2600_reset",
101 .id = UCLASS_RESET,
102 .of_match = ast2600_reset_ids,
103 .probe = ast2600_reset_probe,
104 .ops = &ast2600_reset_ops,
105 .priv_auto = sizeof(struct ast2600_reset_priv),
106};