Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19c860d9 authored by Jonas Gorski's avatar Jonas Gorski Committed by Ralf Baechle
Browse files

MIPS: BCM63XX: Add PCIe Support for BCM6328



Add support for the PCIe port found on BCM6328.

Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3956/


Reviewed-by: default avatarFlorian Fainelli <florian@openwrt.org>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 76f42fe8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ menu "CPU support"

config BCM63XX_CPU_6328
	bool "support 6328 CPU"
	select HW_HAS_PCI

config BCM63XX_CPU_6338
	bool "support 6338 CPU"
+9 −0
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ enum bcm63xx_regs_set {
	RSET_USBH_PRIV,
	RSET_MPI,
	RSET_PCMCIA,
	RSET_PCIE,
	RSET_DSL,
	RSET_ENET0,
	RSET_ENET1,
@@ -188,6 +189,7 @@ enum bcm63xx_regs_set {
#define BCM_6328_USBH_PRIV_BASE		(0xdeadbeef)
#define BCM_6328_MPI_BASE		(0xdeadbeef)
#define BCM_6328_PCMCIA_BASE		(0xdeadbeef)
#define BCM_6328_PCIE_BASE		(0xb0e40000)
#define BCM_6328_SDRAM_REGS_BASE	(0xdeadbeef)
#define BCM_6328_DSL_BASE		(0xb0001900)
#define BCM_6328_UBUS_BASE		(0xdeadbeef)
@@ -232,6 +234,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_USBH_PRIV_BASE		(0xdeadbeef)
#define BCM_6338_MPI_BASE		(0xfffe3160)
#define BCM_6338_PCMCIA_BASE		(0xdeadbeef)
#define BCM_6338_PCIE_BASE		(0xdeadbeef)
#define BCM_6338_SDRAM_REGS_BASE	(0xfffe3100)
#define BCM_6338_DSL_BASE		(0xfffe1000)
#define BCM_6338_UBUS_BASE		(0xdeadbeef)
@@ -279,6 +282,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_ENETSW_BASE		(0xdeadbeef)
#define BCM_6345_PCMCIA_BASE		(0xfffe2028)
#define BCM_6345_MPI_BASE		(0xfffe2000)
#define BCM_6345_PCIE_BASE		(0xdeadbeef)
#define BCM_6345_OHCI0_BASE		(0xfffe2100)
#define BCM_6345_OHCI_PRIV_BASE		(0xfffe2200)
#define BCM_6345_USBH_PRIV_BASE		(0xdeadbeef)
@@ -320,6 +324,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_USBH_PRIV_BASE		(0xdeadbeef)
#define BCM_6348_MPI_BASE		(0xfffe2000)
#define BCM_6348_PCMCIA_BASE		(0xfffe2054)
#define BCM_6348_PCIE_BASE		(0xdeadbeef)
#define BCM_6348_SDRAM_REGS_BASE	(0xfffe2300)
#define BCM_6348_M2M_BASE		(0xfffe2800)
#define BCM_6348_DSL_BASE		(0xfffe3000)
@@ -362,6 +367,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_USBH_PRIV_BASE		(0xfffe1500)
#define BCM_6358_MPI_BASE		(0xfffe1000)
#define BCM_6358_PCMCIA_BASE		(0xfffe1054)
#define BCM_6358_PCIE_BASE		(0xdeadbeef)
#define BCM_6358_SDRAM_REGS_BASE	(0xfffe2300)
#define BCM_6358_M2M_BASE		(0xdeadbeef)
#define BCM_6358_DSL_BASE		(0xfffe3000)
@@ -405,6 +411,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_USBH_PRIV_BASE		(0xb0001700)
#define BCM_6368_MPI_BASE		(0xb0001000)
#define BCM_6368_PCMCIA_BASE		(0xb0001054)
#define BCM_6368_PCIE_BASE		(0xdeadbeef)
#define BCM_6368_SDRAM_REGS_BASE	(0xdeadbeef)
#define BCM_6368_M2M_BASE		(0xdeadbeef)
#define BCM_6368_DSL_BASE		(0xdeadbeef)
@@ -453,6 +460,7 @@ extern const unsigned long *bcm63xx_regs_base;
	__GEN_RSET_BASE(__cpu, USBH_PRIV)				\
	__GEN_RSET_BASE(__cpu, MPI)					\
	__GEN_RSET_BASE(__cpu, PCMCIA)					\
	__GEN_RSET_BASE(__cpu, PCIE)					\
	__GEN_RSET_BASE(__cpu, DSL)					\
	__GEN_RSET_BASE(__cpu, ENET0)					\
	__GEN_RSET_BASE(__cpu, ENET1)					\
@@ -493,6 +501,7 @@ extern const unsigned long *bcm63xx_regs_base;
	[RSET_USBH_PRIV]	= BCM_## __cpu ##_USBH_PRIV_BASE,	\
	[RSET_MPI]		= BCM_## __cpu ##_MPI_BASE,		\
	[RSET_PCMCIA]		= BCM_## __cpu ##_PCMCIA_BASE,		\
	[RSET_PCIE]		= BCM_## __cpu ##_PCIE_BASE,		\
	[RSET_DSL]		= BCM_## __cpu ##_DSL_BASE,		\
	[RSET_ENET0]		= BCM_## __cpu ##_ENET0_BASE,		\
	[RSET_ENET1]		= BCM_## __cpu ##_ENET1_BASE,		\
+6 −0
Original line number Diff line number Diff line
@@ -40,6 +40,10 @@
#define BCM_CB_MEM_END_PA		(BCM_CB_MEM_BASE_PA +		\
					BCM_CB_MEM_SIZE - 1)

#define BCM_PCIE_MEM_BASE_PA		0x10f00000
#define BCM_PCIE_MEM_SIZE		(16 * 1024 * 1024)
#define BCM_PCIE_MEM_END_PA		(BCM_PCIE_MEM_BASE_PA +		\
					BCM_PCIE_MEM_SIZE - 1)

/*
 * Internal registers are accessed through KSEG3
@@ -85,6 +89,8 @@
#define bcm_mpi_writel(v, o)	bcm_rset_writel(RSET_MPI, (v), (o))
#define bcm_pcmcia_readl(o)	bcm_rset_readl(RSET_PCMCIA, (o))
#define bcm_pcmcia_writel(v, o)	bcm_rset_writel(RSET_PCMCIA, (v), (o))
#define bcm_pcie_readl(o)	bcm_rset_readl(RSET_PCIE, (o))
#define bcm_pcie_writel(v, o)	bcm_rset_writel(RSET_PCIE, (v), (o))
#define bcm_sdram_readl(o)	bcm_rset_readl(RSET_SDRAM, (o))
#define bcm_sdram_writel(v, o)	bcm_rset_writel(RSET_SDRAM, (v), (o))
#define bcm_memc_readl(o)	bcm_rset_readl(RSET_MEMC, (o))
+54 −0
Original line number Diff line number Diff line
@@ -1162,6 +1162,9 @@
/*************************************************************************
 * _REG relative to RSET_MISC
 *************************************************************************/
#define MISC_SERDES_CTRL_REG		0x0
#define SERDES_PCIE_EN			(1 << 0)
#define SERDES_PCIE_EXD_EN		(1 << 15)

#define MISC_STRAPBUS_6328_REG		0x240
#define STRAPBUS_6328_FCVO_SHIFT	7
@@ -1169,4 +1172,55 @@
#define STRAPBUS_6328_BOOT_SEL_SERIAL	(1 << 28)
#define STRAPBUS_6328_BOOT_SEL_NAND	(0 << 28)

/*************************************************************************
 * _REG relative to RSET_PCIE
 *************************************************************************/

#define PCIE_CONFIG2_REG		0x408
#define CONFIG2_BAR1_SIZE_EN		1
#define CONFIG2_BAR1_SIZE_MASK		0xf

#define PCIE_IDVAL3_REG			0x43c
#define IDVAL3_CLASS_CODE_MASK		0xffffff
#define IDVAL3_SUBCLASS_SHIFT		8
#define IDVAL3_CLASS_SHIFT		16

#define PCIE_DLSTATUS_REG		0x1048
#define DLSTATUS_PHYLINKUP		(1 << 13)

#define PCIE_BRIDGE_OPT1_REG		0x2820
#define OPT1_RD_BE_OPT_EN		(1 << 7)
#define OPT1_RD_REPLY_BE_FIX_EN		(1 << 9)
#define OPT1_PCIE_BRIDGE_HOLE_DET_EN	(1 << 11)
#define OPT1_L1_INT_STATUS_MASK_POL	(1 << 12)

#define PCIE_BRIDGE_OPT2_REG		0x2824
#define OPT2_UBUS_UR_DECODE_DIS		(1 << 2)
#define OPT2_TX_CREDIT_CHK_EN		(1 << 4)
#define OPT2_CFG_TYPE1_BD_SEL		(1 << 7)
#define OPT2_CFG_TYPE1_BUS_NO_SHIFT	16
#define OPT2_CFG_TYPE1_BUS_NO_MASK	(0xff << OPT2_CFG_TYPE1_BUS_NO_SHIFT)

#define PCIE_BRIDGE_BAR0_BASEMASK_REG	0x2828
#define PCIE_BRIDGE_BAR1_BASEMASK_REG	0x2830
#define BASEMASK_REMAP_EN		(1 << 0)
#define BASEMASK_SWAP_EN		(1 << 1)
#define BASEMASK_MASK_SHIFT		4
#define BASEMASK_MASK_MASK		(0xfff << BASEMASK_MASK_SHIFT)
#define BASEMASK_BASE_SHIFT		20
#define BASEMASK_BASE_MASK		(0xfff << BASEMASK_BASE_SHIFT)

#define PCIE_BRIDGE_BAR0_REBASE_ADDR_REG 0x282c
#define PCIE_BRIDGE_BAR1_REBASE_ADDR_REG 0x2834
#define REBASE_ADDR_BASE_SHIFT		20
#define REBASE_ADDR_BASE_MASK		(0xfff << REBASE_ADDR_BASE_SHIFT)

#define PCIE_BRIDGE_RC_INT_MASK_REG	0x2854
#define PCIE_RC_INT_A			(1 << 0)
#define PCIE_RC_INT_B			(1 << 1)
#define PCIE_RC_INT_C			(1 << 2)
#define PCIE_RC_INT_D			(1 << 3)

#define PCIE_DEVICE_OFFSET		0x8000

#endif /* BCM63XX_REGS_H_ */
+61 −0
Original line number Diff line number Diff line
@@ -465,3 +465,64 @@ static void bcm63xx_fixup(struct pci_dev *dev)

DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
#endif

static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
{
	switch (bus->number) {
	case PCIE_BUS_BRIDGE:
		return (PCI_SLOT(devfn) == 0);
	case PCIE_BUS_DEVICE:
		if (PCI_SLOT(devfn) == 0)
			return bcm_pcie_readl(PCIE_DLSTATUS_REG)
					& DLSTATUS_PHYLINKUP;
	default:
		return false;
	}
}

static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn,
			     int where, int size, u32 *val)
{
	u32 data;
	u32 reg = where & ~3;

	if (!bcm63xx_pcie_can_access(bus, devfn))
		return PCIBIOS_DEVICE_NOT_FOUND;

	if (bus->number == PCIE_BUS_DEVICE)
		reg += PCIE_DEVICE_OFFSET;

	data = bcm_pcie_readl(reg);

	*val = postprocess_read(data, where, size);

	return PCIBIOS_SUCCESSFUL;

}

static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn,
			      int where, int size, u32 val)
{
	u32 data;
	u32 reg = where & ~3;

	if (!bcm63xx_pcie_can_access(bus, devfn))
		return PCIBIOS_DEVICE_NOT_FOUND;

	if (bus->number == PCIE_BUS_DEVICE)
		reg += PCIE_DEVICE_OFFSET;


	data = bcm_pcie_readl(reg);

	data = preprocess_write(data, val, where, size);
	bcm_pcie_writel(data, reg);

	return PCIBIOS_SUCCESSFUL;
}


struct pci_ops bcm63xx_pcie_ops = {
	.read   = bcm63xx_pcie_read,
	.write  = bcm63xx_pcie_write
};
Loading