1*99b3d294SThomas Petazzoni /* 2*99b3d294SThomas Petazzoni * Device Tree support for Armada 370 and XP platforms. 3*99b3d294SThomas Petazzoni * 4*99b3d294SThomas Petazzoni * Copyright (C) 2012 Marvell 5*99b3d294SThomas Petazzoni * 6*99b3d294SThomas Petazzoni * Lior Amsalem <alior@marvell.com> 7*99b3d294SThomas Petazzoni * Gregory CLEMENT <gregory.clement@free-electrons.com> 8*99b3d294SThomas Petazzoni * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 9*99b3d294SThomas Petazzoni * 10*99b3d294SThomas Petazzoni * This file is licensed under the terms of the GNU General Public 11*99b3d294SThomas Petazzoni * License version 2. This program is licensed "as is" without any 12*99b3d294SThomas Petazzoni * warranty of any kind, whether express or implied. 13*99b3d294SThomas Petazzoni */ 14*99b3d294SThomas Petazzoni 15*99b3d294SThomas Petazzoni #include <linux/kernel.h> 16*99b3d294SThomas Petazzoni #include <linux/init.h> 17*99b3d294SThomas Petazzoni #include <linux/clk-provider.h> 18*99b3d294SThomas Petazzoni #include <linux/of_address.h> 19*99b3d294SThomas Petazzoni #include <linux/of_platform.h> 20*99b3d294SThomas Petazzoni #include <linux/io.h> 21*99b3d294SThomas Petazzoni #include <linux/clocksource.h> 22*99b3d294SThomas Petazzoni #include <linux/dma-mapping.h> 23*99b3d294SThomas Petazzoni #include <linux/mbus.h> 24*99b3d294SThomas Petazzoni #include <linux/slab.h> 25*99b3d294SThomas Petazzoni #include <asm/hardware/cache-l2x0.h> 26*99b3d294SThomas Petazzoni #include <asm/mach/arch.h> 27*99b3d294SThomas Petazzoni #include <asm/mach/map.h> 28*99b3d294SThomas Petazzoni #include <asm/mach/time.h> 29*99b3d294SThomas Petazzoni #include "armada-370-xp.h" 30*99b3d294SThomas Petazzoni #include "common.h" 31*99b3d294SThomas Petazzoni #include "coherency.h" 32*99b3d294SThomas Petazzoni #include "mvebu-soc-id.h" 33*99b3d294SThomas Petazzoni 34*99b3d294SThomas Petazzoni static void __init mvebu_timer_and_clk_init(void) 35*99b3d294SThomas Petazzoni { 36*99b3d294SThomas Petazzoni of_clk_init(NULL); 37*99b3d294SThomas Petazzoni clocksource_of_init(); 38*99b3d294SThomas Petazzoni coherency_init(); 39*99b3d294SThomas Petazzoni BUG_ON(mvebu_mbus_dt_init()); 40*99b3d294SThomas Petazzoni #ifdef CONFIG_CACHE_L2X0 41*99b3d294SThomas Petazzoni l2x0_of_init(0, ~0UL); 42*99b3d294SThomas Petazzoni #endif 43*99b3d294SThomas Petazzoni } 44*99b3d294SThomas Petazzoni 45*99b3d294SThomas Petazzoni static void __init i2c_quirk(void) 46*99b3d294SThomas Petazzoni { 47*99b3d294SThomas Petazzoni struct device_node *np; 48*99b3d294SThomas Petazzoni u32 dev, rev; 49*99b3d294SThomas Petazzoni 50*99b3d294SThomas Petazzoni /* 51*99b3d294SThomas Petazzoni * Only revisons more recent than A0 support the offload 52*99b3d294SThomas Petazzoni * mechanism. We can exit only if we are sure that we can 53*99b3d294SThomas Petazzoni * get the SoC revision and it is more recent than A0. 54*99b3d294SThomas Petazzoni */ 55*99b3d294SThomas Petazzoni if (mvebu_get_soc_id(&rev, &dev) == 0 && dev > MV78XX0_A0_REV) 56*99b3d294SThomas Petazzoni return; 57*99b3d294SThomas Petazzoni 58*99b3d294SThomas Petazzoni for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") { 59*99b3d294SThomas Petazzoni struct property *new_compat; 60*99b3d294SThomas Petazzoni 61*99b3d294SThomas Petazzoni new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL); 62*99b3d294SThomas Petazzoni 63*99b3d294SThomas Petazzoni new_compat->name = kstrdup("compatible", GFP_KERNEL); 64*99b3d294SThomas Petazzoni new_compat->length = sizeof("marvell,mv78230-a0-i2c"); 65*99b3d294SThomas Petazzoni new_compat->value = kstrdup("marvell,mv78230-a0-i2c", 66*99b3d294SThomas Petazzoni GFP_KERNEL); 67*99b3d294SThomas Petazzoni 68*99b3d294SThomas Petazzoni of_update_property(np, new_compat); 69*99b3d294SThomas Petazzoni } 70*99b3d294SThomas Petazzoni return; 71*99b3d294SThomas Petazzoni } 72*99b3d294SThomas Petazzoni 73*99b3d294SThomas Petazzoni static void __init mvebu_dt_init(void) 74*99b3d294SThomas Petazzoni { 75*99b3d294SThomas Petazzoni if (of_machine_is_compatible("plathome,openblocks-ax3-4")) 76*99b3d294SThomas Petazzoni i2c_quirk(); 77*99b3d294SThomas Petazzoni of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 78*99b3d294SThomas Petazzoni } 79*99b3d294SThomas Petazzoni 80*99b3d294SThomas Petazzoni static const char * const armada_370_xp_dt_compat[] = { 81*99b3d294SThomas Petazzoni "marvell,armada-370-xp", 82*99b3d294SThomas Petazzoni NULL, 83*99b3d294SThomas Petazzoni }; 84*99b3d294SThomas Petazzoni 85*99b3d294SThomas Petazzoni DT_MACHINE_START(ARMADA_XP_DT, "Marvell Armada 370/XP (Device Tree)") 86*99b3d294SThomas Petazzoni .smp = smp_ops(armada_xp_smp_ops), 87*99b3d294SThomas Petazzoni .init_machine = mvebu_dt_init, 88*99b3d294SThomas Petazzoni .init_time = mvebu_timer_and_clk_init, 89*99b3d294SThomas Petazzoni .restart = mvebu_restart, 90*99b3d294SThomas Petazzoni .dt_compat = armada_370_xp_dt_compat, 91*99b3d294SThomas Petazzoni MACHINE_END 92