0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/io.h>
0009 #include <linux/of.h>
0010 #include <linux/of_address.h>
0011
0012 #include "common.h"
0013
0014 #define SMC_PMCTRL 0x10
0015 #define BP_PMCTRL_PSTOPO 16
0016 #define PSTOPO_PSTOP3 0x3
0017 #define PSTOPO_PSTOP2 0x2
0018 #define PSTOPO_PSTOP1 0x1
0019 #define BP_PMCTRL_RUNM 8
0020 #define RUNM_RUN 0
0021 #define BP_PMCTRL_STOPM 0
0022 #define STOPM_STOP 0
0023
0024 #define BM_PMCTRL_PSTOPO (3 << BP_PMCTRL_PSTOPO)
0025 #define BM_PMCTRL_RUNM (3 << BP_PMCTRL_RUNM)
0026 #define BM_PMCTRL_STOPM (7 << BP_PMCTRL_STOPM)
0027
0028 static void __iomem *smc1_base;
0029
0030 int imx7ulp_set_lpm(enum ulp_cpu_pwr_mode mode)
0031 {
0032 u32 val = readl_relaxed(smc1_base + SMC_PMCTRL);
0033
0034
0035 val &= ~(BM_PMCTRL_RUNM | BM_PMCTRL_STOPM | BM_PMCTRL_PSTOPO);
0036
0037 switch (mode) {
0038 case ULP_PM_RUN:
0039
0040 val |= PSTOPO_PSTOP3 << BP_PMCTRL_PSTOPO;
0041 break;
0042 case ULP_PM_WAIT:
0043
0044 val |= PSTOPO_PSTOP2 << BP_PMCTRL_PSTOPO;
0045 break;
0046 case ULP_PM_STOP:
0047
0048 val |= PSTOPO_PSTOP1 << BP_PMCTRL_PSTOPO;
0049 break;
0050 default:
0051 return -EINVAL;
0052 }
0053
0054 writel_relaxed(val, smc1_base + SMC_PMCTRL);
0055
0056 return 0;
0057 }
0058
0059 void __init imx7ulp_pm_init(void)
0060 {
0061 struct device_node *np;
0062
0063 np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1");
0064 smc1_base = of_iomap(np, 0);
0065 of_node_put(np);
0066 WARN_ON(!smc1_base);
0067
0068 imx7ulp_set_lpm(ULP_PM_RUN);
0069 }