1/* 2 * pwr.c 3 * 4 * DSP-BIOS Bridge driver support functions for TI OMAP processors. 5 * 6 * PWR API for controlling DSP power states. 7 * 8 * Copyright (C) 2005-2006 Texas Instruments, Inc. 9 * 10 * This package is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 */ 18 19/* ----------------------------------- Host OS */ 20#include <dspbridge/host_os.h> 21 22/* ----------------------------------- This */ 23#include <dspbridge/pwr.h> 24 25/* ----------------------------------- Resource Manager */ 26#include <dspbridge/devdefs.h> 27#include <dspbridge/drv.h> 28 29/* ----------------------------------- Platform Manager */ 30#include <dspbridge/dev.h> 31 32/* ----------------------------------- Link Driver */ 33#include <dspbridge/dspioctl.h> 34 35/* 36 * ======== pwr_sleep_dsp ======== 37 * Send command to DSP to enter sleep state. 38 */ 39int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout) 40{ 41 struct bridge_drv_interface *intf_fxns; 42 struct bridge_dev_context *dw_context; 43 int status = -EPERM; 44 struct dev_object *hdev_obj = NULL; 45 u32 ioctlcode = 0; 46 u32 arg = timeout; 47 48 for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); 49 hdev_obj != NULL; 50 hdev_obj = 51 (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) { 52 if (dev_get_bridge_context(hdev_obj, 53 (struct bridge_dev_context **) 54 &dw_context)) { 55 continue; 56 } 57 if (dev_get_intf_fxns(hdev_obj, 58 (struct bridge_drv_interface **) 59 &intf_fxns)) { 60 continue; 61 } 62 if (sleep_code == PWR_DEEPSLEEP) 63 ioctlcode = BRDIOCTL_DEEPSLEEP; 64 else if (sleep_code == PWR_EMERGENCYDEEPSLEEP) 65 ioctlcode = BRDIOCTL_EMERGENCYSLEEP; 66 else 67 status = -EINVAL; 68 69 if (status != -EINVAL) { 70 status = (*intf_fxns->pfn_dev_cntrl) (dw_context, 71 ioctlcode, 72 (void *)&arg); 73 } 74 } 75 return status; 76} 77 78/* 79 * ======== pwr_wake_dsp ======== 80 * Send command to DSP to wake it from sleep. 81 */ 82int pwr_wake_dsp(const u32 timeout) 83{ 84 struct bridge_drv_interface *intf_fxns; 85 struct bridge_dev_context *dw_context; 86 int status = -EPERM; 87 struct dev_object *hdev_obj = NULL; 88 u32 arg = timeout; 89 90 for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); 91 hdev_obj != NULL; 92 hdev_obj = (struct dev_object *)drv_get_next_dev_object 93 ((u32) hdev_obj)) { 94 if (!(dev_get_bridge_context(hdev_obj, 95 (struct bridge_dev_context 96 **)&dw_context))) { 97 if (!(dev_get_intf_fxns(hdev_obj, 98 (struct bridge_drv_interface **)&intf_fxns))) { 99 status = 100 (*intf_fxns->pfn_dev_cntrl) (dw_context, 101 BRDIOCTL_WAKEUP, 102 (void *)&arg); 103 } 104 } 105 } 106 return status; 107} 108 109/* 110 * ======== pwr_pm_pre_scale======== 111 * Sends pre-notification message to DSP. 112 */ 113int pwr_pm_pre_scale(u16 voltage_domain, u32 level) 114{ 115 struct bridge_drv_interface *intf_fxns; 116 struct bridge_dev_context *dw_context; 117 int status = -EPERM; 118 struct dev_object *hdev_obj = NULL; 119 u32 arg[2]; 120 121 arg[0] = voltage_domain; 122 arg[1] = level; 123 124 for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); 125 hdev_obj != NULL; 126 hdev_obj = (struct dev_object *)drv_get_next_dev_object 127 ((u32) hdev_obj)) { 128 if (!(dev_get_bridge_context(hdev_obj, 129 (struct bridge_dev_context 130 **)&dw_context))) { 131 if (!(dev_get_intf_fxns(hdev_obj, 132 (struct bridge_drv_interface **)&intf_fxns))) { 133 status = 134 (*intf_fxns->pfn_dev_cntrl) (dw_context, 135 BRDIOCTL_PRESCALE_NOTIFY, 136 (void *)&arg); 137 } 138 } 139 } 140 return status; 141} 142 143/* 144 * ======== pwr_pm_post_scale======== 145 * Sends post-notification message to DSP. 146 */ 147int pwr_pm_post_scale(u16 voltage_domain, u32 level) 148{ 149 struct bridge_drv_interface *intf_fxns; 150 struct bridge_dev_context *dw_context; 151 int status = -EPERM; 152 struct dev_object *hdev_obj = NULL; 153 u32 arg[2]; 154 155 arg[0] = voltage_domain; 156 arg[1] = level; 157 158 for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); 159 hdev_obj != NULL; 160 hdev_obj = (struct dev_object *)drv_get_next_dev_object 161 ((u32) hdev_obj)) { 162 if (!(dev_get_bridge_context(hdev_obj, 163 (struct bridge_dev_context 164 **)&dw_context))) { 165 if (!(dev_get_intf_fxns(hdev_obj, 166 (struct bridge_drv_interface **)&intf_fxns))) { 167 status = 168 (*intf_fxns->pfn_dev_cntrl) (dw_context, 169 BRDIOCTL_POSTSCALE_NOTIFY, 170 (void *)&arg); 171 } 172 } 173 } 174 return status; 175 176} 177