blob: aca54cd6701c126dda873b7b9f308b2d2bcb6f05 [file] [log] [blame]
Shawn Guo8aa8f302019-03-20 15:32:39 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019, Linaro Limited
4 */
5
Simon Glass0f2af882020-05-10 11:40:05 -06006#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -07007#include <malloc.h>
Shawn Guo8aa8f302019-03-20 15:32:39 +08008#include <asm/io.h>
Shawn Guo8aa8f302019-03-20 15:32:39 +08009#include <dm.h>
10#include <dt-bindings/reset/ti-syscon.h>
11#include <reset-uclass.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060012#include <linux/bitops.h>
Shawn Guo8aa8f302019-03-20 15:32:39 +080013
14struct hisi_reset_priv {
15 void __iomem *base;
16};
17
18static int hisi_reset_deassert(struct reset_ctl *rst)
19{
20 struct hisi_reset_priv *priv = dev_get_priv(rst->dev);
21 u32 val;
22
23 val = readl(priv->base + rst->data);
24 if (rst->polarity & DEASSERT_SET)
25 val |= BIT(rst->id);
26 else
27 val &= ~BIT(rst->id);
28 writel(val, priv->base + rst->data);
29
30 return 0;
31}
32
33static int hisi_reset_assert(struct reset_ctl *rst)
34{
35 struct hisi_reset_priv *priv = dev_get_priv(rst->dev);
36 u32 val;
37
38 val = readl(priv->base + rst->data);
39 if (rst->polarity & ASSERT_SET)
40 val |= BIT(rst->id);
41 else
42 val &= ~BIT(rst->id);
43 writel(val, priv->base + rst->data);
44
45 return 0;
46}
47
Shawn Guo8aa8f302019-03-20 15:32:39 +080048static int hisi_reset_of_xlate(struct reset_ctl *rst,
49 struct ofnode_phandle_args *args)
50{
Yang Xiwen4f171482024-01-19 20:49:17 +080051 unsigned long polarity;
52
53 switch (args->args_count) {
54 case 2:
55 polarity = ASSERT_SET;
56 break;
57
58 case 3:
59 polarity = args->args[2];
60 break;
61
62 default:
Shawn Guo8aa8f302019-03-20 15:32:39 +080063 debug("Invalid args_count: %d\n", args->args_count);
64 return -EINVAL;
65 }
66
67 /* Use .data field as register offset and .id field as bit shift */
68 rst->data = args->args[0];
69 rst->id = args->args[1];
Yang Xiwen4f171482024-01-19 20:49:17 +080070 rst->polarity = polarity;
Shawn Guo8aa8f302019-03-20 15:32:39 +080071
72 return 0;
73}
74
75static const struct reset_ops hisi_reset_reset_ops = {
76 .of_xlate = hisi_reset_of_xlate,
Shawn Guo8aa8f302019-03-20 15:32:39 +080077 .rst_assert = hisi_reset_assert,
78 .rst_deassert = hisi_reset_deassert,
79};
80
81static const struct udevice_id hisi_reset_ids[] = {
82 { .compatible = "hisilicon,hi3798cv200-reset" },
83 { }
84};
85
86static int hisi_reset_probe(struct udevice *dev)
87{
88 struct hisi_reset_priv *priv = dev_get_priv(dev);
89
90 priv->base = dev_remap_addr(dev);
91 if (!priv->base)
92 return -ENOMEM;
93
94 return 0;
95}
96
97U_BOOT_DRIVER(hisi_reset) = {
98 .name = "hisilicon_reset",
99 .id = UCLASS_RESET,
100 .of_match = hisi_reset_ids,
101 .ops = &hisi_reset_reset_ops,
102 .probe = hisi_reset_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700103 .priv_auto = sizeof(struct hisi_reset_priv),
Shawn Guo8aa8f302019-03-20 15:32:39 +0800104};