1414#include <linux/irqchip/chained_irq.h>
1515#include <linux/irqchip/irq-msi-lib.h>
1616#include <linux/irqdomain.h>
17+ #include <linux/kdebug.h>
1718#include <linux/kernel.h>
1819#include <linux/list.h>
1920#include <linux/log2.h>
2021#include <linux/module.h>
2122#include <linux/msi.h>
23+ #include <linux/notifier.h>
2224#include <linux/of_address.h>
2325#include <linux/of_irq.h>
2426#include <linux/of_pci.h>
2527#include <linux/of_platform.h>
28+ #include <linux/panic_notifier.h>
2629#include <linux/pci.h>
2730#include <linux/pci-ecam.h>
2831#include <linux/printk.h>
2932#include <linux/regulator/consumer.h>
3033#include <linux/reset.h>
3134#include <linux/sizes.h>
3235#include <linux/slab.h>
36+ #include <linux/spinlock.h>
3337#include <linux/string.h>
38+ #include <linux/string_choices.h>
3439#include <linux/types.h>
3540
3641#include "../pci.h"
4853
4954#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc
5055#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_MAX_LINK_WIDTH_MASK 0x1f0
51- #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00
5256
5357#define PCIE_RC_CFG_PRIV1_ROOT_CAP 0x4f8
5458#define PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK 0xf8
155159#define MSI_INT_MASK_SET 0x10
156160#define MSI_INT_MASK_CLR 0x14
157161
162+ /* Error report registers */
163+ #define PCIE_OUTB_ERR_TREAT 0x6000
164+ #define PCIE_OUTB_ERR_TREAT_CONFIG 0x1
165+ #define PCIE_OUTB_ERR_TREAT_MEM 0x2
166+ #define PCIE_OUTB_ERR_VALID 0x6004
167+ #define PCIE_OUTB_ERR_CLEAR 0x6008
168+ #define PCIE_OUTB_ERR_ACC_INFO 0x600c
169+ #define PCIE_OUTB_ERR_ACC_INFO_CFG_ERR BIT(0)
170+ #define PCIE_OUTB_ERR_ACC_INFO_MEM_ERR BIT(1)
171+ #define PCIE_OUTB_ERR_ACC_INFO_TYPE_64 BIT(2)
172+ #define PCIE_OUTB_ERR_ACC_INFO_DIR_WRITE BIT(4)
173+ #define PCIE_OUTB_ERR_ACC_INFO_BYTE_LANES 0xff00
174+ #define PCIE_OUTB_ERR_ACC_ADDR 0x6010
175+ #define PCIE_OUTB_ERR_ACC_ADDR_BUS 0xff00000
176+ #define PCIE_OUTB_ERR_ACC_ADDR_DEV 0xf8000
177+ #define PCIE_OUTB_ERR_ACC_ADDR_FUNC 0x7000
178+ #define PCIE_OUTB_ERR_ACC_ADDR_REG 0xfff
179+ #define PCIE_OUTB_ERR_CFG_CAUSE 0x6014
180+ #define PCIE_OUTB_ERR_CFG_CAUSE_TIMEOUT BIT(6)
181+ #define PCIE_OUTB_ERR_CFG_CAUSE_ABORT BIT(5)
182+ #define PCIE_OUTB_ERR_CFG_CAUSE_UNSUPP_REQ BIT(4)
183+ #define PCIE_OUTB_ERR_CFG_CAUSE_ACC_TIMEOUT BIT(2)
184+ #define PCIE_OUTB_ERR_CFG_CAUSE_ACC_DISABLED BIT(1)
185+ #define PCIE_OUTB_ERR_CFG_CAUSE_ACC_64BIT BIT(0)
186+ #define PCIE_OUTB_ERR_MEM_ADDR_LO 0x6018
187+ #define PCIE_OUTB_ERR_MEM_ADDR_HI 0x601c
188+ #define PCIE_OUTB_ERR_MEM_CAUSE 0x6020
189+ #define PCIE_OUTB_ERR_MEM_CAUSE_TIMEOUT BIT(6)
190+ #define PCIE_OUTB_ERR_MEM_CAUSE_ABORT BIT(5)
191+ #define PCIE_OUTB_ERR_MEM_CAUSE_UNSUPP_REQ BIT(4)
192+ #define PCIE_OUTB_ERR_MEM_CAUSE_ACC_DISABLED BIT(1)
193+ #define PCIE_OUTB_ERR_MEM_CAUSE_BAD_ADDR BIT(0)
194+
158195#define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1
159- #define PCIE_RGR1_SW_INIT_1_PERST_SHIFT 0x0
160196
161197#define RGR1_SW_INIT_1_INIT_GENERIC_MASK 0x2
162198#define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT 0x1
@@ -259,6 +295,7 @@ struct pcie_cfg_data {
259295 int (* perst_set )(struct brcm_pcie * pcie , u32 val );
260296 int (* bridge_sw_init_set )(struct brcm_pcie * pcie , u32 val );
261297 int (* post_setup )(struct brcm_pcie * pcie );
298+ bool has_err_report ;
262299};
263300
264301struct subdev_regulators {
@@ -303,13 +340,35 @@ struct brcm_pcie {
303340 struct subdev_regulators * sr ;
304341 bool ep_wakeup_capable ;
305342 const struct pcie_cfg_data * cfg ;
343+ bool bridge_in_reset ;
344+ struct notifier_block die_notifier ;
345+ struct notifier_block panic_notifier ;
346+ spinlock_t bridge_lock ;
306347};
307348
308349static inline bool is_bmips (const struct brcm_pcie * pcie )
309350{
310351 return pcie -> cfg -> soc_base == BCM7435 || pcie -> cfg -> soc_base == BCM7425 ;
311352}
312353
354+ static int brcm_pcie_bridge_sw_init_set (struct brcm_pcie * pcie , u32 val )
355+ {
356+ unsigned long flags ;
357+ int ret ;
358+
359+ if (pcie -> cfg -> has_err_report )
360+ spin_lock_irqsave (& pcie -> bridge_lock , flags );
361+
362+ ret = pcie -> cfg -> bridge_sw_init_set (pcie , val );
363+ /* If we fail, assume the bridge is in reset (off) */
364+ pcie -> bridge_in_reset = ret ? true : val ;
365+
366+ if (pcie -> cfg -> has_err_report )
367+ spin_unlock_irqrestore (& pcie -> bridge_lock , flags );
368+
369+ return ret ;
370+ }
371+
313372/*
314373 * This is to convert the size of the inbound "BAR" region to the
315374 * non-linear values of PCIE_X_MISC_RC_BAR[123]_CONFIG_LO.SIZE
@@ -1075,13 +1134,13 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
10751134 void __iomem * base = pcie -> base ;
10761135 struct pci_host_bridge * bridge ;
10771136 struct resource_entry * entry ;
1078- u32 tmp , burst , aspm_support , num_lanes , num_lanes_cap ;
1137+ u32 tmp , burst , num_lanes , num_lanes_cap ;
10791138 u8 num_out_wins = 0 ;
10801139 int num_inbound_wins = 0 ;
10811140 int memc , ret ;
10821141
10831142 /* Reset the bridge */
1084- ret = pcie -> cfg -> bridge_sw_init_set (pcie , 1 );
1143+ ret = brcm_pcie_bridge_sw_init_set (pcie , 1 );
10851144 if (ret )
10861145 return ret ;
10871146
@@ -1097,7 +1156,7 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
10971156 usleep_range (100 , 200 );
10981157
10991158 /* Take the bridge out of reset */
1100- ret = pcie -> cfg -> bridge_sw_init_set (pcie , 0 );
1159+ ret = brcm_pcie_bridge_sw_init_set (pcie , 0 );
11011160 if (ret )
11021161 return ret ;
11031162
@@ -1175,12 +1234,9 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
11751234
11761235
11771236 /* Don't advertise L0s capability if 'aspm-no-l0s' */
1178- aspm_support = PCIE_LINK_STATE_L1 ;
1179- if (!of_property_read_bool (pcie -> np , "aspm-no-l0s" ))
1180- aspm_support |= PCIE_LINK_STATE_L0S ;
11811237 tmp = readl (base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY );
1182- u32p_replace_bits ( & tmp , aspm_support ,
1183- PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK ) ;
1238+ if ( of_property_read_bool ( pcie -> np , "aspm-no-l0s" ))
1239+ tmp &= ~ PCI_EXP_LNKCAP_ASPM_L0S ;
11841240 writel (tmp , base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY );
11851241
11861242 /* 'tmp' still holds the contents of PRIV1_LINK_CAPABILITY */
@@ -1565,7 +1621,7 @@ static int brcm_pcie_turn_off(struct brcm_pcie *pcie)
15651621
15661622 if (!(pcie -> cfg -> quirks & CFG_QUIRK_AVOID_BRIDGE_SHUTDOWN ))
15671623 /* Shutdown PCIe bridge */
1568- ret = pcie -> cfg -> bridge_sw_init_set (pcie , 1 );
1624+ ret = brcm_pcie_bridge_sw_init_set (pcie , 1 );
15691625
15701626 return ret ;
15711627}
@@ -1653,7 +1709,9 @@ static int brcm_pcie_resume_noirq(struct device *dev)
16531709 goto err_reset ;
16541710
16551711 /* Take bridge out of reset so we can access the SERDES reg */
1656- pcie -> cfg -> bridge_sw_init_set (pcie , 0 );
1712+ ret = brcm_pcie_bridge_sw_init_set (pcie , 0 );
1713+ if (ret )
1714+ goto err_reset ;
16571715
16581716 /* SERDES_IDDQ = 0 */
16591717 tmp = readl (base + HARD_DEBUG (pcie ));
@@ -1707,6 +1765,119 @@ static int brcm_pcie_resume_noirq(struct device *dev)
17071765 return ret ;
17081766}
17091767
1768+ /* Dump out PCIe errors on die or panic */
1769+ static int brcm_pcie_dump_err (struct brcm_pcie * pcie ,
1770+ const char * type )
1771+ {
1772+ void __iomem * base = pcie -> base ;
1773+ int i , is_cfg_err , is_mem_err , lanes ;
1774+ const char * width_str , * direction_str ;
1775+ u32 info , cfg_addr , cfg_cause , mem_cause , lo , hi ;
1776+ struct pci_host_bridge * bridge = pci_host_bridge_from_priv (pcie );
1777+ unsigned long flags ;
1778+ char lanes_str [9 ];
1779+
1780+ spin_lock_irqsave (& pcie -> bridge_lock , flags );
1781+ /* Don't access registers when the bridge is off */
1782+ if (pcie -> bridge_in_reset || readl (base + PCIE_OUTB_ERR_VALID ) == 0 ) {
1783+ spin_unlock_irqrestore (& pcie -> bridge_lock , flags );
1784+ return NOTIFY_DONE ;
1785+ }
1786+
1787+ /* Read all necessary registers so we can release the spinlock ASAP */
1788+ info = readl (base + PCIE_OUTB_ERR_ACC_INFO );
1789+ is_cfg_err = !!(info & PCIE_OUTB_ERR_ACC_INFO_CFG_ERR );
1790+ is_mem_err = !!(info & PCIE_OUTB_ERR_ACC_INFO_MEM_ERR );
1791+ if (is_cfg_err ) {
1792+ cfg_addr = readl (base + PCIE_OUTB_ERR_ACC_ADDR );
1793+ cfg_cause = readl (base + PCIE_OUTB_ERR_CFG_CAUSE );
1794+ }
1795+ if (is_mem_err ) {
1796+ mem_cause = readl (base + PCIE_OUTB_ERR_MEM_CAUSE );
1797+ lo = readl (base + PCIE_OUTB_ERR_MEM_ADDR_LO );
1798+ hi = readl (base + PCIE_OUTB_ERR_MEM_ADDR_HI );
1799+ }
1800+ /* We've got all of the info, clear the error */
1801+ writel (1 , base + PCIE_OUTB_ERR_CLEAR );
1802+ spin_unlock_irqrestore (& pcie -> bridge_lock , flags );
1803+
1804+ dev_err (pcie -> dev , "reporting PCIe info which may be related to %s error\n" ,
1805+ type );
1806+ width_str = (info & PCIE_OUTB_ERR_ACC_INFO_TYPE_64 ) ? "64bit" : "32bit" ;
1807+ direction_str = str_read_write (!(info & PCIE_OUTB_ERR_ACC_INFO_DIR_WRITE ));
1808+ lanes = FIELD_GET (PCIE_OUTB_ERR_ACC_INFO_BYTE_LANES , info );
1809+ for (i = 0 , lanes_str [8 ] = 0 ; i < 8 ; i ++ )
1810+ lanes_str [i ] = (lanes & (1 << i )) ? '1' : '0' ;
1811+
1812+ if (is_cfg_err ) {
1813+ int bus = FIELD_GET (PCIE_OUTB_ERR_ACC_ADDR_BUS , cfg_addr );
1814+ int dev = FIELD_GET (PCIE_OUTB_ERR_ACC_ADDR_DEV , cfg_addr );
1815+ int func = FIELD_GET (PCIE_OUTB_ERR_ACC_ADDR_FUNC , cfg_addr );
1816+ int reg = FIELD_GET (PCIE_OUTB_ERR_ACC_ADDR_REG , cfg_addr );
1817+
1818+ dev_err (pcie -> dev , "Error: CFG Acc, %s, %s (%04x:%02x:%02x.%d) reg=0x%x, lanes=%s\n" ,
1819+ width_str , direction_str , bridge -> domain_nr , bus , dev ,
1820+ func , reg , lanes_str );
1821+ dev_err (pcie -> dev , " Type: TO=%d Abt=%d UnsupReq=%d AccTO=%d AccDsbld=%d Acc64bit=%d\n" ,
1822+ !!(cfg_cause & PCIE_OUTB_ERR_CFG_CAUSE_TIMEOUT ),
1823+ !!(cfg_cause & PCIE_OUTB_ERR_CFG_CAUSE_ABORT ),
1824+ !!(cfg_cause & PCIE_OUTB_ERR_CFG_CAUSE_UNSUPP_REQ ),
1825+ !!(cfg_cause & PCIE_OUTB_ERR_CFG_CAUSE_ACC_TIMEOUT ),
1826+ !!(cfg_cause & PCIE_OUTB_ERR_CFG_CAUSE_ACC_DISABLED ),
1827+ !!(cfg_cause & PCIE_OUTB_ERR_CFG_CAUSE_ACC_64BIT ));
1828+ }
1829+
1830+ if (is_mem_err ) {
1831+ u64 addr = ((u64 )hi << 32 ) | (u64 )lo ;
1832+
1833+ dev_err (pcie -> dev , "Error: Mem Acc, %s, %s, @0x%llx, lanes=%s\n" ,
1834+ width_str , direction_str , addr , lanes_str );
1835+ dev_err (pcie -> dev , " Type: TO=%d Abt=%d UnsupReq=%d AccDsble=%d BadAddr=%d\n" ,
1836+ !!(mem_cause & PCIE_OUTB_ERR_MEM_CAUSE_TIMEOUT ),
1837+ !!(mem_cause & PCIE_OUTB_ERR_MEM_CAUSE_ABORT ),
1838+ !!(mem_cause & PCIE_OUTB_ERR_MEM_CAUSE_UNSUPP_REQ ),
1839+ !!(mem_cause & PCIE_OUTB_ERR_MEM_CAUSE_ACC_DISABLED ),
1840+ !!(mem_cause & PCIE_OUTB_ERR_MEM_CAUSE_BAD_ADDR ));
1841+ }
1842+
1843+ return NOTIFY_DONE ;
1844+ }
1845+
1846+ static int brcm_pcie_die_notify_cb (struct notifier_block * self ,
1847+ unsigned long v , void * p )
1848+ {
1849+ struct brcm_pcie * pcie =
1850+ container_of (self , struct brcm_pcie , die_notifier );
1851+
1852+ return brcm_pcie_dump_err (pcie , "Die" );
1853+ }
1854+
1855+ static int brcm_pcie_panic_notify_cb (struct notifier_block * self ,
1856+ unsigned long v , void * p )
1857+ {
1858+ struct brcm_pcie * pcie =
1859+ container_of (self , struct brcm_pcie , panic_notifier );
1860+
1861+ return brcm_pcie_dump_err (pcie , "Panic" );
1862+ }
1863+
1864+ static void brcm_register_die_notifiers (struct brcm_pcie * pcie )
1865+ {
1866+ pcie -> panic_notifier .notifier_call = brcm_pcie_panic_notify_cb ;
1867+ atomic_notifier_chain_register (& panic_notifier_list ,
1868+ & pcie -> panic_notifier );
1869+
1870+ pcie -> die_notifier .notifier_call = brcm_pcie_die_notify_cb ;
1871+ register_die_notifier (& pcie -> die_notifier );
1872+ }
1873+
1874+ static void brcm_unregister_die_notifiers (struct brcm_pcie * pcie )
1875+ {
1876+ unregister_die_notifier (& pcie -> die_notifier );
1877+ atomic_notifier_chain_unregister (& panic_notifier_list ,
1878+ & pcie -> panic_notifier );
1879+ }
1880+
17101881static void __brcm_pcie_remove (struct brcm_pcie * pcie )
17111882{
17121883 brcm_msi_remove (pcie );
@@ -1725,6 +1896,9 @@ static void brcm_pcie_remove(struct platform_device *pdev)
17251896
17261897 pci_stop_root_bus (bridge -> bus );
17271898 pci_remove_root_bus (bridge -> bus );
1899+ if (pcie -> cfg -> has_err_report )
1900+ brcm_unregister_die_notifiers (pcie );
1901+
17281902 __brcm_pcie_remove (pcie );
17291903}
17301904
@@ -1825,6 +1999,7 @@ static const struct pcie_cfg_data bcm7216_cfg = {
18251999 .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_7278 ,
18262000 .has_phy = true,
18272001 .num_inbound_wins = 3 ,
2002+ .has_err_report = true,
18282003};
18292004
18302005static const struct pcie_cfg_data bcm7712_cfg = {
@@ -1921,7 +2096,10 @@ static int brcm_pcie_probe(struct platform_device *pdev)
19212096 if (ret )
19222097 return dev_err_probe (& pdev -> dev , ret , "could not enable clock\n" );
19232098
1924- pcie -> cfg -> bridge_sw_init_set (pcie , 0 );
2099+ ret = brcm_pcie_bridge_sw_init_set (pcie , 0 );
2100+ if (ret )
2101+ return dev_err_probe (& pdev -> dev , ret ,
2102+ "could not de-assert bridge reset\n" );
19252103
19262104 if (pcie -> swinit_reset ) {
19272105 ret = reset_control_assert (pcie -> swinit_reset );
@@ -1996,6 +2174,11 @@ static int brcm_pcie_probe(struct platform_device *pdev)
19962174 return ret ;
19972175 }
19982176
2177+ if (pcie -> cfg -> has_err_report ) {
2178+ spin_lock_init (& pcie -> bridge_lock );
2179+ brcm_register_die_notifiers (pcie );
2180+ }
2181+
19992182 return 0 ;
20002183
20012184fail :
0 commit comments