@ -30,6 +30,8 @@ struct sti_reset {
* @ reset_bit : Bit number in reset register .
* @ ack_offset : Ack reset register offset in syscon bank .
* @ ack_bit : Bit number in Ack reset register .
* @ deassert_cnt : incremented when reset is deasserted , reset can only be
* asserted when equal to 0
*/
struct syscfg_reset_channel_data {
@ -38,6 +40,7 @@ struct syscfg_reset_channel_data {
int reset_bit ;
int ack_offset ;
int ack_bit ;
int deassert_cnt ;
} ;
/**
@ -54,7 +57,7 @@ struct syscfg_reset_controller_data {
bool wait_for_ack ;
bool active_low ;
int nr_channels ;
const struct syscfg_reset_channel_data * channels ;
struct syscfg_reset_channel_data * channels ;
} ;
/* STiH407 Peripheral powerdown definitions. */
@ -102,7 +105,7 @@ static const char stih407_lpm[] = "st,stih407-lpm-syscfg";
# define SYSSTAT_4520 0x820
# define SYSCFG_4002 0x8
static const struct syscfg_reset_channel_data stih407_powerdowns [ ] = {
static struct syscfg_reset_channel_data stih407_powerdowns [ ] = {
[ STIH407_EMISS_POWERDOWN ] = STIH407_PDN_0 ( 1 ) ,
[ STIH407_NAND_POWERDOWN ] = STIH407_PDN_0 ( 0 ) ,
[ STIH407_USB3_POWERDOWN ] = STIH407_PDN_1 ( 6 ) ,
@ -122,7 +125,7 @@ static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
# define LPM_SYSCFG_1 0x4 /* Softreset IRB & SBC UART */
static const struct syscfg_reset_channel_data stih407_softresets [ ] = {
static struct syscfg_reset_channel_data stih407_softresets [ ] = {
[ STIH407_ETH1_SOFTRESET ] = STIH407_SRST_SBC ( SYSCFG_4002 , 4 ) ,
[ STIH407_MMC1_SOFTRESET ] = STIH407_SRST_CORE ( SYSCFG_5132 , 3 ) ,
[ STIH407_USB2_PORT0_SOFTRESET ] = STIH407_SRST_CORE ( SYSCFG_5132 , 28 ) ,
@ -161,7 +164,7 @@ static const struct syscfg_reset_channel_data stih407_softresets[] = {
/* PicoPHY reset/control */
# define SYSCFG_5061 0x0f4
static const struct syscfg_reset_channel_data stih407_picophyresets [ ] = {
static struct syscfg_reset_channel_data stih407_picophyresets [ ] = {
[ STIH407_PICOPHY0_RESET ] = STIH407_SRST_CORE ( SYSCFG_5061 , 5 ) ,
[ STIH407_PICOPHY1_RESET ] = STIH407_SRST_CORE ( SYSCFG_5061 , 6 ) ,
[ STIH407_PICOPHY2_RESET ] = STIH407_SRST_CORE ( SYSCFG_5061 , 7 ) ,
@ -223,7 +226,7 @@ static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert)
struct udevice * dev = reset_ctl - > dev ;
struct syscfg_reset_controller_data * reset_desc =
( struct syscfg_reset_controller_data * ) ( dev - > driver_data ) ;
struct syscfg_reset_channel_data ch ;
struct syscfg_reset_channel_data * ch ;
phys_addr_t base ;
u32 ctrl_val = reset_desc - > active_low ? ! assert : ! ! assert ;
void __iomem * reg ;
@ -235,19 +238,35 @@ static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert)
/* get reset sysconf register base address */
base = sti_reset_get_regmap ( reset_desc - > channels [ reset_ctl - > id ] . compatible ) ;
ch = reset_desc - > channels [ reset_ctl - > id ] ;
reg = ( void __iomem * ) base + ch . reset_offset ;
ch = & reset_desc - > channels [ reset_ctl - > id ] ;
/* check the deassert counter to assert reset when it reaches 0 */
if ( ! assert ) {
ch - > deassert_cnt + + ;
if ( ch - > deassert_cnt > 1 )
return 0 ;
} else {
if ( ch - > deassert_cnt > 0 ) {
ch - > deassert_cnt - - ;
if ( ch - > deassert_cnt > 0 )
return 0 ;
} else
error ( " Reset balancing error: reset_ctl=%p dev=%p id=%lu \n " ,
reset_ctl , reset_ctl - > dev , reset_ctl - > id ) ;
}
reg = ( void __iomem * ) base + ch - > reset_offset ;
if ( ctrl_val )
generic_set_bit ( ch . reset_bit , reg ) ;
generic_set_bit ( ch - > reset_bit , reg ) ;
else
generic_clear_bit ( ch . reset_bit , reg ) ;
generic_clear_bit ( ch - > reset_bit , reg ) ;
if ( ! reset_desc - > wait_for_ack )
return 0 ;
reg = ( void __iomem * ) base + ch . ack_offset ;
if ( wait_for_bit ( __func__ , reg , BIT ( ch . ack_bit ) , ctrl_val ,
reg = ( void __iomem * ) base + ch - > ack_offset ;
if ( wait_for_bit ( __func__ , reg , BIT ( ch - > ack_bit ) , ctrl_val ,
1000 , false ) ) {
error ( " Stuck on waiting ack reset_ctl=%p dev=%p id=%lu \n " ,
reset_ctl , reset_ctl - > dev , reset_ctl - > id ) ;