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