2011-05-09 20:56:46 +04:00
/*
* Broadcom specific AMBA
* Core ops
*
* Licensed under the GNU / GPL . See COPYING for details .
*/
# include "bcma_private.h"
2011-07-28 05:21:04 +04:00
# include <linux/export.h>
2011-05-09 20:56:46 +04:00
# include <linux/bcma/bcma.h>
2013-06-17 20:34:32 +04:00
static bool bcma_core_wait_value ( struct bcma_device * core , u16 reg , u32 mask ,
u32 value , int timeout )
{
unsigned long deadline = jiffies + timeout ;
u32 val ;
do {
val = bcma_aread32 ( core , reg ) ;
if ( ( val & mask ) = = value )
return true ;
cpu_relax ( ) ;
udelay ( 10 ) ;
} while ( ! time_after_eq ( jiffies , deadline ) ) ;
bcma_warn ( core - > bus , " Timeout waiting for register 0x%04X! \n " , reg ) ;
return false ;
}
2011-05-09 20:56:46 +04:00
bool bcma_core_is_enabled ( struct bcma_device * core )
{
if ( ( bcma_aread32 ( core , BCMA_IOCTL ) & ( BCMA_IOCTL_CLK | BCMA_IOCTL_FGC ) )
! = BCMA_IOCTL_CLK )
return false ;
if ( bcma_aread32 ( core , BCMA_RESET_CTL ) & BCMA_RESET_CTL_RESET )
return false ;
return true ;
}
EXPORT_SYMBOL_GPL ( bcma_core_is_enabled ) ;
2011-06-09 22:07:20 +04:00
void bcma_core_disable ( struct bcma_device * core , u32 flags )
2011-05-09 20:56:46 +04:00
{
if ( bcma_aread32 ( core , BCMA_RESET_CTL ) & BCMA_RESET_CTL_RESET )
return ;
2013-06-17 20:34:32 +04:00
bcma_core_wait_value ( core , BCMA_RESET_ST , ~ 0 , 0 , 300 ) ;
2011-05-09 20:56:46 +04:00
bcma_awrite32 ( core , BCMA_RESET_CTL , BCMA_RESET_CTL_RESET ) ;
2012-05-05 08:56:36 +04:00
bcma_aread32 ( core , BCMA_RESET_CTL ) ;
2011-05-09 20:56:46 +04:00
udelay ( 1 ) ;
2013-06-17 20:34:32 +04:00
bcma_awrite32 ( core , BCMA_IOCTL , flags ) ;
bcma_aread32 ( core , BCMA_IOCTL ) ;
udelay ( 10 ) ;
2011-05-09 20:56:46 +04:00
}
2011-06-09 22:07:20 +04:00
EXPORT_SYMBOL_GPL ( bcma_core_disable ) ;
2011-05-09 20:56:46 +04:00
int bcma_core_enable ( struct bcma_device * core , u32 flags )
{
bcma_core_disable ( core , flags ) ;
bcma_awrite32 ( core , BCMA_IOCTL , ( BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags ) ) ;
bcma_aread32 ( core , BCMA_IOCTL ) ;
bcma_awrite32 ( core , BCMA_RESET_CTL , 0 ) ;
2013-06-17 20:34:32 +04:00
bcma_aread32 ( core , BCMA_RESET_CTL ) ;
2011-05-09 20:56:46 +04:00
udelay ( 1 ) ;
bcma_awrite32 ( core , BCMA_IOCTL , ( BCMA_IOCTL_CLK | flags ) ) ;
bcma_aread32 ( core , BCMA_IOCTL ) ;
udelay ( 1 ) ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( bcma_core_enable ) ;
2011-07-17 03:06:04 +04:00
void bcma_core_set_clockmode ( struct bcma_device * core ,
enum bcma_clkmode clkmode )
{
u16 i ;
WARN_ON ( core - > id . id ! = BCMA_CORE_CHIPCOMMON & &
core - > id . id ! = BCMA_CORE_PCIE & &
core - > id . id ! = BCMA_CORE_80211 ) ;
switch ( clkmode ) {
case BCMA_CLKMODE_FAST :
bcma_set32 ( core , BCMA_CLKCTLST , BCMA_CLKCTLST_FORCEHT ) ;
2012-09-25 12:17:22 +04:00
usleep_range ( 64 , 300 ) ;
2011-07-17 03:06:04 +04:00
for ( i = 0 ; i < 1500 ; i + + ) {
if ( bcma_read32 ( core , BCMA_CLKCTLST ) &
BCMA_CLKCTLST_HAVEHT ) {
i = 0 ;
break ;
}
udelay ( 10 ) ;
}
if ( i )
2012-07-06 00:07:32 +04:00
bcma_err ( core - > bus , " HT force timeout \n " ) ;
2011-07-17 03:06:04 +04:00
break ;
case BCMA_CLKMODE_DYNAMIC :
2012-04-29 04:18:49 +04:00
bcma_set32 ( core , BCMA_CLKCTLST , ~ BCMA_CLKCTLST_FORCEHT ) ;
2011-07-17 03:06:04 +04:00
break ;
}
}
EXPORT_SYMBOL_GPL ( bcma_core_set_clockmode ) ;
2011-07-17 03:06:05 +04:00
void bcma_core_pll_ctl ( struct bcma_device * core , u32 req , u32 status , bool on )
{
u16 i ;
WARN_ON ( req & ~ BCMA_CLKCTLST_EXTRESREQ ) ;
WARN_ON ( status & ~ BCMA_CLKCTLST_EXTRESST ) ;
if ( on ) {
bcma_set32 ( core , BCMA_CLKCTLST , req ) ;
for ( i = 0 ; i < 10000 ; i + + ) {
if ( ( bcma_read32 ( core , BCMA_CLKCTLST ) & status ) = =
status ) {
i = 0 ;
break ;
}
udelay ( 10 ) ;
}
if ( i )
2012-07-06 00:07:32 +04:00
bcma_err ( core - > bus , " PLL enable timeout \n " ) ;
2011-07-17 03:06:05 +04:00
} else {
2013-02-26 13:02:23 +04:00
/*
* Mask the PLL but don ' t wait for it to be disabled . PLL may be
* shared between cores and will be still up if there is another
* core using it .
*/
bcma_mask32 ( core , BCMA_CLKCTLST , ~ req ) ;
bcma_read32 ( core , BCMA_CLKCTLST ) ;
2011-07-17 03:06:05 +04:00
}
}
EXPORT_SYMBOL_GPL ( bcma_core_pll_ctl ) ;
2011-07-20 21:52:15 +04:00
u32 bcma_core_dma_translation ( struct bcma_device * core )
{
switch ( core - > bus - > hosttype ) {
2011-07-23 03:20:08 +04:00
case BCMA_HOSTTYPE_SOC :
return 0 ;
2011-07-20 21:52:15 +04:00
case BCMA_HOSTTYPE_PCI :
if ( bcma_aread32 ( core , BCMA_IOST ) & BCMA_IOST_DMA64 )
return BCMA_DMA_TRANSLATION_DMA64_CMT ;
else
return BCMA_DMA_TRANSLATION_DMA32_CMT ;
default :
2012-07-06 00:07:32 +04:00
bcma_err ( core - > bus , " DMA translation unknown for host %d \n " ,
core - > bus - > hosttype ) ;
2011-07-20 21:52:15 +04:00
}
return BCMA_DMA_TRANSLATION_NONE ;
}
EXPORT_SYMBOL ( bcma_core_dma_translation ) ;