bcm-v4

[Specification

PCIe Core

The Backplane always contains one core responsible for interacting with the computer. In the newer PCI-E cards, it is connected via the PCI-E Core. This core has a Core ID of 0x820.

Configuration Initialization

Besides the normal PCIe initialization done by the kernel routines, the code should also clear bits 0x0000FF00 of configuration register 0x40. This action prevents PCI Tx retries from interfering with the C3 state of the CPU.

Registers

Offset

Size

Meaning

0x000C

4

BIST Status

0x0028

4

Backplane to PCIe Mailbox

0x0100

4

Backplane to PCIe Translation 0 (sbtopcie0)

0x0104

4

Backplane to PCIe Translation 1 (sbtopcie1)

0x0108

4

Backplane to PCIe Translation 2 (sbtopcie2)

0x0120

4

PCIe Configuration Space: Address

0x0124

4

PCIe Configuration Space: Data

0x0128

4

MDIO Access: Control

0x012C

4

MDIO Access: Data

0x0130

4

PCIe PHY/DLLP/TLP Register Access: Address

0x0134

4

PCIe PHY/DLLP/TLP Register Access: Data

Reading and writing PCIe Configuration Space or PCIe Registers

First, write the register offset to the control register (0x120 for PCIe Configuration Registers or 0x130 for PCIe Registers), then either read or write the the associated data register.

PCIe Configuration Space Registers

PCIe Registers

Offset

Size

Usage

TLP Diagnostic Registers

0x0000

4

Configuration Register

0x0004

4

TLP Workarounds Register

0x0010

4

Write DMA Upper Address

0x0014

4

Write DMA Lower Address

0x0018

4

Write DMA Request Length / Byte Encoding

0x001C

4

Read DMA Upper Address

0x0020

4

Read DMA Lower Address

0x0024

4

Read DMA Request Length

0x0028

4

MSI DMA Upper Address

0x002C

4

MSI DMA Lower Address

0x0030

4

MSI DMA Request Length

0x0034

4

Slave Request Length

0x0038

4

Flow Control Inputs

0x003C

4

TX State Machine and Gated Request

0x0040

4

Address ACK, Transfer Count and ARB Length

0x0044

4

DMA Completion Header 0

0x0048

4

DMA Completion Header 1

0x004C

4

DMA Completion Header 2

0x0050

4

DMA Completion Misc 0

0x0054

4

DMA Completion Misc 1

0x0058

4

DMA Completion Misc 2

0x005C

4

Split Controller Request Length

0x0060

4

Splig Controller Misc 0

0x0064

4

Splig Controller Misc 1

0x0068

4

Bus / Device Function

0x006C

4

Reset Counter

0x0070

4

Retry Buffer Value

0x0074

4

Target Debug Register 1

0x0078

4

Target Debug Register 2

0x007C

4

Target Debug Register 3

0x0080

4

Target Debug Register 4

DLLP Diagnostic Registers

0x0100

4

Link Control Register

0x0104

4

Link Status

0x0108

4

Link Attention

0x010C

4

Link Attention Mask

0x0110

4

Next TX Sequence Number

0x0114

4

ACK'd TX Sequence Number

0x0118

4

Purged TX Sequence Number

0x011C

4

RX Sequence Number

0x0120

4

Link Replay

0x0124

4

Link ACK Timeout

0x0128

4

Power Management Threshold

0x012C

4

Retry Buffer Write Pointer

0x0130

4

Retry Buffer Read Pointer

0x0134

4

Retry Buffer Purged Pointer

0x0138

4

Retry Buffer Read / Write

0x013C

4

Error Count Threshold

0x0140

4

TLP Error Counter

0x0144

4

Error Counter

0x0148

4

NAK Received Counter

0x014C

4

Test Register

0x0150

4

Packet BIST

PHY Diagnostic Registers

0x0200

4

Mode

0x0204

4

Status

0x0208

4

LTSSM Control

0x020C

4

Link Training Link Number

0x0210

4

Link Training Lane Number

0x0214

4

Link Training N FTS

0x0218

4

Attention

0x021C

4

Attention Mask

0x0220

4

RX Error Counter

0x0224

4

RX Framing Error Counter

0x0228

4

RX Error Threshold

0x022C

4

Test Control Register

0x0230

4

SERDES Control Override

0x0234

4

Timing Parameters Override

0x0238

4

RX/TX State Machine Diag

0x023C

4

LTSSM State Machine Diag

MDIO Access

MDIO Control Register Usage

Bitmask

Usage

0x007F

MDIO Clock Divsor

0x0080

Enable/Disable Preamble Sequence

0x0100

MDIO Transaction Complete

MDIO SERDES Devices

Address

Device

0x1D

SERDES PLL Device

0x1F

SERDES RX Device

SERDES RX Device Registers

Offset

Usage

1

RX Control

2

RX Timer

6

CDR

7

CDR BW

int PCIe MDIO Set Block (u32 blk)

(updated for 5.10.56.46)

  1. Initialize mdiodata (u32) with Start of Transaction bit set, the Write Transaction bit set and the Turnaround bit set (0x50020000), then Set the SERDES Rx device code (0x1F) in the address field, and OR with blk<<4.

  2. Write mdiodata to the MDIO Data Register
  3. Delay 10 usec
  4. Spin wait for bit 0x100 to be set in the MDIO Control register. Delay 1000 usec between tries and try for 200 times.
  5. If above loop times out
    1. Return 0
  6. Return 1

int Read/Write MDIO Slaves (u32 phys, u32 addr, u32 *val)

(updated for 5.10.56.46)

  1. Write 0x82 (Enable Preamble Sequence bitwise OR'd with a divisor value of 2) to the MDIO Control Register
  2. If PCIe core revision >= 10

    1. Call PCIe MDIO Set Block with phys as argument
    2. If the returned value is 0
      1. Return 1
    3. Set mdiodata as addr << 18

    4. Set spinwait loop counter to 200
  3. Otherwise
    1. Set mdiodata to phys << 22 | addr << 18

    2. Set spinwait loop counter to 10
  4. OR mdiodata with the Start of Transaction bit, and the Turnaround bit.
  5. If reading
    1. Set the Read Transaction bit in mdiodata
  6. Otherwise
    1. Set the Write Transaction bit in mdiodata and OR with *val.
  7. Write mdiodata to the MDIO Data Register
  8. Delay 10 usec
  9. Spinwait for bit 0x100 of the MDIO Control Register to be set. Delay 1000 usec between trials and use the spinwait loop counter to determine the number of tries
  10. If the spinwait loop was not satisfied
    1. Write 0 to the MDIO Control Register
    2. Return 1
  11. If this is a read operation
    1. Delay 10 usec
    2. Read MDIO Data Register, mask with 0xFFFF, and store in *val
  12. Write 0 to MDIO Control Register
  13. Return 0

MDIO Data Word Format

Mask

Function

0x40000000

Start of Transaction

0x20000000

Read Transaction

0x10000000

Write Transaction

0x0FC00000

Device Address

0x003C0000

Register

0x00020000

Turnaround

0x0000FFFF

Data

PCIe Attach (int state)

  1. If (the board vendor is Apple AND the SPROM Rev is 4 AND the boad revision < 0x72) OR bit 0x20 is set in board flags 2

    1. Set pcie_war_aspm_ovr true

  2. Otherwise
    1. Set pcie_war_aspm_ovr false

  3. Set pcie_polarity to 0

  4. Call PCIe Polarity Workaround
  5. Call PCIe SERDES Workaround
  6. Call PCIe ASPM Clock Request Workaround
  7. Call PCIe Clock Request Update with state as argument

PCIe Workaround PCI Setup

  1. If PCI core rev is 0 or 1
    1. Set bit 0x8 in PCI Register 4
  2. If PCI core rev is 1
    1. Set bit 0x40 in PCI Register 0x100
  3. If PCI core rev is 0
    1. Write 0x8128 to serdes RX timer
    2. Write 0x0100 to serdes RX CDR
    3. Write 0x1466 to serdes RX CDR BW
  4. Else if PCIE and PCI core rev is 3, 4, or 5
    1. Read PCI Register 0x128
    2. Mask result with 0x00FF
    3. OR result with 0x72 << 8

    4. Write result to PCI register 0x128
    5. Call PCIe SERDES Workaround
    6. Call PCIe ASPM Clock Request Workaround
  5. Else if PCI core rev is 7
    1. Call PCIe No PLL Down Workaround
  6. If PCI core rev >= 6

    1. Call PCIe Miscellaneous Configuration Fixup

PCIe Polarity Workaround

  1. If pcie_polarity is not zero

    1. Return
  2. If the PCIe PHY Status Register (0x204) anded with 0x10 is zero
    1. Set pcie_polarity to 0x80

  3. Otherwise
    1. Set pcie_polarity to 0xC0

PCIe SERDES Workaround

  1. If pcie_polarity is not zero

    1. Write that value to the SERDES RX Control
  2. Clear bit 0x4000 in the SERDES PLL Control

PCIe ASPM Clock Request Workaround

  1. If the core revision is not 3, 4 or 5
    1. Exit
  2. If pcie_war_aspm_ovr is false

    1. Get the address at sprom[4] (Note: the u16 sprom array is mapped to the shadow sprom location)
    2. Set bits 0x18 in that address
  3. Otherwise
    1. Clear bits 0x18 in that address
  4. Get an MMIO address from sprom[14]
  5. If pcie_war_aspm_ovr is false

    1. Set bit 0x0800 in that address
    2. Set pcie_pr42767 to 1

  6. Otherwise
    1. Clear bit 0x0800 in that address
    2. Set pcie_pr42767 to 0

PCIe Clock Request Update (int state)

  1. If state is 1
    1. If the core revision is 3, 4, or 5
      1. Call PCIe Clock Request with 1, 0 as arguments
  2. Else if state is 2
    1. Else if core revision is 6
      1. Clear the Chip Control Address Register (0x650)
      2. Mask the Chip Control Data (0x654) with mask 0x40
    2. Else if pcie_pr42767 is true

      1. Call PCIe Clock Request with 1, 1 as arguments
  3. Else if state is 3
    1. If core revision is 6
      1. Clear the Chip Control Address Register (0x650)
      2. Write 0x40 to the Chip Control Data (0x654)
    2. Else if core revision is 5
      1. Call PCIe Clock Request with 1, 0 as arguments

u8 PCIe Clock Request (u32 mask, u32 val)

  1. Set offset to pciecap_lcreg_offset

  2. If offset is zero
    1. Return
  3. If maks is not zero
    1. If val is zero
      1. Set bit 0x100 at the PCI Configuration register at offset
    2. Otherwise
      1. Clear bit 0x100 at the PCI Configuration register at offset
  4. Read the PCI Configuration register at offset
  5. If bit 0x100 is set in the result
    1. Return 1
  6. Return 0

PCI Setup Workaround

  1. If the Core Revision is 0 or 1
    1. Set bit 8 in the TLP Workaround register
  2. If the core revision is 1
    1. Set bit 0x40 in the DLLP Link Control register
  3. If the core revision is 0
    1. Write 0x8128 to the SERDES RX Timer
    2. Write 0x0100 to the SERDES RX CDR
    3. Write 0x1466 to the SERDES RX CDR BW
  4. Else if the core revision 3, 4 or 5 and this is a PCIe bus
    1. Maskset the DLLP Power Management Threshold with mask 0x00FF and set with 0x7200
    2. Do the PCI-E SERDES Workaround
    3. Do the PCI-E ASPM Clock Request Workaround
  5. Else if the core revision is 7
    1. Do the PCIe No PLL Down Workaround
  6. If the core revision >= 6

    1. Do the PCIe Miscellaneous Config Fixup

PCIe No PLL Down Workaround

  1. If the core revision is not 7
    1. Return
  2. Set bit 0x800000 in the Chip Control Register (0x28)
  3. Get the address at sprom[6]
  4. Write 0 to that address

PCIe Extend L1 Timer (bool long)

  1. If not a PCI-E core
    1. Exit
  2. If the core revision is not 7 and not 8
    1. Exit
  3. If long is TRUE
    1. Set bit 0x01000000 in the PCI-E DLP Power Management Threshold Register
  4. Otherwise
    1. Clear bit 0x01000000 in the PCI-E DLP Power Management Threshold Register
  5. Do dummy read of the PCI-E DLP Power Management Threshold Register

PCIe Miscellaneous Configuration Fixup

  1. Read sprom[5] to get a register offset
  2. Set bit 0x8000 in that address (for BCM4312, the address is 0x280A)

Exported/Archived from the wiki to HTML on 2016-10-27