Home | History | Annotate | Line # | Download | only in bootimx23
      1  1.5  skrll /* $Id: power_prep.c,v 1.5 2016/08/17 22:04:51 skrll Exp $ */
      2  1.1  jkunz 
      3  1.1  jkunz /*
      4  1.1  jkunz  * Copyright (c) 2012 The NetBSD Foundation, Inc.
      5  1.1  jkunz  * All rights reserved.
      6  1.1  jkunz  *
      7  1.1  jkunz  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  jkunz  * by Petri Laakso.
      9  1.1  jkunz  *
     10  1.1  jkunz  * Redistribution and use in source and binary forms, with or without
     11  1.1  jkunz  * modification, are permitted provided that the following conditions
     12  1.1  jkunz  * are met:
     13  1.1  jkunz  * 1. Redistributions of source code must retain the above copyright
     14  1.1  jkunz  *    notice, this list of conditions and the following disclaimer.
     15  1.1  jkunz  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  jkunz  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  jkunz  *    documentation and/or other materials provided with the distribution.
     18  1.1  jkunz  *
     19  1.1  jkunz  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  1.1  jkunz  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  1.1  jkunz  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  1.1  jkunz  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  1.1  jkunz  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  1.1  jkunz  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  1.1  jkunz  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  1.1  jkunz  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  1.1  jkunz  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  1.1  jkunz  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1  jkunz  * POSSIBILITY OF SUCH DAMAGE.
     30  1.1  jkunz  */
     31  1.1  jkunz 
     32  1.4   matt #include <sys/cdefs.h>
     33  1.1  jkunz #include <sys/param.h>
     34  1.3  jkunz #include <sys/types.h>
     35  1.1  jkunz 
     36  1.1  jkunz #include <arm/imx/imx23_powerreg.h>
     37  1.1  jkunz 
     38  1.4   matt #include <lib/libkern/libkern.h>
     39  1.1  jkunz #include <lib/libsa/stand.h>
     40  1.1  jkunz 
     41  1.1  jkunz #include "common.h"
     42  1.1  jkunz 
     43  1.4   matt #define PWR_CTRL	(HW_POWER_BASE + HW_POWER_CTRL)
     44  1.4   matt #define PWR_CTRL_S	(HW_POWER_BASE + HW_POWER_CTRL_SET)
     45  1.4   matt #define PWR_CTRL_C	(HW_POWER_BASE + HW_POWER_CTRL_CLR)
     46  1.4   matt #define PWR_5VCTRL	(HW_POWER_BASE + HW_POWER_5VCTRL)
     47  1.4   matt #define PWR_5VCTRL_S	(HW_POWER_BASE + HW_POWER_5VCTRL_SET)
     48  1.4   matt #define PWR_5VCTRL_C	(HW_POWER_BASE + HW_POWER_5VCTRL_CLR)
     49  1.4   matt #define PWR_MINPWR	(HW_POWER_BASE + HW_POWER_MINPWR)
     50  1.4   matt #define PWR_MINPWR_S	(HW_POWER_BASE + HW_POWER_MINPWR_SET)
     51  1.4   matt #define PWR_MINPWR_C	(HW_POWER_BASE + HW_POWER_MINPWR_CLR)
     52  1.4   matt #define PWR_CHARGE	(HW_POWER_BASE + HW_POWER_CHARGE)
     53  1.4   matt #define PWR_CHARGE_S	(HW_POWER_BASE + HW_POWER_CHARGE_SET)
     54  1.4   matt #define PWR_CHARGE_C	(HW_POWER_BASE + HW_POWER_CHARGE_CLR)
     55  1.4   matt #define PWR_VDDDCTRL	(HW_POWER_BASE + HW_POWER_VDDDCTRL)
     56  1.4   matt #define PWR_VDDACTRL	(HW_POWER_BASE + HW_POWER_VDDACTRL)
     57  1.4   matt #define PWR_VDDIOCTRL	(HW_POWER_BASE + HW_POWER_VDDIOCTRL)
     58  1.4   matt #define PWR_VDDMEMCTRL	(HW_POWER_BASE + HW_POWER_VDDMEMCTRL)
     59  1.4   matt #define PWR_DCDC4P2	(HW_POWER_BASE + HW_POWER_DCDC4P2)
     60  1.4   matt #define PWR_MISC	(HW_POWER_BASE + HW_POWER_MISC)
     61  1.4   matt #define PWR_DCLIMITS	(HW_POWER_BASE + HW_POWER_DCLIMITS)
     62  1.4   matt #define PWR_LOOPCTRL 	(HW_POWER_BASE + HW_POWER_LOOPCTRL)
     63  1.4   matt #define PWR_LOOPCTRL_S	(HW_POWER_BASE + HW_POWER_LOOPCTRL_SET)
     64  1.4   matt #define PWR_LOOPCTRL_C	(HW_POWER_BASE + HW_POWER_LOOPCTRL_CLR)
     65  1.4   matt #define PWR_STATUS	(HW_POWER_BASE + HW_POWER_STS)
     66  1.4   matt #define PWR_SPEED	(HW_POWER_BASE + HW_POWER_SPEED)
     67  1.4   matt #define PWR_BATTMONITOR	(HW_POWER_BASE + HW_POWER_BATTMONITOR)
     68  1.4   matt #define PWR_RESET	(HW_POWER_BASE + HW_POWER_RESET)
     69  1.4   matt #define PWR_DEBUG	(HW_POWER_BASE + HW_POWER_DEBUG)
     70  1.4   matt #define PWR_SPECIAL	(HW_POWER_BASE + HW_POWER_SPECIAL)
     71  1.4   matt #define PWR_VERSION	(HW_POWER_BASE + HW_POWER_VERSION)
     72  1.4   matt 
     73  1.4   matt #define VBUSVALID_TRSH 5	/* 4.4V */
     74  1.4   matt #define CHARGE_4P2_ILIMIT_MAX 0x3f
     75  1.4   matt #define CMPTRIP 0x1f	/* DCDC_4P2 pin >= 1.05 * BATTERY pin. */
     76  1.4   matt #define DROPOUT_CTRL 0xa /* BO 100mV, DCDC selects higher. */
     77  1.4   matt 
     78  1.4   matt void en_vbusvalid(void);
     79  1.4   matt int vbusvalid(void);
     80  1.4   matt void power_tune(void);
     81  1.4   matt void en_4p2_reg(void);
     82  1.4   matt void en_4p2_to_dcdc(void);
     83  1.4   matt void power_vddd_from_dcdc(int, int);
     84  1.4   matt void power_vdda_from_dcdc(int, int);
     85  1.4   matt void power_vddio_from_dcdc(int, int);
     86  1.4   matt void power_vddmem(int);
     87  1.1  jkunz 
     88  1.4   matt /*
     89  1.4   matt  * Configure the DCDC control logic 5V detection to use VBUSVALID.
     90  1.4   matt  */
     91  1.4   matt void
     92  1.4   matt en_vbusvalid(void)
     93  1.4   matt {
     94  1.4   matt 	uint32_t tmp_r;
     95  1.4   matt 
     96  1.4   matt 	tmp_r = REG_RD(PWR_5VCTRL);
     97  1.4   matt 	tmp_r &= ~HW_POWER_5VCTRL_VBUSVALID_TRSH;
     98  1.4   matt 	tmp_r |= __SHIFTIN(VBUSVALID_TRSH, HW_POWER_5VCTRL_VBUSVALID_TRSH);
     99  1.4   matt 	REG_WR(PWR_5VCTRL, tmp_r);
    100  1.1  jkunz 
    101  1.4   matt 	REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_PWRUP_VBUS_CMPS);
    102  1.4   matt 	delay(1000);
    103  1.4   matt 
    104  1.4   matt 	REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_VBUSVALID_5VDETECT);
    105  1.4   matt 
    106  1.4   matt 	return;
    107  1.4   matt }
    108  1.1  jkunz /*
    109  1.4   matt  * Test VBUSVALID.
    110  1.1  jkunz  */
    111  1.1  jkunz int
    112  1.4   matt vbusvalid(void)
    113  1.1  jkunz {
    114  1.4   matt 	if (REG_RD(PWR_STATUS) & HW_POWER_STS_VBUSVALID)
    115  1.4   matt 		return 1;
    116  1.3  jkunz 	else
    117  1.4   matt 		return 0;
    118  1.1  jkunz }
    119  1.1  jkunz /*
    120  1.4   matt  * Set various registers.
    121  1.1  jkunz  */
    122  1.4   matt void
    123  1.4   matt power_tune(void)
    124  1.1  jkunz {
    125  1.4   matt 	uint32_t tmp_r;
    126  1.1  jkunz 
    127  1.4   matt 	REG_WR(PWR_LOOPCTRL_S, HW_POWER_LOOPCTRL_TOGGLE_DIF |
    128  1.4   matt 		HW_POWER_LOOPCTRL_EN_CM_HYST |
    129  1.4   matt 		HW_POWER_LOOPCTRL_EN_DF_HYST |
    130  1.4   matt 		HW_POWER_LOOPCTRL_RCSCALE_THRESH |
    131  1.4   matt 		__SHIFTIN(3, HW_POWER_LOOPCTRL_EN_RCSCALE));
    132  1.4   matt 
    133  1.4   matt 	REG_WR(PWR_MINPWR_S, HW_POWER_MINPWR_DOUBLE_FETS);
    134  1.4   matt 
    135  1.4   matt 	REG_WR(PWR_5VCTRL_S, __SHIFTIN(4, HW_POWER_5VCTRL_HEADROOM_ADJ));
    136  1.4   matt 
    137  1.4   matt 	tmp_r = REG_RD(PWR_DCLIMITS);
    138  1.4   matt 	tmp_r &= ~HW_POWER_DCLIMITS_POSLIMIT_BUCK;
    139  1.4   matt 	tmp_r |= __SHIFTIN(0x30, HW_POWER_DCLIMITS_POSLIMIT_BUCK);
    140  1.4   matt 	REG_WR(PWR_DCLIMITS, tmp_r);
    141  1.1  jkunz 
    142  1.4   matt 	return;
    143  1.4   matt }
    144  1.4   matt /*
    145  1.4   matt  * AN3883.pdf 2.1.3.1 Enabling the 4P2 LinReg
    146  1.4   matt  */
    147  1.4   matt void
    148  1.4   matt en_4p2_reg(void)
    149  1.4   matt {
    150  1.4   matt 	uint32_t tmp_r;
    151  1.4   matt 	int ilimit;
    152  1.1  jkunz 
    153  1.4   matt 	/* TRG is 4.2V by default. */
    154  1.4   matt 	tmp_r = REG_RD(PWR_DCDC4P2);
    155  1.4   matt 	tmp_r |= HW_POWER_DCDC4P2_ENABLE_4P2;
    156  1.4   matt 	REG_WR(PWR_DCDC4P2, tmp_r);
    157  1.4   matt 
    158  1.4   matt 	REG_WR(PWR_CHARGE_S, HW_POWER_CHARGE_ENABLE_LOAD);
    159  1.4   matt 
    160  1.4   matt 	/* Set CHARGE_4P2_ILIMIT to minimum. */
    161  1.4   matt 	REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
    162  1.4   matt 	REG_WR(PWR_5VCTRL_S, __SHIFTIN(1, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT));
    163  1.4   matt 
    164  1.4   matt 	/* Power up 4.2V regulation circuit. */
    165  1.4   matt 	REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_PWD_CHARGE_4P2);
    166  1.4   matt 
    167  1.4   matt 	/* Ungate path from 4P2 reg to DCDC. */
    168  1.4   matt 	tmp_r = REG_RD(PWR_DCDC4P2);
    169  1.4   matt 	tmp_r |= HW_POWER_DCDC4P2_ENABLE_DCDC;
    170  1.4   matt 	REG_WR(PWR_DCDC4P2, tmp_r);
    171  1.4   matt 
    172  1.4   matt 	delay(10000);
    173  1.4   matt 
    174  1.4   matt 	/* Charge 4P2 capacitance. */
    175  1.4   matt 	tmp_r = REG_RD(PWR_5VCTRL);
    176  1.4   matt 	for (ilimit = 2; ilimit <= CHARGE_4P2_ILIMIT_MAX; ilimit++) {
    177  1.4   matt 		tmp_r &= ~HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT;
    178  1.4   matt 		tmp_r |= __SHIFTIN(ilimit, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
    179  1.4   matt 		REG_WR(PWR_5VCTRL, tmp_r);
    180  1.4   matt 		delay(10000);
    181  1.3  jkunz 	}
    182  1.1  jkunz 
    183  1.1  jkunz 	return;
    184  1.1  jkunz }
    185  1.1  jkunz 
    186  1.4   matt /*
    187  1.4   matt  * AN3883.pdf 2.1.3.3 Enabling 4P2 Input to DC-DC
    188  1.4   matt  */
    189  1.4   matt void en_4p2_to_dcdc(void)
    190  1.1  jkunz {
    191  1.4   matt 	uint32_t tmp_r;
    192  1.4   matt 
    193  1.4   matt 	tmp_r = REG_RD(PWR_DCDC4P2);
    194  1.4   matt 
    195  1.4   matt 	tmp_r &= ~HW_POWER_DCDC4P2_CMPTRIP;
    196  1.4   matt 	tmp_r |= __SHIFTIN(CMPTRIP, HW_POWER_DCDC4P2_CMPTRIP);
    197  1.4   matt 
    198  1.4   matt 	tmp_r &= ~HW_POWER_DCDC4P2_DROPOUT_CTRL;
    199  1.4   matt 	tmp_r |= __SHIFTIN(DROPOUT_CTRL, HW_POWER_DCDC4P2_DROPOUT_CTRL);
    200  1.1  jkunz 
    201  1.4   matt 	REG_WR(PWR_DCDC4P2, tmp_r);
    202  1.1  jkunz 
    203  1.4   matt 	REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_DCDC_XFER);
    204  1.4   matt 
    205  1.4   matt 	/* Enabling DCDC triggers 5V brownout. */
    206  1.4   matt 	REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_PWDN_5VBRNOUT);
    207  1.4   matt 	REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_ENABLE_DCDC);
    208  1.4   matt 	delay(10000);
    209  1.4   matt 	REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_PWDN_5VBRNOUT);
    210  1.4   matt 
    211  1.4   matt 	/* Now DCDC is using 4P2 so I can remove extra temporary load. */
    212  1.4   matt 	REG_WR(PWR_CHARGE_C, HW_POWER_CHARGE_ENABLE_LOAD);
    213  1.1  jkunz 
    214  1.1  jkunz 	return;
    215  1.1  jkunz }
    216  1.1  jkunz 
    217  1.4   matt /*
    218  1.4   matt  * Configure VDDD to source power from DCDC.
    219  1.4   matt  */
    220  1.4   matt void
    221  1.4   matt power_vddd_from_dcdc(int target, int brownout)
    222  1.1  jkunz {
    223  1.4   matt 	uint32_t tmp_r;
    224  1.1  jkunz 
    225  1.5  skrll 	/* BO_OFFSET must be within 800mV - 1475mV */
    226  1.4   matt 	if (brownout > 1475)
    227  1.4   matt 		brownout = 1475;
    228  1.4   matt 	else if (brownout < 800)
    229  1.4   matt 		brownout = 800;
    230  1.4   matt 
    231  1.4   matt 
    232  1.4   matt 	/* Set LINREG_OFFSET one step below TRG. */
    233  1.4   matt 	tmp_r = REG_RD(PWR_VDDDCTRL);
    234  1.4   matt 	tmp_r &= ~HW_POWER_VDDDCTRL_LINREG_OFFSET;
    235  1.4   matt 	tmp_r |= __SHIFTIN(2, HW_POWER_VDDDCTRL_LINREG_OFFSET);
    236  1.4   matt 	REG_WR(PWR_VDDDCTRL, tmp_r);
    237  1.4   matt 	delay(10000);
    238  1.4   matt 
    239  1.4   matt 	/* Enable VDDD switching converter output. */
    240  1.4   matt 	tmp_r = REG_RD(PWR_VDDDCTRL);
    241  1.4   matt 	tmp_r &= ~HW_POWER_VDDDCTRL_DISABLE_FET;
    242  1.4   matt 	REG_WR(PWR_VDDDCTRL, tmp_r);
    243  1.4   matt 	delay(10000);
    244  1.4   matt 
    245  1.4   matt 	/* Disable linear regulator output. */
    246  1.4   matt 	tmp_r = REG_RD(PWR_VDDDCTRL);
    247  1.4   matt 	tmp_r &= ~HW_POWER_VDDDCTRL_ENABLE_LINREG;
    248  1.4   matt 	REG_WR(PWR_VDDDCTRL, tmp_r);
    249  1.4   matt 	delay(10000);
    250  1.4   matt 
    251  1.4   matt 	/* Set target voltage and brownout level. */
    252  1.4   matt 	tmp_r = REG_RD(PWR_VDDDCTRL);
    253  1.4   matt 	tmp_r &= ~(HW_POWER_VDDDCTRL_BO_OFFSET | HW_POWER_VDDDCTRL_TRG);
    254  1.4   matt 	tmp_r |= __SHIFTIN(((target - brownout) / 25),
    255  1.4   matt 		HW_POWER_VDDDCTRL_BO_OFFSET);
    256  1.4   matt 	tmp_r |= __SHIFTIN(((target - 800) / 25), HW_POWER_VDDDCTRL_TRG);
    257  1.4   matt 	REG_WR(PWR_VDDDCTRL, tmp_r);
    258  1.4   matt 	delay(10000);
    259  1.1  jkunz 
    260  1.4   matt 	/* Enable PWDN_BRNOUT. */
    261  1.4   matt 	REG_WR(PWR_CTRL_C, HW_POWER_CTRL_VDDD_BO_IRQ);
    262  1.4   matt 
    263  1.4   matt 	tmp_r = REG_RD(PWR_VDDDCTRL);
    264  1.4   matt 	tmp_r |= HW_POWER_VDDDCTRL_PWDN_BRNOUT;
    265  1.4   matt 	REG_WR(PWR_VDDDCTRL, tmp_r);
    266  1.1  jkunz 
    267  1.1  jkunz 	return;
    268  1.1  jkunz }
    269  1.4   matt /*
    270  1.4   matt  * Configure VDDA to source power from DCDC.
    271  1.4   matt  */
    272  1.4   matt void
    273  1.4   matt power_vdda_from_dcdc(int target, int brownout)
    274  1.4   matt {
    275  1.4   matt 	uint32_t tmp_r;
    276  1.4   matt 
    277  1.5  skrll 	/* BO_OFFSET must be within 1400mV - 2175mV */
    278  1.4   matt 	if (brownout > 2275)
    279  1.4   matt 		brownout = 2275;
    280  1.4   matt 	else if (brownout < 1400)
    281  1.4   matt 		brownout = 1400;
    282  1.4   matt 
    283  1.4   matt 
    284  1.4   matt 	/* Set LINREG_OFFSET one step below TRG. */
    285  1.4   matt 	tmp_r = REG_RD(PWR_VDDACTRL);
    286  1.4   matt 	tmp_r &= ~HW_POWER_VDDACTRL_LINREG_OFFSET;
    287  1.4   matt 	tmp_r |= __SHIFTIN(2, HW_POWER_VDDACTRL_LINREG_OFFSET);
    288  1.4   matt 	REG_WR(PWR_VDDACTRL, tmp_r);
    289  1.4   matt 	delay(10000);
    290  1.4   matt 
    291  1.4   matt 	/* Enable VDDA switching converter output. */
    292  1.4   matt 	tmp_r = REG_RD(PWR_VDDACTRL);
    293  1.4   matt 	tmp_r &= ~HW_POWER_VDDACTRL_DISABLE_FET;
    294  1.4   matt 	REG_WR(PWR_VDDACTRL, tmp_r);
    295  1.4   matt 	delay(10000);
    296  1.4   matt 
    297  1.4   matt 	/* Disable linear regulator output. */
    298  1.4   matt 	tmp_r = REG_RD(PWR_VDDACTRL);
    299  1.4   matt 	tmp_r &= ~HW_POWER_VDDACTRL_ENABLE_LINREG;
    300  1.4   matt 	REG_WR(PWR_VDDACTRL, tmp_r);
    301  1.4   matt 	delay(10000);
    302  1.4   matt 
    303  1.4   matt 	/* Set target voltage and brownout level. */
    304  1.4   matt 	tmp_r = REG_RD(PWR_VDDACTRL);
    305  1.4   matt 	tmp_r &= ~(HW_POWER_VDDACTRL_BO_OFFSET | HW_POWER_VDDACTRL_TRG);
    306  1.4   matt 	tmp_r |= __SHIFTIN(((target - brownout) / 25),
    307  1.4   matt 		HW_POWER_VDDACTRL_BO_OFFSET);
    308  1.4   matt 	tmp_r |= __SHIFTIN(((target - 1500) / 25), HW_POWER_VDDACTRL_TRG);
    309  1.4   matt 	REG_WR(PWR_VDDACTRL, tmp_r);
    310  1.4   matt 	delay(10000);
    311  1.4   matt 
    312  1.4   matt 	/* Enable PWDN_BRNOUT. */
    313  1.4   matt 	REG_WR(PWR_CTRL_C, HW_POWER_CTRL_VDDA_BO_IRQ);
    314  1.4   matt 
    315  1.4   matt 	tmp_r = REG_RD(PWR_VDDACTRL);
    316  1.4   matt 	tmp_r |= HW_POWER_VDDACTRL_PWDN_BRNOUT;
    317  1.4   matt 	REG_WR(PWR_VDDACTRL, tmp_r);
    318  1.1  jkunz 
    319  1.4   matt 	return;
    320  1.4   matt }
    321  1.4   matt /*
    322  1.4   matt  * Configure VDDIO to source power from DCDC.
    323  1.4   matt  */
    324  1.4   matt void
    325  1.4   matt power_vddio_from_dcdc(int target, int brownout)
    326  1.1  jkunz {
    327  1.4   matt 	uint32_t tmp_r;
    328  1.1  jkunz 
    329  1.5  skrll 	/* BO_OFFSET must be within 2700mV - 3475mV */
    330  1.4   matt 	if (brownout > 3475)
    331  1.4   matt 		brownout = 3475;
    332  1.4   matt 	else if (brownout < 2700)
    333  1.4   matt 		brownout = 2700;
    334  1.4   matt 
    335  1.4   matt 
    336  1.4   matt 	/* Set LINREG_OFFSET one step below TRG. */
    337  1.4   matt 	tmp_r = REG_RD(PWR_VDDIOCTRL);
    338  1.4   matt 	tmp_r &= ~HW_POWER_VDDIOCTRL_LINREG_OFFSET;
    339  1.4   matt 	tmp_r |= __SHIFTIN(2, HW_POWER_VDDIOCTRL_LINREG_OFFSET);
    340  1.4   matt 	REG_WR(PWR_VDDIOCTRL, tmp_r);
    341  1.4   matt 	delay(10000);
    342  1.4   matt 
    343  1.4   matt 	/* Enable VDDIO switching converter output. */
    344  1.4   matt 	tmp_r = REG_RD(PWR_VDDIOCTRL);
    345  1.4   matt 	tmp_r &= ~HW_POWER_VDDIOCTRL_DISABLE_FET;
    346  1.4   matt 	REG_WR(PWR_VDDIOCTRL, tmp_r);
    347  1.4   matt 	delay(10000);
    348  1.4   matt 
    349  1.4   matt 	/* Set target voltage and brownout level. */
    350  1.4   matt 	tmp_r = REG_RD(PWR_VDDIOCTRL);
    351  1.4   matt 	tmp_r &= ~(HW_POWER_VDDIOCTRL_BO_OFFSET | HW_POWER_VDDIOCTRL_TRG);
    352  1.4   matt 	tmp_r |= __SHIFTIN(((target - brownout) / 25),
    353  1.4   matt 		HW_POWER_VDDIOCTRL_BO_OFFSET);
    354  1.4   matt 	tmp_r |= __SHIFTIN(((target - 2800) / 25), HW_POWER_VDDIOCTRL_TRG);
    355  1.4   matt 	REG_WR(PWR_VDDIOCTRL, tmp_r);
    356  1.4   matt 	delay(10000);
    357  1.3  jkunz 
    358  1.4   matt 	/* Enable PWDN_BRNOUT. */
    359  1.4   matt 	REG_WR(PWR_CTRL_C, HW_POWER_CTRL_VDDIO_BO_IRQ);
    360  1.4   matt 
    361  1.4   matt 	tmp_r = REG_RD(PWR_VDDIOCTRL);
    362  1.4   matt 	tmp_r |= HW_POWER_VDDIOCTRL_PWDN_BRNOUT;
    363  1.4   matt 	REG_WR(PWR_VDDIOCTRL, tmp_r);
    364  1.1  jkunz 
    365  1.1  jkunz 	return;
    366  1.1  jkunz }
    367  1.4   matt /*
    368  1.4   matt  * AN3883.pdf 2.3.1.2 Setting VDDMEM Target Voltage
    369  1.4   matt  */
    370  1.4   matt void
    371  1.4   matt power_vddmem(int target)
    372  1.4   matt {
    373  1.4   matt 	uint32_t tmp_r;
    374  1.4   matt 
    375  1.4   matt 	/* Set target voltage. */
    376  1.4   matt 	tmp_r = REG_RD(PWR_VDDMEMCTRL);
    377  1.4   matt 	tmp_r &= ~(HW_POWER_VDDMEMCTRL_TRG);
    378  1.4   matt 	tmp_r |= __SHIFTIN(((target - 1700) / 50), HW_POWER_VDDMEMCTRL_TRG);
    379  1.4   matt 	REG_WR(PWR_VDDMEMCTRL, tmp_r);
    380  1.4   matt 	delay(10000);
    381  1.4   matt 
    382  1.4   matt 	tmp_r = REG_RD(PWR_VDDMEMCTRL);
    383  1.4   matt 	tmp_r |= (HW_POWER_VDDMEMCTRL_PULLDOWN_ACTIVE |
    384  1.4   matt 		HW_POWER_VDDMEMCTRL_ENABLE_ILIMIT |
    385  1.4   matt 		HW_POWER_VDDMEMCTRL_ENABLE_LINREG);
    386  1.4   matt 	REG_WR(PWR_VDDMEMCTRL, tmp_r);
    387  1.1  jkunz 
    388  1.4   matt 	delay(1000);
    389  1.4   matt 
    390  1.4   matt 	tmp_r = REG_RD(PWR_VDDMEMCTRL);
    391  1.4   matt 	tmp_r &= ~(HW_POWER_VDDMEMCTRL_PULLDOWN_ACTIVE |
    392  1.4   matt 		HW_POWER_VDDMEMCTRL_ENABLE_ILIMIT);
    393  1.4   matt 	REG_WR(PWR_VDDMEMCTRL, tmp_r);
    394  1.1  jkunz 
    395  1.1  jkunz 	return;
    396  1.1  jkunz }
    397