diff options
| -rw-r--r-- | board/lwmon5/lwmon5.c | 19 | ||||
| -rw-r--r-- | include/configs/lwmon5.h | 92 | ||||
| -rw-r--r-- | include/post.h | 5 | ||||
| -rw-r--r-- | include/ppc440.h | 3 | ||||
| -rw-r--r-- | post/board/lwmon5/Makefile | 28 | ||||
| -rw-r--r-- | post/board/lwmon5/dsp.c | 58 | ||||
| -rw-r--r-- | post/board/lwmon5/dspic.c | 109 | ||||
| -rw-r--r-- | post/board/lwmon5/fpga.c | 104 | ||||
| -rw-r--r-- | post/board/lwmon5/gdc.c | 94 | ||||
| -rw-r--r-- | post/board/lwmon5/sysmon.c | 265 | ||||
| -rw-r--r-- | post/board/lwmon5/watchdog.c | 132 | ||||
| -rw-r--r-- | post/tests.c | 26 | 
12 files changed, 931 insertions, 4 deletions
| diff --git a/board/lwmon5/lwmon5.c b/board/lwmon5/lwmon5.c index 815c01f4e..73d5de588 100644 --- a/board/lwmon5/lwmon5.c +++ b/board/lwmon5/lwmon5.c @@ -96,6 +96,25 @@ int board_early_init_f(void)  	gpio_write_bit(CFG_GPIO_FLASH_WP, 1); +#if CONFIG_POST & CFG_POST_BSPEC1 +	gpio_write_bit(CFG_GPIO_HIGHSIDE, 1); + +	reg = 0; /* reuse as counter */ +	out_be32((void *)CFG_DSPIC_TEST_ADDR, +		in_be32((void *)CFG_DSPIC_TEST_ADDR) +			& ~CFG_DSPIC_TEST_MASK); +	while (!gpio_read_in_bit(CFG_GPIO_DSPIC_READY) && reg++ < 1000) { +		udelay(1000); +	} +	gpio_write_bit(CFG_GPIO_HIGHSIDE, 0); +	if (gpio_read_in_bit(CFG_GPIO_DSPIC_READY)) { +		/* set "boot error" flag */ +		out_be32((void *)CFG_DSPIC_TEST_ADDR, +			in_be32((void *)CFG_DSPIC_TEST_ADDR) | +			CFG_DSPIC_TEST_MASK); +	} +#endif +  	/*  	 * Reset PHY's:  	 * The PHY's need a 2nd reset pulse, since the MDIO address is latched diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h index c3f10c75a..6489e0eef 100644 --- a/include/configs/lwmon5.h +++ b/include/configs/lwmon5.h @@ -86,6 +86,15 @@  #define CFG_POST_ALT_WORD_ADDR	(CFG_PERIPHERAL_BASE + GPT0_COMP6)  						/* unused GPT0 COMP reg	*/ +/* Additional registers for watchdog timer post test */ + +#define CFG_DSPIC_TEST_ADDR	(CFG_PERIPHERAL_BASE + GPT0_COMP5) +#define CFG_WATCHDOG_TIME_ADDR	(CFG_PERIPHERAL_BASE + GPT0_COMP4) +#define CFG_WATCHDOG_FLAGS_ADDR	(CFG_PERIPHERAL_BASE + GPT0_COMP5) +#define CFG_WATCHDOG_MAGIC	0x12480000 +#define CFG_WATCHDOG_MAGIC_MASK	0xFFFF0000 +#define CFG_DSPIC_TEST_MASK	0x00000001 +  /*-----------------------------------------------------------------------   * Serial Port   *----------------------------------------------------------------------*/ @@ -156,7 +165,81 @@  				 CFG_POST_MEMORY   | \  				 CFG_POST_RTC      | \  				 CFG_POST_SPR      | \ -				 CFG_POST_UART) +				 CFG_POST_UART     | \ +				 CFG_POST_SYSMON   | \ +				 CFG_POST_WATCHDOG | \ +				 CFG_POST_DSP      | \ +				 CFG_POST_BSPEC1   | \ +				 CFG_POST_BSPEC2   | \ +				 CFG_POST_BSPEC3   | \ +				 CFG_POST_BSPEC4   | \ +				 CFG_POST_BSPEC5) + +#define CONFIG_POST_WATCHDOG  {\ +	"Watchdog timer test",				\ +	"watchdog",					\ +	"This test checks the watchdog timer.",		\ +	POST_RAM | POST_POWERON | POST_SLOWTEST | POST_MANUAL | POST_REBOOT, \ +	&lwmon5_watchdog_post_test,			\ +	NULL,						\ +	NULL,						\ +	CFG_POST_WATCHDOG				\ +	} + +#define CONFIG_POST_BSPEC1    {\ +	"dsPIC init test",				\ +	"dspic_init",					\ +	"This test returns result of dsPIC READY test run earlier.",	\ +	POST_RAM | POST_ALWAYS,				\ +	&dspic_init_post_test,				\ +	NULL,						\ +	NULL,						\ +	CFG_POST_BSPEC1					\ +	} + +#define CONFIG_POST_BSPEC2    {\ +	"dsPIC test",					\ +	"dspic",					\ +	"This test gets result of dsPIC POST and dsPIC version.",	\ +	POST_RAM | POST_ALWAYS,				\ +	&dspic_post_test,				\ +	NULL,						\ +	NULL,						\ +	CFG_POST_BSPEC2					\ +	} + +#define CONFIG_POST_BSPEC3    {\ +	"FPGA test",					\ +	"fpga",						\ +	"This test checks FPGA registers and memory.",	\ +	POST_RAM | POST_ALWAYS,				\ +	&fpga_post_test,				\ +	NULL,						\ +	NULL,						\ +	CFG_POST_BSPEC3					\ +	} + +#define CONFIG_POST_BSPEC4    {\ +	"GDC test",					\ +	"gdc",						\ +	"This test checks GDC registers and memory.",	\ +	POST_RAM | POST_ALWAYS,				\ +	&gdc_post_test,					\ +	NULL,						\ +	NULL,						\ +	CFG_POST_BSPEC4					\ +	} + +#define CONFIG_POST_BSPEC5    {\ +	"SYSMON1 test",					\ +	"sysmon1",					\ +	"This test checks GPIO_62_EPX pin indicating power failure.",	\ +	POST_RAM | POST_MANUAL | POST_NORMAL | POST_SLOWTEST,	\ +	&sysmon1_post_test,				\ +	NULL,						\ +	NULL,						\ +	CFG_POST_BSPEC5					\ +	}  #define CFG_POST_CACHE_ADDR	0x7fff0000 /* free virtual address	*/  #define CONFIG_LOGBUFFER @@ -181,6 +264,7 @@  #define CONFIG_RTC_PCF8563	1		/* enable Philips PCF8563 RTC	*/  #define CFG_I2C_RTC_ADDR	0x51		/* Philips PCF8563 RTC address	*/  #define CFG_I2C_KEYBD_ADDR	0x56		/* PIC LWE keyboard		*/ +#define CFG_I2C_DSPIC_IO_ADDR	0x57		/* PIC I/O addr               */  #define	CONFIG_POST_KEY_MAGIC	"3C+3E"	/* press F3 + F5 keys to force POST */  #if 0 @@ -366,9 +450,6 @@  #define CFG_PCI_SUBSYS_VENDORID 0x10e8	/* AMCC				*/  #define CFG_PCI_SUBSYS_ID       0xcafe	/* Whatever			*/ -/* - * ToDo: Watchdog is not test fully, so exclude it for now - */  #define CONFIG_HW_WATCHDOG	1	/* Use external HW-Watchdog	*/  #define CONFIG_WD_PERIOD	40000	/* in usec */ @@ -431,10 +512,13 @@  #define CFG_GPIO_PHY1_RST	12  #define CFG_GPIO_FLASH_WP	14  #define CFG_GPIO_PHY0_RST	22 +#define CFG_GPIO_DSPIC_READY	51  #define CFG_GPIO_EEPROM_EXT_WP	55 +#define CFG_GPIO_HIGHSIDE	56  #define CFG_GPIO_EEPROM_INT_WP	57  #define CFG_GPIO_LIME_S		59  #define CFG_GPIO_LIME_RST	60 +#define CFG_GPIO_SYSMON_STATUS	62  #define CFG_GPIO_WATCHDOG	63  /*----------------------------------------------------------------------- diff --git a/include/post.h b/include/post.h index c8062bbbc..12c0e9200 100644 --- a/include/post.h +++ b/include/post.h @@ -93,6 +93,11 @@ extern int post_hotkeys_pressed(void);  #define CFG_POST_CODEC		0x00002000  #define CFG_POST_FPU		0x00004000  #define CFG_POST_ECC		0x00008000 +#define CFG_POST_BSPEC1		0x00010000 +#define CFG_POST_BSPEC2		0x00020000 +#define CFG_POST_BSPEC3		0x00040000 +#define CFG_POST_BSPEC4		0x00080000 +#define CFG_POST_BSPEC5		0x00100000  #endif /* CONFIG_POST */ diff --git a/include/ppc440.h b/include/ppc440.h index 80dd33235..6e3b68d67 100644 --- a/include/ppc440.h +++ b/include/ppc440.h @@ -1431,6 +1431,9 @@  #define   SDR0_MFR_PKT_REJ_POL         0x00200000   /* Packet Reject Polarity */  #define GPT0_COMP6			0x00000098 +#define GPT0_COMP5			0x00000094 +#define GPT0_COMP4			0x00000090 +#define GPT0_COMP3			0x0000008C  #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)  #define SDR0_USB2D0CR                 0x0320 diff --git a/post/board/lwmon5/Makefile b/post/board/lwmon5/Makefile new file mode 100644 index 000000000..5a92d1ce7 --- /dev/null +++ b/post/board/lwmon5/Makefile @@ -0,0 +1,28 @@ +# +# (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com +# +# Developed for DENX Software Engineering GmbH +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA + +LIB	= libpostlwmon5.a + +COBJS	= sysmon.o watchdog.o dspic.o fpga.o dsp.o gdc.o + +include $(TOPDIR)/post/rules.mk diff --git a/post/board/lwmon5/dsp.c b/post/board/lwmon5/dsp.c new file mode 100644 index 000000000..7b53af992 --- /dev/null +++ b/post/board/lwmon5/dsp.c @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com + * + * Developed for DENX Software Engineering GmbH + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#ifdef CONFIG_POST + +#include <post.h> + + +#if CONFIG_POST & CFG_POST_DSP +#include <asm/io.h> + +/* This test verifies DSP status bits in FPGA */ + +DECLARE_GLOBAL_DATA_PTR; + +#define DSP_STATUS_REG 0xC4000008 + +int dsp_post_test(int flags) +{ +	uint   read_value; +	int    ret; + +	ret = 0; +	read_value = in_be32((void *)DSP_STATUS_REG) & 0x3; +	if (read_value != 0x3) { +		post_log("\nDSP status read %08X\n", read_value); +		ret = 1; +	} + +	return ret; +} + +#endif /* CONFIG_POST & CFG_POST_DSP */ +#endif /* CONFIG_POST */ + diff --git a/post/board/lwmon5/dspic.c b/post/board/lwmon5/dspic.c new file mode 100644 index 000000000..e8fed89ba --- /dev/null +++ b/post/board/lwmon5/dspic.c @@ -0,0 +1,109 @@ +/* + * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com + * + * Developed for DENX Software Engineering GmbH + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#ifdef CONFIG_POST + +/* There are two tests for dsPIC currently implemented: + * 1. dsPIC ready test. Done in board_early_init_f(). Only result verified here. + * 2. dsPIC POST result test.  This test gets dsPIC POST codes and version. + */ + +#include <post.h> + +#include <i2c.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define DSPIC_POST_ERROR_REG	0x800 +#define DSPIC_SYS_ERROR_REG	0x802 +#define DSPIC_VERSION_REG	0x804 + +#if CONFIG_POST & CFG_POST_BSPEC1 + +/* Verify that dsPIC ready test done early at hw init passed ok */ +int dspic_init_post_test(int flags) +{ +	if (in_be32((void *)CFG_DSPIC_TEST_ADDR) & CFG_DSPIC_TEST_MASK) { +		post_log("dsPIC init test failed\n"); +		return 1; +	} + +	return 0; +} + +#endif /* CONFIG_POST & CFG_POST_BSPEC1 */ + +#if CONFIG_POST & CFG_POST_BSPEC2 +/* Read a register from the dsPIC. */ +int dspic_read(ushort reg) +{ +	uchar buf[2]; + +	if (i2c_read(CFG_I2C_DSPIC_IO_ADDR, reg, 2, buf, 2)) +		return -1; + +	return (uint)((buf[0] << 8) | buf[1]); +} + +/* Verify error codes regs, display version */ +int dspic_post_test(int flags) +{ +	int data; +	int ret = 0; + +	post_log("\n"); +	data = dspic_read(DSPIC_VERSION_REG); +	if (data == -1) { +		post_log("dsPIC : failed read version\n"); +		ret = 1; +	} else { +		post_log("dsPIC version: %u.%u\n", +			(data >> 8) & 0xFF, data & 0xFF); +	} + +	data = dspic_read(DSPIC_POST_ERROR_REG); +	if (data != 0) ret = 1; +	if (data == -1) { +		post_log("dsPIC : failed read POST code\n"); +	} else { +		post_log("dsPIC POST code 0x%04X\n", data); +	} + +	data = dspic_read(DSPIC_SYS_ERROR_REG); +	if (data != 0) ret = 1; +	if (data == -1) { +		post_log("dsPIC : failed read system error\n"); +	} else { +		post_log("dsPIC SYS-ERROR code: 0x%04X\n", data); +	} + +	return ret; +} + +#endif /* CONFIG_POST & CFG_POST_BSPEC2 */ +#endif /* CONFIG_POST */ + diff --git a/post/board/lwmon5/fpga.c b/post/board/lwmon5/fpga.c new file mode 100644 index 000000000..4e3f1d5cd --- /dev/null +++ b/post/board/lwmon5/fpga.c @@ -0,0 +1,104 @@ +/* + * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com + * + * Developed for DENX Software Engineering GmbH + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#ifdef CONFIG_POST + +/* This test performs testing of FPGA SCRATCH register, + * gets FPGA version and run get_ram_size() on FPGA memory + */ + +#include <post.h> + +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define FPGA_SCRATCH_REG	0xC4000050 +#define FPGA_VERSION_REG	0xC4000040 +#define FPGA_RAM_START		0xC4200000 +#define FPGA_RAM_END		0xC4203FFF + +#define FPGA_PWM_CTRL_REG	0xC4000020 +#define FPGA_PWM_TV_REG		0xC4000024 + +/* Turn on backlight, set brightness */ +void fpga_backlight_enable(int pwm) +{ +	out_be16((void *)FPGA_PWM_CTRL_REG, 0x0701); +	out_be16((void *)FPGA_PWM_TV_REG, pwm); +} + +#if CONFIG_POST & CFG_POST_BSPEC3 + +static int one_scratch_test(uint value) +{ +	uint read_value; +	int ret = 0; + +	out_be32((void *)FPGA_SCRATCH_REG, value); +	/* read other location (protect against data lines capacity) */ +	ret = in_be16((void *)FPGA_VERSION_REG); +	/* verify test pattern */ +	read_value = in_be32((void *)FPGA_SCRATCH_REG); +	if (read_value != value) { +		post_log("FPGA SCRATCH test failed write %08X, read %08X\n", +			value, read_value); +		ret = 1; +	} + +	return ret; +} + +/* Verify FPGA, get version & memory size */ +int fpga_post_test(int flags) +{ +	uint   old_value; +	ushort version; +	uint   read_value; +	int    ret = 0; + +	post_log("\n"); +	old_value = in_be32((void *)FPGA_SCRATCH_REG); + +	if (one_scratch_test(0x55555555)) +		ret = 1; +	if (one_scratch_test(0xAAAAAAAA)) +		ret = 1; + +	out_be32((void *)FPGA_SCRATCH_REG, old_value); + +	version = in_be16((void *)FPGA_VERSION_REG); +	post_log("FPGA : version %u.%u\n", +		(version >> 8) & 0xFF, version & 0xFF); + +	read_value = get_ram_size((void *)CFG_FPGA_BASE_1, 0x4000); +	post_log("FPGA RAM size: %d bytes\n", read_value); + +	return ret; +} + +#endif /* CONFIG_POST & CFG_POST_BSPEC3 */ +#endif /* CONFIG_POST */ + diff --git a/post/board/lwmon5/gdc.c b/post/board/lwmon5/gdc.c new file mode 100644 index 000000000..76e5dd62e --- /dev/null +++ b/post/board/lwmon5/gdc.c @@ -0,0 +1,94 @@ +/* + * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com + * + * Developed for DENX Software Engineering GmbH + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#ifdef CONFIG_POST + +/* This test attempts to verify board GDC. A scratch register tested, then + * simple memory test (get_ram_size()) run over GDC memory. + */ + +#include <post.h> + +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define GDC_SCRATCH_REG 0xC1FF8044 +#define GDC_VERSION_REG 0xC1FF8084 +#define GDC_RAM_START   0xC0000000 +#define GDC_RAM_END     0xC2000000 + +#if CONFIG_POST & CFG_POST_BSPEC4 + +static int gdc_test_reg_one(uint value) +{ +	int ret = 0; +	uint read_value; + +	/* write test pattern */ +	out_be32((void *)GDC_SCRATCH_REG, value); +	/* read other location (protect against data lines capacity) */ +	ret = in_be32((void *)GDC_RAM_START); +	/* verify test pattern */ +	read_value = in_be32((void *)GDC_SCRATCH_REG); +	if (read_value != value) { +		post_log("GDC SCRATCH test failed write %08X, read %08X\n", +			value, read_value); +		ret = 1; +	} + +	return ret; +} + +/* Verify GDC, get memory size */ +int gdc_post_test(int flags) +{ +	uint   old_value; +	int    ret = 0; + +	post_log("\n"); +	old_value = in_be32((void *)GDC_SCRATCH_REG); + +	if (gdc_test_reg_one(0x55555555)) +		ret = 1; +	if (gdc_test_reg_one(0xAAAAAAAA)) +		ret = 1; + +	out_be32((void *)GDC_SCRATCH_REG, old_value); + +	old_value = in_be32((void *)GDC_VERSION_REG); +	post_log("GDC chip version %u.%u, year %04X\n", +		(old_value >> 8) & 0xFF, old_value & 0xFF, +		(old_value >> 16) & 0xFFFF); + +	old_value = get_ram_size((void *)GDC_RAM_START, +				 GDC_RAM_END - GDC_RAM_START); +	post_log("GDC RAM size: %d bytes\n", old_value); + +	return ret; +} +#endif /* CONFIG_POST & CFG_POST_BSPEC4 */ +#endif /* CONFIG_POST */ + diff --git a/post/board/lwmon5/sysmon.c b/post/board/lwmon5/sysmon.c new file mode 100644 index 000000000..0eae4c151 --- /dev/null +++ b/post/board/lwmon5/sysmon.c @@ -0,0 +1,265 @@ +/* + * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com + * + * Developed for DENX Software Engineering GmbH + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <post.h> +#include <common.h> + +#ifdef CONFIG_POST + +/* + * SYSMON test + * + * This test performs the system hardware monitoring. + * The test passes when all the following voltages and temperatures + * are within allowed ranges: + * + * Temperature                -40 .. +85 C + * +5V                      +4.75 .. +5.25 V + * +5V standby              +4.75 .. +5.25 V + * + * LCD backlight is not enabled if temperature values are not within + * allowed ranges (-30 .. + 80). The brightness of backlite can be + * controlled by setting "brightness" enviroment variable. Default value is 50% + * + * See the list of all parameters in the sysmon_table below + */ + +#include <post.h> +#include <watchdog.h> +#include <i2c.h> + +#if CONFIG_POST & CFG_POST_SYSMON + +DECLARE_GLOBAL_DATA_PTR; + +#define DEFAULT_BRIGHTNESS 50 + +/* from dspic.c */ +extern int dspic_read(ushort reg); +/* from fpga.c */ +extern void fpga_backlight_enable(int v); + +static int sysmon_temp_invalid; + +#define	RELOC(x) if (x != NULL) x = (void *) ((ulong) (x) + gd->reloc_off) + +typedef struct sysmon_s sysmon_t; +typedef struct sysmon_table_s sysmon_table_t; + +static void sysmon_dspic_init (sysmon_t * this); +static int sysmon_dspic_read (sysmon_t * this, uint addr); +static void sysmon_backlight_disable (sysmon_table_t * this); +static void sysmon_backlight_enable (sysmon_table_t * this); + +struct sysmon_s +{ +	uchar	chip; +	void	(*init)(sysmon_t *); +	int	(*read)(sysmon_t *, uint); +}; + +static sysmon_t sysmon_dspic = +	{CFG_I2C_DSPIC_IO_ADDR, sysmon_dspic_init, sysmon_dspic_read}; + +static sysmon_t * sysmon_list[] = +{ +	&sysmon_dspic, +	NULL +}; + +struct sysmon_table_s +{ +	char *		name; +	char *		unit_name; +	sysmon_t *	sysmon; +	void		(*exec_before)(sysmon_table_t *); +	void		(*exec_after)(sysmon_table_t *); + +	int		unit_precision; +	int		unit_div; +	int		unit_min; +	int		unit_max; +	uint		val_mask; +	uint		val_min; +	uint		val_max; +	int		val_valid; +	uint		val_min_alt; +	uint		val_max_alt; +	int		val_valid_alt; +	uint		addr; +}; + +static sysmon_table_t sysmon_table[] = +{ +    {"Temperature", " C", &sysmon_dspic, NULL, sysmon_backlight_disable, +     1, 1, -32768, 32767, 0xFFFF, 0x8000-40, 0x8000+85, 0, +                                  0x8000-30, 0x8000+80, 0, 0x12BC}, + +    {"+ 5 V", "V", &sysmon_dspic, NULL, NULL, +     100, 1000, -0x8000, 0x7FFF, 0xFFFF, 0x8000+4750, 0x8000+5250, 0, +                                         0x8000+4750, 0x8000+5250, 0, 0x12CA}, + +    {"+ 5 V standby", "V", &sysmon_dspic, NULL, sysmon_backlight_enable, +     100, 1000, -0x8000, 0x7FFF, 0xFFFF, 0x8000+4750, 0x8000+5250, 0, +                                         0x8000+4750, 0x8000+5250, 0, 0x12C6}, +}; +static int sysmon_table_size = sizeof(sysmon_table) / sizeof(sysmon_table[0]); + +int sysmon_init_f (void) +{ +	sysmon_t ** l; + +	for (l = sysmon_list; *l; l++) +		(*l)->init(*l); + +	return 0; +} + +void sysmon_reloc (void) +{ +	sysmon_t ** l; +	sysmon_table_t * t; + +	for (l = sysmon_list; *l; l++) { +		RELOC(*l); +		RELOC((*l)->init); +		RELOC((*l)->read); +	} + +	for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++) { +		RELOC(t->exec_before); +		RELOC(t->exec_after); +		RELOC(t->sysmon); +	} +} + +static char *sysmon_unit_value (sysmon_table_t *s, uint val) +{ +	static char buf[32]; +	char *p, sign; +	int decimal, frac; +	int unit_val; + +	unit_val = +	    s->unit_min + (s->unit_max - s->unit_min) * val / s->val_mask; + +	if (val == -1) +		return "I/O ERROR"; + +	if (unit_val < 0) { +		sign = '-'; +		unit_val = -unit_val; +	} else +		sign = '+'; + +	p = buf + sprintf(buf, "%c%2d", sign, unit_val / s->unit_div); + + +	frac = unit_val % s->unit_div; + +	frac /= (s->unit_div / s->unit_precision); + +	decimal = s->unit_precision; + +	if (decimal != 1) +		*p++ = '.'; +	for (decimal /= 10; decimal != 0; decimal /= 10) +		*p++ = '0' + (frac / decimal) % 10; +	strcpy(p, s->unit_name); + +	return buf; +} + +static void sysmon_dspic_init (sysmon_t * this) +{ +} + +static int sysmon_dspic_read (sysmon_t * this, uint addr) +{ +	int res = dspic_read(addr); + +	/* To fit into the table range we should add 0x8000 */ +	return (res == -1) ? -1 : (res + 0x8000); +} + +static void sysmon_backlight_disable (sysmon_table_t * this) +{ +	if (!this->val_valid_alt) +		sysmon_temp_invalid = 1; +} + +static void sysmon_backlight_enable (sysmon_table_t * this) +{ +	char * param; +	int rc; + +	if (!sysmon_temp_invalid) { +		param = getenv("brightness"); +		rc = param ? simple_strtol(param, NULL, 10) : -1; +		if (rc >= 0) +			fpga_backlight_enable(rc); +		else +			fpga_backlight_enable(DEFAULT_BRIGHTNESS); +	} +} + +int sysmon_post_test (int flags) +{ +	int res = 0; +	sysmon_table_t * t; +	int val; + +	for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++) { +		if (t->exec_before) +			t->exec_before(t); + +		val = t->sysmon->read(t->sysmon, t->addr); +		if (val != -1) { +			t->val_valid = val >= t->val_min && val <= t->val_max; +			t->val_valid_alt = val >= t->val_min_alt && val <= t->val_max_alt; +		} else { +			t->val_valid = 0; +			t->val_valid_alt = 0; +		} + +		if (t->exec_after) +			t->exec_after(t); + +		if ((!t->val_valid) || (flags & POST_MANUAL)) { +			printf("%-17s = %-10s ", t->name, sysmon_unit_value(t, val)); +			printf("allowed range"); +			printf(" %-8s ..", sysmon_unit_value(t, t->val_min)); +			printf(" %-8s", sysmon_unit_value(t, t->val_max)); +			printf("     %s\n", t->val_valid ? "OK" : "FAIL"); +		} + +		if (!t->val_valid) +			res = 1; +	} + +	return res; +} + +#endif /* CONFIG_POST & CFG_POST_SYSMON */ +#endif /* CONFIG_POST */ diff --git a/post/board/lwmon5/watchdog.c b/post/board/lwmon5/watchdog.c new file mode 100644 index 000000000..ad9e6f384 --- /dev/null +++ b/post/board/lwmon5/watchdog.c @@ -0,0 +1,132 @@ +/* + * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com + * + * Developed for DENX Software Engineering GmbH + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +/* This test verifies if the reason of last reset was an abnormal voltage + * condition, than it performs watchdog test, measuing time required to + * trigger watchdog reset. + */ + +#ifdef CONFIG_POST + +#include <post.h> + +#if CONFIG_POST & CFG_POST_WATCHDOG + +#include <watchdog.h> +#include <asm/gpio.h> +#include <asm/io.h> + +static uint watchdog_magic_read(void) +{ +	return in_be32((void *)CFG_WATCHDOG_FLAGS_ADDR) & +		CFG_WATCHDOG_MAGIC_MASK; +} + +static void watchdog_magic_write(uint value) +{ +	out_be32((void *)CFG_WATCHDOG_FLAGS_ADDR, value | +		(in_be32((void *)CFG_WATCHDOG_FLAGS_ADDR) & +			~CFG_WATCHDOG_MAGIC_MASK)); +} + +int sysmon1_post_test(int flags) +{ +	if (gpio_read_in_bit(CFG_GPIO_SYSMON_STATUS)) { +		/* 3.1. GPIO62 is low +		 * Assuming system voltage failure. +		 */ +		post_log("Abnormal voltage detected (GPIO62)\n"); +		return 1; +	} + +	return 0; +} + +int lwmon5_watchdog_post_test(int flags) +{ +	/* On each reset scratch register 1 should be tested, +	 * but first test GPIO62: +	 */ +	if (!(flags & POST_MANUAL) && sysmon1_post_test(flags)) { +		/* 3.1. GPIO62 is low +		 * Assuming system voltage failure. +		 */ +		/* 3.1.1. Set scratch register 1 to 0x0000xxxx */ +		watchdog_magic_write(0); +		/* 3.1.2. Mark test as failed due to voltage?! */ +		return 1; +	} + +	if (watchdog_magic_read() != CFG_WATCHDOG_MAGIC) { +		/* 3.2. Scratch register 1 differs from magic value 0x1248xxxx +		 * Assuming PowerOn +		 */ +		int ints; +		ulong base; +		ulong time; + +		/* 3.2.1. Set magic value to scratch register */ +		watchdog_magic_write(CFG_WATCHDOG_MAGIC); + +		ints = disable_interrupts (); +		/* 3.2.2. strobe watchdog once */ +		WATCHDOG_RESET(); +		out_be32((void *)CFG_WATCHDOG_TIME_ADDR, 0); +		/* 3.2.3. save time of strobe in scratch register 2 */ +		base = post_time_ms (0); + +		/* 3.2.4. Wait for 150 ms (enough for reset to happen) */ +		while ((time = post_time_ms (base)) < 150) +			out_be32((void *)CFG_WATCHDOG_TIME_ADDR, time); +		if (ints) +			enable_interrupts (); + +		/* 3.2.5. Reset didn't happen. - Set 0x0000xxxx +		 * into scratch register 1 +		 */ +		watchdog_magic_write(0); +		/* 3.2.6. Mark test as failed. */ +		post_log("hw watchdog time : %u ms, failed ", time); +		return 2; +	} else { +		/* 3.3. Scratch register matches magic value 0x1248xxxx +		 * Assume this is watchdog-initiated reset +		 */ +		ulong time; +		/* 3.3.1. So, the test succeed, save measured time to syslog. */ +		time = in_be32((void *)CFG_WATCHDOG_TIME_ADDR); +		post_log("hw watchdog time : %u ms, passed ", time); +		/* 3.3.2. Set scratch register 1 to 0x0000xxxx */ +		watchdog_magic_write(0); +		return 0; +	} +	return -1; +} + + +#endif /* CONFIG_POST & CFG_POST_WATCHDOG */ +#endif /* CONFIG_POST */ + diff --git a/post/tests.c b/post/tests.c index ed4ef2b50..53d01e355 100644 --- a/post/tests.c +++ b/post/tests.c @@ -48,6 +48,13 @@ extern int dsp_post_test (int flags);  extern int codec_post_test (int flags);  extern int ecc_post_test (int flags); +extern int dspic_init_post_test (int flags); +extern int dspic_post_test (int flags); +extern int gdc_post_test (int flags); +extern int fpga_post_test (int flags); +extern int lwmon5_watchdog_post_test(int flags); +extern int sysmon1_post_test(int flags); +  extern int sysmon_init_f (void);  extern void sysmon_reloc (void); @@ -68,6 +75,9 @@ struct post_test post_list[] =      },  #endif  #if CONFIG_POST & CFG_POST_WATCHDOG +#if defined(CONFIG_POST_WATCHDOG) +	CONFIG_POST_WATCHDOG, +#else      {  	"Watchdog timer test",  	"watchdog", @@ -79,6 +89,7 @@ struct post_test post_list[] =  	CFG_POST_WATCHDOG      },  #endif +#endif  #if CONFIG_POST & CFG_POST_I2C      {  	"I2C test", @@ -249,6 +260,21 @@ struct post_test post_list[] =  	CFG_POST_ECC      },  #endif +#if CONFIG_POST & CFG_POST_BSPEC1 +	CONFIG_POST_BSPEC1, +#endif +#if CONFIG_POST & CFG_POST_BSPEC2 +	CONFIG_POST_BSPEC2, +#endif +#if CONFIG_POST & CFG_POST_BSPEC3 +	CONFIG_POST_BSPEC3, +#endif +#if CONFIG_POST & CFG_POST_BSPEC4 +	CONFIG_POST_BSPEC4, +#endif +#if CONFIG_POST & CFG_POST_BSPEC4 +	CONFIG_POST_BSPEC5, +#endif  };  unsigned int post_list_size = sizeof (post_list) / sizeof (struct post_test); |