[U-Boot] [PATCH 2/2] MX28: Add LRADC dump into SPL debug
Marek Vasut
marex at denx.de
Wed Aug 29 03:14:21 CEST 2012
This is useful if the power management on the chip isn't properly
initialized. It's possible to use the internal LRADC to sample various
power rails and debug the problem.
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Wolfgang Denk <wd at denx.de>
Cc: Stefano Babic <sbabic at denx.de>
Cc: Fabio Estevam <fabio.estevam at freescale.com>
---
arch/arm/cpu/arm926ejs/mxs/mxs_init.h | 2 +
arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 3 ++
arch/arm/cpu/arm926ejs/mxs/spl_debug.c | 89 ++++++++++++++++++++++++++++++++
3 files changed, 94 insertions(+)
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs_init.h b/arch/arm/cpu/arm926ejs/mxs/mxs_init.h
index e6f837c..acb62fa 100644
--- a/arch/arm/cpu/arm926ejs/mxs/mxs_init.h
+++ b/arch/arm/cpu/arm926ejs/mxs/mxs_init.h
@@ -44,8 +44,10 @@ void mxs_lradc_enable_batt_measurement(void);
#ifdef CONFIG_MX28_DEBUG
void mx28_common_spl_debug_halt(void);
+void mx28_read_lradc(void);
#else
static inline void mx28_common_spl_debug_halt(void) {}
+static inline void mx28_read_lradc(void) {}
#endif
#endif /* __M28_INIT_H__ */
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
index f4f0c09..ea52a53 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -104,6 +104,9 @@ void mxs_common_spl_init(const iomux_cfg_t *iomux_setup,
mxs_power_init();
mxs_mem_init();
+
+ mx28_read_lradc();
+
data->mem_dram_size = mxs_mem_get_size();
data->boot_mode_idx = bootmode;
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_debug.c b/arch/arm/cpu/arm926ejs/mxs/spl_debug.c
index f0aef20..51f9b79 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_debug.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_debug.c
@@ -61,3 +61,92 @@ void mx28_common_spl_debug_halt(void)
/* Both magic values matched, hang. */
asm volatile("x: b x\n");
}
+
+static void my_print_int(uint32_t val)
+{
+ /* 0xffffffff = 4,294,967,295 */
+ char buf[10] = {0};
+ int i = 0;
+
+ if (!val) {
+ serial_putc('0');
+ return;
+ }
+
+ for (i = 0; i < 9; i++) {
+ buf[i] = val % 10;
+ val /= 10;
+ }
+
+ for (; i >= 0; i--)
+ if (buf[i])
+ break;
+ for (; i >= 0; i--)
+ serial_putc(buf[i] + '0');
+}
+
+static const char * const mx28_lradc_chan_names[16] = {
+ "[General Purpose 0]",
+ "[General Purpose 1]",
+ "[General Purpose 2]",
+ "[General Purpose 3]",
+ "[General Purpose 4]",
+ "[General Purpose 5]",
+ "[General Purpose 6]",
+ "[General Purpose 7 / Battery]",
+ "[Temperature sense 0]",
+ "[Temperature sense 1]",
+ "[VDDIO]",
+ "[VTH]",
+ "[VDDA]",
+ "[VDDD]",
+ "[VBG]",
+ "[5V input]",
+};
+
+static void mx28_read_lradc_chans(int offset)
+{
+ struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE;
+ int i;
+ uint32_t val;
+
+ mxs_reset_block(®s->hw_lradc_ctrl0_reg);
+
+ /* Flush the block */
+ writel(0, ®s->hw_lradc_ctrl0);
+ writel(0, ®s->hw_lradc_ctrl1);
+ writel(0, ®s->hw_lradc_ctrl2);
+ writel(0, ®s->hw_lradc_ctrl3);
+
+ /* Empty the channels */
+ for (i = 0; i < 8; i++)
+ writel(0, ®s->hw_lradc_ch0_reg + i);
+
+ /* Map channels and trigger them */
+ writel(offset ? 0xfedcba98 : 0x76543210, ®s->hw_lradc_ctrl4);
+ writel(0xff, ®s->hw_lradc_ctrl0_set);
+
+ while ((readl(®s->hw_lradc_ctrl1) & 0xff) != 0xff)
+ ;
+
+ /* Read and report the channels */
+ for (i = 0; i < 8; i++) {
+ val = readl(®s->hw_lradc_ch0_reg + i);
+ val &= LRADC_CH_VALUE_MASK;
+ serial_puts("Channel ");
+ my_print_int(i + (offset * 8));
+ serial_putc(' ');
+ serial_puts(mx28_lradc_chan_names[i + (offset * 8)]);
+ serial_puts(" = ");
+ my_print_int(val);
+ serial_putc('\n');
+ }
+}
+
+void mx28_read_lradc(void)
+{
+ serial_init();
+ serial_putc('\n');
+ mx28_read_lradc_chans(0);
+ mx28_read_lradc_chans(1);
+}
--
1.7.10.4
More information about the U-Boot
mailing list