浏览代码

misc: pci_endpoint_test: Add support to test PCI EP in K2G

TI's K2G EP has the following restrictions:
*) BAR_0 of k2g EP is mapped to application registers so
   pci_endpoint_test cannot use it. (Use BAR_1 instead).
   (Ref 11.14.4.9.2 Inbound Address Translation in K2G TRM SPRUHY8F
    January 2016 – Revised May 2017)
*) K2G EP requires host buffer addresses to be aligned to 1MB boundary.
   (Ref: 11.14.4.9.1 Outbound Address Translation in K2G TRM SPRUHY8F
    January 2016 – Revised May 2017)
*) K2G EP requires RC to program the PCI address in
   PCIE_IB_START_LO/PCIE_IB_START_HI registers.
   (Ref 11.14.4.9.2 Inbound Address Translation in K2G TRM SPRUHY8F
    January 2016 – Revised May 2017)

Accommodate these restrictions in pci_endpoint_test in order to use
it to test K2G EP.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Kishon Vijay Abraham I 6 年之前
父节点
当前提交
b566bb21d5
共有 1 个文件被更改,包括 44 次插入1 次删除
  1. 44 1
      drivers/misc/pci_endpoint_test.c

+ 44 - 1
drivers/misc/pci_endpoint_test.c

@@ -76,10 +76,16 @@
 #define PCI_ENDPOINT_TEST_IRQ_NUMBER		0x28
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
+#define PCI_DEVICE_ID_TI_K2G			0xb00b
 
 #define is_am654_pci_dev(pdev)		\
 		((pdev)->device == PCI_DEVICE_ID_TI_AM654)
 
+#define K2G_IB_START_L0(n)		(0x304 + (0x10 * (n)))
+#define K2G_IB_START_HI(n)		(0x308 + (0x10 * (n)))
+
+#define is_k2g_pci_dev(pdev)		((pdev)->device == PCI_DEVICE_ID_TI_K2G)
+
 static DEFINE_IDA(pci_endpoint_test_ida);
 
 #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
@@ -601,7 +607,8 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 		bar = arg;
 		if (bar < 0 || bar > 5)
 			goto ret;
-		if (is_am654_pci_dev(pdev) && bar == BAR_0)
+		if ((is_am654_pci_dev(pdev) || is_k2g_pci_dev(pdev)) &&
+		    bar == BAR_0)
 			goto ret;
 		ret = pci_endpoint_test_bar(test, bar);
 		break;
@@ -639,6 +646,28 @@ static const struct file_operations pci_endpoint_test_fops = {
 	.unlocked_ioctl = pci_endpoint_test_ioctl,
 };
 
+static int pci_endpoint_test_k2g_init(struct pci_endpoint_test *test)
+{
+	struct pci_dev *pdev = test->pdev;
+	enum pci_barno bar;
+	resource_size_t start;
+
+	if (!test->bar[0])
+		return -EINVAL;
+
+	for (bar = BAR_1; bar <= BAR_5; bar++) {
+		start = pci_resource_start(pdev, bar);
+		pci_endpoint_test_bar_writel(test, BAR_0,
+					     K2G_IB_START_L0(bar - 1),
+					     lower_32_bits(start));
+		pci_endpoint_test_bar_writel(test, BAR_0,
+					     K2G_IB_START_HI(bar - 1),
+					     upper_32_bits(start));
+	}
+
+	return 0;
+}
+
 static int pci_endpoint_test_probe(struct pci_dev *pdev,
 				   const struct pci_device_id *ent)
 {
@@ -717,6 +746,12 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
 		goto err_iounmap;
 	}
 
+	if (is_k2g_pci_dev(pdev)) {
+		err = pci_endpoint_test_k2g_init(test);
+		if (err)
+			goto err_iounmap;
+	}
+
 	pci_set_drvdata(pdev, test);
 
 	id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL);
@@ -799,6 +834,11 @@ static const struct pci_endpoint_test_data am654_data = {
 	.alignment = SZ_64K,
 };
 
+static const struct pci_endpoint_test_data k2g_data = {
+	.test_reg_bar = BAR_1,
+	.alignment = SZ_1M,
+};
+
 static const struct pci_device_id pci_endpoint_test_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
@@ -806,6 +846,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
 	  .driver_data = (kernel_ulong_t)&am654_data
 	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_K2G),
+	  .driver_data = (kernel_ulong_t)&k2g_data
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);