2013-06-10 11:27:13 -04:00
/*
* Keystone2 based boards and SOC related code .
*
* Copyright 2013 Texas Instruments , Inc .
* Cyril Chemparathy < cyril @ ti . com >
* Santosh Shilimkar < santosh . shillimkar @ ti . com >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*/
# include <linux/io.h>
# include <linux/of.h>
# include <linux/init.h>
# include <linux/of_platform.h>
# include <linux/of_address.h>
2014-06-05 15:22:52 -04:00
# include <linux/memblock.h>
2013-06-10 11:27:13 -04:00
# include <asm/setup.h>
# include <asm/mach/map.h>
# include <asm/mach/arch.h>
# include <asm/mach/time.h>
2013-06-10 12:20:17 -04:00
# include <asm/smp_plat.h>
2013-06-13 19:24:39 -04:00
# include <asm/memory.h>
# include "memory.h"
2013-06-10 12:20:17 -04:00
# include "keystone.h"
2013-06-10 11:27:13 -04:00
2014-02-24 17:32:59 +02:00
static struct notifier_block platform_nb ;
static unsigned long keystone_dma_pfn_offset __read_mostly ;
static int keystone_platform_notifier ( struct notifier_block * nb ,
unsigned long event , void * data )
{
struct device * dev = data ;
if ( event ! = BUS_NOTIFY_ADD_DEVICE )
return NOTIFY_DONE ;
if ( ! dev )
return NOTIFY_BAD ;
if ( ! dev - > of_node ) {
dev - > dma_pfn_offset = keystone_dma_pfn_offset ;
dev_err ( dev , " set dma_pfn_offset%08lx \n " ,
dev - > dma_pfn_offset ) ;
}
return NOTIFY_OK ;
}
2013-06-10 11:27:13 -04:00
static void __init keystone_init ( void )
{
2013-11-23 17:08:03 -05:00
keystone_pm_runtime_init ( ) ;
2014-02-24 17:32:59 +02:00
if ( platform_nb . notifier_call )
bus_register_notifier ( & platform_bus_type , & platform_nb ) ;
2013-06-10 11:27:13 -04:00
of_platform_populate ( NULL , of_default_bus_match_table , NULL , NULL ) ;
}
2013-06-13 19:24:39 -04:00
static phys_addr_t keystone_virt_to_idmap ( unsigned long x )
{
return ( phys_addr_t ) ( x ) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START ;
}
static void __init keystone_init_meminfo ( void )
{
bool lpae = IS_ENABLED ( CONFIG_ARM_LPAE ) ;
bool pvpatch = IS_ENABLED ( CONFIG_ARM_PATCH_PHYS_VIRT ) ;
phys_addr_t offset = PHYS_OFFSET - KEYSTONE_LOW_PHYS_START ;
phys_addr_t mem_start , mem_end ;
2014-06-05 15:22:52 -04:00
mem_start = memblock_start_of_DRAM ( ) ;
mem_end = memblock_end_of_DRAM ( ) ;
2013-06-13 19:24:39 -04:00
/* nothing to do if we are running out of the <32-bit space */
if ( mem_start > = KEYSTONE_LOW_PHYS_START & &
mem_end < = KEYSTONE_LOW_PHYS_END )
return ;
if ( ! lpae | | ! pvpatch ) {
pr_crit ( " Enable %s%s%s to run outside 32-bit space \n " ,
! lpae ? __stringify ( CONFIG_ARM_LPAE ) : " " ,
( ! lpae & & ! pvpatch ) ? " and " : " " ,
! pvpatch ? __stringify ( CONFIG_ARM_PATCH_PHYS_VIRT ) : " " ) ;
}
if ( mem_start < KEYSTONE_HIGH_PHYS_START | |
mem_end > KEYSTONE_HIGH_PHYS_END ) {
pr_crit ( " Invalid address space for memory (%08llx-%08llx) \n " ,
( u64 ) mem_start , ( u64 ) mem_end ) ;
}
offset + = KEYSTONE_HIGH_PHYS_START ;
__pv_phys_pfn_offset = PFN_DOWN ( offset ) ;
__pv_offset = ( offset - PAGE_OFFSET ) ;
/* Populate the arch idmap hook */
arch_virt_to_idmap = keystone_virt_to_idmap ;
2014-02-24 17:32:59 +02:00
platform_nb . notifier_call = keystone_platform_notifier ;
keystone_dma_pfn_offset = PFN_DOWN ( KEYSTONE_HIGH_PHYS_START -
KEYSTONE_LOW_PHYS_START ) ;
2013-06-13 19:24:39 -04:00
pr_info ( " Switching to high address space at 0x%llx \n " , ( u64 ) offset ) ;
}
2013-06-10 11:27:13 -04:00
static const char * keystone_match [ ] __initconst = {
2014-03-20 17:00:27 -04:00
" ti,keystone " ,
2013-06-10 11:27:13 -04:00
NULL ,
} ;
DT_MACHINE_START ( KEYSTONE , " Keystone " )
2013-11-23 16:58:03 -05:00
# if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
. dma_zone_size = SZ_2G ,
# endif
2013-06-10 12:20:17 -04:00
. smp = smp_ops ( keystone_smp_ops ) ,
2013-06-10 11:27:13 -04:00
. init_machine = keystone_init ,
. dt_compat = keystone_match ,
2013-06-13 19:24:39 -04:00
. init_meminfo = keystone_init_meminfo ,
2013-06-10 11:27:13 -04:00
MACHINE_END