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 |