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
[email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/zaurus-devel