1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2016 Freescale Semiconductor, Inc. 4 * Copyright 2017-2018 NXP 5 * Author: Dong Aisheng <aisheng.dong@nxp.com> 6 */ 7 8 #include <linux/io.h> 9 #include <linux/of.h> 10 #include <linux/of_address.h> 11 12 #include "common.h" 13 14 #define SMC_PMCTRL 0x10 15 #define BP_PMCTRL_PSTOPO 16 16 #define PSTOPO_PSTOP3 0x3 17 #define PSTOPO_PSTOP2 0x2 18 #define PSTOPO_PSTOP1 0x1 19 #define BP_PMCTRL_RUNM 8 20 #define RUNM_RUN 0 21 #define BP_PMCTRL_STOPM 0 22 #define STOPM_STOP 0 23 24 #define BM_PMCTRL_PSTOPO (3 << BP_PMCTRL_PSTOPO) 25 #define BM_PMCTRL_RUNM (3 << BP_PMCTRL_RUNM) 26 #define BM_PMCTRL_STOPM (7 << BP_PMCTRL_STOPM) 27 28 static void __iomem *smc1_base; 29 30 int imx7ulp_set_lpm(enum ulp_cpu_pwr_mode mode) 31 { 32 u32 val = readl_relaxed(smc1_base + SMC_PMCTRL); 33 34 /* clear all */ 35 val &= ~(BM_PMCTRL_RUNM | BM_PMCTRL_STOPM | BM_PMCTRL_PSTOPO); 36 37 switch (mode) { 38 case ULP_PM_RUN: 39 /* system/bus clock enabled */ 40 val |= PSTOPO_PSTOP3 << BP_PMCTRL_PSTOPO; 41 break; 42 case ULP_PM_WAIT: 43 /* system clock disabled, bus clock enabled */ 44 val |= PSTOPO_PSTOP2 << BP_PMCTRL_PSTOPO; 45 break; 46 case ULP_PM_STOP: 47 /* system/bus clock disabled */ 48 val |= PSTOPO_PSTOP1 << BP_PMCTRL_PSTOPO; 49 break; 50 default: 51 return -EINVAL; 52 } 53 54 writel_relaxed(val, smc1_base + SMC_PMCTRL); 55 56 return 0; 57 } 58 59 void __init imx7ulp_pm_init(void) 60 { 61 struct device_node *np; 62 63 np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1"); 64 smc1_base = of_iomap(np, 0); 65 of_node_put(np); 66 WARN_ON(!smc1_base); 67 68 imx7ulp_set_lpm(ULP_PM_RUN); 69 } 70