1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * arch/arm/mach-vt8500/vt8500.c 4 * 5 * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 6 */ 7 8 #include <linux/io.h> 9 #include <linux/pm.h> 10 #include <linux/reboot.h> 11 12 #include <asm/mach-types.h> 13 #include <asm/mach/arch.h> 14 #include <asm/mach/time.h> 15 #include <asm/mach/map.h> 16 17 #include <linux/of.h> 18 #include <linux/of_address.h> 19 #include <linux/of_irq.h> 20 21 #define LEGACY_GPIO_BASE 0xD8110000 22 #define LEGACY_PMC_BASE 0xD8130000 23 24 /* Registers in GPIO Controller */ 25 #define VT8500_GPIO_MUX_REG 0x200 26 27 /* Registers in Power Management Controller */ 28 #define VT8500_HCR_REG 0x12 29 #define VT8500_PMSR_REG 0x60 30 31 static void __iomem *pmc_base; 32 33 static void vt8500_restart(enum reboot_mode mode, const char *cmd) 34 { 35 if (pmc_base) 36 writel(1, pmc_base + VT8500_PMSR_REG); 37 } 38 39 static struct map_desc vt8500_io_desc[] __initdata = { 40 /* SoC MMIO registers */ 41 [0] = { 42 .virtual = 0xf8000000, 43 .pfn = __phys_to_pfn(0xd8000000), 44 .length = 0x00390000, /* max of all chip variants */ 45 .type = MT_DEVICE 46 }, 47 }; 48 49 static void __init vt8500_map_io(void) 50 { 51 iotable_init(vt8500_io_desc, ARRAY_SIZE(vt8500_io_desc)); 52 } 53 54 static void vt8500_power_off(void) 55 { 56 local_irq_disable(); 57 writew(5, pmc_base + VT8500_HCR_REG); 58 asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (0)); 59 } 60 61 static void __init vt8500_init(void) 62 { 63 struct device_node *np; 64 #if defined(CONFIG_FB_VT8500) || defined(CONFIG_FB_WM8505) 65 struct device_node *fb; 66 void __iomem *gpio_base; 67 #endif 68 69 #ifdef CONFIG_FB_VT8500 70 fb = of_find_compatible_node(NULL, NULL, "via,vt8500-fb"); 71 if (fb) { 72 np = of_find_compatible_node(NULL, NULL, "via,vt8500-gpio"); 73 if (np) { 74 gpio_base = of_iomap(np, 0); 75 76 if (!gpio_base) 77 pr_err("%s: of_iomap(gpio_mux) failed\n", 78 __func__); 79 80 of_node_put(np); 81 } else { 82 gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000); 83 if (!gpio_base) 84 pr_err("%s: ioremap(legacy_gpio_mux) failed\n", 85 __func__); 86 } 87 if (gpio_base) { 88 writel(readl(gpio_base + VT8500_GPIO_MUX_REG) | 1, 89 gpio_base + VT8500_GPIO_MUX_REG); 90 iounmap(gpio_base); 91 } else 92 pr_err("%s: Could not remap GPIO mux\n", __func__); 93 94 of_node_put(fb); 95 } 96 #endif 97 98 #ifdef CONFIG_FB_WM8505 99 fb = of_find_compatible_node(NULL, NULL, "wm,wm8505-fb"); 100 if (fb) { 101 np = of_find_compatible_node(NULL, NULL, "wm,wm8505-gpio"); 102 if (!np) 103 np = of_find_compatible_node(NULL, NULL, 104 "wm,wm8650-gpio"); 105 if (np) { 106 gpio_base = of_iomap(np, 0); 107 108 if (!gpio_base) 109 pr_err("%s: of_iomap(gpio_mux) failed\n", 110 __func__); 111 112 of_node_put(np); 113 } else { 114 gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000); 115 if (!gpio_base) 116 pr_err("%s: ioremap(legacy_gpio_mux) failed\n", 117 __func__); 118 } 119 if (gpio_base) { 120 writel(readl(gpio_base + VT8500_GPIO_MUX_REG) | 121 0x80000000, gpio_base + VT8500_GPIO_MUX_REG); 122 iounmap(gpio_base); 123 } else 124 pr_err("%s: Could not remap GPIO mux\n", __func__); 125 126 of_node_put(fb); 127 } 128 #endif 129 130 np = of_find_compatible_node(NULL, NULL, "via,vt8500-pmc"); 131 if (np) { 132 pmc_base = of_iomap(np, 0); 133 134 if (!pmc_base) 135 pr_err("%s:of_iomap(pmc) failed\n", __func__); 136 137 of_node_put(np); 138 } else { 139 pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000); 140 if (!pmc_base) 141 pr_err("%s:ioremap(power_off) failed\n", __func__); 142 } 143 if (pmc_base) 144 pm_power_off = &vt8500_power_off; 145 else 146 pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__); 147 } 148 149 static const char * const vt8500_dt_compat[] = { 150 "via,vt8500", 151 "wm,wm8650", 152 "wm,wm8505", 153 "wm,wm8750", 154 "wm,wm8850", 155 NULL 156 }; 157 158 DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") 159 .dt_compat = vt8500_dt_compat, 160 .map_io = vt8500_map_io, 161 .init_machine = vt8500_init, 162 .restart = vt8500_restart, 163 MACHINE_END 164 165