Skip to content

Commit dc73ed0

Browse files
rwk-gitLorenzo Pieralisi
authored andcommitted
PCI: rockchip: Fix window mapping and address translation for endpoint
The RK3399 PCI endpoint core has 33 windows for PCIe space, now in the driver up to 32 fixed size (1M) windows are used and pages are allocated and mapped accordingly. The driver first used a single window and allocated space inside which caused translation issues (between CPU space and PCI space) because a window can only have a single translation at a given time, which if multiple pages are allocated inside will cause conflicts. Now each window is a single region of 1M which will always guarantee that the translation is not in conflict. Set the translation register addresses for physical function. As documented in the technical reference manual (TRM) section 17.5.5 "PCIe Address Translation" and section 17.6.8 "Address Translation Registers Description" Link: https://lore.kernel.org/r/20230418074700.1083505-9-rick.wertenbroek@gmail.com Fixes: cf590b0 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Tested-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Rick Wertenbroek <rick.wertenbroek@gmail.com> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Cc: stable@vger.kernel.org
1 parent 166e89d commit dc73ed0

File tree

2 files changed

+75
-88
lines changed

2 files changed

+75
-88
lines changed

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

Lines changed: 55 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -64,52 +64,29 @@ static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip,
6464
}
6565

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

75-
/* The minimal region size is 1MB */
7673
if (num_pass_bits < 8)
7774
num_pass_bits = 8;
7875

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

11592
static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
@@ -248,26 +225,20 @@ static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
248225
ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
249226
}
250227

228+
static inline u32 rockchip_ob_region(phys_addr_t addr)
229+
{
230+
return (addr >> ilog2(SZ_1M)) & 0x1f;
231+
}
232+
251233
static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
252234
phys_addr_t addr, u64 pci_addr,
253235
size_t size)
254236
{
255237
struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
256238
struct rockchip_pcie *pcie = &ep->rockchip;
257-
u32 r;
239+
u32 r = rockchip_ob_region(addr);
258240

259-
r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG);
260-
/*
261-
* Region 0 is reserved for configuration space and shouldn't
262-
* be used elsewhere per TRM, so leave it out.
263-
*/
264-
if (r >= ep->max_regions - 1) {
265-
dev_err(&epc->dev, "no free outbound region\n");
266-
return -EINVAL;
267-
}
268-
269-
rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, AXI_WRAPPER_MEM_WRITE, addr,
270-
pci_addr, size);
241+
rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, addr, pci_addr, size);
271242

272243
set_bit(r, &ep->ob_region_map);
273244
ep->ob_addr[r] = addr;
@@ -282,15 +253,11 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
282253
struct rockchip_pcie *rockchip = &ep->rockchip;
283254
u32 r;
284255

285-
for (r = 0; r < ep->max_regions - 1; r++)
256+
for (r = 0; r < ep->max_regions; r++)
286257
if (ep->ob_addr[r] == addr)
287258
break;
288259

289-
/*
290-
* Region 0 is reserved for configuration space and shouldn't
291-
* be used elsewhere per TRM, so leave it out.
292-
*/
293-
if (r == ep->max_regions - 1)
260+
if (r == ep->max_regions)
294261
return;
295262

296263
rockchip_pcie_clear_ep_ob_atu(rockchip, r);
@@ -387,7 +354,8 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
387354
struct rockchip_pcie *rockchip = &ep->rockchip;
388355
u16 flags, mme, data, data_mask;
389356
u8 msi_count;
390-
u64 pci_addr, pci_addr_mask = 0xff;
357+
u64 pci_addr;
358+
u32 r;
391359

392360
/* Check MSI enable bit */
393361
flags = rockchip_pcie_read(&ep->rockchip,
@@ -421,21 +389,20 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
421389
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
422390
ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
423391
PCI_MSI_ADDRESS_LO);
424-
pci_addr &= GENMASK_ULL(63, 2);
425392

426393
/* Set the outbound region if needed. */
427-
if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
394+
if (unlikely(ep->irq_pci_addr != (pci_addr & PCIE_ADDR_MASK) ||
428395
ep->irq_pci_fn != fn)) {
429-
rockchip_pcie_prog_ep_ob_atu(rockchip, fn, ep->max_regions - 1,
430-
AXI_WRAPPER_MEM_WRITE,
396+
r = rockchip_ob_region(ep->irq_phys_addr);
397+
rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r,
431398
ep->irq_phys_addr,
432-
pci_addr & ~pci_addr_mask,
433-
pci_addr_mask + 1);
434-
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);
435402
ep->irq_pci_fn = fn;
436403
}
437404

438-
writew(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
405+
writew(data, ep->irq_cpu_addr + (pci_addr & ~PCIE_ADDR_MASK));
439406
return 0;
440407
}
441408

@@ -516,6 +483,8 @@ static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,
516483
if (err < 0 || ep->max_regions > MAX_REGION_LIMIT)
517484
ep->max_regions = MAX_REGION_LIMIT;
518485

486+
ep->ob_region_map = 0;
487+
519488
err = of_property_read_u8(dev->of_node, "max-functions",
520489
&ep->epc->max_functions);
521490
if (err < 0)
@@ -536,7 +505,8 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
536505
struct rockchip_pcie *rockchip;
537506
struct pci_epc *epc;
538507
size_t max_regions;
539-
int err;
508+
struct pci_epc_mem_window *windows = NULL;
509+
int err, i;
540510

541511
ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
542512
if (!ep)
@@ -583,15 +553,27 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
583553
/* Only enable function 0 by default */
584554
rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG);
585555

586-
err = pci_epc_mem_init(epc, rockchip->mem_res->start,
587-
resource_size(rockchip->mem_res), PAGE_SIZE);
556+
windows = devm_kcalloc(dev, ep->max_regions,
557+
sizeof(struct pci_epc_mem_window), GFP_KERNEL);
558+
if (!windows) {
559+
err = -ENOMEM;
560+
goto err_uninit_port;
561+
}
562+
for (i = 0; i < ep->max_regions; i++) {
563+
windows[i].phys_base = rockchip->mem_res->start + (SZ_1M * i);
564+
windows[i].size = SZ_1M;
565+
windows[i].page_size = SZ_1M;
566+
}
567+
err = pci_epc_multi_mem_init(epc, windows, ep->max_regions);
568+
devm_kfree(dev, windows);
569+
588570
if (err < 0) {
589571
dev_err(dev, "failed to initialize the memory space\n");
590572
goto err_uninit_port;
591573
}
592574

593575
ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr,
594-
SZ_128K);
576+
SZ_1M);
595577
if (!ep->irq_cpu_addr) {
596578
dev_err(dev, "failed to reserve memory space for MSI\n");
597579
err = -ENOMEM;

drivers/pci/controller/pcie-rockchip.h

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139

140140
#define PCIE_RC_RP_ATS_BASE 0x400000
141141
#define PCIE_RC_CONFIG_NORMAL_BASE 0x800000
142+
#define PCIE_EP_PF_CONFIG_REGS_BASE 0x800000
142143
#define PCIE_RC_CONFIG_BASE 0xa00000
143144
#define PCIE_EP_CONFIG_BASE 0xa00000
144145
#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00)
@@ -157,18 +158,19 @@
157158
#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274)
158159
#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20)
159160

161+
#define PCIE_ADDR_MASK 0xffffff00
160162
#define PCIE_CORE_AXI_CONF_BASE 0xc00000
161163
#define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0)
162164
#define PCIE_CORE_OB_REGION_ADDR0_NUM_BITS 0x3f
163-
#define PCIE_CORE_OB_REGION_ADDR0_LO_ADDR 0xffffff00
165+
#define PCIE_CORE_OB_REGION_ADDR0_LO_ADDR PCIE_ADDR_MASK
164166
#define PCIE_CORE_OB_REGION_ADDR1 (PCIE_CORE_AXI_CONF_BASE + 0x4)
165167
#define PCIE_CORE_OB_REGION_DESC0 (PCIE_CORE_AXI_CONF_BASE + 0x8)
166168
#define PCIE_CORE_OB_REGION_DESC1 (PCIE_CORE_AXI_CONF_BASE + 0xc)
167169

168170
#define PCIE_CORE_AXI_INBOUND_BASE 0xc00800
169171
#define PCIE_RP_IB_ADDR0 (PCIE_CORE_AXI_INBOUND_BASE + 0x0)
170172
#define PCIE_CORE_IB_REGION_ADDR0_NUM_BITS 0x3f
171-
#define PCIE_CORE_IB_REGION_ADDR0_LO_ADDR 0xffffff00
173+
#define PCIE_CORE_IB_REGION_ADDR0_LO_ADDR PCIE_ADDR_MASK
172174
#define PCIE_RP_IB_ADDR1 (PCIE_CORE_AXI_INBOUND_BASE + 0x4)
173175

174176
/* Size of one AXI Region (not Region 0) */
@@ -232,34 +234,37 @@
232234
#define ROCKCHIP_PCIE_EP_MSI_CTRL_ME BIT(16)
233235
#define ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP BIT(24)
234236
#define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR 0x1
235-
#define ROCKCHIP_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12))
237+
#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR 0x3
238+
#define ROCKCHIP_PCIE_EP_FUNC_BASE(fn) \
239+
(PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12)))
240+
#define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE(fn) \
241+
(PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12)))
236242
#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
237-
(PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
243+
(PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008)
238244
#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
239-
(PCIE_RC_RP_ATS_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
240-
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
241-
(PCIE_RC_RP_ATS_BASE + 0x0000 + ((r) & 0x1f) * 0x0020)
245+
(PCIE_CORE_AXI_CONF_BASE + 0x082c + (fn) * 0x0040 + (bar) * 0x0008)
242246
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK GENMASK(19, 12)
243247
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
244248
(((devfn) << 12) & \
245249
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
246250
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK GENMASK(27, 20)
247251
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
248252
(((bus) << 20) & ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
253+
#define PCIE_RC_EP_ATR_OB_REGIONS_1_32 (PCIE_CORE_AXI_CONF_BASE + 0x0020)
254+
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
255+
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0000 + ((r) & 0x1f) * 0x0020)
249256
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
250-
(PCIE_RC_RP_ATS_BASE + 0x0004 + ((r) & 0x1f) * 0x0020)
257+
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0004 + ((r) & 0x1f) * 0x0020)
251258
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID BIT(23)
252259
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK GENMASK(31, 24)
253260
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
254261
(((devfn) << 24) & ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
255262
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r) \
256-
(PCIE_RC_RP_ATS_BASE + 0x0008 + ((r) & 0x1f) * 0x0020)
257-
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r) \
258-
(PCIE_RC_RP_ATS_BASE + 0x000c + ((r) & 0x1f) * 0x0020)
259-
#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
260-
(PCIE_RC_RP_ATS_BASE + 0x0018 + ((r) & 0x1f) * 0x0020)
261-
#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
262-
(PCIE_RC_RP_ATS_BASE + 0x001c + ((r) & 0x1f) * 0x0020)
263+
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0008 + ((r) & 0x1f) * 0x0020)
264+
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r) \
265+
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x000c + ((r) & 0x1f) * 0x0020)
266+
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC2(r) \
267+
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0010 + ((r) & 0x1f) * 0x0020)
263268

264269
#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG0(fn) \
265270
(PCIE_CORE_CTRL_MGMT_BASE + 0x0240 + (fn) * 0x0008)

0 commit comments

Comments
 (0)