diff --git a/firmware/target/arm/imx233/debug-imx233.c b/firmware/target/arm/imx233/debug-imx233.c index fdd3de695b..7eacbf7523 100644 --- a/firmware/target/arm/imx233/debug-imx233.c +++ b/firmware/target/arm/imx233/debug-imx233.c @@ -27,6 +27,7 @@ #include "font.h" #include "adc.h" #include "adc-imx233.h" +#include "power-imx233.h" #include "powermgmt.h" static struct @@ -81,6 +82,40 @@ bool dbg_hw_info_dma(void) } } +bool dbg_hw_info_power(void) +{ + lcd_setfont(FONT_SYSFIXED); + + while(1) + { + int button = get_action(CONTEXT_STD, HZ / 25); + switch(button) + { + case ACTION_STD_NEXT: + case ACTION_STD_PREV: + case ACTION_STD_OK: + case ACTION_STD_MENU: + lcd_setfont(FONT_UI); + return true; + case ACTION_STD_CANCEL: + lcd_setfont(FONT_UI); + return false; + } + + 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", info.vddd, info.vddd_linreg); + lcd_putsf(0, 1, "VDDA: %d mV linreg: %d", info.vdda, info.vdda_linreg); + lcd_putsf(0, 2, "VDDIO: %d mV", info.vddio); + 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_update(); + yield(); + } +} + bool dbg_hw_info_adc(void) { lcd_setfont(FONT_SYSFIXED); @@ -118,7 +153,8 @@ bool dbg_hw_info_adc(void) bool dbg_hw_info(void) { - return dbg_hw_info_dma() && dbg_hw_info_adc() && dbg_hw_target_info(); + return dbg_hw_info_dma() && dbg_hw_info_adc() && dbg_hw_info_power() && + dbg_hw_target_info(); } bool dbg_ports(void) diff --git a/firmware/target/arm/imx233/power-imx233.c b/firmware/target/arm/imx233/power-imx233.c index 9a413acadc..557b8521d5 100644 --- a/firmware/target/arm/imx233/power-imx233.c +++ b/firmware/target/arm/imx233/power-imx233.c @@ -22,6 +22,7 @@ #include "config.h" #include "system.h" #include "power.h" +#include "string.h" #include "system-target.h" #include "usb-target.h" @@ -70,3 +71,43 @@ bool charging_state(void) { return false; } + +struct imx233_power_info_t imx233_power_get_info(unsigned flags) +{ + static int dcdc_freqsel[8] = { + [HW_POWER_MISC__FREQSEL__RES] = 0, + [HW_POWER_MISC__FREQSEL__20MHz] = 20000, + [HW_POWER_MISC__FREQSEL__24MHz] = 24000, + [HW_POWER_MISC__FREQSEL__19p2MHz] = 19200, + [HW_POWER_MISC__FREQSEL__14p4MHz] = 14200, + [HW_POWER_MISC__FREQSEL__18MHz] = 18000, + [HW_POWER_MISC__FREQSEL__21p6MHz] = 21600, + [HW_POWER_MISC__FREQSEL__17p28MHz] = 17280, + }; + + 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; + } + 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; + } + if(flags & POWER_INFO_VDDIO) + s.vddio = HW_POWER_VDDIOCTRL__TRG_MIN + HW_POWER_VDDIOCTRL__TRG_STEP * __XTRACT(HW_POWER_VDDIOCTRL, TRG); + 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; + s.dcdc_freqsel = dcdc_freqsel[__XTRACT(HW_POWER_MISC, FREQSEL)]; + } + return s; +} diff --git a/firmware/target/arm/imx233/power-imx233.h b/firmware/target/arm/imx233/power-imx233.h index 4d6edaf0e2..a546b96117 100644 --- a/firmware/target/arm/imx233/power-imx233.h +++ b/firmware/target/arm/imx233/power-imx233.h @@ -52,14 +52,40 @@ #define HW_POWER_VDDDCTRL__TRG_BM 0x1f #define HW_POWER_VDDDCTRL__TRG_STEP 25 /* mV */ #define HW_POWER_VDDDCTRL__TRG_MIN 800 /* mV */ +#define HW_POWER_VDDDCTRL__ENABLE_LINREG (1 << 21) #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__TRG_STEP 25 /* mV */ +#define HW_POWER_VDDACTRL__TRG_MIN 1500 /* mV */ +#define HW_POWER_VDDACTRL__ENABLE_LINREG (1 << 17) #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__TRG_STEP 25 /* mV */ +#define HW_POWER_VDDIOCTRL__TRG_MIN 2800 /* mV */ #define HW_POWER_VDDMEMCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x70)) +#define HW_POWER_VDDMEMCTRL__TRG_BP 0 +#define HW_POWER_VDDMEMCTRL__TRG_BM 0x1f +#define HW_POWER_VDDMEMCTRL__TRG_STEP 50 /* mV */ +#define HW_POWER_VDDMEMCTRL__TRG_MIN 1700 /* mV */ +#define HW_POWER_VDDMEMCTRL__ENABLE_LINREG (1 << 8) #define HW_POWER_MISC (*(volatile uint32_t *)(HW_POWER_BASE + 0x90)) +#define HW_POWER_MISC__SEL_PLLCLK 1 +#define HW_POWER_MISC__FREQSEL_BP 4 +#define HW_POWER_MISC__FREQSEL_BM (0x7 << 4) +#define HW_POWER_MISC__FREQSEL__RES 0 +#define HW_POWER_MISC__FREQSEL__20MHz 1 +#define HW_POWER_MISC__FREQSEL__24MHz 2 +#define HW_POWER_MISC__FREQSEL__19p2MHz 3 +#define HW_POWER_MISC__FREQSEL__14p4MHz 4 +#define HW_POWER_MISC__FREQSEL__18MHz 5 +#define HW_POWER_MISC__FREQSEL__21p6MHz 6 +#define HW_POWER_MISC__FREQSEL__17p28MHz 7 #define HW_POWER_STS (*(volatile uint32_t *)(HW_POWER_BASE + 0xc0)) #define HW_POWER_STS__VBUSVALID (1 << 1) @@ -74,4 +100,26 @@ #define HW_POWER_RESET__UNLOCK 0x3E770000 #define HW_POWER_RESET__PWD 0x1 +struct imx233_power_info_t +{ + int vddd; /* in mV */ + bool vddd_linreg; /* VDDD source: linreg from VDDA or DC-DC */ + int vdda; /* in mV */ + bool vdda_linreg; /* VDDA source: linreg from VDDIO or DC-DC */ + int vddio; /* in mV */ + 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; +}; + +#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_ALL 0x1f + +struct imx233_power_info_t imx233_power_get_info(unsigned flags); + #endif /* __POWER_IMX233__ */