blob: 7b2f7387e6626e09c71697e33cbd5712ede828ed [file] [log] [blame]
A.s. Dongde70d0e2018-11-10 15:13:04 +00001// 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
Anson Huang6d45a402019-01-14 08:54:59 +080012#include "common.h"
13
A.s. Dongde70d0e2018-11-10 15:13:04 +000014#define SMC_PMCTRL 0x10
15#define BP_PMCTRL_PSTOPO 16
16#define PSTOPO_PSTOP3 0x3
Anson Huang6d45a402019-01-14 08:54:59 +080017#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
28static void __iomem *smc1_base;
29
30int 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}
A.s. Dongde70d0e2018-11-10 15:13:04 +000058
59void __init imx7ulp_pm_init(void)
60{
61 struct device_node *np;
A.s. Dongde70d0e2018-11-10 15:13:04 +000062
63 np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1");
64 smc1_base = of_iomap(np, 0);
65 WARN_ON(!smc1_base);
66
Anson Huang6d45a402019-01-14 08:54:59 +080067 imx7ulp_set_lpm(ULP_PM_RUN);
A.s. Dongde70d0e2018-11-10 15:13:04 +000068}