Linux Audio

Check our new training course

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