@@ -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
7066static 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
12592static 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+
259233static 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
347306static 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
392328static 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
511448static 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 ;
635614err_epc_mem_exit :
636615 pci_epc_mem_exit (epc );
0 commit comments