Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'remotes/lorenzo/pci/iproc'

- Work around iproc CRS completion issues (Srinath Mannam)

- Allow smaller iproc outbound windows so driver can work on 32-bit
systems (Srinath Mannam)

- Use iproc-specific config read for PAXBv2 (not PAXB) (Srinath Mannam)

* remotes/lorenzo/pci/iproc:
PCI: iproc: Enable iProc config read for PAXBv2
PCI: iproc: Allow outbound configuration for 32-bit I/O region
PCI: iproc: Add CRS check in config read

+41 -5
+41 -5
drivers/pci/controller/pcie-iproc.c
··· 60 60 #define APB_ERR_EN_SHIFT 0 61 61 #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) 62 62 63 + #define CFG_RD_SUCCESS 0 64 + #define CFG_RD_UR 1 65 + #define CFG_RD_CRS 2 66 + #define CFG_RD_CA 3 63 67 #define CFG_RETRY_STATUS 0xffff0001 64 68 #define CFG_RETRY_STATUS_TIMEOUT_US 500000 /* 500 milliseconds */ 65 69 ··· 293 289 IPROC_PCIE_IARR4, 294 290 IPROC_PCIE_IMAP4, 295 291 292 + /* config read status */ 293 + IPROC_PCIE_CFG_RD_STATUS, 294 + 296 295 /* link status */ 297 296 IPROC_PCIE_LINK_STATUS, 298 297 ··· 357 350 [IPROC_PCIE_IMAP3] = 0xe08, 358 351 [IPROC_PCIE_IARR4] = 0xe68, 359 352 [IPROC_PCIE_IMAP4] = 0xe70, 353 + [IPROC_PCIE_CFG_RD_STATUS] = 0xee0, 360 354 [IPROC_PCIE_LINK_STATUS] = 0xf0c, 361 355 [IPROC_PCIE_APB_ERR_EN] = 0xf40, 362 356 }; ··· 482 474 return (pcie->base + offset); 483 475 } 484 476 485 - static unsigned int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) 477 + static unsigned int iproc_pcie_cfg_retry(struct iproc_pcie *pcie, 478 + void __iomem *cfg_data_p) 486 479 { 487 480 int timeout = CFG_RETRY_STATUS_TIMEOUT_US; 488 481 unsigned int data; 482 + u32 status; 489 483 490 484 /* 491 485 * As per PCIe spec r3.1, sec 2.3.2, CRS Software Visibility only ··· 508 498 */ 509 499 data = readl(cfg_data_p); 510 500 while (data == CFG_RETRY_STATUS && timeout--) { 501 + /* 502 + * CRS state is set in CFG_RD status register 503 + * This will handle the case where CFG_RETRY_STATUS is 504 + * valid config data. 505 + */ 506 + status = iproc_pcie_read_reg(pcie, IPROC_PCIE_CFG_RD_STATUS); 507 + if (status != CFG_RD_CRS) 508 + return data; 509 + 511 510 udelay(1); 512 511 data = readl(cfg_data_p); 513 512 } ··· 595 576 if (!cfg_data_p) 596 577 return PCIBIOS_DEVICE_NOT_FOUND; 597 578 598 - data = iproc_pcie_cfg_retry(cfg_data_p); 579 + data = iproc_pcie_cfg_retry(pcie, cfg_data_p); 599 580 600 581 *val = data; 601 582 if (size <= 2) ··· 955 936 resource_size_t window_size = 956 937 ob_map->window_sizes[size_idx] * SZ_1M; 957 938 958 - if (size < window_size) 959 - continue; 939 + /* 940 + * Keep iterating until we reach the last window and 941 + * with the minimal window size at index zero. In this 942 + * case, we take a compromise by mapping it using the 943 + * minimum window size that can be supported 944 + */ 945 + if (size < window_size) { 946 + if (size_idx > 0 || window_idx > 0) 947 + continue; 948 + 949 + /* 950 + * For the corner case of reaching the minimal 951 + * window size that can be supported on the 952 + * last window 953 + */ 954 + axi_addr = ALIGN_DOWN(axi_addr, window_size); 955 + pci_addr = ALIGN_DOWN(pci_addr, window_size); 956 + size = window_size; 957 + } 960 958 961 959 if (!IS_ALIGNED(axi_addr, window_size) || 962 960 !IS_ALIGNED(pci_addr, window_size)) { ··· 1383 1347 break; 1384 1348 case IPROC_PCIE_PAXB: 1385 1349 regs = iproc_pcie_reg_paxb; 1386 - pcie->iproc_cfg_read = true; 1387 1350 pcie->has_apb_err_disable = true; 1388 1351 if (pcie->need_ob_cfg) { 1389 1352 pcie->ob_map = paxb_ob_map; ··· 1391 1356 break; 1392 1357 case IPROC_PCIE_PAXB_V2: 1393 1358 regs = iproc_pcie_reg_paxb_v2; 1359 + pcie->iproc_cfg_read = true; 1394 1360 pcie->has_apb_err_disable = true; 1395 1361 if (pcie->need_ob_cfg) { 1396 1362 pcie->ob_map = paxb_v2_ob_map;