1193323Sed/** 2193323Sed * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. 3193323Sed * Copyright (c) 2010-2012 Broadcom. All rights reserved. 4193323Sed * 5193323Sed * Redistribution and use in source and binary forms, with or without 6193323Sed * modification, are permitted provided that the following conditions 7193323Sed * are met: 8193323Sed * 1. Redistributions of source code must retain the above copyright 9193323Sed * notice, this list of conditions, and the following disclaimer, 10193323Sed * without modification. 11193323Sed * 2. Redistributions in binary form must reproduce the above copyright 12193323Sed * notice, this list of conditions and the following disclaimer in the 13193323Sed * documentation and/or other materials provided with the distribution. 14193323Sed * 3. The names of the above-listed copyright holders may not be used 15193323Sed * to endorse or promote products derived from this software without 16193323Sed * specific prior written permission. 17193323Sed * 18193323Sed * ALTERNATIVELY, this software may be distributed under the terms of the 19193323Sed * GNU General Public License ("GPL") version 2, as published by the Free 20193323Sed * Software Foundation. 21193323Sed * 22193323Sed * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23193323Sed * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24193323Sed * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25193323Sed * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 26193323Sed * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27193323Sed * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28193323Sed * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29193323Sed * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30193323Sed * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31193323Sed * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32193323Sed * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33193323Sed */ 34193323Sed 35193323Sed#ifndef VCHIQ_ARM_H 36198892Srdivacky#define VCHIQ_ARM_H 37198090Srdivacky 38193323Sed#include "vchiq_core.h" 39193323Sed 40193323Sed 41193323Sedenum vc_suspend_status { 42193323Sed VC_SUSPEND_FORCE_CANCELED = -3, /* Force suspend canceled, too busy */ 43193323Sed VC_SUSPEND_REJECTED = -2, /* Videocore rejected suspend request */ 44193323Sed VC_SUSPEND_FAILED = -1, /* Videocore suspend failed */ 45193323Sed VC_SUSPEND_IDLE = 0, /* VC active, no suspend actions */ 46193323Sed VC_SUSPEND_REQUESTED, /* User has requested suspend */ 47193323Sed VC_SUSPEND_IN_PROGRESS, /* Slot handler has recvd suspend request */ 48193323Sed VC_SUSPEND_SUSPENDED /* Videocore suspend succeeded */ 49202375Srdivacky}; 50202375Srdivacky 51193323Sedenum vc_resume_status { 52193323Sed VC_RESUME_FAILED = -1, /* Videocore resume failed */ 53193323Sed VC_RESUME_IDLE = 0, /* VC suspended, no resume actions */ 54195340Sed VC_RESUME_REQUESTED, /* User has requested resume */ 55195340Sed VC_RESUME_IN_PROGRESS, /* Slot handler has received resume request */ 56198090Srdivacky VC_RESUME_RESUMED /* Videocore resumed successfully (active) */ 57195340Sed}; 58195340Sed 59193323Sed 60193323Sedenum USE_TYPE_E { 61193323Sed USE_TYPE_SERVICE, 62193323Sed USE_TYPE_SERVICE_NO_RESUME, 63193323Sed USE_TYPE_VCHIQ 64193323Sed}; 65193323Sed 66193323Sed 67193323Sed 68193323Sedtypedef struct vchiq_arm_state_struct { 69193323Sed /* Keepalive-related data */ 70193323Sed VCHIQ_THREAD_T ka_thread; 71193323Sed struct completion ka_evt; 72193323Sed atomic_t ka_use_count; 73193323Sed atomic_t ka_use_ack_count; 74193323Sed atomic_t ka_release_count; 75193323Sed 76193323Sed struct completion vc_suspend_complete; 77193323Sed struct completion vc_resume_complete; 78193323Sed 79193323Sed rwlock_t susp_res_lock; 80193323Sed enum vc_suspend_status vc_suspend_state; 81203954Srdivacky enum vc_resume_status vc_resume_state; 82203954Srdivacky 83203954Srdivacky unsigned int wake_address; 84193323Sed 85193323Sed struct timer_list suspend_timer; 86193323Sed int suspend_timer_timeout; 87193323Sed int suspend_timer_running; 88193323Sed 89193323Sed /* Global use count for videocore. 90193323Sed ** This is equal to the sum of the use counts for all services. When 91193323Sed ** this hits zero the videocore suspend procedure will be initiated. 92193323Sed */ 93193323Sed int videocore_use_count; 94193323Sed 95204642Srdivacky /* Use count to track requests from videocore peer. 96204642Srdivacky ** This use count is not associated with a service, so needs to be 97198090Srdivacky ** tracked separately with the state. 98193323Sed */ 99193323Sed int peer_use_count; 100193323Sed 101193323Sed /* Flag to indicate whether resume is blocked. This happens when the 102193323Sed ** ARM is suspending 103193323Sed */ 104193323Sed struct completion resume_blocker; 105193323Sed int resume_blocked; 106193323Sed struct completion blocked_blocker; 107193323Sed int blocked_count; 108193323Sed 109198090Srdivacky int autosuspend_override; 110198090Srdivacky 111198090Srdivacky /* Flag to indicate that the first vchiq connect has made it through. 112198090Srdivacky ** This means that both sides should be fully ready, and we should 113198090Srdivacky ** be able to suspend after this point. 114198090Srdivacky */ 115204792Srdivacky int first_connect; 116198090Srdivacky 117198090Srdivacky unsigned long long suspend_start_time; 118198090Srdivacky unsigned long long sleep_start_time; 119203954Srdivacky unsigned long long resume_start_time; 120204792Srdivacky unsigned long long last_wake_time; 121204792Srdivacky 122193323Sed} VCHIQ_ARM_STATE_T; 123193323Sed 124193323Sedextern int vchiq_arm_log_level; 125203954Srdivackyextern int vchiq_susp_log_level; 126198090Srdivacky 127198090Srdivackyextern int __init 128198090Srdivackyvchiq_platform_init(VCHIQ_STATE_T *state); 129203954Srdivacky 130203954Srdivackyextern void __exit 131203954Srdivackyvchiq_platform_exit(VCHIQ_STATE_T *state); 132203954Srdivacky 133203954Srdivackyextern VCHIQ_STATE_T * 134203954Srdivackyvchiq_get_state(void); 135203954Srdivacky 136203954Srdivackyextern VCHIQ_STATUS_T 137203954Srdivackyvchiq_arm_vcsuspend(VCHIQ_STATE_T *state); 138203954Srdivacky 139203954Srdivackyextern VCHIQ_STATUS_T 140203954Srdivackyvchiq_arm_force_suspend(VCHIQ_STATE_T *state); 141203954Srdivacky 142203954Srdivackyextern int 143203954Srdivackyvchiq_arm_allow_resume(VCHIQ_STATE_T *state); 144203954Srdivacky 145203954Srdivackyextern VCHIQ_STATUS_T 146203954Srdivackyvchiq_arm_vcresume(VCHIQ_STATE_T *state); 147203954Srdivacky 148203954Srdivackyextern VCHIQ_STATUS_T 149203954Srdivackyvchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state); 150203954Srdivacky 151203954Srdivackyextern int 152203954Srdivackyvchiq_check_resume(VCHIQ_STATE_T *state); 153203954Srdivacky 154203954Srdivackyextern void 155203954Srdivackyvchiq_check_suspend(VCHIQ_STATE_T *state); 156203954Srdivacky 157203954SrdivackyVCHIQ_STATUS_T 158203954Srdivackyvchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle); 159203954Srdivacky 160203954Srdivackyextern VCHIQ_STATUS_T 161203954Srdivackyvchiq_platform_suspend(VCHIQ_STATE_T *state); 162203954Srdivacky 163203954Srdivackyextern int 164203954Srdivackyvchiq_platform_videocore_wanted(VCHIQ_STATE_T *state); 165203954Srdivacky 166203954Srdivackyextern int 167203954Srdivackyvchiq_platform_use_suspend_timer(void); 168203954Srdivacky 169203954Srdivackyextern void 170203954Srdivackyvchiq_dump_platform_use_state(VCHIQ_STATE_T *state); 171203954Srdivacky 172203954Srdivackyextern void 173203954Srdivackyvchiq_dump_service_use_state(VCHIQ_STATE_T *state); 174203954Srdivacky 175203954Srdivackyextern VCHIQ_ARM_STATE_T* 176203954Srdivackyvchiq_platform_get_arm_state(VCHIQ_STATE_T *state); 177203954Srdivacky 178203954Srdivackyextern int 179203954Srdivackyvchiq_videocore_wanted(VCHIQ_STATE_T *state); 180203954Srdivacky 181203954Srdivackyextern VCHIQ_STATUS_T 182203954Srdivackyvchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, 183203954Srdivacky enum USE_TYPE_E use_type); 184203954Srdivackyextern VCHIQ_STATUS_T 185203954Srdivackyvchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service); 186203954Srdivacky 187203954Srdivacky#ifdef notyet 188203954Srdivackyextern VCHIQ_DEBUGFS_NODE_T * 189203954Srdivackyvchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance); 190198090Srdivacky#endif 191198090Srdivacky 192198090Srdivackyextern int 193193323Sedvchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance); 194193323Sed 195193323Sedextern int 196193323Sedvchiq_instance_get_pid(VCHIQ_INSTANCE_T instance); 197193323Sed 198193323Sedextern int 199193323Sedvchiq_instance_get_trace(VCHIQ_INSTANCE_T instance); 200193323Sed 201193323Sedextern void 202193323Sedvchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace); 203193323Sed 204193323Sedextern void 205193323Sedset_suspend_state(VCHIQ_ARM_STATE_T *arm_state, 206198090Srdivacky enum vc_suspend_status new_state); 207203954Srdivacky 208203954Srdivackyextern void 209193323Sedset_resume_state(VCHIQ_ARM_STATE_T *arm_state, 210193323Sed enum vc_resume_status new_state); 211193323Sed 212193323Sedextern void 213193323Sedstart_suspend_timer(VCHIQ_ARM_STATE_T *arm_state); 214193323Sed 215193323Sed#endif /* VCHIQ_ARM_H */ 216193323Sed