@@ -51,6 +51,7 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
51
51
struct pci_epf_bar * epf_bar )
52
52
{
53
53
struct cdns_pcie_ep * ep = epc_get_drvdata (epc );
54
+ struct cdns_pcie_epf * epf = & ep -> epf [fn ];
54
55
struct cdns_pcie * pcie = & ep -> pcie ;
55
56
dma_addr_t bar_phys = epf_bar -> phys_addr ;
56
57
enum pci_barno bar = epf_bar -> barno ;
@@ -111,13 +112,16 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
111
112
CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL (b , ctrl ));
112
113
cdns_pcie_writel (pcie , reg , cfg );
113
114
115
+ epf -> epf_bar [bar ] = epf_bar ;
116
+
114
117
return 0 ;
115
118
}
116
119
117
120
static void cdns_pcie_ep_clear_bar (struct pci_epc * epc , u8 fn ,
118
121
struct pci_epf_bar * epf_bar )
119
122
{
120
123
struct cdns_pcie_ep * ep = epc_get_drvdata (epc );
124
+ struct cdns_pcie_epf * epf = & ep -> epf [fn ];
121
125
struct cdns_pcie * pcie = & ep -> pcie ;
122
126
enum pci_barno bar = epf_bar -> barno ;
123
127
u32 reg , cfg , b , ctrl ;
@@ -139,6 +143,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
139
143
140
144
cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0 (fn , bar ), 0 );
141
145
cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1 (fn , bar ), 0 );
146
+
147
+ epf -> epf_bar [bar ] = NULL ;
142
148
}
143
149
144
150
static int cdns_pcie_ep_map_addr (struct pci_epc * epc , u8 fn , phys_addr_t addr ,
@@ -224,6 +230,50 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
224
230
return mme ;
225
231
}
226
232
233
+ static int cdns_pcie_ep_get_msix (struct pci_epc * epc , u8 func_no )
234
+ {
235
+ struct cdns_pcie_ep * ep = epc_get_drvdata (epc );
236
+ struct cdns_pcie * pcie = & ep -> pcie ;
237
+ u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET ;
238
+ u32 val , reg ;
239
+
240
+ reg = cap + PCI_MSIX_FLAGS ;
241
+ val = cdns_pcie_ep_fn_readw (pcie , func_no , reg );
242
+ if (!(val & PCI_MSIX_FLAGS_ENABLE ))
243
+ return - EINVAL ;
244
+
245
+ val &= PCI_MSIX_FLAGS_QSIZE ;
246
+
247
+ return val ;
248
+ }
249
+
250
+ static int cdns_pcie_ep_set_msix (struct pci_epc * epc , u8 fn , u16 interrupts ,
251
+ enum pci_barno bir , u32 offset )
252
+ {
253
+ struct cdns_pcie_ep * ep = epc_get_drvdata (epc );
254
+ struct cdns_pcie * pcie = & ep -> pcie ;
255
+ u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET ;
256
+ u32 val , reg ;
257
+
258
+ reg = cap + PCI_MSIX_FLAGS ;
259
+ val = cdns_pcie_ep_fn_readw (pcie , fn , reg );
260
+ val &= ~PCI_MSIX_FLAGS_QSIZE ;
261
+ val |= interrupts ;
262
+ cdns_pcie_ep_fn_writew (pcie , fn , reg , val );
263
+
264
+ /* Set MSIX BAR and offset */
265
+ reg = cap + PCI_MSIX_TABLE ;
266
+ val = offset | bir ;
267
+ cdns_pcie_ep_fn_writel (pcie , fn , reg , val );
268
+
269
+ /* Set PBA BAR and offset. BAR must match MSIX BAR */
270
+ reg = cap + PCI_MSIX_PBA ;
271
+ val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE )) | bir ;
272
+ cdns_pcie_ep_fn_writel (pcie , fn , reg , val );
273
+
274
+ return 0 ;
275
+ }
276
+
227
277
static void cdns_pcie_ep_assert_intx (struct cdns_pcie_ep * ep , u8 fn ,
228
278
u8 intx , bool is_asserted )
229
279
{
@@ -333,6 +383,51 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
333
383
return 0 ;
334
384
}
335
385
386
+ static int cdns_pcie_ep_send_msix_irq (struct cdns_pcie_ep * ep , u8 fn ,
387
+ u16 interrupt_num )
388
+ {
389
+ u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET ;
390
+ u32 tbl_offset , msg_data , reg ;
391
+ struct cdns_pcie * pcie = & ep -> pcie ;
392
+ struct pci_epf_msix_tbl * msix_tbl ;
393
+ struct cdns_pcie_epf * epf ;
394
+ u64 pci_addr_mask = 0xff ;
395
+ u64 msg_addr ;
396
+ u16 flags ;
397
+ u8 bir ;
398
+
399
+ /* Check whether the MSI-X feature has been enabled by the PCI host. */
400
+ flags = cdns_pcie_ep_fn_readw (pcie , fn , cap + PCI_MSIX_FLAGS );
401
+ if (!(flags & PCI_MSIX_FLAGS_ENABLE ))
402
+ return - EINVAL ;
403
+
404
+ reg = cap + PCI_MSIX_TABLE ;
405
+ tbl_offset = cdns_pcie_ep_fn_readl (pcie , fn , reg );
406
+ bir = tbl_offset & PCI_MSIX_TABLE_BIR ;
407
+ tbl_offset &= PCI_MSIX_TABLE_OFFSET ;
408
+
409
+ epf = & ep -> epf [fn ];
410
+ msix_tbl = epf -> epf_bar [bir ]-> addr + tbl_offset ;
411
+ msg_addr = msix_tbl [(interrupt_num - 1 )].msg_addr ;
412
+ msg_data = msix_tbl [(interrupt_num - 1 )].msg_data ;
413
+
414
+ /* Set the outbound region if needed. */
415
+ if (ep -> irq_pci_addr != (msg_addr & ~pci_addr_mask ) ||
416
+ ep -> irq_pci_fn != fn ) {
417
+ /* First region was reserved for IRQ writes. */
418
+ cdns_pcie_set_outbound_region (pcie , fn , 0 ,
419
+ false,
420
+ ep -> irq_phys_addr ,
421
+ msg_addr & ~pci_addr_mask ,
422
+ pci_addr_mask + 1 );
423
+ ep -> irq_pci_addr = (msg_addr & ~pci_addr_mask );
424
+ ep -> irq_pci_fn = fn ;
425
+ }
426
+ writel (msg_data , ep -> irq_cpu_addr + (msg_addr & pci_addr_mask ));
427
+
428
+ return 0 ;
429
+ }
430
+
336
431
static int cdns_pcie_ep_raise_irq (struct pci_epc * epc , u8 fn ,
337
432
enum pci_epc_irq_type type ,
338
433
u16 interrupt_num )
@@ -346,6 +441,9 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
346
441
case PCI_EPC_IRQ_MSI :
347
442
return cdns_pcie_ep_send_msi_irq (ep , fn , interrupt_num );
348
443
444
+ case PCI_EPC_IRQ_MSIX :
445
+ return cdns_pcie_ep_send_msix_irq (ep , fn , interrupt_num );
446
+
349
447
default :
350
448
break ;
351
449
}
@@ -383,7 +481,7 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
383
481
static const struct pci_epc_features cdns_pcie_epc_features = {
384
482
.linkup_notifier = false,
385
483
.msi_capable = true,
386
- .msix_capable = false ,
484
+ .msix_capable = true ,
387
485
};
388
486
389
487
static const struct pci_epc_features *
@@ -400,6 +498,8 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = {
400
498
.unmap_addr = cdns_pcie_ep_unmap_addr ,
401
499
.set_msi = cdns_pcie_ep_set_msi ,
402
500
.get_msi = cdns_pcie_ep_get_msi ,
501
+ .set_msix = cdns_pcie_ep_set_msix ,
502
+ .get_msix = cdns_pcie_ep_get_msix ,
403
503
.raise_irq = cdns_pcie_ep_raise_irq ,
404
504
.start = cdns_pcie_ep_start ,
405
505
.get_features = cdns_pcie_ep_get_features ,
@@ -458,6 +558,11 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
458
558
if (of_property_read_u8 (np , "max-functions" , & epc -> max_functions ) < 0 )
459
559
epc -> max_functions = 1 ;
460
560
561
+ ep -> epf = devm_kcalloc (dev , epc -> max_functions , sizeof (* ep -> epf ),
562
+ GFP_KERNEL );
563
+ if (!ep -> epf )
564
+ return - ENOMEM ;
565
+
461
566
ret = pci_epc_mem_init (epc , pcie -> mem_res -> start ,
462
567
resource_size (pcie -> mem_res ), PAGE_SIZE );
463
568
if (ret < 0 ) {
0 commit comments