diff mbox

[RFC,RFT,3/4,v6] OMAP: McBSP: Introduce caching in register write operations

Message ID 200912081707.39812.jkrzyszt@tis.icnet.pl (mailing list archive)
State Changes Requested, archived
Delegated to: Tony Lindgren
Headers show

Commit Message

Janusz Krzysztofik Dec. 8, 2009, 4:07 p.m. UTC
None
diff mbox

Patch

diff -upr git.orig/arch/arm/plat-omap/include/plat/mcbsp.h git/arch/arm/plat-omap/include/plat/mcbsp.h
--- git.orig/arch/arm/plat-omap/include/plat/mcbsp.h	2009-12-02 15:48:51.000000000 +0100
+++ git/arch/arm/plat-omap/include/plat/mcbsp.h	2009-12-08 14:26:42.000000000 +0100
@@ -157,6 +157,14 @@ 
 
 #endif
 
+#define OMAP7XX_MCBSP_REG_NUM	(OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1)
+#define OMAP15XX_MCBSP_REG_NUM	(OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1)
+#define OMAP16XX_MCBSP_REG_NUM	(OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1)
+
+#define OMAP24XX_MCBSP_REG_NUM	(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
+#define OMAP34XX_MCBSP_REG_NUM	(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
+#define OMAP44XX_MCBSP_REG_NUM	(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
+
 /************************** McBSP SPCR1 bit definitions ***********************/
 #define RRST			0x0001
 #define RRDY			0x0002
@@ -415,6 +423,7 @@  struct omap_mcbsp {
 	u16 max_tx_thres;
 	u16 max_rx_thres;
 #endif
+	void *reg_cache;
 };
 extern struct omap_mcbsp **mcbsp_ptr;
 extern int omap_mcbsp_count;
diff -upr git.orig/arch/arm/plat-omap/mcbsp.c git/arch/arm/plat-omap/mcbsp.c
--- git.orig/arch/arm/plat-omap/mcbsp.c	2009-12-07 22:43:56.000000000 +0100
+++ git/arch/arm/plat-omap/mcbsp.c	2009-12-08 14:38:38.000000000 +0100
@@ -30,26 +30,40 @@ 
 struct omap_mcbsp **mcbsp_ptr;
 int omap_mcbsp_count;
 
-void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
+void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
 {
-	if (cpu_class_is_omap1() || cpu_is_omap2420())
-		__raw_writew((u16)val, io_base + reg);
-	else
-		__raw_writel(val, io_base + reg);
+	if (cpu_class_is_omap1()) {
+		((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)] = (u16)val;
+		__raw_writew((u16)val, mcbsp->io_base + reg);
+	} else if (cpu_is_omap2420()) {
+		((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)] = (u16)val;
+		__raw_writew((u16)val, mcbsp->io_base + reg);
+	} else {
+		((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)] = val;
+		__raw_writel(val, mcbsp->io_base + reg);
+	}
 }
 
-int omap_mcbsp_read(void __iomem *io_base, u16 reg)
+int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
 {
-	if (cpu_class_is_omap1() || cpu_is_omap2420())
-		return __raw_readw(io_base + reg);
-	else
-		return __raw_readl(io_base + reg);
+	if (cpu_class_is_omap1()) {
+		return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
+				((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)];
+	} else if (cpu_is_omap2420()) {
+		return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
+				((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+	} else {
+		return !from_cache ? __raw_readl(mcbsp->io_base + reg) :
+				((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+	}
 }
 
 #define MCBSP_READ(mcbsp, reg) \
-		omap_mcbsp_read(mcbsp->io_base, OMAP_MCBSP_REG_##reg)
+		omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
 #define MCBSP_WRITE(mcbsp, reg, val) \
-		omap_mcbsp_write(mcbsp->io_base, OMAP_MCBSP_REG_##reg, val)
+		omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
+#define MCBSP_READ_CACHE(mcbsp, reg) \
+		omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
 
 #define omap_mcbsp_check_valid_id(id)	(id < omap_mcbsp_count)
 #define id_to_mcbsp_ptr(id)		mcbsp_ptr[id];
@@ -391,6 +405,31 @@  int omap_mcbsp_request(unsigned int id)
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
 
+	if (cpu_is_omap7xx()) {
+		mcbsp->reg_cache = kzalloc(sizeof(u16) *
+				OMAP7XX_MCBSP_REG_NUM, GFP_KERNEL);
+	} else if (cpu_is_omap15xx()) {
+		mcbsp->reg_cache = kzalloc(sizeof(u16) *
+				OMAP15XX_MCBSP_REG_NUM, GFP_KERNEL);
+	} else if (cpu_is_omap16xx()) {
+		mcbsp->reg_cache = kzalloc(sizeof(u16) *
+				OMAP16XX_MCBSP_REG_NUM, GFP_KERNEL);
+	} else if (cpu_is_omap2420()) {
+		mcbsp->reg_cache = kzalloc(sizeof(u16) *
+				OMAP24XX_MCBSP_REG_NUM, GFP_KERNEL);
+	} else if (cpu_is_omap2430()) {
+		mcbsp->reg_cache = kzalloc(sizeof(u32) *
+				OMAP24XX_MCBSP_REG_NUM, GFP_KERNEL);
+	} else if (cpu_is_omap34xx()) {
+		mcbsp->reg_cache = kzalloc(sizeof(u32) *
+				OMAP34XX_MCBSP_REG_NUM, GFP_KERNEL);
+	} else if (cpu_is_omap44xx()) {
+		mcbsp->reg_cache = kzalloc(sizeof(u32) *
+				OMAP44XX_MCBSP_REG_NUM, GFP_KERNEL);
+	}
+	if (!mcbsp->reg_cache)
+		return -ENOMEM;
+
 	spin_lock(&mcbsp->lock);
 	if (!mcbsp->free) {
 		dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
@@ -481,6 +520,9 @@  void omap_mcbsp_free(unsigned int id)
 
 	mcbsp->free = 1;
 	spin_unlock(&mcbsp->lock);
+
+	kfree(mcbsp->reg_cache);
+	mcbsp->reg_cache = NULL;
 }
 EXPORT_SYMBOL(omap_mcbsp_free);