mxs: Implement common function to setup VDDx
Subsystems (2)
PATCH 1/2 mxs: Implement common function to setup VDDx
Implement common function to setup the VDDIO, VDDD and VDDA voltage. Right now, there are two almost identical functions to setup VDDIO and VDDD, which is prone to breakage. Pull out the differences into constant structure and pass them as an argument to the common function.
Moreover, the function has almost identical loops for setting higher and lower VDDx voltage. Merge these two loops.
--- arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 253 +++++++++------------------ 1 file changed, 83 insertions(+), 170 deletions(-)
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +83 -170
@@ -766,198 +766,112 @@ int mxs_get_vddd_power_source_off(void)return 0 ; } -void mxs_power_set_vddio (uint32_t new_target,uint32_t new_brownout) +struct mxs_vddx_cfg { +uint32_t *reg; +uint8_t step_mV; +uint16_t lowest_mV; +int (*powered_by_linreg)(void ); +uint32_t trg_mask; +uint32_t bo_irq; +uint32_t bo_enirq; +uint32_t bo_offset_mask; +uint32_t bo_offset_offset; +}; + +const struct mxs_vddx_cfg mxs_vddio_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE )-> + hw_power_vddioctrl), + .step_mV =50 , + .lowest_mV =2800 , + .powered_by_linreg = mxs_get_vddio_power_source_off, + .trg_mask =POWER_VDDIOCTRL_TRG_MASK , + .bo_irq =POWER_CTRL_VDDIO_BO_IRQ , + .bo_enirq =POWER_CTRL_ENIRQ_VDDIO_BO , + .bo_offset_mask =POWER_VDDIOCTRL_BO_OFFSET_MASK , + .bo_offset_offset =POWER_VDDIOCTRL_BO_OFFSET_OFFSET , +}; + +const struct mxs_vddx_cfg mxs_vddd_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE )-> + hw_power_vdddctrl), + .step_mV =25 , + .lowest_mV =800 , + .powered_by_linreg = mxs_get_vddd_power_source_off, + .trg_mask =POWER_VDDDCTRL_TRG_MASK , + .bo_irq =POWER_CTRL_VDDD_BO_IRQ , + .bo_enirq =POWER_CTRL_ENIRQ_VDDD_BO , + .bo_offset_mask =POWER_VDDDCTRL_BO_OFFSET_MASK , + .bo_offset_offset =POWER_VDDDCTRL_BO_OFFSET_OFFSET , +}; + +static void mxs_power_set_vddx (const struct mxs_vddx_cfg *cfg, +uint32_t new_target,uint32_t new_brownout) {struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE ;uint32_t cur_target, diff, bo_int =0 ;uint32_t powered_by_linreg =0 ; +int adjust_up, tmp; - new_brownout = (new_target - new_brownout +25 ) /50 ; + new_brownout =DIV_ROUND (new_target - new_brownout, cfg->step_mV); - cur_target =readl (&power_regs->hw_power_vddioctrl); - cur_target &=POWER_VDDIOCTRL_TRG_MASK ; - cur_target *=50 ;/* 50 mV step*/ - cur_target +=2800 ;/* 2800 mV lowest */ + cur_target =readl (cfg->reg); + cur_target &= cfg->trg_mask; + cur_target *= cfg->step_mV; + cur_target += cfg->lowest_mV; - powered_by_linreg =mxs_get_vddio_power_source_off (); -if (new_target > cur_target) { + adjust_up = new_target > cur_target; + powered_by_linreg = cfg->powered_by_linreg (); +if (adjust_up) {if (powered_by_linreg) { - bo_int =readl (&power_regs->hw_power_vddioctrl); -clrbits_le32 (&power_regs->hw_power_vddioctrl, -POWER_CTRL_ENIRQ_VDDIO_BO ); + bo_int =readl (cfg->reg); +clrbits_le32 (cfg->reg, cfg->bo_enirq); } +setbits_le32 (cfg->reg, cfg->bo_offset_mask); + } -setbits_le32 (&power_regs->hw_power_vddioctrl, -POWER_VDDIOCTRL_BO_OFFSET_MASK ); -do { -if (new_target - cur_target >100 ) +do { +if (abs (new_target - cur_target) >100 ) { +if (adjust_up) diff = cur_target +100 ;else - diff = new_target; - - diff -=2800 ; - diff /=50 ; - -clrsetbits_le32 (&power_regs->hw_power_vddioctrl, -POWER_VDDIOCTRL_TRG_MASK , diff); - -if (powered_by_linreg || - (readl (&power_regs->hw_power_sts) & -POWER_STS_VDD5V_GT_VDDIO )) -early_delay (500 ); -else { -while (!(readl (&power_regs->hw_power_sts) & -POWER_STS_DC_OK )) - ; - - } - - cur_target =readl (&power_regs->hw_power_vddioctrl); - cur_target &=POWER_VDDIOCTRL_TRG_MASK ; - cur_target *=50 ;/* 50 mV step*/ - cur_target +=2800 ;/* 2800 mV lowest */ - }while (new_target > cur_target); - -if (powered_by_linreg) { -writel (POWER_CTRL_VDDIO_BO_IRQ , - &power_regs->hw_power_ctrl_clr); -if (bo_int &POWER_CTRL_ENIRQ_VDDIO_BO ) -setbits_le32 (&power_regs->hw_power_vddioctrl, -POWER_CTRL_ENIRQ_VDDIO_BO ); - } - }else { -do { -if (cur_target - new_target >100 ) diff = cur_target -100 ; -else - diff = new_target; - - diff -=2800 ; - diff /=50 ; - -clrsetbits_le32 (&power_regs->hw_power_vddioctrl, -POWER_VDDIOCTRL_TRG_MASK , diff); - -if (powered_by_linreg || - (readl (&power_regs->hw_power_sts) & -POWER_STS_VDD5V_GT_VDDIO )) -early_delay (500 ); -else { -while (!(readl (&power_regs->hw_power_sts) & -POWER_STS_DC_OK )) - ; - - } - - cur_target =readl (&power_regs->hw_power_vddioctrl); - cur_target &=POWER_VDDIOCTRL_TRG_MASK ; - cur_target *=50 ;/* 50 mV step*/ - cur_target +=2800 ;/* 2800 mV lowest */ - }while (new_target < cur_target); - } - -clrsetbits_le32 (&power_regs->hw_power_vddioctrl, -POWER_VDDIOCTRL_BO_OFFSET_MASK , - new_brownout <<POWER_VDDIOCTRL_BO_OFFSET_OFFSET ); -} - -void mxs_power_set_vddd (uint32_t new_target,uint32_t new_brownout) -{ -struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)MXS_POWER_BASE ; -uint32_t cur_target, diff, bo_int =0 ; -uint32_t powered_by_linreg =0 ; - - new_brownout = (new_target - new_brownout +12 ) /25 ; - - cur_target =readl (&power_regs->hw_power_vdddctrl); - cur_target &=POWER_VDDDCTRL_TRG_MASK ; - cur_target *=25 ;/* 25 mV step*/ - cur_target +=800 ;/* 800 mV lowest */ - - powered_by_linreg =mxs_get_vddd_power_source_off (); -if (new_target > cur_target) { -if (powered_by_linreg) { - bo_int =readl (&power_regs->hw_power_vdddctrl); -clrbits_le32 (&power_regs->hw_power_vdddctrl, -POWER_CTRL_ENIRQ_VDDD_BO ); + }else { + diff = new_target; } -setbits_le32 (&power_regs->hw_power_vdddctrl, -POWER_VDDDCTRL_BO_OFFSET_MASK ); - -do { -if (new_target - cur_target >100 ) - diff = cur_target +100 ; -else - diff = new_target; - - diff -=800 ; - diff /=25 ; - -clrsetbits_le32 (&power_regs->hw_power_vdddctrl, -POWER_VDDDCTRL_TRG_MASK , diff); + diff -= cfg->lowest_mV; + diff /= cfg->step_mV; -if (powered_by_linreg || - (readl (&power_regs->hw_power_sts) & -POWER_STS_VDD5V_GT_VDDIO )) -early_delay (500 ); -else { -while (!(readl (&power_regs->hw_power_sts) & -POWER_STS_DC_OK )) - ; +clrsetbits_le32 (cfg->reg, cfg->trg_mask, diff); +if (powered_by_linreg || + (readl (&power_regs->hw_power_sts) & +POWER_STS_VDD5V_GT_VDDIO )) +early_delay (500 ); +else { +for (;;) { + tmp =readl (&power_regs->hw_power_sts); +if (tmp &POWER_STS_DC_OK ) +break ; } - - cur_target =readl (&power_regs->hw_power_vdddctrl); - cur_target &=POWER_VDDDCTRL_TRG_MASK ; - cur_target *=25 ;/* 25 mV step*/ - cur_target +=800 ;/* 800 mV lowest */ - }while (new_target > cur_target); - -if (powered_by_linreg) { -writel (POWER_CTRL_VDDD_BO_IRQ , - &power_regs->hw_power_ctrl_clr); -if (bo_int &POWER_CTRL_ENIRQ_VDDD_BO ) -setbits_le32 (&power_regs->hw_power_vdddctrl, -POWER_CTRL_ENIRQ_VDDD_BO ); } - }else { -do { -if (cur_target - new_target >100 ) - diff = cur_target -100 ; -else - diff = new_target; - diff -=800 ; - diff /=25 ; + cur_target =readl (cfg->reg); + cur_target &= cfg->trg_mask; + cur_target *= cfg->step_mV; + cur_target += cfg->lowest_mV; + }while (new_target > cur_target); -clrsetbits_le32 (&power_regs->hw_power_vdddctrl, -POWER_VDDDCTRL_TRG_MASK , diff); - -if (powered_by_linreg || - (readl (&power_regs->hw_power_sts) & -POWER_STS_VDD5V_GT_VDDIO )) -early_delay (500 ); -else { -while (!(readl (&power_regs->hw_power_sts) & -POWER_STS_DC_OK )) - ; - - } - - cur_target =readl (&power_regs->hw_power_vdddctrl); - cur_target &=POWER_VDDDCTRL_TRG_MASK ; - cur_target *=25 ;/* 25 mV step*/ - cur_target +=800 ;/* 800 mV lowest */ - }while (new_target < cur_target); +if (adjust_up && powered_by_linreg) { +writel (cfg->bo_irq, &power_regs->hw_power_ctrl_clr); +if (bo_int & cfg->bo_enirq) +setbits_le32 (cfg->reg, cfg->bo_enirq); } -clrsetbits_le32 (&power_regs->hw_power_vdddctrl, -POWER_VDDDCTRL_BO_OFFSET_MASK , - new_brownout <<POWER_VDDDCTRL_BO_OFFSET_OFFSET ); +clrsetbits_le32 (cfg->reg, cfg->bo_offset_mask, + new_brownout << cfg->bo_offset_offset); }void mxs_setup_batt_detect (void )
@@ -982,9 +896,8 @@ void mxs_power_init(void)mxs_power_configure_power_source ();mxs_enable_output_rail_protection (); -mxs_power_set_vddio (3300 ,3150 ); - -mxs_power_set_vddd (1350 ,1200 ); +mxs_power_set_vddx (&mxs_vddio_cfg,3300 ,3150 ); +mxs_power_set_vddx (&mxs_vddd_cfg,1350 ,1200 ); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
Signature · 1 line
1.7.10.4
PATCH 2/2 mxs: Properly setup VDDD in power supply setup code
The memory setup code adjusted the VDDD voltage. Remove this adjustment and configure the VDDD voltage correctly in the power supply setup code.
--- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 13 ------------- arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-)
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +0 -13
@@ -171,17 +171,6 @@ void mxs_mem_setup_vdda(void) &power_regs->hw_power_vddactrl); } -void mxs_mem_setup_vddd (void ) -{ -struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)MXS_POWER_BASE ; - -writel ((0x1c <<POWER_VDDDCTRL_TRG_OFFSET ) | - (0x7 <<POWER_VDDDCTRL_BO_OFFSET_OFFSET ) | -POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW , - &power_regs->hw_power_vdddctrl); -} -uint32_t mxs_mem_get_size (void ) {uint32_t sz, da;
@@ -241,8 +230,6 @@ void mxs_mem_init(void)while (!(readl (MXS_DRAM_BASE +0xe8 ) & (1 <<20 ))) ; -mxs_mem_setup_vddd (); -early_delay (10000 );mxs_mem_setup_cpu_and_hbus ();
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +1 -1
@@ -897,7 +897,7 @@ void mxs_power_init(void)mxs_enable_output_rail_protection ();mxs_power_set_vddx (&mxs_vddio_cfg,3300 ,3150 ); -mxs_power_set_vddx (&mxs_vddd_cfg,1350 ,1200 ); +mxs_power_set_vddx (&mxs_vddd_cfg,1500 ,1000 ); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
Signature · 1 line
1.7.10.4
PATCH 2/2 mxs: Properly setup VDDD in power supply setup code
Quoted 11 lines · Marek Vasut
The memory setup code adjusted the VDDD voltage. Remove this adjustment and configure the VDDD voltage correctly in the power supply setup code.
Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Fabio Estevam <[email protected]>--- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 13 ------------- arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-)
Applied to u-boot-imx, thanks.
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
PATCH 1/2 mxs: Implement common function to setup VDDx
In reply to Marek VasutQuoted 5 lines · Marek Vasut
Implement common function to setup the VDDIO, VDDD and VDDA voltage. Right now, there are two almost identical functions to setup VDDIO and VDDD, which is prone to breakage. Pull out the differences into constant structure and pass them as an argument to the common function.
Quoted 7 lines
Moreover, the function has almost identical loops for setting higher and lower VDDx voltage. Merge these two loops.
Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Fabio Estevam <[email protected]>
I like the code cleanup but I am curious if you have taken a look if the mx23 one is compatible.
Signature · 3 lines
Otavio Salvador O.S. Systems E-mail: otavio at ossystems.com.br http://www.ossystems.com.br Mobile: +55 53 9981-7854 http://projetos.ossystems.com.br
PATCH 1/2 mxs: Implement common function to setup VDDx
Dear Otavio Salvador,
Quoted 9 lines · Marek Vasut
Quoted 8 lines
Implement common function to setup the VDDIO, VDDD and VDDA voltage. Right now, there are two almost identical functions to setup VDDIO and VDDD, which is prone to breakage. Pull out the differences into constant structure and pass them as an argument to the common function.
Moreover, the function has almost identical loops for setting higher and lower VDDx voltage. Merge these two loops.
Quoted 6 lines
Quoted 3 lines
Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Fabio Estevam <[email protected]>I like the code cleanup but I am curious if you have taken a look if the mx23 one is compatible.
MX23 is unsupported in the mainline u-boot.
Best regards,
Marek Vasut
PATCH 1/2 mxs: Implement common function to setup VDDx
Quoted 11 lines · Marek Vasut
Dear Otavio Salvador,
Quoted 9 lines · Marek Vasut
Quoted 8 lines
Implement common function to setup the VDDIO, VDDD and VDDA voltage. Right now, there are two almost identical functions to setup VDDIO and VDDD, which is prone to breakage. Pull out the differences into constant structure and pass them as an argument to the common function.
Moreover, the function has almost identical loops for setting higher and lower VDDx voltage. Merge these two loops.
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines
Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Fabio Estevam <[email protected]>I like the code cleanup but I am curious if you have taken a look if the mx23 one is compatible.
MX23 is unsupported in the mainline u-boot.
I see ...
Signature · 3 lines
Otavio Salvador O.S. Systems E-mail: otavio at ossystems.com.br http://www.ossystems.com.br Mobile: +55 53 9981-7854 http://projetos.ossystems.com.br
PATCH 1/2 mxs: Implement common function to setup VDDx
In reply to Marek VasutQuoted 5 lines · Marek Vasut
Implement common function to setup the VDDIO, VDDD and VDDA voltage. Right now, there are two almost identical functions to setup VDDIO and VDDD, which is prone to breakage. Pull out the differences into constant structure and pass them as an argument to the common function.
Quoted 7 lines
Moreover, the function has almost identical loops for setting higher and lower VDDx voltage. Merge these two loops.
Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Fabio Estevam <[email protected]>---
Applied to u-boot-imx, thanks.
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================