Changeset 3725

Show
Ignore:
Timestamp:
11/18/02 22:35:27 (11 years ago)
Author:
mds
Message:

(mds)
Date: Thu, 24 Oct 2002 20:21:50 +0200
From: Joakim Tjernlund <joakim.tjernlund@…>
To: Tom Rini <trini@…>


Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c


Can you please split this into logical chunks, or give me a list of each
fix in here? Thanks.

ohh, kind of hard to remember all that went into that patch. The path
has evoled over many days, but I can try summarize. I have tested this code
pretty well it does not fail for me. Speed has been between 10-150KHz. The
old code fails as soon you start to stress it a little.

  • replace invalidate_dcache_range with flush_dcache_range, since buffers are NOT cache aligned. flush will write to memory AND invalidate the cache.
  • move the chip errata stuff from irq routine into read/write routines. Made it default off since it causes lock ups on my I2C device. I think it causes a too short STOP condition. If enabled I2C will behave better than before, but may still cause problems if the read/write is interrupted with a signal while microcode is enabled.
  • set default speed to 60 KHz instead.
  • missing/faulty initialization of parameter ram when I2C micro patch is active.
  • replaced assingments with mask operations with relevant bits. Example:

/* Shut down IIC. */
i2c->i2c_i2mod = 0;

i2c->i2c_i2mod &= ~1;

  • When reading from I2C device, let the receive BD generate interrupt instead of the dummy trasmit. This is important since the TX interrupt will be too early sometimes, before the RX BD has closed. There is one case where the RX irq is before the TX irq, if iic_mrblr is set to match the number of bytes to read. Therefore must the iic_mrblr be one byte larger than the expected number of bytes.
  • busy wait for small transfers since it's faster.
  • save_flags(flags); cli(); cleanups
  • interruptible_sleep_on_timeout() instead of interruptible_sleep_on() so it won't hang forever if an irq is lost.

Jocke

=======================

Sender: Tom Rini <trini@…>

On Mon, Nov 18, 2002 at 02:04:21PM -0500, Mark D. Studebaker wrote:

whatever your patch was against didn't match our tree very well. would
you please
resolve the differences and generate a new patch against our tree?
thanks

Here's a patch vs current i2c CVS (HEAD, if that makes a difference),
which brings things back into line.

Let me know when you commit this, and I'll bring the linuxppc BK trees
back into line.

--
Tom Rini (TR1265)
 http://gate.crashing.org/~trini/

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • i2c/trunk/kernel/i2c-algo-8xx.c

    r3682 r3725  
    4545 
    4646#define CPM_MAX_READ    513 
    47  
     47/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */ 
    4848static wait_queue_head_t iic_wait; 
    4949static ushort r_tbase, r_rbase; 
    5050 
    51 int cpm_scan = 1; 
     51int cpm_scan = 0; 
    5252int cpm_debug = 0; 
    5353 
    54 static void 
    55 cpm_iic_interrupt(void *dev_id, void *regs) 
     54static  void 
     55cpm_iic_interrupt(void *dev_id, struct pt_regs *regs) 
    5656{ 
    5757        volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id; 
    58  
    5958        if (cpm_debug > 1) 
    6059                printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id); 
    61  
    62         /* Chip errata, clear enable. 
    63         */ 
    64         i2c->i2c_i2mod = 0; 
    65  
     60#if 0 
     61        /* Chip errata, clear enable. This is not needed on rev D4 CPUs */ 
     62        /* This should probably be removed and replaced by I2C_CHIP_ERRATA stuff */ 
     63        /* Someone with a buggy CPU needs to confirm that */ 
     64        i2c->i2c_i2mod &= ~1; 
     65#endif 
    6666        /* Clear interrupt. 
    6767        */ 
     
    7878        volatile iic_t          *iip = cpm_adap->iip; 
    7979        volatile i2c8xx_t       *i2c = cpm_adap->i2c; 
    80  
    81         if (cpm_debug) printk("cpm_iic_init() - iip=%p\n",iip); 
     80        unsigned char brg; 
     81        bd_t *bd = (bd_t *)__res; 
     82 
     83        if (cpm_debug) printk(KERN_DEBUG "cpm_iic_init()\n"); 
    8284 
    8385        /* Initialize the parameter ram. 
     
    116118                        mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG; 
    117119                while (cp->cp_cpcr & CPM_CR_FLG); 
     120        } else { 
     121                iip->iic_rbptr = iip->iic_rbase; 
     122                iip->iic_tbptr = iip->iic_tbase; 
     123                iip->iic_rstate = 0; 
     124                iip->iic_tstate = 0; 
    118125        } 
    119126 
    120127        /* Select an arbitrary address.  Just make sure it is unique. 
    121128        */ 
    122         i2c->i2c_i2add = 0x34; 
    123  
    124         /* Make clock run maximum slow. 
    125         */ 
    126         i2c->i2c_i2brg = 7; 
     129        i2c->i2c_i2add = 0xfe; 
     130 
     131        /* Make clock run at 60 KHz. 
     132        */ 
     133        brg = (unsigned char) (bd->bi_intfreq/(32*2*60000) -3); 
     134        i2c->i2c_i2brg = brg; 
     135 
     136        i2c->i2c_i2mod = 0x00;  
     137        i2c->i2c_i2com = 0x01; /* Master mode */ 
    127138 
    128139        /* Disable interrupts. 
     
    150161        /* Shut down IIC. 
    151162        */ 
    152         i2c->i2c_i2mod = 0; 
     163        i2c->i2c_i2mod &= ~1; 
    153164        i2c->i2c_i2cmr = 0; 
    154165        i2c->i2c_i2cer = 0xff; 
     
    170181        iip->iic_rstate = 0; 
    171182        iip->iic_rdp = 0; 
    172         iip->iic_rbptr = r_rbase; 
     183        iip->iic_rbptr = iip->iic_rbase; 
    173184        iip->iic_rbc = 0; 
    174185        iip->iic_rxtmp = 0; 
    175186        iip->iic_tstate = 0; 
    176187        iip->iic_tdp = 0; 
    177         iip->iic_tbptr = r_tbase; 
     188        iip->iic_tbptr = iip->iic_tbase; 
    178189        iip->iic_tbc = 0; 
    179190        iip->iic_txtmp = 0; 
     
    181192 
    182193#define BD_SC_NAK               ((ushort)0x0004) /* NAK - did not respond */ 
     194#define BD_SC_OV                ((ushort)0x0002) /* OV - receive overrun */ 
    183195#define CPM_CR_CLOSE_RXBD       ((ushort)0x0007) 
    184196 
    185197static void force_close(struct i2c_algo_8xx_data *cpm) 
    186198{ 
    187         if (cpm->reloc == 0) { 
     199        volatile i2c8xx_t *i2c = cpm->i2c; 
     200        if (cpm->reloc == 0) { /* micro code disabled */ 
    188201                volatile cpm8xx_t *cp = cpm->cp; 
    189202 
     
    195208                while (cp->cp_cpcr & CPM_CR_FLG); 
    196209        } 
     210        i2c->i2c_i2cmr = 0x00;  /* Disable all interrupts */ 
     211        i2c->i2c_i2cer = 0xff;  
    197212} 
    198213 
     
    209224        volatile cbd_t  *tbdf, *rbdf; 
    210225        u_char *tb; 
    211         unsigned long flags; 
     226        unsigned long flags, tmo; 
    212227 
    213228        if (count >= CPM_MAX_READ) 
     
    226241         * is just used for timing (and doesn't really have to exist). 
    227242         */ 
    228         if (cpm->reloc) { 
    229                 cpm_reset_iic_params(iip); 
    230         } 
    231243        tb = cpm->temp; 
    232244        tb = (u_char *)(((uint)tb + 15) & ~15); 
     
    240252        tbdf->cbd_datlen = count + 1; 
    241253        tbdf->cbd_sc = 
    242                 BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | 
     254                BD_SC_READY | BD_SC_LAST | 
    243255                BD_SC_WRAP | BD_IIC_START; 
     256 
     257        iip->iic_mrblr = count +1; /* prevent excessive read, +1 
     258                                      is needed otherwise will the 
     259                                      RXB interrupt come too early */ 
     260 
     261        /* flush will invalidate too. */ 
     262        flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count)); 
    244263 
    245264        rbdf->cbd_datlen = 0; 
    246265        rbdf->cbd_bufaddr = __pa(buf); 
    247         rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; 
    248  
    249         invalidate_dcache_range((unsigned long) buf, (unsigned long) (buf+count)); 
    250  
    251         /* Chip bug, set enable here */ 
    252         local_irq_save(flags); 
    253         i2c->i2c_i2cmr = 0x13;  /* Enable some interupts */ 
    254         i2c->i2c_i2cer = 0xff; 
    255         i2c->i2c_i2mod = 1;     /* Enable */ 
    256         i2c->i2c_i2com = 0x81;  /* Start master */ 
    257  
    258         /* Wait for IIC transfer */ 
    259         interruptible_sleep_on(&iic_wait); 
    260         local_irq_restore(flags); 
    261         if (signal_pending(current)) 
     266        rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT; 
     267        if(count > 16){ 
     268                /* Chip bug, set enable here */ 
     269                local_irq_save(flags); 
     270                i2c->i2c_i2cmr = 0x13;  /* Enable some interupts */ 
     271                i2c->i2c_i2cer = 0xff; 
     272                i2c->i2c_i2mod |= 1;    /* Enable */ 
     273                i2c->i2c_i2com |= 0x80; /* Begin transmission */ 
     274 
     275                /* Wait for IIC transfer */ 
     276                tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); 
     277                local_irq_restore(flags); 
     278        } else { /* busy wait for small transfers, its faster */ 
     279                i2c->i2c_i2cmr = 0x00;  /* Disable I2C interupts */ 
     280                i2c->i2c_i2cer = 0xff; 
     281                i2c->i2c_i2mod |= 1;    /* Enable */ 
     282                i2c->i2c_i2com |= 0x80; /* Begin transmission */ 
     283                tmo = jiffies + 1*HZ;  
     284                while(!(i2c->i2c_i2cer & 0x11 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */ 
     285        }                
     286 
     287        if (signal_pending(current) || !tmo){ 
     288                force_close(cpm); 
     289                if(cpm_debug)  
     290                        printk("IIC read: timeout!\n"); 
    262291                return -EIO; 
    263  
     292        } 
     293#ifdef I2C_CHIP_ERRATA 
     294        /* Chip errata, clear enable. This is not needed on rev D4 CPUs. 
     295         Disabling I2C too early may cause too short stop condition */ 
     296        udelay(4); 
     297        i2c->i2c_i2mod &= ~1; 
     298#endif 
    264299        if (cpm_debug) { 
    265300                printk("tx sc %04x, rx sc %04x\n", 
     
    267302        } 
    268303 
    269         if (tbdf->cbd_sc & BD_SC_NAK) { 
    270                 printk("IIC read; no ack\n"); 
    271                 return 0; 
    272         } 
    273  
    274         if (rbdf->cbd_sc & BD_SC_EMPTY) { 
    275                 printk("IIC read; complete but rbuf empty\n"); 
     304        if (tbdf->cbd_sc & BD_SC_READY) { 
     305                printk("IIC read; complete but tbuf ready\n"); 
    276306                force_close(cpm); 
    277307                printk("tx sc %04x, rx sc %04x\n", 
     
    279309        } 
    280310 
     311        if (tbdf->cbd_sc & BD_SC_NAK) { 
     312                if (cpm_debug) 
     313                        printk("IIC read; no ack\n"); 
     314                return -EREMOTEIO; 
     315        } 
     316 
     317        if (rbdf->cbd_sc & BD_SC_EMPTY) { 
     318                /* force_close(cpm); */ 
     319                if (cpm_debug){ 
     320                        printk("IIC read; complete but rbuf empty\n"); 
     321                        printk("tx sc %04x, rx sc %04x\n", 
     322                               tbdf->cbd_sc, rbdf->cbd_sc); 
     323                } 
     324                return -EREMOTEIO; 
     325        } 
     326 
     327        if (rbdf->cbd_sc & BD_SC_OV) { 
     328                if (cpm_debug) 
     329                        printk("IIC read; Overrun\n"); 
     330                return -EREMOTEIO;; 
     331        } 
     332 
    281333        if (cpm_debug) printk("read %d bytes\n", rbdf->cbd_datlen); 
    282334 
    283335        if (rbdf->cbd_datlen < count) { 
    284                 printk("IIC read; short, wanted %d got %d\n", 
    285                        count, rbdf->cbd_datlen); 
     336                if (cpm_debug) 
     337                        printk("IIC read; short, wanted %d got %d\n", 
     338                               count, rbdf->cbd_datlen); 
    286339                return 0; 
    287340        } 
    288  
    289  
    290         invalidate_dcache_range((unsigned long) buf, (unsigned long) (buf+count)); 
    291341 
    292342        return count; 
     
    304354        volatile cbd_t  *tbdf; 
    305355        u_char *tb; 
    306         unsigned long flags; 
     356        unsigned long flags, tmo; 
    307357 
    308358        /* check for and use a microcode relocation patch */ 
     
    330380        tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP; 
    331381 
    332         /* Chip bug, set enable here */ 
    333         local_irq_save(flags); 
    334         i2c->i2c_i2cmr = 0x13;  /* Enable some interupts */ 
    335         i2c->i2c_i2cer = 0xff; 
    336         i2c->i2c_i2mod = 1;     /* Enable */ 
    337         i2c->i2c_i2com = 0x81;  /* Start master */ 
    338  
    339         /* Wait for IIC transfer */ 
    340         interruptible_sleep_on(&iic_wait); 
    341         local_irq_restore(flags); 
    342         if (signal_pending(current)) 
     382        if(count > 16){ 
     383                /* Chip bug, set enable here */ 
     384                local_irq_save(flags); 
     385                i2c->i2c_i2cmr = 0x13;  /* Enable some interupts */ 
     386                i2c->i2c_i2cer = 0xff; 
     387                i2c->i2c_i2mod |= 1;    /* Enable */ 
     388                i2c->i2c_i2com |= 0x80; /* Begin transmission */ 
     389                 
     390                /* Wait for IIC transfer */ 
     391                tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); 
     392                local_irq_restore(flags); 
     393        } else {  /* busy wait for small transfers, its faster */ 
     394                i2c->i2c_i2cmr = 0x00;  /* Disable I2C interupts */ 
     395                i2c->i2c_i2cer = 0xff; 
     396                i2c->i2c_i2mod |= 1;    /* Enable */ 
     397                i2c->i2c_i2com |= 0x80; /* Begin transmission */ 
     398                tmo = jiffies + 1*HZ;  
     399                while(!(i2c->i2c_i2cer & 0x12 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */ 
     400        }                
     401 
     402        if (signal_pending(current) || !tmo){ 
     403                force_close(cpm); 
     404                if(cpm_debug && !tmo)  
     405                        printk("IIC write: timeout!\n"); 
    343406                return -EIO; 
    344  
     407        } 
     408         
     409#if I2C_CHIP_ERRATA 
     410        /* Chip errata, clear enable. This is not needed on rev D4 CPUs. 
     411         Disabling I2C too early may cause too short stop condition */ 
     412        udelay(4); 
     413        i2c->i2c_i2mod &= ~1; 
     414#endif 
    345415        if (cpm_debug) { 
    346416                printk("tx0 sc %04x, tx1 sc %04x\n", 
     
    349419 
    350420        if (tbdf->cbd_sc & BD_SC_NAK) { 
    351                 printk("IIC write; no ack\n"); 
     421                if (cpm_debug)  
     422                        printk("IIC write; no ack\n"); 
    352423                return 0; 
    353424        } 
    354425           
    355426        if (tbdf->cbd_sc & BD_SC_READY) { 
    356                 printk("IIC write; complete but tbuf ready\n"); 
     427                if (cpm_debug) 
     428                        printk("IIC write; complete but tbuf ready\n"); 
    357429                return 0; 
    358430        } 
     
    372444        volatile cbd_t *tbdf, *rbdf; 
    373445        u_char *tb; 
    374         unsigned long flags, len; 
     446        unsigned long flags, len, tmo; 
    375447 
    376448        if (cpm_debug > 1) 
     
    397469        len = 2; 
    398470 
    399         flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1)); 
     471        flush_dcache_range((unsigned long) tb, (unsigned long) (tb+2)); 
    400472 
    401473        tbdf->cbd_bufaddr = __pa(tb); 
    402474        tbdf->cbd_datlen = len; 
    403475        tbdf->cbd_sc = 
    404                 BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | 
     476                BD_SC_READY | BD_SC_LAST | 
    405477                BD_SC_WRAP | BD_IIC_START; 
    406478 
    407479        rbdf->cbd_datlen = 0; 
    408480        rbdf->cbd_bufaddr = __pa(tb+2); 
    409         rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; 
     481        rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT; 
    410482 
    411483        local_irq_save(flags); 
    412484        i2c->i2c_i2cmr = 0x13;  /* Enable some interupts */ 
    413485        i2c->i2c_i2cer = 0xff; 
    414         i2c->i2c_i2mod = 1;     /* Enable */ 
    415         i2c->i2c_i2com = 0x81;  /* Start master */ 
     486        i2c->i2c_i2mod |= 1;    /* Enable */ 
     487        i2c->i2c_i2com |= 0x80; /* Begin transmission */ 
    416488 
    417489        if (cpm_debug > 1) printk("about to sleep\n"); 
    418490 
    419491        /* wait for IIC transfer */ 
    420         interruptible_sleep_on(&iic_wait); 
     492        tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); 
    421493        local_irq_restore(flags); 
    422         if (signal_pending(current)) 
     494 
     495#ifdef I2C_CHIP_ERRATA 
     496        /* Chip errata, clear enable. This is not needed on rev D4 CPUs. 
     497         Disabling I2C too early may cause too short stop condition */ 
     498        udelay(4); 
     499        i2c->i2c_i2mod &= ~1; 
     500#endif 
     501 
     502        if (signal_pending(current) || !tmo){ 
     503                force_close(cpm); 
     504                if(cpm_debug && !tmo)  
     505                        printk("IIC tryaddress: timeout!\n"); 
    423506                return -EIO; 
     507        } 
    424508 
    425509        if (cpm_debug > 1) printk("back from sleep\n"); 
     
    451535                if (cpm_debug) 
    452536                        printk("i2c-algo-8xx.o: " 
    453                                "#%d addr=0x%x flags=0x%x len=%d\n", 
    454                                i, pmsg->addr, pmsg->flags, pmsg->len); 
     537                               "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n", 
     538                               i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf); 
    455539 
    456540                addr = pmsg->addr << 1;