[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(&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



More information about the U-Boot mailing list