LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Zhang Wei <wei.zhang@freescale.com>
To: mporter@kernel.crashing.org, galak@kernel.crashing.org
Cc: linux-kernel@vger.kernel.org, linuxppc-dev@ozlabs.org,
	Zhang Wei <wei.zhang@freescale.com>
Subject: [PATCH 13/17] Add FSL RapidIO controller memory ops functions.
Date: Wed,  5 Mar 2008 00:29:58 +0800	[thread overview]
Message-ID: <1204648202-5495-13-git-send-email-wei.zhang@freescale.com> (raw)
In-Reply-To: <1204648202-5495-12-git-send-email-wei.zhang@freescale.com>

Add FSL RapidIO controller (MPC85xx, MPC86xx) memory operation
functions, which include map inbound/outbound window and
unmap incound/outbound window.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
 arch/powerpc/sysdev/fsl_rio.c |  202 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 202 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index d793084..c260ae5 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -30,6 +30,8 @@
 #define IRQ_RIO_TX(m)		(((struct rio_priv *)(m->priv))->txirq)
 #define IRQ_RIO_RX(m)		(((struct rio_priv *)(m->priv))->rxirq)
 
+#define IS_64BIT_RES ((sizeof(resource_size_t) == 8) ? 1 : 0)
+
 #define RIO_ATMU_REGS_OFFSET	0x10c00
 #define RIO_P_MSG_REGS_OFFSET	0x11000
 #define RIO_S_MSG_REGS_OFFSET	0x13000
@@ -39,6 +41,15 @@
 #define RIO_ISR_AACR_AA		0x1	/* Accept All ID */
 #define RIO_MAINT_WIN_SIZE	0x400000
 #define RIO_DBELL_WIN_SIZE	0x1000
+#define RIO_MAX_INB_ATMU	4
+#define RIO_MAX_OUTB_ATMU	8
+#define RIO_INB_ATMU_REGS_OFFSET	0x10de0
+#define RIO_ATMU_EN_MASK	0x80000000
+
+#define RIO_NREAD		0x4
+#define RIO_NWRITE		0x4
+#define RIO_NWRITE_R		0x5
+#define RIO_NREAD_R		0x5
 
 #define RIO_MSG_OMR_MUI		0x00000002
 #define RIO_MSG_OSR_TE		0x00000080
@@ -82,6 +93,15 @@ struct rio_atmu_regs {
 	u32 pad3[3];
 };
 
+struct rio_inb_atmu_regs {
+	u32 riwtar;
+	u32 pad1;
+	u32 riwbar;
+	u32 pad2;
+	u32 riwar;
+	u32 pad3[3];
+};
+
 struct rio_msg_regs {
 	u32 omr;
 	u32 osr;
@@ -334,6 +354,180 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
 }
 
 /**
+ * fsl_rio_map_inb_mem -- Mapping inbound memory region.
+ * @lstart: Local memory space start address.
+ * @rstart: RapidIO space start address.
+ * @size: The mapping region size.
+ * @flags: Flags for mapping. 0 for using default flags.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the inbound mapping
+ * from rstart to lstart.
+ */
+static int fsl_rio_map_inb_mem(struct rio_mport *mport, resource_size_t lstart,
+		resource_size_t rstart,	resource_size_t size, u32 flags)
+{
+	int i;
+	struct rio_priv *priv = mport->priv;
+	struct rio_inb_atmu_regs __iomem *inbatmu = (struct rio_inb_atmu_regs *)
+				(priv->regs_win + RIO_INB_ATMU_REGS_OFFSET) - 1;
+	int size_ffs;
+	resource_size_t align;
+
+	if (flags == 0)
+		flags = (RIO_NREAD_R << 4) | RIO_NWRITE_R;
+
+	align = (size < 0x1000) ? 0x1000 : 1 << (__ilog2(size - 1) + 1);
+
+	/* Align the size */
+	if ((lstart + size) > (_ALIGN_DOWN(lstart, align) + align)) {
+		size_ffs = __ffs(_ALIGN_DOWN(lstart + size - 1, align));
+		size = 1 << (size_ffs +	(((_ALIGN_DOWN(lstart, 1 << size_ffs) +
+				(1 << size_ffs)) < (lstart + size)) ? 1 : 0));
+	} else
+		size = align;
+
+	if ((lstart & (size - 1)) != (rstart & (size - 1))) {
+		dev_err(mport->dev, "The local address 0x%x can not be aligned "
+			"to the same size 0x%x with the RapidIO space "
+			"address 0x%x!\n", lstart, size, rstart);
+		return -EINVAL;
+	}
+
+	/* Search for free inbound ATMU */
+	for (i = 1;
+		(i <= RIO_MAX_INB_ATMU) && (inbatmu->riwar & RIO_ATMU_EN_MASK);
+		i++, inbatmu--)
+		;
+
+	if (i > RIO_MAX_INB_ATMU) {
+		dev_err(mport->dev, "No free inbound ATMU!\n");
+		return -EBUSY;
+	}
+	out_be32(&inbatmu->riwtar, ((IS_64BIT_RES ? (lstart >> 32)
+				& 0xf : 0) << 20) | ((lstart >> 12) & 0xfffff));
+	out_be32(&inbatmu->riwbar, ((IS_64BIT_RES ? (rstart >> 32)
+				& 0x3 : 0) << 20) | ((rstart >> 12) & 0xfffff));
+	out_be32(&inbatmu->riwar, 0x80000000 | (0xf << 20)
+				| ((flags & 0xff) << 12)
+				| (__ilog2(size) - 1));
+	return 0;
+}
+
+/**
+ * fsl_rio_map_outb_mem -- Mapping outbound memory region.
+ * @lstart: Local memory space start address.
+ * @rstart: RapidIO space start address.
+ * @size: The mapping region size.
+ * @tid: The target RapidIO device id.
+ * @flags: Flags for mapping. 0 for using default flags.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the outbound mapping
+ * from lstart to rstart.
+ */
+static int fsl_rio_map_outb_mem(struct rio_mport *mport, resource_size_t lstart,
+		resource_size_t rstart,	resource_size_t size,
+		u16 tid, u32 flags)
+{
+	int i;
+	struct rio_priv *priv = mport->priv;
+	struct rio_atmu_regs __iomem *outbatmu = (struct rio_atmu_regs *)
+			(priv->regs_win + RIO_ATMU_REGS_OFFSET) + 1;
+	int size_ffs;
+	resource_size_t align;
+
+	if (flags == 0)
+		flags = (RIO_NREAD << 4) | RIO_NWRITE_R;
+
+	align = (size < 0x1000) ? 0x1000 : 1 << (__ilog2(size - 1) + 1);
+
+	/* Align the size */
+	if ((lstart + size) > (_ALIGN_DOWN(lstart, align) + align)) {
+		size_ffs = __ffs(_ALIGN_DOWN(lstart + size - 1, align));
+		size = 1 << (size_ffs +	(((_ALIGN_DOWN(lstart, 1 << size_ffs) +
+				(1 << size_ffs)) < (lstart + size)) ? 1 : 0));
+	} else
+		size = align;
+
+	if ((lstart & (size - 1)) != (rstart & (size - 1))) {
+		dev_err(mport->dev, "The local address 0x%x can not be aligned "
+			"to the same size 0x%x with the RapidIO space address "
+			"0x%x!\n", lstart, size, rstart);
+		return -EINVAL;
+	}
+
+	/* Search for free outbound ATMU */
+	for (i = 1;
+	      (i <= RIO_MAX_OUTB_ATMU) && (outbatmu->rowar & RIO_ATMU_EN_MASK);
+	      i++, outbatmu++)
+		;
+
+	if (i > RIO_MAX_OUTB_ATMU) {
+		dev_err(mport->dev, "No free outbound ATMU!\n");
+		return -EBUSY;
+	}
+	out_be32(&outbatmu->rowtar, ((tid & 0x3ff) << 22)
+			| ((IS_64BIT_RES ? (rstart >> 32) & 0x3 : 0) << 20)
+			| ((rstart >> 12) & 0xfffff));
+	if (mport->phy_type == RIO_PHY_SERIAL)
+		out_be32(&outbatmu->rowtear, tid >> 10);
+	out_be32(&outbatmu->rowbar, ((IS_64BIT_RES ?
+					(lstart >> 32) & 0xf : 0) << 20)
+					| ((lstart >> 12) & 0xfffff));
+	out_be32(&outbatmu->rowar, 0x80000000
+				| ((flags & 0xff) << 12)
+				| (__ilog2(size) - 1));
+	return 0;
+}
+
+/**
+ * fsl_rio_unmap_inb_mem -- Unmapping inbound memory region.
+ * @lstart: Local memory space start address.
+ */
+static void fsl_rio_unmap_inb_mem(struct rio_mport *mport, resource_size_t lstart)
+{
+	int i;
+	struct rio_priv *priv = mport->priv;
+	struct rio_inb_atmu_regs __iomem *inbatmu = (struct rio_inb_atmu_regs *)
+			(priv->regs_win + RIO_INB_ATMU_REGS_OFFSET) - 1;
+
+	/* Search for inbound ATMU */
+	for (i = 1; i <= RIO_MAX_INB_ATMU ; i++, inbatmu--) {
+		u32 tar = ((IS_64BIT_RES ? (lstart >> 32) & 0xf : 0) << 20)
+			| ((lstart >> 12) & 0xfffff);
+		if (inbatmu->riwtar == tar) {
+			out_be32(&inbatmu->riwar, ~(RIO_ATMU_EN_MASK));
+			return;
+		}
+	}
+}
+
+/**
+ * fsl_rio_unmap_inb_mem -- Unmapping outbound memory region.
+ * @lstart: Local memory space start address.
+ */
+static void fsl_rio_unmap_outb_mem(struct rio_mport *mport, resource_size_t lstart)
+{
+	int i;
+	struct rio_priv *priv = mport->priv;
+	struct rio_atmu_regs __iomem *outbatmu = (struct rio_atmu_regs *)
+			(priv->regs_win + RIO_ATMU_REGS_OFFSET) + 1;
+
+	/* Search for outbound ATMU */
+	for (i = 1; i <= RIO_MAX_OUTB_ATMU ; i++, outbatmu++) {
+		u32 bar = ((IS_64BIT_RES ? (lstart >> 32) & 0xf : 0) << 20)
+			| ((lstart >> 12) & 0xfffff);
+		if (outbatmu->rowbar == bar) {
+			out_be32(&outbatmu->rowar, ~(RIO_ATMU_EN_MASK));
+			return;
+		}
+	}
+}
+
+/**
  * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
  * @mport: Master port with outbound message queue
  * @rdev: Target of outbound message
@@ -956,6 +1150,13 @@ static int fsl_rio_get_cmdline(char *s)
 
 __setup("riohdid=", fsl_rio_get_cmdline);
 
+static struct rio_mem_ops fsl_mem_ops = {
+	.map_inb = fsl_rio_map_inb_mem,
+	.map_outb = fsl_rio_map_outb_mem,
+	.unmap_inb = fsl_rio_unmap_inb_mem,
+	.unmap_outb = fsl_rio_unmap_outb_mem,
+};
+
 static inline void fsl_rio_info(struct device *dev, u32 ccsr)
 {
 	const char *str;
@@ -1099,6 +1300,7 @@ int fsl_rio_setup(struct of_device *dev)
 	strcpy(port->name, "RIO0 mport");
 
 	port->ops = ops;
+	port->mops = &fsl_mem_ops;
 	port->host_deviceid = fsl_rio_get_hdid(port->id);
 
 	port->priv = priv;
-- 
1.5.4


  reply	other threads:[~2008-03-04  8:34 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-04 16:29 [PATCH 01/17] Change RIO function mpc85xx_ to fsl_ Zhang Wei
2008-03-04 16:29 ` [PATCH 02/17] Add RapidIO option to kernel configuration Zhang Wei
2008-03-04 16:29   ` [PATCH 03/17] Move include/asm-ppc/rio.h to include/asm-powerpc/rio.h Zhang Wei
2008-03-04 16:29     ` [PATCH 04/17] Add RapidIO multi mport support Zhang Wei
2008-03-04 16:29       ` [PATCH 05/17] Add OF-tree support to RapidIO controller driver Zhang Wei
2008-03-04 10:12         ` Stephen Rothwell
2008-03-04 16:29         ` [PATCH 06/17] Change the kernel configurated RapidIO system size to auto-probing Zhang Wei
2008-03-04 10:20           ` Stephen Rothwell
2008-03-04 16:29           ` [PATCH 07/17] Add RapidIO node into MPC8641HPCN dts file Zhang Wei
2008-03-04 16:29             ` [PATCH 08/17] Add RapidIO node probing into MPC86xx_HPCN board id table Zhang Wei
2008-03-04 16:29               ` [PATCH 09/17] Add serial RapidIO controller support, which includes MPC8548, MPC8641 Zhang Wei
2008-03-04 16:29                 ` [PATCH 10/17] Add RapidIO connection info print out and re-training for break connection Zhang Wei
2008-03-04 16:29                   ` [PATCH 11/17] Add memory mapping driver to RapidIO Zhang Wei
2008-03-04 10:37                     ` Stephen Rothwell
2008-03-05  1:59                       ` Zhang Wei
2008-03-05  2:51                         ` Stephen Rothwell
2008-03-11  8:53                           ` Zhang Wei
2008-03-04 16:29                     ` [PATCH 12/17] Add RapidIO space allocation bitmap arithmetic Zhang Wei
2008-03-04 16:29                       ` Zhang Wei [this message]
2008-03-04 16:29                         ` [PATCH 14/17] Add the RapidIO master port maintance and doorbell window to space resources Zhang Wei
2008-03-04 16:30                           ` [PATCH 15/17] Add RapidIO proc fs for memory mapping debugging Zhang Wei
2008-03-04 16:30                             ` [PATCH 16/17] Change RapidIO doorbell source and target ID field to 16-bit Zhang Wei
2008-03-04 16:30                               ` [PATCH 17/17] Add the memory mapping support in rionet driver Zhang Wei
2008-03-11  9:07 [PATCH 01/17] Change RIO function mpc85xx_ to fsl_ Zhang Wei
2008-03-11  9:07 ` [PATCH 02/17] Add RapidIO option to kernel configuration Zhang Wei
2008-03-11  9:07   ` [PATCH 03/17] Move include/asm-ppc/rio.h to include/asm-powerpc/rio.h Zhang Wei
2008-03-11  9:07     ` [PATCH 04/17] Add RapidIO multi mport support Zhang Wei
2008-03-11  9:07       ` [PATCH 05/17] Add OF-tree support to RapidIO controller driver Zhang Wei
2008-03-11  9:07         ` [PATCH 06/17] Change the kernel configurated RapidIO system size to auto-probing Zhang Wei
2008-03-11  9:07           ` [PATCH 07/17] Add RapidIO node into MPC8641HPCN dts file Zhang Wei
2008-03-11  9:07             ` [PATCH 08/17] Add RapidIO node probing into MPC86xx_HPCN board id table Zhang Wei
2008-03-11  9:07               ` [PATCH 09/17] Add serial RapidIO controller support, which includes MPC8548, MPC8641 Zhang Wei
2008-03-11  9:07                 ` [PATCH 10/17] Add RapidIO connection info print out and re-training for break connection Zhang Wei
2008-03-11  9:07                   ` [PATCH 11/17] Add memory mapping driver to RapidIO Zhang Wei
2008-03-11  9:07                     ` [PATCH 12/17] Add RapidIO space allocation bitmap arithmetic Zhang Wei
2008-03-11  9:07                       ` [PATCH 13/17] Add FSL RapidIO controller memory ops functions Zhang Wei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1204648202-5495-13-git-send-email-wei.zhang@freescale.com \
    --to=wei.zhang@freescale.com \
    --cc=galak@kernel.crashing.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=mporter@kernel.crashing.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).