Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/arm/mach-davinci/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  pm.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * DaVinci Power Management Routines
 *
 * Copyright (C) 2009 Texas Instruments, Inc. https://www.ti.com/
 */


#include <linux/pm.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/spinlock.h>

#include <asm/cacheflush.h>
#include <asm/delay.h>
#include <asm/io.h>

#include "common.h"
#include "da8xx.h"
#include "mux.h"
#include "pm.h"
#include "clock.h"
#include "psc.h"
#include "sram.h"

#define DA850_PLL1_BASE  0x01e1a000
#define DEEPSLEEP_SLEEPCOUNT_MASK 0xFFFF
#define DEEPSLEEP_SLEEPCOUNT  128

static void (*davinci_sram_suspend) (struct davinci_pm_config *);
static struct davinci_pm_config pm_config = {
 .sleepcount = DEEPSLEEP_SLEEPCOUNT,
 .ddrpsc_num = DA8XX_LPSC1_EMIF3C,
};

static void davinci_sram_push(void *dest, void *src, unsigned int size)
{
 memcpy(dest, src, size);
 flush_icache_range((unsigned long)dest, (unsigned long)(dest + size));
}

static void davinci_pm_suspend(void)
{
 unsigned val;

 if (pm_config.cpupll_reg_base != pm_config.ddrpll_reg_base) {

  /* Switch CPU PLL to bypass mode */
  val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
  val &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
  __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

  udelay(PLL_BYPASS_TIME);

  /* Powerdown CPU PLL */
  val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
  val |= PLLCTL_PLLPWRDN;
  __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
 }

 /* Configure sleep count in deep sleep register */
 val = __raw_readl(pm_config.deepsleep_reg);
 val &= ~DEEPSLEEP_SLEEPCOUNT_MASK;
 val |= pm_config.sleepcount;
 __raw_writel(val, pm_config.deepsleep_reg);

 /* System goes to sleep in this call */
 davinci_sram_suspend(&pm_config);

 if (pm_config.cpupll_reg_base != pm_config.ddrpll_reg_base) {

  /* put CPU PLL in reset */
  val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
  val &= ~PLLCTL_PLLRST;
  __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

  /* put CPU PLL in power down */
  val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
  val &= ~PLLCTL_PLLPWRDN;
  __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

  /* wait for CPU PLL reset */
  udelay(PLL_RESET_TIME);

  /* bring CPU PLL out of reset */
  val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
  val |= PLLCTL_PLLRST;
  __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

  /* Wait for CPU PLL to lock */
  udelay(PLL_LOCK_TIME);

  /* Remove CPU PLL from bypass mode */
  val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
  val &= ~PLLCTL_PLLENSRC;
  val |= PLLCTL_PLLEN;
  __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
 }
}

static int davinci_pm_enter(suspend_state_t state)
{
 int ret = 0;

 switch (state) {
 case PM_SUSPEND_MEM:
  davinci_pm_suspend();
  break;
 default:
  ret = -EINVAL;
 }

 return ret;
}

static const struct platform_suspend_ops davinci_pm_ops = {
 .enter  = davinci_pm_enter,
 .valid  = suspend_valid_only_mem,
};

int __init davinci_pm_init(void)
{
 int ret;

 ret = davinci_cfg_reg(DA850_RTC_ALARM);
 if (ret)
  return ret;

 pm_config.ddr2_ctlr_base = da8xx_get_mem_ctlr();
 pm_config.deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);

 pm_config.cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
 if (!pm_config.cpupll_reg_base)
  return -ENOMEM;

 pm_config.ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K);
 if (!pm_config.ddrpll_reg_base) {
  ret = -ENOMEM;
  goto no_ddrpll_mem;
 }

 pm_config.ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
 if (!pm_config.ddrpsc_reg_base) {
  ret = -ENOMEM;
  goto no_ddrpsc_mem;
 }

 davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
 if (!davinci_sram_suspend) {
  pr_err("PM: cannot allocate SRAM memory\n");
  ret = -ENOMEM;
  goto no_sram_mem;
 }

 davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
      davinci_cpu_suspend_sz);

 suspend_set_ops(&davinci_pm_ops);

 return 0;

no_sram_mem:
 iounmap(pm_config.ddrpsc_reg_base);
no_ddrpsc_mem:
 iounmap(pm_config.ddrpll_reg_base);
no_ddrpll_mem:
 iounmap(pm_config.cpupll_reg_base);
 return ret;
}

Messung V0.5
C=93 H=76 G=84

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.