]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/reset/reset-meson.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / reset / reset-meson.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0
20367bb5
NA
2/*
3 * Amlogic Meson Reset Controller driver
4 *
5 * Copyright (c) 2018 BayLibre, SAS.
6 * Author: Neil Armstrong <narmstrong@baylibre.com>
20367bb5
NA
7 */
8
d678a59d 9#include <common.h>
20367bb5 10#include <dm.h>
f7ae49fc 11#include <log.h>
336d4615 12#include <malloc.h>
20367bb5
NA
13#include <reset-uclass.h>
14#include <regmap.h>
cd93d625 15#include <linux/bitops.h>
cffe312b 16#include <linux/delay.h>
20367bb5 17
20367bb5 18#define BITS_PER_REG 32
cffe312b
AR
19
20struct meson_reset_drvdata {
21 unsigned int reg_count;
22 unsigned int level_offset;
23};
20367bb5
NA
24
25struct meson_reset_priv {
26 struct regmap *regmap;
cffe312b 27 struct meson_reset_drvdata *drvdata;
20367bb5
NA
28};
29
30static int meson_reset_request(struct reset_ctl *reset_ctl)
31{
cffe312b
AR
32 struct meson_reset_priv *priv = dev_get_priv(reset_ctl->dev);
33 struct meson_reset_drvdata *data = priv->drvdata;
34
35 if (reset_ctl->id > (data->reg_count * BITS_PER_REG))
20367bb5
NA
36 return -EINVAL;
37
38 return 0;
39}
40
20367bb5
NA
41static int meson_reset_level(struct reset_ctl *reset_ctl, bool assert)
42{
43 struct meson_reset_priv *priv = dev_get_priv(reset_ctl->dev);
cffe312b 44 struct meson_reset_drvdata *data = priv->drvdata;
20367bb5
NA
45 uint bank = reset_ctl->id / BITS_PER_REG;
46 uint offset = reset_ctl->id % BITS_PER_REG;
cffe312b 47 uint reg_offset = data->level_offset + (bank << 2);
20367bb5
NA
48 uint val;
49
50 regmap_read(priv->regmap, reg_offset, &val);
51 if (assert)
52 val &= ~BIT(offset);
53 else
54 val |= BIT(offset);
55 regmap_write(priv->regmap, reg_offset, val);
56
57 return 0;
58}
59
60static int meson_reset_assert(struct reset_ctl *reset_ctl)
61{
62 return meson_reset_level(reset_ctl, true);
63}
64
65static int meson_reset_deassert(struct reset_ctl *reset_ctl)
66{
67 return meson_reset_level(reset_ctl, false);
68}
69
70struct reset_ops meson_reset_ops = {
71 .request = meson_reset_request,
20367bb5
NA
72 .rst_assert = meson_reset_assert,
73 .rst_deassert = meson_reset_deassert,
74};
75
cffe312b
AR
76static const struct meson_reset_drvdata meson_gxbb_data = {
77 .reg_count = 8,
78 .level_offset = 0x7c,
79};
80
81static const struct meson_reset_drvdata meson_a1_data = {
82 .reg_count = 3,
83 .level_offset = 0x40,
84};
85
0a50b3c9 86static const struct udevice_id meson_reset_ids[] = {
cffe312b
AR
87 {
88 .compatible = "amlogic,meson-gxbb-reset",
89 .data = (ulong)&meson_gxbb_data,
90 },
91 {
92 .compatible = "amlogic,meson-axg-reset",
93 .data = (ulong)&meson_gxbb_data,
94 },
95 {
96 .compatible = "amlogic,meson-a1-reset",
97 .data = (ulong)&meson_a1_data,
98 },
0a50b3c9
WD
99 { }
100};
20367bb5
NA
101
102static int meson_reset_probe(struct udevice *dev)
103{
104 struct meson_reset_priv *priv = dev_get_priv(dev);
cffe312b 105 priv->drvdata = (struct meson_reset_drvdata *)dev_get_driver_data(dev);
0a50b3c9 106
d3581236 107 return regmap_init_mem(dev_ofnode(dev), &priv->regmap);
20367bb5
NA
108}
109
110U_BOOT_DRIVER(meson_reset) = {
111 .name = "meson_reset",
112 .id = UCLASS_RESET,
113 .of_match = meson_reset_ids,
114 .probe = meson_reset_probe,
115 .ops = &meson_reset_ops,
41575d8e 116 .priv_auto = sizeof(struct meson_reset_priv),
20367bb5 117};