162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2016 Freescale Semiconductor, Inc.
462306a36Sopenharmony_ci * Copyright 2017-2018 NXP
562306a36Sopenharmony_ci *   Anson Huang <Anson.Huang@nxp.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/cpuidle.h>
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci#include <asm/cpuidle.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "common.h"
1362306a36Sopenharmony_ci#include "cpuidle.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistatic __cpuidle int imx7ulp_enter_wait(struct cpuidle_device *dev,
1662306a36Sopenharmony_ci					struct cpuidle_driver *drv, int index)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	if (index == 1)
1962306a36Sopenharmony_ci		imx7ulp_set_lpm(ULP_PM_WAIT);
2062306a36Sopenharmony_ci	else
2162306a36Sopenharmony_ci		imx7ulp_set_lpm(ULP_PM_STOP);
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	cpu_do_idle();
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	imx7ulp_set_lpm(ULP_PM_RUN);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	return index;
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic struct cpuidle_driver imx7ulp_cpuidle_driver = {
3162306a36Sopenharmony_ci	.name = "imx7ulp_cpuidle",
3262306a36Sopenharmony_ci	.owner = THIS_MODULE,
3362306a36Sopenharmony_ci	.states = {
3462306a36Sopenharmony_ci		/* WFI */
3562306a36Sopenharmony_ci		ARM_CPUIDLE_WFI_STATE,
3662306a36Sopenharmony_ci		/* WAIT */
3762306a36Sopenharmony_ci		{
3862306a36Sopenharmony_ci			.exit_latency = 50,
3962306a36Sopenharmony_ci			.target_residency = 75,
4062306a36Sopenharmony_ci			.enter = imx7ulp_enter_wait,
4162306a36Sopenharmony_ci			.name = "WAIT",
4262306a36Sopenharmony_ci			.desc = "PSTOP2",
4362306a36Sopenharmony_ci		},
4462306a36Sopenharmony_ci		/* STOP */
4562306a36Sopenharmony_ci		{
4662306a36Sopenharmony_ci			.exit_latency = 100,
4762306a36Sopenharmony_ci			.target_residency = 150,
4862306a36Sopenharmony_ci			.enter = imx7ulp_enter_wait,
4962306a36Sopenharmony_ci			.name = "STOP",
5062306a36Sopenharmony_ci			.desc = "PSTOP1",
5162306a36Sopenharmony_ci		},
5262306a36Sopenharmony_ci	},
5362306a36Sopenharmony_ci	.state_count = 3,
5462306a36Sopenharmony_ci	.safe_state_index = 0,
5562306a36Sopenharmony_ci};
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciint __init imx7ulp_cpuidle_init(void)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	return cpuidle_register(&imx7ulp_cpuidle_driver, NULL);
6062306a36Sopenharmony_ci}
61