1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * MPC85xx PM operators 4 * 5 * Copyright 2015 Freescale Semiconductor Inc. 6 */ 7 8 #define pr_fmt(fmt) "%s: " fmt, __func__ 9 10 #include <linux/kernel.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/fsl/guts.h> 14 15 #include <asm/io.h> 16 #include <asm/fsl_pm.h> 17 18 static struct ccsr_guts __iomem *guts; 19 20 #ifdef CONFIG_FSL_PMC 21 static void mpc85xx_irq_mask(int cpu) 22 { 23 24 } 25 26 static void mpc85xx_irq_unmask(int cpu) 27 { 28 29 } 30 31 static void mpc85xx_cpu_die(int cpu) 32 { 33 u32 tmp; 34 35 tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; 36 mtspr(SPRN_HID0, tmp); 37 38 /* Enter NAP mode. */ 39 tmp = mfmsr(); 40 tmp |= MSR_WE; 41 asm volatile( 42 "msync\n" 43 "mtmsr %0\n" 44 "isync\n" 45 : 46 : "r" (tmp)); 47 } 48 49 static void mpc85xx_cpu_up_prepare(int cpu) 50 { 51 52 } 53 #endif 54 55 static void mpc85xx_freeze_time_base(bool freeze) 56 { 57 uint32_t mask; 58 59 mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; 60 if (freeze) 61 setbits32(&guts->devdisr, mask); 62 else 63 clrbits32(&guts->devdisr, mask); 64 65 in_be32(&guts->devdisr); 66 } 67 68 static const struct of_device_id mpc85xx_smp_guts_ids[] = { 69 { .compatible = "fsl,mpc8572-guts", }, 70 { .compatible = "fsl,p1020-guts", }, 71 { .compatible = "fsl,p1021-guts", }, 72 { .compatible = "fsl,p1022-guts", }, 73 { .compatible = "fsl,p1023-guts", }, 74 { .compatible = "fsl,p2020-guts", }, 75 { .compatible = "fsl,bsc9132-guts", }, 76 {}, 77 }; 78 79 static const struct fsl_pm_ops mpc85xx_pm_ops = { 80 .freeze_time_base = mpc85xx_freeze_time_base, 81 #ifdef CONFIG_FSL_PMC 82 .irq_mask = mpc85xx_irq_mask, 83 .irq_unmask = mpc85xx_irq_unmask, 84 .cpu_die = mpc85xx_cpu_die, 85 .cpu_up_prepare = mpc85xx_cpu_up_prepare, 86 #endif 87 }; 88 89 int __init mpc85xx_setup_pmc(void) 90 { 91 struct device_node *np; 92 93 np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); 94 if (np) { 95 guts = of_iomap(np, 0); 96 of_node_put(np); 97 if (!guts) { 98 pr_err("Could not map guts node address\n"); 99 return -ENOMEM; 100 } 101 qoriq_pm_ops = &mpc85xx_pm_ops; 102 } 103 104 return 0; 105 } 106