Skip to content

Commit 3785393

Browse files
committed
Merge branch 'pci/controller/dwc'
- Use msleep() in DWC core instead of usleep_range() for ~100 ms sleep (Konrad Dybcio) - Fix iATU slot management to avoid using the wrong slot after PERST# assert/deassert, which could potentially cause DMA to go the wrong place (Frank Li) - Consolidate dw_pcie_prog_outbound_atu() arguments into a struct to ease adding new functionality like initiating Message TLPs (Yoshihiro Shimoda) - Add support for endpoints to initiate PCIe messages (Yoshihiro Shimoda) - Add #defines for PCIe INTx messages (Yoshihiro Shimoda) - Add support for endpoints to initiate PCIe PME_Turn_Off messages for system suspend (Frank Li) - Add dw_pcie_ep_linkdown() to reinitialize registers that are lost when the link goes down (Manivannan Sadhasivam) - Use dw_pcie_ep_linkdown() to reinitialize qcom non-sticky registers that are lost when the link goes down (Manivannan Sadhasivam) - Enforce DWC limitation that 64-bit BARs must start with the even numbered BAR (Niklas Cassel) * pci/controller/dwc: PCI: dwc: ep: Enforce DWC specific 64-bit BAR limitation PCI: layerscape-ep: Use the generic dw_pcie_ep_linkdown() API to handle Link Down event PCI: qcom-ep: Use the generic dw_pcie_ep_linkdown() API to handle Link Down event PCI: dwc: ep: Remove dw_pcie_ep_init_notify() wrapper PCI: dwc: ep: Add a generic dw_pcie_ep_linkdown() API to handle Link Down event PCI: dwc: Add generic MSG TLP support for sending PME_Turn_Off when system suspend PCI: Add PCIE_MSG_CODE_PME_TURN_OFF message macro PCI: Add PCIE_MSG_CODE_ASSERT_INTx message macros PCI: dwc: Add outbound MSG TLPs support PCI: dwc: Consolidate args of dw_pcie_prog_outbound_atu() into a structure PCI: dwc: Fix index 0 incorrectly being interpreted as a free ATU slot PCI: dwc: Use msleep() in dw_pcie_wait_for_link()
2 parents 35f0c94 + 9b10e87 commit 3785393

16 files changed

+304
-135
lines changed

drivers/pci/controller/dwc/pci-dra7xx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
474474
return ret;
475475
}
476476

477-
dw_pcie_ep_init_notify(ep);
477+
pci_epc_init_notify(ep->epc);
478478

479479
return 0;
480480
}

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,7 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
11261126
return ret;
11271127
}
11281128

1129-
dw_pcie_ep_init_notify(ep);
1129+
pci_epc_init_notify(ep->epc);
11301130

11311131
/* Start LTSSM. */
11321132
imx6_pcie_ltssm_enable(dev);

drivers/pci/controller/dwc/pci-keystone.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ static int ks_pcie_probe(struct platform_device *pdev)
12931293
goto err_ep_init;
12941294
}
12951295

1296-
dw_pcie_ep_init_notify(&pci->ep);
1296+
pci_epc_init_notify(pci->ep.epc);
12971297

12981298
break;
12991299
default:

drivers/pci/controller/dwc/pci-layerscape-ep.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
104104
dev_dbg(pci->dev, "Link up\n");
105105
} else if (val & PEX_PF0_PME_MES_DR_LDD) {
106106
dev_dbg(pci->dev, "Link down\n");
107-
pci_epc_linkdown(pci->ep.epc);
107+
dw_pcie_ep_linkdown(&pci->ep);
108108
} else if (val & PEX_PF0_PME_MES_DR_HRD) {
109109
dev_dbg(pci->dev, "Hot reset\n");
110110
}
@@ -286,7 +286,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
286286
return ret;
287287
}
288288

289-
dw_pcie_ep_init_notify(&pci->ep);
289+
pci_epc_init_notify(pci->ep.epc);
290290

291291
return ls_pcie_ep_interrupt_init(pcie, pdev);
292292
}

drivers/pci/controller/dwc/pcie-artpec6.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
452452
return ret;
453453
}
454454

455-
dw_pcie_ep_init_notify(&pci->ep);
455+
pci_epc_init_notify(pci->ep.epc);
456456

457457
break;
458458
default:

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 98 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,6 @@
1515
#include <linux/pci-epc.h>
1616
#include <linux/pci-epf.h>
1717

18-
/**
19-
* dw_pcie_ep_linkup - Notify EPF drivers about Link Up event
20-
* @ep: DWC EP device
21-
*/
22-
void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
23-
{
24-
struct pci_epc *epc = ep->epc;
25-
26-
pci_epc_linkup(epc);
27-
}
28-
EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
29-
30-
/**
31-
* dw_pcie_ep_init_notify - Notify EPF drivers about EPC initialization complete
32-
* @ep: DWC EP device
33-
*/
34-
void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
35-
{
36-
struct pci_epc *epc = ep->epc;
37-
38-
pci_epc_init_notify(epc);
39-
}
40-
EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify);
41-
4218
/**
4319
* dw_pcie_ep_get_func_from_ep - Get the struct dw_pcie_ep_func corresponding to
4420
* the endpoint function
@@ -161,7 +137,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
161137
if (!ep->bar_to_atu[bar])
162138
free_win = find_first_zero_bit(ep->ib_window_map, pci->num_ib_windows);
163139
else
164-
free_win = ep->bar_to_atu[bar];
140+
free_win = ep->bar_to_atu[bar] - 1;
165141

166142
if (free_win >= pci->num_ib_windows) {
167143
dev_err(pci->dev, "No free inbound window\n");
@@ -175,15 +151,18 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
175151
return ret;
176152
}
177153

178-
ep->bar_to_atu[bar] = free_win;
154+
/*
155+
* Always increment free_win before assignment, since value 0 is used to identify
156+
* unallocated mapping.
157+
*/
158+
ep->bar_to_atu[bar] = free_win + 1;
179159
set_bit(free_win, ep->ib_window_map);
180160

181161
return 0;
182162
}
183163

184-
static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
185-
phys_addr_t phys_addr,
186-
u64 pci_addr, size_t size)
164+
static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep,
165+
struct dw_pcie_ob_atu_cfg *atu)
187166
{
188167
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
189168
u32 free_win;
@@ -195,13 +174,13 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
195174
return -EINVAL;
196175
}
197176

198-
ret = dw_pcie_prog_ep_outbound_atu(pci, func_no, free_win, PCIE_ATU_TYPE_MEM,
199-
phys_addr, pci_addr, size);
177+
atu->index = free_win;
178+
ret = dw_pcie_prog_outbound_atu(pci, atu);
200179
if (ret)
201180
return ret;
202181

203182
set_bit(free_win, ep->ob_window_map);
204-
ep->outbound_addr[free_win] = phys_addr;
183+
ep->outbound_addr[free_win] = atu->cpu_addr;
205184

206185
return 0;
207186
}
@@ -212,7 +191,10 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
212191
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
213192
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
214193
enum pci_barno bar = epf_bar->barno;
215-
u32 atu_index = ep->bar_to_atu[bar];
194+
u32 atu_index = ep->bar_to_atu[bar] - 1;
195+
196+
if (!ep->bar_to_atu[bar])
197+
return;
216198

217199
__dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags);
218200

@@ -233,6 +215,13 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
233215
int ret, type;
234216
u32 reg;
235217

218+
/*
219+
* DWC does not allow BAR pairs to overlap, e.g. you cannot combine BARs
220+
* 1 and 2 to form a 64-bit BAR.
221+
*/
222+
if ((flags & PCI_BASE_ADDRESS_MEM_TYPE_64) && (bar & 1))
223+
return -EINVAL;
224+
236225
reg = PCI_BASE_ADDRESS_0 + (4 * bar);
237226

238227
if (!(flags & PCI_BASE_ADDRESS_SPACE))
@@ -301,8 +290,14 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
301290
int ret;
302291
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
303292
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
304-
305-
ret = dw_pcie_ep_outbound_atu(ep, func_no, addr, pci_addr, size);
293+
struct dw_pcie_ob_atu_cfg atu = { 0 };
294+
295+
atu.func_no = func_no;
296+
atu.type = PCIE_ATU_TYPE_MEM;
297+
atu.cpu_addr = addr;
298+
atu.pci_addr = pci_addr;
299+
atu.size = size;
300+
ret = dw_pcie_ep_outbound_atu(ep, &atu);
306301
if (ret) {
307302
dev_err(pci->dev, "Failed to enable address\n");
308303
return ret;
@@ -673,6 +668,34 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
673668
return 0;
674669
}
675670

671+
static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
672+
{
673+
unsigned int offset;
674+
unsigned int nbars;
675+
u32 reg, i;
676+
677+
offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
678+
679+
dw_pcie_dbi_ro_wr_en(pci);
680+
681+
if (offset) {
682+
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
683+
nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
684+
PCI_REBAR_CTRL_NBAR_SHIFT;
685+
686+
/*
687+
* PCIe r6.0, sec 7.8.6.2 require us to support at least one
688+
* size in the range from 1 MB to 512 GB. Advertise support
689+
* for 1 MB BAR size only.
690+
*/
691+
for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
692+
dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
693+
}
694+
695+
dw_pcie_setup(pci);
696+
dw_pcie_dbi_ro_wr_dis(pci);
697+
}
698+
676699
/**
677700
* dw_pcie_ep_init_registers - Initialize DWC EP specific registers
678701
* @ep: DWC EP device
@@ -687,13 +710,11 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
687710
struct dw_pcie_ep_func *ep_func;
688711
struct device *dev = pci->dev;
689712
struct pci_epc *epc = ep->epc;
690-
unsigned int offset, ptm_cap_base;
691-
unsigned int nbars;
713+
u32 ptm_cap_base, reg;
692714
u8 hdr_type;
693715
u8 func_no;
694-
int i, ret;
695716
void *addr;
696-
u32 reg;
717+
int ret;
697718

698719
hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &
699720
PCI_HEADER_TYPE_MASK;
@@ -756,25 +777,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
756777
if (ep->ops->init)
757778
ep->ops->init(ep);
758779

759-
offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
760780
ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
761781

762-
dw_pcie_dbi_ro_wr_en(pci);
763-
764-
if (offset) {
765-
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
766-
nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
767-
PCI_REBAR_CTRL_NBAR_SHIFT;
768-
769-
/*
770-
* PCIe r6.0, sec 7.8.6.2 require us to support at least one
771-
* size in the range from 1 MB to 512 GB. Advertise support
772-
* for 1 MB BAR size only.
773-
*/
774-
for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
775-
dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, BIT(4));
776-
}
777-
778782
/*
779783
* PTM responder capability can be disabled only after disabling
780784
* PTM root capability.
@@ -791,8 +795,7 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
791795
dw_pcie_dbi_ro_wr_dis(pci);
792796
}
793797

794-
dw_pcie_setup(pci);
795-
dw_pcie_dbi_ro_wr_dis(pci);
798+
dw_pcie_ep_init_non_sticky_registers(pci);
796799

797800
return 0;
798801

@@ -803,6 +806,43 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
803806
}
804807
EXPORT_SYMBOL_GPL(dw_pcie_ep_init_registers);
805808

809+
/**
810+
* dw_pcie_ep_linkup - Notify EPF drivers about Link Up event
811+
* @ep: DWC EP device
812+
*/
813+
void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
814+
{
815+
struct pci_epc *epc = ep->epc;
816+
817+
pci_epc_linkup(epc);
818+
}
819+
EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
820+
821+
/**
822+
* dw_pcie_ep_linkdown - Notify EPF drivers about Link Down event
823+
* @ep: DWC EP device
824+
*
825+
* Non-sticky registers are also initialized before sending the notification to
826+
* the EPF drivers. This is needed since the registers need to be initialized
827+
* before the link comes back again.
828+
*/
829+
void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep)
830+
{
831+
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
832+
struct pci_epc *epc = ep->epc;
833+
834+
/*
835+
* Initialize the non-sticky DWC registers as they would've reset post
836+
* Link Down. This is specifically needed for drivers not supporting
837+
* PERST# as they have no way to reinitialize the registers before the
838+
* link comes back again.
839+
*/
840+
dw_pcie_ep_init_non_sticky_registers(pci);
841+
842+
pci_epc_linkdown(epc);
843+
}
844+
EXPORT_SYMBOL_GPL(dw_pcie_ep_linkdown);
845+
806846
/**
807847
* dw_pcie_ep_init - Initialize the endpoint device
808848
* @ep: DWC EP device

0 commit comments

Comments
 (0)