Patchwork [7/7] powerpc/85xx: Fix the RapidIO maintenance access functions

login
register
mail settings
Submitter Alexandre Bounine
Date Feb. 24, 2010, 3:37 p.m.
Message ID <20100224153751.GG13661@kaneng01.tundra.com>
Download mbox | patch
Permalink /patch/46179/
State Superseded
Delegated to: Kumar Gala
Headers show

Comments

Alexandre Bounine - Feb. 24, 2010, 3:37 p.m.
From: Thomas Moll <thomas.moll@sysgo.com>

Fix the maintenance access functions to farend RapidIO devices.
1. Fixed shift of the given offset, to open the maintenance window
2. Mask offset to limit access to the opened maintenance window
3. Added extended destid part to rowtear register, required for 16bit mode

For easier handling of the access routines, the access was limited to aligned
memory regions. This should be no problem because all registers are 32bit
wide.

Signed-off-by: Thomas Moll <thomas.moll@sysgo.com>
---

 fsl_rio.c |   34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)


---

Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you.
Micha Nelissen - Feb. 25, 2010, 7:20 p.m.
Bounine, Alexandre wrote:
> Hi Micha,
> 
> I tested it on my setup - it works.
> Maybe Thomas may give more details on this change.

Did you (for fun) try once to decrease the maintenance window to say, 4 
kB? Then you really need these "high" bits to work properly.

Or did you try with some register at offset > 4MB? The Tundra's have 
registers going up to 0x14000 or so? So don't need 16MB addressing for that.

Thanks, Micha


>> -----Original Message-----
>> From: Micha Nelissen [mailto:micha@neli.hopto.org]
>> Sent: Wednesday, February 24, 2010 3:21 PM
>> To: Alexandre Bounine
>> Subject: Re: [PATCH 7/7] powerpc/85xx: Fix the RapidIO maintenance
> access functions
>> Alexandre Bounine wrote:
>>>  	out_be32(&priv->maint_atmu_regs->rowtar,
>>> -		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >>
> 9));
>>> +		 (destid << 22) | (hopcount << 12) | (offset >> 12));
>>> +	out_be32(&priv->maint_atmu_regs->rowtear,  (destid >> 10));
>> Did this actually work for you? The (offset >> 12) is due to the 4MB
>> window size right?
>>
>> Micha
>
tmo@sysgo.com - March 5, 2010, 6 a.m.
Quoting "Micha Nelissen" <micha@neli.hopto.org>:

> Bounine, Alexandre wrote:
>> Hi Micha,
>>
>> I tested it on my setup - it works.
>> Maybe Thomas may give more details on this change.
>
> Did you (for fun) try once to decrease the maintenance window to  
> say, 4 kB? Then you really need these "high" bits to work properly.

We have never changed the configuration of the window size in Linux,  
but we have an test application that uses these 4kb window setting.
With the current window configuration in Linux, I expect problems when  
someone tries to read a register that is located at offset > 512KB. I  
have currently no equipment to verify this behaviour.

>
> Or did you try with some register at offset > 4MB? The Tundra's have  
> registers going up to 0x14000 or so? So don't need 16MB addressing  
> for that.
We have devices that requires access to registers that are located at  
offset > 15MB.

>
> Thanks, Micha
>
>
>>> -----Original Message-----
>>> From: Micha Nelissen [mailto:micha@neli.hopto.org]
>>> Sent: Wednesday, February 24, 2010 3:21 PM
>>> To: Alexandre Bounine
>>> Subject: Re: [PATCH 7/7] powerpc/85xx: Fix the RapidIO maintenance
>> access functions
>>> Alexandre Bounine wrote:
>>>> 	out_be32(&priv->maint_atmu_regs->rowtar,
>>>> -		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >>
>> 9));
>>>> +		 (destid << 22) | (hopcount << 12) | (offset >> 12));
>>>> +	out_be32(&priv->maint_atmu_regs->rowtear,  (destid >> 10));
>>> Did this actually work for you? The (offset >> 12) is due to the 4MB
>>> window size right?
>>>
>>> Micha
>>
>
>

Patch

diff -purN linux-base/arch/powerpc/sysdev/fsl_rio.c linux-new/arch/powerpc/sysdev/fsl_rio.c
--- linux-base/arch/powerpc/sysdev/fsl_rio.c	2010-02-24 08:37:05.000000000 +0100
+++ linux-new/arch/powerpc/sysdev/fsl_rio.c	2010-02-24 08:45:27.000000000 +0100
@@ -1,6 +1,10 @@ 
 /*
  * Freescale MPC85xx/MPC86xx RapidIO support
  *
+ * Copyright 2009 Sysgo AG
+ * Thomas Moll <thomas.moll@sysgo.com>
+ * - fixed maintenance access routines, check for aligned access
+ *
  * Copyright 2009 Integrated Device Technology, Inc.
  * Alex Bounine <alexandre.bounine@idt.com>
  * - Added Port-Write message handling
@@ -370,10 +374,17 @@  fsl_rio_config_read(struct rio_mport *mp
 	pr_debug
 	    ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
 	     index, destid, hopcount, offset, len);
+
+	/* 16MB maintenance window possible */
+	/* allow only aligned access to maintenance registers */
+	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
+		return -EINVAL;
+
 	out_be32(&priv->maint_atmu_regs->rowtar,
-		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+		 (destid << 22) | (hopcount << 12) | (offset >> 12));
+	out_be32(&priv->maint_atmu_regs->rowtear,  (destid >> 10));
 
-	data = (u8 *) priv->maint_win + offset;
+	data = (u8 *) priv->maint_win + (offset & 0x3FFFFF);
 	switch (len) {
 	case 1:
 		__fsl_read_rio_config(rval, data, err, "lbz");
@@ -381,9 +392,11 @@  fsl_rio_config_read(struct rio_mport *mp
 	case 2:
 		__fsl_read_rio_config(rval, data, err, "lhz");
 		break;
-	default:
+	case 4:
 		__fsl_read_rio_config(rval, data, err, "lwz");
 		break;
+	default:
+		return -EINVAL;
 	}
 
 	if (err) {
@@ -418,10 +431,17 @@  fsl_rio_config_write(struct rio_mport *m
 	pr_debug
 	    ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
 	     index, destid, hopcount, offset, len, val);
+
+	/* 16MB maintenance windows possible */
+	/* allow only aligned access to maintenance registers */
+	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
+		return -EINVAL;
+
 	out_be32(&priv->maint_atmu_regs->rowtar,
-		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+		 (destid << 22) | (hopcount << 12) | (offset >> 12));
+	out_be32(&priv->maint_atmu_regs->rowtear,  (destid >> 10));
 
-	data = (u8 *) priv->maint_win + offset;
+	data = (u8 *) priv->maint_win + (offset & 0x3FFFFF);
 	switch (len) {
 	case 1:
 		out_8((u8 *) data, val);
@@ -429,9 +449,11 @@  fsl_rio_config_write(struct rio_mport *m
 	case 2:
 		out_be16((u16 *) data, val);
 		break;
-	default:
+	case 4:
 		out_be32((u32 *) data, val);
 		break;
+	default:
+		return -EINVAL;
 	}
 
 	return 0;