118393f70SÁlvaro Fernández Rojas /*
218393f70SÁlvaro Fernández Rojas * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
318393f70SÁlvaro Fernández Rojas *
418393f70SÁlvaro Fernández Rojas * Derived from linux/arch/mips/bcm63xx/reset.c:
518393f70SÁlvaro Fernández Rojas * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
618393f70SÁlvaro Fernández Rojas *
718393f70SÁlvaro Fernández Rojas * SPDX-License-Identifier: GPL-2.0+
818393f70SÁlvaro Fernández Rojas */
918393f70SÁlvaro Fernández Rojas
1018393f70SÁlvaro Fernández Rojas #include <common.h>
1118393f70SÁlvaro Fernández Rojas #include <dm.h>
1218393f70SÁlvaro Fernández Rojas #include <errno.h>
1318393f70SÁlvaro Fernández Rojas #include <reset-uclass.h>
1418393f70SÁlvaro Fernández Rojas #include <asm/io.h>
1518393f70SÁlvaro Fernández Rojas
1618393f70SÁlvaro Fernández Rojas #define MAX_RESETS 32
1718393f70SÁlvaro Fernández Rojas
1818393f70SÁlvaro Fernández Rojas struct bcm6345_reset_priv {
1918393f70SÁlvaro Fernández Rojas void __iomem *regs;
2018393f70SÁlvaro Fernández Rojas };
2118393f70SÁlvaro Fernández Rojas
bcm6345_reset_assert(struct reset_ctl * rst)2218393f70SÁlvaro Fernández Rojas static int bcm6345_reset_assert(struct reset_ctl *rst)
2318393f70SÁlvaro Fernández Rojas {
2418393f70SÁlvaro Fernández Rojas struct bcm6345_reset_priv *priv = dev_get_priv(rst->dev);
2518393f70SÁlvaro Fernández Rojas
2618393f70SÁlvaro Fernández Rojas clrbits_be32(priv->regs, BIT(rst->id));
2718393f70SÁlvaro Fernández Rojas mdelay(20);
2818393f70SÁlvaro Fernández Rojas
2918393f70SÁlvaro Fernández Rojas return 0;
3018393f70SÁlvaro Fernández Rojas }
3118393f70SÁlvaro Fernández Rojas
bcm6345_reset_deassert(struct reset_ctl * rst)3218393f70SÁlvaro Fernández Rojas static int bcm6345_reset_deassert(struct reset_ctl *rst)
3318393f70SÁlvaro Fernández Rojas {
3418393f70SÁlvaro Fernández Rojas struct bcm6345_reset_priv *priv = dev_get_priv(rst->dev);
3518393f70SÁlvaro Fernández Rojas
3618393f70SÁlvaro Fernández Rojas setbits_be32(priv->regs, BIT(rst->id));
3718393f70SÁlvaro Fernández Rojas mdelay(20);
3818393f70SÁlvaro Fernández Rojas
3918393f70SÁlvaro Fernández Rojas return 0;
4018393f70SÁlvaro Fernández Rojas }
4118393f70SÁlvaro Fernández Rojas
bcm6345_reset_free(struct reset_ctl * rst)4218393f70SÁlvaro Fernández Rojas static int bcm6345_reset_free(struct reset_ctl *rst)
4318393f70SÁlvaro Fernández Rojas {
4418393f70SÁlvaro Fernández Rojas return 0;
4518393f70SÁlvaro Fernández Rojas }
4618393f70SÁlvaro Fernández Rojas
bcm6345_reset_request(struct reset_ctl * rst)4718393f70SÁlvaro Fernández Rojas static int bcm6345_reset_request(struct reset_ctl *rst)
4818393f70SÁlvaro Fernández Rojas {
4918393f70SÁlvaro Fernández Rojas if (rst->id >= MAX_RESETS)
5018393f70SÁlvaro Fernández Rojas return -EINVAL;
5118393f70SÁlvaro Fernández Rojas
5218393f70SÁlvaro Fernández Rojas return bcm6345_reset_assert(rst);
5318393f70SÁlvaro Fernández Rojas }
5418393f70SÁlvaro Fernández Rojas
5518393f70SÁlvaro Fernández Rojas struct reset_ops bcm6345_reset_reset_ops = {
5618393f70SÁlvaro Fernández Rojas .free = bcm6345_reset_free,
5718393f70SÁlvaro Fernández Rojas .request = bcm6345_reset_request,
5818393f70SÁlvaro Fernández Rojas .rst_assert = bcm6345_reset_assert,
5918393f70SÁlvaro Fernández Rojas .rst_deassert = bcm6345_reset_deassert,
6018393f70SÁlvaro Fernández Rojas };
6118393f70SÁlvaro Fernández Rojas
6218393f70SÁlvaro Fernández Rojas static const struct udevice_id bcm6345_reset_ids[] = {
6318393f70SÁlvaro Fernández Rojas { .compatible = "brcm,bcm6345-reset" },
6418393f70SÁlvaro Fernández Rojas { /* sentinel */ }
6518393f70SÁlvaro Fernández Rojas };
6618393f70SÁlvaro Fernández Rojas
bcm6345_reset_probe(struct udevice * dev)6718393f70SÁlvaro Fernández Rojas static int bcm6345_reset_probe(struct udevice *dev)
6818393f70SÁlvaro Fernández Rojas {
6918393f70SÁlvaro Fernández Rojas struct bcm6345_reset_priv *priv = dev_get_priv(dev);
7018393f70SÁlvaro Fernández Rojas fdt_addr_t addr;
7118393f70SÁlvaro Fernández Rojas fdt_size_t size;
7218393f70SÁlvaro Fernández Rojas
73*a821c4afSSimon Glass addr = devfdt_get_addr_size_index(dev, 0, &size);
7418393f70SÁlvaro Fernández Rojas if (addr == FDT_ADDR_T_NONE)
7518393f70SÁlvaro Fernández Rojas return -EINVAL;
7618393f70SÁlvaro Fernández Rojas
7718393f70SÁlvaro Fernández Rojas priv->regs = ioremap(addr, size);
7818393f70SÁlvaro Fernández Rojas
7918393f70SÁlvaro Fernández Rojas return 0;
8018393f70SÁlvaro Fernández Rojas }
8118393f70SÁlvaro Fernández Rojas
8218393f70SÁlvaro Fernández Rojas U_BOOT_DRIVER(bcm6345_reset) = {
8318393f70SÁlvaro Fernández Rojas .name = "bcm6345-reset",
8418393f70SÁlvaro Fernández Rojas .id = UCLASS_RESET,
8518393f70SÁlvaro Fernández Rojas .of_match = bcm6345_reset_ids,
8618393f70SÁlvaro Fernández Rojas .ops = &bcm6345_reset_reset_ops,
8718393f70SÁlvaro Fernández Rojas .probe = bcm6345_reset_probe,
8818393f70SÁlvaro Fernández Rojas .priv_auto_alloc_size = sizeof(struct bcm6345_reset_priv),
8918393f70SÁlvaro Fernández Rojas };
90