1af75655c066621352c419646ec0775e9523dc720Jamie Iles/* 2af75655c066621352c419646ec0775e9523dc720Jamie Iles * Copyright (c) 2011 Picochip Ltd., Jamie Iles 3af75655c066621352c419646ec0775e9523dc720Jamie Iles * 4af75655c066621352c419646ec0775e9523dc720Jamie Iles * This program is free software; you can redistribute it and/or modify 5af75655c066621352c419646ec0775e9523dc720Jamie Iles * it under the terms of the GNU General Public License version 2 as 6af75655c066621352c419646ec0775e9523dc720Jamie Iles * published by the Free Software Foundation. 7af75655c066621352c419646ec0775e9523dc720Jamie Iles * 8af75655c066621352c419646ec0775e9523dc720Jamie Iles * All enquiries to support@picochip.com 9af75655c066621352c419646ec0775e9523dc720Jamie Iles */ 101b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles#include <linux/delay.h> 11af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <linux/irq.h> 12af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <linux/irqdomain.h> 13af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <linux/of.h> 14af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <linux/of_address.h> 15c05012ce9a70100dd547042865df751498244ec3Jamie Iles#include <linux/of_irq.h> 16af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <linux/of_platform.h> 17af75655c066621352c419646ec0775e9523dc720Jamie Iles 18af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <asm/mach/arch.h> 19af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <asm/hardware/vic.h> 208f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles#include <asm/mach/map.h> 21af75655c066621352c419646ec0775e9523dc720Jamie Iles 22af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <mach/map.h> 23af75655c066621352c419646ec0775e9523dc720Jamie Iles#include <mach/picoxcell_soc.h> 24af75655c066621352c419646ec0775e9523dc720Jamie Iles 25af75655c066621352c419646ec0775e9523dc720Jamie Iles#include "common.h" 26af75655c066621352c419646ec0775e9523dc720Jamie Iles 271b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles#define WDT_CTRL_REG_EN_MASK (1 << 0) 281b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles#define WDT_CTRL_REG_OFFS (0x00) 291b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles#define WDT_TIMEOUT_REG_OFFS (0x04) 301b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Ilesstatic void __iomem *wdt_regs; 311b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles 321b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles/* 331b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles * The machine restart method can be called from an atomic context so we won't 341b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles * be able to ioremap the regs then. 351b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles */ 361b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Ilesstatic void picoxcell_setup_restart(void) 371b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles{ 381b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles struct device_node *np = of_find_compatible_node(NULL, NULL, 391b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles "snps,dw-apb-wdg"); 401b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles if (WARN(!np, "unable to setup watchdog restart")) 411b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles return; 421b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles 431b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles wdt_regs = of_iomap(np, 0); 441b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles WARN(!wdt_regs, "failed to remap watchdog regs"); 451b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles} 461b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles 478f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Ilesstatic struct map_desc io_map __initdata = { 488f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE), 498f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE), 508f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles .length = PICOXCELL_PERIPH_LENGTH, 518f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles .type = MT_DEVICE, 528f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles}; 538f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles 548f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Ilesstatic void __init picoxcell_map_io(void) 558f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles{ 568f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles iotable_init(&io_map, 1); 578f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles} 588f37a0b49656ed961598351da3ebdd89f2d2e5b4Jamie Iles 59af75655c066621352c419646ec0775e9523dc720Jamie Ilesstatic void __init picoxcell_init_machine(void) 60af75655c066621352c419646ec0775e9523dc720Jamie Iles{ 61af75655c066621352c419646ec0775e9523dc720Jamie Iles of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 621b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles picoxcell_setup_restart(); 63af75655c066621352c419646ec0775e9523dc720Jamie Iles} 64af75655c066621352c419646ec0775e9523dc720Jamie Iles 65af75655c066621352c419646ec0775e9523dc720Jamie Ilesstatic const char *picoxcell_dt_match[] = { 66af75655c066621352c419646ec0775e9523dc720Jamie Iles "picochip,pc3x2", 67af75655c066621352c419646ec0775e9523dc720Jamie Iles "picochip,pc3x3", 68af75655c066621352c419646ec0775e9523dc720Jamie Iles NULL 69af75655c066621352c419646ec0775e9523dc720Jamie Iles}; 70af75655c066621352c419646ec0775e9523dc720Jamie Iles 71af75655c066621352c419646ec0775e9523dc720Jamie Ilesstatic const struct of_device_id vic_of_match[] __initconst = { 72c05012ce9a70100dd547042865df751498244ec3Jamie Iles { .compatible = "arm,pl192-vic", .data = vic_of_init, }, 73af75655c066621352c419646ec0775e9523dc720Jamie Iles { /* Sentinel */ } 74af75655c066621352c419646ec0775e9523dc720Jamie Iles}; 75af75655c066621352c419646ec0775e9523dc720Jamie Iles 76af75655c066621352c419646ec0775e9523dc720Jamie Ilesstatic void __init picoxcell_init_irq(void) 77af75655c066621352c419646ec0775e9523dc720Jamie Iles{ 78c05012ce9a70100dd547042865df751498244ec3Jamie Iles of_irq_init(vic_of_match); 79af75655c066621352c419646ec0775e9523dc720Jamie Iles} 80af75655c066621352c419646ec0775e9523dc720Jamie Iles 811b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Ilesstatic void picoxcell_wdt_restart(char mode, const char *cmd) 821b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles{ 831b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles /* 841b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles * Configure the watchdog to reset with the shortest possible timeout 851b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles * and give it chance to do the reset. 861b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles */ 871b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles if (wdt_regs) { 881b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles writel_relaxed(WDT_CTRL_REG_EN_MASK, wdt_regs + WDT_CTRL_REG_OFFS); 891b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles writel_relaxed(0, wdt_regs + WDT_TIMEOUT_REG_OFFS); 901b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles /* No sleeping, possibly atomic. */ 911b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles mdelay(500); 921b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles } 931b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles} 941b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles 95af75655c066621352c419646ec0775e9523dc720Jamie IlesDT_MACHINE_START(PICOXCELL, "Picochip picoXcell") 96af75655c066621352c419646ec0775e9523dc720Jamie Iles .map_io = picoxcell_map_io, 9798e27a5c13badb5c56d9d1d6c8ec210753ac1195Jamie Iles .nr_irqs = NR_IRQS_LEGACY, 98af75655c066621352c419646ec0775e9523dc720Jamie Iles .init_irq = picoxcell_init_irq, 99c05012ce9a70100dd547042865df751498244ec3Jamie Iles .handle_irq = vic_handle_irq, 100af75655c066621352c419646ec0775e9523dc720Jamie Iles .timer = &picoxcell_timer, 101af75655c066621352c419646ec0775e9523dc720Jamie Iles .init_machine = picoxcell_init_machine, 102af75655c066621352c419646ec0775e9523dc720Jamie Iles .dt_compat = picoxcell_dt_match, 1031b46f8782c2607afa1298b0c7f7fe307fc0f7a5bJamie Iles .restart = picoxcell_wdt_restart, 104af75655c066621352c419646ec0775e9523dc720Jamie IlesMACHINE_END 105