Skip to content

Commit 9f5eb1b

Browse files
committed
Merge branch 'pci/controller/rockchip'
- Remove writes to unused registers (Rick Wertenbroek) - Write endpoint Device ID using correct register (Rick Wertenbroek) - Assert PCI Configuration Enable bit after probe so endpoint responds instead of generating Request Retry Status messages (Rick Wertenbroek) - Poll waiting for PHY PLLs to lock (Rick Wertenbroek) - Update RK3399 example DT binding to be valid (Rick Wertenbroek) - Use RK3399 PCIE_CLIENT_LEGACY_INT_CTRL to generate INTx instead of manually generating PCIe message (Rick Wertenbroek) - Use multiple windows to avoid address translation conflicts (Rick Wertenbroek) - Use u32 (not u16) when accessing 32-bit registers (Rick Wertenbroek) - Hide MSI-X Capability, since RK3399 can't generate MSI-X (Rick Wertenbroek) - Set endpoint controller required alignment to 256 (Damien Le Moal) * pci/controller/rockchip: PCI: rockchip: Set address alignment for endpoint mode PCI: rockchip: Don't advertise MSI-X in PCIe capabilities PCI: rockchip: Use u32 variable to access 32-bit registers PCI: rockchip: Fix window mapping and address translation for endpoint PCI: rockchip: Fix legacy IRQ generation for RK3399 PCIe endpoint core dt-bindings: PCI: Update the RK3399 example to a valid one PCI: rockchip: Add poll and timeout to wait for PHY PLLs to be locked PCI: rockchip: Assert PCI Configuration Enable bit after probe PCI: rockchip: Write PCI Device ID to correct register PCI: rockchip: Remove writes to unused registers
2 parents 9cd5f2c + 7e6689b commit 9f5eb1b

File tree

4 files changed

+154
-137
lines changed

4 files changed

+154
-137
lines changed

Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ examples:
4747
4848
pcie-ep@f8000000 {
4949
compatible = "rockchip,rk3399-pcie-ep";
50-
reg = <0x0 0xfd000000 0x0 0x1000000>, <0x0 0x80000000 0x0 0x20000>;
50+
reg = <0x0 0xfd000000 0x0 0x1000000>, <0x0 0xfa000000 0x0 0x2000000>;
5151
reg-names = "apb-base", "mem-base";
5252
clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,
5353
<&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;
@@ -63,6 +63,8 @@ examples:
6363
phys = <&pcie_phy 0>, <&pcie_phy 1>, <&pcie_phy 2>, <&pcie_phy 3>;
6464
phy-names = "pcie-phy-0", "pcie-phy-1", "pcie-phy-2", "pcie-phy-3";
6565
rockchip,max-outbound-regions = <16>;
66+
pinctrl-names = "default";
67+
pinctrl-0 = <&pcie_clkreqnb_cpm>;
6668
};
6769
};
6870
...

drivers/pci/controller/pcie-rockchip-ep.c

Lines changed: 100 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -61,70 +61,38 @@ static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip,
6161
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(region));
6262
rockchip_pcie_write(rockchip, 0,
6363
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region));
64-
rockchip_pcie_write(rockchip, 0,
65-
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(region));
66-
rockchip_pcie_write(rockchip, 0,
67-
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(region));
6864
}
6965

7066
static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
71-
u32 r, u32 type, u64 cpu_addr,
72-
u64 pci_addr, size_t size)
67+
u32 r, u64 cpu_addr, u64 pci_addr,
68+
size_t size)
7369
{
74-
u64 sz = 1ULL << fls64(size - 1);
75-
int num_pass_bits = ilog2(sz);
76-
u32 addr0, addr1, desc0, desc1;
77-
bool is_nor_msg = (type == AXI_WRAPPER_NOR_MSG);
70+
int num_pass_bits = fls64(size - 1);
71+
u32 addr0, addr1, desc0;
7872

79-
/* The minimal region size is 1MB */
8073
if (num_pass_bits < 8)
8174
num_pass_bits = 8;
8275

83-
cpu_addr -= rockchip->mem_res->start;
84-
addr0 = ((is_nor_msg ? 0x10 : (num_pass_bits - 1)) &
85-
PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
86-
(lower_32_bits(cpu_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
87-
addr1 = upper_32_bits(is_nor_msg ? cpu_addr : pci_addr);
88-
desc0 = ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(fn) | type;
89-
desc1 = 0;
90-
91-
if (is_nor_msg) {
92-
rockchip_pcie_write(rockchip, 0,
93-
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
94-
rockchip_pcie_write(rockchip, 0,
95-
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
96-
rockchip_pcie_write(rockchip, desc0,
97-
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
98-
rockchip_pcie_write(rockchip, desc1,
99-
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
100-
} else {
101-
/* PCI bus address region */
102-
rockchip_pcie_write(rockchip, addr0,
103-
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
104-
rockchip_pcie_write(rockchip, addr1,
105-
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
106-
rockchip_pcie_write(rockchip, desc0,
107-
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
108-
rockchip_pcie_write(rockchip, desc1,
109-
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
110-
111-
addr0 =
112-
((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
113-
(lower_32_bits(cpu_addr) &
114-
PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
115-
addr1 = upper_32_bits(cpu_addr);
116-
}
76+
addr0 = ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
77+
(lower_32_bits(pci_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
78+
addr1 = upper_32_bits(pci_addr);
79+
desc0 = ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(fn) | AXI_WRAPPER_MEM_WRITE;
11780

118-
/* CPU bus address region */
81+
/* PCI bus address region */
11982
rockchip_pcie_write(rockchip, addr0,
120-
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(r));
83+
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
12184
rockchip_pcie_write(rockchip, addr1,
122-
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r));
85+
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
86+
rockchip_pcie_write(rockchip, desc0,
87+
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
88+
rockchip_pcie_write(rockchip, 0,
89+
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
12390
}
12491

12592
static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
12693
struct pci_epf_header *hdr)
12794
{
95+
u32 reg;
12896
struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
12997
struct rockchip_pcie *rockchip = &ep->rockchip;
13098

@@ -137,8 +105,9 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
137105
PCIE_CORE_CONFIG_VENDOR);
138106
}
139107

140-
rockchip_pcie_write(rockchip, hdr->deviceid << 16,
141-
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + PCI_VENDOR_ID);
108+
reg = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_DID_VID);
109+
reg = (reg & 0xFFFF) | (hdr->deviceid << 16);
110+
rockchip_pcie_write(rockchip, reg, PCIE_EP_CONFIG_DID_VID);
142111

143112
rockchip_pcie_write(rockchip,
144113
hdr->revid |
@@ -256,26 +225,20 @@ static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
256225
ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
257226
}
258227

228+
static inline u32 rockchip_ob_region(phys_addr_t addr)
229+
{
230+
return (addr >> ilog2(SZ_1M)) & 0x1f;
231+
}
232+
259233
static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
260234
phys_addr_t addr, u64 pci_addr,
261235
size_t size)
262236
{
263237
struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
264238
struct rockchip_pcie *pcie = &ep->rockchip;
265-
u32 r;
266-
267-
r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG);
268-
/*
269-
* Region 0 is reserved for configuration space and shouldn't
270-
* be used elsewhere per TRM, so leave it out.
271-
*/
272-
if (r >= ep->max_regions - 1) {
273-
dev_err(&epc->dev, "no free outbound region\n");
274-
return -EINVAL;
275-
}
239+
u32 r = rockchip_ob_region(addr);
276240

277-
rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, AXI_WRAPPER_MEM_WRITE, addr,
278-
pci_addr, size);
241+
rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, addr, pci_addr, size);
279242

280243
set_bit(r, &ep->ob_region_map);
281244
ep->ob_addr[r] = addr;
@@ -290,15 +253,11 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
290253
struct rockchip_pcie *rockchip = &ep->rockchip;
291254
u32 r;
292255

293-
for (r = 0; r < ep->max_regions - 1; r++)
256+
for (r = 0; r < ep->max_regions; r++)
294257
if (ep->ob_addr[r] == addr)
295258
break;
296259

297-
/*
298-
* Region 0 is reserved for configuration space and shouldn't
299-
* be used elsewhere per TRM, so leave it out.
300-
*/
301-
if (r == ep->max_regions - 1)
260+
if (r == ep->max_regions)
302261
return;
303262

304263
rockchip_pcie_clear_ep_ob_atu(rockchip, r);
@@ -312,15 +271,15 @@ static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
312271
{
313272
struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
314273
struct rockchip_pcie *rockchip = &ep->rockchip;
315-
u16 flags;
274+
u32 flags;
316275

317276
flags = rockchip_pcie_read(rockchip,
318277
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
319278
ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
320279
flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK;
321280
flags |=
322-
((multi_msg_cap << 1) << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) |
323-
PCI_MSI_FLAGS_64BIT;
281+
(multi_msg_cap << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) |
282+
(PCI_MSI_FLAGS_64BIT << ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET);
324283
flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP;
325284
rockchip_pcie_write(rockchip, flags,
326285
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
@@ -332,7 +291,7 @@ static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
332291
{
333292
struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
334293
struct rockchip_pcie *rockchip = &ep->rockchip;
335-
u16 flags;
294+
u32 flags;
336295

337296
flags = rockchip_pcie_read(rockchip,
338297
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
@@ -345,48 +304,25 @@ static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
345304
}
346305

347306
static void rockchip_pcie_ep_assert_intx(struct rockchip_pcie_ep *ep, u8 fn,
348-
u8 intx, bool is_asserted)
307+
u8 intx, bool do_assert)
349308
{
350309
struct rockchip_pcie *rockchip = &ep->rockchip;
351-
u32 r = ep->max_regions - 1;
352-
u32 offset;
353-
u32 status;
354-
u8 msg_code;
355-
356-
if (unlikely(ep->irq_pci_addr != ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR ||
357-
ep->irq_pci_fn != fn)) {
358-
rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r,
359-
AXI_WRAPPER_NOR_MSG,
360-
ep->irq_phys_addr, 0, 0);
361-
ep->irq_pci_addr = ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR;
362-
ep->irq_pci_fn = fn;
363-
}
364310

365311
intx &= 3;
366-
if (is_asserted) {
312+
313+
if (do_assert) {
367314
ep->irq_pending |= BIT(intx);
368-
msg_code = ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTA + intx;
315+
rockchip_pcie_write(rockchip,
316+
PCIE_CLIENT_INT_IN_ASSERT |
317+
PCIE_CLIENT_INT_PEND_ST_PEND,
318+
PCIE_CLIENT_LEGACY_INT_CTRL);
369319
} else {
370320
ep->irq_pending &= ~BIT(intx);
371-
msg_code = ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTA + intx;
321+
rockchip_pcie_write(rockchip,
322+
PCIE_CLIENT_INT_IN_DEASSERT |
323+
PCIE_CLIENT_INT_PEND_ST_NORMAL,
324+
PCIE_CLIENT_LEGACY_INT_CTRL);
372325
}
373-
374-
status = rockchip_pcie_read(rockchip,
375-
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
376-
ROCKCHIP_PCIE_EP_CMD_STATUS);
377-
status &= ROCKCHIP_PCIE_EP_CMD_STATUS_IS;
378-
379-
if ((status != 0) ^ (ep->irq_pending != 0)) {
380-
status ^= ROCKCHIP_PCIE_EP_CMD_STATUS_IS;
381-
rockchip_pcie_write(rockchip, status,
382-
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
383-
ROCKCHIP_PCIE_EP_CMD_STATUS);
384-
}
385-
386-
offset =
387-
ROCKCHIP_PCIE_MSG_ROUTING(ROCKCHIP_PCIE_MSG_ROUTING_LOCAL_INTX) |
388-
ROCKCHIP_PCIE_MSG_CODE(msg_code) | ROCKCHIP_PCIE_MSG_NO_DATA;
389-
writel(0, ep->irq_cpu_addr + offset);
390326
}
391327

392328
static int rockchip_pcie_ep_send_legacy_irq(struct rockchip_pcie_ep *ep, u8 fn,
@@ -416,9 +352,10 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
416352
u8 interrupt_num)
417353
{
418354
struct rockchip_pcie *rockchip = &ep->rockchip;
419-
u16 flags, mme, data, data_mask;
355+
u32 flags, mme, data, data_mask;
420356
u8 msi_count;
421-
u64 pci_addr, pci_addr_mask = 0xff;
357+
u64 pci_addr;
358+
u32 r;
422359

423360
/* Check MSI enable bit */
424361
flags = rockchip_pcie_read(&ep->rockchip,
@@ -452,21 +389,20 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
452389
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
453390
ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
454391
PCI_MSI_ADDRESS_LO);
455-
pci_addr &= GENMASK_ULL(63, 2);
456392

457393
/* Set the outbound region if needed. */
458-
if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
394+
if (unlikely(ep->irq_pci_addr != (pci_addr & PCIE_ADDR_MASK) ||
459395
ep->irq_pci_fn != fn)) {
460-
rockchip_pcie_prog_ep_ob_atu(rockchip, fn, ep->max_regions - 1,
461-
AXI_WRAPPER_MEM_WRITE,
396+
r = rockchip_ob_region(ep->irq_phys_addr);
397+
rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r,
462398
ep->irq_phys_addr,
463-
pci_addr & ~pci_addr_mask,
464-
pci_addr_mask + 1);
465-
ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
399+
pci_addr & PCIE_ADDR_MASK,
400+
~PCIE_ADDR_MASK + 1);
401+
ep->irq_pci_addr = (pci_addr & PCIE_ADDR_MASK);
466402
ep->irq_pci_fn = fn;
467403
}
468404

469-
writew(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
405+
writew(data, ep->irq_cpu_addr + (pci_addr & ~PCIE_ADDR_MASK));
470406
return 0;
471407
}
472408

@@ -506,6 +442,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features = {
506442
.linkup_notifier = false,
507443
.msi_capable = true,
508444
.msix_capable = false,
445+
.align = 256,
509446
};
510447

511448
static const struct pci_epc_features*
@@ -547,6 +484,8 @@ static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,
547484
if (err < 0 || ep->max_regions > MAX_REGION_LIMIT)
548485
ep->max_regions = MAX_REGION_LIMIT;
549486

487+
ep->ob_region_map = 0;
488+
550489
err = of_property_read_u8(dev->of_node, "max-functions",
551490
&ep->epc->max_functions);
552491
if (err < 0)
@@ -567,7 +506,9 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
567506
struct rockchip_pcie *rockchip;
568507
struct pci_epc *epc;
569508
size_t max_regions;
570-
int err;
509+
struct pci_epc_mem_window *windows = NULL;
510+
int err, i;
511+
u32 cfg_msi, cfg_msix_cp;
571512

572513
ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
573514
if (!ep)
@@ -614,15 +555,27 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
614555
/* Only enable function 0 by default */
615556
rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG);
616557

617-
err = pci_epc_mem_init(epc, rockchip->mem_res->start,
618-
resource_size(rockchip->mem_res), PAGE_SIZE);
558+
windows = devm_kcalloc(dev, ep->max_regions,
559+
sizeof(struct pci_epc_mem_window), GFP_KERNEL);
560+
if (!windows) {
561+
err = -ENOMEM;
562+
goto err_uninit_port;
563+
}
564+
for (i = 0; i < ep->max_regions; i++) {
565+
windows[i].phys_base = rockchip->mem_res->start + (SZ_1M * i);
566+
windows[i].size = SZ_1M;
567+
windows[i].page_size = SZ_1M;
568+
}
569+
err = pci_epc_multi_mem_init(epc, windows, ep->max_regions);
570+
devm_kfree(dev, windows);
571+
619572
if (err < 0) {
620573
dev_err(dev, "failed to initialize the memory space\n");
621574
goto err_uninit_port;
622575
}
623576

624577
ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr,
625-
SZ_128K);
578+
SZ_1M);
626579
if (!ep->irq_cpu_addr) {
627580
dev_err(dev, "failed to reserve memory space for MSI\n");
628581
err = -ENOMEM;
@@ -631,6 +584,32 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
631584

632585
ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR;
633586

587+
/*
588+
* MSI-X is not supported but the controller still advertises the MSI-X
589+
* capability by default, which can lead to the Root Complex side
590+
* allocating MSI-X vectors which cannot be used. Avoid this by skipping
591+
* the MSI-X capability entry in the PCIe capabilities linked-list: get
592+
* the next pointer from the MSI-X entry and set that in the MSI
593+
* capability entry (which is the previous entry). This way the MSI-X
594+
* entry is skipped (left out of the linked-list) and not advertised.
595+
*/
596+
cfg_msi = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_BASE +
597+
ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
598+
599+
cfg_msi &= ~ROCKCHIP_PCIE_EP_MSI_CP1_MASK;
600+
601+
cfg_msix_cp = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_BASE +
602+
ROCKCHIP_PCIE_EP_MSIX_CAP_REG) &
603+
ROCKCHIP_PCIE_EP_MSIX_CAP_CP_MASK;
604+
605+
cfg_msi |= cfg_msix_cp;
606+
607+
rockchip_pcie_write(rockchip, cfg_msi,
608+
PCIE_EP_CONFIG_BASE + ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
609+
610+
rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE,
611+
PCIE_CLIENT_CONFIG);
612+
634613
return 0;
635614
err_epc_mem_exit:
636615
pci_epc_mem_exit(epc);

0 commit comments

Comments
 (0)