vt8500.c (3772B)
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 31static void __iomem *pmc_base; 32 33static 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 39static 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 49static void __init vt8500_map_io(void) 50{ 51 iotable_init(vt8500_io_desc, ARRAY_SIZE(vt8500_io_desc)); 52} 53 54static 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 61static 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 149static 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 158DT_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, 163MACHINE_END 164