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 <ma...@denx.de>
Cc: Wolfgang Denk <w...@denx.de>
Cc: Stefano Babic <sba...@denx.de>
Cc: Fabio Estevam <fabio.este...@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(&regs->hw_lradc_ctrl0_reg);
+
+       /* Flush the block */
+       writel(0, &regs->hw_lradc_ctrl0);
+       writel(0, &regs->hw_lradc_ctrl1);
+       writel(0, &regs->hw_lradc_ctrl2);
+       writel(0, &regs->hw_lradc_ctrl3);
+
+       /* Empty the channels */
+       for (i = 0; i < 8; i++)
+               writel(0, &regs->hw_lradc_ch0_reg + i);
+
+       /* Map channels and trigger them */
+       writel(offset ? 0xfedcba98 : 0x76543210, &regs->hw_lradc_ctrl4);
+       writel(0xff, &regs->hw_lradc_ctrl0_set);
+
+       while ((readl(&regs->hw_lradc_ctrl1) & 0xff) != 0xff)
+               ;
+
+       /* Read and report the channels */
+       for (i = 0; i < 8; i++) {
+               val = readl(&regs->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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to