- New watchdog interface via watchdog.h to support Wave 7 Optics
hardware watchdog; cleanup the whole watchdog stuff
+ Patch 6 of 9:
+ - Fix length check bug in cpu/ppc4xx/i2c.c
+ - Fix special case handling (for all IBM 4xx derivatives) in
+ include/i2c.h
+ - Add new i2c_write_page function.
+
+ Patch 7 of 9:
+ - Fix and document bug in cpu/ppc4xx/serial.c concerning hardware
+ errata about the serial divisor on all 405s.
+ - Add watchdog support to cpu/ppc4xx/serial.c
+
* Add I2C support for Xicor X40430 EEPROM (ICU862 board)
* Fix comment and change overly conservative value in
#include <ppcboot.h>
#include <ppc4xx.h>
#include <405gp_i2c.h>
+#include <i2c.h>
#define IIC_OK 0
{
int rcode = 0;
- if ((alen != 2) && (alen != 3)) {
+ if ((alen < 1) || (alen > 3)) {
printf ("I2C read: addr len %d not supported\n", alen);
return 1;
}
}
#endif /* CFG_EEPROM_PAGE_WRITE_ENABLE */
+
+int i2c_write_page (uchar *addr, int alen, uchar *data, int dlen, int dsize)
+{
+ uchar xbuf[7];
+ int idx, i;
+
+ /* Validate parameters. */
+ if (alen > 3) {
+ printf("I2C write: addr len %d not supported\n", alen);
+ return 1;
+ }
+ if (dsize > 4) {
+ printf ("I2C write: data size %d not supported\n", dsize);
+ return 1;
+ }
+
+ /* write with ack polling */
+ while (dlen > 0) {
+ /* build up an output buffer */
+ idx = 0;
+
+ /* move the extra address bytes to buffer */
+ for (i = 1; i < alen; i++)
+ xbuf[idx++] = addr[i];
+
+ /* move the data to output buffer */
+ for (i = 0; ((i < dsize) && (dlen-- > 0)); i++)
+ xbuf[idx++] = *data++;
+
+ /* single write + ack polling */
+ while ((i2c_send(addr[0] << 1, idx, xbuf)) != 0) {
+ udelay(100);
+ }
+ }
+
+ return 0;
+}
+
#include <ppcboot.h>
#include <commproc.h>
#include <asm/processor.h>
+#include <watchdog.h>
#if CONFIG_SERIAL_SOFTWARE_FIFO
#include <malloc.h>
/*
* Use internal cpu clock to generate serial clock
*/
+#if 0
+ /*
+ * The divisor bits are STUCK on ALL IBM 405GP/CR Rev. D silicon.
+ * RTF Errata!
+ */
cntrl0Reg = mfdcr(cntrl0) & 0xffffe000;
cntrl0Reg |= 0x00001022;
mtdcr(cntrl0, cntrl0Reg); /* serial clock = cpu clock / 18 */
-#if 0
br_reg = (((((cpu_clock/16)/18) * 10) / baudrate) + 5) / 10 ;
#else
- /*
- * The divisor bits are STUCK on some Walnut boards.
- * Dave Updegraff <dave@cray.com> Thu, 12 Jul 2001 10:52:32 -0500
- */
+ cntrl0Reg = mfdcr(cntrl0) & 0xffffe000;
+ cntrl0Reg |= 0x0000103c;
+ mtdcr(cntrl0, cntrl0Reg); /* Divisor stuck at 31 */
br_reg = ( ( (cpu_clock / (16 * (((mfdcr(cntrl0) & 0x3e) >> 1) + 1)) * 10)
/ baudrate ) + 5 ) / 10;
#endif /* 0 */
#ifdef CFG_EXT_SERIAL_CLOCK
br_reg = (((CFG_EXT_SERIAL_CLOCK*10)/16) / baudrate + 5) / 10;
#else
+
+#if 0
+ /*
+ * The divisor bits are STUCK on ALL IBM 405GP/CR Rev. D silicon.
+ * RTF Errata!
+ */
br_reg = (((((cpu_clock/16)/18) * 10) / baudrate) + 5) / 10 ;
+#else
+ br_reg = ( ( (cpu_clock / (16 * (((mfdcr(cntrl0) & 0x3e) >> 1) + 1)) * 10)
+ / baudrate ) + 5 ) / 10;
+#endif /* 0 */
+
#endif
out8(UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
void
serial_putc(const char c)
{
- if (c == '\n')
- serial_putc ('\r');
-
- out8(UART0_BASE + UART_THR, c); /* put character out */
-
- /* check THRE bit, wait for transfer done */
- while ((in8(UART0_BASE + UART_LSR) & 0x20) != 0x20)
- ;
+ int i;
+ if (c == '\n')
+ serial_putc ('\r');
+
+ /* check THRE bit, wait for transmiter available */
+ for(i = 1; i < 3500 ; i++) {
+ if ((in8(UART0_BASE + UART_LSR) & 0x20) == 0x20)
+ break;
+#if defined(CONFIG_HW_WATCHDOG)
+ WATCHDOG_RESET(); /* Reset HW Watchdog, if needed */
+#endif /* CONFIG_HW_WATCHDOG */
+ udelay(100);
+ }
+ out8(UART0_BASE + UART_THR, c); /* put character out */
}
{
unsigned char status=0;
- while(1)
- {
+ while(1) {
+#if defined(CONFIG_HW_WATCHDOG)
+ WATCHDOG_RESET(); /* Reset HW Watchdog, if needed */
+#endif /* CONFIG_HW_WATCHDOG*/
status = in8(UART0_BASE + UART_LSR);
if ((status&asyncLSRDataReady1)!=0x0)
{
serial_buffered_putc (const char c)
{
/* Wait for CTS */
+#if defined(CONFIG_HW_WATCHDOG)
+ while (!(in8(UART0_BASE + UART_MSR) & 0x10))
+ WATCHDOG_RESET();
+#else
while (!(in8(UART0_BASE + UART_MSR) & 0x10))
;
+#endif
serial_putc(c);
}
int c;
int rx_get = buf_info.rx_get;
int rx_put;
+#if defined(CONFIG_HW_WATCHDOG)
+ while (rx_get == buf_info.rx_put)
+ WATCHDOG_RESET();
+#else
while (rx_get == buf_info.rx_put) ;
+#endif
c = buf_info.rx_buffer[rx_get++];
if (rx_get==CONFIG_SERIAL_SOFTWARE_FIFO) rx_get = 0;
buf_info.rx_get = rx_get;
int i2c_read (uchar *addr, int alen, uchar *buffer, int len);
int i2c_write (uchar *addr, int alen, uchar *buffer, int len);
-#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) || \
- defined (CONFIG_PIP405) || defined (CONFIG_W7O)
+#if defined(CONFIG_4xx) || defined(CONFIG_IOP480)
void i2c_init(void);
int i2c_receive(unsigned char address,
unsigned short size_to_expect, unsigned char datain[] );
int i2c_send(unsigned char address,
unsigned short size_to_send, unsigned char dataout[] );
+int i2c_write_page(uchar *addr, int alen, uchar *data, int dlen, int dsize);
-#else /* !CPCI405, !AR405, !WALNUT405, !ERIC */
+#else /* !( CONFIG_4xx || CONFIG_IOP480) */
uchar i2c_reg_read (uchar i2c_addr, uchar reg);
void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val);