2015-09-14 12:09:34 -07:00
/*
* Broadcom STB SoCs Bus Unit Interface controls
*
* Copyright ( C ) 2015 , Broadcom Corporation
*
* This program 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 .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# define pr_fmt(fmt) "brcmstb: " KBUILD_MODNAME ": " fmt
# include <linux/kernel.h>
# include <linux/io.h>
# include <linux/of_address.h>
# include <linux/syscore_ops.h>
2016-06-07 18:54:54 +01:00
# include <linux/soc/brcmstb/brcmstb.h>
2015-09-14 12:09:34 -07:00
# define CPU_CREDIT_REG_OFFSET 0x184
# define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000
static void __iomem * cpubiuctrl_base ;
static bool mcp_wr_pairing_en ;
static int __init mcp_write_pairing_set ( void )
{
u32 creds = 0 ;
if ( ! cpubiuctrl_base )
return - 1 ;
creds = readl_relaxed ( cpubiuctrl_base + CPU_CREDIT_REG_OFFSET ) ;
if ( mcp_wr_pairing_en ) {
pr_info ( " MCP: Enabling write pairing \n " ) ;
writel_relaxed ( creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK ,
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET ) ;
} else if ( creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK ) {
pr_info ( " MCP: Disabling write pairing \n " ) ;
writel_relaxed ( creds & ~ CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK ,
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET ) ;
} else {
pr_info ( " MCP: Write pairing already disabled \n " ) ;
}
return 0 ;
}
static int __init setup_hifcpubiuctrl_regs ( void )
{
struct device_node * np ;
int ret = 0 ;
np = of_find_compatible_node ( NULL , NULL , " brcm,brcmstb-cpu-biu-ctrl " ) ;
if ( ! np ) {
pr_err ( " missing BIU control node \n " ) ;
return - ENODEV ;
}
cpubiuctrl_base = of_iomap ( np , 0 ) ;
if ( ! cpubiuctrl_base ) {
pr_err ( " failed to remap BIU control base \n " ) ;
ret = - ENOMEM ;
goto out ;
}
mcp_wr_pairing_en = of_property_read_bool ( np , " brcm,write-pairing " ) ;
out :
of_node_put ( np ) ;
return ret ;
}
# ifdef CONFIG_PM_SLEEP
static u32 cpu_credit_reg_dump ; /* for save/restore */
static int brcmstb_cpu_credit_reg_suspend ( void )
{
if ( cpubiuctrl_base )
cpu_credit_reg_dump =
readl_relaxed ( cpubiuctrl_base + CPU_CREDIT_REG_OFFSET ) ;
return 0 ;
}
static void brcmstb_cpu_credit_reg_resume ( void )
{
if ( cpubiuctrl_base )
writel_relaxed ( cpu_credit_reg_dump ,
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET ) ;
}
static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
. suspend = brcmstb_cpu_credit_reg_suspend ,
. resume = brcmstb_cpu_credit_reg_resume ,
} ;
# endif
void __init brcmstb_biuctrl_init ( void )
{
int ret ;
setup_hifcpubiuctrl_regs ( ) ;
ret = mcp_write_pairing_set ( ) ;
if ( ret ) {
pr_err ( " MCP: Unable to disable write pairing! \n " ) ;
return ;
}
# ifdef CONFIG_PM_SLEEP
register_syscore_ops ( & brcmstb_cpu_credit_syscore_ops ) ;
# endif
}