From 4a301766f5263dd94c1b95d1b1bbdf338afb1a37 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Sat, 15 Jul 2017 23:39:45 -0700 Subject: PCI: dwc: designware: Handle ->host_init() failures In several dwc-based drivers, ->host_init() can fail, so make sure to propagate and handle this to avoid continuing operation of a driver or hardware in an invalid state. Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Helgaas Acked-by: Joao Pinto Acked-by: Jingoo Han --- drivers/pci/dwc/pci-layerscape.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index fd861289ad8b..7581490f007c 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -108,31 +108,35 @@ static int ls1021_pcie_link_up(struct dw_pcie *pci) return 1; } -static void ls1021_pcie_host_init(struct pcie_port *pp) +static int ls1021_pcie_host_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct ls_pcie *pcie = to_ls_pcie(pci); struct device *dev = pci->dev; u32 index[2]; + int ret; pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,pcie-scfg"); if (IS_ERR(pcie->scfg)) { + ret = PTR_ERR(pcie->scfg); dev_err(dev, "No syscfg phandle specified\n"); pcie->scfg = NULL; - return; + return ret; } if (of_property_read_u32_array(dev->of_node, "fsl,pcie-scfg", index, 2)) { pcie->scfg = NULL; - return; + return -EINVAL; } pcie->index = index[1]; dw_pcie_setup_rc(pp); ls_pcie_drop_msg_tlp(pcie); + + return 0; } static int ls_pcie_link_up(struct dw_pcie *pci) @@ -150,7 +154,7 @@ static int ls_pcie_link_up(struct dw_pcie *pci) return 1; } -static void ls_pcie_host_init(struct pcie_port *pp) +static int ls_pcie_host_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct ls_pcie *pcie = to_ls_pcie(pci); @@ -160,6 +164,8 @@ static void ls_pcie_host_init(struct pcie_port *pp) ls_pcie_clear_multifunction(pcie); ls_pcie_drop_msg_tlp(pcie); iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); + + return 0; } static int ls_pcie_msi_host_init(struct pcie_port *pp, -- cgit v1.2.3 From a36deff6d13da8e146ad02cf38c0b81752efb305 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:52:53 +0800 Subject: PCI: layerscape: Call dw_pcie_setup_rc() from ls_pcie_host_init() We called dw_pcie_setup_rc() from the ls1021a host init function, but not from the common ls_pcie_host_init() function, so platforms other than ls1021a still depended on initialization by the bootloader. Call dw_pcie_setup_rc() from ls_pcie_host_init() to reduce dependencies on the bootloader. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index 7581490f007c..aebefb42377a 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -165,6 +165,8 @@ static int ls_pcie_host_init(struct pcie_port *pp) ls_pcie_drop_msg_tlp(pcie); iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); + dw_pcie_setup_rc(pp); + return 0; } -- cgit v1.2.3 From 02232343349e606c8809e2555985a806d615e4ee Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:52:54 +0800 Subject: PCI: layerscape: Move STRFMR1 access out from the DBI write-enable bracket The STRFMR1 is not a DBI read-only register, so move it out from the write-enable bracket. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index aebefb42377a..c16940044ed6 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -162,9 +162,10 @@ static int ls_pcie_host_init(struct pcie_port *pp) iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); ls_pcie_fix_class(pcie); ls_pcie_clear_multifunction(pcie); - ls_pcie_drop_msg_tlp(pcie); iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); + ls_pcie_drop_msg_tlp(pcie); + dw_pcie_setup_rc(pp); return 0; -- cgit v1.2.3 From 5da39bf0919b6e129010f1554e639940be5bcdce Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:52:55 +0800 Subject: PCI: layerscape: Add class code and multifunction fixups for ls1021a The current code depends on class code and multifunction fixups done by the bootloader. Perform these fixups in ls1021_pcie_host_init() to remove this dependency. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index c16940044ed6..3aa34214643c 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -134,6 +134,11 @@ static int ls1021_pcie_host_init(struct pcie_port *pp) dw_pcie_setup_rc(pp); + iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); + ls_pcie_fix_class(pcie); + ls_pcie_clear_multifunction(pcie); + iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); + ls_pcie_drop_msg_tlp(pcie); return 0; -- cgit v1.2.3 From ba95a82e31490b2415e9fe967c6997f5dac8fe31 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:52:56 +0800 Subject: PCI: layerscape: Move generic init functions earlier in file We will use the generic ls_pcie_link_up() and ls_pcie_host_init() from device-specific routines. Move the generic functions earlier in the file so we won't need forward declarations. This is strictly a code move with no functional change intended. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 64 ++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index 3aa34214643c..160035efa4d9 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -108,6 +108,38 @@ static int ls1021_pcie_link_up(struct dw_pcie *pci) return 1; } +static int ls_pcie_link_up(struct dw_pcie *pci) +{ + struct ls_pcie *pcie = to_ls_pcie(pci); + u32 state; + + state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >> + pcie->drvdata->ltssm_shift) & + LTSSM_STATE_MASK; + + if (state < LTSSM_PCIE_L0) + return 0; + + return 1; +} + +static int ls_pcie_host_init(struct pcie_port *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct ls_pcie *pcie = to_ls_pcie(pci); + + iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); + ls_pcie_fix_class(pcie); + ls_pcie_clear_multifunction(pcie); + iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); + + ls_pcie_drop_msg_tlp(pcie); + + dw_pcie_setup_rc(pp); + + return 0; +} + static int ls1021_pcie_host_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -144,38 +176,6 @@ static int ls1021_pcie_host_init(struct pcie_port *pp) return 0; } -static int ls_pcie_link_up(struct dw_pcie *pci) -{ - struct ls_pcie *pcie = to_ls_pcie(pci); - u32 state; - - state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >> - pcie->drvdata->ltssm_shift) & - LTSSM_STATE_MASK; - - if (state < LTSSM_PCIE_L0) - return 0; - - return 1; -} - -static int ls_pcie_host_init(struct pcie_port *pp) -{ - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct ls_pcie *pcie = to_ls_pcie(pci); - - iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); - ls_pcie_fix_class(pcie); - ls_pcie_clear_multifunction(pcie); - iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); - - ls_pcie_drop_msg_tlp(pcie); - - dw_pcie_setup_rc(pp); - - return 0; -} - static int ls_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip) { -- cgit v1.2.3 From fa92dba92c0026a8378085dbeab8a1d8ad8476c6 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:52:57 +0800 Subject: PCI: layerscape: Refactor ls1021_pcie_host_init() ls1021_pcie_host_init() duplicated the code in the generic ls_pcie_host_init(). Call ls_pcie_host_init() instead of duplicating the code. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index 160035efa4d9..27234dae4cba 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -164,16 +164,7 @@ static int ls1021_pcie_host_init(struct pcie_port *pp) } pcie->index = index[1]; - dw_pcie_setup_rc(pp); - - iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); - ls_pcie_fix_class(pcie); - ls_pcie_clear_multifunction(pcie); - iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); - - ls_pcie_drop_msg_tlp(pcie); - - return 0; + return ls_pcie_host_init(pp); } static int ls_pcie_msi_host_init(struct pcie_port *pp, -- cgit v1.2.3 From 4a2745d760facac895c107bed41e167e3806fced Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:52:58 +0800 Subject: PCI: layerscape: Disable outbound windows configured by bootloader Disable all the outbound windows to avoid one transaction hitting multiple outbound windows. dw_pcie_setup_rc() will reconfigure the outbound windows, which may conflict with windows configured by the bootloader. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index 27234dae4cba..a77f7562c310 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -35,6 +35,8 @@ #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ #define PCIE_DBI_RO_WR_EN 0x8bc /* DBI Read-Only Write Enable Register */ +#define PCIE_IATU_NUM 6 + struct ls_pcie_drvdata { u32 lut_offset; u32 ltssm_shift; @@ -91,6 +93,14 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) iowrite32(val, pci->dbi_base + PCIE_STRFMR1); } +static void ls_pcie_disable_outbound_atus(struct ls_pcie *pcie) +{ + int i; + + for (i = 0; i < PCIE_IATU_NUM; i++) + dw_pcie_disable_atu(pcie->pci, DW_PCIE_REGION_OUTBOUND, i); +} + static int ls1021_pcie_link_up(struct dw_pcie *pci) { u32 state; @@ -128,6 +138,13 @@ static int ls_pcie_host_init(struct pcie_port *pp) struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct ls_pcie *pcie = to_ls_pcie(pci); + /* + * Disable outbound windows configured by the bootloader to avoid + * one transaction hitting multiple outbound windows. + * dw_pcie_setup_rc() will reconfigure the outbound windows. + */ + ls_pcie_disable_outbound_atus(pcie); + iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); ls_pcie_fix_class(pcie); ls_pcie_clear_multifunction(pcie); -- cgit v1.2.3 From e44abfed6fcb750d24f4438dc9d5a02eebb5fcac Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:52:59 +0800 Subject: PCI: dwc: Add accessors for write permission of DBI read-only registers The read-only DBI registers can be written only when the "Write to RO Registers Using DBI" (DBI_RO_WR_EN) field of MISC_CONTROL_1_OFF is set. Add accessors to enable and disable write permission, and use them instead of accessing MISC_CONTROL_1_OFF directly. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Joao Pinto Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index a77f7562c310..627e2ed48090 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -33,7 +33,6 @@ /* PEX Internal Configuration Registers */ #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ -#define PCIE_DBI_RO_WR_EN 0x8bc /* DBI Read-Only Write Enable Register */ #define PCIE_IATU_NUM 6 @@ -145,10 +144,10 @@ static int ls_pcie_host_init(struct pcie_port *pp) */ ls_pcie_disable_outbound_atus(pcie); - iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); + dw_pcie_dbi_ro_wr_en(pci); ls_pcie_fix_class(pcie); ls_pcie_clear_multifunction(pcie); - iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); + dw_pcie_dbi_ro_wr_dis(pci); ls_pcie_drop_msg_tlp(pcie); -- cgit v1.2.3 From c3f909398827b03fad9391951b3daa4a11dcf663 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 28 Aug 2017 18:53:01 +0800 Subject: PCI: layerscape: Remove unnecessary class code fixup Now that the Class Code fixup in dw_pcie_setup_rc() works, remove the fixup from the Layerscape driver. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Roy Zang --- drivers/pci/dwc/pci-layerscape.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index 627e2ed48090..3f53826b127e 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -73,14 +73,6 @@ static void ls_pcie_clear_multifunction(struct ls_pcie *pcie) iowrite8(PCI_HEADER_TYPE_BRIDGE, pci->dbi_base + PCI_HEADER_TYPE); } -/* Fix class value */ -static void ls_pcie_fix_class(struct ls_pcie *pcie) -{ - struct dw_pcie *pci = pcie->pci; - - iowrite16(PCI_CLASS_BRIDGE_PCI, pci->dbi_base + PCI_CLASS_DEVICE); -} - /* Drop MSG TLP except for Vendor MSG */ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) { @@ -145,7 +137,6 @@ static int ls_pcie_host_init(struct pcie_port *pp) ls_pcie_disable_outbound_atus(pcie); dw_pcie_dbi_ro_wr_en(pci); - ls_pcie_fix_class(pcie); ls_pcie_clear_multifunction(pcie); dw_pcie_dbi_ro_wr_dis(pci); -- cgit v1.2.3 From 8f89357094e67bb09456457a00bbad4002293d15 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Fri, 4 Aug 2017 14:41:33 +0800 Subject: PCI: layerscape: Add support for ls2088a The ls2088a PCIe controller's register addresses are different from ls2080a, so add a match entry to identify ls2088a PCIe. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Minghuan Lian --- drivers/pci/dwc/pci-layerscape.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index 3f53826b127e..780eab9beb1e 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -244,12 +244,21 @@ static struct ls_pcie_drvdata ls2080_drvdata = { .dw_pcie_ops = &dw_ls_pcie_ops, }; +static struct ls_pcie_drvdata ls2088_drvdata = { + .lut_offset = 0x80000, + .ltssm_shift = 0, + .lut_dbg = 0x407fc, + .ops = &ls_pcie_host_ops, + .dw_pcie_ops = &dw_ls_pcie_ops, +}; + static const struct of_device_id ls_pcie_of_match[] = { { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata }, { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, + { .compatible = "fsl,ls2088a-pcie", .data = &ls2088_drvdata }, { }, }; -- cgit v1.2.3 From 03fc6134c260930b3784fd0a06edcf44f4e39581 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Fri, 4 Aug 2017 14:41:34 +0800 Subject: PCI: layerscape: Add support for ls1088a Add support for ls1088a. Signed-off-by: Hou Zhiqiang Signed-off-by: Bjorn Helgaas Acked-by: Minghuan Lian --- drivers/pci/dwc/pci-layerscape.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/dwc/pci-layerscape.c') diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index 780eab9beb1e..87fa486bee2c 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -259,6 +259,7 @@ static const struct of_device_id ls_pcie_of_match[] = { { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, { .compatible = "fsl,ls2088a-pcie", .data = &ls2088_drvdata }, + { .compatible = "fsl,ls1088a-pcie", .data = &ls2088_drvdata }, { }, }; -- cgit v1.2.3