File Index
Files and directories
Sign in
FILE

at91-reset.c

File preview with syntax highlighting.

linux-6.19.14/drivers/power/reset/at91-reset.c C
  1/*
  2 * Atmel AT91 SAM9 & SAMA5 SoCs reset code
  3 *
  4 * Copyright (C) 2007 Atmel Corporation.
  5 * Copyright (C) BitBox Ltd 2010
  6 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
  7 * Copyright (C) 2014 Free Electrons
  8 *
  9 * This file is licensed under the terms of the GNU General Public
 10 * License version 2.  This program is licensed "as is" without any
 11 * warranty of any kind, whether express or implied.
 12 */
 13
 14#include <linux/clk.h>
 15#include <linux/io.h>
 16#include <linux/module.h>
 17#include <linux/of_address.h>
 18#include <linux/platform_device.h>
 19#include <linux/reboot.h>
 20#include <linux/reset-controller.h>
 21#include <linux/power/power_on_reason.h>
 22
 23#include <soc/at91/at91sam9_ddrsdr.h>
 24#include <soc/at91/at91sam9_sdramc.h>
 25
 26#include <dt-bindings/reset/sama7g5-reset.h>
 27
 28#define AT91_RSTC_CR	0x00		/* Reset Controller Control Register */
 29#define AT91_RSTC_PROCRST	BIT(0)		/* Processor Reset */
 30#define AT91_RSTC_PERRST	BIT(2)		/* Peripheral Reset */
 31#define AT91_RSTC_EXTRST	BIT(3)		/* External Reset */
 32#define AT91_RSTC_KEY		(0xa5 << 24)	/* KEY Password */
 33
 34#define AT91_RSTC_SR	0x04		/* Reset Controller Status Register */
 35#define AT91_RSTC_URSTS		BIT(0)		/* User Reset Status */
 36#define AT91_RSTC_RSTTYP	GENMASK(10, 8)	/* Reset Type */
 37#define AT91_RSTC_NRSTL		BIT(16)		/* NRST Pin Level */
 38#define AT91_RSTC_SRCMP		BIT(17)		/* Software Reset Command in Progress */
 39
 40#define AT91_RSTC_MR	0x08		/* Reset Controller Mode Register */
 41#define AT91_RSTC_URSTEN	BIT(0)		/* User Reset Enable */
 42#define AT91_RSTC_URSTASYNC	BIT(2)		/* User Reset Asynchronous Control */
 43#define AT91_RSTC_URSTIEN	BIT(4)		/* User Reset Interrupt Enable */
 44#define AT91_RSTC_ERSTL		GENMASK(11, 8)	/* External Reset Length */
 45
 46/**
 47 * enum reset_type - reset types
 48 * @RESET_TYPE_GENERAL:		first power-up reset
 49 * @RESET_TYPE_WAKEUP:		return from backup mode
 50 * @RESET_TYPE_WATCHDOG:	watchdog fault
 51 * @RESET_TYPE_SOFTWARE:	processor reset required by software
 52 * @RESET_TYPE_USER:		NRST pin detected low
 53 * @RESET_TYPE_CPU_FAIL:	CPU clock failure detection
 54 * @RESET_TYPE_XTAL_FAIL:	32KHz crystal failure dectection fault
 55 * @RESET_TYPE_ULP2:		ULP2 reset
 56 */
 57enum reset_type {
 58	RESET_TYPE_GENERAL	= 0,
 59	RESET_TYPE_WAKEUP	= 1,
 60	RESET_TYPE_WATCHDOG	= 2,
 61	RESET_TYPE_SOFTWARE	= 3,
 62	RESET_TYPE_USER		= 4,
 63	RESET_TYPE_CPU_FAIL	= 6,
 64	RESET_TYPE_XTAL_FAIL	= 7,
 65	RESET_TYPE_ULP2		= 8,
 66};
 67
 68/**
 69 * struct at91_reset - AT91 reset specific data structure
 70 * @rstc_base:		base address for system reset
 71 * @ramc_base:		array with base addresses of RAM controllers
 72 * @dev_base:		base address for devices reset
 73 * @sclk:		slow clock
 74 * @data:		platform specific reset data
 75 * @rcdev:		reset controller device
 76 * @lock:		lock for devices reset register access
 77 * @nb:			reset notifier block
 78 * @args:		SoC specific system reset arguments
 79 * @ramc_lpr:		SDRAM Controller Low Power Register
 80 */
 81struct at91_reset {
 82	void __iomem *rstc_base;
 83	void __iomem *ramc_base[2];
 84	void __iomem *dev_base;
 85	struct clk *sclk;
 86	const struct at91_reset_data *data;
 87	struct reset_controller_dev rcdev;
 88	spinlock_t lock;
 89	struct notifier_block nb;
 90	u32 args;
 91	u32 ramc_lpr;
 92};
 93
 94#define to_at91_reset(r)	container_of(r, struct at91_reset, rcdev)
 95
 96/**
 97 * struct at91_reset_data - AT91 reset data
 98 * @reset_args:			SoC specific system reset arguments
 99 * @n_device_reset:		number of device resets
100 * @device_reset_min_id:	min id for device reset
101 * @device_reset_max_id:	max id for device reset
102 */
103struct at91_reset_data {
104	u32 reset_args;
105	u32 n_device_reset;
106	u8 device_reset_min_id;
107	u8 device_reset_max_id;
108};
109
110/*
111* unless the SDRAM is cleanly shutdown before we hit the
112* reset register it can be left driving the data bus and
113* killing the chance of a subsequent boot from NAND
114*/
115static int at91_reset(struct notifier_block *this, unsigned long mode,
116		      void *cmd)
117{
118	struct at91_reset *reset = container_of(this, struct at91_reset, nb);
119
120	asm volatile(
121		/* Align to cache lines */
122		".balign 32\n\t"
123
124		/* Disable SDRAM0 accesses */
125		"	tst	%0, #0\n\t"
126		"	beq	1f\n\t"
127		"	str	%3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
128		/* Power down SDRAM0 */
129		"	str	%4, [%0, %6]\n\t"
130		/* Disable SDRAM1 accesses */
131		"1:	tst	%1, #0\n\t"
132		"	strne	%3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
133		/* Power down SDRAM1 */
134		"	strne	%4, [%1, %6]\n\t"
135		/* Reset CPU */
136		"	str	%5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
137
138		"	b	.\n\t"
139		:
140		: "r" (reset->ramc_base[0]),
141		  "r" (reset->ramc_base[1]),
142		  "r" (reset->rstc_base),
143		  "r" (1),
144		  "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN),
145		  "r" (reset->data->reset_args),
146		  "r" (reset->ramc_lpr)
147	);
148
149	return NOTIFY_DONE;
150}
151
152static const char *at91_reset_reason(struct at91_reset *reset)
153{
154	u32 reg = readl(reset->rstc_base + AT91_RSTC_SR);
155	const char *reason;
156
157	switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
158	case RESET_TYPE_GENERAL:
159		reason = POWER_ON_REASON_REGULAR;
160		break;
161	case RESET_TYPE_WAKEUP:
162		reason = POWER_ON_REASON_RTC;
163		break;
164	case RESET_TYPE_WATCHDOG:
165		reason = POWER_ON_REASON_WATCHDOG;
166		break;
167	case RESET_TYPE_SOFTWARE:
168		reason = POWER_ON_REASON_SOFTWARE;
169		break;
170	case RESET_TYPE_USER:
171		reason = POWER_ON_REASON_RST_BTN;
172		break;
173	case RESET_TYPE_CPU_FAIL:
174		reason = POWER_ON_REASON_CPU_CLK_FAIL;
175		break;
176	case RESET_TYPE_XTAL_FAIL:
177		reason = POWER_ON_REASON_XTAL_FAIL;
178		break;
179	case RESET_TYPE_ULP2:
180		reason = POWER_ON_REASON_BROWN_OUT;
181		break;
182	default:
183		reason = POWER_ON_REASON_UNKNOWN;
184		break;
185	}
186
187	return reason;
188}
189
190static ssize_t power_on_reason_show(struct device *dev,
191				    struct device_attribute *attr, char *buf)
192{
193	struct platform_device *pdev = to_platform_device(dev);
194	struct at91_reset *reset = platform_get_drvdata(pdev);
195
196	return sprintf(buf, "%s\n", at91_reset_reason(reset));
197}
198static DEVICE_ATTR_RO(power_on_reason);
199
200static const struct of_device_id at91_ramc_of_match[] = {
201	{
202		.compatible = "atmel,at91sam9260-sdramc",
203		.data = (void *)AT91_SDRAMC_LPR,
204	},
205	{
206		.compatible = "atmel,at91sam9g45-ddramc",
207		.data = (void *)AT91_DDRSDRC_LPR,
208	},
209	{ /* sentinel */ }
210};
211
212static const struct at91_reset_data sam9260 = {
213	.reset_args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST,
214};
215
216static const struct at91_reset_data samx7 = {
217	.reset_args = AT91_RSTC_KEY | AT91_RSTC_PROCRST,
218};
219
220static const struct at91_reset_data sama7g5 = {
221	.reset_args = AT91_RSTC_KEY | AT91_RSTC_PROCRST,
222	.n_device_reset = 3,
223	.device_reset_min_id = SAMA7G5_RESET_USB_PHY1,
224	.device_reset_max_id = SAMA7G5_RESET_USB_PHY3,
225};
226
227static const struct of_device_id at91_reset_of_match[] = {
228	{
229		.compatible = "atmel,at91sam9260-rstc",
230		.data = &sam9260,
231	},
232	{
233		.compatible = "atmel,at91sam9g45-rstc",
234		.data = &sam9260,
235	},
236	{
237		.compatible = "atmel,sama5d3-rstc",
238		.data = &sam9260,
239	},
240	{
241		.compatible = "atmel,samx7-rstc",
242		.data = &samx7,
243	},
244	{
245		.compatible = "microchip,sam9x60-rstc",
246		.data = &samx7,
247	},
248	{
249		.compatible = "microchip,sama7g5-rstc",
250		.data = &sama7g5,
251	},
252	{ /* sentinel */ }
253};
254MODULE_DEVICE_TABLE(of, at91_reset_of_match);
255
256static int at91_reset_update(struct reset_controller_dev *rcdev,
257			     unsigned long id, bool assert)
258{
259	struct at91_reset *reset = to_at91_reset(rcdev);
260	unsigned long flags;
261	u32 val;
262
263	spin_lock_irqsave(&reset->lock, flags);
264	val = readl_relaxed(reset->dev_base);
265	if (assert)
266		val |= BIT(id);
267	else
268		val &= ~BIT(id);
269	writel_relaxed(val, reset->dev_base);
270	spin_unlock_irqrestore(&reset->lock, flags);
271
272	return 0;
273}
274
275static int at91_reset_assert(struct reset_controller_dev *rcdev,
276			     unsigned long id)
277{
278	return at91_reset_update(rcdev, id, true);
279}
280
281static int at91_reset_deassert(struct reset_controller_dev *rcdev,
282			       unsigned long id)
283{
284	return at91_reset_update(rcdev, id, false);
285}
286
287static int at91_reset_dev_status(struct reset_controller_dev *rcdev,
288				 unsigned long id)
289{
290	struct at91_reset *reset = to_at91_reset(rcdev);
291	u32 val;
292
293	val = readl_relaxed(reset->dev_base);
294
295	return !!(val & BIT(id));
296}
297
298static const struct reset_control_ops at91_reset_ops = {
299	.assert = at91_reset_assert,
300	.deassert = at91_reset_deassert,
301	.status = at91_reset_dev_status,
302};
303
304static int at91_reset_of_xlate(struct reset_controller_dev *rcdev,
305			       const struct of_phandle_args *reset_spec)
306{
307	struct at91_reset *reset = to_at91_reset(rcdev);
308
309	if (!reset->data->n_device_reset ||
310	    (reset_spec->args[0] < reset->data->device_reset_min_id ||
311	     reset_spec->args[0] > reset->data->device_reset_max_id))
312		return -EINVAL;
313
314	return reset_spec->args[0];
315}
316
317static int at91_rcdev_init(struct at91_reset *reset,
318			   struct platform_device *pdev)
319{
320	if (!reset->data->n_device_reset)
321		return 0;
322
323	reset->dev_base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 1,
324					NULL);
325	if (IS_ERR(reset->dev_base))
326		return -ENODEV;
327
328	spin_lock_init(&reset->lock);
329	reset->rcdev.ops = &at91_reset_ops;
330	reset->rcdev.owner = THIS_MODULE;
331	reset->rcdev.of_node = pdev->dev.of_node;
332	reset->rcdev.nr_resets = reset->data->n_device_reset;
333	reset->rcdev.of_reset_n_cells = 1;
334	reset->rcdev.of_xlate = at91_reset_of_xlate;
335
336	return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
337}
338
339static int at91_reset_probe(struct platform_device *pdev)
340{
341	const struct of_device_id *match;
342	struct at91_reset *reset;
343	struct device_node *np;
344	int ret, idx = 0;
345
346	reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
347	if (!reset)
348		return -ENOMEM;
349
350	reset->rstc_base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
351	if (IS_ERR(reset->rstc_base)) {
352		dev_err(&pdev->dev, "Could not map reset controller address\n");
353		return -ENODEV;
354	}
355
356	if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) {
357		/* we need to shutdown the ddr controller, so get ramc base */
358		for_each_matching_node_and_match(np, at91_ramc_of_match, &match) {
359			reset->ramc_lpr = (u32)match->data;
360			reset->ramc_base[idx] = devm_of_iomap(&pdev->dev, np, 0, NULL);
361			if (IS_ERR(reset->ramc_base[idx])) {
362				dev_err(&pdev->dev, "Could not map ram controller address\n");
363				of_node_put(np);
364				return -ENODEV;
365			}
366			idx++;
367		}
368	}
369
370	reset->data = device_get_match_data(&pdev->dev);
371	if (!reset->data)
372		return -ENODEV;
373
374	reset->nb.notifier_call = at91_reset;
375	reset->nb.priority = 192;
376
377	reset->sclk = devm_clk_get(&pdev->dev, NULL);
378	if (IS_ERR(reset->sclk))
379		return PTR_ERR(reset->sclk);
380
381	ret = clk_prepare_enable(reset->sclk);
382	if (ret) {
383		dev_err(&pdev->dev, "Could not enable slow clock\n");
384		return ret;
385	}
386
387	platform_set_drvdata(pdev, reset);
388
389	ret = at91_rcdev_init(reset, pdev);
390	if (ret)
391		goto disable_clk;
392
393	if (of_device_is_compatible(pdev->dev.of_node, "microchip,sam9x60-rstc")) {
394		u32 val = readl(reset->rstc_base + AT91_RSTC_MR);
395
396		writel(AT91_RSTC_KEY | AT91_RSTC_URSTASYNC | val,
397		       reset->rstc_base + AT91_RSTC_MR);
398	}
399
400	ret = register_restart_handler(&reset->nb);
401	if (ret)
402		goto disable_clk;
403
404	ret = device_create_file(&pdev->dev, &dev_attr_power_on_reason);
405	if (ret) {
406		dev_err(&pdev->dev, "Could not create sysfs entry\n");
407		return ret;
408	}
409
410	dev_info(&pdev->dev, "Starting after %s\n", at91_reset_reason(reset));
411
412	return 0;
413
414disable_clk:
415	clk_disable_unprepare(reset->sclk);
416	return ret;
417}
418
419static void at91_reset_remove(struct platform_device *pdev)
420{
421	struct at91_reset *reset = platform_get_drvdata(pdev);
422
423	unregister_restart_handler(&reset->nb);
424	clk_disable_unprepare(reset->sclk);
425}
426
427static struct platform_driver at91_reset_driver = {
428	.probe = at91_reset_probe,
429	.remove = at91_reset_remove,
430	.driver = {
431		.name = "at91-reset",
432		.of_match_table = at91_reset_of_match,
433	},
434};
435module_platform_driver(at91_reset_driver);
436
437MODULE_AUTHOR("Atmel Corporation");
438MODULE_DESCRIPTION("Reset driver for Atmel SoCs");
439MODULE_LICENSE("GPL v2");
~/ Read-only file preview.