1818
1919#include "pcie-designware.h"
2020
21+ #define PEX_PF0_CONFIG 0xC0014
22+ #define PEX_PF0_CFG_READY BIT(0)
23+
24+ /* PEX PFa PCIE PME and message interrupt registers*/
25+ #define PEX_PF0_PME_MES_DR 0xC0020
26+ #define PEX_PF0_PME_MES_DR_LUD BIT(7)
27+ #define PEX_PF0_PME_MES_DR_LDD BIT(9)
28+ #define PEX_PF0_PME_MES_DR_HRD BIT(10)
29+
30+ #define PEX_PF0_PME_MES_IER 0xC0028
31+ #define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
32+ #define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
33+ #define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
34+
2135#define to_ls_pcie_ep (x ) dev_get_drvdata((x)->dev)
2236
2337struct ls_pcie_ep_drvdata {
@@ -30,8 +44,84 @@ struct ls_pcie_ep {
3044 struct dw_pcie * pci ;
3145 struct pci_epc_features * ls_epc ;
3246 const struct ls_pcie_ep_drvdata * drvdata ;
47+ int irq ;
48+ bool big_endian ;
3349};
3450
51+ static u32 ls_lut_readl (struct ls_pcie_ep * pcie , u32 offset )
52+ {
53+ struct dw_pcie * pci = pcie -> pci ;
54+
55+ if (pcie -> big_endian )
56+ return ioread32be (pci -> dbi_base + offset );
57+ else
58+ return ioread32 (pci -> dbi_base + offset );
59+ }
60+
61+ static void ls_lut_writel (struct ls_pcie_ep * pcie , u32 offset , u32 value )
62+ {
63+ struct dw_pcie * pci = pcie -> pci ;
64+
65+ if (pcie -> big_endian )
66+ iowrite32be (value , pci -> dbi_base + offset );
67+ else
68+ iowrite32 (value , pci -> dbi_base + offset );
69+ }
70+
71+ static irqreturn_t ls_pcie_ep_event_handler (int irq , void * dev_id )
72+ {
73+ struct ls_pcie_ep * pcie = dev_id ;
74+ struct dw_pcie * pci = pcie -> pci ;
75+ u32 val , cfg ;
76+
77+ val = ls_lut_readl (pcie , PEX_PF0_PME_MES_DR );
78+ ls_lut_writel (pcie , PEX_PF0_PME_MES_DR , val );
79+
80+ if (!val )
81+ return IRQ_NONE ;
82+
83+ if (val & PEX_PF0_PME_MES_DR_LUD ) {
84+ cfg = ls_lut_readl (pcie , PEX_PF0_CONFIG );
85+ cfg |= PEX_PF0_CFG_READY ;
86+ ls_lut_writel (pcie , PEX_PF0_CONFIG , cfg );
87+ dw_pcie_ep_linkup (& pci -> ep );
88+
89+ dev_dbg (pci -> dev , "Link up\n" );
90+ } else if (val & PEX_PF0_PME_MES_DR_LDD ) {
91+ dev_dbg (pci -> dev , "Link down\n" );
92+ } else if (val & PEX_PF0_PME_MES_DR_HRD ) {
93+ dev_dbg (pci -> dev , "Hot reset\n" );
94+ }
95+
96+ return IRQ_HANDLED ;
97+ }
98+
99+ static int ls_pcie_ep_interrupt_init (struct ls_pcie_ep * pcie ,
100+ struct platform_device * pdev )
101+ {
102+ u32 val ;
103+ int ret ;
104+
105+ pcie -> irq = platform_get_irq_byname (pdev , "pme" );
106+ if (pcie -> irq < 0 )
107+ return pcie -> irq ;
108+
109+ ret = devm_request_irq (& pdev -> dev , pcie -> irq , ls_pcie_ep_event_handler ,
110+ IRQF_SHARED , pdev -> name , pcie );
111+ if (ret ) {
112+ dev_err (& pdev -> dev , "Can't register PCIe IRQ\n" );
113+ return ret ;
114+ }
115+
116+ /* Enable interrupts */
117+ val = ls_lut_readl (pcie , PEX_PF0_PME_MES_IER );
118+ val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
119+ PEX_PF0_PME_MES_IER_LUDIE ;
120+ ls_lut_writel (pcie , PEX_PF0_PME_MES_IER , val );
121+
122+ return 0 ;
123+ }
124+
35125static const struct pci_epc_features *
36126ls_pcie_ep_get_features (struct dw_pcie_ep * ep )
37127{
@@ -125,6 +215,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
125215 struct ls_pcie_ep * pcie ;
126216 struct pci_epc_features * ls_epc ;
127217 struct resource * dbi_base ;
218+ int ret ;
128219
129220 pcie = devm_kzalloc (dev , sizeof (* pcie ), GFP_KERNEL );
130221 if (!pcie )
@@ -144,6 +235,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
144235 pci -> ops = pcie -> drvdata -> dw_pcie_ops ;
145236
146237 ls_epc -> bar_fixed_64bit = (1 << BAR_2 ) | (1 << BAR_4 );
238+ ls_epc -> linkup_notifier = true;
147239
148240 pcie -> pci = pci ;
149241 pcie -> ls_epc = ls_epc ;
@@ -155,9 +247,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
155247
156248 pci -> ep .ops = & ls_pcie_ep_ops ;
157249
250+ pcie -> big_endian = of_property_read_bool (dev -> of_node , "big-endian" );
251+
158252 platform_set_drvdata (pdev , pcie );
159253
160- return dw_pcie_ep_init (& pci -> ep );
254+ ret = dw_pcie_ep_init (& pci -> ep );
255+ if (ret )
256+ return ret ;
257+
258+ return ls_pcie_ep_interrupt_init (pcie , pdev );
161259}
162260
163261static struct platform_driver ls_pcie_ep_driver = {
0 commit comments