1 /* 2 * Reset driver for NXP LPC18xx/43xx Reset Generation Unit (RGU). 3 * 4 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 */ 11 12 #include <linux/clk.h> 13 #include <linux/delay.h> 14 #include <linux/err.h> 15 #include <linux/io.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/platform_device.h> 19 #include <linux/reboot.h> 20 #include <linux/reset-controller.h> 21 #include <linux/spinlock.h> 22 23 /* LPC18xx RGU registers */ 24 #define LPC18XX_RGU_CTRL0 0x100 25 #define LPC18XX_RGU_CTRL1 0x104 26 #define LPC18XX_RGU_ACTIVE_STATUS0 0x150 27 #define LPC18XX_RGU_ACTIVE_STATUS1 0x154 28 29 #define LPC18XX_RGU_RESETS_PER_REG 32 30 31 /* Internal reset outputs */ 32 #define LPC18XX_RGU_CORE_RST 0 33 #define LPC43XX_RGU_M0SUB_RST 12 34 #define LPC43XX_RGU_M0APP_RST 56 35 36 struct lpc18xx_rgu_data { 37 struct reset_controller_dev rcdev; 38 struct clk *clk_delay; 39 struct clk *clk_reg; 40 void __iomem *base; 41 spinlock_t lock; 42 u32 delay_us; 43 }; 44 45 #define to_rgu_data(p) container_of(p, struct lpc18xx_rgu_data, rcdev) 46 47 static void __iomem *rgu_base; 48 49 static int lpc18xx_rgu_restart(struct notifier_block *this, unsigned long mode, 50 void *cmd) 51 { 52 writel(BIT(LPC18XX_RGU_CORE_RST), rgu_base + LPC18XX_RGU_CTRL0); 53 mdelay(2000); 54 55 pr_emerg("%s: unable to restart system\n", __func__); 56 57 return NOTIFY_DONE; 58 } 59 60 static struct notifier_block lpc18xx_rgu_restart_nb = { 61 .notifier_call = lpc18xx_rgu_restart, 62 .priority = 192, 63 }; 64 65 /* 66 * The LPC18xx RGU has mostly self-deasserting resets except for the 67 * two reset lines going to the internal Cortex-M0 cores. 68 * 69 * To prevent the M0 core resets from accidentally getting deasserted 70 * status register must be check and bits in control register set to 71 * preserve the state. 72 */ 73 static int lpc18xx_rgu_setclear_reset(struct reset_controller_dev *rcdev, 74 unsigned long id, bool set) 75 { 76 struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev); 77 u32 stat_offset = LPC18XX_RGU_ACTIVE_STATUS0; 78 u32 ctrl_offset = LPC18XX_RGU_CTRL0; 79 unsigned long flags; 80 u32 stat, rst_bit; 81 82 stat_offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32); 83 ctrl_offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32); 84 rst_bit = 1 << (id % LPC18XX_RGU_RESETS_PER_REG); 85 86 spin_lock_irqsave(&rc->lock, flags); 87 stat = ~readl(rc->base + stat_offset); 88 if (set) 89 writel(stat | rst_bit, rc->base + ctrl_offset); 90 else 91 writel(stat & ~rst_bit, rc->base + ctrl_offset); 92 spin_unlock_irqrestore(&rc->lock, flags); 93 94 return 0; 95 } 96 97 static int lpc18xx_rgu_assert(struct reset_controller_dev *rcdev, 98 unsigned long id) 99 { 100 return lpc18xx_rgu_setclear_reset(rcdev, id, true); 101 } 102 103 static int lpc18xx_rgu_deassert(struct reset_controller_dev *rcdev, 104 unsigned long id) 105 { 106 return lpc18xx_rgu_setclear_reset(rcdev, id, false); 107 } 108 109 /* Only M0 cores require explicit reset deassert */ 110 static int lpc18xx_rgu_reset(struct reset_controller_dev *rcdev, 111 unsigned long id) 112 { 113 struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev); 114 115 lpc18xx_rgu_assert(rcdev, id); 116 udelay(rc->delay_us); 117 118 switch (id) { 119 case LPC43XX_RGU_M0SUB_RST: 120 case LPC43XX_RGU_M0APP_RST: 121 lpc18xx_rgu_setclear_reset(rcdev, id, false); 122 } 123 124 return 0; 125 } 126 127 static int lpc18xx_rgu_status(struct reset_controller_dev *rcdev, 128 unsigned long id) 129 { 130 struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev); 131 u32 bit, offset = LPC18XX_RGU_ACTIVE_STATUS0; 132 133 offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32); 134 bit = 1 << (id % LPC18XX_RGU_RESETS_PER_REG); 135 136 return !(readl(rc->base + offset) & bit); 137 } 138 139 static struct reset_control_ops lpc18xx_rgu_ops = { 140 .reset = lpc18xx_rgu_reset, 141 .assert = lpc18xx_rgu_assert, 142 .deassert = lpc18xx_rgu_deassert, 143 .status = lpc18xx_rgu_status, 144 }; 145 146 static int lpc18xx_rgu_probe(struct platform_device *pdev) 147 { 148 struct lpc18xx_rgu_data *rc; 149 struct resource *res; 150 u32 fcclk, firc; 151 int ret; 152 153 rc = devm_kzalloc(&pdev->dev, sizeof(*rc), GFP_KERNEL); 154 if (!rc) 155 return -ENOMEM; 156 157 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 158 rc->base = devm_ioremap_resource(&pdev->dev, res); 159 if (IS_ERR(rc->base)) 160 return PTR_ERR(rc->base); 161 162 rc->clk_reg = devm_clk_get(&pdev->dev, "reg"); 163 if (IS_ERR(rc->clk_reg)) { 164 dev_err(&pdev->dev, "reg clock not found\n"); 165 return PTR_ERR(rc->clk_reg); 166 } 167 168 rc->clk_delay = devm_clk_get(&pdev->dev, "delay"); 169 if (IS_ERR(rc->clk_delay)) { 170 dev_err(&pdev->dev, "delay clock not found\n"); 171 return PTR_ERR(rc->clk_delay); 172 } 173 174 ret = clk_prepare_enable(rc->clk_reg); 175 if (ret) { 176 dev_err(&pdev->dev, "unable to enable reg clock\n"); 177 return ret; 178 } 179 180 ret = clk_prepare_enable(rc->clk_delay); 181 if (ret) { 182 dev_err(&pdev->dev, "unable to enable delay clock\n"); 183 goto dis_clk_reg; 184 } 185 186 fcclk = clk_get_rate(rc->clk_reg) / USEC_PER_SEC; 187 firc = clk_get_rate(rc->clk_delay) / USEC_PER_SEC; 188 if (fcclk == 0 || firc == 0) 189 rc->delay_us = 2; 190 else 191 rc->delay_us = DIV_ROUND_UP(fcclk, firc * firc); 192 193 spin_lock_init(&rc->lock); 194 195 rc->rcdev.owner = THIS_MODULE; 196 rc->rcdev.nr_resets = 64; 197 rc->rcdev.ops = &lpc18xx_rgu_ops; 198 rc->rcdev.of_node = pdev->dev.of_node; 199 200 platform_set_drvdata(pdev, rc); 201 202 ret = reset_controller_register(&rc->rcdev); 203 if (ret) { 204 dev_err(&pdev->dev, "unable to register device\n"); 205 goto dis_clks; 206 } 207 208 rgu_base = rc->base; 209 ret = register_restart_handler(&lpc18xx_rgu_restart_nb); 210 if (ret) 211 dev_warn(&pdev->dev, "failed to register restart handler\n"); 212 213 return 0; 214 215 dis_clks: 216 clk_disable_unprepare(rc->clk_delay); 217 dis_clk_reg: 218 clk_disable_unprepare(rc->clk_reg); 219 220 return ret; 221 } 222 223 static int lpc18xx_rgu_remove(struct platform_device *pdev) 224 { 225 struct lpc18xx_rgu_data *rc = platform_get_drvdata(pdev); 226 int ret; 227 228 ret = unregister_restart_handler(&lpc18xx_rgu_restart_nb); 229 if (ret) 230 dev_warn(&pdev->dev, "failed to unregister restart handler\n"); 231 232 reset_controller_unregister(&rc->rcdev); 233 234 clk_disable_unprepare(rc->clk_delay); 235 clk_disable_unprepare(rc->clk_reg); 236 237 return 0; 238 } 239 240 static const struct of_device_id lpc18xx_rgu_match[] = { 241 { .compatible = "nxp,lpc1850-rgu" }, 242 { } 243 }; 244 MODULE_DEVICE_TABLE(of, lpc18xx_rgu_match); 245 246 static struct platform_driver lpc18xx_rgu_driver = { 247 .probe = lpc18xx_rgu_probe, 248 .remove = lpc18xx_rgu_remove, 249 .driver = { 250 .name = "lpc18xx-reset", 251 .of_match_table = lpc18xx_rgu_match, 252 }, 253 }; 254 module_platform_driver(lpc18xx_rgu_driver); 255 256 MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>"); 257 MODULE_DESCRIPTION("Reset driver for LPC18xx/43xx RGU"); 258 MODULE_LICENSE("GPL v2"); 259