mpc85xx_pm_ops.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * MPC85xx PM operators
  3. *
  4. * Copyright 2015 Freescale Semiconductor Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version.
  10. */
  11. #define pr_fmt(fmt) "%s: " fmt, __func__
  12. #include <linux/kernel.h>
  13. #include <linux/of.h>
  14. #include <linux/of_address.h>
  15. #include <linux/fsl/guts.h>
  16. #include <asm/io.h>
  17. #include <asm/fsl_pm.h>
  18. static struct ccsr_guts __iomem *guts;
  19. static void mpc85xx_irq_mask(int cpu)
  20. {
  21. }
  22. static void mpc85xx_irq_unmask(int cpu)
  23. {
  24. }
  25. static void mpc85xx_cpu_die(int cpu)
  26. {
  27. u32 tmp;
  28. tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
  29. mtspr(SPRN_HID0, tmp);
  30. /* Enter NAP mode. */
  31. tmp = mfmsr();
  32. tmp |= MSR_WE;
  33. asm volatile(
  34. "msync\n"
  35. "mtmsr %0\n"
  36. "isync\n"
  37. :
  38. : "r" (tmp));
  39. }
  40. static void mpc85xx_cpu_up_prepare(int cpu)
  41. {
  42. }
  43. static void mpc85xx_freeze_time_base(bool freeze)
  44. {
  45. uint32_t mask;
  46. mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
  47. if (freeze)
  48. setbits32(&guts->devdisr, mask);
  49. else
  50. clrbits32(&guts->devdisr, mask);
  51. in_be32(&guts->devdisr);
  52. }
  53. static const struct of_device_id mpc85xx_smp_guts_ids[] = {
  54. { .compatible = "fsl,mpc8572-guts", },
  55. { .compatible = "fsl,p1020-guts", },
  56. { .compatible = "fsl,p1021-guts", },
  57. { .compatible = "fsl,p1022-guts", },
  58. { .compatible = "fsl,p1023-guts", },
  59. { .compatible = "fsl,p2020-guts", },
  60. { .compatible = "fsl,bsc9132-guts", },
  61. {},
  62. };
  63. static const struct fsl_pm_ops mpc85xx_pm_ops = {
  64. .freeze_time_base = mpc85xx_freeze_time_base,
  65. .irq_mask = mpc85xx_irq_mask,
  66. .irq_unmask = mpc85xx_irq_unmask,
  67. .cpu_die = mpc85xx_cpu_die,
  68. .cpu_up_prepare = mpc85xx_cpu_up_prepare,
  69. };
  70. int __init mpc85xx_setup_pmc(void)
  71. {
  72. struct device_node *np;
  73. np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
  74. if (np) {
  75. guts = of_iomap(np, 0);
  76. of_node_put(np);
  77. if (!guts) {
  78. pr_err("Could not map guts node address\n");
  79. return -ENOMEM;
  80. }
  81. }
  82. qoriq_pm_ops = &mpc85xx_pm_ops;
  83. return 0;
  84. }