2010-03-25 17:12:41 +03:00
/*
* Copyright 2008 Cavium Networks
*
* This file 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 .
*/
2010-11-23 00:32:43 +08:00
# include <linux/init.h>
# include <linux/module.h>
2010-06-02 14:12:08 +04:00
# include <linux/io.h>
2010-03-25 17:12:41 +03:00
# include <linux/delay.h>
2011-07-26 16:09:06 -07:00
# include <linux/atomic.h>
2010-03-25 17:12:41 +03:00
# include <mach/cns3xxx.h>
2010-11-23 00:32:43 +08:00
# include <mach/pm.h>
2011-11-05 15:32:23 +00:00
# include "core.h"
2010-03-25 17:12:41 +03:00
void cns3xxx_pwr_clk_en ( unsigned int block )
{
2010-06-02 14:12:08 +04:00
u32 reg = __raw_readl ( PM_CLK_GATE_REG ) ;
reg | = ( block & PM_CLK_GATE_REG_MASK ) ;
__raw_writel ( reg , PM_CLK_GATE_REG ) ;
2010-03-25 17:12:41 +03:00
}
2010-11-23 00:32:43 +08:00
EXPORT_SYMBOL ( cns3xxx_pwr_clk_en ) ;
void cns3xxx_pwr_clk_dis ( unsigned int block )
{
u32 reg = __raw_readl ( PM_CLK_GATE_REG ) ;
reg & = ~ ( block & PM_CLK_GATE_REG_MASK ) ;
__raw_writel ( reg , PM_CLK_GATE_REG ) ;
}
EXPORT_SYMBOL ( cns3xxx_pwr_clk_dis ) ;
2010-03-25 17:12:41 +03:00
void cns3xxx_pwr_power_up ( unsigned int block )
{
2010-06-02 14:12:08 +04:00
u32 reg = __raw_readl ( PM_PLL_HM_PD_CTRL_REG ) ;
reg & = ~ ( block & CNS3XXX_PWR_PLL_ALL ) ;
__raw_writel ( reg , PM_PLL_HM_PD_CTRL_REG ) ;
2010-03-25 17:12:41 +03:00
/* Wait for 300us for the PLL output clock locked. */
udelay ( 300 ) ;
} ;
2010-11-23 00:32:43 +08:00
EXPORT_SYMBOL ( cns3xxx_pwr_power_up ) ;
2010-03-25 17:12:41 +03:00
void cns3xxx_pwr_power_down ( unsigned int block )
{
2010-06-02 14:12:08 +04:00
u32 reg = __raw_readl ( PM_PLL_HM_PD_CTRL_REG ) ;
2010-03-25 17:12:41 +03:00
/* write '1' to power down */
2010-06-02 14:12:08 +04:00
reg | = ( block & CNS3XXX_PWR_PLL_ALL ) ;
__raw_writel ( reg , PM_PLL_HM_PD_CTRL_REG ) ;
2010-03-25 17:12:41 +03:00
} ;
2010-11-23 00:32:43 +08:00
EXPORT_SYMBOL ( cns3xxx_pwr_power_down ) ;
2010-03-25 17:12:41 +03:00
static void cns3xxx_pwr_soft_rst_force ( unsigned int block )
{
2010-06-02 14:12:08 +04:00
u32 reg = __raw_readl ( PM_SOFT_RST_REG ) ;
2010-03-25 17:12:41 +03:00
/*
* bit 0 , 28 , 29 = > program low to reset ,
* the other else program low and then high
*/
if ( block & 0x30000001 ) {
2010-06-02 14:12:08 +04:00
reg & = ~ ( block & PM_SOFT_RST_REG_MASK ) ;
2010-03-25 17:12:41 +03:00
} else {
2010-06-02 14:12:08 +04:00
reg & = ~ ( block & PM_SOFT_RST_REG_MASK ) ;
2010-11-26 20:48:35 +03:00
__raw_writel ( reg , PM_SOFT_RST_REG ) ;
2010-06-02 14:12:08 +04:00
reg | = ( block & PM_SOFT_RST_REG_MASK ) ;
2010-03-25 17:12:41 +03:00
}
2010-06-02 14:12:08 +04:00
__raw_writel ( reg , PM_SOFT_RST_REG ) ;
2010-03-25 17:12:41 +03:00
}
2010-11-23 00:32:43 +08:00
EXPORT_SYMBOL ( cns3xxx_pwr_soft_rst_force ) ;
2010-03-25 17:12:41 +03:00
void cns3xxx_pwr_soft_rst ( unsigned int block )
{
static unsigned int soft_reset ;
if ( soft_reset & block ) {
/* SPI/I2C/GPIO use the same block, reset once. */
return ;
} else {
soft_reset | = block ;
}
cns3xxx_pwr_soft_rst_force ( block ) ;
}
2010-11-23 00:32:43 +08:00
EXPORT_SYMBOL ( cns3xxx_pwr_soft_rst ) ;
2010-03-25 17:12:41 +03:00
2011-11-05 15:32:23 +00:00
void cns3xxx_restart ( char mode , const char * cmd )
2010-03-25 17:12:41 +03:00
{
/*
* To reset , we hit the on - board reset register
* in the system FPGA .
*/
cns3xxx_pwr_soft_rst ( CNS3XXX_PWR_SOFTWARE_RST ( GLOBAL ) ) ;
}
/*
* cns3xxx_cpu_clock - return CPU / L2 clock
* aclk : cpu clock / 2
* hclk : cpu clock / 4
* pclk : cpu clock / 8
*/
int cns3xxx_cpu_clock ( void )
{
2010-06-02 14:12:08 +04:00
u32 reg = __raw_readl ( PM_CLK_CTRL_REG ) ;
2010-03-25 17:12:41 +03:00
int cpu ;
int cpu_sel ;
int div_sel ;
2010-06-02 14:12:08 +04:00
cpu_sel = ( reg > > PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL ) & 0xf ;
div_sel = ( reg > > PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV ) & 0x3 ;
2010-03-25 17:12:41 +03:00
cpu = ( 300 + ( ( cpu_sel / 3 ) * 100 ) + ( ( cpu_sel % 3 ) * 33 ) ) > > div_sel ;
return cpu ;
}
2010-11-23 00:32:43 +08:00
EXPORT_SYMBOL ( cns3xxx_cpu_clock ) ;
2010-11-23 00:32:44 +08:00
atomic_t usb_pwr_ref = ATOMIC_INIT ( 0 ) ;
EXPORT_SYMBOL ( usb_pwr_ref ) ;