1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2019, Linaro Limited
4 */
5
6 #include <asm/io.h>
7 #include <common.h>
8 #include <dm.h>
9 #include <dt-bindings/reset/ti-syscon.h>
10 #include <reset-uclass.h>
11
12 struct hisi_reset_priv {
13 void __iomem *base;
14 };
15
hisi_reset_deassert(struct reset_ctl * rst)16 static int hisi_reset_deassert(struct reset_ctl *rst)
17 {
18 struct hisi_reset_priv *priv = dev_get_priv(rst->dev);
19 u32 val;
20
21 val = readl(priv->base + rst->data);
22 if (rst->polarity & DEASSERT_SET)
23 val |= BIT(rst->id);
24 else
25 val &= ~BIT(rst->id);
26 writel(val, priv->base + rst->data);
27
28 return 0;
29 }
30
hisi_reset_assert(struct reset_ctl * rst)31 static int hisi_reset_assert(struct reset_ctl *rst)
32 {
33 struct hisi_reset_priv *priv = dev_get_priv(rst->dev);
34 u32 val;
35
36 val = readl(priv->base + rst->data);
37 if (rst->polarity & ASSERT_SET)
38 val |= BIT(rst->id);
39 else
40 val &= ~BIT(rst->id);
41 writel(val, priv->base + rst->data);
42
43 return 0;
44 }
45
hisi_reset_free(struct reset_ctl * rst)46 static int hisi_reset_free(struct reset_ctl *rst)
47 {
48 return 0;
49 }
50
hisi_reset_request(struct reset_ctl * rst)51 static int hisi_reset_request(struct reset_ctl *rst)
52 {
53 return 0;
54 }
55
hisi_reset_of_xlate(struct reset_ctl * rst,struct ofnode_phandle_args * args)56 static int hisi_reset_of_xlate(struct reset_ctl *rst,
57 struct ofnode_phandle_args *args)
58 {
59 if (args->args_count != 3) {
60 debug("Invalid args_count: %d\n", args->args_count);
61 return -EINVAL;
62 }
63
64 /* Use .data field as register offset and .id field as bit shift */
65 rst->data = args->args[0];
66 rst->id = args->args[1];
67 rst->polarity = args->args[2];
68
69 return 0;
70 }
71
72 static const struct reset_ops hisi_reset_reset_ops = {
73 .of_xlate = hisi_reset_of_xlate,
74 .request = hisi_reset_request,
75 .free = hisi_reset_free,
76 .rst_assert = hisi_reset_assert,
77 .rst_deassert = hisi_reset_deassert,
78 };
79
80 static const struct udevice_id hisi_reset_ids[] = {
81 { .compatible = "hisilicon,hi3798cv200-reset" },
82 { }
83 };
84
hisi_reset_probe(struct udevice * dev)85 static int hisi_reset_probe(struct udevice *dev)
86 {
87 struct hisi_reset_priv *priv = dev_get_priv(dev);
88
89 priv->base = dev_remap_addr(dev);
90 if (!priv->base)
91 return -ENOMEM;
92
93 return 0;
94 }
95
96 U_BOOT_DRIVER(hisi_reset) = {
97 .name = "hisilicon_reset",
98 .id = UCLASS_RESET,
99 .of_match = hisi_reset_ids,
100 .ops = &hisi_reset_reset_ops,
101 .probe = hisi_reset_probe,
102 .priv_auto_alloc_size = sizeof(struct hisi_reset_priv),
103 };
104