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