linux/arch/arm/mach-vt8500/vt8500.c
<<
>>
Prefs
   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
 165