Merge tag 'efi-2019-07-rc1-3' of git://git.denx.de/u-boot-efi
[oweals/u-boot.git] / drivers / reset / reset-hisilicon.c
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
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
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
46 static int hisi_reset_free(struct reset_ctl *rst)
47 {
48         return 0;
49 }
50
51 static int hisi_reset_request(struct reset_ctl *rst)
52 {
53         return 0;
54 }
55
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
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 };