]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
Series of patches by Erik Theisen, 25 Nov 2001:
authorwdenk <wdenk>
Mon, 26 Nov 2001 23:10:26 +0000 (23:10 +0000)
committerwdenk <wdenk>
Mon, 26 Nov 2001 23:10:26 +0000 (23:10 +0000)
  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

CHANGELOG
cpu/ppc4xx/i2c.c
cpu/ppc4xx/serial.c
include/i2c.h

index f37e6e063ff7bb69503ee51faaf55197f3ac7219..5804a8681ff67286182a15f50bf49b5596add73b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -115,6 +115,17 @@ Modifications for 1.1.2:
   - 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
index 420fa67ee8b811da151b64bf4c1f1fd019037638..4cb5246e9d497b41320ce46b4444143ea90d8341 100644 (file)
@@ -8,6 +8,7 @@
 #include <ppcboot.h>
 #include <ppc4xx.h>
 #include <405gp_i2c.h>
+#include <i2c.h>
 
 
 #define IIC_OK         0
@@ -272,7 +273,7 @@ int i2c_read (uchar *addr, int alen, uchar *buffer, int len)
 {
        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;
        }
@@ -362,3 +363,41 @@ int i2c_write (uchar *addr, int alen, uchar *buffer, int len)
 }
 #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;
+}
+
index 6ef73fd87ef114358afe6bf5e31ff05b0528ad52..88474725aed8a9a6c1797cd6b39841fab9f4fedd 100644 (file)
@@ -44,6 +44,7 @@
 #include <ppcboot.h>
 #include <commproc.h>
 #include <asm/processor.h>
+#include <watchdog.h>
 
 #if CONFIG_SERIAL_SOFTWARE_FIFO
 #include <malloc.h>
@@ -337,16 +338,19 @@ serial_init(ulong cpu_clock, int baudrate)
   /*
    * 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 */
@@ -377,7 +381,18 @@ serial_setbrg (ulong cpu_clock, int baudrate)
 #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 */
@@ -390,14 +405,20 @@ serial_setbrg (ulong cpu_clock, int baudrate)
 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 */
 }
 
 
@@ -415,8 +436,10 @@ int serial_getc()
 {
   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)
         {
@@ -513,8 +536,13 @@ void
 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);
 }
 
@@ -531,7 +559,12 @@ serial_buffered_getc (void)
   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;
index e4e6ddd91b3f74ef94e2fa31578d7127a5438b87..45b8cafef90d8b30493a58466503e5ccad38b05f 100644 (file)
 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);