2019-05-27 09:55:08 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-02-04 23:21:53 +03:00
/*
2010-11-15 20:30:00 +03:00
* Copyright 2008 - 2010 Freescale Semiconductor , Inc . All Rights Reserved .
2010-02-04 23:21:53 +03:00
*
* This file contains the CPU initialization code .
*/
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/init.h>
2010-03-19 12:50:55 +03:00
# include <linux/module.h>
2011-11-21 22:26:52 +04:00
# include <linux/io.h>
2014-05-19 18:23:43 +04:00
# include <linux/of.h>
# include <linux/of_address.h>
2010-02-04 23:21:53 +03:00
2012-09-14 10:14:45 +04:00
# include "hardware.h"
2013-03-25 16:20:31 +04:00
# include "common.h"
2012-09-14 10:14:45 +04:00
2011-08-26 09:35:23 +04:00
static int mx5_cpu_rev = - 1 ;
2010-03-19 12:50:55 +03:00
2010-11-15 20:30:01 +03:00
# define IIM_SREV 0x24
2010-03-19 12:50:55 +03:00
2014-05-19 18:23:43 +04:00
static u32 imx5_read_srev_reg ( const char * compat )
{
void __iomem * iim_base ;
struct device_node * np ;
u32 srev ;
np = of_find_compatible_node ( NULL , NULL , compat ) ;
iim_base = of_iomap ( np , 0 ) ;
WARN_ON ( ! iim_base ) ;
srev = readl ( iim_base + IIM_SREV ) & 0xff ;
iounmap ( iim_base ) ;
return srev ;
}
2010-11-15 20:30:01 +03:00
static int get_mx51_srev ( void )
2010-03-19 12:50:55 +03:00
{
2014-05-19 18:23:43 +04:00
u32 rev = imx5_read_srev_reg ( " fsl,imx51-iim " ) ;
2010-03-19 12:50:55 +03:00
2011-08-26 09:35:23 +04:00
switch ( rev ) {
case 0x0 :
2010-11-15 20:30:01 +03:00
return IMX_CHIP_REVISION_2_0 ;
2011-08-26 09:35:23 +04:00
case 0x10 :
2010-11-15 20:30:01 +03:00
return IMX_CHIP_REVISION_3_0 ;
2011-08-26 09:35:23 +04:00
default :
return IMX_CHIP_REVISION_UNKNOWN ;
}
2010-03-19 12:50:55 +03:00
}
/*
* Returns :
* the silicon revision of the cpu
*/
int mx51_revision ( void )
{
2011-08-26 09:35:23 +04:00
if ( mx5_cpu_rev = = - 1 )
mx5_cpu_rev = get_mx51_srev ( ) ;
2010-03-19 12:50:55 +03:00
2011-08-26 09:35:23 +04:00
return mx5_cpu_rev ;
2010-03-19 12:50:55 +03:00
}
EXPORT_SYMBOL ( mx51_revision ) ;
2010-09-01 23:49:13 +04:00
# ifdef CONFIG_NEON
/*
* All versions of the silicon before Rev . 3 have broken NEON implementations .
* Dependent on link order - so the assumption is that vfp_init is called
* before us .
*/
2012-04-26 07:42:34 +04:00
int __init mx51_neon_fixup ( void )
2010-09-01 23:49:13 +04:00
{
2011-11-21 22:26:52 +04:00
if ( mx51_revision ( ) < IMX_CHIP_REVISION_3_0 & &
( elf_hwcap & HWCAP_NEON ) ) {
2010-09-01 23:49:13 +04:00
elf_hwcap & = ~ HWCAP_NEON ;
pr_info ( " Turning off NEON support, detected broken NEON implementation \n " ) ;
}
return 0 ;
}
# endif
2010-11-15 20:30:01 +03:00
static int get_mx53_srev ( void )
{
2014-05-19 18:23:43 +04:00
u32 rev = imx5_read_srev_reg ( " fsl,imx53-iim " ) ;
2010-11-15 20:30:01 +03:00
2011-02-18 15:26:30 +03:00
switch ( rev ) {
case 0x0 :
2010-11-15 20:30:01 +03:00
return IMX_CHIP_REVISION_1_0 ;
2011-02-18 15:26:30 +03:00
case 0x2 :
2010-11-15 20:30:01 +03:00
return IMX_CHIP_REVISION_2_0 ;
2011-02-18 15:26:30 +03:00
case 0x3 :
return IMX_CHIP_REVISION_2_1 ;
default :
return IMX_CHIP_REVISION_UNKNOWN ;
}
2010-11-15 20:30:01 +03:00
}
2010-11-15 20:30:00 +03:00
/*
* Returns :
* the silicon revision of the cpu
*/
int mx53_revision ( void )
{
2011-08-26 09:35:23 +04:00
if ( mx5_cpu_rev = = - 1 )
mx5_cpu_rev = get_mx53_srev ( ) ;
2010-11-15 20:30:00 +03:00
2011-08-26 09:35:23 +04:00
return mx5_cpu_rev ;
2010-11-15 20:30:00 +03:00
}
EXPORT_SYMBOL ( mx53_revision ) ;
2018-07-10 19:31:48 +03:00
# define ARM_GPC 0x4
# define DBGEN BIT(16)
/*
* This enables the DBGEN bit in ARM_GPC register , which is
* required for accessing some performance counter features .
* Technically it is only required while perf is used , but to
* keep the source code simple we just enable it all the time
* when the kernel configuration allows using the feature .
*/
void __init imx5_pmu_init ( void )
{
void __iomem * tigerp_base ;
struct device_node * np ;
u32 gpc ;
if ( ! IS_ENABLED ( CONFIG_ARM_PMU ) )
return ;
np = of_find_compatible_node ( NULL , NULL , " arm,cortex-a8-pmu " ) ;
if ( ! np )
return ;
if ( ! of_property_read_bool ( np , " secure-reg-access " ) )
goto exit ;
of_node_put ( np ) ;
np = of_find_compatible_node ( NULL , NULL , " fsl,imx51-tigerp " ) ;
if ( ! np )
return ;
tigerp_base = of_iomap ( np , 0 ) ;
if ( ! tigerp_base )
goto exit ;
gpc = readl_relaxed ( tigerp_base + ARM_GPC ) ;
gpc | = DBGEN ;
writel_relaxed ( gpc , tigerp_base + ARM_GPC ) ;
iounmap ( tigerp_base ) ;
exit :
of_node_put ( np ) ;
}