svn commit: r300015 - in head/sys: conf dev/bhnd dev/bhnd/bhndb dev/bhnd/cores/chipc dev/bhnd/cores/pci dev/bhnd/cores/pcie2 dev/bhnd/siba modules/bhnd/cores/bhnd_pci modules/bhnd/cores/bhnd_pci_ho...
Adrian Chadd
adrian at FreeBSD.org
Tue May 17 06:52:56 UTC 2016
Author: adrian
Date: Tue May 17 06:52:53 2016
New Revision: 300015
URL: https://svnweb.freebsd.org/changeset/base/300015
Log:
[bhnd] Finish bhnd(4) PCI/PCIe-G1 hostb support.
Now that we've got access to SPROM and can access board identification,
this implements all known remaining hardware work-arounds for the bhnd(4)
PCI and PCIe-G1 cores operating endpoint mode.
Additionally, this adds an initial set of skeleton PCIe-G2 hostb and pcib
drivers, required by fullmac and newer softmac devices.
Submitted by: Landon Fuller <landonf at landonf.org>
Differential Revision: https://reviews.freebsd.org/D6377
Added:
head/sys/dev/bhnd/cores/pcie2/
head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2.c (contents, props changed)
head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2_hostb.c (contents, props changed)
head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2_hostbvar.h (contents, props changed)
head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2_reg.h (contents, props changed)
head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2_var.h (contents, props changed)
head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2b.c (contents, props changed)
head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2b_var.h (contents, props changed)
Modified:
head/sys/conf/files
head/sys/dev/bhnd/bhnd.h
head/sys/dev/bhnd/bhnd_ids.h
head/sys/dev/bhnd/bhnd_subr.c
head/sys/dev/bhnd/bhndb/bhndb_pci.c
head/sys/dev/bhnd/bhndb/bhndb_pcireg.h
head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
head/sys/dev/bhnd/cores/chipc/chipc.c
head/sys/dev/bhnd/cores/pci/bhnd_pci.c
head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
head/sys/dev/bhnd/cores/pci/bhnd_pci_hostbvar.h
head/sys/dev/bhnd/cores/pci/bhnd_pcib.c
head/sys/dev/bhnd/cores/pci/bhnd_pcireg.h
head/sys/dev/bhnd/siba/siba.c
head/sys/dev/bhnd/siba/siba_bhndb.c
head/sys/dev/bhnd/siba/sibavar.h
head/sys/modules/bhnd/cores/bhnd_pci/Makefile
head/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile
head/sys/modules/bhnd/cores/bhnd_pcib/Makefile
Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/conf/files Tue May 17 06:52:53 2016 (r300015)
@@ -1142,6 +1142,9 @@ dev/bhnd/cores/chipc/bhnd_chipc_if.m opt
dev/bhnd/cores/pci/bhnd_pci.c optional bhndbus pci | bhnd pci
dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndbus pci | bhndb pci
dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci
+dev/bhnd/cores/pcie2/bhnd_pcie2.c optional bhndbus pci | bhnd pci
+dev/bhnd/cores/pcie2/bhnd_pcie2_hostb.c optional bhndbus pci | bhndb pci
+dev/bhnd/cores/pcie2/bhnd_pcie2b.c optional bhnd_pcie2b bhnd pci
dev/bhnd/nvram/bhnd_nvram_if.m optional bhndbus | bhnd
dev/bhnd/nvram/bhnd_sprom.c optional bhndbus | bhnd
dev/bhnd/nvram/nvram_subr.c optional bhndbus | bhnd
Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/bhnd.h Tue May 17 06:52:53 2016 (r300015)
@@ -318,8 +318,8 @@ struct bhnd_chip_match {
.match_bvendor = 1, .board_vendor = _vend
/** Set the required board type within a bhnd_chip_match instance */
-#define BHND_CHIP_BT(_btype) \
- .match_btype = 1, .board_type = BHND_BOARD_BCM ## _btype
+#define BHND_CHIP_BTYPE(_btype) \
+ .match_btype = 1, .board_type = BHND_BOARD_ ## _btype
/** Set the required SROM revision range within a bhnd_chip_match instance */
#define BHND_CHIP_SROMREV(_rev) \
@@ -331,7 +331,7 @@ struct bhnd_chip_match {
/** Set the required board vendor and type within a bhnd_chip_match instance */
#define BHND_CHIP_BVT(_vend, _type) \
- BHND_CHIP_BVEND(_vend), BHND_CHIP_BTYPE(_type)
+ BHND_CHIP_BVENDOR(_vend), BHND_CHIP_BTYPE(_type)
/** Set the required board vendor, type, and revision within a bhnd_chip_match
* instance */
@@ -429,6 +429,9 @@ device_t bhnd_match_child(device_t de
device_t bhnd_find_child(device_t dev,
bhnd_devclass_t class, int unit);
+device_t bhnd_find_bridge_root(device_t dev,
+ devclass_t bus_class);
+
const struct bhnd_core_info *bhnd_match_core(
const struct bhnd_core_info *cores,
u_int num_cores,
Modified: head/sys/dev/bhnd/bhnd_ids.h
==============================================================================
--- head/sys/dev/bhnd/bhnd_ids.h Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/bhnd_ids.h Tue May 17 06:52:53 2016 (r300015)
@@ -26,8 +26,6 @@
#ifndef _BHND_BHND_IDS_H_
#define _BHND_BHND_IDS_H_
-
-
/*
* JEDEC JEP-106 Core Vendor IDs
*
@@ -851,12 +849,12 @@
#define BHND_BOARD_BU4785 0x0478
/* 4321 boards */
-#define BHND_BOARD_BU4321 0x046b
-#define BHND_BOARD_BU4321E 0x047c
-#define BHND_BOARD_MP4321 0x046c
-#define BHND_BOARD_CB2_4321 0x046d
-#define BHND_BOARD_CB2_4321_AG 0x0066
-#define BHND_BOARD_MC4321 0x046e
+#define BHND_BOARD_BCM4321BU 0x046b
+#define BHND_BOARD_BCM4321BUE 0x047c
+#define BHND_BOARD_BCM4321MP 0x046c
+#define BHND_BOARD_BCM4321CB2 0x046d
+#define BHND_BOARD_BCM4321CB2_AG 0x0066
+#define BHND_BOARD_BCM4321MC 0x046e
/* 4328 boards */
#define BHND_BOARD_BU4328 0x0481
Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/bhnd_subr.c Tue May 17 06:52:53 2016 (r300015)
@@ -350,6 +350,56 @@ done:
}
/**
+ * Walk up the bhnd device hierarchy to locate the root device
+ * to which the bhndb bridge is attached.
+ *
+ * This can be used from within bhnd host bridge drivers to locate the
+ * actual upstream host device.
+ *
+ * @param dev A bhnd device.
+ * @param bus_class The expected bus (e.g. "pci") to which the bridge root
+ * should be attached.
+ *
+ * @retval device_t if a matching parent device is found.
+ * @retval NULL @p dev is not attached via a bhndb bus
+ * @retval NULL no parent device is attached via @p bus_class.
+ */
+device_t
+bhnd_find_bridge_root(device_t dev, devclass_t bus_class)
+{
+ devclass_t bhndb_class;
+ device_t parent;
+
+ KASSERT(device_get_devclass(device_get_parent(dev)) == bhnd_devclass,
+ ("%s not a bhnd device", device_get_nameunit(dev)));
+
+ bhndb_class = devclass_find("bhndb");
+
+ /* Walk the device tree until we hit a bridge */
+ parent = dev;
+ while ((parent = device_get_parent(parent)) != NULL) {
+ if (device_get_devclass(parent) == bhndb_class)
+ break;
+ }
+
+ /* No bridge? */
+ if (parent == NULL)
+ return (NULL);
+
+ /* Search for a parent attached to the expected bus class */
+ while ((parent = device_get_parent(parent)) != NULL) {
+ device_t bus;
+
+ bus = device_get_parent(parent);
+ if (bus != NULL && device_get_devclass(bus) == bus_class)
+ return (parent);
+ }
+
+ /* Not found */
+ return (NULL);
+}
+
+/**
* Find the first core in @p cores that matches @p desc.
*
* @param cores The table to search.
Modified: head/sys/dev/bhnd/bhndb/bhndb_pci.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pci.c Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/bhndb/bhndb_pci.c Tue May 17 06:52:53 2016 (r300015)
@@ -37,9 +37,10 @@ __FBSDID("$FreeBSD$");
* bus (e.g. bcma or siba) via a Broadcom PCI core configured in end-point
* mode.
*
- * This driver handles all host-level PCI interactions with a PCI/PCIe bridge
- * core operating in endpoint mode. On the bridged bhnd bus, the PCI core
- * device will be managed by a bhnd_pci_hostb driver.
+ * This driver handles all initial generic host-level PCI interactions with a
+ * PCI/PCIe bridge core operating in endpoint mode. Once the bridged bhnd(4)
+ * bus has been enumerated, this driver works in tandem with a core-specific
+ * bhnd_pci_hostb driver to manage the PCI core.
*/
#include <sys/param.h>
@@ -482,6 +483,35 @@ bhndb_pci_populate_board_info(device_t d
sc = device_get_softc(dev);
+ /*
+ * On a subset of Apple BCM4360 modules, always prefer the
+ * PCI subdevice to the SPROM-supplied boardtype.
+ *
+ * TODO:
+ *
+ * Broadcom's own drivers implement this override, and then later use
+ * the remapped BCM4360 board type to determine the required
+ * board-specific workarounds.
+ *
+ * Without access to this hardware, it's unclear why this mapping
+ * is done, and we must do the same. If we can survey the hardware
+ * in question, it may be possible to replace this behavior with
+ * explicit references to the SPROM-supplied boardtype(s) in our
+ * quirk definitions.
+ */
+ if (pci_get_subvendor(sc->parent) == PCI_VENDOR_APPLE) {
+ switch (info->board_type) {
+ case BHND_BOARD_BCM94360X29C:
+ case BHND_BOARD_BCM94360X29CP2:
+ case BHND_BOARD_BCM94360X51:
+ case BHND_BOARD_BCM94360X51P2:
+ info->board_type = 0; /* allow override below */
+ break;
+ default:
+ break;
+ }
+ }
+
/* If NVRAM did not supply vendor/type info, provide the PCI
* subvendor/subdevice values. */
if (info->board_vendor == 0)
@@ -560,10 +590,6 @@ bhndb_disable_pci_clocks(struct bhndb_pc
if (sc->pci_devclass != BHND_DEVCLASS_PCI)
return (0);
- // TODO: Check board flags for BFL2_XTALBUFOUTEN?
- // TODO: Check PCI core revision?
- // TODO: Switch to 'slow' clock?
-
/* Fetch current config */
gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
@@ -601,6 +627,7 @@ DEFINE_CLASS_1(bhndb, bhndb_pci_driver,
MODULE_VERSION(bhndb_pci, 1);
MODULE_DEPEND(bhndb_pci, bhnd_pci_hostb, 1, 1, 1);
+MODULE_DEPEND(bhndb_pci, bhnd_pcie2_hostb, 1, 1, 1);
MODULE_DEPEND(bhndb_pci, pci, 1, 1, 1);
MODULE_DEPEND(bhndb_pci, bhndb, 1, 1, 1);
MODULE_DEPEND(bhndb_pci, bhnd, 1, 1, 1);
Modified: head/sys/dev/bhnd/bhndb/bhndb_pcireg.h
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pcireg.h Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/bhndb/bhndb_pcireg.h Tue May 17 06:52:53 2016 (r300015)
@@ -29,13 +29,13 @@
*
* = MAJOR CORE REVISIONS =
*
- * There have been four revisions to the BAR0/BAR1 memory mappings used
+ * There have been four revisions to the BAR0 memory mappings used
* in BHND PCI/PCIE bridge cores:
*
* == PCI_V0 ==
* Applies to:
* - PCI (cid=0x804, revision <= 12)
- * BAR size: 8KB
+ * BAR0 size: 8KB
* Address Map:
* [offset+ size] type description
* [0x0000+0x1000] dynamic mapped backplane address space (window 0).
@@ -46,7 +46,7 @@
* Applies to:
* - PCI (cid=0x804, revision >= 13)
* - PCIE (cid=0x820) with ChipCommon (revision <= 31)
- * BAR size: 16KB
+ * BAR0 size: 16KB
* Address Map:
* [offset+ size] type description
* [0x0000+0x1000] dynamic mapped backplane address space (window 0).
@@ -57,7 +57,7 @@
* == PCI_V2 ==
* Applies to:
* - PCIE (cid=0x820) with ChipCommon (revision >= 32)
- * BAR size: 16KB
+ * BAR0 size: 16KB
* Address Map:
* [offset+ size] type description
* [0x0000+0x1000] dynamic mapped backplane address space (window 0).
@@ -68,7 +68,7 @@
* == PCI_V3 ==
* Applies to:
* - PCIE Gen 2 (cid=0x83c)
- * BAR size: 32KB?
+ * BAR0 size: 32KB
* Address Map:
* [offset+ size] type description
* [0x0000+0x1000] dynamic mapped backplane address space (window 0).
@@ -76,6 +76,12 @@
* [0x2000+0x1000] fixed pci/pcie core registers
* [0x3000+0x1000] fixed chipcommon core registers
* [???]
+ * BAR1 size: varies
+ * Address Map:
+ * [offset+ size] type description
+ * [0x0000+0x????] fixed ARM tightly-coupled memory (TCM).
+ * While fullmac chipsets provided a fixed
+ * 4KB mapping, newer devices will vary.
*
* = MINOR CORE REVISIONS =
*
@@ -86,28 +92,6 @@
* == PCI/PCIE Cores Revision >= 14 ==
* - Mapped the clock CSR into the PCI config space. Refer to
* BHND_PCI_CLK_CTL_ST
- *
- * = Hardware Bugs =
- * == BAR1 ==
- *
- * The BHND PCI(e) cores hypothetically support an additional memory mapping
- * of the backplane address space via BAR1, but this appears to be subject
- * to a hardware bug in which BAR1 is initially configured with a 4 byte
- * length.
- *
- * A work-around for this bug may be possible by writing to the PCI core's
- * BAR1 config register (0x4e0), but this requires further research -- I've
- * found three sources for information on the BAR1 PCI core configuration that
- * may be relevant:
- * - The QLogix NetXTreme 10GB PCIe NIC seems to use the same PCIE
- * core IP block as is used in other BHND devices. The bxe(4) driver
- * contains example initialization code and register constants
- * that may apply (e.g. GRC_BAR2_CONFIG/PCI_CONFIG_2_BAR2_SIZE).
- * - The publicly available Broadcom BCM440X data sheet (440X-PG02-R)
- * appears to (partially) document a Broadcom PCI(e) core that has a
- * seemingly compatible programming model.
- * - The Android bcmdhd driver sources include a possible work-around
- * implementation (writing to 0x4e0) in dhd_pcie.c
*/
/* Common PCI/PCIE Config Registers */
@@ -181,12 +165,11 @@
#define BHNDB_PCI_V2_BAR0_CCREGS_OFFSET 0x3000 /* bar0 + 12K accesses chipc core registers */
#define BHNDB_PCI_V2_BAR0_CCREGS_SIZE 0x1000
-/* PCI_V3 */
+/* PCI_V3 (PCIe-G2) */
#define BHNDB_PCI_V3_BAR0_WIN0_CONTROL 0x80 /* backplane address space accessed by BAR0/WIN0 */
-#define BHNDB_PCI_V3_BAR1_WIN0_CONTROL 0x84 /* backplane address space accessed by BAR1/WIN0. */
#define BHNDB_PCI_V3_BAR0_WIN1_CONTROL 0x70 /* backplane address space accessed by BAR0/WIN1 */
-#define BHNDB_PCI_V3_BAR0_SIZE 0x8000 /* 32KB BAR0 (?) */
+#define BHNDB_PCI_V3_BAR0_SIZE 0x8000 /* 32KB BAR0 */
#define BHNDB_PCI_V3_BAR0_WIN0_OFFSET 0x0 /* bar0 + 0x0 accesses configurable 4K region of backplane address space */
#define BHNDB_PCI_V3_BAR0_WIN0_SIZE 0x1000
#define BHNDB_PCI_V3_BAR0_WIN1_OFFSET 0x1000 /* bar0 + 4K accesses second 4K window */
Modified: head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m Tue May 17 06:52:53 2016 (r300015)
@@ -43,4 +43,23 @@ INTERFACE bhnd_chipc;
*/
METHOD bhnd_nvram_src_t nvram_src {
device_t dev;
-}
\ No newline at end of file
+}
+
+/**
+ * Write @p value with @p mask directly to the chipctrl register.
+ *
+ * @param dev A bhnd(4) ChipCommon device.
+ * @param value The value to write.
+ * @param mask The mask of bits to be written from @p value.
+ *
+ * Drivers should only use function for functionality that is not
+ * available via another bhnd_chipc() function.
+ *
+ * Currently, the only known valid use-case is in implementing a hardware
+ * work-around for the BCM4321 PCIe rev7 core revision.
+ */
+METHOD void write_chipctrl {
+ device_t dev;
+ uint32_t value;
+ uint32_t mask;
+}
Modified: head/sys/dev/bhnd/cores/chipc/chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/cores/chipc/chipc.c Tue May 17 06:52:53 2016 (r300015)
@@ -489,20 +489,38 @@ chipc_nvram_setvar(device_t dev, const c
return (ENODEV);
}
+static void
+chipc_write_chipctrl(device_t dev, uint32_t value, uint32_t mask)
+{
+ struct chipc_softc *sc;
+ uint32_t cctrl;
+
+ sc = device_get_softc(dev);
+
+ CHIPC_LOCK(sc);
+
+ cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
+ cctrl = (cctrl & ~mask) | (value | mask);
+ bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
+
+ CHIPC_UNLOCK(sc);
+}
+
static device_method_t chipc_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, chipc_probe),
- DEVMETHOD(device_attach, chipc_attach),
- DEVMETHOD(device_detach, chipc_detach),
- DEVMETHOD(device_suspend, chipc_suspend),
- DEVMETHOD(device_resume, chipc_resume),
+ DEVMETHOD(device_probe, chipc_probe),
+ DEVMETHOD(device_attach, chipc_attach),
+ DEVMETHOD(device_detach, chipc_detach),
+ DEVMETHOD(device_suspend, chipc_suspend),
+ DEVMETHOD(device_resume, chipc_resume),
/* ChipCommon interface */
- DEVMETHOD(bhnd_chipc_nvram_src, chipc_nvram_src),
+ DEVMETHOD(bhnd_chipc_nvram_src, chipc_nvram_src),
+ DEVMETHOD(bhnd_chipc_write_chipctrl, chipc_write_chipctrl),
/* NVRAM interface */
- DEVMETHOD(bhnd_nvram_getvar, chipc_nvram_getvar),
- DEVMETHOD(bhnd_nvram_setvar, chipc_nvram_setvar),
+ DEVMETHOD(bhnd_nvram_getvar, chipc_nvram_getvar),
+ DEVMETHOD(bhnd_nvram_setvar, chipc_nvram_setvar),
DEVMETHOD_END
};
Modified: head/sys/dev/bhnd/cores/pci/bhnd_pci.c
==============================================================================
--- head/sys/dev/bhnd/cores/pci/bhnd_pci.c Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/cores/pci/bhnd_pci.c Tue May 17 06:52:53 2016 (r300015)
@@ -429,8 +429,7 @@ bhnd_pcie_mdio_read_ext(struct bhnd_pci_
int reg)
{
uint32_t cmd;
- uint16_t blk, val;
- uint8_t blk_reg;
+ uint16_t val;
int error;
if (devaddr == MDIO_DEVADDR_NONE)
@@ -438,27 +437,23 @@ bhnd_pcie_mdio_read_ext(struct bhnd_pci_
/* Extended register access is only supported for the SerDes device,
* using the non-standard C22 extended address mechanism */
- if (!(sc->quirks & BHND_PCI_QUIRK_SD_C22_EXTADDR))
+ if (!(sc->quirks & BHND_PCI_QUIRK_SD_C22_EXTADDR) ||
+ phy != BHND_PCIE_PHYADDR_SD)
+ {
return (~0U);
- if (phy != BHND_PCIE_PHYADDR_SD || devaddr != BHND_PCIE_DEVAD_SD)
- return (~0U);
+ }
/* Enable MDIO access */
BHND_PCI_LOCK(sc);
bhnd_pcie_mdio_enable(sc);
- /* Determine the block and register values */
- blk = (reg & BHND_PCIE_SD_ADDREXT_BLK_MASK);
- blk_reg = (reg & BHND_PCIE_SD_ADDREXT_REG_MASK);
-
/* Write the block address to the address extension register */
- cmd = BHND_PCIE_MDIODATA_ADDR(phy, BHND_PCIE_SD_ADDREXT) |
- (blk & BHND_PCIE_MDIODATA_DATA_MASK);
+ cmd = BHND_PCIE_MDIODATA_ADDR(phy, BHND_PCIE_SD_ADDREXT) | devaddr;
if ((error = bhnd_pcie_mdio_cmd_write(sc, cmd)))
goto cleanup;
/* Issue the read */
- cmd = BHND_PCIE_MDIODATA_ADDR(phy, blk_reg);
+ cmd = BHND_PCIE_MDIODATA_ADDR(phy, reg);
error = bhnd_pcie_mdio_cmd_read(sc, cmd, &val);
cleanup:
@@ -476,8 +471,6 @@ bhnd_pcie_mdio_write_ext(struct bhnd_pci
int reg, int val)
{
uint32_t cmd;
- uint16_t blk;
- uint8_t blk_reg;
int error;
if (devaddr == MDIO_DEVADDR_NONE)
@@ -485,27 +478,23 @@ bhnd_pcie_mdio_write_ext(struct bhnd_pci
/* Extended register access is only supported for the SerDes device,
* using the non-standard C22 extended address mechanism */
- if (!(sc->quirks & BHND_PCI_QUIRK_SD_C22_EXTADDR))
+ if (!(sc->quirks & BHND_PCI_QUIRK_SD_C22_EXTADDR) ||
+ phy != BHND_PCIE_PHYADDR_SD)
+ {
return (~0U);
- if (phy != BHND_PCIE_PHYADDR_SD || devaddr != BHND_PCIE_DEVAD_SD)
- return (~0U);
+ }
/* Enable MDIO access */
BHND_PCI_LOCK(sc);
bhnd_pcie_mdio_enable(sc);
- /* Determine the block and register values */
- blk = (reg & BHND_PCIE_SD_ADDREXT_BLK_MASK);
- blk_reg = (reg & BHND_PCIE_SD_ADDREXT_REG_MASK);
-
/* Write the block address to the address extension register */
- cmd = BHND_PCIE_MDIODATA_ADDR(phy, BHND_PCIE_SD_ADDREXT) |
- (blk & BHND_PCIE_MDIODATA_DATA_MASK);
+ cmd = BHND_PCIE_MDIODATA_ADDR(phy, BHND_PCIE_SD_ADDREXT) | devaddr;
if ((error = bhnd_pcie_mdio_cmd_write(sc, cmd)))
goto cleanup;
/* Issue the write */
- cmd = BHND_PCIE_MDIODATA_ADDR(phy, blk_reg) |
+ cmd = BHND_PCIE_MDIODATA_ADDR(phy, reg) |
(val & BHND_PCIE_MDIODATA_DATA_MASK);
error = bhnd_pcie_mdio_cmd_write(sc, cmd);
Modified: head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
==============================================================================
--- head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c Tue May 17 06:52:53 2016 (r300015)
@@ -56,28 +56,43 @@ __FBSDID("$FreeBSD$");
#include <dev/bhnd/bhnd.h>
-#include "bhnd_pcireg.h"
-#include "bhnd_pci_hostbvar.h"
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
-#define BHND_PCI_ASSERT_QUIRK(_sc, _name) \
- KASSERT((_sc)->quirks & (_name), ("quirk " __STRING(_name) " not set"))
+#include <dev/bhnd/cores/chipc/chipc.h>
+#include <dev/bhnd/cores/chipc/chipcreg.h>
-#define BHND_PCI_DEV(_core, _quirks, _chip_quirks) \
- BHND_DEVICE(_core, "", _quirks, _chip_quirks, BHND_DF_HOSTB)
+#include "bhnd_pcireg.h"
+#include "bhnd_pci_hostbvar.h"
static const struct bhnd_device_quirk bhnd_pci_quirks[];
static const struct bhnd_device_quirk bhnd_pcie_quirks[];
+static const struct bhnd_chip_quirk bhnd_pci_chip_quirks[];
static const struct bhnd_chip_quirk bhnd_pcie_chip_quirks[];
+/* Device driver work-around variations */
+typedef enum {
+ BHND_PCI_WAR_ATTACH, /**< apply attach workarounds */
+ BHND_PCI_WAR_RESUME, /**< apply resume workarounds */
+ BHND_PCI_WAR_SUSPEND, /**< apply suspend workarounds */
+ BHND_PCI_WAR_DETACH /**< apply detach workarounds */
+} bhnd_pci_war_state;
+
static int bhnd_pci_wars_early_once(struct bhnd_pcihb_softc *sc);
-static int bhnd_pci_wars_hwup(struct bhnd_pcihb_softc *sc);
-static int bhnd_pci_wars_hwdown(struct bhnd_pcihb_softc *sc);
+static int bhnd_pci_wars_hwup(struct bhnd_pcihb_softc *sc,
+ bhnd_pci_war_state state);
+static int bhnd_pci_wars_hwdown(struct bhnd_pcihb_softc *sc,
+ bhnd_pci_war_state state);
/*
* device/quirk tables
*/
+
+#define BHND_PCI_DEV(_core, _quirks, _chip_quirks) \
+ BHND_DEVICE(_core, "", _quirks, _chip_quirks, BHND_DF_HOSTB)
+
static const struct bhnd_device bhnd_pci_devs[] = {
- BHND_PCI_DEV(PCI, bhnd_pci_quirks, NULL),
+ BHND_PCI_DEV(PCI, bhnd_pci_quirks, bhnd_pci_chip_quirks),
BHND_PCI_DEV(PCIE, bhnd_pcie_quirks, bhnd_pcie_chip_quirks),
BHND_DEVICE_END
};
@@ -89,12 +104,22 @@ static const struct bhnd_device_quirk bh
BHND_DEVICE_QUIRK_END
};
+static const struct bhnd_chip_quirk bhnd_pci_chip_quirks[] = {
+ /* BCM4321CB2 boards that require 960ns latency timer override */
+ {{ BHND_CHIP_BTYPE(BCM4321CB2) },
+ BHND_PCI_QUIRK_960NS_LATTIM_OVR },
+ {{ BHND_CHIP_BTYPE(BCM4321CB2_AG) },
+ BHND_PCI_QUIRK_960NS_LATTIM_OVR },
+
+ BHND_CHIP_QUIRK_END
+};
+
static const struct bhnd_device_quirk bhnd_pcie_quirks[] = {
{ BHND_HWREV_EQ (0), BHND_PCIE_QUIRK_SDR9_L0s_HANG },
- { BHND_HWREV_RANGE (0, 1), BHND_PCIE_QUIRK_UR_STATUS_FIX },
+ { BHND_HWREV_RANGE (0,1), BHND_PCIE_QUIRK_UR_STATUS_FIX },
{ BHND_HWREV_EQ (1), BHND_PCIE_QUIRK_PCIPM_REQEN },
- { BHND_HWREV_RANGE (3, 5), BHND_PCIE_QUIRK_ASPM_OVR |
+ { BHND_HWREV_RANGE (3,5), BHND_PCIE_QUIRK_ASPM_OVR |
BHND_PCIE_QUIRK_SDR9_POLARITY |
BHND_PCIE_QUIRK_SDR9_NO_FREQRETRY },
@@ -102,37 +127,50 @@ static const struct bhnd_device_quirk bh
{ BHND_HWREV_GTE (6), BHND_PCIE_QUIRK_SPROM_L23_PCI_RESET },
{ BHND_HWREV_EQ (7), BHND_PCIE_QUIRK_SERDES_NOPLLDOWN },
{ BHND_HWREV_GTE (8), BHND_PCIE_QUIRK_L1_TIMER_PERF },
- { BHND_HWREV_GTE (10), BHND_PCIE_QUIRK_SD_C22_EXTADDR },
+
+ { BHND_HWREV_LTE (17), BHND_PCIE_QUIRK_MAX_MRRS_128 },
+
BHND_DEVICE_QUIRK_END
};
static const struct bhnd_chip_quirk bhnd_pcie_chip_quirks[] = {
/* Apple boards on which BHND_BFL2_PCIEWAR_OVR should be assumed
* to be set. */
- {{ BHND_CHIP_BVENDOR (PCI_VENDOR_APPLE),
- BHND_CHIP_SROMREV (HWREV_EQ(4)),
- BHND_CHIP_BREV (HWREV_LTE(0x71)) },
- BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN },
+ {{ BHND_CHIP_BVENDOR (PCI_VENDOR_APPLE),
+ BHND_CHIP_SROMREV (HWREV_EQ(4)),
+ BHND_CHIP_BREV (HWREV_LTE(0x71)) },
+ BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN },
+
+ /* Apple BCM4322 boards that require 700mV SerDes TX drive strength. */
+ {{ BHND_CHIP_BVT (PCI_VENDOR_APPLE, BCM94322X9) },
+ BHND_PCIE_QUIRK_SERDES_TXDRV_700MV },
+
+ /* Apple BCM4331 board-specific quirks */
+#define BHND_APPLE_4331_QUIRK(_board, ...) \
+ {{ BHND_CHIP_ID (4331), \
+ BHND_CHIP_BVT (PCI_VENDOR_APPLE, _board), }, \
+ __VA_ARGS__ }
+
+ BHND_APPLE_4331_QUIRK(BCM94331X19,
+ BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
+
+ BHND_APPLE_4331_QUIRK(BCM94331X28,
+ BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
+ BHND_APPLE_4331_QUIRK(BCM94331X28B, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
+
+ BHND_APPLE_4331_QUIRK(BCM94331X29B,
+ BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
+
+ BHND_APPLE_4331_QUIRK(BCM94331X19C,
+ BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
+
+ BHND_APPLE_4331_QUIRK(BCM94331X29D, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
+ BHND_APPLE_4331_QUIRK(BCM94331X33, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
+#undef BHND_APPLE_4331_QUIRK
BHND_CHIP_QUIRK_END
};
-// Quirk handling TODO
-// WARs for the following are not yet implemented:
-// - BHND_PCIE_QUIRK_ASPM_OVR
-// - BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN
-// - BHND_PCIE_QUIRK_SERDES_NOPLLDOWN
-// Quirks (and WARs) for the following are not yet defined:
-// - Power savings via MDIO BLK1/PWR_MGMT3 on PCIe hwrev 15-20, 21-22
-// - WOWL PME enable/disable
-// - 4360 PCIe SerDes Tx amplitude/deemphasis (vendor Apple, boards
-// BCM94360X51P2, BCM94360X51A).
-// - PCI latency timer (boards CB2_4321_BOARD, CB2_4321_AG_BOARD)
-// - Max SerDes TX drive strength (vendor Apple, pcie >= rev10,
-// board BCM94322X9)
-// - 700mV SerDes TX drive strength (chipid BCM4331, boards BCM94331X19,
-// BCM94331X28, BCM94331X29B, BCM94331X19C)
-
#define BHND_PCI_SOFTC(_sc) (&((_sc)->common))
#define BHND_PCI_READ_2(_sc, _reg) \
@@ -159,6 +197,13 @@ static const struct bhnd_chip_quirk bhnd
#define BHND_PCI_MDIO_WRITE(_sc, _phy, _reg, _val) \
bhnd_pcie_mdio_write(BHND_PCI_SOFTC(_sc), (_phy), (_reg), (_val))
+#define BHND_PCI_MDIO_READ_EXT(_sc, _phy, _devaddr, _reg) \
+ bhnd_pcie_mdio_read_ext(BHND_PCI_SOFTC(_sc), (_phy), (_devaddr), (_reg))
+
+#define BHND_PCI_MDIO_WRITE_EXT(_sc, _phy, _devaddr, _reg, _val) \
+ bhnd_pcie_mdio_write_ext(BHND_PCI_SOFTC(_sc), (_phy), \
+ (_devaddr), (_reg), (_val))
+
#define BPCI_REG_SET(_regv, _attr, _val) \
BHND_PCI_REG_SET((_regv), BHND_ ## _attr, (_val))
@@ -180,26 +225,34 @@ bhnd_pci_hostb_attach(device_t dev)
int error;
sc = device_get_softc(dev);
+ sc->dev = dev;
sc->quirks = bhnd_device_quirks(dev, bhnd_pci_devs,
sizeof(bhnd_pci_devs[0]));
+ /* Find the host PCI bridge device */
+ sc->pci_dev = bhnd_find_bridge_root(dev, devclass_find("pci"));
+ if (sc->pci_dev == NULL) {
+ device_printf(dev, "parent pci bridge device not found\n");
+ return (ENXIO);
+ }
+
+ /* Common setup */
if ((error = bhnd_pci_generic_attach(dev)))
return (error);
/* Apply early single-shot work-arounds */
- if ((error = bhnd_pci_wars_early_once(sc))) {
- bhnd_pci_generic_detach(dev);
- return (error);
- }
+ if ((error = bhnd_pci_wars_early_once(sc)))
+ goto failed;
/* Apply attach/resume work-arounds */
- if ((error = bhnd_pci_wars_hwup(sc))) {
- bhnd_pci_generic_detach(dev);
- return (error);
- }
-
+ if ((error = bhnd_pci_wars_hwup(sc, BHND_PCI_WAR_ATTACH)))
+ goto failed;
return (0);
+
+failed:
+ bhnd_pci_generic_detach(dev);
+ return (error);
}
static int
@@ -211,7 +264,7 @@ bhnd_pci_hostb_detach(device_t dev)
sc = device_get_softc(dev);
/* Apply suspend/detach work-arounds */
- if ((error = bhnd_pci_wars_hwdown(sc)))
+ if ((error = bhnd_pci_wars_hwdown(sc, BHND_PCI_WAR_DETACH)))
return (error);
return (bhnd_pci_generic_detach(dev));
@@ -226,7 +279,7 @@ bhnd_pci_hostb_suspend(device_t dev)
sc = device_get_softc(dev);
/* Apply suspend/detach work-arounds */
- if ((error = bhnd_pci_wars_hwdown(sc)))
+ if ((error = bhnd_pci_wars_hwdown(sc, BHND_PCI_WAR_SUSPEND)))
return (error);
return (bhnd_pci_generic_suspend(dev));
@@ -244,7 +297,7 @@ bhnd_pci_hostb_resume(device_t dev)
return (error);
/* Apply attach/resume work-arounds */
- if ((error = bhnd_pci_wars_hwup(sc))) {
+ if ((error = bhnd_pci_wars_hwup(sc, BHND_PCI_WAR_RESUME))) {
bhnd_pci_generic_detach(dev);
return (error);
}
@@ -263,6 +316,36 @@ bhnd_pci_hostb_resume(device_t dev)
static int
bhnd_pci_wars_early_once(struct bhnd_pcihb_softc *sc)
{
+ int error;
+
+ /* Set PCI latency timer */
+ if (sc->quirks & BHND_PCI_QUIRK_960NS_LATTIM_OVR) {
+ pci_write_config(sc->pci_dev, PCIR_LATTIMER, 0x20 /* 960ns */,
+ 1);
+ }
+
+ /* Determine whether ASPM/CLKREQ should be forced on, or forced off. */
+ if (sc->quirks & BHND_PCIE_QUIRK_ASPM_OVR) {
+ struct bhnd_board_info board;
+ bool aspm_en;
+
+ /* Fetch board info */
+ if ((error = bhnd_read_board_info(sc->dev, &board)))
+ return (error);
+
+ /* Check board flags */
+ aspm_en = true;
+ if (board.board_flags2 & BHND_BFL2_PCIEWAR_OVR)
+ aspm_en = false;
+
+ /* Early Apple devices did not (but should have) set
+ * BHND_BFL2_PCIEWAR_OVR in SPROM. */
+ if (sc->quirks & BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN)
+ aspm_en = false;
+
+ sc->aspm_quirk_override.aspm_en = aspm_en;
+ }
+
/* Determine correct polarity by observing the attach-time PCIe PHY
* link status. This is used later to reset/force the SerDes
* polarity */
@@ -270,12 +353,23 @@ bhnd_pci_wars_early_once(struct bhnd_pci
uint32_t st;
bool inv;
-
st = BHND_PCI_PROTO_READ_4(sc, BHND_PCIE_PLP_STATUSREG);
inv = ((st & BHND_PCIE_PLP_POLARITY_INV) != 0);
sc->sdr9_quirk_polarity.inv = inv;
}
+ /* Override maximum read request size */
+ if (bhnd_get_class(sc->dev) == BHND_DEVCLASS_PCIE) {
+ int msize;
+
+ msize = 128; /* compatible with all PCIe-G1 core revisions */
+ if (sc->quirks & BHND_PCIE_QUIRK_DEFAULT_MRRS_512)
+ msize = 512;
+
+ if (pci_set_max_read_req(sc->pci_dev, msize) == 0)
+ panic("set mrrs on non-PCIe device");
+ }
+
return (0);
}
@@ -284,7 +378,7 @@ bhnd_pci_wars_early_once(struct bhnd_pci
* of the bridge device.
*/
static int
-bhnd_pci_wars_hwup(struct bhnd_pcihb_softc *sc)
+bhnd_pci_wars_hwup(struct bhnd_pcihb_softc *sc, bhnd_pci_war_state state)
{
/* Note that the order here matters; these work-arounds
* should not be re-ordered without careful review of their
@@ -407,6 +501,47 @@ bhnd_pci_wars_hwup(struct bhnd_pcihb_sof
BHND_PCI_PROTO_WRITE_4(sc, BHND_PCIE_DLLP_PMTHRESHREG, pmt);
}
+ /* Override ASPM/ECPM settings in SPROM shadow and PCIER_LINK_CTL */
+ if (sc->quirks & BHND_PCIE_QUIRK_ASPM_OVR) {
+ bus_size_t reg;
+ uint16_t cfg;
+
+ /* Set ASPM L1/L0s flags in SPROM shadow */
+ reg = BHND_PCIE_SPROM_SHADOW + BHND_PCIE_SRSH_ASPM_OFFSET;
+ cfg = BHND_PCI_READ_2(sc, reg);
+
+ if (sc->aspm_quirk_override.aspm_en)
+ cfg |= BHND_PCIE_SRSH_ASPM_ENB;
+ else
+ cfg &= ~BHND_PCIE_SRSH_ASPM_ENB;
+
+ BHND_PCI_WRITE_2(sc, reg, cfg);
+
+
+ /* Set ASPM/ECPM (CLKREQ) flags in PCIe link control register */
+ cfg = pcie_read_config(sc->pci_dev, PCIER_LINK_CTL, 2);
+
+ if (sc->aspm_quirk_override.aspm_en)
+ cfg |= PCIEM_LINK_CTL_ASPMC;
+ else
+ cfg &= ~PCIEM_LINK_CTL_ASPMC;
+
+ cfg &= ~PCIEM_LINK_CTL_ECPM; /* CLKREQ# */
+
+ pcie_write_config(sc->pci_dev, PCIER_LINK_CTL, cfg, 2);
+
+ /* Set CLKREQ (ECPM) flags in SPROM shadow */
+ reg = BHND_PCIE_SPROM_SHADOW + BHND_PCIE_SRSH_CLKREQ_OFFSET_R5;
+ cfg = BHND_PCI_READ_2(sc, reg);
+
+ if (sc->aspm_quirk_override.aspm_en)
+ cfg |= BHND_PCIE_SRSH_CLKREQ_ENB;
+ else
+ cfg &= ~BHND_PCIE_SRSH_CLKREQ_ENB;
+
+ BHND_PCI_WRITE_2(sc, reg, cfg);
+ }
+
/* Enable L23READY_EXIT_NOPRST if not already set in SPROM. */
if (sc->quirks & BHND_PCIE_QUIRK_SPROM_L23_PCI_RESET) {
bus_size_t reg;
@@ -423,6 +558,54 @@ bhnd_pci_wars_hwup(struct bhnd_pcihb_sof
}
}
+ /* Disable SerDes PLL down */
+ if (sc->quirks & BHND_PCIE_QUIRK_SERDES_NOPLLDOWN) {
+ device_t bhnd, chipc;
+ bus_size_t reg;
+
+ bhnd = device_get_parent(sc->dev);
+ chipc = bhnd_find_child(bhnd, BHND_DEVCLASS_CC, 0);
+ KASSERT(chipc != NULL, ("missing chipcommon device"));
+
+ /* Write SerDes PLL disable flag to the ChipCommon core */
+ BHND_CHIPC_WRITE_CHIPCTRL(chipc, CHIPCTRL_4321_PLL_DOWN,
+ CHIPCTRL_4321_PLL_DOWN);
+
+ /* Clear SPROM shadow backdoor register */
+ reg = BHND_PCIE_SPROM_SHADOW + BHND_PCIE_SRSH_BD_OFFSET;
+ BHND_PCI_WRITE_2(sc, reg, 0);
+ }
+
+ /* Adjust TX drive strength and pre-emphasis coefficient */
+ if (sc->quirks & BHND_PCIE_QUIRK_SERDES_TXDRV_ADJUST) {
+ uint16_t txdrv;
+
+ /* Fetch current TX driver parameters */
+ txdrv = BHND_PCI_MDIO_READ_EXT(sc, BHND_PCIE_PHYADDR_SD,
+ BHND_PCIE_SD_REGS_TX0, BHND_PCIE_SD_TX_DRIVER);
+
+ /* Set 700mV drive strength */
+ if (sc->quirks & BHND_PCIE_QUIRK_SERDES_TXDRV_700MV) {
+ txdrv = BPCI_REG_SET(txdrv, PCIE_SD_TX_DRIVER_P2_COEFF,
+ BHND_PCIE_APPLE_TX_P2_COEFF_700MV);
+
+ txdrv = BPCI_REG_SET(txdrv, PCIE_SD_TX_DRIVER_IDRIVER,
+ BHND_PCIE_APPLE_TX_IDRIVER_700MV);
+ }
+
+ /* ... or, set max drive strength */
+ if (sc->quirks & BHND_PCIE_QUIRK_SERDES_TXDRV_MAX) {
+ txdrv = BPCI_REG_SET(txdrv, PCIE_SD_TX_DRIVER_P2_COEFF,
+ BHND_PCIE_APPLE_TX_P2_COEFF_MAX);
+
+ txdrv = BPCI_REG_SET(txdrv, PCIE_SD_TX_DRIVER_IDRIVER,
+ BHND_PCIE_APPLE_TX_IDRIVER_MAX);
+ }
+
+ BHND_PCI_MDIO_WRITE_EXT(sc, BHND_PCIE_PHYADDR_SD,
+ BHND_PCIE_SD_REGS_TX0, BHND_PCIE_SD_TX_DRIVER, txdrv);
+ }
+
return (0);
}
@@ -431,8 +614,8 @@ bhnd_pci_wars_hwup(struct bhnd_pcihb_sof
* of the bridge device.
*/
static int
-bhnd_pci_wars_hwdown(struct bhnd_pcihb_softc *sc)
-{
+bhnd_pci_wars_hwdown(struct bhnd_pcihb_softc *sc, bhnd_pci_war_state state)
+{
/* Reduce L1 timer for better power savings.
* TODO: We could enable/disable this on demand for better power
* savings if we tie this to HT clock request handling */
@@ -443,6 +626,19 @@ bhnd_pci_wars_hwdown(struct bhnd_pcihb_s
BHND_PCI_PROTO_WRITE_4(sc, BHND_PCIE_DLLP_PMTHRESHREG, pmt);
}
+ /* Enable CLKREQ (ECPM). If suspending, also disable ASPM L1 entry */
+ if (sc->quirks & BHND_PCIE_QUIRK_ASPM_OVR) {
+ uint16_t lcreg;
+
+ lcreg = pcie_read_config(sc->pci_dev, PCIER_LINK_CTL, 2);
+
+ lcreg |= PCIEM_LINK_CTL_ECPM; /* CLKREQ# */
+ if (state == BHND_PCI_WAR_SUSPEND)
+ lcreg &= ~PCIEM_LINK_CTL_ASPMC_L1;
+
+ pcie_write_config(sc->pci_dev, PCIER_LINK_CTL, lcreg, 2);
+ }
+
return (0);
}
@@ -456,10 +652,9 @@ static device_method_t bhnd_pci_hostb_me
DEVMETHOD_END
};
-DEFINE_CLASS_1(bhnd_pci_hostb, bhnd_pci_hostb_driver, bhnd_pci_hostb_methods,
+DEFINE_CLASS_1(bhnd_hostb, bhnd_pci_hostb_driver, bhnd_pci_hostb_methods,
sizeof(struct bhnd_pcihb_softc), bhnd_pci_driver);
-
-DRIVER_MODULE(bhnd_hostb, bhnd, bhnd_pci_hostb_driver, bhnd_hostb_devclass, 0, 0);
+DRIVER_MODULE(bhnd_pci_hostb, bhnd, bhnd_pci_hostb_driver, bhnd_hostb_devclass, 0, 0);
MODULE_VERSION(bhnd_pci_hostb, 1);
MODULE_DEPEND(bhnd_pci_hostb, bhnd, 1, 1, 1);
Modified: head/sys/dev/bhnd/cores/pci/bhnd_pci_hostbvar.h
==============================================================================
--- head/sys/dev/bhnd/cores/pci/bhnd_pci_hostbvar.h Tue May 17 06:45:25 2016 (r300014)
+++ head/sys/dev/bhnd/cores/pci/bhnd_pci_hostbvar.h Tue May 17 06:52:53 2016 (r300015)
@@ -43,7 +43,7 @@
DECLARE_CLASS(bhnd_pci_hostb_driver);
-/*
+/**
* PCI/PCIe-Gen1 endpoint-mode device quirks
*/
enum {
@@ -56,7 +56,6 @@ enum {
*/
BHND_PCI_QUIRK_SBTOPCI2_PREF_BURST = (1<<1),
-
/**
* SBTOPCI_RC_READMULTI must be set on the SSB_PCICORE_SBTOPCI2
* register.
@@ -74,18 +73,24 @@ enum {
BHND_PCI_QUIRK_CLKRUN_DSBL = (1<<3),
/**
+ * On PCI-attached BCM4321CB* boards, the PCI latency timer must be set
+ * to 960ns on initial attach.
+ */
+ BHND_PCI_QUIRK_960NS_LATTIM_OVR = (1<<4),
+
+ /**
* TLP workaround for unmatched address handling is required.
*
* This TLP workaround will enable setting of the PCIe UR status bit
* on memory access to an unmatched address.
*/
- BHND_PCIE_QUIRK_UR_STATUS_FIX = (1<<4),
+ BHND_PCIE_QUIRK_UR_STATUS_FIX = (1<<5),
/**
* PCI-PM power management must be explicitly enabled via
* the data link control register.
*/
- BHND_PCIE_QUIRK_PCIPM_REQEN = (1<<5),
+ BHND_PCIE_QUIRK_PCIPM_REQEN = (1<<6),
/**
* Fix L0s to L0 exit transition on SerDes <= rev9 devices.
@@ -98,46 +103,50 @@ enum {
* filters must be tweaked to ensure the CDR has fully stabilized
* before asserting receive sequencer completion.
*/
- BHND_PCIE_QUIRK_SDR9_L0s_HANG = (1<<6),
+ BHND_PCIE_QUIRK_SDR9_L0s_HANG = (1<<7),
/**
* The idle time for entering L1 low-power state must be
* explicitly set (to 114ns) to fix slow L1->L0 transition issues.
*/
- BHND_PCIE_QUIRK_L1_IDLE_THRESH = (1<<7),
+ BHND_PCIE_QUIRK_L1_IDLE_THRESH = (1<<8),
/**
* The ASPM L1 entry timer should be extended for better performance,
* and restored for better power savings.
*/
- BHND_PCIE_QUIRK_L1_TIMER_PERF = (1<<8),
+ BHND_PCIE_QUIRK_L1_TIMER_PERF = (1<<9),
/**
* ASPM and ECPM settings must be overridden manually.
+ * Applies to 4311B0/4321B1 chipset revisions.
*
* The override behavior is controlled by the BHND_BFL2_PCIEWAR_OVR
- * flag. If this flag is set, ASPM/CLKREQ should be overridden as
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list