root/arch/arm/mach-versatile/versatile_dt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mmc_status
  2. versatile_map_io
  3. versatile_init_early
  4. versatile_dt_pci_init
  5. versatile_dt_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Versatile board support using the device tree
   4  *
   5  *  Copyright (C) 2010 Secret Lab Technologies Ltd.
   6  *  Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com>
   7  *  Copyright (C) 2004 ARM Limited
   8  *  Copyright (C) 2000 Deep Blue Solutions Ltd
   9  */
  10 
  11 #include <linux/init.h>
  12 #include <linux/io.h>
  13 #include <linux/of.h>
  14 #include <linux/of_address.h>
  15 #include <linux/of_irq.h>
  16 #include <linux/of_platform.h>
  17 #include <linux/slab.h>
  18 #include <linux/amba/bus.h>
  19 #include <linux/amba/mmci.h>
  20 #include <asm/mach-types.h>
  21 #include <asm/mach/arch.h>
  22 #include <asm/mach/map.h>
  23 
  24 /* macro to get at MMIO space when running virtually */
  25 #define IO_ADDRESS(x)           (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
  26 #define __io_address(n)         ((void __iomem __force *)IO_ADDRESS(n))
  27 
  28 /*
  29  * ------------------------------------------------------------------------
  30  *  Versatile Registers
  31  * ------------------------------------------------------------------------
  32  */
  33 #define VERSATILE_SYS_PCICTL_OFFSET           0x44
  34 #define VERSATILE_SYS_MCI_OFFSET              0x48
  35 
  36 /*
  37  * VERSATILE peripheral addresses
  38  */
  39 #define VERSATILE_MMCI0_BASE           0x10005000       /* MMC interface */
  40 #define VERSATILE_MMCI1_BASE           0x1000B000       /* MMC Interface */
  41 #define VERSATILE_SCTL_BASE            0x101E0000       /* System controller */
  42 #define VERSATILE_IB2_BASE             0x24000000       /* IB2 module */
  43 #define VERSATILE_IB2_CTL_BASE          (VERSATILE_IB2_BASE + 0x03000000)
  44 
  45 /*
  46  * System controller bit assignment
  47  */
  48 #define VERSATILE_REFCLK        0
  49 #define VERSATILE_TIMCLK        1
  50 
  51 #define VERSATILE_TIMER1_EnSel  15
  52 #define VERSATILE_TIMER2_EnSel  17
  53 #define VERSATILE_TIMER3_EnSel  19
  54 #define VERSATILE_TIMER4_EnSel  21
  55 
  56 static void __iomem *versatile_sys_base;
  57 static void __iomem *versatile_ib2_ctrl;
  58 
  59 unsigned int mmc_status(struct device *dev)
  60 {
  61         struct amba_device *adev = container_of(dev, struct amba_device, dev);
  62         u32 mask;
  63 
  64         if (adev->res.start == VERSATILE_MMCI0_BASE)
  65                 mask = 1;
  66         else
  67                 mask = 2;
  68 
  69         return readl(versatile_sys_base + VERSATILE_SYS_MCI_OFFSET) & mask;
  70 }
  71 
  72 static struct mmci_platform_data mmc0_plat_data = {
  73         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
  74         .status         = mmc_status,
  75 };
  76 
  77 static struct mmci_platform_data mmc1_plat_data = {
  78         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
  79         .status         = mmc_status,
  80 };
  81 
  82 /*
  83  * Lookup table for attaching a specific name and platform_data pointer to
  84  * devices as they get created by of_platform_populate().  Ideally this table
  85  * would not exist, but the current clock implementation depends on some devices
  86  * having a specific name.
  87  */
  88 struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
  89         OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data),
  90         OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", &mmc1_plat_data),
  91         {}
  92 };
  93 
  94 static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
  95         {
  96                 .virtual        =  IO_ADDRESS(VERSATILE_SCTL_BASE),
  97                 .pfn            = __phys_to_pfn(VERSATILE_SCTL_BASE),
  98                 .length         = SZ_4K * 9,
  99                 .type           = MT_DEVICE
 100         }
 101 };
 102 
 103 static void __init versatile_map_io(void)
 104 {
 105         debug_ll_io_init();
 106         iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
 107 }
 108 
 109 static void __init versatile_init_early(void)
 110 {
 111         u32 val;
 112 
 113         /*
 114          * set clock frequency:
 115          *      VERSATILE_REFCLK is 32KHz
 116          *      VERSATILE_TIMCLK is 1MHz
 117          */
 118         val = readl(__io_address(VERSATILE_SCTL_BASE));
 119         writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
 120                (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
 121                (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
 122                (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
 123                __io_address(VERSATILE_SCTL_BASE));
 124 }
 125 
 126 static void __init versatile_dt_pci_init(void)
 127 {
 128         u32 val;
 129         struct device_node *np;
 130         struct property *newprop;
 131 
 132         np = of_find_compatible_node(NULL, NULL, "arm,versatile-pci");
 133         if (!np)
 134                 return;
 135 
 136         /* Check if PCI backplane is detected */
 137         val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
 138         if (val & 1) {
 139                 /*
 140                  * Enable PCI accesses. Note that the documentaton is
 141                  * inconsistent whether or not this is needed, but the old
 142                  * driver had it so we will keep it.
 143                  */
 144                 writel(1, versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
 145                 goto out_put_node;
 146         }
 147 
 148         newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
 149         if (!newprop)
 150                 goto out_put_node;
 151 
 152         newprop->name = kstrdup("status", GFP_KERNEL);
 153         newprop->value = kstrdup("disabled", GFP_KERNEL);
 154         newprop->length = sizeof("disabled");
 155         of_update_property(np, newprop);
 156 
 157         pr_info("Not plugged into PCI backplane!\n");
 158 
 159 out_put_node:
 160         of_node_put(np);
 161 }
 162 
 163 static void __init versatile_dt_init(void)
 164 {
 165         struct device_node *np;
 166 
 167         np = of_find_compatible_node(NULL, NULL, "arm,core-module-versatile");
 168         if (np)
 169                 versatile_sys_base = of_iomap(np, 0);
 170         WARN_ON(!versatile_sys_base);
 171 
 172         versatile_ib2_ctrl = ioremap(VERSATILE_IB2_CTL_BASE, SZ_4K);
 173 
 174         versatile_dt_pci_init();
 175 
 176         of_platform_default_populate(NULL, versatile_auxdata_lookup, NULL);
 177 }
 178 
 179 static const char *const versatile_dt_match[] __initconst = {
 180         "arm,versatile-ab",
 181         "arm,versatile-pb",
 182         NULL,
 183 };
 184 
 185 DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
 186         .map_io         = versatile_map_io,
 187         .init_early     = versatile_init_early,
 188         .init_machine   = versatile_dt_init,
 189         .dt_compat      = versatile_dt_match,
 190 MACHINE_END

/* [<][>][^][v][top][bottom][index][help] */