xref: /openbmc/u-boot/test/dm/pci.c (revision 95e11069)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2d3b7ff14SSimon Glass /*
3d3b7ff14SSimon Glass  * Copyright (C) 2015 Google, Inc
4d3b7ff14SSimon Glass  */
5d3b7ff14SSimon Glass 
6d3b7ff14SSimon Glass #include <common.h>
7d3b7ff14SSimon Glass #include <dm.h>
8d3b7ff14SSimon Glass #include <asm/io.h>
93839b4e8SBin Meng #include <asm/test.h>
10d3b7ff14SSimon Glass #include <dm/test.h>
11e721b882SJoe Hershberger #include <test/ut.h>
12d3b7ff14SSimon Glass 
13d3b7ff14SSimon Glass /* Test that sandbox PCI works correctly */
14e721b882SJoe Hershberger static int dm_test_pci_base(struct unit_test_state *uts)
15d3b7ff14SSimon Glass {
16d3b7ff14SSimon Glass 	struct udevice *bus;
17d3b7ff14SSimon Glass 
18d3b7ff14SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus));
19d3b7ff14SSimon Glass 
20d3b7ff14SSimon Glass 	return 0;
21d3b7ff14SSimon Glass }
22d3b7ff14SSimon Glass DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
23d3b7ff14SSimon Glass 
242db7f2b7SBin Meng /* Test that sandbox PCI bus numbering and device works correctly */
252db7f2b7SBin Meng static int dm_test_pci_busdev(struct unit_test_state *uts)
262bb02e4fSSimon Glass {
272bb02e4fSSimon Glass 	struct udevice *bus;
283839b4e8SBin Meng 	struct udevice *swap;
293839b4e8SBin Meng 	u16 vendor, device;
302bb02e4fSSimon Glass 
31dee4d752SBin Meng 	/* Test bus#0 and its devices */
322bb02e4fSSimon Glass 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus));
332bb02e4fSSimon Glass 
342db7f2b7SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x00, 0), &swap));
353839b4e8SBin Meng 	vendor = 0;
363839b4e8SBin Meng 	ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor));
373839b4e8SBin Meng 	ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor);
382db7f2b7SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap));
393839b4e8SBin Meng 	device = 0;
403839b4e8SBin Meng 	ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device));
413839b4e8SBin Meng 	ut_asserteq(SANDBOX_PCI_DEVICE_ID, device);
422db7f2b7SBin Meng 
43dee4d752SBin Meng 	/* Test bus#1 and its devices */
44dee4d752SBin Meng 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus));
45dee4d752SBin Meng 
46dee4d752SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap));
473839b4e8SBin Meng 	vendor = 0;
483839b4e8SBin Meng 	ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor));
493839b4e8SBin Meng 	ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor);
50dee4d752SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x0c, 0), &swap));
513839b4e8SBin Meng 	device = 0;
523839b4e8SBin Meng 	ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device));
533839b4e8SBin Meng 	ut_asserteq(SANDBOX_PCI_DEVICE_ID, device);
54dee4d752SBin Meng 
552bb02e4fSSimon Glass 	return 0;
562bb02e4fSSimon Glass }
572db7f2b7SBin Meng DM_TEST(dm_test_pci_busdev, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
582bb02e4fSSimon Glass 
59d3b7ff14SSimon Glass /* Test that we can use the swapcase device correctly */
60e721b882SJoe Hershberger static int dm_test_pci_swapcase(struct unit_test_state *uts)
61d3b7ff14SSimon Glass {
62dd4808f9SBin Meng 	struct udevice *swap;
63d3b7ff14SSimon Glass 	ulong io_addr, mem_addr;
64d3b7ff14SSimon Glass 	char *ptr;
65d3b7ff14SSimon Glass 
662db7f2b7SBin Meng 	/* Check that asking for the device 0 automatically fires up PCI */
672db7f2b7SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x00, 0), &swap));
682db7f2b7SBin Meng 
692db7f2b7SBin Meng 	/* First test I/O */
702db7f2b7SBin Meng 	io_addr = dm_pci_read_bar32(swap, 0);
712db7f2b7SBin Meng 	outb(2, io_addr);
722db7f2b7SBin Meng 	ut_asserteq(2, inb(io_addr));
732db7f2b7SBin Meng 
742db7f2b7SBin Meng 	/*
752db7f2b7SBin Meng 	 * Now test memory mapping - note we must unmap and remap to cause
762db7f2b7SBin Meng 	 * the swapcase emulation to see our data and response.
772db7f2b7SBin Meng 	 */
782db7f2b7SBin Meng 	mem_addr = dm_pci_read_bar32(swap, 1);
792db7f2b7SBin Meng 	ptr = map_sysmem(mem_addr, 20);
802db7f2b7SBin Meng 	strcpy(ptr, "This is a TesT");
812db7f2b7SBin Meng 	unmap_sysmem(ptr);
822db7f2b7SBin Meng 
832db7f2b7SBin Meng 	ptr = map_sysmem(mem_addr, 20);
842db7f2b7SBin Meng 	ut_asserteq_str("tHIS IS A tESt", ptr);
852db7f2b7SBin Meng 	unmap_sysmem(ptr);
862db7f2b7SBin Meng 
872db7f2b7SBin Meng 	/* Check that asking for the device 1 automatically fires up PCI */
88c0322412SSimon Glass 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap));
89d3b7ff14SSimon Glass 
90d3b7ff14SSimon Glass 	/* First test I/O */
91c0322412SSimon Glass 	io_addr = dm_pci_read_bar32(swap, 0);
92d3b7ff14SSimon Glass 	outb(2, io_addr);
93d3b7ff14SSimon Glass 	ut_asserteq(2, inb(io_addr));
94d3b7ff14SSimon Glass 
95d3b7ff14SSimon Glass 	/*
96d3b7ff14SSimon Glass 	 * Now test memory mapping - note we must unmap and remap to cause
97d3b7ff14SSimon Glass 	 * the swapcase emulation to see our data and response.
98d3b7ff14SSimon Glass 	 */
99c0322412SSimon Glass 	mem_addr = dm_pci_read_bar32(swap, 1);
100d3b7ff14SSimon Glass 	ptr = map_sysmem(mem_addr, 20);
101d3b7ff14SSimon Glass 	strcpy(ptr, "This is a TesT");
102d3b7ff14SSimon Glass 	unmap_sysmem(ptr);
103d3b7ff14SSimon Glass 
104d3b7ff14SSimon Glass 	ptr = map_sysmem(mem_addr, 20);
105d3b7ff14SSimon Glass 	ut_asserteq_str("tHIS IS A tESt", ptr);
106d3b7ff14SSimon Glass 	unmap_sysmem(ptr);
107d3b7ff14SSimon Glass 
108d3b7ff14SSimon Glass 	return 0;
109d3b7ff14SSimon Glass }
110d3b7ff14SSimon Glass DM_TEST(dm_test_pci_swapcase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
11182b31043SBin Meng 
11282b31043SBin Meng /* Test that we can dynamically bind the device driver correctly */
11382b31043SBin Meng static int dm_test_pci_drvdata(struct unit_test_state *uts)
11482b31043SBin Meng {
11582b31043SBin Meng 	struct udevice *bus, *swap;
11682b31043SBin Meng 
11782b31043SBin Meng 	/* Check that asking for the device automatically fires up PCI */
11882b31043SBin Meng 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus));
11982b31043SBin Meng 
12082b31043SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap));
12182b31043SBin Meng 	ut_asserteq(SWAP_CASE_DRV_DATA, swap->driver_data);
12282b31043SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x0c, 0), &swap));
12382b31043SBin Meng 	ut_asserteq(SWAP_CASE_DRV_DATA, swap->driver_data);
12482b31043SBin Meng 
12582b31043SBin Meng 	return 0;
12682b31043SBin Meng }
12782b31043SBin Meng DM_TEST(dm_test_pci_drvdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
1283ed214acSBin Meng 
1293ed214acSBin Meng /* Test that devices on PCI bus#2 can be accessed correctly */
1303ed214acSBin Meng static int dm_test_pci_mixed(struct unit_test_state *uts)
1313ed214acSBin Meng {
1323ed214acSBin Meng 	/* PCI bus#2 has both statically and dynamic declared devices */
1333ed214acSBin Meng 	struct udevice *bus, *swap;
1343ed214acSBin Meng 	u16 vendor, device;
1353ed214acSBin Meng 	ulong io_addr, mem_addr;
1363ed214acSBin Meng 	char *ptr;
1373ed214acSBin Meng 
1383ed214acSBin Meng 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 2, &bus));
1393ed214acSBin Meng 
1403ed214acSBin Meng 	/* Test the dynamic device */
1413ed214acSBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(2, 0x08, 0), &swap));
1423ed214acSBin Meng 	vendor = 0;
1433ed214acSBin Meng 	ut_assertok(dm_pci_read_config16(swap, PCI_VENDOR_ID, &vendor));
1443ed214acSBin Meng 	ut_asserteq(SANDBOX_PCI_VENDOR_ID, vendor);
1453ed214acSBin Meng 
1463ed214acSBin Meng 	/* First test I/O */
1473ed214acSBin Meng 	io_addr = dm_pci_read_bar32(swap, 0);
1483ed214acSBin Meng 	outb(2, io_addr);
1493ed214acSBin Meng 	ut_asserteq(2, inb(io_addr));
1503ed214acSBin Meng 
1513ed214acSBin Meng 	/*
1523ed214acSBin Meng 	 * Now test memory mapping - note we must unmap and remap to cause
1533ed214acSBin Meng 	 * the swapcase emulation to see our data and response.
1543ed214acSBin Meng 	 */
1553ed214acSBin Meng 	mem_addr = dm_pci_read_bar32(swap, 1);
1563ed214acSBin Meng 	ptr = map_sysmem(mem_addr, 30);
1573ed214acSBin Meng 	strcpy(ptr, "This is a TesT oN dYNAMIc");
1583ed214acSBin Meng 	unmap_sysmem(ptr);
1593ed214acSBin Meng 
1603ed214acSBin Meng 	ptr = map_sysmem(mem_addr, 30);
1613ed214acSBin Meng 	ut_asserteq_str("tHIS IS A tESt On DynamiC", ptr);
1623ed214acSBin Meng 	unmap_sysmem(ptr);
1633ed214acSBin Meng 
1643ed214acSBin Meng 	/* Test the static device */
1653ed214acSBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(2, 0x1f, 0), &swap));
1663ed214acSBin Meng 	device = 0;
1673ed214acSBin Meng 	ut_assertok(dm_pci_read_config16(swap, PCI_DEVICE_ID, &device));
1683ed214acSBin Meng 	ut_asserteq(SANDBOX_PCI_DEVICE_ID, device);
1693ed214acSBin Meng 
1703ed214acSBin Meng 	/* First test I/O */
1713ed214acSBin Meng 	io_addr = dm_pci_read_bar32(swap, 0);
1723ed214acSBin Meng 	outb(2, io_addr);
1733ed214acSBin Meng 	ut_asserteq(2, inb(io_addr));
1743ed214acSBin Meng 
1753ed214acSBin Meng 	/*
1763ed214acSBin Meng 	 * Now test memory mapping - note we must unmap and remap to cause
1773ed214acSBin Meng 	 * the swapcase emulation to see our data and response.
1783ed214acSBin Meng 	 */
1793ed214acSBin Meng 	mem_addr = dm_pci_read_bar32(swap, 1);
1803ed214acSBin Meng 	ptr = map_sysmem(mem_addr, 30);
1813ed214acSBin Meng 	strcpy(ptr, "This is a TesT oN sTATIc");
1823ed214acSBin Meng 	unmap_sysmem(ptr);
1833ed214acSBin Meng 
1843ed214acSBin Meng 	ptr = map_sysmem(mem_addr, 30);
1853ed214acSBin Meng 	ut_asserteq_str("tHIS IS A tESt On StatiC", ptr);
1863ed214acSBin Meng 	unmap_sysmem(ptr);
1873ed214acSBin Meng 
1883ed214acSBin Meng 	return 0;
1893ed214acSBin Meng }
1903ed214acSBin Meng DM_TEST(dm_test_pci_mixed, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
191*95e11069SBin Meng 
192*95e11069SBin Meng /* Test looking up PCI capability and extended capability */
193*95e11069SBin Meng static int dm_test_pci_cap(struct unit_test_state *uts)
194*95e11069SBin Meng {
195*95e11069SBin Meng 	struct udevice *bus, *swap;
196*95e11069SBin Meng 	int cap;
197*95e11069SBin Meng 
198*95e11069SBin Meng 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus));
199*95e11069SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap));
200*95e11069SBin Meng 
201*95e11069SBin Meng 	/* look up PCI_CAP_ID_EXP */
202*95e11069SBin Meng 	cap = dm_pci_find_capability(swap, PCI_CAP_ID_EXP);
203*95e11069SBin Meng 	ut_asserteq(PCI_CAP_ID_EXP_OFFSET, cap);
204*95e11069SBin Meng 
205*95e11069SBin Meng 	/* look up PCI_CAP_ID_PCIX */
206*95e11069SBin Meng 	cap = dm_pci_find_capability(swap, PCI_CAP_ID_PCIX);
207*95e11069SBin Meng 	ut_asserteq(0, cap);
208*95e11069SBin Meng 
209*95e11069SBin Meng 	ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus));
210*95e11069SBin Meng 	ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap));
211*95e11069SBin Meng 
212*95e11069SBin Meng 	/* look up PCI_EXT_CAP_ID_DSN */
213*95e11069SBin Meng 	cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_DSN);
214*95e11069SBin Meng 	ut_asserteq(PCI_EXT_CAP_ID_DSN_OFFSET, cap);
215*95e11069SBin Meng 
216*95e11069SBin Meng 	/* look up PCI_EXT_CAP_ID_SRIOV */
217*95e11069SBin Meng 	cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_SRIOV);
218*95e11069SBin Meng 	ut_asserteq(0, cap);
219*95e11069SBin Meng 
220*95e11069SBin Meng 	return 0;
221*95e11069SBin Meng }
222*95e11069SBin Meng DM_TEST(dm_test_pci_cap, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
223