summaryrefslogtreecommitdiff
path: root/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/tidspbridge/core/tiomap3430_pwr.c')
-rw-r--r--drivers/staging/tidspbridge/core/tiomap3430_pwr.c556
1 files changed, 0 insertions, 556 deletions
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
deleted file mode 100644
index 657104f37f7d..000000000000
--- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * tiomap_pwr.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implementation of DSP wake/sleep routines.
- *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-#include <linux/platform_data/dsp-omap.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/drv.h>
-#include <dspbridge/io_sm.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/brddefs.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/io.h>
-
-/* ------------------------------------ Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
-#include <dspbridge/pwr.h>
-
-/* ----------------------------------- Bridge Driver */
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/wdt.h>
-
-/* ----------------------------------- specific to this file */
-#include "_tiomap.h"
-#include "_tiomap_pwr.h"
-#include <mach-omap2/prm-regbits-34xx.h>
-#include <mach-omap2/cm-regbits-34xx.h>
-
-#define PWRSTST_TIMEOUT 200
-
-/*
- * ======== handle_constraints_set ========
- * Sets new DSP constraint
- */
-int handle_constraints_set(struct bridge_dev_context *dev_context,
- void *pargs)
-{
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 *constraint_val;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- constraint_val = (u32 *) (pargs);
- /* Read the target value requested by DSP */
- dev_dbg(bridge, "OPP: %s opp requested = 0x%x\n", __func__,
- (u32) *(constraint_val + 1));
-
- /* Set the new opp value */
- if (pdata->dsp_set_min_opp)
- (*pdata->dsp_set_min_opp) ((u32) *(constraint_val + 1));
-#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
- return 0;
-}
-
-/*
- * ======== handle_hibernation_from_dsp ========
- * Handle Hibernation requested from DSP
- */
-int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context)
-{
- int status = 0;
-#ifdef CONFIG_PM
- u16 timeout = PWRSTST_TIMEOUT / 10;
- u32 pwr_state;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 opplevel;
- struct io_mgr *hio_mgr;
-#endif
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
- /* Wait for DSP to move into OFF state */
- while ((pwr_state != PWRDM_POWER_OFF) && --timeout) {
- if (msleep_interruptible(10)) {
- pr_err("Waiting for DSP OFF mode interrupted\n");
- return -EPERM;
- }
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
- OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
- }
- if (timeout == 0) {
- pr_err("%s: Timed out waiting for DSP off mode\n", __func__);
- status = -ETIMEDOUT;
- return status;
- } else {
-
- /* Save mailbox settings */
- omap_mbox_save_ctx(dev_context->mbox);
-
- /* Turn off DSP Peripheral clocks and DSP Load monitor timer */
- status = dsp_clock_disable_all(dev_context->dsp_per_clks);
-
- /* Disable wdt on hibernation. */
- dsp_wdt_enable(false);
-
- if (!status) {
- /* Update the Bridger Driver state */
- dev_context->brd_state = BRD_DSP_HIBERNATION;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- status =
- dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
- if (!hio_mgr) {
- status = DSP_EHANDLE;
- return status;
- }
- io_sh_msetting(hio_mgr, SHM_GETOPP, &opplevel);
-
- /*
- * Set the OPP to low level before moving to OFF
- * mode
- */
- if (pdata->dsp_set_min_opp)
- (*pdata->dsp_set_min_opp) (VDD1_OPP1);
- status = 0;
-#endif /* CONFIG_TIDSPBRIDGE_DVFS */
- }
- }
-#endif
- return status;
-}
-
-/*
- * ======== sleep_dsp ========
- * Put DSP in low power consuming state.
- */
-int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
- void *pargs)
-{
- int status = 0;
-#ifdef CONFIG_PM
-#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
- struct deh_mgr *hdeh_mgr;
-#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
- u16 timeout = PWRSTST_TIMEOUT / 10;
- u32 pwr_state, target_pwr_state;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- /* Check if sleep code is valid */
- if ((dw_cmd != PWR_DEEPSLEEP) && (dw_cmd != PWR_EMERGENCYDEEPSLEEP))
- return -EINVAL;
-
- switch (dev_context->brd_state) {
- case BRD_RUNNING:
- omap_mbox_save_ctx(dev_context->mbox);
- if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
- sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
- dev_dbg(bridge, "PM: %s - sent hibernate cmd to DSP\n",
- __func__);
- target_pwr_state = PWRDM_POWER_OFF;
- } else {
- sm_interrupt_dsp(dev_context, MBX_PM_DSPRETENTION);
- target_pwr_state = PWRDM_POWER_RET;
- }
- break;
- case BRD_RETENTION:
- omap_mbox_save_ctx(dev_context->mbox);
- if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
- sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
- target_pwr_state = PWRDM_POWER_OFF;
- } else
- return 0;
- break;
- case BRD_HIBERNATION:
- case BRD_DSP_HIBERNATION:
- /* Already in Hibernation, so just return */
- dev_dbg(bridge, "PM: %s - DSP already in hibernation\n",
- __func__);
- return 0;
- case BRD_STOPPED:
- dev_dbg(bridge, "PM: %s - Board in STOP state\n", __func__);
- return 0;
- default:
- dev_dbg(bridge, "PM: %s - Bridge in Illegal state\n", __func__);
- return -EPERM;
- }
-
- /* Get the PRCM DSP power domain status */
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
-
- /* Wait for DSP to move into target power state */
- while ((pwr_state != target_pwr_state) && --timeout) {
- if (msleep_interruptible(10)) {
- pr_err("Waiting for DSP to Suspend interrupted\n");
- return -EPERM;
- }
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
- OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
- }
-
- if (!timeout) {
- pr_err("%s: Timed out waiting for DSP off mode, state %x\n",
- __func__, pwr_state);
-#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
- dev_get_deh_mgr(dev_context->dev_obj, &hdeh_mgr);
- bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0);
-#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
- return -ETIMEDOUT;
- } else {
- /* Update the Bridger Driver state */
- if (dsp_test_sleepstate == PWRDM_POWER_OFF)
- dev_context->brd_state = BRD_HIBERNATION;
- else
- dev_context->brd_state = BRD_RETENTION;
-
- /* Disable wdt on hibernation. */
- dsp_wdt_enable(false);
-
- /* Turn off DSP Peripheral clocks */
- status = dsp_clock_disable_all(dev_context->dsp_per_clks);
- if (status)
- return status;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- else if (target_pwr_state == PWRDM_POWER_OFF) {
- /*
- * Set the OPP to low level before moving to OFF mode
- */
- if (pdata->dsp_set_min_opp)
- (*pdata->dsp_set_min_opp) (VDD1_OPP1);
- }
-#endif /* CONFIG_TIDSPBRIDGE_DVFS */
- }
-#endif /* CONFIG_PM */
- return status;
-}
-
-/*
- * ======== wake_dsp ========
- * Wake up DSP from sleep.
- */
-int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
-{
- int status = 0;
-#ifdef CONFIG_PM
-
- /* Check the board state, if it is not 'SLEEP' then return */
- if (dev_context->brd_state == BRD_RUNNING ||
- dev_context->brd_state == BRD_STOPPED) {
- /* The Device is in 'RET' or 'OFF' state and Bridge state is not
- * 'SLEEP', this means state inconsistency, so return */
- return 0;
- }
-
- /* Send a wakeup message to DSP */
- sm_interrupt_dsp(dev_context, MBX_PM_DSPWAKEUP);
-
- /* Set the device state to RUNNIG */
- dev_context->brd_state = BRD_RUNNING;
-#endif /* CONFIG_PM */
- return status;
-}
-
-/*
- * ======== dsp_peripheral_clk_ctrl ========
- * Enable/Disable the DSP peripheral clocks as needed..
- */
-int dsp_peripheral_clk_ctrl(struct bridge_dev_context *dev_context,
- void *pargs)
-{
- u32 ext_clk = 0;
- u32 ext_clk_id = 0;
- u32 ext_clk_cmd = 0;
- u32 clk_id_index = MBX_PM_MAX_RESOURCES;
- u32 tmp_index;
- u32 dsp_per_clks_before;
- int status = 0;
-
- dsp_per_clks_before = dev_context->dsp_per_clks;
-
- ext_clk = (u32) *((u32 *) pargs);
- ext_clk_id = ext_clk & MBX_PM_CLK_IDMASK;
-
- /* process the power message -- TODO, keep it in a separate function */
- for (tmp_index = 0; tmp_index < MBX_PM_MAX_RESOURCES; tmp_index++) {
- if (ext_clk_id == bpwr_clkid[tmp_index]) {
- clk_id_index = tmp_index;
- break;
- }
- }
- /* TODO -- Assert may be a too hard restriction here.. May be we should
- * just return with failure when the CLK ID does not match */
- if (clk_id_index == MBX_PM_MAX_RESOURCES) {
- /* return with a more meaningfull error code */
- return -EPERM;
- }
- ext_clk_cmd = (ext_clk >> MBX_PM_CLK_CMDSHIFT) & MBX_PM_CLK_CMDMASK;
- switch (ext_clk_cmd) {
- case BPWR_DISABLE_CLOCK:
- status = dsp_clk_disable(bpwr_clks[clk_id_index].clk);
- dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id,
- false);
- if (!status) {
- (dev_context->dsp_per_clks) &=
- (~((u32) (1 << bpwr_clks[clk_id_index].clk)));
- }
- break;
- case BPWR_ENABLE_CLOCK:
- status = dsp_clk_enable(bpwr_clks[clk_id_index].clk);
- dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id, true);
- if (!status)
- (dev_context->dsp_per_clks) |=
- (1 << bpwr_clks[clk_id_index].clk);
- break;
- default:
- dev_dbg(bridge, "%s: Unsupported CMD\n", __func__);
- /* unsupported cmd */
- /* TODO -- provide support for AUTOIDLE Enable/Disable
- * commands */
- }
- return status;
-}
-
-/*
- * ========pre_scale_dsp========
- * Sends prescale notification to DSP
- *
- */
-int pre_scale_dsp(struct bridge_dev_context *dev_context, void *pargs)
-{
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 level;
- u32 voltage_domain;
-
- voltage_domain = *((u32 *) pargs);
- level = *((u32 *) pargs + 1);
-
- dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
- __func__, voltage_domain, level);
- if ((dev_context->brd_state == BRD_HIBERNATION) ||
- (dev_context->brd_state == BRD_RETENTION) ||
- (dev_context->brd_state == BRD_DSP_HIBERNATION)) {
- dev_dbg(bridge, "OPP: %s IVA in sleep. No message to DSP\n");
- return 0;
- } else if (dev_context->brd_state == BRD_RUNNING) {
- /* Send a prenotification to DSP */
- dev_dbg(bridge, "OPP: %s sent notification to DSP\n", __func__);
- sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_PRENOTIFY);
- return 0;
- } else {
- return -EPERM;
- }
-#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
- return 0;
-}
-
-/*
- * ========post_scale_dsp========
- * Sends postscale notification to DSP
- *
- */
-int post_scale_dsp(struct bridge_dev_context *dev_context,
- void *pargs)
-{
- int status = 0;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 level;
- u32 voltage_domain;
- struct io_mgr *hio_mgr;
-
- status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
- if (!hio_mgr)
- return -EFAULT;
-
- voltage_domain = *((u32 *) pargs);
- level = *((u32 *) pargs + 1);
- dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
- __func__, voltage_domain, level);
- if ((dev_context->brd_state == BRD_HIBERNATION) ||
- (dev_context->brd_state == BRD_RETENTION) ||
- (dev_context->brd_state == BRD_DSP_HIBERNATION)) {
- /* Update the OPP value in shared memory */
- io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
- dev_dbg(bridge, "OPP: %s IVA in sleep. Wrote to shm\n",
- __func__);
- } else if (dev_context->brd_state == BRD_RUNNING) {
- /* Update the OPP value in shared memory */
- io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
- /* Send a post notification to DSP */
- sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_POSTNOTIFY);
- dev_dbg(bridge,
- "OPP: %s wrote to shm. Sent post notification to DSP\n",
- __func__);
- } else {
- status = -EPERM;
- }
-#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
- return status;
-}
-
-void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable)
-{
- struct cfg_hostres *resources;
- int status = 0;
- u32 iva2_grpsel;
- u32 mpu_grpsel;
- struct dev_object *hdev_object = NULL;
- struct bridge_dev_context *bridge_context = NULL;
-
- hdev_object = (struct dev_object *)drv_get_first_dev_object();
- if (!hdev_object)
- return;
-
- status = dev_get_bridge_context(hdev_object, &bridge_context);
- if (!bridge_context)
- return;
-
- resources = bridge_context->resources;
- if (!resources)
- return;
-
- switch (clock_id) {
- case BPWR_GP_TIMER5:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_GP_TIMER6:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_GP_TIMER7:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_GP_TIMER8:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP1:
- iva2_grpsel = readl(resources->core_pm_base + 0xA8);
- mpu_grpsel = readl(resources->core_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
- }
- writel(iva2_grpsel, resources->core_pm_base + 0xA8);
- writel(mpu_grpsel, resources->core_pm_base + 0xA4);
- break;
- case BPWR_MCBSP2:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP3:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP4:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP5:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- }
-}