Skip to content

Commit aa8589a

Browse files
jim2101024tsbogend
authored andcommitted
PCI: brcmstb: Augment driver for MIPs SOCs
The current brcmstb driver works for Arm and Arm64. A few things are modified here for us to support MIPs as well. o There are four outbound range register groups and each directs a window of up to 128MB. Even though there are four 128MB DT "ranges" in the bmips PCIe DT node, these ranges are contiguous and are collapsed into a single range by the OF range parser. Now the driver assumes a single range -- for MIPs only -- and splits it back into 128MB sizes. o For bcm7425, the config space accesses must be 32-bit reads or writes. In addition, the 4k config space register array is missing and not used. o The registers for the upper 32-bits of the outbound window address do not exist. o Burst size must be set to 256 (this refers to an internal bus). Signed-off-by: Jim Quinlan <[email protected]> Acked-by: Florian Fainelli <[email protected]> Signed-off-by: Thomas Bogendoerfer <[email protected]>
1 parent d552dde commit aa8589a

File tree

2 files changed

+79
-5
lines changed

2 files changed

+79
-5
lines changed

drivers/pci/controller/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ config PCIE_BRCMSTB
274274
BMIPS_GENERIC || COMPILE_TEST
275275
depends on OF
276276
depends on PCI_MSI_IRQ_DOMAIN
277-
default ARCH_BRCMSTB
277+
default ARCH_BRCMSTB || BMIPS_GENERIC
278278
help
279279
Say Y here to enable PCIe host controller support for
280280
Broadcom STB based SoCs, like the Raspberry Pi 4.

drivers/pci/controller/pcie-brcmstb.c

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
119119
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
120120
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
121+
#define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000
121122

122123

123124
#define PCIE_INTR2_CPU_BASE 0x4300
@@ -205,6 +206,8 @@ enum {
205206

206207
enum pcie_type {
207208
GENERIC,
209+
BCM7425,
210+
BCM7435,
208211
BCM4908,
209212
BCM7278,
210213
BCM2711,
@@ -223,13 +226,33 @@ static const int pcie_offsets[] = {
223226
[EXT_CFG_DATA] = 0x9004,
224227
};
225228

229+
static const int pcie_offsets_bmips_7425[] = {
230+
[RGR1_SW_INIT_1] = 0x8010,
231+
[EXT_CFG_INDEX] = 0x8300,
232+
[EXT_CFG_DATA] = 0x8304,
233+
};
234+
226235
static const struct pcie_cfg_data generic_cfg = {
227236
.offsets = pcie_offsets,
228237
.type = GENERIC,
229238
.perst_set = brcm_pcie_perst_set_generic,
230239
.bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,
231240
};
232241

242+
static const struct pcie_cfg_data bcm7425_cfg = {
243+
.offsets = pcie_offsets_bmips_7425,
244+
.type = BCM7425,
245+
.perst_set = brcm_pcie_perst_set_generic,
246+
.bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,
247+
};
248+
249+
static const struct pcie_cfg_data bcm7435_cfg = {
250+
.offsets = pcie_offsets,
251+
.type = BCM7435,
252+
.perst_set = brcm_pcie_perst_set_generic,
253+
.bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,
254+
};
255+
233256
static const struct pcie_cfg_data bcm4908_cfg = {
234257
.offsets = pcie_offsets,
235258
.type = BCM4908,
@@ -297,6 +320,11 @@ struct brcm_pcie {
297320
void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
298321
};
299322

323+
static inline bool is_bmips(const struct brcm_pcie *pcie)
324+
{
325+
return pcie->type == BCM7435 || pcie->type == BCM7425;
326+
}
327+
300328
/*
301329
* This is to convert the size of the inbound "BAR" region to the
302330
* non-linear values of PCIE_X_MISC_RC_BAR[123]_CONFIG_LO.SIZE
@@ -443,6 +471,9 @@ static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
443471
PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK);
444472
writel(tmp, pcie->base + PCIE_MEM_WIN0_BASE_LIMIT(win));
445473

474+
if (is_bmips(pcie))
475+
return;
476+
446477
/* Write the cpu & limit addr upper bits */
447478
high_addr_shift =
448479
HWEIGHT32(PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK);
@@ -718,12 +749,35 @@ static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
718749
return base + PCIE_EXT_CFG_DATA + where;
719750
}
720751

752+
static void __iomem *brcm_pcie_map_conf32(struct pci_bus *bus, unsigned int devfn,
753+
int where)
754+
{
755+
struct brcm_pcie *pcie = bus->sysdata;
756+
void __iomem *base = pcie->base;
757+
int idx;
758+
759+
/* Accesses to the RC go right to the RC registers if slot==0 */
760+
if (pci_is_root_bus(bus))
761+
return PCI_SLOT(devfn) ? NULL : base + (where & ~0x3);
762+
763+
/* For devices, write to the config space index register */
764+
idx = PCIE_ECAM_OFFSET(bus->number, devfn, (where & ~3));
765+
writel(idx, base + IDX_ADDR(pcie));
766+
return base + DATA_ADDR(pcie);
767+
}
768+
721769
static struct pci_ops brcm_pcie_ops = {
722770
.map_bus = brcm_pcie_map_conf,
723771
.read = pci_generic_config_read,
724772
.write = pci_generic_config_write,
725773
};
726774

775+
static struct pci_ops brcm_pcie_ops32 = {
776+
.map_bus = brcm_pcie_map_conf32,
777+
.read = pci_generic_config_read32,
778+
.write = pci_generic_config_write32,
779+
};
780+
727781
static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val)
728782
{
729783
u32 tmp, mask = RGR1_SW_INIT_1_INIT_GENERIC_MASK;
@@ -883,7 +937,10 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
883937
pcie->bridge_sw_init_set(pcie, 0);
884938

885939
tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
886-
tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK;
940+
if (is_bmips(pcie))
941+
tmp &= ~PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK;
942+
else
943+
tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK;
887944
writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
888945
/* Wait for SerDes to be stable */
889946
usleep_range(100, 200);
@@ -893,8 +950,10 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
893950
* is encoded as 0=128, 1=256, 2=512, 3=Rsvd, for BCM7278 it
894951
* is encoded as 0=Rsvd, 1=128, 2=256, 3=512.
895952
*/
896-
if (pcie->type == BCM2711)
897-
burst = 0x0; /* 128B */
953+
if (is_bmips(pcie))
954+
burst = 0x1; /* 256 bytes */
955+
else if (pcie->type == BCM2711)
956+
burst = 0x0; /* 128 bytes */
898957
else if (pcie->type == BCM7278)
899958
burst = 0x3; /* 512 bytes */
900959
else
@@ -988,6 +1047,19 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
9881047
return -EINVAL;
9891048
}
9901049

1050+
if (is_bmips(pcie)) {
1051+
u64 start = res->start;
1052+
unsigned int j, nwins = resource_size(res) / SZ_128M;
1053+
1054+
/* bmips PCIe outbound windows have a 128MB max size */
1055+
if (nwins > BRCM_NUM_PCIE_OUT_WINS)
1056+
nwins = BRCM_NUM_PCIE_OUT_WINS;
1057+
for (j = 0; j < nwins; j++, start += SZ_128M)
1058+
brcm_pcie_set_outbound_win(pcie, j, start,
1059+
start - entry->offset,
1060+
SZ_128M);
1061+
break;
1062+
}
9911063
brcm_pcie_set_outbound_win(pcie, num_out_wins, res->start,
9921064
res->start - entry->offset,
9931065
resource_size(res));
@@ -1226,6 +1298,8 @@ static const struct of_device_id brcm_pcie_match[] = {
12261298
{ .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg },
12271299
{ .compatible = "brcm,bcm7216-pcie", .data = &bcm7278_cfg },
12281300
{ .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg },
1301+
{ .compatible = "brcm,bcm7435-pcie", .data = &bcm7435_cfg },
1302+
{ .compatible = "brcm,bcm7425-pcie", .data = &bcm7425_cfg },
12291303
{},
12301304
};
12311305

@@ -1315,7 +1389,7 @@ static int brcm_pcie_probe(struct platform_device *pdev)
13151389
}
13161390
}
13171391

1318-
bridge->ops = &brcm_pcie_ops;
1392+
bridge->ops = pcie->type == BCM7425 ? &brcm_pcie_ops32 : &brcm_pcie_ops;
13191393
bridge->sysdata = pcie;
13201394

13211395
platform_set_drvdata(pdev, pcie);

0 commit comments

Comments
 (0)