blob: e484d1fff449ff22063eaf0b9ee53e33e963ebe3 [file] [log] [blame]
Jagan Teki7f6c2a82019-01-18 22:18:13 +05301// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (C) 2018 Amarula Solutions.
4 * Author: Jagan Teki <jagan@amarulasolutions.com>
5 */
6
Tom Riniabb9a042024-05-18 20:20:43 -06007#include <common.h>
Jagan Teki7f6c2a82019-01-18 22:18:13 +05308#include <dm.h>
9#include <errno.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -070011#include <malloc.h>
Jagan Teki7f6c2a82019-01-18 22:18:13 +053012#include <reset-uclass.h>
13#include <asm/io.h>
Samuel Holland12e3faa2021-09-12 11:48:43 -050014#include <clk/sunxi.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060015#include <linux/bitops.h>
Jagan Teki7f6c2a82019-01-18 22:18:13 +053016#include <linux/log2.h>
Jagan Teki7f6c2a82019-01-18 22:18:13 +053017
Samuel Holland86b561c2022-05-09 00:29:37 -050018static const struct ccu_reset *plat_to_reset(struct ccu_plat *plat,
Jagan Teki7f6c2a82019-01-18 22:18:13 +053019 unsigned long id)
20{
Samuel Holland24a870c2022-05-09 00:29:36 -050021 return &plat->desc->resets[id];
Jagan Teki7f6c2a82019-01-18 22:18:13 +053022}
23
24static int sunxi_reset_request(struct reset_ctl *reset_ctl)
25{
Samuel Holland86b561c2022-05-09 00:29:37 -050026 struct ccu_plat *plat = dev_get_plat(reset_ctl->dev);
Jagan Teki7f6c2a82019-01-18 22:18:13 +053027
28 debug("%s: (RST#%ld)\n", __func__, reset_ctl->id);
29
Samuel Holland24a870c2022-05-09 00:29:36 -050030 if (reset_ctl->id >= plat->desc->num_resets)
Jagan Teki7f6c2a82019-01-18 22:18:13 +053031 return -EINVAL;
32
33 return 0;
34}
35
Jagan Teki7f6c2a82019-01-18 22:18:13 +053036static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on)
37{
Samuel Holland86b561c2022-05-09 00:29:37 -050038 struct ccu_plat *plat = dev_get_plat(reset_ctl->dev);
Samuel Holland24a870c2022-05-09 00:29:36 -050039 const struct ccu_reset *reset = plat_to_reset(plat, reset_ctl->id);
Jagan Teki7f6c2a82019-01-18 22:18:13 +053040 u32 reg;
41
42 if (!(reset->flags & CCU_RST_F_IS_VALID)) {
43 printf("%s: (RST#%ld) unhandled\n", __func__, reset_ctl->id);
44 return 0;
45 }
46
47 debug("%s: (RST#%ld) off#0x%x, BIT(%d)\n", __func__,
48 reset_ctl->id, reset->off, ilog2(reset->bit));
49
Samuel Holland24a870c2022-05-09 00:29:36 -050050 reg = readl(plat->base + reset->off);
Jagan Teki7f6c2a82019-01-18 22:18:13 +053051 if (on)
52 reg |= reset->bit;
53 else
54 reg &= ~reset->bit;
55
Samuel Holland24a870c2022-05-09 00:29:36 -050056 writel(reg, plat->base + reset->off);
Jagan Teki7f6c2a82019-01-18 22:18:13 +053057
58 return 0;
59}
60
61static int sunxi_reset_assert(struct reset_ctl *reset_ctl)
62{
63 return sunxi_set_reset(reset_ctl, false);
64}
65
66static int sunxi_reset_deassert(struct reset_ctl *reset_ctl)
67{
68 return sunxi_set_reset(reset_ctl, true);
69}
70
71struct reset_ops sunxi_reset_ops = {
72 .request = sunxi_reset_request,
Jagan Teki7f6c2a82019-01-18 22:18:13 +053073 .rst_assert = sunxi_reset_assert,
74 .rst_deassert = sunxi_reset_deassert,
75};
76
Jagan Teki7f6c2a82019-01-18 22:18:13 +053077U_BOOT_DRIVER(sunxi_reset) = {
78 .name = "sunxi_reset",
79 .id = UCLASS_RESET,
80 .ops = &sunxi_reset_ops,
Jagan Teki7f6c2a82019-01-18 22:18:13 +053081};