[linux-yocto] [PATCH 24/30] Added support for ncr_read/ncr_write to access PCIe/SRIO SerDes config in 0x115 node
Charlie Paul
cpaul.windriver at gmail.com
Thu Apr 17 19:37:12 PDT 2014
From: SangeethaRao <sangeetha.rao at lsi.com>
Signed-off-by: SangeethaRao <sangeetha.rao at lsi.com>
---
arch/arm/mach-axxia/ncr.c | 137 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 123 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-axxia/ncr.c b/arch/arm/mach-axxia/ncr.c
index 84c260f..f166cd5 100644
--- a/arch/arm/mach-axxia/ncr.c
+++ b/arch/arm/mach-axxia/ncr.c
@@ -203,7 +203,6 @@ ncr_unlock(int domain)
----------------------------------------------------------------------
ncr_read
*/
-
int
ncr_read(unsigned long region, unsigned long address, int number,
void *buffer)
@@ -224,7 +223,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 +273,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 +284,75 @@ ncr_read(unsigned long region, unsigned long address, int number,
}
} else {
#ifdef APB2SER_PHY_PHYS_ADDRESS
- void __iomem *targ_address = apb2ser0_address +
- (address & (~0x3));
- /*
- * Copy data words to the buffer.
- */
-
- while (4 <= number) {
- *((unsigned long *) buffer) =
- *((unsigned long *) targ_address);
- targ_address += 4;
- number -= 4;
+ if (NCP_NODE_ID(region) != 0x115) {
+ void __iomem *targ_address = apb2ser0_address +
+ (address & (~0x3));
+ /*
+ * 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);
+ }
}
#else
ncr_unlock(LOCK_DOMAIN);
@@ -335,7 +393,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.
*/
@@ -418,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));
/*
@@ -430,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