mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
imx233: add regulator api
Remove the old debug stuff about VDDx and add a clean api to get/set the regulator (VDDD, VDDA, VDDIO, VDDMEM). This is useful for proper frequency scaling. Change-Id: Ia5a1a712fd66652a8ad9601ed00db31aba5a7561
This commit is contained in:
parent
51f63f0b2a
commit
7ee1e30609
3 changed files with 184 additions and 56 deletions
|
|
@ -34,6 +34,7 @@
|
|||
#include "pinctrl-imx233.h"
|
||||
#include "ocotp-imx233.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#define DEBUG_CANCEL BUTTON_BACK
|
||||
|
||||
|
|
@ -150,21 +151,33 @@ bool dbg_hw_info_power(void)
|
|||
lcd_clear_display();
|
||||
|
||||
struct imx233_power_info_t info = imx233_power_get_info(POWER_INFO_ALL);
|
||||
lcd_putsf(0, 0, "VDDD: %d mV linreg: %d offset: %d", info.vddd, info.vddd_linreg,
|
||||
info.vddd_linreg_offset);
|
||||
lcd_putsf(0, 1, "VDDA: %d mV linreg: %d offset: %d", info.vdda, info.vdda_linreg,
|
||||
info.vdda_linreg_offset);
|
||||
lcd_putsf(0, 2, "VDDIO: %d mV offset: %d", info.vddio, info.vddio_linreg_offset);
|
||||
lcd_putsf(0, 3, "VDDMEM: %d mV linreg: %d", info.vddmem, info.vddmem_linreg);
|
||||
lcd_putsf(0, 4, "DC-DC: pll: %d freq: %d", info.dcdc_sel_pllclk, info.dcdc_freqsel);
|
||||
lcd_putsf(0, 5, "charge: %d mA stop: %d mA", info.charge_current, info.stop_current);
|
||||
lcd_putsf(0, 6, "charging: %d bat_adj: %d", info.charging, info.batt_adj);
|
||||
lcd_putsf(0, 7, "4.2: en: %d dcdc: %d", info._4p2_enable, info._4p2_dcdc);
|
||||
lcd_putsf(0, 8, "4.2: cmptrip: %d dropout: %d", info._4p2_cmptrip, info._4p2_dropout);
|
||||
lcd_putsf(0, 9, "5V: pwd_4.2_charge: %d", info._5v_pwd_charge_4p2);
|
||||
lcd_putsf(0, 10, "5V: chargelim: %d mA", info._5v_charge_4p2_limit);
|
||||
lcd_putsf(0, 11, "5V: dcdc: %d xfer: %d", info._5v_enable_dcdc, info._5v_dcdc_xfer);
|
||||
lcd_putsf(0, 12, "5V: thr: %d mV use: %d cmps: %d", info._5v_vbusvalid_thr,
|
||||
int line = 0;
|
||||
unsigned trg, bo;
|
||||
bool en;
|
||||
int linreg;
|
||||
char buf[16];
|
||||
|
||||
lcd_putsf(0, line++, "name value bo linreg");
|
||||
#define DISP_REGULATOR(name) \
|
||||
imx233_power_get_regulator(REGULATOR_##name, &trg, &bo); \
|
||||
imx233_power_get_regulator_linreg(REGULATOR_##name, &en, &linreg); \
|
||||
if(en) snprintf(buf, sizeof(buf), "%d", linreg); \
|
||||
else snprintf(buf, sizeof(buf), " "); \
|
||||
lcd_putsf(0, line++, "%6s %4d %4d %s", #name, trg, bo, buf); \
|
||||
|
||||
DISP_REGULATOR(VDDD);
|
||||
DISP_REGULATOR(VDDA);
|
||||
DISP_REGULATOR(VDDIO);
|
||||
DISP_REGULATOR(VDDMEM);
|
||||
lcd_putsf(0, line++, "DC-DC: pll: %d freq: %d", info.dcdc_sel_pllclk, info.dcdc_freqsel);
|
||||
lcd_putsf(0, line++, "charge: %d mA stop: %d mA", info.charge_current, info.stop_current);
|
||||
lcd_putsf(0, line++, "charging: %d bat_adj: %d", info.charging, info.batt_adj);
|
||||
lcd_putsf(0, line++, "4.2: en: %d dcdc: %d", info._4p2_enable, info._4p2_dcdc);
|
||||
lcd_putsf(0, line++, "4.2: cmptrip: %d dropout: %d", info._4p2_cmptrip, info._4p2_dropout);
|
||||
lcd_putsf(0, line++, "5V: pwd_4.2_charge: %d", info._5v_pwd_charge_4p2);
|
||||
lcd_putsf(0, line++, "5V: chargelim: %d mA", info._5v_charge_4p2_limit);
|
||||
lcd_putsf(0, line++, "5V: dcdc: %d xfer: %d", info._5v_enable_dcdc, info._5v_dcdc_xfer);
|
||||
lcd_putsf(0, line++, "5V: thr: %d mV use: %d cmps: %d", info._5v_vbusvalid_thr,
|
||||
info._5v_vbusvalid_detect, info._5v_vbus_cmps);
|
||||
|
||||
lcd_update();
|
||||
|
|
@ -286,7 +299,8 @@ bool dbg_hw_info_clkctrl(void)
|
|||
#undef c
|
||||
}
|
||||
int line = ARRAYLEN(dbg_clk) + 1;
|
||||
lcd_putsf(0, line, "auto slow: %d", imx233_clkctrl_is_auto_slow_enabled());
|
||||
lcd_putsf(0, line, "auto slow: %d emi sync: %d", imx233_clkctrl_is_auto_slow_enabled(),
|
||||
imx233_clkctrl_is_emi_sync_enabled());
|
||||
line++;
|
||||
lcd_putsf(0, line, "as monitor: ");
|
||||
int x_off = 12;
|
||||
|
|
|
|||
|
|
@ -165,6 +165,130 @@ void imx233_power_set_stop_current(unsigned current)
|
|||
}
|
||||
}
|
||||
|
||||
/* regulator info */
|
||||
#define HAS_BO (1 << 0)
|
||||
#define HAS_LINREG (1 << 1)
|
||||
#define HAS_LINREG_OFFSET (1 << 2)
|
||||
|
||||
static struct
|
||||
{
|
||||
unsigned min, step;
|
||||
volatile uint32_t *reg;
|
||||
uint32_t trg_bm, trg_bp; // bitmask and bitpos
|
||||
unsigned flags;
|
||||
uint32_t bo_bm, bo_bp; // bitmask and bitpos
|
||||
uint32_t linreg_bm;
|
||||
uint32_t linreg_offset_bm, linreg_offset_bp; // bitmask and bitpos
|
||||
} regulator_info[] =
|
||||
{
|
||||
#define ADD_REGULATOR(name, mask) \
|
||||
.min = HW_POWER_##name##CTRL__TRG_MIN, \
|
||||
.step = HW_POWER_##name##CTRL__TRG_STEP, \
|
||||
.reg = &HW_POWER_##name##CTRL, \
|
||||
.trg_bm = HW_POWER_##name##CTRL__TRG_BM, \
|
||||
.trg_bp = HW_POWER_##name##CTRL__TRG_BP, \
|
||||
.flags = mask
|
||||
#define ADD_REGULATOR_BO(name) \
|
||||
.bo_bm = HW_POWER_##name##CTRL__BO_OFFSET_BM, \
|
||||
.bo_bp = HW_POWER_##name##CTRL__BO_OFFSET_BP
|
||||
#define ADD_REGULATOR_LINREG(name) \
|
||||
.linreg_bm = HW_POWER_##name##CTRL__ENABLE_LINREG
|
||||
#define ADD_REGULATOR_LINREG_OFFSET(name) \
|
||||
.linreg_offset_bm = HW_POWER_##name##CTRL__LINREG_OFFSET_BM, \
|
||||
.linreg_offset_bp = HW_POWER_##name##CTRL__LINREG_OFFSET_BP
|
||||
[REGULATOR_VDDD] =
|
||||
{
|
||||
ADD_REGULATOR(VDDD, HAS_BO|HAS_LINREG|HAS_LINREG_OFFSET),
|
||||
ADD_REGULATOR_BO(VDDD),
|
||||
ADD_REGULATOR_LINREG(VDDD),
|
||||
ADD_REGULATOR_LINREG_OFFSET(VDDD)
|
||||
},
|
||||
[REGULATOR_VDDA] =
|
||||
{
|
||||
ADD_REGULATOR(VDDA, HAS_BO|HAS_LINREG|HAS_LINREG_OFFSET),
|
||||
ADD_REGULATOR_BO(VDDA),
|
||||
ADD_REGULATOR_LINREG(VDDA),
|
||||
ADD_REGULATOR_LINREG_OFFSET(VDDA)
|
||||
},
|
||||
[REGULATOR_VDDIO] =
|
||||
{
|
||||
ADD_REGULATOR(VDDIO, HAS_BO|HAS_LINREG_OFFSET),
|
||||
ADD_REGULATOR_BO(VDDIO),
|
||||
ADD_REGULATOR_LINREG_OFFSET(VDDIO)
|
||||
},
|
||||
[REGULATOR_VDDMEM] =
|
||||
{
|
||||
ADD_REGULATOR(VDDMEM, HAS_LINREG),
|
||||
ADD_REGULATOR_LINREG(VDDMEM),
|
||||
},
|
||||
};
|
||||
|
||||
void imx233_power_get_regulator(enum imx233_regulator_t reg, unsigned *value_mv,
|
||||
unsigned *brownout_mv)
|
||||
{
|
||||
uint32_t reg_val = *regulator_info[reg].reg;
|
||||
/* read target value */
|
||||
unsigned raw_val = (reg_val & regulator_info[reg].trg_bm) >> regulator_info[reg].trg_bp;
|
||||
/* convert it to mv */
|
||||
if(value_mv)
|
||||
*value_mv = regulator_info[reg].min + regulator_info[reg].step * raw_val;
|
||||
if(regulator_info[reg].flags & HAS_BO)
|
||||
{
|
||||
/* read brownout offset */
|
||||
unsigned raw_bo = (reg_val & regulator_info[reg].bo_bm) >> regulator_info[reg].bo_bp;
|
||||
/* convert it to mv */
|
||||
if(brownout_mv)
|
||||
*brownout_mv = regulator_info[reg].min + regulator_info[reg].step * (raw_val - raw_bo);
|
||||
}
|
||||
else if(brownout_mv)
|
||||
*brownout_mv = 0;
|
||||
}
|
||||
|
||||
void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned value_mv,
|
||||
unsigned brownout_mv)
|
||||
{
|
||||
// compute raw values
|
||||
unsigned raw_val = (value_mv - regulator_info[reg].min) / regulator_info[reg].step;
|
||||
unsigned raw_bo_offset = (value_mv - brownout_mv) / regulator_info[reg].step;
|
||||
// update
|
||||
uint32_t reg_val = (*regulator_info[reg].reg) & ~regulator_info[reg].trg_bm;
|
||||
reg_val |= raw_val << regulator_info[reg].trg_bp;
|
||||
if(regulator_info[reg].flags & HAS_BO)
|
||||
{
|
||||
reg_val &= ~regulator_info[reg].bo_bm;
|
||||
reg_val |= raw_bo_offset << regulator_info[reg].bo_bp;
|
||||
}
|
||||
*regulator_info[reg].reg = reg_val;
|
||||
}
|
||||
|
||||
// offset is -1,0 or 1
|
||||
void imx233_power_get_regulator_linreg(enum imx233_regulator_t reg,
|
||||
bool *enabled, int *linreg_offset)
|
||||
{
|
||||
if(enabled && regulator_info[reg].flags & HAS_LINREG)
|
||||
*enabled = !!(*regulator_info[reg].reg & regulator_info[reg].linreg_bm);
|
||||
else if(enabled)
|
||||
*enabled = true;
|
||||
if(regulator_info[reg].flags & HAS_LINREG_OFFSET)
|
||||
{
|
||||
unsigned v = (*regulator_info[reg].reg & regulator_info[reg].linreg_offset_bm);
|
||||
v >>= regulator_info[reg].linreg_offset_bp;
|
||||
if(linreg_offset)
|
||||
*linreg_offset = (v == 0) ? 0 : (v == 1) ? 1 : -1;
|
||||
}
|
||||
else if(linreg_offset)
|
||||
*linreg_offset = 0;
|
||||
}
|
||||
|
||||
// offset is -1,0 or 1
|
||||
/*
|
||||
void imx233_power_set_regulator_linreg(enum imx233_regulator_t reg,
|
||||
bool enabled, int linreg_offset)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
struct imx233_power_info_t imx233_power_get_info(unsigned flags)
|
||||
{
|
||||
static int dcdc_freqsel[8] = {
|
||||
|
|
@ -180,31 +304,6 @@ struct imx233_power_info_t imx233_power_get_info(unsigned flags)
|
|||
|
||||
struct imx233_power_info_t s;
|
||||
memset(&s, 0, sizeof(s));
|
||||
if(flags & POWER_INFO_VDDD)
|
||||
{
|
||||
s.vddd = HW_POWER_VDDDCTRL__TRG_MIN + HW_POWER_VDDDCTRL__TRG_STEP * __XTRACT(HW_POWER_VDDDCTRL, TRG);
|
||||
s.vddd_linreg = HW_POWER_VDDDCTRL & HW_POWER_VDDDCTRL__ENABLE_LINREG;
|
||||
s.vddd_linreg_offset = __XTRACT(HW_POWER_VDDDCTRL, LINREG_OFFSET) == 0 ? 0 :
|
||||
__XTRACT(HW_POWER_VDDDCTRL, LINREG_OFFSET) == 1 ? 25 : -25;
|
||||
}
|
||||
if(flags & POWER_INFO_VDDA)
|
||||
{
|
||||
s.vdda = HW_POWER_VDDACTRL__TRG_MIN + HW_POWER_VDDACTRL__TRG_STEP * __XTRACT(HW_POWER_VDDACTRL, TRG);
|
||||
s.vdda_linreg = HW_POWER_VDDACTRL & HW_POWER_VDDACTRL__ENABLE_LINREG;
|
||||
s.vdda_linreg_offset = __XTRACT(HW_POWER_VDDACTRL, LINREG_OFFSET) == 0 ? 0 :
|
||||
__XTRACT(HW_POWER_VDDACTRL, LINREG_OFFSET) == 1 ? 25 : -25;
|
||||
}
|
||||
if(flags & POWER_INFO_VDDIO)
|
||||
{
|
||||
s.vddio = HW_POWER_VDDIOCTRL__TRG_MIN + HW_POWER_VDDIOCTRL__TRG_STEP * __XTRACT(HW_POWER_VDDIOCTRL, TRG);
|
||||
s.vddio_linreg_offset = __XTRACT(HW_POWER_VDDIOCTRL, LINREG_OFFSET) == 0 ? 0 :
|
||||
__XTRACT(HW_POWER_VDDIOCTRL, LINREG_OFFSET) == 1 ? 25 : -25;
|
||||
}
|
||||
if(flags & POWER_INFO_VDDMEM)
|
||||
{
|
||||
s.vddmem = HW_POWER_VDDMEMCTRL__TRG_MIN + HW_POWER_VDDMEMCTRL__TRG_STEP * __XTRACT(HW_POWER_VDDMEMCTRL, TRG);
|
||||
s.vddmem_linreg = HW_POWER_VDDMEMCTRL & HW_POWER_VDDMEMCTRL__ENABLE_LINREG;
|
||||
}
|
||||
if(flags & POWER_INFO_DCDC)
|
||||
{
|
||||
s.dcdc_sel_pllclk = HW_POWER_MISC & HW_POWER_MISC__SEL_PLLCLK;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@
|
|||
#define HW_POWER_VDDDCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x40))
|
||||
#define HW_POWER_VDDDCTRL__TRG_BP 0
|
||||
#define HW_POWER_VDDDCTRL__TRG_BM 0x1f
|
||||
#define HW_POWER_VDDDCTRL__BO_OFFSET_BP 8
|
||||
#define HW_POWER_VDDDCTRL__BO_OFFSET_BM (0x7 << 8)
|
||||
#define HW_POWER_VDDDCTRL__TRG_STEP 25 /* mV */
|
||||
#define HW_POWER_VDDDCTRL__TRG_MIN 800 /* mV */
|
||||
#define HW_POWER_VDDDCTRL__LINREG_OFFSET_BP 16
|
||||
|
|
@ -86,6 +88,8 @@
|
|||
#define HW_POWER_VDDACTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x50))
|
||||
#define HW_POWER_VDDACTRL__TRG_BP 0
|
||||
#define HW_POWER_VDDACTRL__TRG_BM 0x1f
|
||||
#define HW_POWER_VDDACTRL__BO_OFFSET_BP 8
|
||||
#define HW_POWER_VDDACTRL__BO_OFFSET_BM (0x7 << 8)
|
||||
#define HW_POWER_VDDACTRL__TRG_STEP 25 /* mV */
|
||||
#define HW_POWER_VDDACTRL__TRG_MIN 1500 /* mV */
|
||||
#define HW_POWER_VDDACTRL__LINREG_OFFSET_BP 12
|
||||
|
|
@ -95,6 +99,8 @@
|
|||
#define HW_POWER_VDDIOCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x60))
|
||||
#define HW_POWER_VDDIOCTRL__TRG_BP 0
|
||||
#define HW_POWER_VDDIOCTRL__TRG_BM 0x1f
|
||||
#define HW_POWER_VDDIOCTRL__BO_OFFSET_BP 8
|
||||
#define HW_POWER_VDDIOCTRL__BO_OFFSET_BM (0x7 << 8)
|
||||
#define HW_POWER_VDDIOCTRL__TRG_STEP 25 /* mV */
|
||||
#define HW_POWER_VDDIOCTRL__TRG_MIN 2800 /* mV */
|
||||
#define HW_POWER_VDDIOCTRL__LINREG_OFFSET_BP 12
|
||||
|
|
@ -173,10 +179,33 @@ void imx233_power_set_charge_current(unsigned current); /* in mA */
|
|||
void imx233_power_set_stop_current(unsigned current); /* in mA */
|
||||
void imx233_power_enable_batadj(bool enable);
|
||||
|
||||
enum imx233_regulator_t
|
||||
{
|
||||
REGULATOR_VDDD, /* target, brownout, linreg, linreg offset */
|
||||
REGULATOR_VDDA, /* target, brownout, linreg, linreg offset */
|
||||
REGULATOR_VDDIO, /* target, brownout, linreg offset */
|
||||
REGULATOR_VDDMEM, /* target, linreg */
|
||||
REGULATOR_COUNT,
|
||||
};
|
||||
|
||||
void imx233_power_get_regulator(enum imx233_regulator_t reg, unsigned *target_mv,
|
||||
unsigned *brownout_mv);
|
||||
|
||||
void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned target_mv,
|
||||
unsigned brownout_mv);
|
||||
|
||||
// offset is -1,0 or 1
|
||||
void imx233_power_get_regulator_linreg(enum imx233_regulator_t reg,
|
||||
bool *enabled, int *linreg_offset);
|
||||
|
||||
// offset is -1,0 or 1
|
||||
void imx233_power_set_regulator_linreg(enum imx233_regulator_t reg,
|
||||
bool enabled, int linreg_offset);
|
||||
|
||||
static inline void imx233_power_set_dcdc_freq(bool pll, unsigned freq)
|
||||
{
|
||||
HW_POWER_MISC &= ~(HW_POWER_MISC__SEL_PLLCLK | HW_POWER_MISC__FREQSEL_BM);
|
||||
/* WARNING: HW_POWER_MISC does have a SET/CLR variant ! */
|
||||
/* WARNING: HW_POWER_MISC does not have a SET/CLR variant ! */
|
||||
if(pll)
|
||||
{
|
||||
HW_POWER_MISC |= freq << HW_POWER_MISC__FREQSEL_BP;
|
||||
|
|
@ -186,16 +215,6 @@ static inline void imx233_power_set_dcdc_freq(bool pll, unsigned freq)
|
|||
|
||||
struct imx233_power_info_t
|
||||
{
|
||||
int vddd; /* in mV */
|
||||
bool vddd_linreg; /* VDDD source: linreg from VDDA or DC-DC */
|
||||
int vddd_linreg_offset;
|
||||
int vdda; /* in mV */
|
||||
bool vdda_linreg; /* VDDA source: linreg from VDDIO or DC-DC */
|
||||
int vdda_linreg_offset;
|
||||
int vddio; /* in mV */
|
||||
int vddio_linreg_offset;
|
||||
int vddmem; /* in mV */
|
||||
bool vddmem_linreg; /* VDDMEM source: linreg from VDDIO or off */
|
||||
bool dcdc_sel_pllclk; /* clock source of DC-DC: pll or 24MHz xtal */
|
||||
int dcdc_freqsel;
|
||||
int charge_current;
|
||||
|
|
@ -215,10 +234,6 @@ struct imx233_power_info_t
|
|||
bool _5v_vbus_cmps;
|
||||
};
|
||||
|
||||
#define POWER_INFO_VDDD (1 << 0)
|
||||
#define POWER_INFO_VDDA (1 << 1)
|
||||
#define POWER_INFO_VDDIO (1 << 2)
|
||||
#define POWER_INFO_VDDMEM (1 << 3)
|
||||
#define POWER_INFO_DCDC (1 << 4)
|
||||
#define POWER_INFO_CHARGE (1 << 5)
|
||||
#define POWER_INFO_4P2 (1 << 6)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue