Add kernel Hibernation code for porter board.
[AGL/meta-agl.git] / meta-agl-bsp / meta-renesas / recipes-kernel / linux / linux / hibernation / 0011-Add-rcar-pci-hibernation-code.patch
1 From f8691a62199319d9e37cd451a9b8364aa640c4cb Mon Sep 17 00:00:00 2001
2 From: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
3 Date: Thu, 18 May 2017 17:45:19 +0900
4 Subject: [PATCH 11/15] Add rcar-pci hibernation code
5
6 Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
7 ---
8  drivers/pci/host/pci-rcar-gen2.c | 281 ++++++++++++++++++++++++++++++++++++---
9  1 file changed, 266 insertions(+), 15 deletions(-)
10
11 diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
12 index 57b6572..4cb9693 100644
13 --- a/drivers/pci/host/pci-rcar-gen2.c
14 +++ b/drivers/pci/host/pci-rcar-gen2.c
15 @@ -23,9 +23,12 @@
16  #include <linux/sizes.h>
17  #include <linux/slab.h>
18  #include <linux/usb/phy.h>
19 +#include <linux/clk.h>
20  
21  /* AHB-PCI Bridge PCI communication registers */
22  #define RCAR_AHBPCI_PCICOM_OFFSET      0x800
23 +#define RCAR_PCICONF_OHCI              0x0
24 +#define RCAR_PCICONF_EHCI              0x100
25  
26  #define RCAR_PCIAHB_WIN1_CTR_REG       (RCAR_AHBPCI_PCICOM_OFFSET + 0x00)
27  #define RCAR_PCIAHB_WIN2_CTR_REG       (RCAR_AHBPCI_PCICOM_OFFSET + 0x04)
28 @@ -104,6 +107,14 @@ struct rcar_pci_priv {
29         int domain;
30         int irq;
31         unsigned long window_size;
32 +       void __iomem *ohci_memdata;
33 +       void __iomem *ehci_memdata;
34 +#ifndef        MCCILDK_CHANGE_DISABLE
35 +       u32 store_cfg[12];
36 +#else
37 +       u32 store_cfg[9];
38 +#endif
39 +       struct usb_phy *phy;
40  };
41  
42  /* PCI configuration space operations */
43 @@ -276,12 +287,6 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
44         /* Configure AHB master and slave modes */
45         iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG);
46  
47 -       /* Configure PCI arbiter */
48 -       val = ioread32(reg + RCAR_PCI_ARBITER_CTR_REG);
49 -       val |= RCAR_PCI_ARBITER_PCIREQ0 | RCAR_PCI_ARBITER_PCIREQ1 |
50 -              RCAR_PCI_ARBITER_PCIBP_MODE;
51 -       iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
52 -
53         /* PCI-AHB mapping: 0x40000000 base */
54         iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16,
55                   reg + RCAR_PCIAHB_WIN1_CTR_REG);
56 @@ -290,9 +295,25 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
57         val = priv->mem_res.start | RCAR_AHBPCI_WIN_CTR_MEM;
58         iowrite32(val, reg + RCAR_AHBPCI_WIN2_CTR_REG);
59  
60 +       /* Enable PCI interrupts */
61 +       iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
62 +                 reg + RCAR_PCI_INT_ENABLE_REG);
63 +
64 +       /* Configure PCI arbiter */
65 +       val = ioread32(reg + RCAR_PCI_ARBITER_CTR_REG);
66 +       val |= RCAR_PCI_ARBITER_PCIREQ0 | RCAR_PCI_ARBITER_PCIREQ1 |
67 +              RCAR_PCI_ARBITER_PCIBP_MODE;
68 +       iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
69 +
70         /* Enable AHB-PCI bridge PCI configuration access */
71         iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG,
72                   reg + RCAR_AHBPCI_WIN1_CTR_REG);
73 +       val = ioread32(reg + PCI_COMMAND);
74 +
75 +       val |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
76 +              PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
77 +       iowrite32(val, reg + PCI_COMMAND);
78 +
79         /* Set PCI-AHB Window1 address */
80         iowrite32(0x40000000 | PCI_BASE_ADDRESS_MEM_PREFETCH,
81                   reg + PCI_BASE_ADDRESS_1);
82 @@ -300,15 +321,6 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
83         val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET;
84         iowrite32(val, reg + PCI_BASE_ADDRESS_0);
85  
86 -       val = ioread32(reg + PCI_COMMAND);
87 -       val |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
88 -              PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
89 -       iowrite32(val, reg + PCI_COMMAND);
90 -
91 -       /* Enable PCI interrupts */
92 -       iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
93 -                 reg + RCAR_PCI_INT_ENABLE_REG);
94 -
95         if (priv->irq > 0)
96                 rcar_pci_setup_errirq(priv);
97  
98 @@ -326,6 +338,8 @@ static struct pci_ops rcar_pci_ops = {
99         .write  = rcar_pci_write_config,
100  };
101  
102 +#define RCAR_MAX_PCI_HOSTS     2
103 +static struct rcar_pci_priv *keep_priv[RCAR_MAX_PCI_HOSTS];
104  static int rcar_pci_probe(struct platform_device *pdev)
105  {
106         struct resource *cfg_res, *mem_res;
107 @@ -350,6 +364,7 @@ static int rcar_pci_probe(struct platform_device *pdev)
108                 return -ENOMEM;
109  
110         priv->mem_res = *mem_res;
111 +       keep_priv[pdev->id] = priv;
112         /*
113          * The controller does not support/use port I/O,
114          * so setup a dummy port I/O region here.
115 @@ -378,6 +393,7 @@ static int rcar_pci_probe(struct platform_device *pdev)
116                 return PTR_ERR(phy);
117  
118         usb_phy_init(phy);
119 +       priv->phy = phy;
120  
121         hw_private[0] = priv;
122         memset(&hw, 0, sizeof(hw));
123 @@ -390,14 +406,249 @@ static int rcar_pci_probe(struct platform_device *pdev)
124         hw.domain = priv->domain;
125  #endif
126         pci_common_init_dev(&pdev->dev, &hw);
127 +       priv->ohci_memdata = ioremap(cfg_res->start - 0x10000, 0x1000);
128 +       priv->ehci_memdata = ioremap(cfg_res->start - 0x10000 + 0x1000, 0x1000);
129 +       return 0;
130 +}
131 +
132 +static int rcar_pci_suspend(struct device *dev)
133 +{
134 +       struct clk *clk;
135 +       clk = clk_get(NULL, "ehci");
136 +       clk_disable_unprepare(clk);
137 +       clk_put(clk);
138 +       return 0;
139 +}
140 +static int rcar_pci_resume(struct device *dev)
141 +{
142 +       struct clk *clk;
143 +       clk = clk_get(NULL, "ehci");
144 +       clk_prepare_enable(clk);
145 +       clk_put(clk);
146 +       return 0;
147 +}
148 +static u32 rcar_pci_get_conf(struct rcar_pci_priv *priv, int id, int offset)
149 +{
150 +       u32 val, kpt;
151 +       void __iomem *data;
152 +       kpt = ioread32(priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
153 +       val = id ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG :
154 +                    RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;
155 +
156 +       iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
157 +       data = priv->reg + (id >> 1) * 0x100;
158 +       val = ioread32(data + offset);
159 +       iowrite32(kpt, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
160 +       return val;
161 +}
162 +
163 +static void rcar_pci_set_conf(struct rcar_pci_priv *priv,
164 +               int id, int offset, u32 d)
165 +{
166 +       u32 val, kpt;
167 +       void __iomem *data;
168 +       kpt = ioread32(priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
169 +       val = id ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG :
170 +                    RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;
171 +
172 +       iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
173 +       data = priv->reg + (id >> 1) * 0x100;
174 +       iowrite32(d, data + offset);
175 +       iowrite32(kpt, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
176 +}
177 +
178 +
179 +static int rcar_pci_freeze(struct device *dev)
180 +{
181 +       struct rcar_pci_priv *priv = keep_priv[to_platform_device(dev)->id];
182 +       struct clk *clk;
183 +       clk = clk_get(NULL, "ehci");
184 +       clk_disable_unprepare(clk);
185 +       clk_put(clk);
186 +
187 +#ifndef        MCCILDK_CHANGE_DISABLE
188 +       priv->store_cfg[0] = rcar_pci_get_conf(priv, 0, PCI_COMMAND);
189 +       priv->store_cfg[1] = rcar_pci_get_conf(priv, 1, PCI_COMMAND);
190 +       priv->store_cfg[2] = rcar_pci_get_conf(priv, 2, PCI_COMMAND);
191 +       priv->store_cfg[3] = rcar_pci_get_conf(priv, 0, PCI_CACHE_LINE_SIZE);
192 +       priv->store_cfg[4] = rcar_pci_get_conf(priv, 1, PCI_CACHE_LINE_SIZE);
193 +       priv->store_cfg[5] = rcar_pci_get_conf(priv, 2, PCI_CACHE_LINE_SIZE);
194 +       priv->store_cfg[6] = rcar_pci_get_conf(priv, 0, PCI_INTERRUPT_LINE);
195 +       priv->store_cfg[7] = rcar_pci_get_conf(priv, 1, PCI_INTERRUPT_LINE);
196 +       priv->store_cfg[8] = rcar_pci_get_conf(priv, 2, PCI_INTERRUPT_LINE);
197 +       priv->store_cfg[9] =  rcar_pci_get_conf(priv, 0, PCI_BASE_ADDRESS_0);
198 +       priv->store_cfg[10] = rcar_pci_get_conf(priv, 1, PCI_BASE_ADDRESS_0);
199 +       priv->store_cfg[11] = rcar_pci_get_conf(priv, 2, PCI_BASE_ADDRESS_0);
200 +#else
201 +       priv->store_cfg[0] = rcar_pci_get_conf(priv, 0, 0x04);
202 +       priv->store_cfg[1] = rcar_pci_get_conf(priv, 1, 0x04);
203 +       priv->store_cfg[2] = rcar_pci_get_conf(priv, 2, 0x04);
204 +       priv->store_cfg[3] = rcar_pci_get_conf(priv, 0, 0x0c);
205 +       priv->store_cfg[4] = rcar_pci_get_conf(priv, 1, 0x0c);
206 +       priv->store_cfg[5] = rcar_pci_get_conf(priv, 2, 0x0c);
207 +       priv->store_cfg[6] = rcar_pci_get_conf(priv, 0, 0x3c);
208 +       priv->store_cfg[7] = rcar_pci_get_conf(priv, 1, 0x3c);
209 +       priv->store_cfg[8] = rcar_pci_get_conf(priv, 2, 0x3c);
210 +#endif
211 +       pm_runtime_disable(priv->dev);
212 +       return 0;
213 +}
214 +
215 +static int rcar_pci_restore(struct device *dev)
216 +{
217 +       struct clk *clk;
218 +       void *m;
219 +       u32 val;
220 +       struct rcar_pci_priv *priv = keep_priv[to_platform_device(dev)->id];
221 +       void __iomem *reg = priv->reg;
222 +       int id = to_platform_device(dev)->id;
223 +
224 +       pm_runtime_enable(priv->dev);
225 +       pm_runtime_get_sync(priv->dev);
226 +
227 +       clk = clk_get(NULL, "ehci");
228 +       clk_prepare_enable(clk);
229 +       clk_put(clk);
230 +       clk = clk_get(NULL, "hsusb");
231 +       clk_prepare_enable(clk);
232 +       clk_put(clk);
233 +       usb_phy_set_suspend(priv->phy, 0);
234 +       m = ioremap(0xe61501c4, 4);
235 +       val = readl(m);
236 +       iounmap(m);
237 +       m = ioremap(0xe615014c, 4);
238 +       writel(val & ~(3 << 3), m);
239 +       iounmap(m);
240 +       val = ioread32(reg + RCAR_PCI_UNIT_REV_REG);
241 +       dev_info(priv->dev, "PCI: bus%u revision %x\n", id, val);
242 +
243 +       /* Disable Direct Power Down State and assert reset */
244 +       val = ioread32(reg + RCAR_USBCTR_REG) & ~RCAR_USBCTR_DIRPD;
245 +#ifndef        MCCILDK_CHANGE_DISABLE
246 +       val |= RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST;
247 +#else
248 +       val |= RCAR_USBCTR_USBH_RST;
249 +#endif
250 +       iowrite32(val, reg + RCAR_USBCTR_REG);
251 +       udelay(4);
252 +       /* De-assert reset */
253 +#ifndef        MCCILDK_CHANGE_DISABLE
254 +       val &= ~(RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST
255 +                       | RCAR_USBCTR_PCICLK_MASK);
256 +       iowrite32(val, reg + RCAR_USBCTR_REG);
257 +       /* reset PCIAHB window size */
258 +       val &= ~RCAR_USBCTR_PCIAHB_WIN1_MASK;
259 +       val |= RCAR_USBCTR_PCIAHB_WIN1_1G;
260 +       iowrite32(val, reg + RCAR_USBCTR_REG);
261 +#else
262 +       val &=  RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST
263 +               | RCAR_USBCTR_PCICLK_MASK;
264 +       iowrite32(val, reg + RCAR_USBCTR_REG);
265 +       val &=  RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST
266 +               | RCAR_USBCTR_PCICLK_MASK;
267 +       iowrite32(val, reg + RCAR_USBCTR_REG);
268 +       /* reset PCIAHB window size */
269 +       val &= RCAR_USBCTR_PCIAHB_WIN1_MASK;
270 +       val |= RCAR_USBCTR_PCIAHB_WIN1_1G;
271 +       iowrite32(val, reg + RCAR_USBCTR_REG);
272 +#endif
273 +
274 +       /* Configure AHB master and slave modes */
275 +       iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG);
276 +
277 +       /* PCI-AHB mapping: 0x40000000 base */
278 +       iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16,
279 +                 reg + RCAR_PCIAHB_WIN1_CTR_REG);
280 +
281 +       /* AHB-PCI mapping: OHCI/EHCI registers */
282 +       val = priv->mem_res.start | RCAR_AHBPCI_WIN_CTR_MEM;
283 +       iowrite32(val, reg + RCAR_AHBPCI_WIN2_CTR_REG);
284 +
285 +       /* Enable PCI interrupts */
286 +       iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
287 +                 reg + RCAR_PCI_INT_ENABLE_REG);
288 +
289 +       /* Configure PCI arbiter */
290 +       val = ioread32(reg + RCAR_PCI_ARBITER_CTR_REG);
291 +       val |= RCAR_PCI_ARBITER_PCIREQ0 | RCAR_PCI_ARBITER_PCIREQ1 |
292 +              RCAR_PCI_ARBITER_PCIBP_MODE;
293 +       iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
294 +
295 +       /* Enable AHB-PCI bridge PCI configuration access */
296 +       iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG,
297 +                 reg + RCAR_AHBPCI_WIN1_CTR_REG);
298 +
299 +       val = ioread32(reg + PCI_COMMAND);
300 +       val |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
301 +              PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
302 +       iowrite32(val, reg + PCI_COMMAND);
303 +
304 +       /* Set PCI-AHB Window1 address */
305 +       iowrite32(0x40000000 | PCI_BASE_ADDRESS_MEM_PREFETCH,
306 +                 reg + PCI_BASE_ADDRESS_1);
307 +       /* Set AHB-PCI bridge PCI communication area address */
308 +       val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET;
309 +       iowrite32(val, reg + PCI_BASE_ADDRESS_0);
310 +
311 +       if (priv->irq > 0)
312 +               rcar_pci_setup_errirq(priv);
313 +#ifndef        MCCILDK_CHANGE_DISABLE
314 +       rcar_pci_set_conf(priv, 0, PCI_COMMAND, priv->store_cfg[0]);
315 +       rcar_pci_set_conf(priv, 1, PCI_COMMAND, priv->store_cfg[1]);
316 +       rcar_pci_set_conf(priv, 2, PCI_COMMAND, priv->store_cfg[2]);
317 +       rcar_pci_set_conf(priv, 0, PCI_CACHE_LINE_SIZE, priv->store_cfg[3]);
318 +       rcar_pci_set_conf(priv, 1, PCI_CACHE_LINE_SIZE, priv->store_cfg[4]);
319 +       rcar_pci_set_conf(priv, 2, PCI_CACHE_LINE_SIZE, priv->store_cfg[5]);
320 +       rcar_pci_set_conf(priv, 0, PCI_INTERRUPT_LINE, priv->store_cfg[6]);
321 +       rcar_pci_set_conf(priv, 1, PCI_INTERRUPT_LINE, priv->store_cfg[7]);
322 +       rcar_pci_set_conf(priv, 2, PCI_INTERRUPT_LINE, priv->store_cfg[8]);
323 +       rcar_pci_set_conf(priv, 1, PCI_BASE_ADDRESS_0, priv->store_cfg[10]);
324 +       rcar_pci_set_conf(priv, 2, PCI_BASE_ADDRESS_0, priv->store_cfg[11]);
325 +#else
326 +       rcar_pci_set_conf(priv, 1, PCI_COMMAND, PCI_COMMAND_SERR
327 +                       | PCI_COMMAND_PARITY | PCI_COMMAND_MEMORY
328 +                       | PCI_COMMAND_MASTER);
329 +       rcar_pci_set_conf(priv, 1, PCI_BASE_ADDRESS_0
330 +                       priv->cfg_res->start - 0x10000);
331 +       rcar_pci_set_conf(priv, 2, PCI_COMMAND, PCI_COMMAND_SERR
332 +                       | PCI_COMMAND_PARITY | PCI_COMMAND_MEMORY
333 +                       | PCI_COMMAND_MASTER);
334 +       rcar_pci_set_conf(priv, 2, PCI_BASE_ADDRESS_0,
335 +                       priv->cfg_res->start - 0x10000 + 0x1000);
336 +       rcar_pci_set_conf(priv, 0, PCI_CACHE_LINE_SIZE, priv->store_cfg[3]);
337 +       rcar_pci_set_conf(priv, 1, PCI_CACHE_LINE_SIZE, priv->store_cfg[4]);
338 +       rcar_pci_set_conf(priv, 2, PCI_CACHE_LINE_SIZE, priv->store_cfg[5]);
339 +       rcar_pci_set_conf(priv, 0, PCI_INTERRUPT_LINE, 0x00020100);
340 +       rcar_pci_set_conf(priv, 1, PCI_INTERRUPT_LINE, 0x2a010100);
341 +       rcar_pci_set_conf(priv, 2, PCI_INTERRUPT_LINE, 0x22100200);
342 +       val = RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG;
343 +       iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
344 +       val = ioread32(priv->reg + 0x04);
345 +       iowrite32(val | (1 << 1), priv->reg + 0x04);
346 +       val = ioread32(priv->reg + 0x104);
347 +       iowrite32(val | (1 << 1), priv->reg + 0x104);
348 +
349 +       val = RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;
350 +       iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
351 +#endif
352         return 0;
353  }
354  
355 +static const struct dev_pm_ops rcar_pci_pm_ops = {
356 +       .suspend        = rcar_pci_suspend,
357 +       .resume         = rcar_pci_resume,
358 +       .freeze_noirq   = rcar_pci_freeze,
359 +       .restore_noirq  = rcar_pci_restore,
360 +       .thaw           = rcar_pci_resume,
361 +       .poweroff       = rcar_pci_suspend
362 +};
363 +
364  static struct platform_driver rcar_pci_driver = {
365         .driver = {
366                 .name = "pci-rcar-gen2",
367                 .owner = THIS_MODULE,
368                 .suppress_bind_attrs = true,
369 +               .pm = &rcar_pci_pm_ops,
370         },
371         .probe = rcar_pci_probe,
372  };
373 -- 
374 1.8.3.1
375