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
6 Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
8 drivers/pci/host/pci-rcar-gen2.c | 281 ++++++++++++++++++++++++++++++++++++---
9 1 file changed, 266 insertions(+), 15 deletions(-)
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
16 #include <linux/sizes.h>
17 #include <linux/slab.h>
18 #include <linux/usb/phy.h>
19 +#include <linux/clk.h>
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
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 {
31 unsigned long window_size;
32 + void __iomem *ohci_memdata;
33 + void __iomem *ehci_memdata;
34 +#ifndef MCCILDK_CHANGE_DISABLE
39 + struct usb_phy *phy;
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);
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);
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);
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);
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);
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);
75 + val |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
76 + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
77 + iowrite32(val, reg + PCI_COMMAND);
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);
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);
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);
96 rcar_pci_setup_errirq(priv);
98 @@ -326,6 +338,8 @@ static struct pci_ops rcar_pci_ops = {
99 .write = rcar_pci_write_config,
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)
106 struct resource *cfg_res, *mem_res;
107 @@ -350,6 +364,7 @@ static int rcar_pci_probe(struct platform_device *pdev)
110 priv->mem_res = *mem_res;
111 + keep_priv[pdev->id] = priv;
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)
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;
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);
132 +static int rcar_pci_suspend(struct device *dev)
135 + clk = clk_get(NULL, "ehci");
136 + clk_disable_unprepare(clk);
140 +static int rcar_pci_resume(struct device *dev)
143 + clk = clk_get(NULL, "ehci");
144 + clk_prepare_enable(clk);
148 +static u32 rcar_pci_get_conf(struct rcar_pci_priv *priv, int id, int offset)
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;
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);
163 +static void rcar_pci_set_conf(struct rcar_pci_priv *priv,
164 + int id, int offset, u32 d)
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;
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);
179 +static int rcar_pci_freeze(struct device *dev)
181 + struct rcar_pci_priv *priv = keep_priv[to_platform_device(dev)->id];
183 + clk = clk_get(NULL, "ehci");
184 + clk_disable_unprepare(clk);
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);
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);
211 + pm_runtime_disable(priv->dev);
215 +static int rcar_pci_restore(struct device *dev)
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;
224 + pm_runtime_enable(priv->dev);
225 + pm_runtime_get_sync(priv->dev);
227 + clk = clk_get(NULL, "ehci");
228 + clk_prepare_enable(clk);
230 + clk = clk_get(NULL, "hsusb");
231 + clk_prepare_enable(clk);
233 + usb_phy_set_suspend(priv->phy, 0);
234 + m = ioremap(0xe61501c4, 4);
237 + m = ioremap(0xe615014c, 4);
238 + writel(val & ~(3 << 3), m);
240 + val = ioread32(reg + RCAR_PCI_UNIT_REV_REG);
241 + dev_info(priv->dev, "PCI: bus%u revision %x\n", id, val);
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;
248 + val |= RCAR_USBCTR_USBH_RST;
250 + iowrite32(val, reg + RCAR_USBCTR_REG);
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);
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);
274 + /* Configure AHB master and slave modes */
275 + iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG);
277 + /* PCI-AHB mapping: 0x40000000 base */
278 + iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16,
279 + reg + RCAR_PCIAHB_WIN1_CTR_REG);
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);
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);
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);
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);
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);
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);
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]);
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);
349 + val = RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;
350 + iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
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
364 static struct platform_driver rcar_pci_driver = {
366 .name = "pci-rcar-gen2",
367 .owner = THIS_MODULE,
368 .suppress_bind_attrs = true,
369 + .pm = &rcar_pci_pm_ops,
371 .probe = rcar_pci_probe,