1de70d0e9SA.s. Dong // SPDX-License-Identifier: GPL-2.0+ 2de70d0e9SA.s. Dong /* 3de70d0e9SA.s. Dong * Copyright (C) 2016 Freescale Semiconductor, Inc. 4de70d0e9SA.s. Dong * Copyright 2017-2018 NXP 5de70d0e9SA.s. Dong * Author: Dong Aisheng <aisheng.dong@nxp.com> 6de70d0e9SA.s. Dong */ 7de70d0e9SA.s. Dong 8de70d0e9SA.s. Dong #include <linux/io.h> 9de70d0e9SA.s. Dong #include <linux/of.h> 10de70d0e9SA.s. Dong #include <linux/of_address.h> 11de70d0e9SA.s. Dong 126d45a402SAnson Huang #include "common.h" 136d45a402SAnson Huang 14de70d0e9SA.s. Dong #define SMC_PMCTRL 0x10 15de70d0e9SA.s. Dong #define BP_PMCTRL_PSTOPO 16 16de70d0e9SA.s. Dong #define PSTOPO_PSTOP3 0x3 176d45a402SAnson Huang #define PSTOPO_PSTOP2 0x2 186d45a402SAnson Huang #define PSTOPO_PSTOP1 0x1 196d45a402SAnson Huang #define BP_PMCTRL_RUNM 8 206d45a402SAnson Huang #define RUNM_RUN 0 216d45a402SAnson Huang #define BP_PMCTRL_STOPM 0 226d45a402SAnson Huang #define STOPM_STOP 0 236d45a402SAnson Huang 246d45a402SAnson Huang #define BM_PMCTRL_PSTOPO (3 << BP_PMCTRL_PSTOPO) 256d45a402SAnson Huang #define BM_PMCTRL_RUNM (3 << BP_PMCTRL_RUNM) 266d45a402SAnson Huang #define BM_PMCTRL_STOPM (7 << BP_PMCTRL_STOPM) 276d45a402SAnson Huang 286d45a402SAnson Huang static void __iomem *smc1_base; 296d45a402SAnson Huang imx7ulp_set_lpm(enum ulp_cpu_pwr_mode mode)306d45a402SAnson Huangint imx7ulp_set_lpm(enum ulp_cpu_pwr_mode mode) 316d45a402SAnson Huang { 326d45a402SAnson Huang u32 val = readl_relaxed(smc1_base + SMC_PMCTRL); 336d45a402SAnson Huang 346d45a402SAnson Huang /* clear all */ 356d45a402SAnson Huang val &= ~(BM_PMCTRL_RUNM | BM_PMCTRL_STOPM | BM_PMCTRL_PSTOPO); 366d45a402SAnson Huang 376d45a402SAnson Huang switch (mode) { 386d45a402SAnson Huang case ULP_PM_RUN: 396d45a402SAnson Huang /* system/bus clock enabled */ 406d45a402SAnson Huang val |= PSTOPO_PSTOP3 << BP_PMCTRL_PSTOPO; 416d45a402SAnson Huang break; 426d45a402SAnson Huang case ULP_PM_WAIT: 436d45a402SAnson Huang /* system clock disabled, bus clock enabled */ 446d45a402SAnson Huang val |= PSTOPO_PSTOP2 << BP_PMCTRL_PSTOPO; 456d45a402SAnson Huang break; 466d45a402SAnson Huang case ULP_PM_STOP: 476d45a402SAnson Huang /* system/bus clock disabled */ 486d45a402SAnson Huang val |= PSTOPO_PSTOP1 << BP_PMCTRL_PSTOPO; 496d45a402SAnson Huang break; 506d45a402SAnson Huang default: 516d45a402SAnson Huang return -EINVAL; 526d45a402SAnson Huang } 536d45a402SAnson Huang 546d45a402SAnson Huang writel_relaxed(val, smc1_base + SMC_PMCTRL); 556d45a402SAnson Huang 566d45a402SAnson Huang return 0; 576d45a402SAnson Huang } 58de70d0e9SA.s. Dong imx7ulp_pm_init(void)59de70d0e9SA.s. Dongvoid __init imx7ulp_pm_init(void) 60de70d0e9SA.s. Dong { 61de70d0e9SA.s. Dong struct device_node *np; 62de70d0e9SA.s. Dong 63de70d0e9SA.s. Dong np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1"); 64de70d0e9SA.s. Dong smc1_base = of_iomap(np, 0); 654a4fb661SAnson Huang of_node_put(np); 66de70d0e9SA.s. Dong WARN_ON(!smc1_base); 67de70d0e9SA.s. Dong 686d45a402SAnson Huang imx7ulp_set_lpm(ULP_PM_RUN); 69de70d0e9SA.s. Dong } 70