From f8da22c0f81995de80f1f31f96e8748bb4f96ece Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 28 Dec 2015 13:55:13 +0100 Subject: [PATCH] updates Signed-off-by: Russell King --- arch/arm/boot/dts/armada-388-clearfog.dts | 36 +++++----- drivers/pci/host/pci-mvebu.c | 109 ++++++++++++++++++++++++++++-- drivers/pci/pcie/aspm.c | 2 + drivers/pci/pcie/portdrv_core.c | 2 + 4 files changed, 126 insertions(+), 23 deletions(-) diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts index db52a8e..df8557c 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dts +++ b/arch/arm/boot/dts/armada-388-clearfog.dts @@ -479,13 +479,13 @@ }; /* -+#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x10460011 -MPP18: gpio ? -MPP19: gpio ? -MPP20: ua1:txd ? ++#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x00400011 +MPP18: gpio ? (pca9655 int?) +MPP19: gpio ? (clkreq?) +MPP20: gpio ? (sd0 detect) MPP21: sd0:cmd x sd0 MPP22: gpio x mikro int -MPP23: spi0:sck ? +MPP23: gpio x switch irq +#define A38x_CUSTOMER_BOARD_1_MPP24_31 0x22043333 MPP24: ua1:rxd x mikro rx MPP25: ua1:txd x mikro tx @@ -493,15 +493,15 @@ MPP26: i2c1:sck x mikro sck MPP27: i2c1:sda x mikro sda MPP28: sd0:clk x sd0 MPP29: gpio x mikro rst -MPP30: ge1:txd2 -MPP31: ge1:txd3 +MPP30: ge1:txd2 ? (config) +MPP31: ge1:txd3 ? (config) +#define A38x_CUSTOMER_BOARD_1_MPP32_39 0x44400002 -MPP32: ge1:txctl -MPP33: gpio ? -MPP34: gpio x rear button -MPP35: gpio ? -MPP36: gpio ? -MPP37: sd0:d3 ?? +MPP32: ge1:txctl ? (unused) +MPP33: gpio ? (pic_com0) +MPP34: gpio x rear button (pic_com1) +MPP35: gpio ? (pic_com2) +MPP36: gpio ? (unused) +MPP37: sd0:d3 x sd0 MPP38: sd0:d0 x sd0 MPP39: sd0:d1 x sd0 +#define A38x_CUSTOMER_BOARD_1_MPP40_47 0x41144004 @@ -509,18 +509,18 @@ MPP40: sd0:d2 x sd0 MPP41: gpio x switch reset MPP42: gpio ? sw1-1 MPP43: spi1:cs2 x mikro cs -MPP44: sata3:prsnt +MPP44: sata3:prsnt ? (unused) MPP45: ref:clk_out0 ? -MPP46: ref:clk_out1 ? -MPP47: 4 ?? -+#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x45333333 +MPP46: ref:clk_out1 x switch clk +MPP47: 4 ? (unused) ++#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x40333333 MPP48: tdm:pclk MPP49: tdm:fsync MPP50: tdm:drx MPP51: tdm:dtx MPP52: tdm:int MPP53: tdm:rst -MPP54: sd0:d3 ?? +MPP54: gpio ? (pwm) MPP55: spi1:cs1 x slic +#define A38x_CUSTOMER_BOARD_1_MPP56_63 0x00004444 MPP56: spi1:mosi x mikro mosi diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 53b79c5..7980be0 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -51,7 +51,14 @@ PCIE_CONF_ADDR_EN) #define PCIE_CONF_DATA_OFF 0x18fc #define PCIE_MASK_OFF 0x1910 +#define PCIE_MASK_PM_PME BIT(28) #define PCIE_MASK_ENABLE_INTS 0x0f000000 +#define PCIE_MASK_ERR_COR BIT(18) +#define PCIE_MASK_ERR_NONFATAL BIT(17) +#define PCIE_MASK_ERR_FATAL BIT(16) +#define PCIE_MASK_FERR_DET BIT(10) +#define PCIE_MASK_NFERR_DET BIT(9) +#define PCIE_MASK_CORERR_DET BIT(8) #define PCIE_CTRL_OFF 0x1a00 #define PCIE_CTRL_X1_MODE 0x0001 #define PCIE_STAT_OFF 0x1a04 @@ -455,6 +462,54 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) MVEBU_MBUS_NO_REMAP); } +static void mvebu_pcie_handle_irq_change(struct mvebu_pcie_port *port) +{ + u32 reg, old; + u16 devctl, rtctl; + + /* + * Errors from downstream devices: + * bridge control register SERR: enables reception of errors + * Errors from this device, or received errors: + * command SERR: enables ERR_NONFATAL and ERR_FATAL messages + * => when enabled, these conditions also flag SERR in status register + * devctl CERE: enables ERR_CORR messages + * devctl NFERE: enables ERR_NONFATAL messages + * devctl FERE: enables ERR_FATAL messages + * Enabled messages then have three paths: + * 1. rtctl: enables system error indication + * 2. root error status register updated + * 3. root error command register: forwarding via MSI + */ + old = mvebu_readl(port, PCIE_MASK_OFF); + reg = old & ~(PCIE_MASK_PM_PME | PCIE_MASK_FERR_DET | + PCIE_MASK_NFERR_DET | PCIE_MASK_CORERR_DET | + PCIE_MASK_ERR_COR | PCIE_MASK_ERR_NONFATAL | + PCIE_MASK_ERR_FATAL); + + devctl = port->bridge.pcie_devctl; + if (devctl & PCI_EXP_DEVCTL_FERE) + reg |= PCIE_MASK_FERR_DET | PCIE_MASK_ERR_FATAL; + if (devctl & PCI_EXP_DEVCTL_NFERE) + reg |= PCIE_MASK_NFERR_DET | PCIE_MASK_ERR_NONFATAL; + if (devctl & PCI_EXP_DEVCTL_CERE) + reg |= PCIE_MASK_CORERR_DET | PCIE_MASK_ERR_COR; + if (port->bridge.command & PCI_COMMAND_SERR) + reg |= PCIE_MASK_FERR_DET | PCIE_MASK_NFERR_DET | + PCIE_MASK_ERR_FATAL | PCIE_MASK_ERR_NONFATAL; + + if (!(port->bridge.bridgectrl & PCI_BRIDGE_CTL_SERR)) + reg &= ~(PCIE_MASK_ERR_COR | PCIE_MASK_ERR_NONFATAL | + PCIE_MASK_ERR_FATAL); + + rtctl = port->bridge.pcie_rtctl; + if (rtctl & PCI_EXP_RTCTL_PMEIE) + reg |= PCIE_MASK_PM_PME; + + if (old != reg) + mvebu_writel(port, reg, PCIE_MASK_OFF); +} + /* * Initialize the configuration space of the PCI-to-PCI bridge * associated with the given PCIe interface. @@ -478,6 +533,7 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) /* Add capabilities */ bridge->status = PCI_STATUS_CAP_LIST; + bridge->bridgectrl = PCI_BRIDGE_CTL_SERR; } /* @@ -550,7 +606,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, case PCI_INTERRUPT_LINE: /* LINE PIN MIN_GNT MAX_LAT */ - *value = 0; + *value = bridge->bridgectrl << 16; break; case PCISWCAP_EXP_LIST_ID: @@ -599,6 +655,16 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, *value = mvebu_readl(port, PCIE_RC_RTSTA); break; + case 0x100 ... 0x128: + *value = mvebu_readl(port, where & ~3); + break; + + case 0x100 + PCI_ERR_ROOT_COMMAND: + case 0x100 + PCI_ERR_ROOT_STATUS: + case 0x100 + PCI_ERR_ROOT_ERR_SRC: + *value = 0; + break; + /* PCIe requires the v2 fields to be hard-wired to zero */ case PCISWCAP_EXP_DEVCAP2: case PCISWCAP_EXP_DEVCTL2: @@ -629,7 +695,7 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, unsigned int where, int size, u32 value) { struct mvebu_sw_pci_bridge *bridge = &port->bridge; - u32 mask, reg; + u32 mask, reg, old; int err; if (size == 4) @@ -649,8 +715,7 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, switch (where & ~3) { case PCI_COMMAND: - { - u32 old = bridge->command; + old = bridge->command; if (!mvebu_has_ioport(port)) value &= ~PCI_COMMAND_IO; @@ -660,8 +725,9 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, mvebu_pcie_handle_iobase_change(port); if ((old ^ bridge->command) & PCI_COMMAND_MEMORY) mvebu_pcie_handle_membase_change(port); + if ((old ^ bridge->command) & PCI_COMMAND_SERR) + mvebu_pcie_handle_irq_change(port); break; - } case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1: bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4] = value; @@ -690,6 +756,17 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, mvebu_pcie_handle_iobase_change(port); break; + case PCI_INTERRUPT_LINE: + value >>= 16; + old = bridge->bridgectrl; + /* PCIe only has three bits here */ + bridge->bridgectrl = value & (PCI_BRIDGE_CTL_BUS_RESET | + PCI_BRIDGE_CTL_SERR | + PCI_BRIDGE_CTL_PARITY); + if ((old ^ bridge->bridgectrl) & PCI_BRIDGE_CTL_SERR) + mvebu_pcie_handle_irq_change(port); + break; + case PCI_PRIMARY_BUS: bridge->primary_bus = value & 0xff; bridge->secondary_bus = (value >> 8) & 0xff; @@ -699,6 +776,14 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, break; case PCISWCAP_EXP_DEVCTL: + old = bridge->pcie_devctl; + bridge->pcie_devctl = value & (PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_URRE); + if (bridge->pcie_devctl ^ old) + mvebu_pcie_handle_irq_change(port); + /* * Armada370 data says these bits must always * be zero when in root complex mode. @@ -739,10 +824,24 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, mvebu_writel(port, value, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); break; + case PCISWCAP_EXP_RTCTL: + old = bridge->pcie_rtctl; + bridge->pcie_rtctl = value & (PCI_EXP_RTCTL_SECEE | + PCI_EXP_RTCTL_SENFEE | + PCI_EXP_RTCTL_SEFEE | + PCI_EXP_RTCTL_PMEIE); + if (bridge->pcie_rtctl ^ old) + mvebu_pcie_handle_irq_change(port); + break; + case PCISWCAP_EXP_RTSTA: mvebu_writel(port, value, PCIE_RC_RTSTA); break; + case 0x100 ... 0x128: + mvebu_writel(port, value, where & ~3); + break; + default: break; } diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 317e355..f1de057 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -356,8 +356,10 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) /* Get upstream/downstream components' register state */ pcie_get_aspm_reg(parent, &upreg); +dev_info(&parent->dev, "up support %x enabled %x\n", upreg.support, upreg.enabled); child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); pcie_get_aspm_reg(child, &dwreg); +dev_info(&parent->dev, "dn support %x enabled %x\n", dwreg.support, dwreg.enabled); /* * Setup L0s state diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 88122dc..bd14993 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -372,6 +372,7 @@ int pcie_port_device_register(struct pci_dev *dev) /* Get and check PCI Express port services */ capabilities = get_port_device_capability(dev); +dev_info(&dev->dev, "PCIe capabilities: 0x%x\n", capabilities); if (!capabilities) return 0; @@ -384,6 +385,7 @@ int pcie_port_device_register(struct pci_dev *dev) * if that is to be used. */ status = init_service_irqs(dev, irqs, capabilities); +dev_info(&dev->dev, "init_service_irqs: %d\n", status); if (status) { capabilities &= PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_HP; if (!capabilities) -- 1.9.1