/* * pwr.c * * DSP-BIOS Bridge driver support functions for TI OMAP processors. * * PWR API for controlling DSP power states. * * Copyright (C) 2005-2006 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> /* ----------------------------------- This */ #include <dspbridge/pwr.h> /* ----------------------------------- Resource Manager */ #include <dspbridge/devdefs.h> #include <dspbridge/drv.h> /* ----------------------------------- Platform Manager */ #include <dspbridge/dev.h> /* ----------------------------------- Link Driver */ #include <dspbridge/dspioctl.h> /* * ======== pwr_sleep_dsp ======== * Send command to DSP to enter sleep state. */ int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout) { struct bridge_drv_interface *intf_fxns; struct bridge_dev_context *dw_context; int status = -EPERM; struct dev_object *hdev_obj = NULL; u32 ioctlcode = 0; u32 arg = timeout; for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); hdev_obj != NULL; hdev_obj = (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) { if (dev_get_bridge_context(hdev_obj, (struct bridge_dev_context **) &dw_context)) { continue; } if (dev_get_intf_fxns(hdev_obj, (struct bridge_drv_interface **) &intf_fxns)) { continue; } if (sleep_code == PWR_DEEPSLEEP) ioctlcode = BRDIOCTL_DEEPSLEEP; else if (sleep_code == PWR_EMERGENCYDEEPSLEEP) ioctlcode = BRDIOCTL_EMERGENCYSLEEP; else status = -EINVAL; if (status != -EINVAL) { status = (*intf_fxns->dev_cntrl) (dw_context, ioctlcode, (void *)&arg); } } return status; } /* * ======== pwr_wake_dsp ======== * Send command to DSP to wake it from sleep. */ int pwr_wake_dsp(const u32 timeout) { struct bridge_drv_interface *intf_fxns; struct bridge_dev_context *dw_context; int status = -EPERM; struct dev_object *hdev_obj = NULL; u32 arg = timeout; for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); hdev_obj != NULL; hdev_obj = (struct dev_object *)drv_get_next_dev_object ((u32) hdev_obj)) { if (!(dev_get_bridge_context(hdev_obj, (struct bridge_dev_context **)&dw_context))) { if (!(dev_get_intf_fxns(hdev_obj, (struct bridge_drv_interface **)&intf_fxns))) { status = (*intf_fxns->dev_cntrl) (dw_context, BRDIOCTL_WAKEUP, (void *)&arg); } } } return status; } /* * ======== pwr_pm_pre_scale======== * Sends pre-notification message to DSP. */ int pwr_pm_pre_scale(u16 voltage_domain, u32 level) { struct bridge_drv_interface *intf_fxns; struct bridge_dev_context *dw_context; int status = -EPERM; struct dev_object *hdev_obj = NULL; u32 arg[2]; arg[0] = voltage_domain; arg[1] = level; for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); hdev_obj != NULL; hdev_obj = (struct dev_object *)drv_get_next_dev_object ((u32) hdev_obj)) { if (!(dev_get_bridge_context(hdev_obj, (struct bridge_dev_context **)&dw_context))) { if (!(dev_get_intf_fxns(hdev_obj, (struct bridge_drv_interface **)&intf_fxns))) { status = (*intf_fxns->dev_cntrl) (dw_context, BRDIOCTL_PRESCALE_NOTIFY, (void *)&arg); } } } return status; } /* * ======== pwr_pm_post_scale======== * Sends post-notification message to DSP. */ int pwr_pm_post_scale(u16 voltage_domain, u32 level) { struct bridge_drv_interface *intf_fxns; struct bridge_dev_context *dw_context; int status = -EPERM; struct dev_object *hdev_obj = NULL; u32 arg[2]; arg[0] = voltage_domain; arg[1] = level; for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); hdev_obj != NULL; hdev_obj = (struct dev_object *)drv_get_next_dev_object ((u32) hdev_obj)) { if (!(dev_get_bridge_context(hdev_obj, (struct bridge_dev_context **)&dw_context))) { if (!(dev_get_intf_fxns(hdev_obj, (struct bridge_drv_interface **)&intf_fxns))) { status = (*intf_fxns->dev_cntrl) (dw_context, BRDIOCTL_POSTSCALE_NOTIFY, (void *)&arg); } } } return status; }