2015-06-24 08:17:02 +02:00
/*
* Copyright ( c ) 2015 Pengutronix , Sascha Hauer < kernel @ pengutronix . de >
*
* 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 .
*/
# include <linux/export.h>
# include <linux/jiffies.h>
# include <linux/regmap.h>
# include <linux/soc/mediatek/infracfg.h>
# include <asm/processor.h>
2018-04-23 14:42:45 +08:00
# define MTK_POLL_DELAY_US 10
# define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
2015-06-24 08:17:02 +02:00
# define INFRA_TOPAXI_PROTECTEN 0x0220
# define INFRA_TOPAXI_PROTECTSTA1 0x0228
2017-11-28 15:28:18 +08:00
# define INFRA_TOPAXI_PROTECTEN_SET 0x0260
# define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
2015-06-24 08:17:02 +02:00
/**
* mtk_infracfg_set_bus_protection - enable bus protection
* @ regmap : The infracfg regmap
* @ mask : The mask containing the protection bits to be enabled .
2017-11-28 15:28:18 +08:00
* @ reg_update : The boolean flag determines to set the protection bits
* by regmap_update_bits with enable register ( PROTECTEN ) or
* by regmap_write with set register ( PROTECTEN_SET ) .
2015-06-24 08:17:02 +02:00
*
* This function enables the bus protection bits for disabled power
* domains so that the system does not hang when some unit accesses the
* bus while in power down .
*/
2017-11-28 15:28:18 +08:00
int mtk_infracfg_set_bus_protection ( struct regmap * infracfg , u32 mask ,
bool reg_update )
2015-06-24 08:17:02 +02:00
{
u32 val ;
int ret ;
2017-11-28 15:28:18 +08:00
if ( reg_update )
regmap_update_bits ( infracfg , INFRA_TOPAXI_PROTECTEN , mask ,
mask ) ;
else
regmap_write ( infracfg , INFRA_TOPAXI_PROTECTEN_SET , mask ) ;
2015-06-24 08:17:02 +02:00
2018-04-23 14:42:45 +08:00
ret = regmap_read_poll_timeout ( infracfg , INFRA_TOPAXI_PROTECTSTA1 ,
val , ( val & mask ) = = mask ,
MTK_POLL_DELAY_US , MTK_POLL_TIMEOUT ) ;
2015-06-24 08:17:02 +02:00
2018-04-23 14:42:45 +08:00
return ret ;
2015-06-24 08:17:02 +02:00
}
/**
* mtk_infracfg_clear_bus_protection - disable bus protection
* @ regmap : The infracfg regmap
* @ mask : The mask containing the protection bits to be disabled .
2017-11-28 15:28:18 +08:00
* @ reg_update : The boolean flag determines to clear the protection bits
* by regmap_update_bits with enable register ( PROTECTEN ) or
* by regmap_write with clear register ( PROTECTEN_CLR ) .
2015-06-24 08:17:02 +02:00
*
* This function disables the bus protection bits previously enabled with
* mtk_infracfg_set_bus_protection .
*/
2017-11-28 15:28:18 +08:00
int mtk_infracfg_clear_bus_protection ( struct regmap * infracfg , u32 mask ,
bool reg_update )
2015-06-24 08:17:02 +02:00
{
int ret ;
2018-04-23 14:42:45 +08:00
u32 val ;
2015-06-24 08:17:02 +02:00
2017-11-28 15:28:18 +08:00
if ( reg_update )
regmap_update_bits ( infracfg , INFRA_TOPAXI_PROTECTEN , mask , 0 ) ;
else
regmap_write ( infracfg , INFRA_TOPAXI_PROTECTEN_CLR , mask ) ;
2015-06-24 08:17:02 +02:00
2018-04-23 14:42:45 +08:00
ret = regmap_read_poll_timeout ( infracfg , INFRA_TOPAXI_PROTECTSTA1 ,
val , ! ( val & mask ) ,
MTK_POLL_DELAY_US , MTK_POLL_TIMEOUT ) ;
2015-06-24 08:17:02 +02:00
2018-04-23 14:42:45 +08:00
return ret ;
2015-06-24 08:17:02 +02:00
}