2006-11-28 00:16:28 +03:00
/*
* Freescale Lite5200 board support
*
* Written by : Grant Likely < grant . likely @ secretlab . ca >
*
* Copyright ( C ) Secret Lab Technologies Ltd . 2006. All rights reserved .
* Copyright ( C ) Freescale Semicondutor , Inc . 2006. All rights reserved .
*
* Description :
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*/
# undef DEBUG
# include <linux/init.h>
# include <linux/pci.h>
2007-10-10 19:52:00 +04:00
# include <linux/of.h>
2010-07-29 21:49:01 +04:00
# include <linux/of_address.h>
2007-10-13 22:40:08 +04:00
# include <linux/root_dev.h>
# include <linux/initrd.h>
2006-11-28 00:16:28 +03:00
# include <asm/time.h>
# include <asm/io.h>
# include <asm/machdep.h>
# include <asm/prom.h>
# include <asm/mpc52xx.h>
/* ************************************************************************
*
* Setup the architecture
*
*/
2008-01-25 08:25:31 +03:00
/* mpc5200 device tree match tables */
static struct of_device_id mpc5200_cdm_ids [ ] __initdata = {
{ . compatible = " fsl,mpc5200-cdm " , } ,
{ . compatible = " mpc5200-cdm " , } ,
{ }
} ;
static struct of_device_id mpc5200_gpio_ids [ ] __initdata = {
{ . compatible = " fsl,mpc5200-gpio " , } ,
{ . compatible = " mpc5200-gpio " , } ,
{ }
} ;
2007-10-10 00:45:28 +04:00
/*
* Fix clock configuration .
*
* Firmware is supposed to be responsible for this . If you are creating a
* new board port , do * NOT * duplicate this code . Fix your boot firmware
* to set it correctly in the first place
*/
2006-11-28 00:16:28 +03:00
static void __init
2007-10-10 00:45:28 +04:00
lite5200_fix_clock_config ( void )
{
2008-01-18 19:30:37 +03:00
struct device_node * np ;
2007-10-10 00:45:28 +04:00
struct mpc52xx_cdm __iomem * cdm ;
/* Map zones */
2008-01-25 08:25:31 +03:00
np = of_find_matching_node ( NULL , mpc5200_cdm_ids ) ;
2008-01-18 19:30:37 +03:00
cdm = of_iomap ( np , 0 ) ;
of_node_put ( np ) ;
2007-10-10 00:45:28 +04:00
if ( ! cdm ) {
printk ( KERN_ERR " %s() failed; expect abnormal behaviour \n " ,
2008-03-29 00:21:07 +03:00
__func__ ) ;
2007-10-10 00:45:28 +04:00
return ;
}
/* Use internal 48 Mhz */
out_8 ( & cdm - > ext_48mhz_en , 0x00 ) ;
out_8 ( & cdm - > fd_enable , 0x01 ) ;
if ( in_be32 ( & cdm - > rstcfg ) & 0x40 ) /* Assumes 33Mhz clock */
out_be16 ( & cdm - > fd_counters , 0x0001 ) ;
else
out_be16 ( & cdm - > fd_counters , 0x5555 ) ;
/* Unmap the regs */
iounmap ( cdm ) ;
}
/*
* Fix setting of port_config register .
*
* Firmware is supposed to be responsible for this . If you are creating a
* new board port , do * NOT * duplicate this code . Fix your boot firmware
* to set it correctly in the first place
*/
static void __init
lite5200_fix_port_config ( void )
2006-11-28 00:16:28 +03:00
{
2008-01-18 19:30:37 +03:00
struct device_node * np ;
2006-11-28 00:16:28 +03:00
struct mpc52xx_gpio __iomem * gpio ;
u32 port_config ;
2008-01-25 08:25:31 +03:00
np = of_find_matching_node ( NULL , mpc5200_gpio_ids ) ;
2008-01-18 19:30:37 +03:00
gpio = of_iomap ( np , 0 ) ;
of_node_put ( np ) ;
2006-11-28 00:16:28 +03:00
if ( ! gpio ) {
2007-10-10 00:45:28 +04:00
printk ( KERN_ERR " %s() failed. expect abnormal behavior \n " ,
2008-03-29 00:21:07 +03:00
__func__ ) ;
2007-10-10 00:45:28 +04:00
return ;
2006-11-28 00:16:28 +03:00
}
/* Set port config */
port_config = in_be32 ( & gpio - > port_config ) ;
port_config & = ~ 0x00800000 ; /* 48Mhz internal, pin is GPIO */
port_config & = ~ 0x00007000 ; /* USB port : Differential mode */
port_config | = 0x00001000 ; /* USB 1 only */
port_config & = ~ 0x03000000 ; /* ATA CS is on csb_4/5 */
port_config | = 0x01000000 ;
pr_debug ( " port_config: old:%x new:%x \n " ,
in_be32 ( & gpio - > port_config ) , port_config ) ;
out_be32 ( & gpio - > port_config , port_config ) ;
/* Unmap zone */
iounmap ( gpio ) ;
}
2007-05-06 19:38:52 +04:00
# ifdef CONFIG_PM
static void lite5200_suspend_prepare ( void __iomem * mbar )
{
u8 pin = 1 ; /* GPIO_WKUP_1 (GPIO_PSC2_4) */
u8 level = 0 ; /* wakeup on low level */
mpc52xx_set_wakeup_gpio ( pin , level ) ;
/*
* power down usb port
* this needs to be called before of - ohci suspend code
*/
2007-07-18 00:32:31 +04:00
/* set ports to "power switched" and "powered at the same time"
* USB Rh descriptor A : NPS = 0 , PSM = 0 */
out_be32 ( mbar + 0x1048 , in_be32 ( mbar + 0x1048 ) & ~ 0x300 ) ;
/* USB Rh status: LPS = 1 - turn off power */
out_be32 ( mbar + 0x1050 , 0x00000001 ) ;
2007-05-06 19:38:52 +04:00
}
static void lite5200_resume_finish ( void __iomem * mbar )
{
2007-07-18 00:32:31 +04:00
/* USB Rh status: LPSC = 1 - turn on power */
out_be32 ( mbar + 0x1050 , 0x00010000 ) ;
2007-05-06 19:38:52 +04:00
}
# endif
2007-02-12 23:36:55 +03:00
static void __init lite5200_setup_arch ( void )
2006-11-28 00:16:28 +03:00
{
if ( ppc_md . progress )
2007-02-12 23:36:55 +03:00
ppc_md . progress ( " lite5200_setup_arch() " , 0 ) ;
2006-11-28 00:16:28 +03:00
2008-01-25 08:25:31 +03:00
/* Map important registers from the internal memory map */
mpc52xx_map_common_devices ( ) ;
2007-10-10 00:45:28 +04:00
/* Some mpc5200 & mpc5200b related configuration */
mpc5200_setup_xlb_arbiter ( ) ;
2006-11-28 00:16:28 +03:00
2008-01-25 08:25:31 +03:00
/* Fix things that firmware should have done. */
lite5200_fix_clock_config ( ) ;
lite5200_fix_port_config ( ) ;
2007-10-18 22:44:39 +04:00
2007-05-06 19:38:52 +04:00
# ifdef CONFIG_PM
mpc52xx_suspend . board_suspend_prepare = lite5200_suspend_prepare ;
mpc52xx_suspend . board_resume_finish = lite5200_resume_finish ;
2007-07-18 00:32:31 +04:00
lite5200_pm_init ( ) ;
2007-05-06 19:38:52 +04:00
# endif
2007-11-09 20:11:56 +03:00
mpc52xx_setup_pci ( ) ;
2006-11-28 00:16:28 +03:00
}
2010-10-30 19:49:09 +04:00
static const char * board [ ] __initdata = {
" fsl,lite5200 " ,
" fsl,lite5200b " ,
NULL ,
} ;
2006-11-28 00:16:28 +03:00
/*
* Called very early , MMU is off , device - tree isn ' t unflattened
*/
2007-02-12 23:36:55 +03:00
static int __init lite5200_probe ( void )
2006-11-28 00:16:28 +03:00
{
2010-10-30 19:49:09 +04:00
return of_flat_dt_match ( of_get_flat_dt_root ( ) , board ) ;
2006-11-28 00:16:28 +03:00
}
2007-02-12 23:36:55 +03:00
define_machine ( lite5200 ) {
. name = " lite5200 " ,
. probe = lite5200_probe ,
. setup_arch = lite5200_setup_arch ,
2007-01-03 01:29:53 +03:00
. init = mpc52xx_declare_of_platform_devices ,
2006-11-28 00:16:28 +03:00
. init_IRQ = mpc52xx_init_irq ,
. get_irq = mpc52xx_get_irq ,
2007-10-18 22:44:39 +04:00
. restart = mpc52xx_restart ,
2006-11-28 00:16:28 +03:00
. calibrate_decr = generic_calibrate_decr ,
} ;