• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Copyright (c) 2011 Picochip Ltd., Jamie Iles
4   *
5   * All enquiries to support@picochip.com
6   */
7  #include <linux/delay.h>
8  #include <linux/of.h>
9  #include <linux/of_address.h>
10  #include <linux/reboot.h>
11  
12  #include <asm/mach/arch.h>
13  #include <asm/mach/map.h>
14  
15  #define PHYS_TO_IO(x)			(((x) & 0x00ffffff) | 0xfe000000)
16  #define PICOXCELL_PERIPH_BASE		0x80000000
17  #define PICOXCELL_PERIPH_LENGTH		SZ_4M
18  
19  #define WDT_CTRL_REG_EN_MASK		(1 << 0)
20  #define WDT_CTRL_REG_OFFS		(0x00)
21  #define WDT_TIMEOUT_REG_OFFS		(0x04)
22  static void __iomem *wdt_regs;
23  
24  /*
25   * The machine restart method can be called from an atomic context so we won't
26   * be able to ioremap the regs then.
27   */
picoxcell_setup_restart(void)28  static void picoxcell_setup_restart(void)
29  {
30  	struct device_node *np = of_find_compatible_node(NULL, NULL,
31  							 "snps,dw-apb-wdg");
32  	if (WARN(!np, "unable to setup watchdog restart"))
33  		return;
34  
35  	wdt_regs = of_iomap(np, 0);
36  	WARN(!wdt_regs, "failed to remap watchdog regs");
37  }
38  
39  static struct map_desc io_map __initdata = {
40  	.virtual	= PHYS_TO_IO(PICOXCELL_PERIPH_BASE),
41  	.pfn		= __phys_to_pfn(PICOXCELL_PERIPH_BASE),
42  	.length		= PICOXCELL_PERIPH_LENGTH,
43  	.type		= MT_DEVICE,
44  };
45  
picoxcell_map_io(void)46  static void __init picoxcell_map_io(void)
47  {
48  	iotable_init(&io_map, 1);
49  }
50  
picoxcell_init_machine(void)51  static void __init picoxcell_init_machine(void)
52  {
53  	picoxcell_setup_restart();
54  }
55  
56  static const char *picoxcell_dt_match[] = {
57  	"picochip,pc3x2",
58  	"picochip,pc3x3",
59  	NULL
60  };
61  
picoxcell_wdt_restart(enum reboot_mode mode,const char * cmd)62  static void picoxcell_wdt_restart(enum reboot_mode mode, const char *cmd)
63  {
64  	/*
65  	 * Configure the watchdog to reset with the shortest possible timeout
66  	 * and give it chance to do the reset.
67  	 */
68  	if (wdt_regs) {
69  		writel_relaxed(WDT_CTRL_REG_EN_MASK, wdt_regs + WDT_CTRL_REG_OFFS);
70  		writel_relaxed(0, wdt_regs + WDT_TIMEOUT_REG_OFFS);
71  		/* No sleeping, possibly atomic. */
72  		mdelay(500);
73  	}
74  }
75  
76  DT_MACHINE_START(PICOXCELL, "Picochip picoXcell")
77  	.map_io		= picoxcell_map_io,
78  	.init_machine	= picoxcell_init_machine,
79  	.dt_compat	= picoxcell_dt_match,
80  	.restart	= picoxcell_wdt_restart,
81  MACHINE_END
82