1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * MPC83xx suspend support 4 * 5 * Author: Scott Wood <scottwood@freescale.com> 6 * 7 * Copyright (c) 2006-2007 Freescale Semiconductor, Inc. 8 */ 9 10 #include <linux/pm.h> 11 #include <linux/types.h> 12 #include <linux/ioport.h> 13 #include <linux/interrupt.h> 14 #include <linux/wait.h> 15 #include <linux/sched/signal.h> 16 #include <linux/kthread.h> 17 #include <linux/freezer.h> 18 #include <linux/suspend.h> 19 #include <linux/fsl_devices.h> 20 #include <linux/of_address.h> 21 #include <linux/of_irq.h> 22 #include <linux/of_platform.h> 23 #include <linux/export.h> 24 25 #include <asm/reg.h> 26 #include <asm/io.h> 27 #include <asm/time.h> 28 #include <asm/mpc6xx.h> 29 #include <asm/switch_to.h> 30 31 #include <sysdev/fsl_soc.h> 32 33 #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ 34 #define PMCCR1_NEXT_STATE_SHIFT 2 35 #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ 36 #define IMMR_SYSCR_OFFSET 0x100 37 #define IMMR_RCW_OFFSET 0x900 38 #define RCW_PCI_HOST 0x80000000 39 40 void mpc83xx_enter_deep_sleep(phys_addr_t immrbase); 41 42 struct mpc83xx_pmc { 43 u32 config; 44 #define PMCCR_DLPEN 2 /* DDR SDRAM low power enable */ 45 #define PMCCR_SLPEN 1 /* System low power enable */ 46 47 u32 event; 48 u32 mask; 49 /* All but PMCI are deep-sleep only */ 50 #define PMCER_GPIO 0x100 51 #define PMCER_PCI 0x080 52 #define PMCER_USB 0x040 53 #define PMCER_ETSEC1 0x020 54 #define PMCER_ETSEC2 0x010 55 #define PMCER_TIMER 0x008 56 #define PMCER_INT1 0x004 57 #define PMCER_INT2 0x002 58 #define PMCER_PMCI 0x001 59 #define PMCER_ALL 0x1FF 60 61 /* deep-sleep only */ 62 u32 config1; 63 #define PMCCR1_USE_STATE 0x80000000 64 #define PMCCR1_PME_EN 0x00000080 65 #define PMCCR1_ASSERT_PME 0x00000040 66 #define PMCCR1_POWER_OFF 0x00000020 67 68 /* deep-sleep only */ 69 u32 config2; 70 }; 71 72 struct mpc83xx_rcw { 73 u32 rcwlr; 74 u32 rcwhr; 75 }; 76 77 struct mpc83xx_clock { 78 u32 spmr; 79 u32 occr; 80 u32 sccr; 81 }; 82 83 struct mpc83xx_syscr { 84 __be32 sgprl; 85 __be32 sgprh; 86 __be32 spridr; 87 __be32 :32; 88 __be32 spcr; 89 __be32 sicrl; 90 __be32 sicrh; 91 }; 92 93 struct mpc83xx_saved { 94 u32 sicrl; 95 u32 sicrh; 96 u32 sccr; 97 }; 98 99 struct pmc_type { 100 int has_deep_sleep; 101 }; 102 103 static struct platform_device *pmc_dev; 104 static int has_deep_sleep, deep_sleeping; 105 static int pmc_irq; 106 static struct mpc83xx_pmc __iomem *pmc_regs; 107 static struct mpc83xx_clock __iomem *clock_regs; 108 static struct mpc83xx_syscr __iomem *syscr_regs; 109 static struct mpc83xx_saved saved_regs; 110 static int is_pci_agent, wake_from_pci; 111 static phys_addr_t immrbase; 112 static int pci_pm_state; 113 static DECLARE_WAIT_QUEUE_HEAD(agent_wq); 114 115 int fsl_deep_sleep(void) 116 { 117 return deep_sleeping; 118 } 119 EXPORT_SYMBOL(fsl_deep_sleep); 120 121 static int mpc83xx_change_state(void) 122 { 123 u32 curr_state; 124 u32 reg_cfg1 = in_be32(&pmc_regs->config1); 125 126 if (is_pci_agent) { 127 pci_pm_state = (reg_cfg1 & PMCCR1_NEXT_STATE) >> 128 PMCCR1_NEXT_STATE_SHIFT; 129 curr_state = reg_cfg1 & PMCCR1_CURR_STATE; 130 131 if (curr_state != pci_pm_state) { 132 reg_cfg1 &= ~PMCCR1_CURR_STATE; 133 reg_cfg1 |= pci_pm_state; 134 out_be32(&pmc_regs->config1, reg_cfg1); 135 136 wake_up(&agent_wq); 137 return 1; 138 } 139 } 140 141 return 0; 142 } 143 144 static irqreturn_t pmc_irq_handler(int irq, void *dev_id) 145 { 146 u32 event = in_be32(&pmc_regs->event); 147 int ret = IRQ_NONE; 148 149 if (mpc83xx_change_state()) 150 ret = IRQ_HANDLED; 151 152 if (event) { 153 out_be32(&pmc_regs->event, event); 154 ret = IRQ_HANDLED; 155 } 156 157 return ret; 158 } 159 160 static void mpc83xx_suspend_restore_regs(void) 161 { 162 out_be32(&syscr_regs->sicrl, saved_regs.sicrl); 163 out_be32(&syscr_regs->sicrh, saved_regs.sicrh); 164 out_be32(&clock_regs->sccr, saved_regs.sccr); 165 } 166 167 static void mpc83xx_suspend_save_regs(void) 168 { 169 saved_regs.sicrl = in_be32(&syscr_regs->sicrl); 170 saved_regs.sicrh = in_be32(&syscr_regs->sicrh); 171 saved_regs.sccr = in_be32(&clock_regs->sccr); 172 } 173 174 static int mpc83xx_suspend_enter(suspend_state_t state) 175 { 176 int ret = -EAGAIN; 177 178 /* Don't go to sleep if there's a race where pci_pm_state changes 179 * between the agent thread checking it and the PM code disabling 180 * interrupts. 181 */ 182 if (wake_from_pci) { 183 if (pci_pm_state != (deep_sleeping ? 3 : 2)) 184 goto out; 185 186 out_be32(&pmc_regs->config1, 187 in_be32(&pmc_regs->config1) | PMCCR1_PME_EN); 188 } 189 190 /* Put the system into low-power mode and the RAM 191 * into self-refresh mode once the core goes to 192 * sleep. 193 */ 194 195 out_be32(&pmc_regs->config, PMCCR_SLPEN | PMCCR_DLPEN); 196 197 /* If it has deep sleep (i.e. it's an 831x or compatible), 198 * disable power to the core upon entering sleep mode. This will 199 * require going through the boot firmware upon a wakeup event. 200 */ 201 202 if (deep_sleeping) { 203 mpc83xx_suspend_save_regs(); 204 205 out_be32(&pmc_regs->mask, PMCER_ALL); 206 207 out_be32(&pmc_regs->config1, 208 in_be32(&pmc_regs->config1) | PMCCR1_POWER_OFF); 209 210 enable_kernel_fp(); 211 212 mpc83xx_enter_deep_sleep(immrbase); 213 214 out_be32(&pmc_regs->config1, 215 in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); 216 217 out_be32(&pmc_regs->mask, PMCER_PMCI); 218 219 mpc83xx_suspend_restore_regs(); 220 } else { 221 out_be32(&pmc_regs->mask, PMCER_PMCI); 222 223 mpc6xx_enter_standby(); 224 } 225 226 ret = 0; 227 228 out: 229 out_be32(&pmc_regs->config1, 230 in_be32(&pmc_regs->config1) & ~PMCCR1_PME_EN); 231 232 return ret; 233 } 234 235 static void mpc83xx_suspend_end(void) 236 { 237 deep_sleeping = 0; 238 } 239 240 static int mpc83xx_suspend_valid(suspend_state_t state) 241 { 242 return state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM; 243 } 244 245 static int mpc83xx_suspend_begin(suspend_state_t state) 246 { 247 switch (state) { 248 case PM_SUSPEND_STANDBY: 249 deep_sleeping = 0; 250 return 0; 251 252 case PM_SUSPEND_MEM: 253 if (has_deep_sleep) 254 deep_sleeping = 1; 255 256 return 0; 257 258 default: 259 return -EINVAL; 260 } 261 } 262 263 static int agent_thread_fn(void *data) 264 { 265 while (1) { 266 wait_event_interruptible(agent_wq, pci_pm_state >= 2); 267 try_to_freeze(); 268 269 if (signal_pending(current) || pci_pm_state < 2) 270 continue; 271 272 /* With a preemptible kernel (or SMP), this could race with 273 * a userspace-driven suspend request. It's probably best 274 * to avoid mixing the two with such a configuration (or 275 * else fix it by adding a mutex to state_store that we can 276 * synchronize with). 277 */ 278 279 wake_from_pci = 1; 280 281 pm_suspend(pci_pm_state == 3 ? PM_SUSPEND_MEM : 282 PM_SUSPEND_STANDBY); 283 284 wake_from_pci = 0; 285 } 286 287 return 0; 288 } 289 290 static void mpc83xx_set_agent(void) 291 { 292 out_be32(&pmc_regs->config1, PMCCR1_USE_STATE); 293 out_be32(&pmc_regs->mask, PMCER_PMCI); 294 295 kthread_run(agent_thread_fn, NULL, "PCI power mgt"); 296 } 297 298 static int mpc83xx_is_pci_agent(void) 299 { 300 struct mpc83xx_rcw __iomem *rcw_regs; 301 int ret; 302 303 rcw_regs = ioremap(get_immrbase() + IMMR_RCW_OFFSET, 304 sizeof(struct mpc83xx_rcw)); 305 306 if (!rcw_regs) 307 return -ENOMEM; 308 309 ret = !(in_be32(&rcw_regs->rcwhr) & RCW_PCI_HOST); 310 311 iounmap(rcw_regs); 312 return ret; 313 } 314 315 static const struct platform_suspend_ops mpc83xx_suspend_ops = { 316 .valid = mpc83xx_suspend_valid, 317 .begin = mpc83xx_suspend_begin, 318 .enter = mpc83xx_suspend_enter, 319 .end = mpc83xx_suspend_end, 320 }; 321 322 static const struct of_device_id pmc_match[]; 323 static int pmc_probe(struct platform_device *ofdev) 324 { 325 const struct of_device_id *match; 326 struct device_node *np = ofdev->dev.of_node; 327 struct resource res; 328 const struct pmc_type *type; 329 int ret = 0; 330 331 match = of_match_device(pmc_match, &ofdev->dev); 332 if (!match) 333 return -EINVAL; 334 335 type = match->data; 336 337 if (!of_device_is_available(np)) 338 return -ENODEV; 339 340 has_deep_sleep = type->has_deep_sleep; 341 immrbase = get_immrbase(); 342 pmc_dev = ofdev; 343 344 is_pci_agent = mpc83xx_is_pci_agent(); 345 if (is_pci_agent < 0) 346 return is_pci_agent; 347 348 ret = of_address_to_resource(np, 0, &res); 349 if (ret) 350 return -ENODEV; 351 352 pmc_irq = irq_of_parse_and_map(np, 0); 353 if (pmc_irq) { 354 ret = request_irq(pmc_irq, pmc_irq_handler, IRQF_SHARED, 355 "pmc", ofdev); 356 357 if (ret) 358 return -EBUSY; 359 } 360 361 pmc_regs = ioremap(res.start, sizeof(*pmc_regs)); 362 363 if (!pmc_regs) { 364 ret = -ENOMEM; 365 goto out; 366 } 367 368 ret = of_address_to_resource(np, 1, &res); 369 if (ret) { 370 ret = -ENODEV; 371 goto out_pmc; 372 } 373 374 clock_regs = ioremap(res.start, sizeof(*clock_regs)); 375 376 if (!clock_regs) { 377 ret = -ENOMEM; 378 goto out_pmc; 379 } 380 381 if (has_deep_sleep) { 382 syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET, 383 sizeof(*syscr_regs)); 384 if (!syscr_regs) { 385 ret = -ENOMEM; 386 goto out_syscr; 387 } 388 } 389 390 if (is_pci_agent) 391 mpc83xx_set_agent(); 392 393 suspend_set_ops(&mpc83xx_suspend_ops); 394 return 0; 395 396 out_syscr: 397 iounmap(clock_regs); 398 out_pmc: 399 iounmap(pmc_regs); 400 out: 401 if (pmc_irq) 402 free_irq(pmc_irq, ofdev); 403 404 return ret; 405 } 406 407 static int pmc_remove(struct platform_device *ofdev) 408 { 409 return -EPERM; 410 }; 411 412 static struct pmc_type pmc_types[] = { 413 { 414 .has_deep_sleep = 1, 415 }, 416 { 417 .has_deep_sleep = 0, 418 } 419 }; 420 421 static const struct of_device_id pmc_match[] = { 422 { 423 .compatible = "fsl,mpc8313-pmc", 424 .data = &pmc_types[0], 425 }, 426 { 427 .compatible = "fsl,mpc8349-pmc", 428 .data = &pmc_types[1], 429 }, 430 {} 431 }; 432 433 static struct platform_driver pmc_driver = { 434 .driver = { 435 .name = "mpc83xx-pmc", 436 .of_match_table = pmc_match, 437 }, 438 .probe = pmc_probe, 439 .remove = pmc_remove 440 }; 441 442 builtin_platform_driver(pmc_driver); 443