2009-11-28 08:17:18 +01:00
/*
2011-12-15 13:38:40 +01:00
* Copyright ( C ) 2008 - 2009 ST - Ericsson SA
2009-11-28 08:17:18 +01:00
*
* Author : Srinidhi KASAGAR < srinidhi . kasagar @ stericsson . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 , as
* published by the Free Software Foundation .
*
*/
# include <linux/types.h>
# include <linux/init.h>
# include <linux/device.h>
# include <linux/amba/bus.h>
2011-02-08 09:24:37 +05:30
# include <linux/interrupt.h>
2009-11-28 08:17:18 +01:00
# include <linux/irq.h>
2016-06-20 23:40:55 +02:00
# include <linux/irqchip.h>
# include <linux/irqchip/arm-gic.h>
# include <linux/mfd/dbx500-prcmu.h>
# include <linux/platform_data/arm-ux500-pm.h>
2009-11-28 08:17:18 +01:00
# include <linux/platform_device.h>
2010-03-01 05:03:31 +01:00
# include <linux/io.h>
2012-09-27 10:17:36 +01:00
# include <linux/of.h>
2016-06-20 23:40:55 +02:00
# include <linux/of_address.h>
2012-09-27 10:17:36 +01:00
# include <linux/of_platform.h>
# include <linux/regulator/machine.h>
2009-11-28 08:17:18 +01:00
2016-06-20 23:40:55 +02:00
# include <asm/outercache.h>
# include <asm/hardware/cache-l2x0.h>
2009-11-28 08:17:18 +01:00
# include <asm/mach/map.h>
2016-06-20 23:40:55 +02:00
# include <asm/mach/arch.h>
2012-12-13 10:57:16 -08:00
2013-11-06 10:05:43 +00:00
# include "db8500-regs.h"
2017-10-06 06:20:25 +02:00
# include "pm_domains.h"
2009-11-28 08:17:18 +01:00
2016-06-20 23:40:55 +02:00
static int __init ux500_l2x0_unlock ( void )
{
int i ;
struct device_node * np ;
void __iomem * l2x0_base ;
np = of_find_compatible_node ( NULL , NULL , " arm,pl310-cache " ) ;
l2x0_base = of_iomap ( np , 0 ) ;
of_node_put ( np ) ;
if ( ! l2x0_base )
return - ENODEV ;
/*
* Unlock Data and Instruction Lock if locked . Ux500 U - Boot versions
* apparently locks both caches before jumping to the kernel . The
* l2x0 core will not touch the unlock registers if the l2x0 is
* already enabled , so we do it right here instead . The PL310 has
* 8 sets of registers , one per possible CPU .
*/
for ( i = 0 ; i < 8 ; i + + ) {
writel_relaxed ( 0x0 , l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
i * L2X0_LOCKDOWN_STRIDE ) ;
writel_relaxed ( 0x0 , l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
i * L2X0_LOCKDOWN_STRIDE ) ;
}
iounmap ( l2x0_base ) ;
return 0 ;
}
static void ux500_l2c310_write_sec ( unsigned long val , unsigned reg )
{
/*
* We can ' t write to secure registers as we are in non - secure
* mode , until we have some SMI service available .
*/
}
/*
* FIXME : Should we set up the GPIO domain here ?
*
* The problem is that we cannot put the interrupt resources into the platform
* device until the irqdomain has been added . Right now , we set the GIC interrupt
* domain from init_irq ( ) , then load the gpio driver from
* core_initcall ( nmk_gpio_init ) and add the platform devices from
* arch_initcall ( customize_machine ) .
*
* This feels fragile because it depends on the gpio device getting probed
* _before_ any device uses the gpio interrupts .
*/
static void __init ux500_init_irq ( void )
{
struct device_node * np ;
struct resource r ;
irqchip_init ( ) ;
np = of_find_compatible_node ( NULL , NULL , " stericsson,db8500-prcmu " ) ;
of_address_to_resource ( np , 0 , & r ) ;
of_node_put ( np ) ;
if ( ! r . start ) {
pr_err ( " could not find PRCMU base resource \n " ) ;
return ;
}
prcmu_early_init ( r . start , r . end - r . start ) ;
ux500_pm_init ( r . start , r . end - r . start ) ;
/* Unlock before init */
ux500_l2x0_unlock ( ) ;
outer_cache . write_sec = ux500_l2c310_write_sec ;
}
static void ux500_restart ( enum reboot_mode mode , const char * cmd )
{
local_irq_disable ( ) ;
local_fiq_disable ( ) ;
prcmu_system_reset ( 0 ) ;
}
2012-09-27 10:17:36 +01:00
static const struct of_device_id u8500_local_bus_nodes [ ] = {
/* only create devices below soc node */
{ . compatible = " stericsson,db8500 " , } ,
{ . compatible = " stericsson,db8500-prcmu " , } ,
{ . compatible = " simple-bus " } ,
{ } ,
} ;
static void __init u8500_init_machine ( void )
{
2017-10-06 06:20:25 +02:00
/* Initialize ux500 power domains */
ux500_pm_domains_init ( ) ;
2018-03-07 14:29:23 +01:00
of_platform_populate ( NULL , u8500_local_bus_nodes ,
NULL , NULL ) ;
2012-09-27 10:17:36 +01:00
}
2012-10-15 10:07:55 +01:00
static const char * stericsson_dt_platform_compat [ ] = {
" st-ericsson,u8500 " ,
" st-ericsson,u9500 " ,
2012-09-27 10:17:36 +01:00
NULL ,
} ;
2012-10-15 08:55:17 +01:00
DT_MACHINE_START ( U8500_DT , " ST-Ericsson Ux5x0 platform (Device Tree Support) " )
2016-06-20 22:27:23 +02:00
. l2c_aux_val = 0 ,
. l2c_aux_mask = ~ 0 ,
2012-09-27 10:17:36 +01:00
. init_irq = ux500_init_irq ,
. init_machine = u8500_init_machine ,
2012-10-15 10:07:55 +01:00
. dt_compat = stericsson_dt_platform_compat ,
2013-06-14 15:22:40 +02:00
. restart = ux500_restart ,
2012-09-27 10:17:36 +01:00
MACHINE_END