Skip to content

Commit 0ef2830

Browse files
committed
Merge branch 'remotes/lorenzo/pci/brcmstb'
- Enable Multi-MSI (Jim Quinlan) - Wait for 100ms after PERST# deassert for power and clocks to stabilize (Jim Quinlan) - Use readl_poll_timeout_atomic() instead of hand-rolled timeout loop (Jim Quinlan) - Drop needless "inline" annotations (Jim Quinlan) - Set RCB_MPS mode bit so data for reads up to MPS are returned in a single completion (Jim Quinlan) * remotes/lorenzo/pci/brcmstb: PCI: brcmstb: Set RCB_{MPS,64B}_MODE bits PCI: brcmstb: Drop needless 'inline' annotations PCI: brcmstb: Replace status loops with read_poll_timeout_atomic() PCI: brcmstb: Wait for 100ms following PERST# deassert PCI: brcmstb: Enable Multi-MSI
2 parents e6936c8 + 602fb86 commit 0ef2830

File tree

1 file changed

+48
-37
lines changed

1 file changed

+48
-37
lines changed

drivers/pci/controller/pcie-brcmstb.c

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/init.h>
1010
#include <linux/interrupt.h>
1111
#include <linux/io.h>
12+
#include <linux/iopoll.h>
1213
#include <linux/ioport.h>
1314
#include <linux/irqchip/chained_irq.h>
1415
#include <linux/irqdomain.h>
@@ -52,6 +53,8 @@
5253
#define PCIE_RC_DL_MDIO_RD_DATA 0x1108
5354

5455
#define PCIE_MISC_MISC_CTRL 0x4008
56+
#define PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE_MASK 0x80
57+
#define PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE_MASK 0x400
5558
#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000
5659
#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000
5760
#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
@@ -302,42 +305,34 @@ static u32 brcm_pcie_mdio_form_pkt(int port, int regad, int cmd)
302305
/* negative return value indicates error */
303306
static int brcm_pcie_mdio_read(void __iomem *base, u8 port, u8 regad, u32 *val)
304307
{
305-
int tries;
306308
u32 data;
309+
int err;
307310

308311
writel(brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_READ),
309312
base + PCIE_RC_DL_MDIO_ADDR);
310313
readl(base + PCIE_RC_DL_MDIO_ADDR);
311-
312-
data = readl(base + PCIE_RC_DL_MDIO_RD_DATA);
313-
for (tries = 0; !MDIO_RD_DONE(data) && tries < 10; tries++) {
314-
udelay(10);
315-
data = readl(base + PCIE_RC_DL_MDIO_RD_DATA);
316-
}
317-
314+
err = readl_poll_timeout_atomic(base + PCIE_RC_DL_MDIO_RD_DATA, data,
315+
MDIO_RD_DONE(data), 10, 100);
318316
*val = FIELD_GET(MDIO_DATA_MASK, data);
319-
return MDIO_RD_DONE(data) ? 0 : -EIO;
317+
318+
return err;
320319
}
321320

322321
/* negative return value indicates error */
323322
static int brcm_pcie_mdio_write(void __iomem *base, u8 port,
324323
u8 regad, u16 wrdata)
325324
{
326-
int tries;
327325
u32 data;
326+
int err;
328327

329328
writel(brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_WRITE),
330329
base + PCIE_RC_DL_MDIO_ADDR);
331330
readl(base + PCIE_RC_DL_MDIO_ADDR);
332331
writel(MDIO_DATA_DONE_MASK | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);
333332

334-
data = readl(base + PCIE_RC_DL_MDIO_WR_DATA);
335-
for (tries = 0; !MDIO_WT_DONE(data) && tries < 10; tries++) {
336-
udelay(10);
337-
data = readl(base + PCIE_RC_DL_MDIO_WR_DATA);
338-
}
339-
340-
return MDIO_WT_DONE(data) ? 0 : -EIO;
333+
err = readw_poll_timeout_atomic(base + PCIE_RC_DL_MDIO_WR_DATA, data,
334+
MDIO_WT_DONE(data), 10, 100);
335+
return err;
341336
}
342337

343338
/*
@@ -445,7 +440,8 @@ static struct irq_chip brcm_msi_irq_chip = {
445440

446441
static struct msi_domain_info brcm_msi_domain_info = {
447442
/* Multi MSI is supported by the controller, but not by this driver */
448-
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
443+
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
444+
MSI_FLAG_MULTI_PCI_MSI),
449445
.chip = &brcm_msi_irq_chip,
450446
};
451447

@@ -505,38 +501,41 @@ static struct irq_chip brcm_msi_bottom_irq_chip = {
505501
.irq_ack = brcm_msi_ack_irq,
506502
};
507503

508-
static int brcm_msi_alloc(struct brcm_msi *msi)
504+
static int brcm_msi_alloc(struct brcm_msi *msi, unsigned int nr_irqs)
509505
{
510506
int hwirq;
511507

512508
mutex_lock(&msi->lock);
513-
hwirq = bitmap_find_free_region(msi->used, msi->nr, 0);
509+
hwirq = bitmap_find_free_region(msi->used, msi->nr,
510+
order_base_2(nr_irqs));
514511
mutex_unlock(&msi->lock);
515512

516513
return hwirq;
517514
}
518515

519-
static void brcm_msi_free(struct brcm_msi *msi, unsigned long hwirq)
516+
static void brcm_msi_free(struct brcm_msi *msi, unsigned long hwirq,
517+
unsigned int nr_irqs)
520518
{
521519
mutex_lock(&msi->lock);
522-
bitmap_release_region(msi->used, hwirq, 0);
520+
bitmap_release_region(msi->used, hwirq, order_base_2(nr_irqs));
523521
mutex_unlock(&msi->lock);
524522
}
525523

526524
static int brcm_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
527525
unsigned int nr_irqs, void *args)
528526
{
529527
struct brcm_msi *msi = domain->host_data;
530-
int hwirq;
528+
int hwirq, i;
531529

532-
hwirq = brcm_msi_alloc(msi);
530+
hwirq = brcm_msi_alloc(msi, nr_irqs);
533531

534532
if (hwirq < 0)
535533
return hwirq;
536534

537-
irq_domain_set_info(domain, virq, (irq_hw_number_t)hwirq,
538-
&brcm_msi_bottom_irq_chip, domain->host_data,
539-
handle_edge_irq, NULL, NULL);
535+
for (i = 0; i < nr_irqs; i++)
536+
irq_domain_set_info(domain, virq + i, hwirq + i,
537+
&brcm_msi_bottom_irq_chip, domain->host_data,
538+
handle_edge_irq, NULL, NULL);
540539
return 0;
541540
}
542541

@@ -546,7 +545,7 @@ static void brcm_irq_domain_free(struct irq_domain *domain,
546545
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
547546
struct brcm_msi *msi = irq_data_get_irq_chip_data(d);
548547

549-
brcm_msi_free(msi, d->hwirq);
548+
brcm_msi_free(msi, d->hwirq, nr_irqs);
550549
}
551550

552551
static const struct irq_domain_ops msi_domain_ops = {
@@ -726,7 +725,7 @@ static void __iomem *brcm7425_pcie_map_bus(struct pci_bus *bus,
726725
return base + DATA_ADDR(pcie);
727726
}
728727

729-
static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val)
728+
static void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val)
730729
{
731730
u32 tmp, mask = RGR1_SW_INIT_1_INIT_GENERIC_MASK;
732731
u32 shift = RGR1_SW_INIT_1_INIT_GENERIC_SHIFT;
@@ -736,7 +735,7 @@ static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie,
736735
writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
737736
}
738737

739-
static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val)
738+
static void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val)
740739
{
741740
u32 tmp, mask = RGR1_SW_INIT_1_INIT_7278_MASK;
742741
u32 shift = RGR1_SW_INIT_1_INIT_7278_SHIFT;
@@ -746,7 +745,7 @@ static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32
746745
writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
747746
}
748747

749-
static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
748+
static void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
750749
{
751750
if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
752751
return;
@@ -757,7 +756,7 @@ static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
757756
reset_control_deassert(pcie->perst_reset);
758757
}
759758

760-
static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
759+
static void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
761760
{
762761
u32 tmp;
763762

@@ -767,7 +766,7 @@ static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
767766
writel(tmp, pcie->base + PCIE_MISC_PCIE_CTRL);
768767
}
769768

770-
static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
769+
static void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
771770
{
772771
u32 tmp;
773772

@@ -776,7 +775,7 @@ static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
776775
writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
777776
}
778777

779-
static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
778+
static int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
780779
u64 *rc_bar2_size,
781780
u64 *rc_bar2_offset)
782781
{
@@ -903,11 +902,16 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
903902
else
904903
burst = 0x2; /* 512 bytes */
905904

906-
/* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
905+
/*
906+
* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN,
907+
* RCB_MPS_MODE, RCB_64B_MODE
908+
*/
907909
tmp = readl(base + PCIE_MISC_MISC_CTRL);
908910
u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK);
909911
u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK);
910912
u32p_replace_bits(&tmp, burst, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK);
913+
u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE_MASK);
914+
u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE_MASK);
911915
writel(tmp, base + PCIE_MISC_MISC_CTRL);
912916

913917
ret = brcm_pcie_get_rc_bar2_size_and_offset(pcie, &rc_bar2_size,
@@ -1033,8 +1037,15 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
10331037
pcie->perst_set(pcie, 0);
10341038

10351039
/*
1036-
* Give the RC/EP time to wake up, before trying to configure RC.
1037-
* Intermittently check status for link-up, up to a total of 100ms.
1040+
* Wait for 100ms after PERST# deassertion; see PCIe CEM specification
1041+
* sections 2.2, PCIe r5.0, 6.6.1.
1042+
*/
1043+
msleep(100);
1044+
1045+
/*
1046+
* Give the RC/EP even more time to wake up, before trying to
1047+
* configure RC. Intermittently check status for link-up, up to a
1048+
* total of 100ms.
10381049
*/
10391050
for (i = 0; i < 100 && !brcm_pcie_link_up(pcie); i += 5)
10401051
msleep(5);

0 commit comments

Comments
 (0)