Skip to content

Commit

Permalink
rapidio/tsi721: add inbound memory mapping callbacks
Browse files Browse the repository at this point in the history
Add Tsi721 routines to support RapidIO subsystem's inbound memory mapping
interface (RapidIO to system's local memory).

Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Alexandre Bounine authored and Linus Torvalds committed Oct 5, 2012
1 parent da1589f commit 71afe34
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 4 deletions.
88 changes: 87 additions & 1 deletion drivers/rapidio/devices/tsi721.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,90 @@ static void tsi721_init_pc2sr_mapping(struct tsi721_device *priv)
iowrite32(0, priv->regs + TSI721_OBWINLB(i));
}

/**
* tsi721_rio_map_inb_mem -- Mapping inbound memory region.
* @mport: RapidIO master port
* @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 tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
u64 rstart, u32 size, u32 flags)
{
struct tsi721_device *priv = mport->priv;
int i;
u32 regval;

if (!is_power_of_2(size) || size < 0x1000 ||
((u64)lstart & (size - 1)) || (rstart & (size - 1)))
return -EINVAL;

/* Search for free inbound translation window */
for (i = 0; i < TSI721_IBWIN_NUM; i++) {
regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
if (!(regval & TSI721_IBWIN_LB_WEN))
break;
}

if (i >= TSI721_IBWIN_NUM) {
dev_err(&priv->pdev->dev,
"Unable to find free inbound window\n");
return -EBUSY;
}

iowrite32(TSI721_IBWIN_SIZE(size) << 8,
priv->regs + TSI721_IBWIN_SZ(i));

iowrite32(((u64)lstart >> 32), priv->regs + TSI721_IBWIN_TUA(i));
iowrite32(((u64)lstart & TSI721_IBWIN_TLA_ADD),
priv->regs + TSI721_IBWIN_TLA(i));

iowrite32(rstart >> 32, priv->regs + TSI721_IBWIN_UB(i));
iowrite32((rstart & TSI721_IBWIN_LB_BA) | TSI721_IBWIN_LB_WEN,
priv->regs + TSI721_IBWIN_LB(i));
dev_dbg(&priv->pdev->dev,
"Configured IBWIN%d mapping (RIO_0x%llx -> PCIe_0x%llx)\n",
i, rstart, (unsigned long long)lstart);

return 0;
}

/**
* fsl_rio_unmap_inb_mem -- Unmapping inbound memory region.
* @mport: RapidIO master port
* @lstart: Local memory space start address.
*/
static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport,
dma_addr_t lstart)
{
struct tsi721_device *priv = mport->priv;
int i;
u64 addr;
u32 regval;

/* Search for matching active inbound translation window */
for (i = 0; i < TSI721_IBWIN_NUM; i++) {
regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
if (regval & TSI721_IBWIN_LB_WEN) {
regval = ioread32(priv->regs + TSI721_IBWIN_TUA(i));
addr = (u64)regval << 32;
regval = ioread32(priv->regs + TSI721_IBWIN_TLA(i));
addr |= regval & TSI721_IBWIN_TLA_ADD;

if (addr == (u64)lstart) {
iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
break;
}
}
}
}

/**
* tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe)
* translation regions.
Expand All @@ -874,7 +958,7 @@ static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv)

/* Disable all SR2PC inbound windows */
for (i = 0; i < TSI721_IBWIN_NUM; i++)
iowrite32(0, priv->regs + TSI721_IBWINLB(i));
iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
}

/**
Expand Down Expand Up @@ -2144,6 +2228,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv)
ops->add_outb_message = tsi721_add_outb_message;
ops->add_inb_buffer = tsi721_add_inb_buffer;
ops->get_inb_message = tsi721_get_inb_message;
ops->map_inb = tsi721_rio_map_inb_mem;
ops->unmap_inb = tsi721_rio_unmap_inb_mem;

mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
if (!mport) {
Expand Down
15 changes: 12 additions & 3 deletions drivers/rapidio/devices/tsi721.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,18 @@

#define TSI721_IBWIN_NUM 8

#define TSI721_IBWINLB(x) (0x29000 + (x) * 0x20)
#define TSI721_IBWINLB_BA 0xfffff000
#define TSI721_IBWINLB_WEN 0x00000001
#define TSI721_IBWIN_LB(x) (0x29000 + (x) * 0x20)
#define TSI721_IBWIN_LB_BA 0xfffff000
#define TSI721_IBWIN_LB_WEN 0x00000001

#define TSI721_IBWIN_UB(x) (0x29004 + (x) * 0x20)
#define TSI721_IBWIN_SZ(x) (0x29008 + (x) * 0x20)
#define TSI721_IBWIN_SZ_SIZE 0x00001f00
#define TSI721_IBWIN_SIZE(size) (__fls(size) - 12)

#define TSI721_IBWIN_TLA(x) (0x2900c + (x) * 0x20)
#define TSI721_IBWIN_TLA_ADD 0xfffff000
#define TSI721_IBWIN_TUA(x) (0x29010 + (x) * 0x20)

#define TSI721_SR2PC_GEN_INTE 0x29800
#define TSI721_SR2PC_PWE 0x29804
Expand Down

0 comments on commit 71afe34

Please sign in to comment.