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