162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2014 Freescale Semiconductor, Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/clk/imx.h>
762306a36Sopenharmony_ci#include <linux/cpuidle.h>
862306a36Sopenharmony_ci#include <linux/module.h>
962306a36Sopenharmony_ci#include <asm/cpuidle.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "common.h"
1262306a36Sopenharmony_ci#include "cpuidle.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistatic __cpuidle int imx6sl_enter_wait(struct cpuidle_device *dev,
1562306a36Sopenharmony_ci				       struct cpuidle_driver *drv, int index)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	imx6_set_lpm(WAIT_UNCLOCKED);
1862306a36Sopenharmony_ci	/*
1962306a36Sopenharmony_ci	 * Software workaround for ERR005311, see function
2062306a36Sopenharmony_ci	 * description for details.
2162306a36Sopenharmony_ci	 */
2262306a36Sopenharmony_ci	imx6sl_set_wait_clk(true);
2362306a36Sopenharmony_ci	cpu_do_idle();
2462306a36Sopenharmony_ci	imx6sl_set_wait_clk(false);
2562306a36Sopenharmony_ci	imx6_set_lpm(WAIT_CLOCKED);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	return index;
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic struct cpuidle_driver imx6sl_cpuidle_driver = {
3162306a36Sopenharmony_ci	.name = "imx6sl_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			.flags = CPUIDLE_FLAG_TIMER_STOP,
4162306a36Sopenharmony_ci			.enter = imx6sl_enter_wait,
4262306a36Sopenharmony_ci			.name = "WAIT",
4362306a36Sopenharmony_ci			.desc = "Clock off",
4462306a36Sopenharmony_ci		},
4562306a36Sopenharmony_ci	},
4662306a36Sopenharmony_ci	.state_count = 2,
4762306a36Sopenharmony_ci	.safe_state_index = 0,
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciint __init imx6sl_cpuidle_init(void)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	return cpuidle_register(&imx6sl_cpuidle_driver, NULL);
5362306a36Sopenharmony_ci}
54