2012-06-13 19:01:28 +02:00
/*
* Device Tree support for Armada 370 and XP platforms .
*
* Copyright ( C ) 2012 Marvell
*
* Lior Amsalem < alior @ marvell . com >
* Gregory CLEMENT < gregory . clement @ free - electrons . com >
* Thomas Petazzoni < thomas . petazzoni @ free - electrons . com >
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*/
# include <linux/kernel.h>
# include <linux/init.h>
2013-06-05 09:04:59 +02:00
# include <linux/of_address.h>
2014-11-21 17:00:07 +01:00
# include <linux/of_fdt.h>
2012-06-13 19:01:28 +02:00
# include <linux/of_platform.h>
# include <linux/io.h>
2013-08-13 11:43:12 -03:00
# include <linux/clocksource.h>
2012-10-26 14:30:46 +02:00
# include <linux/dma-mapping.h>
2014-11-21 17:00:07 +01:00
# include <linux/memblock.h>
2013-03-21 17:59:15 +01:00
# include <linux/mbus.h>
2014-01-07 16:26:01 +01:00
# include <linux/slab.h>
ARM: mvebu: update L2/PCIe deadlock workaround after L2CC cleanup
Commit 497a92308af8e9385fa3d135f7f416a997e4b93b ("ARM: mvebu:
implement L2/PCIe deadlock workaround") introduced some logic in
coherency.c to adjust the PL310 cache controller Device Tree node of
Armada 375 and Armada 38x platform to include the 'arm,io-coherent'
property if the system is running with hardware I/O coherency enabled.
However, with the L2CC driver cleanup done by Russell King, the
initialization of the L2CC driver has been moved earlier, and is now
part of the init_IRQ() ARM function in
arch/arm/kernel/irq.c. Therefore, calling coherency_init() in
->init_time() is now too late, as the Device Tree property gets added
too late (after the L2CC driver has been initialized).
In order to fix this, this commit removes the ->init_time() callback
use in board-v7.c and replaces it with an ->init_irq() callback. We
therefore no longer use the default ->init_irq() callback, but we now
use the default ->init_time() callback.
In this newly introduced ->init_irq() callback, we call irqchip_init()
which is the default behavior when ->init_irq() isn't defined, and
then do the initialization related to the coherency: SCU, coherency
fabric, and mvebu-mbus (which is needed to start secondary CPUs).
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1402585772-10405-4-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2014-06-12 17:09:32 +02:00
# include <linux/irqchip.h>
2013-04-09 23:26:14 +02:00
# include <asm/hardware/cache-l2x0.h>
2012-06-13 19:01:28 +02:00
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
# include <asm/mach/time.h>
2014-04-14 15:47:03 +02:00
# include <asm/smp_scu.h>
2012-09-02 14:57:33 -05:00
# include "armada-370-xp.h"
2012-06-13 19:01:28 +02:00
# include "common.h"
2012-11-14 22:51:08 +01:00
# include "coherency.h"
2014-01-07 16:26:01 +01:00
# include "mvebu-soc-id.h"
2012-06-13 19:01:28 +02:00
2014-07-23 15:00:46 +02:00
static void __iomem * scu_base ;
2014-04-14 15:47:03 +02:00
/*
* Enables the SCU when available . Obviously , this is only useful on
* Cortex - A based SOCs , not on PJ4B based ones .
*/
static void __init mvebu_scu_enable ( void )
{
struct device_node * np =
of_find_compatible_node ( NULL , NULL , " arm,cortex-a9-scu " ) ;
if ( np ) {
scu_base = of_iomap ( np , 0 ) ;
scu_enable ( scu_base ) ;
of_node_put ( np ) ;
}
}
2014-07-23 15:00:46 +02:00
void __iomem * mvebu_get_scu_base ( void )
{
return scu_base ;
}
2014-11-21 17:00:07 +01:00
/*
* When returning from suspend , the platform goes through the
* bootloader , which executes its DDR3 training code . This code has
* the unfortunate idea of using the first 10 KB of each DRAM bank to
* exercise the RAM and calculate the optimal timings . Therefore , this
* area of RAM is overwritten , and shouldn ' t be used by the kernel if
* suspend / resume is supported .
*/
# ifdef CONFIG_SUSPEND
# define MVEBU_DDR_TRAINING_AREA_SZ (10 * SZ_1K)
static int __init mvebu_scan_mem ( unsigned long node , const char * uname ,
int depth , void * data )
{
const char * type = of_get_flat_dt_prop ( node , " device_type " , NULL ) ;
const __be32 * reg , * endp ;
int l ;
if ( type = = NULL | | strcmp ( type , " memory " ) )
return 0 ;
reg = of_get_flat_dt_prop ( node , " linux,usable-memory " , & l ) ;
if ( reg = = NULL )
reg = of_get_flat_dt_prop ( node , " reg " , & l ) ;
if ( reg = = NULL )
return 0 ;
endp = reg + ( l / sizeof ( __be32 ) ) ;
while ( ( endp - reg ) > = ( dt_root_addr_cells + dt_root_size_cells ) ) {
u64 base , size ;
base = dt_mem_next_cell ( dt_root_addr_cells , & reg ) ;
size = dt_mem_next_cell ( dt_root_size_cells , & reg ) ;
memblock_reserve ( base , MVEBU_DDR_TRAINING_AREA_SZ ) ;
}
return 0 ;
}
static void __init mvebu_memblock_reserve ( void )
{
of_scan_flat_dt ( mvebu_scan_mem , NULL ) ;
}
# else
static void __init mvebu_memblock_reserve ( void ) { }
# endif
ARM: mvebu: update L2/PCIe deadlock workaround after L2CC cleanup
Commit 497a92308af8e9385fa3d135f7f416a997e4b93b ("ARM: mvebu:
implement L2/PCIe deadlock workaround") introduced some logic in
coherency.c to adjust the PL310 cache controller Device Tree node of
Armada 375 and Armada 38x platform to include the 'arm,io-coherent'
property if the system is running with hardware I/O coherency enabled.
However, with the L2CC driver cleanup done by Russell King, the
initialization of the L2CC driver has been moved earlier, and is now
part of the init_IRQ() ARM function in
arch/arm/kernel/irq.c. Therefore, calling coherency_init() in
->init_time() is now too late, as the Device Tree property gets added
too late (after the L2CC driver has been initialized).
In order to fix this, this commit removes the ->init_time() callback
use in board-v7.c and replaces it with an ->init_irq() callback. We
therefore no longer use the default ->init_irq() callback, but we now
use the default ->init_time() callback.
In this newly introduced ->init_irq() callback, we call irqchip_init()
which is the default behavior when ->init_irq() isn't defined, and
then do the initialization related to the coherency: SCU, coherency
fabric, and mvebu-mbus (which is needed to start secondary CPUs).
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1402585772-10405-4-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2014-06-12 17:09:32 +02:00
static void __init mvebu_init_irq ( void )
2013-06-05 09:04:59 +02:00
{
ARM: mvebu: update L2/PCIe deadlock workaround after L2CC cleanup
Commit 497a92308af8e9385fa3d135f7f416a997e4b93b ("ARM: mvebu:
implement L2/PCIe deadlock workaround") introduced some logic in
coherency.c to adjust the PL310 cache controller Device Tree node of
Armada 375 and Armada 38x platform to include the 'arm,io-coherent'
property if the system is running with hardware I/O coherency enabled.
However, with the L2CC driver cleanup done by Russell King, the
initialization of the L2CC driver has been moved earlier, and is now
part of the init_IRQ() ARM function in
arch/arm/kernel/irq.c. Therefore, calling coherency_init() in
->init_time() is now too late, as the Device Tree property gets added
too late (after the L2CC driver has been initialized).
In order to fix this, this commit removes the ->init_time() callback
use in board-v7.c and replaces it with an ->init_irq() callback. We
therefore no longer use the default ->init_irq() callback, but we now
use the default ->init_time() callback.
In this newly introduced ->init_irq() callback, we call irqchip_init()
which is the default behavior when ->init_irq() isn't defined, and
then do the initialization related to the coherency: SCU, coherency
fabric, and mvebu-mbus (which is needed to start secondary CPUs).
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1402585772-10405-4-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2014-06-12 17:09:32 +02:00
irqchip_init ( ) ;
2014-04-14 15:47:03 +02:00
mvebu_scu_enable ( ) ;
2013-06-05 09:04:59 +02:00
coherency_init ( ) ;
2014-04-14 15:47:01 +02:00
BUG_ON ( mvebu_mbus_dt_init ( coherency_available ( ) ) ) ;
2014-06-12 17:09:31 +02:00
}
2014-01-07 16:26:01 +01:00
static void __init i2c_quirk ( void )
{
struct device_node * np ;
u32 dev , rev ;
/*
* Only revisons more recent than A0 support the offload
* mechanism . We can exit only if we are sure that we can
* get the SoC revision and it is more recent than A0 .
*/
2014-04-19 18:32:50 +02:00
if ( mvebu_get_soc_id ( & dev , & rev ) = = 0 & & rev > MV78XX0_A0_REV )
2014-01-07 16:26:01 +01:00
return ;
for_each_compatible_node ( np , NULL , " marvell,mv78230-i2c " ) {
struct property * new_compat ;
new_compat = kzalloc ( sizeof ( * new_compat ) , GFP_KERNEL ) ;
new_compat - > name = kstrdup ( " compatible " , GFP_KERNEL ) ;
new_compat - > length = sizeof ( " marvell,mv78230-a0-i2c " ) ;
new_compat - > value = kstrdup ( " marvell,mv78230-a0-i2c " ,
GFP_KERNEL ) ;
of_update_property ( np , new_compat ) ;
}
return ;
}
2014-02-17 15:23:19 +01:00
static void __init mvebu_dt_init ( void )
2012-06-13 19:01:28 +02:00
{
2014-07-26 19:20:37 +02:00
if ( of_machine_is_compatible ( " marvell,armadaxp " ) )
2014-01-07 16:26:01 +01:00
i2c_quirk ( ) ;
2014-04-24 17:23:22 -03:00
2012-06-13 19:01:28 +02:00
of_platform_populate ( NULL , of_default_bus_match_table , NULL , NULL ) ;
}
2015-03-03 15:40:56 +01:00
static const char * const armada_370_xp_dt_compat [ ] __initconst = {
2012-11-09 16:26:26 +01:00
" marvell,armada-370-xp " ,
2012-06-13 19:01:28 +02:00
NULL ,
} ;
2014-02-17 15:23:20 +01:00
DT_MACHINE_START ( ARMADA_370_XP_DT , " Marvell Armada 370/XP (Device Tree) " )
2014-04-28 15:44:47 +01:00
. l2c_aux_val = 0 ,
. l2c_aux_mask = ~ 0 ,
2014-10-30 12:39:41 +01:00
/*
* The following field ( . smp ) is still needed to ensure backward
* compatibility with old Device Trees that were not specifying the
* cpus enable - method property .
*/
2012-11-14 22:51:08 +01:00
. smp = smp_ops ( armada_xp_smp_ops ) ,
2014-02-17 15:23:19 +01:00
. init_machine = mvebu_dt_init ,
ARM: mvebu: update L2/PCIe deadlock workaround after L2CC cleanup
Commit 497a92308af8e9385fa3d135f7f416a997e4b93b ("ARM: mvebu:
implement L2/PCIe deadlock workaround") introduced some logic in
coherency.c to adjust the PL310 cache controller Device Tree node of
Armada 375 and Armada 38x platform to include the 'arm,io-coherent'
property if the system is running with hardware I/O coherency enabled.
However, with the L2CC driver cleanup done by Russell King, the
initialization of the L2CC driver has been moved earlier, and is now
part of the init_IRQ() ARM function in
arch/arm/kernel/irq.c. Therefore, calling coherency_init() in
->init_time() is now too late, as the Device Tree property gets added
too late (after the L2CC driver has been initialized).
In order to fix this, this commit removes the ->init_time() callback
use in board-v7.c and replaces it with an ->init_irq() callback. We
therefore no longer use the default ->init_irq() callback, but we now
use the default ->init_time() callback.
In this newly introduced ->init_irq() callback, we call irqchip_init()
which is the default behavior when ->init_irq() isn't defined, and
then do the initialization related to the coherency: SCU, coherency
fabric, and mvebu-mbus (which is needed to start secondary CPUs).
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1402585772-10405-4-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2014-06-12 17:09:32 +02:00
. init_irq = mvebu_init_irq ,
2012-06-13 19:01:28 +02:00
. restart = mvebu_restart ,
2014-11-21 17:00:07 +01:00
. reserve = mvebu_memblock_reserve ,
2012-11-09 16:26:26 +01:00
. dt_compat = armada_370_xp_dt_compat ,
2012-06-13 19:01:28 +02:00
MACHINE_END
2014-02-17 15:23:23 +01:00
2015-03-03 15:40:56 +01:00
static const char * const armada_375_dt_compat [ ] __initconst = {
2014-02-17 15:23:23 +01:00
" marvell,armada375 " ,
NULL ,
} ;
DT_MACHINE_START ( ARMADA_375_DT , " Marvell Armada 375 (Device Tree) " )
2014-04-28 15:44:47 +01:00
. l2c_aux_val = 0 ,
. l2c_aux_mask = ~ 0 ,
ARM: mvebu: update L2/PCIe deadlock workaround after L2CC cleanup
Commit 497a92308af8e9385fa3d135f7f416a997e4b93b ("ARM: mvebu:
implement L2/PCIe deadlock workaround") introduced some logic in
coherency.c to adjust the PL310 cache controller Device Tree node of
Armada 375 and Armada 38x platform to include the 'arm,io-coherent'
property if the system is running with hardware I/O coherency enabled.
However, with the L2CC driver cleanup done by Russell King, the
initialization of the L2CC driver has been moved earlier, and is now
part of the init_IRQ() ARM function in
arch/arm/kernel/irq.c. Therefore, calling coherency_init() in
->init_time() is now too late, as the Device Tree property gets added
too late (after the L2CC driver has been initialized).
In order to fix this, this commit removes the ->init_time() callback
use in board-v7.c and replaces it with an ->init_irq() callback. We
therefore no longer use the default ->init_irq() callback, but we now
use the default ->init_time() callback.
In this newly introduced ->init_irq() callback, we call irqchip_init()
which is the default behavior when ->init_irq() isn't defined, and
then do the initialization related to the coherency: SCU, coherency
fabric, and mvebu-mbus (which is needed to start secondary CPUs).
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1402585772-10405-4-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2014-06-12 17:09:32 +02:00
. init_irq = mvebu_init_irq ,
2014-04-24 17:23:22 -03:00
. init_machine = mvebu_dt_init ,
2014-02-17 15:23:23 +01:00
. restart = mvebu_restart ,
. dt_compat = armada_375_dt_compat ,
MACHINE_END
2014-02-17 15:23:27 +01:00
2015-03-03 15:40:56 +01:00
static const char * const armada_38x_dt_compat [ ] __initconst = {
2014-02-17 15:23:27 +01:00
" marvell,armada380 " ,
" marvell,armada385 " ,
NULL ,
} ;
DT_MACHINE_START ( ARMADA_38X_DT , " Marvell Armada 380/385 (Device Tree) " )
2014-04-28 15:44:47 +01:00
. l2c_aux_val = 0 ,
. l2c_aux_mask = ~ 0 ,
ARM: mvebu: update L2/PCIe deadlock workaround after L2CC cleanup
Commit 497a92308af8e9385fa3d135f7f416a997e4b93b ("ARM: mvebu:
implement L2/PCIe deadlock workaround") introduced some logic in
coherency.c to adjust the PL310 cache controller Device Tree node of
Armada 375 and Armada 38x platform to include the 'arm,io-coherent'
property if the system is running with hardware I/O coherency enabled.
However, with the L2CC driver cleanup done by Russell King, the
initialization of the L2CC driver has been moved earlier, and is now
part of the init_IRQ() ARM function in
arch/arm/kernel/irq.c. Therefore, calling coherency_init() in
->init_time() is now too late, as the Device Tree property gets added
too late (after the L2CC driver has been initialized).
In order to fix this, this commit removes the ->init_time() callback
use in board-v7.c and replaces it with an ->init_irq() callback. We
therefore no longer use the default ->init_irq() callback, but we now
use the default ->init_time() callback.
In this newly introduced ->init_irq() callback, we call irqchip_init()
which is the default behavior when ->init_irq() isn't defined, and
then do the initialization related to the coherency: SCU, coherency
fabric, and mvebu-mbus (which is needed to start secondary CPUs).
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1402585772-10405-4-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2014-06-12 17:09:32 +02:00
. init_irq = mvebu_init_irq ,
2014-02-17 15:23:27 +01:00
. restart = mvebu_restart ,
. dt_compat = armada_38x_dt_compat ,
MACHINE_END
ARM: mvebu: add core support for Armada 39x
This commit adds the core support for Armada 39x, which is quite
simple:
- a new Kconfig option which selects the appropriate clock and
pinctrl drivers as well as other common features (GIC, L2 cache,
SMP, etc.)
- a new DT_MACHINE_START which references the top-level compatible
strings supported for the Marvell Armada 39x.
- a new SMP enable-method. The mechanism to enable CPUs for Armada
39x appears to be the same as Armada 38x. However, we do not want
to use marvell,armada-380-smp in the Device Tree, in the case of
the discovery of a subtle difference in the future, which would
require changing the Device Tree. And the enable-method isn't a
compatible string: you can't specify several values and expect a
fallback on the second string if the first one isn't
supported. Therefore, we simply declare the SMP enable method
"marvell,armada-390-smp" as doing the same thing as the
"marvell,armada-380-smp" one.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
2015-03-03 15:41:11 +01:00
static const char * const armada_39x_dt_compat [ ] __initconst = {
" marvell,armada390 " ,
" marvell,armada398 " ,
NULL ,
} ;
DT_MACHINE_START ( ARMADA_39X_DT , " Marvell Armada 39x (Device Tree) " )
. l2c_aux_val = 0 ,
. l2c_aux_mask = ~ 0 ,
. init_irq = mvebu_init_irq ,
. restart = mvebu_restart ,
. dt_compat = armada_39x_dt_compat ,
MACHINE_END