2
2
/* Copyright (C) 2009 - 2019 Broadcom */
3
3
4
4
#include <linux/bitfield.h>
5
+ #include <linux/bitops.h>
5
6
#include <linux/clk.h>
6
7
#include <linux/compiler.h>
7
8
#include <linux/delay.h>
8
9
#include <linux/init.h>
9
10
#include <linux/interrupt.h>
10
11
#include <linux/io.h>
11
12
#include <linux/ioport.h>
13
+ #include <linux/irqchip/chained_irq.h>
12
14
#include <linux/irqdomain.h>
13
15
#include <linux/kernel.h>
14
16
#include <linux/list.h>
15
17
#include <linux/log2.h>
16
18
#include <linux/module.h>
19
+ #include <linux/msi.h>
17
20
#include <linux/of_address.h>
18
21
#include <linux/of_irq.h>
19
22
#include <linux/of_pci.h>
67
70
#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
68
71
#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f
69
72
73
+ #define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044
74
+ #define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048
75
+
76
+ #define PCIE_MISC_MSI_DATA_CONFIG 0x404c
77
+ #define PCIE_MISC_MSI_DATA_CONFIG_VAL 0xffe06540
78
+
70
79
#define PCIE_MISC_PCIE_CTRL 0x4064
71
80
#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1
72
81
114
123
115
124
/* PCIe parameters */
116
125
#define BRCM_NUM_PCIE_OUT_WINS 0x4
126
+ #define BRCM_INT_PCI_MSI_NR 32
127
+
128
+ /* MSI target adresses */
129
+ #define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL
130
+ #define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL
117
131
118
132
/* MDIO registers */
119
133
#define MDIO_PORT0 0x0
135
149
#define SSC_STATUS_SSC_MASK 0x400
136
150
#define SSC_STATUS_PLL_LOCK_MASK 0x800
137
151
152
+ struct brcm_msi {
153
+ struct device * dev ;
154
+ void __iomem * base ;
155
+ struct device_node * np ;
156
+ struct irq_domain * msi_domain ;
157
+ struct irq_domain * inner_domain ;
158
+ struct mutex lock ; /* guards the alloc/free operations */
159
+ u64 target_addr ;
160
+ int irq ;
161
+ /* used indicates which MSI interrupts have been alloc'd */
162
+ unsigned long used ;
163
+ };
164
+
138
165
/* Internal PCIe Host Controller Information.*/
139
166
struct brcm_pcie {
140
167
struct device * dev ;
@@ -144,6 +171,8 @@ struct brcm_pcie {
144
171
struct device_node * np ;
145
172
bool ssc ;
146
173
int gen ;
174
+ u64 msi_target_addr ;
175
+ struct brcm_msi * msi ;
147
176
};
148
177
149
178
/*
@@ -309,6 +338,215 @@ static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
309
338
writel (tmp , pcie -> base + PCIE_MEM_WIN0_LIMIT_HI (win ));
310
339
}
311
340
341
+ static struct irq_chip brcm_msi_irq_chip = {
342
+ .name = "BRCM STB PCIe MSI" ,
343
+ .irq_ack = irq_chip_ack_parent ,
344
+ .irq_mask = pci_msi_mask_irq ,
345
+ .irq_unmask = pci_msi_unmask_irq ,
346
+ };
347
+
348
+ static struct msi_domain_info brcm_msi_domain_info = {
349
+ /* Multi MSI is supported by the controller, but not by this driver */
350
+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS ),
351
+ .chip = & brcm_msi_irq_chip ,
352
+ };
353
+
354
+ static void brcm_pcie_msi_isr (struct irq_desc * desc )
355
+ {
356
+ struct irq_chip * chip = irq_desc_get_chip (desc );
357
+ unsigned long status , virq ;
358
+ struct brcm_msi * msi ;
359
+ struct device * dev ;
360
+ u32 bit ;
361
+
362
+ chained_irq_enter (chip , desc );
363
+ msi = irq_desc_get_handler_data (desc );
364
+ dev = msi -> dev ;
365
+
366
+ status = readl (msi -> base + PCIE_MSI_INTR2_STATUS );
367
+ for_each_set_bit (bit , & status , BRCM_INT_PCI_MSI_NR ) {
368
+ virq = irq_find_mapping (msi -> inner_domain , bit );
369
+ if (virq )
370
+ generic_handle_irq (virq );
371
+ else
372
+ dev_dbg (dev , "unexpected MSI\n" );
373
+ }
374
+
375
+ chained_irq_exit (chip , desc );
376
+ }
377
+
378
+ static void brcm_msi_compose_msi_msg (struct irq_data * data , struct msi_msg * msg )
379
+ {
380
+ struct brcm_msi * msi = irq_data_get_irq_chip_data (data );
381
+
382
+ msg -> address_lo = lower_32_bits (msi -> target_addr );
383
+ msg -> address_hi = upper_32_bits (msi -> target_addr );
384
+ msg -> data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL ) | data -> hwirq ;
385
+ }
386
+
387
+ static int brcm_msi_set_affinity (struct irq_data * irq_data ,
388
+ const struct cpumask * mask , bool force )
389
+ {
390
+ return - EINVAL ;
391
+ }
392
+
393
+ static void brcm_msi_ack_irq (struct irq_data * data )
394
+ {
395
+ struct brcm_msi * msi = irq_data_get_irq_chip_data (data );
396
+
397
+ writel (1 << data -> hwirq , msi -> base + PCIE_MSI_INTR2_CLR );
398
+ }
399
+
400
+
401
+ static struct irq_chip brcm_msi_bottom_irq_chip = {
402
+ .name = "BRCM STB MSI" ,
403
+ .irq_compose_msi_msg = brcm_msi_compose_msi_msg ,
404
+ .irq_set_affinity = brcm_msi_set_affinity ,
405
+ .irq_ack = brcm_msi_ack_irq ,
406
+ };
407
+
408
+ static int brcm_msi_alloc (struct brcm_msi * msi )
409
+ {
410
+ int hwirq ;
411
+
412
+ mutex_lock (& msi -> lock );
413
+ hwirq = bitmap_find_free_region (& msi -> used , BRCM_INT_PCI_MSI_NR , 0 );
414
+ mutex_unlock (& msi -> lock );
415
+
416
+ return hwirq ;
417
+ }
418
+
419
+ static void brcm_msi_free (struct brcm_msi * msi , unsigned long hwirq )
420
+ {
421
+ mutex_lock (& msi -> lock );
422
+ bitmap_release_region (& msi -> used , hwirq , 0 );
423
+ mutex_unlock (& msi -> lock );
424
+ }
425
+
426
+ static int brcm_irq_domain_alloc (struct irq_domain * domain , unsigned int virq ,
427
+ unsigned int nr_irqs , void * args )
428
+ {
429
+ struct brcm_msi * msi = domain -> host_data ;
430
+ int hwirq ;
431
+
432
+ hwirq = brcm_msi_alloc (msi );
433
+
434
+ if (hwirq < 0 )
435
+ return hwirq ;
436
+
437
+ irq_domain_set_info (domain , virq , (irq_hw_number_t )hwirq ,
438
+ & brcm_msi_bottom_irq_chip , domain -> host_data ,
439
+ handle_edge_irq , NULL , NULL );
440
+ return 0 ;
441
+ }
442
+
443
+ static void brcm_irq_domain_free (struct irq_domain * domain ,
444
+ unsigned int virq , unsigned int nr_irqs )
445
+ {
446
+ struct irq_data * d = irq_domain_get_irq_data (domain , virq );
447
+ struct brcm_msi * msi = irq_data_get_irq_chip_data (d );
448
+
449
+ brcm_msi_free (msi , d -> hwirq );
450
+ }
451
+
452
+ static const struct irq_domain_ops msi_domain_ops = {
453
+ .alloc = brcm_irq_domain_alloc ,
454
+ .free = brcm_irq_domain_free ,
455
+ };
456
+
457
+ static int brcm_allocate_domains (struct brcm_msi * msi )
458
+ {
459
+ struct fwnode_handle * fwnode = of_node_to_fwnode (msi -> np );
460
+ struct device * dev = msi -> dev ;
461
+
462
+ msi -> inner_domain = irq_domain_add_linear (NULL , BRCM_INT_PCI_MSI_NR ,
463
+ & msi_domain_ops , msi );
464
+ if (!msi -> inner_domain ) {
465
+ dev_err (dev , "failed to create IRQ domain\n" );
466
+ return - ENOMEM ;
467
+ }
468
+
469
+ msi -> msi_domain = pci_msi_create_irq_domain (fwnode ,
470
+ & brcm_msi_domain_info ,
471
+ msi -> inner_domain );
472
+ if (!msi -> msi_domain ) {
473
+ dev_err (dev , "failed to create MSI domain\n" );
474
+ irq_domain_remove (msi -> inner_domain );
475
+ return - ENOMEM ;
476
+ }
477
+
478
+ return 0 ;
479
+ }
480
+
481
+ static void brcm_free_domains (struct brcm_msi * msi )
482
+ {
483
+ irq_domain_remove (msi -> msi_domain );
484
+ irq_domain_remove (msi -> inner_domain );
485
+ }
486
+
487
+ static void brcm_msi_remove (struct brcm_pcie * pcie )
488
+ {
489
+ struct brcm_msi * msi = pcie -> msi ;
490
+
491
+ if (!msi )
492
+ return ;
493
+ irq_set_chained_handler (msi -> irq , NULL );
494
+ irq_set_handler_data (msi -> irq , NULL );
495
+ brcm_free_domains (msi );
496
+ }
497
+
498
+ static void brcm_msi_set_regs (struct brcm_msi * msi )
499
+ {
500
+ writel (0xffffffff , msi -> base + PCIE_MSI_INTR2_MASK_CLR );
501
+
502
+ /*
503
+ * The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI
504
+ * enable, which we set to 1.
505
+ */
506
+ writel (lower_32_bits (msi -> target_addr ) | 0x1 ,
507
+ msi -> base + PCIE_MISC_MSI_BAR_CONFIG_LO );
508
+ writel (upper_32_bits (msi -> target_addr ),
509
+ msi -> base + PCIE_MISC_MSI_BAR_CONFIG_HI );
510
+
511
+ writel (PCIE_MISC_MSI_DATA_CONFIG_VAL ,
512
+ msi -> base + PCIE_MISC_MSI_DATA_CONFIG );
513
+ }
514
+
515
+ static int brcm_pcie_enable_msi (struct brcm_pcie * pcie )
516
+ {
517
+ struct brcm_msi * msi ;
518
+ int irq , ret ;
519
+ struct device * dev = pcie -> dev ;
520
+
521
+ irq = irq_of_parse_and_map (dev -> of_node , 1 );
522
+ if (irq <= 0 ) {
523
+ dev_err (dev , "cannot map MSI interrupt\n" );
524
+ return - ENODEV ;
525
+ }
526
+
527
+ msi = devm_kzalloc (dev , sizeof (struct brcm_msi ), GFP_KERNEL );
528
+ if (!msi )
529
+ return - ENOMEM ;
530
+
531
+ mutex_init (& msi -> lock );
532
+ msi -> dev = dev ;
533
+ msi -> base = pcie -> base ;
534
+ msi -> np = pcie -> np ;
535
+ msi -> target_addr = pcie -> msi_target_addr ;
536
+ msi -> irq = irq ;
537
+
538
+ ret = brcm_allocate_domains (msi );
539
+ if (ret )
540
+ return ret ;
541
+
542
+ irq_set_chained_handler_and_data (msi -> irq , brcm_pcie_msi_isr , msi );
543
+
544
+ brcm_msi_set_regs (msi );
545
+ pcie -> msi = msi ;
546
+
547
+ return 0 ;
548
+ }
549
+
312
550
/* The controller is capable of serving in both RC and EP roles */
313
551
static bool brcm_pcie_rc_mode (struct brcm_pcie * pcie )
314
552
{
@@ -497,6 +735,18 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
497
735
PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK );
498
736
writel (tmp , base + PCIE_MISC_MISC_CTRL );
499
737
738
+ /*
739
+ * We ideally want the MSI target address to be located in the 32bit
740
+ * addressable memory area. Some devices might depend on it. This is
741
+ * possible either when the inbound window is located above the lower
742
+ * 4GB or when the inbound area is smaller than 4GB (taking into
743
+ * account the rounding-up we're forced to perform).
744
+ */
745
+ if (rc_bar2_offset >= SZ_4G || (rc_bar2_size + rc_bar2_offset ) < SZ_4G )
746
+ pcie -> msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB ;
747
+ else
748
+ pcie -> msi_target_addr = BRCM_MSI_TARGET_ADDR_GT_4GB ;
749
+
500
750
/* disable the PCIe->GISB memory window (RC_BAR1) */
501
751
tmp = readl (base + PCIE_MISC_RC_BAR1_CONFIG_LO );
502
752
tmp &= ~PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK ;
@@ -646,6 +896,7 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
646
896
647
897
static void __brcm_pcie_remove (struct brcm_pcie * pcie )
648
898
{
899
+ brcm_msi_remove (pcie );
649
900
brcm_pcie_turn_off (pcie );
650
901
clk_disable_unprepare (pcie -> clk );
651
902
clk_put (pcie -> clk );
@@ -664,7 +915,7 @@ static int brcm_pcie_remove(struct platform_device *pdev)
664
915
665
916
static int brcm_pcie_probe (struct platform_device * pdev )
666
917
{
667
- struct device_node * np = pdev -> dev .of_node ;
918
+ struct device_node * np = pdev -> dev .of_node , * msi_np ;
668
919
struct pci_host_bridge * bridge ;
669
920
struct brcm_pcie * pcie ;
670
921
struct pci_bus * child ;
@@ -708,6 +959,15 @@ static int brcm_pcie_probe(struct platform_device *pdev)
708
959
if (ret )
709
960
goto fail ;
710
961
962
+ msi_np = of_parse_phandle (pcie -> np , "msi-parent" , 0 );
963
+ if (pci_msi_enabled () && msi_np == pcie -> np ) {
964
+ ret = brcm_pcie_enable_msi (pcie );
965
+ if (ret ) {
966
+ dev_err (pcie -> dev , "probe of internal MSI failed" );
967
+ goto fail ;
968
+ }
969
+ }
970
+
711
971
bridge -> dev .parent = & pdev -> dev ;
712
972
bridge -> busnr = 0 ;
713
973
bridge -> ops = & brcm_pcie_ops ;
0 commit comments