diff options
| author | Alexandre Bounine <alexandre.bounine@idt.com> | 2012-10-04 20:16:00 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-05 14:05:21 -0400 |
| commit | 71afe3417173437361d4f4900a925f0158a4d713 (patch) | |
| tree | 407798803c40f6ef4cacbe54b1ddedf04352c887 /drivers/rapidio | |
| parent | da1589f07393e88e917c317ea0c85ea37918a1cf (diff) | |
rapidio/tsi721: add inbound memory mapping callbacks
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>
Diffstat (limited to 'drivers/rapidio')
| -rw-r--r-- | drivers/rapidio/devices/tsi721.c | 88 | ||||
| -rw-r--r-- | drivers/rapidio/devices/tsi721.h | 15 |
2 files changed, 99 insertions, 4 deletions
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 78dff6f40736..38ecd8f4d60e 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
| @@ -862,6 +862,90 @@ static void tsi721_init_pc2sr_mapping(struct tsi721_device *priv) | |||
| 862 | } | 862 | } |
| 863 | 863 | ||
| 864 | /** | 864 | /** |
| 865 | * tsi721_rio_map_inb_mem -- Mapping inbound memory region. | ||
| 866 | * @mport: RapidIO master port | ||
| 867 | * @lstart: Local memory space start address. | ||
| 868 | * @rstart: RapidIO space start address. | ||
| 869 | * @size: The mapping region size. | ||
| 870 | * @flags: Flags for mapping. 0 for using default flags. | ||
| 871 | * | ||
| 872 | * Return: 0 -- Success. | ||
| 873 | * | ||
| 874 | * This function will create the inbound mapping | ||
| 875 | * from rstart to lstart. | ||
| 876 | */ | ||
| 877 | static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart, | ||
| 878 | u64 rstart, u32 size, u32 flags) | ||
| 879 | { | ||
| 880 | struct tsi721_device *priv = mport->priv; | ||
| 881 | int i; | ||
| 882 | u32 regval; | ||
| 883 | |||
| 884 | if (!is_power_of_2(size) || size < 0x1000 || | ||
| 885 | ((u64)lstart & (size - 1)) || (rstart & (size - 1))) | ||
| 886 | return -EINVAL; | ||
| 887 | |||
| 888 | /* Search for free inbound translation window */ | ||
| 889 | for (i = 0; i < TSI721_IBWIN_NUM; i++) { | ||
| 890 | regval = ioread32(priv->regs + TSI721_IBWIN_LB(i)); | ||
| 891 | if (!(regval & TSI721_IBWIN_LB_WEN)) | ||
| 892 | break; | ||
| 893 | } | ||
| 894 | |||
| 895 | if (i >= TSI721_IBWIN_NUM) { | ||
| 896 | dev_err(&priv->pdev->dev, | ||
| 897 | "Unable to find free inbound window\n"); | ||
| 898 | return -EBUSY; | ||
| 899 | } | ||
| 900 | |||
| 901 | iowrite32(TSI721_IBWIN_SIZE(size) << 8, | ||
| 902 | priv->regs + TSI721_IBWIN_SZ(i)); | ||
| 903 | |||
| 904 | iowrite32(((u64)lstart >> 32), priv->regs + TSI721_IBWIN_TUA(i)); | ||
| 905 | iowrite32(((u64)lstart & TSI721_IBWIN_TLA_ADD), | ||
| 906 | priv->regs + TSI721_IBWIN_TLA(i)); | ||
| 907 | |||
| 908 | iowrite32(rstart >> 32, priv->regs + TSI721_IBWIN_UB(i)); | ||
| 909 | iowrite32((rstart & TSI721_IBWIN_LB_BA) | TSI721_IBWIN_LB_WEN, | ||
| 910 | priv->regs + TSI721_IBWIN_LB(i)); | ||
| 911 | dev_dbg(&priv->pdev->dev, | ||
| 912 | "Configured IBWIN%d mapping (RIO_0x%llx -> PCIe_0x%llx)\n", | ||
| 913 | i, rstart, (unsigned long long)lstart); | ||
| 914 | |||
| 915 | return 0; | ||
| 916 | } | ||
| 917 | |||
| 918 | /** | ||
| 919 | * fsl_rio_unmap_inb_mem -- Unmapping inbound memory region. | ||
| 920 | * @mport: RapidIO master port | ||
| 921 | * @lstart: Local memory space start address. | ||
| 922 | */ | ||
| 923 | static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport, | ||
| 924 | dma_addr_t lstart) | ||
| 925 | { | ||
| 926 | struct tsi721_device *priv = mport->priv; | ||
| 927 | int i; | ||
| 928 | u64 addr; | ||
| 929 | u32 regval; | ||
| 930 | |||
| 931 | /* Search for matching active inbound translation window */ | ||
| 932 | for (i = 0; i < TSI721_IBWIN_NUM; i++) { | ||
| 933 | regval = ioread32(priv->regs + TSI721_IBWIN_LB(i)); | ||
| 934 | if (regval & TSI721_IBWIN_LB_WEN) { | ||
| 935 | regval = ioread32(priv->regs + TSI721_IBWIN_TUA(i)); | ||
| 936 | addr = (u64)regval << 32; | ||
| 937 | regval = ioread32(priv->regs + TSI721_IBWIN_TLA(i)); | ||
| 938 | addr |= regval & TSI721_IBWIN_TLA_ADD; | ||
| 939 | |||
| 940 | if (addr == (u64)lstart) { | ||
| 941 | iowrite32(0, priv->regs + TSI721_IBWIN_LB(i)); | ||
| 942 | break; | ||
| 943 | } | ||
| 944 | } | ||
| 945 | } | ||
| 946 | } | ||
| 947 | |||
| 948 | /** | ||
| 865 | * tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe) | 949 | * tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe) |
| 866 | * translation regions. | 950 | * translation regions. |
| 867 | * @priv: pointer to tsi721 private data | 951 | * @priv: pointer to tsi721 private data |
| @@ -874,7 +958,7 @@ static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv) | |||
| 874 | 958 | ||
| 875 | /* Disable all SR2PC inbound windows */ | 959 | /* Disable all SR2PC inbound windows */ |
| 876 | for (i = 0; i < TSI721_IBWIN_NUM; i++) | 960 | for (i = 0; i < TSI721_IBWIN_NUM; i++) |
| 877 | iowrite32(0, priv->regs + TSI721_IBWINLB(i)); | 961 | iowrite32(0, priv->regs + TSI721_IBWIN_LB(i)); |
| 878 | } | 962 | } |
| 879 | 963 | ||
| 880 | /** | 964 | /** |
| @@ -2144,6 +2228,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
| 2144 | ops->add_outb_message = tsi721_add_outb_message; | 2228 | ops->add_outb_message = tsi721_add_outb_message; |
| 2145 | ops->add_inb_buffer = tsi721_add_inb_buffer; | 2229 | ops->add_inb_buffer = tsi721_add_inb_buffer; |
| 2146 | ops->get_inb_message = tsi721_get_inb_message; | 2230 | ops->get_inb_message = tsi721_get_inb_message; |
| 2231 | ops->map_inb = tsi721_rio_map_inb_mem; | ||
| 2232 | ops->unmap_inb = tsi721_rio_unmap_inb_mem; | ||
| 2147 | 2233 | ||
| 2148 | mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); | 2234 | mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); |
| 2149 | if (!mport) { | 2235 | if (!mport) { |
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index 59de9d7be346..7d5b13ba8d4f 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
| @@ -156,9 +156,18 @@ | |||
| 156 | 156 | ||
| 157 | #define TSI721_IBWIN_NUM 8 | 157 | #define TSI721_IBWIN_NUM 8 |
| 158 | 158 | ||
| 159 | #define TSI721_IBWINLB(x) (0x29000 + (x) * 0x20) | 159 | #define TSI721_IBWIN_LB(x) (0x29000 + (x) * 0x20) |
| 160 | #define TSI721_IBWINLB_BA 0xfffff000 | 160 | #define TSI721_IBWIN_LB_BA 0xfffff000 |
| 161 | #define TSI721_IBWINLB_WEN 0x00000001 | 161 | #define TSI721_IBWIN_LB_WEN 0x00000001 |
| 162 | |||
| 163 | #define TSI721_IBWIN_UB(x) (0x29004 + (x) * 0x20) | ||
| 164 | #define TSI721_IBWIN_SZ(x) (0x29008 + (x) * 0x20) | ||
| 165 | #define TSI721_IBWIN_SZ_SIZE 0x00001f00 | ||
| 166 | #define TSI721_IBWIN_SIZE(size) (__fls(size) - 12) | ||
| 167 | |||
| 168 | #define TSI721_IBWIN_TLA(x) (0x2900c + (x) * 0x20) | ||
| 169 | #define TSI721_IBWIN_TLA_ADD 0xfffff000 | ||
| 170 | #define TSI721_IBWIN_TUA(x) (0x29010 + (x) * 0x20) | ||
| 162 | 171 | ||
| 163 | #define TSI721_SR2PC_GEN_INTE 0x29800 | 172 | #define TSI721_SR2PC_GEN_INTE 0x29800 |
| 164 | #define TSI721_SR2PC_PWE 0x29804 | 173 | #define TSI721_SR2PC_PWE 0x29804 |
