xref: /linux/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
256f1ba28Schenhui zhao /*
356f1ba28Schenhui zhao  * MPC85xx PM operators
456f1ba28Schenhui zhao  *
556f1ba28Schenhui zhao  * Copyright 2015 Freescale Semiconductor Inc.
656f1ba28Schenhui zhao  */
756f1ba28Schenhui zhao 
856f1ba28Schenhui zhao #define pr_fmt(fmt) "%s: " fmt, __func__
956f1ba28Schenhui zhao 
1056f1ba28Schenhui zhao #include <linux/kernel.h>
1156f1ba28Schenhui zhao #include <linux/of.h>
1256f1ba28Schenhui zhao #include <linux/of_address.h>
1356f1ba28Schenhui zhao #include <linux/fsl/guts.h>
1456f1ba28Schenhui zhao 
1556f1ba28Schenhui zhao #include <asm/io.h>
1656f1ba28Schenhui zhao #include <asm/fsl_pm.h>
1756f1ba28Schenhui zhao 
18*4ea9e321SMichael Ellerman #include "smp.h"
19*4ea9e321SMichael Ellerman 
2056f1ba28Schenhui zhao static struct ccsr_guts __iomem *guts;
2156f1ba28Schenhui zhao 
22c45361abSXiaoming Ni #ifdef CONFIG_FSL_PMC
mpc85xx_irq_mask(int cpu)2356f1ba28Schenhui zhao static void mpc85xx_irq_mask(int cpu)
2456f1ba28Schenhui zhao {
2556f1ba28Schenhui zhao 
2656f1ba28Schenhui zhao }
2756f1ba28Schenhui zhao 
mpc85xx_irq_unmask(int cpu)2856f1ba28Schenhui zhao static void mpc85xx_irq_unmask(int cpu)
2956f1ba28Schenhui zhao {
3056f1ba28Schenhui zhao 
3156f1ba28Schenhui zhao }
3256f1ba28Schenhui zhao 
mpc85xx_cpu_die(int cpu)3356f1ba28Schenhui zhao static void mpc85xx_cpu_die(int cpu)
3456f1ba28Schenhui zhao {
3556f1ba28Schenhui zhao 	u32 tmp;
3656f1ba28Schenhui zhao 
3756f1ba28Schenhui zhao 	tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
3856f1ba28Schenhui zhao 	mtspr(SPRN_HID0, tmp);
3956f1ba28Schenhui zhao 
4056f1ba28Schenhui zhao 	/* Enter NAP mode. */
4156f1ba28Schenhui zhao 	tmp = mfmsr();
4256f1ba28Schenhui zhao 	tmp |= MSR_WE;
4356f1ba28Schenhui zhao 	asm volatile(
4456f1ba28Schenhui zhao 		"msync\n"
4556f1ba28Schenhui zhao 		"mtmsr %0\n"
4656f1ba28Schenhui zhao 		"isync\n"
4756f1ba28Schenhui zhao 		:
4856f1ba28Schenhui zhao 		: "r" (tmp));
4956f1ba28Schenhui zhao }
5056f1ba28Schenhui zhao 
mpc85xx_cpu_up_prepare(int cpu)5156f1ba28Schenhui zhao static void mpc85xx_cpu_up_prepare(int cpu)
5256f1ba28Schenhui zhao {
5356f1ba28Schenhui zhao 
5456f1ba28Schenhui zhao }
55c45361abSXiaoming Ni #endif
5656f1ba28Schenhui zhao 
mpc85xx_freeze_time_base(bool freeze)5756f1ba28Schenhui zhao static void mpc85xx_freeze_time_base(bool freeze)
5856f1ba28Schenhui zhao {
5956f1ba28Schenhui zhao 	uint32_t mask;
6056f1ba28Schenhui zhao 
6156f1ba28Schenhui zhao 	mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
6256f1ba28Schenhui zhao 	if (freeze)
6356f1ba28Schenhui zhao 		setbits32(&guts->devdisr, mask);
6456f1ba28Schenhui zhao 	else
6556f1ba28Schenhui zhao 		clrbits32(&guts->devdisr, mask);
6656f1ba28Schenhui zhao 
6756f1ba28Schenhui zhao 	in_be32(&guts->devdisr);
6856f1ba28Schenhui zhao }
6956f1ba28Schenhui zhao 
7056f1ba28Schenhui zhao static const struct of_device_id mpc85xx_smp_guts_ids[] = {
7156f1ba28Schenhui zhao 	{ .compatible = "fsl,mpc8572-guts", },
7256f1ba28Schenhui zhao 	{ .compatible = "fsl,p1020-guts", },
7356f1ba28Schenhui zhao 	{ .compatible = "fsl,p1021-guts", },
7456f1ba28Schenhui zhao 	{ .compatible = "fsl,p1022-guts", },
7556f1ba28Schenhui zhao 	{ .compatible = "fsl,p1023-guts", },
7656f1ba28Schenhui zhao 	{ .compatible = "fsl,p2020-guts", },
7756f1ba28Schenhui zhao 	{ .compatible = "fsl,bsc9132-guts", },
7856f1ba28Schenhui zhao 	{},
7956f1ba28Schenhui zhao };
8056f1ba28Schenhui zhao 
8156f1ba28Schenhui zhao static const struct fsl_pm_ops mpc85xx_pm_ops = {
8256f1ba28Schenhui zhao 	.freeze_time_base = mpc85xx_freeze_time_base,
83c45361abSXiaoming Ni #ifdef CONFIG_FSL_PMC
8456f1ba28Schenhui zhao 	.irq_mask = mpc85xx_irq_mask,
8556f1ba28Schenhui zhao 	.irq_unmask = mpc85xx_irq_unmask,
8656f1ba28Schenhui zhao 	.cpu_die = mpc85xx_cpu_die,
8756f1ba28Schenhui zhao 	.cpu_up_prepare = mpc85xx_cpu_up_prepare,
88c45361abSXiaoming Ni #endif
8956f1ba28Schenhui zhao };
9056f1ba28Schenhui zhao 
mpc85xx_setup_pmc(void)9156f1ba28Schenhui zhao int __init mpc85xx_setup_pmc(void)
9256f1ba28Schenhui zhao {
9356f1ba28Schenhui zhao 	struct device_node *np;
9456f1ba28Schenhui zhao 
9556f1ba28Schenhui zhao 	np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
9656f1ba28Schenhui zhao 	if (np) {
9756f1ba28Schenhui zhao 		guts = of_iomap(np, 0);
9856f1ba28Schenhui zhao 		of_node_put(np);
9956f1ba28Schenhui zhao 		if (!guts) {
10056f1ba28Schenhui zhao 			pr_err("Could not map guts node address\n");
10156f1ba28Schenhui zhao 			return -ENOMEM;
10256f1ba28Schenhui zhao 		}
10356f1ba28Schenhui zhao 		qoriq_pm_ops = &mpc85xx_pm_ops;
1043c2172c1SXiaoming Ni 	}
10556f1ba28Schenhui zhao 
10656f1ba28Schenhui zhao 	return 0;
10756f1ba28Schenhui zhao }
108