]> git.sur5r.net Git - u-boot/blob - drivers/reset/reset-socfpga.c
466455d073991db6ec950550ca12c24551ca2b9c
[u-boot] / drivers / reset / reset-socfpga.c
1 /*
2  * Socfpga Reset Controller Driver
3  *
4  * Copyright 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
5  *
6  * based on
7  * Allwinner SoCs Reset Controller driver
8  *
9  * Copyright 2013 Maxime Ripard
10  *
11  * Maxime Ripard <maxime.ripard@free-electrons.com>
12  *
13  * SPDX-License-Identifier:     GPL-2.0+
14  */
15
16 #include <common.h>
17 #include <dm.h>
18 #include <dm/of_access.h>
19 #include <reset-uclass.h>
20 #include <linux/bitops.h>
21 #include <linux/io.h>
22 #include <linux/sizes.h>
23
24 #define BANK_INCREMENT          4
25 #define NR_BANKS                8
26
27 struct socfpga_reset_data {
28         void __iomem *membase;
29 };
30
31 static int socfpga_reset_assert(struct reset_ctl *reset_ctl)
32 {
33         struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev);
34         int id = reset_ctl->id;
35         int reg_width = sizeof(u32);
36         int bank = id / (reg_width * BITS_PER_BYTE);
37         int offset = id % (reg_width * BITS_PER_BYTE);
38
39         setbits_le32(data->membase + (bank * BANK_INCREMENT), BIT(offset));
40         return 0;
41 }
42
43 static int socfpga_reset_deassert(struct reset_ctl *reset_ctl)
44 {
45         struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev);
46         int id = reset_ctl->id;
47         int reg_width = sizeof(u32);
48         int bank = id / (reg_width * BITS_PER_BYTE);
49         int offset = id % (reg_width * BITS_PER_BYTE);
50
51         clrbits_le32(data->membase + (bank * BANK_INCREMENT), BIT(offset));
52         return 0;
53 }
54
55 static int socfpga_reset_request(struct reset_ctl *reset_ctl)
56 {
57         debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__,
58               reset_ctl, reset_ctl->dev, reset_ctl->id);
59
60         return 0;
61 }
62
63 static int socfpga_reset_free(struct reset_ctl *reset_ctl)
64 {
65         debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
66               reset_ctl->dev, reset_ctl->id);
67
68         return 0;
69 }
70
71 static const struct reset_ops socfpga_reset_ops = {
72         .request = socfpga_reset_request,
73         .free = socfpga_reset_free,
74         .rst_assert = socfpga_reset_assert,
75         .rst_deassert = socfpga_reset_deassert,
76 };
77
78 static int socfpga_reset_probe(struct udevice *dev)
79 {
80         struct socfpga_reset_data *data = dev_get_priv(dev);
81         const void *blob = gd->fdt_blob;
82         int node = dev_of_offset(dev);
83         u32 modrst_offset;
84
85         data->membase = devfdt_get_addr_ptr(dev);
86
87         modrst_offset = fdtdec_get_int(blob, node, "altr,modrst-offset", 0x10);
88         data->membase += modrst_offset;
89
90         return 0;
91 }
92
93 static const struct udevice_id socfpga_reset_match[] = {
94         { .compatible = "altr,rst-mgr" },
95         { /* sentinel */ },
96 };
97
98 U_BOOT_DRIVER(socfpga_reset) = {
99         .name = "socfpga-reset",
100         .id = UCLASS_RESET,
101         .of_match = socfpga_reset_match,
102         .probe = socfpga_reset_probe,
103         .priv_auto_alloc_size = sizeof(struct socfpga_reset_data),
104         .ops = &socfpga_reset_ops,
105 };