kirill wrote:
>> Yes, patch would be nice. 
Here's the patch. I didn't test it on 2.6.35, however the affected
functions are not changed from 2.6.1x. So it should work...
Note pcmcia_cycle_ns in original code. AFAIK it's not pcmcia cyce ns. See my 
FIXME below.

diff -ru linux-2.6.35-orig/drivers/pcmcia/pxa2xx_base.c 
linux-2.6.35-pxapcmciatimings/drivers/pcmcia/pxa2xx_base.c
--- linux-2.6.35-orig/drivers/pcmcia/pxa2xx_base.c      2010-09-10 
18:29:08.000000000 +0400
+++ linux-2.6.35-pxapcmciatimings/drivers/pcmcia/pxa2xx_base.c  2010-09-10 
18:38:29.000000000 +0400
@@ -85,43 +85,93 @@
 #define MCXX_ASST_SHIFT     (7)
 #define MCXX_HOLD_SHIFT     (14)

-static inline u_int pxa2xx_mcxx_hold(u_int pcmcia_cycle_ns,
+/*
+ * address hold time: value = ceil(ns*freq);
+ */
+static inline u_int pxa2xx_mcxx_hold(u_int hold,
                                     u_int mem_clk_10khz)
 {
-       u_int code = pcmcia_cycle_ns * mem_clk_10khz;
-       return (code / 300000) + ((code % 300000) ? 1 : 0) - 1;
+       u_int code = hold * mem_clk_10khz;
+       return (code / 100000) + ((code % 100000) ? 1 : 0);
 }

-static inline u_int pxa2xx_mcxx_asst(u_int pcmcia_cycle_ns,
+
+/*
+ * command assertion time: value = ceil(ns*freq/3 - 5/3)
+ */
+static inline u_int pxa2xx_mcxx_asst(u_int cas,
                                     u_int mem_clk_10khz)
 {
-       u_int code = pcmcia_cycle_ns * mem_clk_10khz;
-       return (code / 300000) + ((code % 300000) ? 1 : 0) + 1;
+       u_int code = cas * mem_clk_10khz;
+       if(code % 300000 > 200000) return code/300000;
+       code = code/300000;
+       return code > 1 ? code-1 : 0;
 }

-static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns,
+/*
+ * address setup time: value = ceil(ns*freq - 2)
+ */
+static inline u_int pxa2xx_mcxx_setup(u_int set,
                                      u_int mem_clk_10khz)
 {
-       u_int code = pcmcia_cycle_ns * mem_clk_10khz;
-       return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
+       u_int code = set * mem_clk_10khz;
+       code = (code / 100000) + ((code % 100000) ? 1 : 0);
+       return code > 2 ? code-2 : 0;
 }

-/* This function returns the (approximate) command assertion period, in
- * nanoseconds, for a given CPU clock frequency and MCXX_ASST value:
+/*
+ * FIXME: why the speed is specified as command assertion time?
+ * Driver may specify AccessSpeed in call to pcmcia_request_window.
+ * I guess that AccessSpeed is cycle speed, but no conversion is done.
  */
-static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz,
-                                          u_int pcmcia_mcxx_asst)
-{
-       return (300000 * (pcmcia_mcxx_asst + 1) / mem_clk_10khz);
-}
-
 static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock )
 {
-       MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+       u_int set, cas, hold;
+
+       do {
+        switch(speed) {
+                        case 300:
+                                        cas = 300; /*tw(WE)*/
+                                        set = 100; /*tsu(A)*/
+                                        hold = 70; /*trec(WE)*/
+                                        break;
+                        case 150:
+                                        cas = 150;
+                                        set = 30;
+                                        hold = 30;
+                                        break;
+                        case 120:
+                                        cas = 120;
+                                        set = 20;
+                                        hold = 30;
+                                        break;
+                        case 80:
+                                        cas = 80;
+                                        set = 20;
+                                        hold = 20;
+                                        break;
+                        case 60:
+                                        cas = 60;
+                                        set = 10;
+                                        hold = 15;
+                                        break;
+                        default:
+                                        if(speed > 300) {
+                                         set = 100*speed/300;
+                                         hold = 70*speed/300;
+                                         cas = speed;
+                                        } else {
+                                         speed = (speed/20+1)*20;
+                                         cas = 0;
+                                        }
+        }
+       } while(cas == 0);
+
+       MCMEM(sock) = ((pxa2xx_mcxx_setup(set, clock)
                & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-               | ((pxa2xx_mcxx_asst(speed, clock)
+               | ((pxa2xx_mcxx_asst(cas, clock)
                & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-               | ((pxa2xx_mcxx_hold(speed, clock)
+               | ((pxa2xx_mcxx_hold(hold, clock)
                & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);

        return 0;
@@ -129,11 +179,22 @@

 static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock )
 {
-       MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+       u_int set, cas, hold;
+
+       if(speed == 165) {
+        set = 70;
+        hold = 20;
+        cas = 165;
+       } else {
+        cas = speed;
+        set = 70*speed/165;
+        hold = 20*speed/165;
+       }
+       MCIO(sock) = ((pxa2xx_mcxx_setup(set, clock)
                & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-               | ((pxa2xx_mcxx_asst(speed, clock)
+               | ((pxa2xx_mcxx_asst(cas, clock)
                & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-               | ((pxa2xx_mcxx_hold(speed, clock)
+               | ((pxa2xx_mcxx_hold(hold, clock)
                & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);

        return 0;
@@ -141,11 +202,36 @@

 static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock )
 {
-       MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+       u_int set, cas, hold;
+       do {
+        switch(speed) {
+                        case 300:
+                                        cas = 300; /*tw(WE)*/
+                                        set = 100; /*tsu(A)*/
+                                        hold = 70; /*trec(WE)*/
+                                        break;
+                        case 150:
+                                        cas = 150;
+                                        set = 30;
+                                        hold = 30;
+                                        break;
+                        default:
+                                        if(speed > 300) {
+                                         set = 100*speed/300;
+                                         hold = 70*speed/300;
+                                         cas = speed;
+                                        } else {
+                                         speed = (speed/50+1)*50;
+                                         cas = 0;
+                                        }
+        }
+       } while(cas == 0);
+
+       MCATT(sock) = ((pxa2xx_mcxx_setup(set, clock)
                & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-               | ((pxa2xx_mcxx_asst(speed, clock)
+               | ((pxa2xx_mcxx_asst(cas, clock)
                & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-               | ((pxa2xx_mcxx_hold(speed, clock)
+               | ((pxa2xx_mcxx_hold(hold, clock)
                & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);

        return 0;

_______________________________________________
Zaurus-devel mailing list
Zaurus-devel@lists.linuxtogo.org
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/zaurus-devel

Reply via email to