1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Socfpga Reset Controller Driver 4 * 5 * Copyright 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de> 6 * 7 * based on 8 * Allwinner SoCs Reset Controller driver 9 * 10 * Copyright 2013 Maxime Ripard 11 * 12 * Maxime Ripard <maxime.ripard@free-electrons.com> 13 */ 14 15 #include <common.h> 16 #include <dm.h> 17 #include <dm/of_access.h> 18 #include <reset-uclass.h> 19 #include <linux/bitops.h> 20 #include <linux/io.h> 21 #include <linux/sizes.h> 22 23 #define BANK_INCREMENT 4 24 #define NR_BANKS 8 25 26 struct socfpga_reset_data { 27 void __iomem *membase; 28 }; 29 30 static int socfpga_reset_assert(struct reset_ctl *reset_ctl) 31 { 32 struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev); 33 int id = reset_ctl->id; 34 int reg_width = sizeof(u32); 35 int bank = id / (reg_width * BITS_PER_BYTE); 36 int offset = id % (reg_width * BITS_PER_BYTE); 37 38 setbits_le32(data->membase + (bank * BANK_INCREMENT), BIT(offset)); 39 return 0; 40 } 41 42 static int socfpga_reset_deassert(struct reset_ctl *reset_ctl) 43 { 44 struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev); 45 int id = reset_ctl->id; 46 int reg_width = sizeof(u32); 47 int bank = id / (reg_width * BITS_PER_BYTE); 48 int offset = id % (reg_width * BITS_PER_BYTE); 49 50 clrbits_le32(data->membase + (bank * BANK_INCREMENT), BIT(offset)); 51 return 0; 52 } 53 54 static int socfpga_reset_request(struct reset_ctl *reset_ctl) 55 { 56 debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, 57 reset_ctl, reset_ctl->dev, reset_ctl->id); 58 59 return 0; 60 } 61 62 static int socfpga_reset_free(struct reset_ctl *reset_ctl) 63 { 64 debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, 65 reset_ctl->dev, reset_ctl->id); 66 67 return 0; 68 } 69 70 static const struct reset_ops socfpga_reset_ops = { 71 .request = socfpga_reset_request, 72 .free = socfpga_reset_free, 73 .rst_assert = socfpga_reset_assert, 74 .rst_deassert = socfpga_reset_deassert, 75 }; 76 77 static int socfpga_reset_probe(struct udevice *dev) 78 { 79 struct socfpga_reset_data *data = dev_get_priv(dev); 80 const void *blob = gd->fdt_blob; 81 int node = dev_of_offset(dev); 82 u32 modrst_offset; 83 84 data->membase = devfdt_get_addr_ptr(dev); 85 86 modrst_offset = fdtdec_get_int(blob, node, "altr,modrst-offset", 0x10); 87 data->membase += modrst_offset; 88 89 return 0; 90 } 91 92 static const struct udevice_id socfpga_reset_match[] = { 93 { .compatible = "altr,rst-mgr" }, 94 { /* sentinel */ }, 95 }; 96 97 U_BOOT_DRIVER(socfpga_reset) = { 98 .name = "socfpga-reset", 99 .id = UCLASS_RESET, 100 .of_match = socfpga_reset_match, 101 .probe = socfpga_reset_probe, 102 .priv_auto_alloc_size = sizeof(struct socfpga_reset_data), 103 .ops = &socfpga_reset_ops, 104 }; 105