0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/init.h>
0014 #include <linux/of_address.h>
0015 #include <linux/of_fdt.h>
0016 #include <linux/io.h>
0017 #include <linux/clocksource.h>
0018 #include <linux/dma-mapping.h>
0019 #include <linux/memblock.h>
0020 #include <linux/mbus.h>
0021 #include <linux/slab.h>
0022 #include <linux/irqchip.h>
0023 #include <asm/hardware/cache-l2x0.h>
0024 #include <asm/mach/arch.h>
0025 #include <asm/mach/map.h>
0026 #include <asm/mach/time.h>
0027 #include <asm/smp_scu.h>
0028 #include "armada-370-xp.h"
0029 #include "common.h"
0030 #include "coherency.h"
0031 #include "mvebu-soc-id.h"
0032
0033 static void __iomem *scu_base;
0034
0035
0036
0037
0038
0039 static void __init mvebu_scu_enable(void)
0040 {
0041 struct device_node *np =
0042 of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
0043 if (np) {
0044 scu_base = of_iomap(np, 0);
0045 scu_enable(scu_base);
0046 of_node_put(np);
0047 }
0048 }
0049
0050 void __iomem *mvebu_get_scu_base(void)
0051 {
0052 return scu_base;
0053 }
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #ifdef CONFIG_SUSPEND
0065 #define MVEBU_DDR_TRAINING_AREA_SZ (10 * SZ_1K)
0066 static int __init mvebu_scan_mem(unsigned long node, const char *uname,
0067 int depth, void *data)
0068 {
0069 const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
0070 const __be32 *reg, *endp;
0071 int l;
0072
0073 if (type == NULL || strcmp(type, "memory"))
0074 return 0;
0075
0076 reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
0077 if (reg == NULL)
0078 reg = of_get_flat_dt_prop(node, "reg", &l);
0079 if (reg == NULL)
0080 return 0;
0081
0082 endp = reg + (l / sizeof(__be32));
0083 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
0084 u64 base, size;
0085
0086 base = dt_mem_next_cell(dt_root_addr_cells, ®);
0087 size = dt_mem_next_cell(dt_root_size_cells, ®);
0088
0089 memblock_reserve(base, MVEBU_DDR_TRAINING_AREA_SZ);
0090 }
0091
0092 return 0;
0093 }
0094
0095 static void __init mvebu_memblock_reserve(void)
0096 {
0097 of_scan_flat_dt(mvebu_scan_mem, NULL);
0098 }
0099 #else
0100 static void __init mvebu_memblock_reserve(void) {}
0101 #endif
0102
0103 static void __init mvebu_init_irq(void)
0104 {
0105 irqchip_init();
0106 mvebu_scu_enable();
0107 coherency_init();
0108 BUG_ON(mvebu_mbus_dt_init(coherency_available()));
0109 }
0110
0111 static void __init i2c_quirk(void)
0112 {
0113 struct device_node *np;
0114 u32 dev, rev;
0115
0116
0117
0118
0119
0120
0121 if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > MV78XX0_A0_REV)
0122 return;
0123
0124 for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") {
0125 struct property *new_compat;
0126
0127 new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
0128
0129 new_compat->name = kstrdup("compatible", GFP_KERNEL);
0130 new_compat->length = sizeof("marvell,mv78230-a0-i2c");
0131 new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
0132 GFP_KERNEL);
0133
0134 of_update_property(np, new_compat);
0135 }
0136 }
0137
0138 static void __init mvebu_dt_init(void)
0139 {
0140 if (of_machine_is_compatible("marvell,armadaxp"))
0141 i2c_quirk();
0142 }
0143
0144 static void __init armada_370_xp_dt_fixup(void)
0145 {
0146 #ifdef CONFIG_SMP
0147 smp_set_ops(smp_ops(armada_xp_smp_ops));
0148 #endif
0149 }
0150
0151 static const char * const armada_370_xp_dt_compat[] __initconst = {
0152 "marvell,armada-370-xp",
0153 NULL,
0154 };
0155
0156 DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
0157 .l2c_aux_val = 0,
0158 .l2c_aux_mask = ~0,
0159 .init_machine = mvebu_dt_init,
0160 .init_irq = mvebu_init_irq,
0161 .restart = mvebu_restart,
0162 .reserve = mvebu_memblock_reserve,
0163 .dt_compat = armada_370_xp_dt_compat,
0164 .dt_fixup = armada_370_xp_dt_fixup,
0165 MACHINE_END
0166
0167 static const char * const armada_375_dt_compat[] __initconst = {
0168 "marvell,armada375",
0169 NULL,
0170 };
0171
0172 DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
0173 .l2c_aux_val = 0,
0174 .l2c_aux_mask = ~0,
0175 .init_irq = mvebu_init_irq,
0176 .init_machine = mvebu_dt_init,
0177 .restart = mvebu_restart,
0178 .dt_compat = armada_375_dt_compat,
0179 MACHINE_END
0180
0181 static const char * const armada_38x_dt_compat[] __initconst = {
0182 "marvell,armada380",
0183 "marvell,armada385",
0184 NULL,
0185 };
0186
0187 DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
0188 .l2c_aux_val = 0,
0189 .l2c_aux_mask = ~0,
0190 .init_irq = mvebu_init_irq,
0191 .restart = mvebu_restart,
0192 .dt_compat = armada_38x_dt_compat,
0193 MACHINE_END
0194
0195 static const char * const armada_39x_dt_compat[] __initconst = {
0196 "marvell,armada390",
0197 "marvell,armada398",
0198 NULL,
0199 };
0200
0201 DT_MACHINE_START(ARMADA_39X_DT, "Marvell Armada 39x (Device Tree)")
0202 .l2c_aux_val = 0,
0203 .l2c_aux_mask = ~0,
0204 .init_irq = mvebu_init_irq,
0205 .restart = mvebu_restart,
0206 .dt_compat = armada_39x_dt_compat,
0207 MACHINE_END