[PATCH] PXA PCMCIA timing

stefan.eletzhofer at eletztrick.de stefan.eletzhofer at eletztrick.de
Tue Jun 29 09:31:00 EDT 2004


Hi,
here's a patch which allows boards to override the
timing calculations done in pxa2xx_core.c.

The patch is against 2.6.6-bkpxa, If the patch is OK
I'll update it to the latest 2.6 bk tree. AFAIK the timing
calculation stuff did not change in 2.6.7.

Please comment.

Thanks,
	Stefan E.
-- 
Eletztrick Computing - Customized Linux Development
Stefan Eletzhofer, Marktstrasse 43, DE-88214 Ravensburg
http://www.eletztrick.de
-------------- next part --------------
Allow boards to override MCMEM/IO/ATTR timing calculations

#
# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
#

--- linux-ra_alpha/include/asm-arm/arch-pxa/pcmcia.h~pxa-pcmcia-board-timing
+++ linux-ra_alpha/include/asm-arm/arch-pxa/pcmcia.h
@@ -96,13 +96,12 @@
 	 */
 	void (*socket_suspend)(struct pxa2xx_pcmcia_socket *);
 
-	/*
-	 * Calculate MECR timing clock wait states
-	 *
-	 * FIXME: fixt this to match PXA registers
+	/* Override timing calculations for this platform.
+	 * If not set, use default timing calc from pxa2xx_core.c
 	 */
-	unsigned int (*socket_get_timing)(struct pxa2xx_pcmcia_socket *,
-			unsigned int cpu_speed, unsigned int cmd_time);
+	int (*socket_set_mcmem)(struct pxa2xx_pcmcia_socket *skt, int speed, int clock );
+	int (*socket_set_mcio)(struct pxa2xx_pcmcia_socket *skt, int speed, int clock );
+	int (*socket_set_mcatt)(struct pxa2xx_pcmcia_socket *skt, int speed, int clock );
 };
 
 #endif
--- linux-ra_alpha/drivers/pcmcia/pxa2xx_core.c~pxa-pcmcia-board-timing
+++ linux-ra_alpha/drivers/pcmcia/pxa2xx_core.c
@@ -65,33 +65,6 @@
 
 #define to_pxa2xx_socket(x)	container_of(x, struct pxa2xx_pcmcia_socket, socket)
 
-/* FIXME */
-#define cpufreq_get(dummy) (get_clk_frequency_khz())
-
-#if 0
-/*
- * pxa2xx_core_pcmcia_default_mecr_timing
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- *
- * Calculate MECR clock wait states for given CPU clock
- * speed and command wait state. This function can be over-
- * written by a board specific version.
- *
- * The default is to simply calculate the BS values as specified in
- * the INTEL SA1100 development manual
- * "Expansion Memory (PCMCIA) Configuration Register (MECR)"
- * that's section 10.2.5 in _my_ version of the manual ;)
- */
-static unsigned int
-pxa2xx_core_pcmcia_default_mecr_timing(struct pxa2xx_pcmcia_socket *skt,
-		unsigned int cpu_speed,
-		unsigned int cmd_time)
-{
-	debugs( skt, 1, "speed=%d, time=%d", cpu_speed, cmd_time );
-	return pxa2xx_core_pcmcia_mecr_bs(cmd_time, cpu_speed);
-}
-#endif
-
 static unsigned short calc_speed(unsigned short *spds, int num, unsigned short dflt)
 {
 	unsigned short speed = 0;
@@ -106,49 +79,71 @@
 	return speed;
 }
 
-static int pxa2xx_core_pcmcia_set_mcmem( int sock, int speed, int clock )
+static int pxa2xx_core_pcmcia_set_mcmem( struct pxa2xx_pcmcia_socket *skt,
+		int speed, int clock )
 {
-	MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock)
-		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-		| ((pxa2xx_mcxx_asst(speed, clock)
-		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-		| ((pxa2xx_mcxx_hold(speed, clock)
-		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+	int ret = 0;
+	int sock = skt->nr;
 
-	return 0;
+	if (skt->ops->socket_set_mcmem) {
+		ret = skt->ops->socket_set_mcmem(skt, speed, clock);
+	} else  {
+		MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+			& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
+			| ((pxa2xx_mcxx_asst(speed, clock)
+			& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
+			| ((pxa2xx_mcxx_hold(speed, clock)
+			& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+	}
+
+	return ret;
 }
 
-static int pxa2xx_core_pcmcia_set_mcio( int sock, int speed, int clock )
+static int pxa2xx_core_pcmcia_set_mcio( struct pxa2xx_pcmcia_socket *skt,
+		int speed, int clock )
 {
-	MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock)
-		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-		| ((pxa2xx_mcxx_asst(speed, clock)
-		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-		| ((pxa2xx_mcxx_hold(speed, clock)
-		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+	int ret = 0;
+	int sock = skt->nr;
 
-	return 0;
+	if (skt->ops->socket_set_mcio) {
+		ret = skt->ops->socket_set_mcio(skt, speed, clock);
+	} else  {
+		MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+			& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
+			| ((pxa2xx_mcxx_asst(speed, clock)
+			& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
+			| ((pxa2xx_mcxx_hold(speed, clock)
+			& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+	}
+
+	return ret;
 }
 
-static int pxa2xx_core_pcmcia_set_mcatt( int sock, int speed, int clock )
+static int pxa2xx_core_pcmcia_set_mcatt( struct pxa2xx_pcmcia_socket *skt,
+		int speed, int clock )
 {
-	MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock)
-		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-		| ((pxa2xx_mcxx_asst(speed, clock)
-		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-		| ((pxa2xx_mcxx_hold(speed, clock)
-		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+	int ret = 0;
+	int sock = skt->nr;
 
-	return 0;
+	if (skt->ops->socket_set_mcatt) {
+		ret = skt->ops->socket_set_mcatt(skt, speed, clock);
+	} else  {
+		MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+			& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
+			| ((pxa2xx_mcxx_asst(speed, clock)
+			& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
+			| ((pxa2xx_mcxx_hold(speed, clock)
+			& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+	}
+
+	return ret;
 }
 
 static int pxa2xx_core_pcmcia_set_mcxx(struct pxa2xx_pcmcia_socket *skt, unsigned int cpu_clock)
 {
-	int sock = skt->nr;
-
-	pxa2xx_core_pcmcia_set_mcmem( sock, PXA_PCMCIA_5V_MEM_ACCESS, cpu_clock );
-	pxa2xx_core_pcmcia_set_mcatt( sock, PXA_PCMCIA_ATTR_MEM_ACCESS, cpu_clock );
-	pxa2xx_core_pcmcia_set_mcio( sock, PXA_PCMCIA_IO_ACCESS, cpu_clock );
+	pxa2xx_core_pcmcia_set_mcmem( skt, PXA_PCMCIA_5V_MEM_ACCESS, cpu_clock );
+	pxa2xx_core_pcmcia_set_mcatt( skt, PXA_PCMCIA_ATTR_MEM_ACCESS, cpu_clock );
+	pxa2xx_core_pcmcia_set_mcio( skt, PXA_PCMCIA_IO_ACCESS, cpu_clock );
 
 	return 0;
 }
@@ -466,7 +461,7 @@
 	}
 
 	skt->spd_io[map->map] = speed;
-	pxa2xx_core_pcmcia_set_mcio( skt->nr, speed, get_lclk_frequency_10khz() );
+	pxa2xx_core_pcmcia_set_mcio( skt, speed, get_lclk_frequency_10khz() );
 
 	if (map->stop == 1)
 		map->stop = PAGE_SIZE-1;
@@ -521,12 +516,12 @@
 		res = &skt->res_attr;
 		skt->spd_attr[map->map] = speed;
 		skt->spd_mem[map->map] = 0;
-		pxa2xx_core_pcmcia_set_mcatt( skt->nr, speed, get_lclk_frequency_10khz() );
+		pxa2xx_core_pcmcia_set_mcatt( skt, speed, get_lclk_frequency_10khz() );
 	} else {
 		res = &skt->res_mem;
 		skt->spd_attr[map->map] = 0;
 		skt->spd_mem[map->map] = speed;
-		pxa2xx_core_pcmcia_set_mcmem( skt->nr, speed , get_lclk_frequency_10khz());
+		pxa2xx_core_pcmcia_set_mcmem( skt, speed , get_lclk_frequency_10khz());
 	}
 
 	map->sys_stop -= map->sys_start;
@@ -711,15 +706,6 @@
 	struct pcmcia_low_level *ops;
 	int first, nr;
 
-#if 0
-	/* FIXME: fix this for pxa or kill it
-	 * set default MECR calculation if the board specific
-	 * code did not specify one...
-	 */
-	if (!ops->socket_get_timing)
-		ops->socket_get_timing = pxa2xx_pcmcia_default_mecr_timing;
-#endif
-	
 	if (!dev || !dev->platform_data)
 		goto out;
 
@@ -977,11 +963,11 @@
 
 	down(&pxa2xx_sockets_lock);
 	list_for_each_entry(skt, &pxa2xx_sockets, node) {
-		pxa2xx_core_pcmcia_set_mcio(skt->nr, calc_speed(skt->spd_io,
+		pxa2xx_core_pcmcia_set_mcio(skt, calc_speed(skt->spd_io,
 					MAX_IO_WIN, PXA_PCMCIA_IO_ACCESS), clock);
-		pxa2xx_core_pcmcia_set_mcmem(skt->nr, calc_speed(skt->spd_io,
+		pxa2xx_core_pcmcia_set_mcmem(skt, calc_speed(skt->spd_io,
 					MAX_IO_WIN, PXA_PCMCIA_3V_MEM_ACCESS), clock );
-		pxa2xx_core_pcmcia_set_mcatt(skt->nr, calc_speed(skt->spd_io,
+		pxa2xx_core_pcmcia_set_mcatt(skt, calc_speed(skt->spd_io,
 					MAX_IO_WIN, PXA_PCMCIA_3V_MEM_ACCESS), clock );
 	}
 	up(&pxa2xx_sockets_lock);


More information about the linux-pcmcia mailing list