18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2016 Freescale Semiconductor, Inc.
48c2ecf20Sopenharmony_ci * Copyright 2017-2018 NXP
58c2ecf20Sopenharmony_ci *   Anson Huang <Anson.Huang@nxp.com>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/cpuidle.h>
98c2ecf20Sopenharmony_ci#include <linux/module.h>
108c2ecf20Sopenharmony_ci#include <asm/cpuidle.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include "common.h"
138c2ecf20Sopenharmony_ci#include "cpuidle.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic int imx7ulp_enter_wait(struct cpuidle_device *dev,
168c2ecf20Sopenharmony_ci			    struct cpuidle_driver *drv, int index)
178c2ecf20Sopenharmony_ci{
188c2ecf20Sopenharmony_ci	if (index == 1)
198c2ecf20Sopenharmony_ci		imx7ulp_set_lpm(ULP_PM_WAIT);
208c2ecf20Sopenharmony_ci	else
218c2ecf20Sopenharmony_ci		imx7ulp_set_lpm(ULP_PM_STOP);
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	cpu_do_idle();
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	imx7ulp_set_lpm(ULP_PM_RUN);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	return index;
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistatic struct cpuidle_driver imx7ulp_cpuidle_driver = {
318c2ecf20Sopenharmony_ci	.name = "imx7ulp_cpuidle",
328c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
338c2ecf20Sopenharmony_ci	.states = {
348c2ecf20Sopenharmony_ci		/* WFI */
358c2ecf20Sopenharmony_ci		ARM_CPUIDLE_WFI_STATE,
368c2ecf20Sopenharmony_ci		/* WAIT */
378c2ecf20Sopenharmony_ci		{
388c2ecf20Sopenharmony_ci			.exit_latency = 50,
398c2ecf20Sopenharmony_ci			.target_residency = 75,
408c2ecf20Sopenharmony_ci			.enter = imx7ulp_enter_wait,
418c2ecf20Sopenharmony_ci			.name = "WAIT",
428c2ecf20Sopenharmony_ci			.desc = "PSTOP2",
438c2ecf20Sopenharmony_ci		},
448c2ecf20Sopenharmony_ci		/* STOP */
458c2ecf20Sopenharmony_ci		{
468c2ecf20Sopenharmony_ci			.exit_latency = 100,
478c2ecf20Sopenharmony_ci			.target_residency = 150,
488c2ecf20Sopenharmony_ci			.enter = imx7ulp_enter_wait,
498c2ecf20Sopenharmony_ci			.name = "STOP",
508c2ecf20Sopenharmony_ci			.desc = "PSTOP1",
518c2ecf20Sopenharmony_ci		},
528c2ecf20Sopenharmony_ci	},
538c2ecf20Sopenharmony_ci	.state_count = 3,
548c2ecf20Sopenharmony_ci	.safe_state_index = 0,
558c2ecf20Sopenharmony_ci};
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ciint __init imx7ulp_cpuidle_init(void)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	return cpuidle_register(&imx7ulp_cpuidle_driver, NULL);
608c2ecf20Sopenharmony_ci}
61