cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpuidle.c (2212B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * CPU idle for DaVinci SoCs
      4 *
      5 * Copyright (C) 2009 Texas Instruments Incorporated. https://www.ti.com/
      6 *
      7 * Derived from Marvell Kirkwood CPU idle code
      8 * (arch/arm/mach-kirkwood/cpuidle.c)
      9 */
     10
     11#include <linux/kernel.h>
     12#include <linux/init.h>
     13#include <linux/platform_device.h>
     14#include <linux/cpuidle.h>
     15#include <linux/io.h>
     16#include <linux/export.h>
     17#include <asm/cpuidle.h>
     18
     19#include "cpuidle.h"
     20#include "ddr2.h"
     21
     22#define DAVINCI_CPUIDLE_MAX_STATES	2
     23
     24static void __iomem *ddr2_reg_base;
     25static bool ddr2_pdown;
     26
     27static void davinci_save_ddr_power(int enter, bool pdown)
     28{
     29	u32 val;
     30
     31	val = __raw_readl(ddr2_reg_base + DDR2_SDRCR_OFFSET);
     32
     33	if (enter) {
     34		if (pdown)
     35			val |= DDR2_SRPD_BIT;
     36		else
     37			val &= ~DDR2_SRPD_BIT;
     38		val |= DDR2_LPMODEN_BIT;
     39	} else {
     40		val &= ~(DDR2_SRPD_BIT | DDR2_LPMODEN_BIT);
     41	}
     42
     43	__raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET);
     44}
     45
     46/* Actual code that puts the SoC in different idle states */
     47static int davinci_enter_idle(struct cpuidle_device *dev,
     48			      struct cpuidle_driver *drv, int index)
     49{
     50	davinci_save_ddr_power(1, ddr2_pdown);
     51	cpu_do_idle();
     52	davinci_save_ddr_power(0, ddr2_pdown);
     53
     54	return index;
     55}
     56
     57static struct cpuidle_driver davinci_idle_driver = {
     58	.name			= "cpuidle-davinci",
     59	.owner			= THIS_MODULE,
     60	.states[0]		= ARM_CPUIDLE_WFI_STATE,
     61	.states[1]		= {
     62		.enter			= davinci_enter_idle,
     63		.exit_latency		= 10,
     64		.target_residency	= 10000,
     65		.name			= "DDR SR",
     66		.desc			= "WFI and DDR Self Refresh",
     67	},
     68	.state_count = DAVINCI_CPUIDLE_MAX_STATES,
     69};
     70
     71static int __init davinci_cpuidle_probe(struct platform_device *pdev)
     72{
     73	struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
     74
     75	if (!pdata) {
     76		dev_err(&pdev->dev, "cannot get platform data\n");
     77		return -ENOENT;
     78	}
     79
     80	ddr2_reg_base = pdata->ddr2_ctlr_base;
     81
     82	ddr2_pdown = pdata->ddr2_pdown;
     83
     84	return cpuidle_register(&davinci_idle_driver, NULL);
     85}
     86
     87static struct platform_driver davinci_cpuidle_driver = {
     88	.driver = {
     89		.name	= "cpuidle-davinci",
     90	},
     91};
     92
     93static int __init davinci_cpuidle_init(void)
     94{
     95	return platform_driver_probe(&davinci_cpuidle_driver,
     96						davinci_cpuidle_probe);
     97}
     98device_initcall(davinci_cpuidle_init);
     99