Commit 3ea675fc7bbc15f8a1b3b97d801bee2e9b4261e5

Authored by Richard Zhu
1 parent 8d2b169fd7
Exists in imx_3.0.35_4.1.0

ENGR00298393 pcie: rc can access mem of ep

- setup one new outbound memory region at rc side, used
to let imx6 pcie rc can access the memory of imx6 pcie ep
in imx6 pcie rc ep validation system.
- set the default address of the ddr memory to be 0x4000_0000
- change the test region size to be 15MB.

NOTE:
- default address 0x4000_0000 of ep side would be
accessed in this demo.
Test howto:
step1:
EP side:
1.1:
echo 0x40000000 > /sys/devices/platform/imx-pcie/ep_bar0_addr

1.2:
memtool -32 0x40000000 4
E
Reading 0x4 count starting at address 0x40000000

0x40000000:  EFE9EDF4 7583FB39 39EAFFEA FBDCFD78

step2:
RC side:
memtool -32 0x01000000=58D454DA
memtool -32 0x01000004=7332095B

step3:
EP side:
memtool -32 0x40000000 4
E
Reading 0x4 count starting at address 0x40000000

0x40000000:  58D454DA 7332095B 39EAFFEA FBDCFD78

Signed-off-by: Richard Zhu <r65037@freescale.com>

Showing 1 changed file with 81 additions and 42 deletions Side-by-side Diff

arch/arm/mach-mx6/pcie.c
... ... @@ -3,7 +3,7 @@
3 3 *
4 4 * PCIe host controller driver for IMX6 SOCs
5 5 *
6   - * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  6 + * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved.
7 7 *
8 8 * Bits taken from arch/arm/mach-dove/pcie.c
9 9 *
10 10  
11 11  
... ... @@ -163,16 +163,17 @@
163 163 #define PCIE_CONF_REG(r) ((r) & ~0x3)
164 164  
165 165 /*
166   - * The default values of the RC's reserved ddr memory
167   - * used to verify EP mode.
  166 + * The default value of the reserved ddr memory
  167 + * used to verify EP/RC memory space access operations.
168 168 * BTW, here is the layout of the 1G ddr on SD boards
169 169 * 0x1000_0000 ~ 0x4FFF_FFFF
170 170 */
171   -static u32 rc_ddr_test_region = 0x40000000;
172   -static u32 rc_ddr_test_region_size = (SZ_16M - SZ_16K);
  171 +static u32 ddr_test_region = 0x40000000;
  172 +/* The upper 1MB space is reserved for CFG, MSI, and so on usage */
  173 +static u32 ddr_test_region_size = (SZ_16M - SZ_1M);
173 174  
174 175 #ifdef EP_SELF_IO_TEST
175   -static void *rc_ddr_test_reg1, *rc_ddr_test_reg2;
  176 +static void *ddr_test_reg1, *ddr_test_reg2;
176 177 static void __iomem *pcie_arb_base_addr;
177 178 static struct timeval tv1, tv2, tv3;
178 179 static u32 tv_count1, tv_count2;
179 180  
... ... @@ -396,10 +397,10 @@
396 397 writel(0, dbi_base + ATU_VIEWPORT_R);
397 398 writel(PCIE_ARB_BASE_ADDR, dbi_base + ATU_REGION_LOWBASE_R);
398 399 writel(0, dbi_base + ATU_REGION_UPBASE_R);
399   - writel(PCIE_ARB_BASE_ADDR + rc_ddr_test_region_size,
  400 + writel(PCIE_ARB_BASE_ADDR + ddr_test_region_size,
400 401 dbi_base + ATU_REGION_LIMIT_ADDR_R);
401 402  
402   - writel(rc_ddr_test_region,
  403 + writel(ddr_test_region,
403 404 dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
404 405 writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
405 406 writel(MemRdWr, dbi_base + ATU_REGION_CTRL1_R);
... ... @@ -424,6 +425,24 @@
424 425 writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
425 426 writel(CfgRdWr0, dbi_base + ATU_REGION_CTRL1_R);
426 427 writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
  428 +
  429 +#ifdef CONFIG_IMX_PCIE_RC_MODE_IN_EP_RC_SYS
  430 + /*
  431 + * region1 outbound used to access target mem
  432 + * in imx6 pcie ep/rc validation system
  433 + */
  434 + writel(1, dbi_base + ATU_VIEWPORT_R);
  435 + writel(PCIE_ARB_BASE_ADDR,
  436 + dbi_base + ATU_REGION_LOWBASE_R);
  437 + writel(PCIE_ARB_BASE_ADDR + SZ_8M,
  438 + dbi_base + ATU_REGION_LIMIT_ADDR_R);
  439 + writel(0, dbi_base + ATU_REGION_UPBASE_R);
  440 +
  441 + writel(ddr_test_region, dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
  442 + writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
  443 + writel(MemRdWr, dbi_base + ATU_REGION_CTRL1_R);
  444 + writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
  445 +#endif
427 446 }
428 447  
429 448 #ifdef CONFIG_PCI_MSI
430 449  
431 450  
432 451  
... ... @@ -875,15 +894,33 @@
875 894 }
876 895  
877 896 #ifdef CONFIG_IMX_PCIE_EP_MODE_IN_EP_RC_SYS
878   -static ssize_t imx_pcie_rc_memw_info(struct device *dev,
  897 +static ssize_t imx_pcie_bar0_addr_info(struct device *dev,
879 898 struct device_attribute *devattr, char *buf)
880 899 {
  900 + return sprintf(buf, "imx-pcie-bar0-addr-info start 0x%08x\n",
  901 + readl(dbi_base + PCI_BASE_ADDRESS_0));
  902 +}
  903 +
  904 +static ssize_t imx_pcie_bar0_addr_start(struct device *dev,
  905 + struct device_attribute *attr, const char *buf, size_t count)
  906 +{
  907 + u32 bar_start;
  908 +
  909 + sscanf(buf, "%x\n", &bar_start);
  910 + writel(bar_start, dbi_base + PCI_BASE_ADDRESS_0);
  911 +
  912 + return count;
  913 +}
  914 +
  915 +static ssize_t imx_pcie_memw_info(struct device *dev,
  916 + struct device_attribute *devattr, char *buf)
  917 +{
881 918 return sprintf(buf, "imx-pcie-rc-memw-info start 0x%08x, size 0x%08x\n",
882   - rc_ddr_test_region, rc_ddr_test_region_size);
  919 + ddr_test_region, ddr_test_region_size);
883 920 }
884 921  
885 922 static ssize_t
886   -imx_pcie_rc_memw_start(struct device *dev, struct device_attribute *attr,
  923 +imx_pcie_memw_start(struct device *dev, struct device_attribute *attr,
887 924 const char *buf, size_t count)
888 925 {
889 926 u32 memw_start;
... ... @@ -896,8 +933,8 @@
896 933 return -1;
897 934 }
898 935  
899   - if (rc_ddr_test_region != memw_start) {
900   - rc_ddr_test_region = memw_start;
  936 + if (ddr_test_region != memw_start) {
  937 + ddr_test_region = memw_start;
901 938 /* Re-setup the iATU */
902 939 imx_pcie_regions_setup(dev, dbi_base);
903 940 }
904 941  
905 942  
... ... @@ -906,21 +943,21 @@
906 943 }
907 944  
908 945 static ssize_t
909   -imx_pcie_rc_memw_size(struct device *dev, struct device_attribute *attr,
  946 +imx_pcie_memw_size(struct device *dev, struct device_attribute *attr,
910 947 const char *buf, size_t count)
911 948 {
912 949 u32 memw_size;
913 950  
914 951 sscanf(buf, "%x\n", &memw_size);
915 952  
916   - if ((memw_size > (SZ_16M - SZ_16K)) || (memw_size < SZ_64K)) {
917   - dev_err(dev, "Invalid, should be [SZ_64K,SZ_16M - SZ_16KB].\n");
  953 + if ((memw_size > (SZ_16M - SZ_1M)) || (memw_size < SZ_64K)) {
  954 + dev_err(dev, "Invalid, should be [SZ_64K,SZ_16M - SZ_1MB].\n");
918 955 dev_info(dev, "For example: echo 0x800000 > /sys/...");
919 956 return -1;
920 957 }
921 958  
922   - if (rc_ddr_test_region_size != memw_size) {
923   - rc_ddr_test_region_size = memw_size;
  959 + if (ddr_test_region_size != memw_size) {
  960 + ddr_test_region_size = memw_size;
924 961 /* Re-setup the iATU */
925 962 imx_pcie_regions_setup(dev, dbi_base);
926 963 }
927 964  
928 965  
... ... @@ -928,19 +965,22 @@
928 965 return count;
929 966 }
930 967  
931   -static DEVICE_ATTR(rc_memw_info, S_IRUGO, imx_pcie_rc_memw_info, NULL);
932   -static DEVICE_ATTR(rc_memw_start_set, S_IWUGO, NULL, imx_pcie_rc_memw_start);
933   -static DEVICE_ATTR(rc_memw_size_set, S_IWUGO, NULL, imx_pcie_rc_memw_size);
  968 +static DEVICE_ATTR(memw_info, S_IRUGO, imx_pcie_memw_info, NULL);
  969 +static DEVICE_ATTR(memw_start_set, S_IWUGO, NULL, imx_pcie_memw_start);
  970 +static DEVICE_ATTR(memw_size_set, S_IWUGO, NULL, imx_pcie_memw_size);
  971 +static DEVICE_ATTR(ep_bar0_addr, S_IRWXUGO, imx_pcie_bar0_addr_info,
  972 + imx_pcie_bar0_addr_start);
934 973  
935 974 static struct attribute *imx_pcie_attrs[] = {
936 975 /*
937   - * The start address, and the limitation (64KB ~ (16MB - 16KB))
  976 + * The start address, and the limitation (64KB ~ (16MB - 1MB))
938 977 * of the ddr mem window reserved by RC, and used for EP to access.
939 978 * BTW, these attrs are only configured at EP side.
940 979 */
941   - &dev_attr_rc_memw_info.attr,
942   - &dev_attr_rc_memw_start_set.attr,
943   - &dev_attr_rc_memw_size_set.attr,
  980 + &dev_attr_memw_info.attr,
  981 + &dev_attr_memw_start_set.attr,
  982 + &dev_attr_memw_size_set.attr,
  983 + &dev_attr_ep_bar0_addr.attr,
944 984 NULL
945 985 };
946 986  
947 987  
948 988  
949 989  
950 990  
... ... @@ -1032,30 +1072,30 @@
1032 1072 if (pdata->type_ep) {
1033 1073 #ifdef EP_SELF_IO_TEST
1034 1074 /* Prepare the test regions and data */
1035   - rc_ddr_test_reg1 = kzalloc(rc_ddr_test_region_size, GFP_KERNEL);
1036   - if (!rc_ddr_test_reg1)
  1075 + ddr_test_reg1 = kzalloc(ddr_test_region_size, GFP_KERNEL);
  1076 + if (!ddr_test_reg1)
1037 1077 pr_err("PCIe EP: can't alloc the test region1.\n");
1038 1078  
1039   - rc_ddr_test_reg2 = kzalloc(rc_ddr_test_region_size, GFP_KERNEL);
1040   - if (!rc_ddr_test_reg2) {
1041   - kfree(rc_ddr_test_reg1);
  1079 + ddr_test_reg2 = kzalloc(ddr_test_region_size, GFP_KERNEL);
  1080 + if (!ddr_test_reg2) {
  1081 + kfree(ddr_test_reg1);
1042 1082 pr_err("PCIe EP: can't alloc the test region2.\n");
1043 1083 }
1044 1084  
1045 1085 pcie_arb_base_addr = ioremap_cached(PCIE_ARB_BASE_ADDR,
1046   - rc_ddr_test_region_size);
  1086 + ddr_test_region_size);
1047 1087  
1048 1088 if (!pcie_arb_base_addr) {
1049 1089 pr_err("error with ioremap in function %s\n", __func__);
1050 1090 ret = PTR_ERR(pcie_arb_base_addr);
1051   - kfree(rc_ddr_test_reg2);
1052   - kfree(rc_ddr_test_reg1);
  1091 + kfree(ddr_test_reg2);
  1092 + kfree(ddr_test_reg1);
1053 1093 goto err_base;
1054 1094 }
1055 1095  
1056   - for (i = 0; i < rc_ddr_test_region_size; i = i + 4) {
1057   - writel(0xE6600D00 + i, rc_ddr_test_reg1 + i);
1058   - writel(0xDEADBEAF, rc_ddr_test_reg2 + i);
  1096 + for (i = 0; i < ddr_test_region_size; i = i + 4) {
  1097 + writel(0xE6600D00 + i, ddr_test_reg1 + i);
  1098 + writel(0xDEADBEAF, ddr_test_reg2 + i);
1059 1099 }
1060 1100 #endif
1061 1101  
... ... @@ -1070,8 +1110,8 @@
1070 1110 } else {
1071 1111 pr_info("PCIe EP: ERROR link is down, exit!\n");
1072 1112 #ifdef EP_SELF_IO_TEST
1073   - kfree(rc_ddr_test_reg2);
1074   - kfree(rc_ddr_test_reg1);
  1113 + kfree(ddr_test_reg2);
  1114 + kfree(ddr_test_reg1);
1075 1115 iounmap(pcie_arb_base_addr);
1076 1116 #endif
1077 1117 goto err_link_down;
1078 1118  
1079 1119  
... ... @@ -1084,16 +1124,16 @@
1084 1124 do_gettimeofday(&tv1);
1085 1125  
1086 1126 memcpy((unsigned long *)pcie_arb_base_addr,
1087   - (unsigned long *)rc_ddr_test_reg1, 0xFFC000);
  1127 + (unsigned long *)ddr_test_reg1, 0xFFC000);
1088 1128  
1089 1129 do_gettimeofday(&tv2);
1090 1130  
1091   - memcpy((unsigned long *)rc_ddr_test_reg2,
  1131 + memcpy((unsigned long *)ddr_test_reg2,
1092 1132 (unsigned long *)pcie_arb_base_addr, 0xFFC000);
1093 1133  
1094 1134 do_gettimeofday(&tv3);
1095 1135  
1096   - if (memcmp(rc_ddr_test_reg2, rc_ddr_test_reg1, 0xFFC000) != 0) {
  1136 + if (memcmp(ddr_test_reg2, ddr_test_reg1, 0xFFC000) != 0) {
1097 1137 pr_info("PCIe EP: Data transfer is failed.\n");
1098 1138 } else {
1099 1139 tv_count1 = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC
... ... @@ -1112,7 +1152,6 @@
1112 1152 /(tv_count2));
1113 1153 }
1114 1154 #endif
1115   -
1116 1155 } else {
1117 1156 /* add the pcie port */
1118 1157 add_pcie_port(base, dbi_base, pdata);