blob: a07b0f4fd553779c598b4db0830f619f08882dfe [file] [log] [blame]
Simon Goldschmidtbe366392019-07-15 21:47:53 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2019 Pepperl+Fuchs
4 * Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
5 */
6
Simon Goldschmidtbe366392019-07-15 21:47:53 +02007#include <dm.h>
8#include <errno.h>
9#include <sysreset.h>
10#include <asm/io.h>
11#include <asm/arch/reset_manager.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060012#include <linux/bitops.h>
Simon Goldschmidtbe366392019-07-15 21:47:53 +020013
14struct socfpga_sysreset_data {
Ley Foon Tanfed4c952019-11-08 10:38:19 +080015 void __iomem *rstmgr_base;
Simon Goldschmidtbe366392019-07-15 21:47:53 +020016};
17
18static int socfpga_sysreset_request(struct udevice *dev,
19 enum sysreset_t type)
20{
21 struct socfpga_sysreset_data *data = dev_get_priv(dev);
22
23 switch (type) {
24 case SYSRESET_WARM:
25 writel(BIT(RSTMGR_CTRL_SWWARMRSTREQ_LSB),
Ley Foon Tanfed4c952019-11-08 10:38:19 +080026 data->rstmgr_base + RSTMGR_CTRL);
Simon Goldschmidtbe366392019-07-15 21:47:53 +020027 break;
28 case SYSRESET_COLD:
29 writel(BIT(RSTMGR_CTRL_SWCOLDRSTREQ_LSB),
Ley Foon Tanfed4c952019-11-08 10:38:19 +080030 data->rstmgr_base + RSTMGR_CTRL);
Simon Goldschmidtbe366392019-07-15 21:47:53 +020031 break;
32 default:
33 return -EPROTONOSUPPORT;
34 }
35 return -EINPROGRESS;
36}
37
38static int socfpga_sysreset_probe(struct udevice *dev)
39{
40 struct socfpga_sysreset_data *data = dev_get_priv(dev);
41
Paweł Anikiel2d445722022-06-17 12:47:22 +020042 data->rstmgr_base = dev_read_addr_ptr(dev_get_parent(dev));
Simon Goldschmidtbe366392019-07-15 21:47:53 +020043 return 0;
44}
45
46static struct sysreset_ops socfpga_sysreset = {
47 .request = socfpga_sysreset_request,
48};
49
50U_BOOT_DRIVER(sysreset_socfpga) = {
51 .id = UCLASS_SYSRESET,
52 .name = "socfpga_sysreset",
Simon Glass8a2b47f2020-12-03 16:55:17 -070053 .priv_auto = sizeof(struct socfpga_sysreset_data),
Simon Goldschmidtbe366392019-07-15 21:47:53 +020054 .ops = &socfpga_sysreset,
55 .probe = socfpga_sysreset_probe,
56};