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
*
* The code contained herein is licensed under the GNU General Public
* License . You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations :
*
* http : //www.opensource.org/licenses/gpl-license.html
* http : //www.gnu.org/copyleft/gpl.html
*
* 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>
2010-02-04 23:21:53 +03:00
# include <mach/hardware.h>
# include <asm/io.h>
2010-03-19 12:50:55 +03:00
static int cpu_silicon_rev = - 1 ;
# define SI_REV 0x48
static void query_silicon_parameter ( void )
{
void __iomem * rom = ioremap ( MX51_IROM_BASE_ADDR , MX51_IROM_SIZE ) ;
u32 rev ;
if ( ! rom ) {
cpu_silicon_rev = - EINVAL ;
return ;
}
rev = readl ( rom + SI_REV ) ;
switch ( rev ) {
case 0x1 :
cpu_silicon_rev = MX51_CHIP_REV_1_0 ;
break ;
case 0x2 :
cpu_silicon_rev = MX51_CHIP_REV_1_1 ;
break ;
case 0x10 :
cpu_silicon_rev = MX51_CHIP_REV_2_0 ;
break ;
case 0x20 :
cpu_silicon_rev = MX51_CHIP_REV_3_0 ;
break ;
default :
cpu_silicon_rev = 0 ;
}
iounmap ( rom ) ;
}
/*
* Returns :
* the silicon revision of the cpu
* - EINVAL - not a mx51
*/
int mx51_revision ( void )
{
if ( ! cpu_is_mx51 ( ) )
return - EINVAL ;
if ( cpu_silicon_rev = = - 1 )
query_silicon_parameter ( ) ;
return cpu_silicon_rev ;
}
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 .
*/
static int __init mx51_neon_fixup ( void )
{
2010-11-05 01:08:17 +03:00
if ( ! cpu_is_mx51 ( ) )
return 0 ;
2010-09-01 23:49:13 +04:00
if ( mx51_revision ( ) < MX51_CHIP_REV_3_0 & & ( elf_hwcap & HWCAP_NEON ) ) {
elf_hwcap & = ~ HWCAP_NEON ;
pr_info ( " Turning off NEON support, detected broken NEON implementation \n " ) ;
}
return 0 ;
}
late_initcall ( mx51_neon_fixup ) ;
# endif
2010-11-15 20:30:00 +03:00
/*
* Returns :
* the silicon revision of the cpu
* - EINVAL - not a mx53
*/
int mx53_revision ( void )
{
if ( ! cpu_is_mx53 ( ) )
return - EINVAL ;
if ( cpu_silicon_rev = = - 1 )
query_silicon_parameter ( ) ;
return cpu_silicon_rev ;
}
EXPORT_SYMBOL ( mx53_revision ) ;
2010-02-04 23:21:53 +03:00
static int __init post_cpu_init ( void )
{
unsigned int reg ;
void __iomem * base ;
2010-11-15 20:29:59 +03:00
if ( cpu_is_mx51 ( ) | | cpu_is_mx53 ( ) ) {
if ( cpu_is_mx51 ( ) )
base = MX51_IO_ADDRESS ( MX51_AIPS1_BASE_ADDR ) ;
else
base = MX53_IO_ADDRESS ( MX53_AIPS1_BASE_ADDR ) ;
__raw_writel ( 0x0 , base + 0x40 ) ;
__raw_writel ( 0x0 , base + 0x44 ) ;
__raw_writel ( 0x0 , base + 0x48 ) ;
__raw_writel ( 0x0 , base + 0x4C ) ;
reg = __raw_readl ( base + 0x50 ) & 0x00FFFFFF ;
__raw_writel ( reg , base + 0x50 ) ;
if ( cpu_is_mx51 ( ) )
base = MX51_IO_ADDRESS ( MX51_AIPS2_BASE_ADDR ) ;
else
base = MX53_IO_ADDRESS ( MX53_AIPS2_BASE_ADDR ) ;
__raw_writel ( 0x0 , base + 0x40 ) ;
__raw_writel ( 0x0 , base + 0x44 ) ;
__raw_writel ( 0x0 , base + 0x48 ) ;
__raw_writel ( 0x0 , base + 0x4C ) ;
reg = __raw_readl ( base + 0x50 ) & 0x00FFFFFF ;
__raw_writel ( reg , base + 0x50 ) ;
}
2010-02-04 23:21:53 +03:00
return 0 ;
}
postcore_initcall ( post_cpu_init ) ;