[linux-yocto] [PATCH 11/18] arch/arm/mach-axxia: added support for ncr_read/ncr_write() to access PCIe/SRIO SerDes Config in 0x115 node

Charlie Paul cpaul.windriver at gmail.com
Tue Feb 18 09:26:41 PST 2014


From: SangeethaRao <sangeetha.rao at lsi.com>

Signed-off-by: SangeethaRao <sangeetha.rao at lsi.com>
---
 arch/arm/mach-axxia/ncr.c |  133 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 122 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-axxia/ncr.c b/arch/arm/mach-axxia/ncr.c
index 58b959a..4112038 100644
--- a/arch/arm/mach-axxia/ncr.c
+++ b/arch/arm/mach-axxia/ncr.c
@@ -224,7 +224,7 @@ ncr_read(unsigned long region, unsigned long address, int number,
 	if (0 != ncr_lock(LOCK_DOMAIN))
 		return -1;
 
-	if (NCP_NODE_ID(region) != 0x0153) {
+	if ((NCP_NODE_ID(region) != 0x0153) && (NCP_NODE_ID(region) != 0x115)) {
 		/*
 		Set up the read command.
 		*/
@@ -274,6 +274,7 @@ ncr_read(unsigned long region, unsigned long address, int number,
 			*((unsigned long *) buffer) =
 				ncr_register_read((unsigned *) address);
 			address += 4;
+			buffer += 4;
 			number -= 4;
 		}
 
@@ -284,17 +285,76 @@ ncr_read(unsigned long region, unsigned long address, int number,
 		}
 	} else {
 #ifdef APB2SER_PHY_PHYS_ADDRESS
-		void __iomem *targ_address = apb2ser0_address +
+		if (NCP_NODE_ID(region) != 0x115) {
+			void __iomem *targ_address = apb2ser0_address +
 				(address & (~0x3));
-		/*
-		Copy data words to the buffer.
-		*/
+			/*
+			* Copy data words to the buffer.
+			*/
+
+			while (4 <= number) {
+				*((unsigned long *) buffer) =
+					*((unsigned long *) targ_address);
+				targ_address += 4;
+				number -= 4;
+			}
+		} else {
+			void __iomem *base;
+			if (0xffff < address) {
+				ncr_unlock(LOCK_DOMAIN);
+				return -1;
+			}
+
+			switch (NCP_TARGET_ID(region)) {
+			case 0:
+				base = (apb2ser0_address + 0x1e0);
+				break;
+			case 1:
+				base = (apb2ser0_address + 0x1f0);
+				break;
+			case 2:
+				base = (apb2ser0_address + 0x200);
+				break;
+			case 3:
+				base = (apb2ser0_address + 0x210);
+				break;
+			case 4:
+				base = (apb2ser0_address + 0x220);
+				break;
+			case 5:
+				base = (apb2ser0_address + 0x230);
+				break;
+			default:
+				ncr_unlock(LOCK_DOMAIN);
+				return -1;
+			}
+			if ((NCP_TARGET_ID(region) == 0x1) ||
+				(NCP_TARGET_ID(region) == 0x4)) {
+				writel((0x84c00000 + address), (base + 4));
+			} else {
+				writel((0x85400000 + address), (base + 4));
+			}
+			do {
+				--wfc_timeout;
+				*((unsigned long *) buffer) =
+					readl(base + 4);
+			} while (0 != (*((unsigned long *) buffer) & 0x80000000)
+					&& 0 < wfc_timeout);
+
+			if (0 == wfc_timeout) {
+				ncr_unlock(LOCK_DOMAIN);
+				return -1;
+			}
+
+			if ((NCP_TARGET_ID(region) == 0x1) ||
+				(NCP_TARGET_ID(region) == 0x4)) {
+				*((unsigned short *) buffer) =
+					readl(base + 8);
+			} else {
+				*((unsigned long *) buffer) =
+					readl(base + 8);
+			}
 
-		while (4 <= number) {
-			*((unsigned long *) buffer) =
-				*((unsigned long *) targ_address);
-			targ_address += 4;
-			number -= 4;
 		}
 #else
 		ncr_unlock(LOCK_DOMAIN);
@@ -335,7 +395,7 @@ ncr_write(unsigned long region, unsigned long address, int number,
 	if (0 != ncr_lock(LOCK_DOMAIN))
 		return -1;
 
-	if (NCP_NODE_ID(region) != 0x0153) {
+	if ((NCP_NODE_ID(region) != 0x0153) && (NCP_NODE_ID(region) != 0x115)) {
 		/*
 		  Set up the write.
 		*/
@@ -416,6 +476,7 @@ ncr_write(unsigned long region, unsigned long address, int number,
 		}
 	} else {
 #ifdef APB2SER_PHY_PHYS_ADDRESS
+	if (NCP_NODE_ID(region) != 0x115) {
 		void __iomem *targ_address = apb2ser0_address +
 					     (address & (~0x3));
 		/*
@@ -428,6 +489,56 @@ ncr_write(unsigned long region, unsigned long address, int number,
 			targ_address += 4;
 			number -= 4;
 		}
+	} else {
+		void __iomem *base;
+		if (0xffff < address) {
+			ncr_unlock(LOCK_DOMAIN);
+			return -1;
+		}
+
+		switch (NCP_TARGET_ID(region)) {
+			case 0:
+				base = (apb2ser0_address + 0x1e0);
+				break;
+			case 1:
+				base = (apb2ser0_address + 0x1f0);
+				break;
+			case 2:
+				base = (apb2ser0_address + 0x200);
+				break;
+			case 3:
+				base = (apb2ser0_address + 0x210);
+				break;
+			case 4:
+				base = (apb2ser0_address + 0x220);
+				break;
+			case 5:
+				base = (apb2ser0_address + 0x230);
+				break;
+			default:
+				ncr_unlock(LOCK_DOMAIN);
+				return -1;
+		}
+		if ((NCP_TARGET_ID(region) == 0x1) ||
+				(NCP_TARGET_ID(region) == 0x4)) {
+			writel(*((unsigned short *) buffer), base);
+			writel((0xc4c00000 + address), (base + 4));
+		} else {
+			writel(*((unsigned long *) buffer), base);
+			writel((0xc5400000 + address), (base + 4));
+		}
+			do {
+				--wfc_timeout;
+				*((unsigned long *) buffer) =
+					readl(base + 4);
+			} while (0 != (*((unsigned long *) buffer) & 0x80000000)
+				&& 0 < wfc_timeout);
+
+			if (0 == wfc_timeout) {
+				ncr_unlock(LOCK_DOMAIN);
+				return -1;
+			}
+		}
 #else
 		ncr_unlock(LOCK_DOMAIN);
 		return -1;
-- 
1.7.9.5



More information about the linux-yocto mailing list