root/arch/arm/mach-zynq/common.c

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

DEFINITIONS

This source file includes following definitions.
  1. zynq_memory_init
  2. zynq_get_revision
  3. zynq_init_late
  4. zynq_init_machine
  5. zynq_timer_init
  6. zynq_scu_map_io
  7. zynq_map_io
  8. zynq_irq_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * This file contains common code that is intended to be used across
   4  * boards so that it's not replicated.
   5  *
   6  *  Copyright (C) 2011 Xilinx
   7  */
   8 
   9 #include <linux/init.h>
  10 #include <linux/io.h>
  11 #include <linux/kernel.h>
  12 #include <linux/cpumask.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/clk.h>
  15 #include <linux/clk-provider.h>
  16 #include <linux/clk/zynq.h>
  17 #include <linux/clocksource.h>
  18 #include <linux/of_address.h>
  19 #include <linux/of_irq.h>
  20 #include <linux/of_platform.h>
  21 #include <linux/of.h>
  22 #include <linux/memblock.h>
  23 #include <linux/irqchip.h>
  24 #include <linux/irqchip/arm-gic.h>
  25 #include <linux/slab.h>
  26 #include <linux/sys_soc.h>
  27 
  28 #include <asm/mach/arch.h>
  29 #include <asm/mach/map.h>
  30 #include <asm/mach/time.h>
  31 #include <asm/mach-types.h>
  32 #include <asm/page.h>
  33 #include <asm/pgtable.h>
  34 #include <asm/smp_scu.h>
  35 #include <asm/system_info.h>
  36 #include <asm/hardware/cache-l2x0.h>
  37 
  38 #include "common.h"
  39 
  40 #define ZYNQ_DEVCFG_MCTRL               0x80
  41 #define ZYNQ_DEVCFG_PS_VERSION_SHIFT    28
  42 #define ZYNQ_DEVCFG_PS_VERSION_MASK     0xF
  43 
  44 void __iomem *zynq_scu_base;
  45 
  46 /**
  47  * zynq_memory_init - Initialize special memory
  48  *
  49  * We need to stop things allocating the low memory as DMA can't work in
  50  * the 1st 512K of memory.
  51  */
  52 static void __init zynq_memory_init(void)
  53 {
  54         if (!__pa(PAGE_OFFSET))
  55                 memblock_reserve(__pa(PAGE_OFFSET), 0x80000);
  56 }
  57 
  58 static struct platform_device zynq_cpuidle_device = {
  59         .name = "cpuidle-zynq",
  60 };
  61 
  62 /**
  63  * zynq_get_revision - Get Zynq silicon revision
  64  *
  65  * Return: Silicon version or -1 otherwise
  66  */
  67 static int __init zynq_get_revision(void)
  68 {
  69         struct device_node *np;
  70         void __iomem *zynq_devcfg_base;
  71         u32 revision;
  72 
  73         np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-devcfg-1.0");
  74         if (!np) {
  75                 pr_err("%s: no devcfg node found\n", __func__);
  76                 return -1;
  77         }
  78 
  79         zynq_devcfg_base = of_iomap(np, 0);
  80         if (!zynq_devcfg_base) {
  81                 pr_err("%s: Unable to map I/O memory\n", __func__);
  82                 return -1;
  83         }
  84 
  85         revision = readl(zynq_devcfg_base + ZYNQ_DEVCFG_MCTRL);
  86         revision >>= ZYNQ_DEVCFG_PS_VERSION_SHIFT;
  87         revision &= ZYNQ_DEVCFG_PS_VERSION_MASK;
  88 
  89         iounmap(zynq_devcfg_base);
  90 
  91         return revision;
  92 }
  93 
  94 static void __init zynq_init_late(void)
  95 {
  96         zynq_core_pm_init();
  97         zynq_pm_late_init();
  98 }
  99 
 100 /**
 101  * zynq_init_machine - System specific initialization, intended to be
 102  *                     called from board specific initialization.
 103  */
 104 static void __init zynq_init_machine(void)
 105 {
 106         struct soc_device_attribute *soc_dev_attr;
 107         struct soc_device *soc_dev;
 108         struct device *parent = NULL;
 109 
 110         soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 111         if (!soc_dev_attr)
 112                 goto out;
 113 
 114         system_rev = zynq_get_revision();
 115 
 116         soc_dev_attr->family = kasprintf(GFP_KERNEL, "Xilinx Zynq");
 117         soc_dev_attr->revision = kasprintf(GFP_KERNEL, "0x%x", system_rev);
 118         soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x",
 119                                          zynq_slcr_get_device_id());
 120 
 121         soc_dev = soc_device_register(soc_dev_attr);
 122         if (IS_ERR(soc_dev)) {
 123                 kfree(soc_dev_attr->family);
 124                 kfree(soc_dev_attr->revision);
 125                 kfree(soc_dev_attr->soc_id);
 126                 kfree(soc_dev_attr);
 127                 goto out;
 128         }
 129 
 130         parent = soc_device_to_device(soc_dev);
 131 
 132 out:
 133         /*
 134          * Finished with the static registrations now; fill in the missing
 135          * devices
 136          */
 137         of_platform_default_populate(NULL, NULL, parent);
 138 
 139         platform_device_register(&zynq_cpuidle_device);
 140 }
 141 
 142 static void __init zynq_timer_init(void)
 143 {
 144         zynq_clock_init();
 145         of_clk_init(NULL);
 146         timer_probe();
 147 }
 148 
 149 static struct map_desc zynq_cortex_a9_scu_map __initdata = {
 150         .length = SZ_256,
 151         .type   = MT_DEVICE,
 152 };
 153 
 154 static void __init zynq_scu_map_io(void)
 155 {
 156         unsigned long base;
 157 
 158         base = scu_a9_get_base();
 159         zynq_cortex_a9_scu_map.pfn = __phys_to_pfn(base);
 160         /* Expected address is in vmalloc area that's why simple assign here */
 161         zynq_cortex_a9_scu_map.virtual = base;
 162         iotable_init(&zynq_cortex_a9_scu_map, 1);
 163         zynq_scu_base = (void __iomem *)base;
 164         BUG_ON(!zynq_scu_base);
 165 }
 166 
 167 /**
 168  * zynq_map_io - Create memory mappings needed for early I/O.
 169  */
 170 static void __init zynq_map_io(void)
 171 {
 172         debug_ll_io_init();
 173         zynq_scu_map_io();
 174 }
 175 
 176 static void __init zynq_irq_init(void)
 177 {
 178         zynq_early_slcr_init();
 179         irqchip_init();
 180 }
 181 
 182 static const char * const zynq_dt_match[] = {
 183         "xlnx,zynq-7000",
 184         NULL
 185 };
 186 
 187 DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
 188         /* 64KB way size, 8-way associativity, parity disabled */
 189         .l2c_aux_val    = 0x00400000,
 190         .l2c_aux_mask   = 0xffbfffff,
 191         .smp            = smp_ops(zynq_smp_ops),
 192         .map_io         = zynq_map_io,
 193         .init_irq       = zynq_irq_init,
 194         .init_machine   = zynq_init_machine,
 195         .init_late      = zynq_init_late,
 196         .init_time      = zynq_timer_init,
 197         .dt_compat      = zynq_dt_match,
 198         .reserve        = zynq_memory_init,
 199 MACHINE_END

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