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