├── Android.mk ├── README.md ├── cryptfs_hw ├── Android.mk ├── cryptfs_hw.c └── cryptfs_hw.h ├── dtbtool ├── Android.mk ├── dtbtool.c └── dtbtool.txt ├── extractors ├── README.md ├── audio-msm8996.txt ├── extract-files.sh ├── graphics-msm8916-32.txt ├── graphics-msm8916-64.txt ├── graphics-msm8960.txt ├── graphics-msm8974.txt ├── graphics-msm8992.txt ├── graphics-msm8994.txt ├── graphics-msm8996.txt └── setup-makefiles.sh ├── power ├── Android.mk ├── hint-data.c ├── hint-data.h ├── list.c ├── list.h ├── metadata-defs.h ├── metadata-parser.c ├── performance.h ├── power-8084.c ├── power-8226.c ├── power-8610.c ├── power-8909.c ├── power-8916.c ├── power-8937.c ├── power-8952.c ├── power-8960.c ├── power-8974.c ├── power-8992.c ├── power-8994.c ├── power-8996.c ├── power-common.h ├── power-feature-default.c ├── power-feature.h ├── power.c ├── utils.c └── utils.h ├── recovery ├── Android.mk ├── miniui │ ├── Android.mk │ └── msm_recovery_ui.cpp └── oem-recovery │ ├── Android.mk │ ├── dec.cpp │ ├── dec.h │ ├── gpt-utils.cpp │ ├── gpt-utils.h │ └── oem-updater.cpp ├── releasetools.py └── sdllvm-lto-defs.mk /Android.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014 The CyanogenMod Project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM))) 17 | 18 | include $(all-subdir-makefiles) 19 | 20 | endif 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Generic common qcom configuration tools 2 | =============================== 3 | 4 | Copyright 2014 - The CyanogenMod Project 5 | -------------------------------------------------------------------------------- /cryptfs_hw/Android.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(TARGET_HW_DISK_ENCRYPTION),true) 2 | LOCAL_PATH:= $(call my-dir) 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_PROPRIETARY_MODULE := true 6 | 7 | sourceFiles := \ 8 | cryptfs_hw.c 9 | 10 | commonSharedLibraries := \ 11 | libcutils \ 12 | libutils \ 13 | libdl \ 14 | libhardware 15 | commonIncludes := \ 16 | hardware/libhardware/include/hardware/ 17 | 18 | LOCAL_C_INCLUDES := $(commonIncludes) 19 | LOCAL_SRC_FILES := $(sourceFiles) 20 | 21 | LOCAL_MODULE_TAGS := optional 22 | LOCAL_MODULE:= libcryptfs_hw 23 | LOCAL_SHARED_LIBRARIES := $(commonSharedLibraries) 24 | 25 | LOCAL_MODULE_OWNER := qcom 26 | 27 | ifeq ($(TARGET_SWV8_DISK_ENCRYPTION),true) 28 | LOCAL_CFLAGS += -DCONFIG_SWV8_DISK_ENCRYPTION 29 | endif 30 | 31 | # USE_ICE_FOR_STORAGE_ENCRYPTION would be true in future if 32 | # TARGET_USE_EMMC_USE_ICE is set 33 | ifeq ($(TARGET_USE_UFS_ICE),true) 34 | LOCAL_CFLAGS += -DUSE_ICE_FOR_STORAGE_ENCRYPTION 35 | endif 36 | 37 | include $(BUILD_SHARED_LIBRARY) 38 | endif 39 | -------------------------------------------------------------------------------- /cryptfs_hw/cryptfs_hw.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014, The Linux Foundation. All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions are 5 | * met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above 9 | * copyright notice, this list of conditions and the following 10 | * disclaimer in the documentation and/or other materials provided 11 | * with the distribution. 12 | * * Neither the name of The Linux Foundation nor the names of its 13 | * contributors may be used to endorse or promote products derived 14 | * from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "cutils/log.h" 39 | #include "cutils/properties.h" 40 | #include "cutils/android_reboot.h" 41 | #include "keymaster_common.h" 42 | #include "hardware.h" 43 | 44 | 45 | // When device comes up or when user tries to change the password, user can 46 | // try wrong password upto a certain number of times. If user enters wrong 47 | // password further, HW would wipe all disk encryption related crypto data 48 | // and would return an error ERR_MAX_PASSWORD_ATTEMPTS to VOLD. VOLD would 49 | // wipe userdata partition once this error is received. 50 | #define ERR_MAX_PASSWORD_ATTEMPTS -10 51 | #define QSEECOM_DISK_ENCRYPTION 1 52 | #define QSEECOM_UFS_ICE_DISK_ENCRYPTION 3 53 | #define QSEECOM_SDCC_ICE_DISK_ENCRYPTION 4 54 | #define MAX_PASSWORD_LEN 32 55 | #define QTI_ICE_STORAGE_UFS 1 56 | #define QTI_ICE_STORAGE_SDCC 2 57 | 58 | /* Operations that be performed on HW based device encryption key */ 59 | #define SET_HW_DISK_ENC_KEY 1 60 | #define UPDATE_HW_DISK_ENC_KEY 2 61 | #define MAX_DEVICE_ID_LENGTH 4 /* 4 = 3 (MAX_SOC_ID_LENGTH) + 1 */ 62 | 63 | static unsigned int cpu_id[] = { 64 | 239, /* MSM8939 SOC ID */ 65 | }; 66 | 67 | #define KEYMASTER_PARTITION_NAME "/dev/block/bootdevice/by-name/keymaster" 68 | 69 | static int loaded_library = 0; 70 | static int (*qseecom_create_key)(int, void*); 71 | static int (*qseecom_update_key)(int, void*, void*); 72 | static int (*qseecom_wipe_key)(int); 73 | 74 | static int map_usage(int usage) 75 | { 76 | int storage_type = is_ice_enabled(); 77 | if (usage == QSEECOM_DISK_ENCRYPTION) { 78 | if (storage_type == QTI_ICE_STORAGE_UFS) { 79 | return QSEECOM_UFS_ICE_DISK_ENCRYPTION; 80 | } 81 | else if (storage_type == QTI_ICE_STORAGE_SDCC) { 82 | return QSEECOM_SDCC_ICE_DISK_ENCRYPTION ; 83 | } 84 | } 85 | return usage; 86 | } 87 | 88 | static unsigned char* get_tmp_passwd(const char* passwd) 89 | { 90 | int passwd_len = 0; 91 | unsigned char * tmp_passwd = NULL; 92 | if(passwd) { 93 | tmp_passwd = (unsigned char*)malloc(MAX_PASSWORD_LEN); 94 | if(tmp_passwd) { 95 | memset(tmp_passwd, 0, MAX_PASSWORD_LEN); 96 | passwd_len = (strlen(passwd) > MAX_PASSWORD_LEN) ? MAX_PASSWORD_LEN : strlen(passwd); 97 | memcpy(tmp_passwd, passwd, passwd_len); 98 | } else { 99 | SLOGE("%s: Failed to allocate memory for tmp passwd \n", __func__); 100 | } 101 | } else { 102 | SLOGE("%s: Passed argument is NULL \n", __func__); 103 | } 104 | return tmp_passwd; 105 | } 106 | 107 | static void wipe_userdata() 108 | { 109 | mkdir("/cache/recovery", 0700); 110 | int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC|O_NOFOLLOW, 0600); 111 | if (fd >= 0) { 112 | write(fd, "--wipe_data", strlen("--wipe_data") + 1); 113 | close(fd); 114 | } else { 115 | SLOGE("could not open /cache/recovery/command\n"); 116 | } 117 | android_reboot(ANDROID_RB_RESTART2, 0, "recovery"); 118 | } 119 | 120 | static int load_qseecom_library() 121 | { 122 | const char *error = NULL; 123 | if (loaded_library) 124 | return loaded_library; 125 | 126 | #ifdef __LP64__ 127 | void * handle = dlopen("/vendor/lib64/libQSEEComAPI.so", RTLD_NOW); 128 | #else 129 | void * handle = dlopen("/vendor/lib/libQSEEComAPI.so", RTLD_NOW); 130 | #endif 131 | if(handle) { 132 | dlerror(); /* Clear any existing error */ 133 | *(void **) (&qseecom_create_key) = dlsym(handle,"QSEECom_create_key"); 134 | 135 | if((error = dlerror()) == NULL) { 136 | SLOGD("Success loading QSEECom_create_key \n"); 137 | *(void **) (&qseecom_update_key) = dlsym(handle,"QSEECom_update_key_user_info"); 138 | if ((error = dlerror()) == NULL) { 139 | SLOGD("Success loading QSEECom_update_key_user_info\n"); 140 | *(void **) (&qseecom_wipe_key) = dlsym(handle,"QSEECom_wipe_key"); 141 | if ((error = dlerror()) == NULL) { 142 | loaded_library = 1; 143 | SLOGD("Success loading QSEECom_wipe_key \n"); 144 | } 145 | else 146 | SLOGE("Error %s loading symbols for QSEECom APIs \n", error); 147 | } 148 | else 149 | SLOGE("Error %s loading symbols for QSEECom APIs \n", error); 150 | } 151 | } else { 152 | SLOGE("Could not load libQSEEComAPI.so \n"); 153 | } 154 | 155 | if(error) 156 | dlclose(handle); 157 | 158 | return loaded_library; 159 | } 160 | 161 | /* 162 | * For NON-ICE targets, it would return 0 on success. On ICE based targets, 163 | * it would return key index in the ICE Key LUT 164 | */ 165 | static int set_key(const char* currentpasswd, const char* passwd, const char* enc_mode, int operation) 166 | { 167 | int err = -1; 168 | if (is_hw_disk_encryption(enc_mode) && load_qseecom_library()) { 169 | unsigned char* tmp_passwd = get_tmp_passwd(passwd); 170 | unsigned char* tmp_currentpasswd = get_tmp_passwd(currentpasswd); 171 | if(tmp_passwd) { 172 | if (operation == UPDATE_HW_DISK_ENC_KEY) { 173 | if (tmp_currentpasswd) 174 | err = qseecom_update_key(map_usage(QSEECOM_DISK_ENCRYPTION), tmp_currentpasswd, tmp_passwd); 175 | } else if (operation == SET_HW_DISK_ENC_KEY) { 176 | err = qseecom_create_key(map_usage(QSEECOM_DISK_ENCRYPTION), tmp_passwd); 177 | } 178 | if(err < 0) { 179 | if(ERR_MAX_PASSWORD_ATTEMPTS == err) 180 | wipe_userdata(); 181 | } 182 | free(tmp_passwd); 183 | free(tmp_currentpasswd); 184 | } 185 | } 186 | return err; 187 | } 188 | 189 | int set_hw_device_encryption_key(const char* passwd, const char* enc_mode) 190 | { 191 | return set_key(NULL, passwd, enc_mode, SET_HW_DISK_ENC_KEY); 192 | } 193 | 194 | int update_hw_device_encryption_key(const char* oldpw, const char* newpw, const char* enc_mode) 195 | { 196 | return set_key(oldpw, newpw, enc_mode, UPDATE_HW_DISK_ENC_KEY); 197 | } 198 | 199 | unsigned int is_hw_disk_encryption(const char* encryption_mode) 200 | { 201 | int ret = 0; 202 | if(encryption_mode) { 203 | if (!strcmp(encryption_mode, "aes-xts")) { 204 | SLOGD("HW based disk encryption is enabled \n"); 205 | ret = 1; 206 | } 207 | } 208 | return ret; 209 | } 210 | 211 | int clear_hw_device_encryption_key(void) 212 | { 213 | if (load_qseecom_library()) 214 | return qseecom_wipe_key(map_usage(QSEECOM_DISK_ENCRYPTION)); 215 | 216 | return 0; 217 | } 218 | 219 | /* 220 | * By default HW FDE is enabled, if the execution comes to 221 | * is_hw_fde_enabled() API then for specific device/soc id, 222 | * HW FDE is disabled. 223 | */ 224 | #ifdef CONFIG_SWV8_DISK_ENCRYPTION 225 | unsigned int is_hw_fde_enabled(void) 226 | { 227 | unsigned int device_id = -1; 228 | unsigned int array_size; 229 | unsigned int status = 1; 230 | FILE *fd = NULL; 231 | unsigned int i; 232 | int ret = -1; 233 | char buf[MAX_DEVICE_ID_LENGTH]; 234 | 235 | fd = fopen("/sys/devices/soc0/soc_id", "r"); 236 | if (fd) { 237 | ret = fread(buf, 1, MAX_DEVICE_ID_LENGTH, fd); 238 | fclose(fd); 239 | } else { 240 | fd = fopen("/sys/devices/system/soc/soc0/id", "r"); 241 | if (fd) { 242 | ret = fread(buf, 1, MAX_DEVICE_ID_LENGTH, fd); 243 | fclose(fd); 244 | } 245 | } 246 | 247 | if (ret > 0) { 248 | device_id = atoi(buf); 249 | } else { 250 | SLOGE("Failed to read device id"); 251 | return status; 252 | } 253 | 254 | array_size = sizeof(cpu_id) / sizeof(cpu_id[0]); 255 | for (i = 0; i < array_size; i++) { 256 | if (device_id == cpu_id[i]) { 257 | status = 0; 258 | break; 259 | } 260 | } 261 | 262 | return status; 263 | } 264 | #else 265 | unsigned int is_hw_fde_enabled(void) 266 | { 267 | return 1; 268 | } 269 | #endif 270 | 271 | int is_ice_enabled(void) 272 | { 273 | char prop_storage[PATH_MAX]; 274 | int storage_type = 0; 275 | int fd; 276 | 277 | if (property_get("ro.boot.bootdevice", prop_storage, "")) { 278 | if (strstr(prop_storage, "ufs")) { 279 | /* All UFS based devices has ICE in it. So we dont need 280 | * to check if corresponding device exists or not 281 | */ 282 | storage_type = QTI_ICE_STORAGE_UFS; 283 | } else if (strstr(prop_storage, "sdhc")) { 284 | if (access("/dev/icesdcc", F_OK) != -1) 285 | storage_type = QTI_ICE_STORAGE_SDCC; 286 | } 287 | } 288 | return storage_type; 289 | } 290 | 291 | static int get_keymaster_version() 292 | { 293 | int rc = -1; 294 | const hw_module_t* mod; 295 | rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 296 | if (rc) { 297 | SLOGE("could not find any keystore module"); 298 | return rc; 299 | } 300 | 301 | return mod->module_api_version; 302 | } 303 | 304 | int should_use_keymaster() 305 | { 306 | /* HW FDE key would be tied to keymaster only if: 307 | * New Keymaster is available 308 | * keymaster partition exists on the device 309 | */ 310 | int rc = 0; 311 | if (get_keymaster_version() != KEYMASTER_MODULE_API_VERSION_1_0) { 312 | SLOGI("Keymaster version is not 1.0"); 313 | return rc; 314 | } 315 | 316 | if (access(KEYMASTER_PARTITION_NAME, F_OK) == -1) { 317 | SLOGI("Keymaster partition does not exists"); 318 | return rc; 319 | } 320 | 321 | return 1; 322 | } 323 | -------------------------------------------------------------------------------- /cryptfs_hw/cryptfs_hw.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014, The Linux Foundation. All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions are 5 | * met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above 9 | * copyright notice, this list of conditions and the following 10 | * disclaimer in the documentation and/or other materials provided 11 | * with the distribution. 12 | * * Neither the name of The Linux Foundation nor the names of its 13 | * contributors may be used to endorse or promote products derived 14 | * from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __CRYPTFS_HW_H_ 30 | #define __CRYPTFS_HW_H_ 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | unsigned int wipe_hw_device_encryption_key(const char*); 37 | int set_hw_device_encryption_key(const char*, const char*); 38 | int update_hw_device_encryption_key(const char*, const char*, const char*); 39 | int clear_hw_device_encryption_key(void); 40 | unsigned int is_hw_disk_encryption(const char*); 41 | unsigned int is_hw_fde_enabled(void); 42 | int is_ice_enabled(void); 43 | int should_use_keymaster(); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | #endif 49 | -------------------------------------------------------------------------------- /dtbtool/Android.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(BOARD_KERNEL_SEPARATED_DT),true) 2 | LOCAL_PATH := $(call my-dir) 3 | 4 | include $(CLEAR_VARS) 5 | 6 | LOCAL_SRC_FILES := \ 7 | dtbtool.c 8 | 9 | LOCAL_CFLAGS += \ 10 | -Wall 11 | 12 | ## Hybrid v1/v2 dtbTool. Use a different name to avoid conflicts with copies in device repos 13 | LOCAL_MODULE := dtbToolCM 14 | LOCAL_MODULE_TAGS := optional 15 | 16 | include $(BUILD_HOST_EXECUTABLE) 17 | endif 18 | -------------------------------------------------------------------------------- /dtbtool/dtbtool.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. 2 | 3 | Redistribution and use in source form and compiled forms (SGML, HTML, 4 | PDF, PostScript, RTF and so forth) with or without modification, are 5 | permitted provided that the following conditions are met: 6 | 7 | Redistributions in source form must retain the above copyright 8 | notice, this list of conditions and the following disclaimer as the 9 | first lines of this file unmodified. 10 | 11 | Redistributions in compiled form (transformed to other DTDs, 12 | converted to PDF, PostScript, RTF and other formats) must reproduce 13 | the above copyright notice, this list of conditions and the following 14 | disclaimer in the documentation and/or other materials provided with 15 | the distribution. 16 | 17 | THIS DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND 20 | NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD 21 | DOCUMENTATION PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 28 | DAMAGE. 29 | 30 | 31 | Android - Table of Device Tree 32 | ============================== 33 | 34 | 0) Document revision 35 | v1.0 - Initial version (dng) 36 | v1.1 - Add v2 format to allow subtype (dng) 37 | 38 | 1) Android boot image: 39 | ---------------------- 40 | 1.1) Header: 41 | 1) Magic (8B) 42 | 2) kernel size (4B) 43 | 3) kernel addr (4B) 44 | 4) ramdisk size (4B) 45 | 5) ramdisk addr (4B) 46 | 6) 2ndary size (4B) 47 | 7) 2ndary addr (4B) 48 | 8) tags addr (4B) 49 | 9) page size (4B) 50 | 10) unused #1 (4B) (zero in standard Android) 51 | 11) unused #2 (4B) (zero in standard Android) 52 | 12) product name (16B) 53 | 13) kernel cmdline (512B) 54 | 14) id (8B) 55 | 56 | 1.2) Layout: 57 | A) header (as above - 1 page) 58 | B) kernel (n pages) 59 | C) ramdisk (m pages) 60 | D) second stage (o pages) 61 | 62 | 2) QC table of device tree 63 | -------------------------- 64 | 2.1) Changes: 65 | i) use "unused #1, #2" members in existing boot image 66 | header to point to new table of device tree 67 | (#1 - size of QC table of DT) 68 | ii) append table of device tree (described later) 69 | after "D) second stage" 70 | 71 | 2.2) Format: 72 | size 73 | x +------------------+ 74 | | | MAGIC ("QCDT") | 4B 75 | | +------------------+ 76 | header | VERSION | uint32 (version 3) 77 | | +------------------+ 78 | | | num of DTBs | uint32 (number of DTB entries) 79 | x +------------------+ 80 | | | platform id #1 | uint32 (e.g. ID for MSM8974) 81 | | +------------------+ 82 | | | variant id #1 | uint32 (e.g. ID for CDP, MTP) 83 | | +------------------+ 84 | | | subtype id #1 | uint32 (e.g. ID for subtype) (QCDT v2) 85 | device +------------------+ 86 | #1 | soc rev #1 | uint32 (e.g. MSM8974 v2) 87 | entry +------------------+ 88 | | | pmic0 #1 | uint32 (pmic0-> first smallest SID of existing pmic) 89 | | +------------------+ 90 | | | pmic1 #1 | uint32 (pmic1-> secondary smallest SID of existing pmic) 91 | | +------------------+ 92 | | | pmic2 #1 | uint32 (pmic2-> third smallest SID of existing pmic) 93 | | +------------------+ 94 | | | pmic3 #1 | uint32 (pmic3-> fourth smallest SID of existing pmic) 95 | | +------------------+ 96 | | | offset #1 | uint32 (byte offset from start/before MAGIC 97 | | +------------------+ to DTB entry) 98 | | | size #1 | uint32 (size in bytes of DTB blob) 99 | x +------------------+ 100 | . . 101 | . . (repeat) 102 | . . 103 | 104 | x +------------------+ 105 | | | platform id #Z | uint32 (e.g. ID for MSM8974) 106 | | +------------------+ 107 | device | variant id #Z | uint32 (e.g. ID for CDP, MTP) 108 | #Z +------------------+ 109 | entry | subtype id #Z | uint32 (e.g. ID for subtype) (QCDT v2) 110 | (last) +------------------+ 111 | | | soc rev #Z | uint32 (e.g. MSM8974 v2) 112 | | +------------------+ 113 | | | pmic0 #1 | uint32 (pmic0-> first smallest SID of existing pmic) 114 | | +------------------+ 115 | | | pmic1 #1 | uint32 (pmic1-> secondary smallest SID of existing pmic) 116 | | +------------------+ 117 | | | pmic2 #1 | uint32 (pmic2-> third smallest SID of existing pmic) 118 | | +------------------+ 119 | | | pmic3 #1 | uint32 (pmic3-> fourth smallest SID of existing pmic) 120 | | +------------------+ 121 | | | offset #Z | uint32 (byte offset from start/before MAGIC 122 | x +------------------+ to DTB entry) 123 | | 0 ("zero") | uint32 (end of list delimiter) 124 | +------------------+ to DTB entry) 125 | | padding | variable length for next DTB to start on 126 | +------------------+ page boundary 127 | | DTB #1 | variable (start is page aligned) 128 | | | 129 | | | 130 | +------------------+ 131 | | padding | variable length for next DTB to start on 132 | +------------------+ page boundary 133 | . 134 | . 135 | . 136 | 137 | +------------------+ 138 | | DTB #Z (last) | variable (start is page aligned) 139 | | | 140 | | | 141 | +------------------+ 142 | 143 | 3) Operations 144 | ------------- 145 | 3.1) Build-time: 146 | 1) Each DTS per device will add a "qcom,msm-id" entry 147 | e.g. for msm8974-sim.dts, add 148 | qcom,msm-id = ; 149 | or 150 | qcom,msm-id = ; 151 | qcom,board-id = ; 152 | or 153 | qcom,msm-id = ; 154 | qcom,board-id = ; 155 | qcom,pmic-id = ; 156 | x = ID for msm8974 157 | y = ID for CDP, MTP, etc. 158 | y' = ID for subtype (assumed zero if absent) 159 | z = ID for soc revision 160 | a = pmic0 161 | b = pmic1 162 | c = pmic2 163 | d = pmic3 164 | SBL populates the pmic entries always in ascending order of SID, so 165 | pmic0-> SID0, pmic1-> SID1, pmic2-> SID2, pmic3-> SID3. 166 | e.g. for qcom,pmic-id = 167 | Board X = MSM8994 + PM8994 + PMI8994 (Existing boards [ROW]) 168 | Board Y = MSM8994 + PM8994 + PMI8994 + PM8004 (Internal SS board variant) 169 | Board Z = MSM8994 + PM8994 + PM8004 (Boards that SS will be making) 170 | 171 | For all boards X, Y, and Z, PMICs have the following SIDs and REVID SUBTYPEs 172 | (i.e. PMIC Model): 173 | PM8994 - SID 0 and 1; subtype = 9 174 | PMI8994 - SID 2 and 3; subtype = 10 175 | PM8004 - SID 4 and 5; subtype = 12 176 | 177 | LK using SMEM PMIC info(1 as major and 0 as minor version for example): 178 | Board X: qcom,pmic-id = <0x0109 0x010A 0x0 0x0>; 179 | Board Y: qcom,pmic-id = <0x0109 0x010A 0x010C 0x0>; 180 | Board Z: qcom,pmic-id = <0x0109 0x010C 0x0 0x0>; 181 | 182 | The entry can optionally be an array: 183 | qcom,msm-id = , , ...; 184 | or 185 | qcom,msm-id = , , ...; 186 | qcom,board-id = , ...; 187 | or 188 | qcom,msm-id = , , ...; 189 | qcom,board-id = , ...; 190 | qcom,pmic-id = , ...; 191 | Note that qcom,msm-id, qcom,board-id and qcom,pmic-id are not matched pairs. 192 | 2) Kernel compile will generate the DTB 193 | 3) Android build will run a new tool (dtbTool) 194 | a) scan the DTB output directory for all compiled DTB 195 | b) decompile the DTB for "qcom,msm-id"/"qcom,board-id"/"qcom,pmic-id" 196 | c) generate the QC table of device tree in sorted 197 | order (platform, variant, subtype, soc rev, pmic0, pmic1, pmic2, pmic3) 198 | d) modified mkbootimg will merge new table of DT 199 | 200 | 3.2) Run-time: 201 | 1) LK bootloader will obtain platform id/variant/subtype/soc rev/major ver/minor ver 202 | /pmic0/pmic1/pmic2/pmic3 info either from early bootloaders or via other means 203 | 2) LK bootloader will check entries #10 for non-zero 204 | value (set to zero for standard boot.img). If the 205 | value is non-zero, refer to page section after 206 | the "second stage" in the boot.img layout 207 | 3) Check QCDT magic 208 | 4) Check QCDT version (optional LK to handle multiple 209 | QCDT version) 210 | 5) LK scans through the QCDT table to look for matching 211 | entry. Search order is: 212 | 1) msm ID exact match 213 | 2) Platform type exact match 214 | 3) subtype ID exact match 215 | 4) HLOS subtype exact match 216 | 5) Pmic0 model ID exact match 217 | 6) Pmic1 model ID exact match 218 | 7) Pmic2 model ID exact match 219 | 8) Pmic3 model ID exact match 220 | 9) foundry ID, look for exact match, if not found choose 221 | device tree with foundry-id(0x0) 222 | 10) select the highest soc rev in QCDT that is 223 | equal to or lower than the runtime detected soc rev 224 | 11) select the highest major&minor ver in QCDT that is 225 | equal to or lower than the runtime detected major ver 226 | 12) select the highest pmic0 major&minor in QCDT that is 227 | equal to or lower than the runtime detected pmic0 228 | 13) select the highest pmic1 major&minor in QCDT that is 229 | equal to or lower than the runtime detected pmic1 230 | 14) select the highest pmic2 major&minor in QCDT that is 231 | equal to or lower than the runtime detected pmic2 232 | 15) select the highest pmic3 major&minor in QCDT that is 233 | equal to or lower than the runtime detected pmic3 234 | 6) Load the matching DTB blob to the tags addr 235 | 7) LK pass the correct DTB to the kernel 236 | -------------------------------------------------------------------------------- /extractors/README.md: -------------------------------------------------------------------------------- 1 | # Qualcomm Binaries 2 | Binary makefile generation scripts 3 | 4 | ## Graphics: 5 | ### Branch compiled from: 6 | msm8916: LA.BR.1.2.6_rb1.7 7 | msm8960: N/A[2](#floEGL) 8 | msm8974: LA.BF.1.1.3_rb1.5 9 | msm8992: assumed[1](#googleEGL) LA.BF64.1.2.3_rb1.2 10 | msm8994: assumed[1](#googleEGL) LA.BF64.1.2.3_rb1.2 11 | msm8996: LA.UM.5.5_rb1.10 12 | ### Origins: 13 | msm8916: 6.0.1 blobs from kipper/crackling 14 | msm8960: 6.0.1 blobs from flo mob30x 15 | msm8974: 6.0.1 blobs from bacon 16 | msm8992: 7.0 blobs from bullhead nrd90s 17 | msm8994: 7.0 blobs from angler nrd90u 18 | msm8996: 7.0 blobs from gemini 6.10.13 nrd90m 19 | ### Min kernel patch level required: 20 | msm8916: Any 5.0+ kernel 21 | msm8960: Patched kgsl up to android-msm-flo-3.4-marshmallow-mr2 22 | msm8974: Any 5.1+ kernel 23 | msm8992: Any 6.0+ kernel 24 | msm8994: Any 6.0+ kernel 25 | msm8996: Patched mdss/kgsl up to LA.UM.5.5.r1-00100-8x96.0 26 | 27 | ### Notes: 28 | 1: Google likes to strip QUIC branches from their shipped binaries so we can't really know which branch they originate from 29 | 2: On top of what's stated in footnote 1, flo's drivers deviate greatly from those of any CAF branch 30 | -------------------------------------------------------------------------------- /extractors/audio-msm8996.txt: -------------------------------------------------------------------------------- 1 | # Listen 2 | vendor/lib/hw/sound_trigger.primary.msm8996.so 3 | -------------------------------------------------------------------------------- /extractors/extract-files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2016 The CyanogenMod Project 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | set -e 19 | 20 | # Required! 21 | DEVICE=binaries 22 | DEVICE_COMMON=binaries 23 | VENDOR=qcom 24 | 25 | # Load extract_utils and do some sanity checks 26 | MY_DIR="${BASH_SOURCE%/*}" 27 | if [[ ! -d "$MY_DIR" ]]; then MY_DIR="$PWD"; fi 28 | 29 | CM_ROOT="$MY_DIR"/../../../.. 30 | 31 | HELPER="$CM_ROOT"/vendor/cm/build/tools/extract_utils.sh 32 | if [ ! -f "$HELPER" ]; then 33 | echo "Unable to find helper script at $HELPER" 34 | exit 1 35 | fi 36 | . "$HELPER" 37 | 38 | SRC=$1 39 | PLATFORM=$2 40 | SUBSYSTEM=$3 41 | 42 | # Initialize the helper for common device 43 | if [ -f "$MY_DIR"/"$SUBSYSTEM"-"$PLATFORM"-32.txt -a -f "$MY_DIR"/"$SUBSYSTEM"-"$PLATFORM"-64.txt ]; then 44 | setup_vendor "$DEVICE/${PLATFORM}-32/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 45 | extract "$MY_DIR"/"$SUBSYSTEM"-"$PLATFORM"-32.txt "$SRC" 46 | 47 | setup_vendor "$DEVICE/${PLATFORM}-64/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 48 | extract "$MY_DIR"/"$SUBSYSTEM"-"$PLATFORM"-64.txt "$SRC" 49 | else 50 | setup_vendor "$DEVICE/$PLATFORM/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 51 | extract "$MY_DIR"/"$SUBSYSTEM"-"$PLATFORM".txt "$SRC" 52 | fi 53 | 54 | "$MY_DIR"/setup-makefiles.sh 55 | -------------------------------------------------------------------------------- /extractors/graphics-msm8916-32.txt: -------------------------------------------------------------------------------- 1 | # Graphics 2 | vendor/lib/egl/eglsubAndroid.so 3 | vendor/lib/egl/eglSubDriverAndroid.so 4 | vendor/lib/egl/libEGL_adreno.so 5 | vendor/lib/egl/libESXEGL_adreno.so 6 | vendor/lib/egl/libESXGLESv1_CM_adreno.so 7 | vendor/lib/egl/libESXGLESv2_adreno.so 8 | vendor/lib/egl/libGLESv1_CM_adreno.so 9 | vendor/lib/egl/libGLESv2_adreno.so 10 | vendor/lib/egl/libq3dtools_adreno.so 11 | vendor/lib/egl/libQTapGLES.so 12 | vendor/lib/egl/libRBEGL_adreno.so 13 | vendor/lib/egl/libRBGLESv1_CM_adreno.so 14 | vendor/lib/egl/libRBGLESv2_adreno.so 15 | vendor/lib/libadreno_utils.so 16 | vendor/lib/libc2d30-a3xx.so 17 | vendor/lib/libc2d30-a4xx.so 18 | vendor/lib/libC2D2.so 19 | vendor/lib/libCB.so 20 | vendor/lib/libgsl.so 21 | vendor/lib/libllvm-glnext.so 22 | vendor/lib/libllvm-qcom.so 23 | vendor/lib/libOpenCL.so 24 | vendor/lib/libRSDriver_adreno.so 25 | vendor/lib/librs_adreno.so 26 | vendor/lib/librs_adreno_sha1.so 27 | vendor/lib/libsc-a3xx.so 28 | vendor/lib/libscale.so 29 | -------------------------------------------------------------------------------- /extractors/graphics-msm8916-64.txt: -------------------------------------------------------------------------------- 1 | # Graphics 2 | vendor/lib64/egl/eglsubAndroid.so 3 | vendor/lib64/egl/eglSubDriverAndroid.so 4 | vendor/lib64/egl/libEGL_adreno.so 5 | vendor/lib64/egl/libESXEGL_adreno.so 6 | vendor/lib64/egl/libESXGLESv1_CM_adreno.so 7 | vendor/lib64/egl/libESXGLESv2_adreno.so 8 | vendor/lib64/egl/libGLESv1_CM_adreno.so 9 | vendor/lib64/egl/libGLESv2_adreno.so 10 | vendor/lib64/egl/libq3dtools_adreno.so 11 | vendor/lib64/egl/libQTapGLES.so 12 | vendor/lib64/egl/libRBEGL_adreno.so 13 | vendor/lib64/egl/libRBGLESv1_CM_adreno.so 14 | vendor/lib64/egl/libRBGLESv2_adreno.so 15 | vendor/lib64/libadreno_utils.so 16 | vendor/lib64/libc2d30-a3xx.so 17 | vendor/lib64/libc2d30-a4xx.so 18 | vendor/lib64/libC2D2.so 19 | vendor/lib64/libCB.so 20 | vendor/lib64/libgsl.so 21 | vendor/lib64/libllvm-glnext.so 22 | vendor/lib64/libllvm-qcom.so 23 | vendor/lib64/libOpenCL.so 24 | vendor/lib64/libRSDriver_adreno.so 25 | vendor/lib64/librs_adreno.so 26 | vendor/lib64/librs_adreno_sha1.so 27 | vendor/lib64/libsc-a3xx.so 28 | vendor/lib64/libscale.so 29 | -------------------------------------------------------------------------------- /extractors/graphics-msm8960.txt: -------------------------------------------------------------------------------- 1 | # Graphics 2 | vendor/lib/egl/eglsubAndroid.so 3 | vendor/lib/egl/libEGL_adreno.so 4 | vendor/lib/egl/libGLESv1_CM_adreno.so 5 | vendor/lib/egl/libGLESv2_adreno.so 6 | vendor/lib/egl/libq3dtools_adreno.so 7 | vendor/lib/libadreno_utils.so 8 | vendor/lib/libbccQTI.so 9 | vendor/lib/libC2D2.so 10 | vendor/lib/libCB.so 11 | vendor/lib/libc2d30-a3xx.so 12 | vendor/lib/libgsl.so 13 | vendor/lib/libllvm-qcom.so 14 | vendor/lib/libRSDriver_adreno.so 15 | vendor/lib/librs_adreno.so 16 | vendor/lib/librs_adreno_sha1.so 17 | vendor/lib/libsc-a3xx.so 18 | vendor/lib/libuiblur.so 19 | -------------------------------------------------------------------------------- /extractors/graphics-msm8974.txt: -------------------------------------------------------------------------------- 1 | # Graphics 2 | vendor/lib/egl/eglsubAndroid.so 3 | vendor/lib/egl/libEGL_adreno.so 4 | vendor/lib/egl/libGLESv1_CM_adreno.so 5 | vendor/lib/egl/libGLESv2_adreno.so 6 | vendor/lib/egl/libq3dtools_adreno.so 7 | vendor/lib/libadreno_utils.so 8 | vendor/lib/libbccQTI.so 9 | vendor/lib/libC2D2.so 10 | vendor/lib/libCB.so 11 | vendor/lib/libc2d30-a3xx.so 12 | vendor/lib/libgsl.so 13 | vendor/lib/libllvm-qcom.so 14 | vendor/lib/libOpenCL.so 15 | vendor/lib/libsc-a3xx.so 16 | vendor/lib/libRSDriver_adreno.so 17 | vendor/lib/librs_adreno.so 18 | vendor/lib/librs_adreno_sha1.so 19 | vendor/lib/libscale.so 20 | vendor/lib/libuiblur.so 21 | -------------------------------------------------------------------------------- /extractors/graphics-msm8992.txt: -------------------------------------------------------------------------------- 1 | # Graphics 2 | vendor/lib/hw/vulkan.msm8992.so 3 | vendor/lib/egl/eglSubDriverAndroid.so 4 | vendor/lib/egl/libEGL_adreno.so 5 | vendor/lib/egl/libGLESv1_CM_adreno.so 6 | vendor/lib/egl/libGLESv2_adreno.so 7 | vendor/lib/egl/libq3dtools_adreno.so 8 | vendor/lib/libC2D2.so 9 | vendor/lib/libCB.so 10 | vendor/lib/libRSDriver_adreno.so 11 | vendor/lib/libadreno_utils.so 12 | vendor/lib/libbccQTI.so 13 | vendor/lib/libc2d30-a4xx.so 14 | vendor/lib/libgsl.so 15 | vendor/lib/libllvm-glnext.so 16 | vendor/lib/libllvm-qcom.so 17 | vendor/lib/libllvm-qgl.so 18 | vendor/lib/librs_adreno.so 19 | vendor/lib/librs_adreno_sha1.so 20 | vendor/lib/libscale.so 21 | vendor/lib64/hw/vulkan.msm8992.so 22 | vendor/lib64/egl/eglSubDriverAndroid.so 23 | vendor/lib64/egl/libEGL_adreno.so 24 | vendor/lib64/egl/libGLESv1_CM_adreno.so 25 | vendor/lib64/egl/libGLESv2_adreno.so 26 | vendor/lib64/egl/libq3dtools_adreno.so 27 | vendor/lib64/libC2D2.so 28 | vendor/lib64/libCB.so 29 | vendor/lib64/libRSDriver_adreno.so 30 | vendor/lib64/libadreno_utils.so 31 | vendor/lib64/libbccQTI.so 32 | vendor/lib64/libc2d30-a4xx.so 33 | vendor/lib64/libgsl.so 34 | vendor/lib64/libllvm-glnext.so 35 | vendor/lib64/libllvm-qcom.so 36 | vendor/lib64/libllvm-qgl.so 37 | vendor/lib64/librs_adreno.so 38 | vendor/lib64/librs_adreno_sha1.so 39 | vendor/lib64/libscale.so 40 | vendor/lib64/libuiblur.so 41 | -------------------------------------------------------------------------------- /extractors/graphics-msm8994.txt: -------------------------------------------------------------------------------- 1 | # Graphics 2 | vendor/lib/hw/vulkan.msm8994.so 3 | vendor/lib/egl/eglSubDriverAndroid.so 4 | vendor/lib/egl/libEGL_adreno.so 5 | vendor/lib/egl/libGLESv1_CM_adreno.so 6 | vendor/lib/egl/libGLESv2_adreno.so 7 | vendor/lib/egl/libq3dtools_adreno.so 8 | vendor/lib/libC2D2.so 9 | vendor/lib/libCB.so 10 | vendor/lib/libRSDriver_adreno.so 11 | vendor/lib/libadreno_utils.so 12 | vendor/lib/libbccQTI.so 13 | vendor/lib/libc2d30-a4xx.so 14 | vendor/lib/libgsl.so 15 | vendor/lib/libllvm-glnext.so 16 | vendor/lib/libllvm-qcom.so 17 | vendor/lib/libllvm-qgl.so 18 | vendor/lib/librs_adreno.so 19 | vendor/lib/librs_adreno_sha1.so 20 | vendor/lib/libscale.so 21 | vendor/lib64/hw/vulkan.msm8994.so 22 | vendor/lib64/egl/eglSubDriverAndroid.so 23 | vendor/lib64/egl/libEGL_adreno.so 24 | vendor/lib64/egl/libGLESv1_CM_adreno.so 25 | vendor/lib64/egl/libGLESv2_adreno.so 26 | vendor/lib64/egl/libq3dtools_adreno.so 27 | vendor/lib64/libC2D2.so 28 | vendor/lib64/libCB.so 29 | vendor/lib64/libRSDriver_adreno.so 30 | vendor/lib64/libadreno_utils.so 31 | vendor/lib64/libbccQTI.so 32 | vendor/lib64/libc2d30-a4xx.so 33 | vendor/lib64/libgsl.so 34 | vendor/lib64/libllvm-glnext.so 35 | vendor/lib64/libllvm-qcom.so 36 | vendor/lib64/libllvm-qgl.so 37 | vendor/lib64/libmm-disp-apis.so 38 | vendor/lib64/libmm-qdcm.so 39 | vendor/lib64/librs_adreno.so 40 | vendor/lib64/librs_adreno_sha1.so 41 | vendor/lib64/libscale.so 42 | vendor/lib64/libuiblur.so 43 | -------------------------------------------------------------------------------- /extractors/graphics-msm8996.txt: -------------------------------------------------------------------------------- 1 | # Graphics 2 | vendor/lib/hw/vulkan.msm8996.so 3 | vendor/lib/egl/eglSubDriverAndroid.so 4 | vendor/lib/egl/libEGL_adreno.so 5 | vendor/lib/egl/libGLESv1_CM_adreno.so 6 | vendor/lib/egl/libGLESv2_adreno.so 7 | vendor/lib/egl/libQTapGLES.so 8 | vendor/lib/egl/libq3dtools_adreno.so 9 | vendor/lib/libC2D2.so 10 | vendor/lib/libCB.so 11 | vendor/lib/libOpenCL.so 12 | vendor/lib/libRSDriver_adreno.so 13 | vendor/lib/libadreno_utils.so 14 | vendor/lib/libbccQTI.so 15 | vendor/lib/libc2d30-a5xx.so 16 | vendor/lib/libc2d30_bltlib.so 17 | vendor/lib/libgsl.so 18 | vendor/lib/libllvm-glnext.so 19 | vendor/lib/libllvm-qcom.so 20 | vendor/lib/libllvm-qgl.so 21 | vendor/lib/libmmQSM.so 22 | vendor/lib/librs_adreno.so 23 | vendor/lib/librs_adreno_sha1.so 24 | vendor/lib/libsd_sdk_display.so 25 | -vendor/lib/libsdm-disp-apis.so 26 | vendor/lib64/hw/vulkan.msm8996.so 27 | vendor/lib64/egl/eglSubDriverAndroid.so 28 | vendor/lib64/egl/libEGL_adreno.so 29 | vendor/lib64/egl/libGLESv1_CM_adreno.so 30 | vendor/lib64/egl/libGLESv2_adreno.so 31 | vendor/lib64/egl/libQTapGLES.so 32 | vendor/lib64/egl/libq3dtools_adreno.so 33 | vendor/lib64/libC2D2.so 34 | vendor/lib64/libCB.so 35 | vendor/lib64/libOpenCL.so 36 | vendor/lib64/libRSDriver_adreno.so 37 | vendor/lib64/libadreno_utils.so 38 | vendor/lib64/libbccQTI.so 39 | vendor/lib64/libc2d30-a5xx.so 40 | vendor/lib64/libc2d30_bltlib.so 41 | vendor/lib64/libgsl.so 42 | vendor/lib64/libllvm-glnext.so 43 | vendor/lib64/libllvm-qcom.so 44 | vendor/lib64/libllvm-qgl.so 45 | vendor/lib64/libmm-disp-apis.so 46 | vendor/lib64/libmm-qdcm.so 47 | vendor/lib64/libmmQSM.so 48 | vendor/lib64/librs_adreno.so 49 | vendor/lib64/librs_adreno_sha1.so 50 | vendor/lib64/libscalar.so 51 | vendor/lib64/libsd_sdk_display.so 52 | vendor/lib64/libsdm-color.so 53 | vendor/lib64/libsdm-diag.so 54 | -vendor/lib64/libsdm-disp-apis.so 55 | vendor/lib64/libsdmextension.so 56 | vendor/lib64/libuiblur.so 57 | -------------------------------------------------------------------------------- /extractors/setup-makefiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2016 The CyanogenMod Project 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | set -e 19 | 20 | # Required! 21 | DEVICE=binaries 22 | DEVICE_COMMON="common/extractors" 23 | VENDOR=qcom 24 | 25 | # Load extractutils and do some sanity checks 26 | MY_DIR="${BASH_SOURCE%/*}" 27 | if [[ ! -d "$MY_DIR" ]]; then MY_DIR="$PWD"; fi 28 | 29 | CM_ROOT="$MY_DIR"/../../../.. 30 | 31 | HELPER="$CM_ROOT"/vendor/cm/build/tools/extract_utils.sh 32 | if [ ! -f "$HELPER" ]; then 33 | echo "Unable to find helper script at $HELPER" 34 | exit 1 35 | fi 36 | . "$HELPER" 37 | 38 | PLATFORM=msm8916 39 | SUBSYSTEM=graphics 40 | 41 | # Initialize the helper 42 | setup_vendor "$DEVICE/${PLATFORM}-32/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 43 | 44 | # Copyright headers and guards 45 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 46 | 47 | # Qualcomm BSP blobs - we put a conditional around here 48 | # in case the BSP is actually being built 49 | echo "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 50 | 51 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM"-32.txt 52 | 53 | printf "endif" >> "$PRODUCTMK" 54 | 55 | # We are done! 56 | write_footers 57 | 58 | # Initialize the helper 59 | setup_vendor "$DEVICE/${PLATFORM}-64/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 60 | 61 | # Copyright headers and guards 62 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 63 | 64 | # Qualcomm BSP blobs - we put a conditional around here 65 | # in case the BSP is actually being built 66 | echo "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 67 | 68 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM"-64.txt 69 | 70 | printf "endif" >> "$PRODUCTMK" 71 | 72 | # We are done! 73 | write_footers 74 | 75 | PLATFORM=msm8960 76 | SUBSYSTEM=graphics 77 | 78 | # Initialize the helper 79 | setup_vendor "$DEVICE/$PLATFORM/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 80 | 81 | # Copyright headers and guards 82 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 83 | 84 | # Qualcomm BSP blobs - we put a conditional around here 85 | # in case the BSP is actually being built 86 | printf '\n%s\n' "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 87 | 88 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM".txt 89 | 90 | echo "endif" >> "$PRODUCTMK" 91 | 92 | # We are done! 93 | write_footers 94 | 95 | PLATFORM=msm8974 96 | SUBSYSTEM=graphics 97 | 98 | # Initialize the helper 99 | setup_vendor "$DEVICE/$PLATFORM/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 100 | 101 | # Copyright headers and guards 102 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 103 | 104 | # Qualcomm BSP blobs - we put a conditional around here 105 | # in case the BSP is actually being built 106 | printf '\n%s\n' "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 107 | 108 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM".txt 109 | 110 | echo "endif" >> "$PRODUCTMK" 111 | 112 | # We are done! 113 | write_footers 114 | 115 | PLATFORM=msm8992 116 | SUBSYSTEM=graphics 117 | 118 | # Initialize the helper 119 | setup_vendor "$DEVICE/$PLATFORM/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 120 | 121 | # Copyright headers and guards 122 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 123 | 124 | # Qualcomm BSP blobs - we put a conditional around here 125 | # in case the BSP is actually being built 126 | printf '\n%s\n' "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 127 | 128 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM".txt 129 | 130 | echo "endif" >> "$PRODUCTMK" 131 | 132 | cat << EOF >> "$ANDROIDMK" 133 | \$(shell mkdir -p \$(PRODUCT_OUT)/system/vendor/lib/egl && pushd \$(PRODUCT_OUT)/system/vendor/lib > /dev/null && ln -s egl/libEGL_adreno.so libEGL_adreno.so && popd > /dev/null) 134 | \$(shell mkdir -p \$(PRODUCT_OUT)/system/vendor/lib64/egl && pushd \$(PRODUCT_OUT)/system/vendor/lib64 > /dev/null && ln -s egl/libEGL_adreno.so libEGL_adreno.so && popd > /dev/null) 135 | EOF 136 | 137 | # We are done! 138 | write_footers 139 | 140 | PLATFORM=msm8994 141 | SUBSYSTEM=graphics 142 | 143 | # Initialize the helper 144 | setup_vendor "$DEVICE/$PLATFORM/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 145 | 146 | # Copyright headers and guards 147 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 148 | 149 | # Qualcomm BSP blobs - we put a conditional around here 150 | # in case the BSP is actually being built 151 | printf '\n%s\n' "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 152 | 153 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM".txt 154 | 155 | echo "endif" >> "$PRODUCTMK" 156 | 157 | cat << EOF >> "$ANDROIDMK" 158 | \$(shell mkdir -p \$(PRODUCT_OUT)/system/vendor/lib/egl && pushd \$(PRODUCT_OUT)/system/vendor/lib > /dev/null && ln -s egl/libEGL_adreno.so libEGL_adreno.so && popd > /dev/null) 159 | \$(shell mkdir -p \$(PRODUCT_OUT)/system/vendor/lib64/egl && pushd \$(PRODUCT_OUT)/system/vendor/lib64 > /dev/null && ln -s egl/libEGL_adreno.so libEGL_adreno.so && popd > /dev/null) 160 | EOF 161 | 162 | # We are done! 163 | write_footers 164 | 165 | PLATFORM=msm8996 166 | SUBSYSTEM=graphics 167 | 168 | # Initialize the helper 169 | setup_vendor "$DEVICE/$PLATFORM/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 170 | 171 | # Copyright headers and guards 172 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 173 | 174 | # Qualcomm BSP blobs - we put a conditional around here 175 | # in case the BSP is actually being built 176 | printf '\n%s\n' "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 177 | printf '\n%s\n' "ifeq (\$(QCPATH),)" >> "$ANDROIDMK" 178 | 179 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM".txt 180 | 181 | echo "endif" >> "$PRODUCTMK" 182 | 183 | cat << EOF >> "$ANDROIDMK" 184 | endif 185 | 186 | \$(shell mkdir -p \$(PRODUCT_OUT)/system/vendor/lib/egl && pushd \$(PRODUCT_OUT)/system/vendor/lib > /dev/null && ln -s egl/libEGL_adreno.so libEGL_adreno.so && popd > /dev/null) 187 | \$(shell mkdir -p \$(PRODUCT_OUT)/system/vendor/lib64/egl && pushd \$(PRODUCT_OUT)/system/vendor/lib64 > /dev/null && ln -s egl/libEGL_adreno.so libEGL_adreno.so && popd > /dev/null) 188 | EOF 189 | 190 | # We are done! 191 | write_footers 192 | 193 | SUBSYSTEM=audio 194 | 195 | # Initialize the helper 196 | setup_vendor "$DEVICE/$PLATFORM/$SUBSYSTEM" "$VENDOR" "$CM_ROOT" true true $SUBSYSTEM 197 | 198 | # Copyright headers and guards 199 | write_headers $PLATFORM TARGET_BOARD_PLATFORM 200 | 201 | # Qualcomm BSP blobs - we put a conditional around here 202 | # in case the BSP is actually being built 203 | printf '\n%s\n' "ifeq (\$(QCPATH),)" >> "$PRODUCTMK" 204 | 205 | write_makefiles "$MY_DIR"/"$SUBSYSTEM-$PLATFORM".txt 206 | 207 | echo "endif" >> "$PRODUCTMK" 208 | 209 | # We are done! 210 | write_footers 211 | 212 | # Add a guard on the top level 213 | cat << EOF > "$CM_ROOT/vendor/$VENDOR/$DEVICE/Android.mk" 214 | LOCAL_PATH := \$(call my-dir) 215 | 216 | include \$(CLEAR_VARS) 217 | 218 | ifeq (\$(BOARD_USES_QCOM_HARDWARE),true) 219 | include \$(call all-makefiles-under,\$(LOCAL_PATH)/\$(TARGET_BOARD_PLATFORM)) 220 | endif 221 | EOF 222 | -------------------------------------------------------------------------------- /power/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | # Hey Mr. Make Author, DIAF PLX 4 | ifeq ($(TARGET_POWERHAL_VARIANT),qcom) 5 | USE_ME := true 6 | endif 7 | 8 | ifneq (,$(filter true,$(USE_ME) $(WITH_QC_PERF))) 9 | 10 | # HAL module implemenation stored in 11 | # hw/..so 12 | include $(CLEAR_VARS) 13 | 14 | LOCAL_MODULE_RELATIVE_PATH := hw 15 | LOCAL_PROPRIETARY_MODULE := true 16 | LOCAL_SHARED_LIBRARIES := liblog libcutils libdl 17 | LOCAL_SRC_FILES := power.c metadata-parser.c utils.c list.c hint-data.c 18 | 19 | ifneq ($(BOARD_POWER_CUSTOM_BOARD_LIB),) 20 | LOCAL_WHOLE_STATIC_LIBRARIES += $(BOARD_POWER_CUSTOM_BOARD_LIB) 21 | else 22 | 23 | # Include target-specific files. 24 | ifeq ($(call is-board-platform-in-list, msm8974), true) 25 | LOCAL_SRC_FILES += power-8974.c 26 | endif 27 | 28 | ifeq ($(call is-board-platform-in-list, msm8960), true) 29 | LOCAL_SRC_FILES += power-8960.c 30 | endif 31 | 32 | ifeq ($(call is-board-platform-in-list, msm8226), true) 33 | LOCAL_SRC_FILES += power-8226.c 34 | endif 35 | 36 | ifeq ($(call is-board-platform-in-list, msm8610), true) 37 | LOCAL_SRC_FILES += power-8610.c 38 | endif 39 | 40 | ifeq ($(call is-board-platform-in-list, msm8909), true) 41 | LOCAL_SRC_FILES += power-8909.c 42 | endif 43 | 44 | ifeq ($(call is-board-platform-in-list, msm8916), true) 45 | LOCAL_SRC_FILES += power-8916.c 46 | endif 47 | 48 | ifeq ($(call is-board-platform-in-list, msm8952), true) 49 | LOCAL_SRC_FILES += power-8952.c 50 | endif 51 | 52 | ifeq ($(call is-board-platform-in-list,msm8937), true) 53 | LOCAL_SRC_FILES += power-8937.c 54 | LOCAL_CFLAGS += -DMPCTLV3 55 | endif 56 | 57 | ifeq ($(call is-board-platform-in-list, apq8084), true) 58 | LOCAL_SRC_FILES += power-8084.c 59 | endif 60 | 61 | ifeq ($(call is-board-platform-in-list, msm8992), true) 62 | LOCAL_SRC_FILES += power-8992.c 63 | endif 64 | 65 | ifeq ($(call is-board-platform-in-list, msm8994), true) 66 | LOCAL_SRC_FILES += power-8994.c 67 | endif 68 | 69 | ifeq ($(call is-board-platform-in-list, msm8996), true) 70 | LOCAL_SRC_FILES += power-8996.c 71 | LOCAL_CFLAGS += -DMPCTLV3 72 | endif 73 | 74 | endif # End of board specific list 75 | 76 | ifneq ($(TARGET_POWERHAL_SET_INTERACTIVE_EXT),) 77 | LOCAL_CFLAGS += -DSET_INTERACTIVE_EXT 78 | LOCAL_SRC_FILES += ../../../../$(TARGET_POWERHAL_SET_INTERACTIVE_EXT) 79 | endif 80 | 81 | ifneq ($(TARGET_TAP_TO_WAKE_NODE),) 82 | LOCAL_CFLAGS += -DTAP_TO_WAKE_NODE=\"$(TARGET_TAP_TO_WAKE_NODE)\" 83 | endif 84 | 85 | ifeq ($(TARGET_POWER_SET_FEATURE_LIB),) 86 | LOCAL_SRC_FILES += power-feature-default.c 87 | else 88 | LOCAL_STATIC_LIBRARIES += $(TARGET_POWER_SET_FEATURE_LIB) 89 | endif 90 | 91 | ifneq ($(CM_POWERHAL_EXTENSION),) 92 | LOCAL_MODULE := power.$(CM_POWERHAL_EXTENSION) 93 | else 94 | LOCAL_MODULE := power.$(TARGET_BOARD_PLATFORM) 95 | endif 96 | LOCAL_MODULE_TAGS := optional 97 | include $(BUILD_SHARED_LIBRARY) 98 | 99 | endif # TARGET_POWERHAL_VARIANT == qcom || WITH_QC_PERF 100 | -------------------------------------------------------------------------------- /power/hint-data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "hint-data.h" 31 | 32 | int hint_compare(struct hint_data *first_hint, 33 | struct hint_data *other_hint) { 34 | if (first_hint == other_hint) { 35 | return 0; 36 | } else if ((first_hint && other_hint) && 37 | (first_hint->hint_id == other_hint->hint_id)) { 38 | return 0; 39 | } else { 40 | return 1; 41 | } 42 | } 43 | 44 | void hint_dump(__attribute__((unused)) struct hint_data *hint) 45 | { 46 | /*ALOGI("hint_id: %lu", hint->hint_id);*/ 47 | } 48 | -------------------------------------------------------------------------------- /power/hint-data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /* Default use-case hint IDs */ 31 | #define DEFAULT_VIDEO_ENCODE_HINT_ID (0x0A00) 32 | #define DEFAULT_VIDEO_DECODE_HINT_ID (0x0B00) 33 | #define DISPLAY_STATE_HINT_ID (0x0C00) 34 | #define DISPLAY_STATE_HINT_ID_2 (0x0D00) 35 | #define DEFAULT_AUDIO_HINT_ID (0x0E00) 36 | #define DEFAULT_PROFILE_HINT_ID (0x0F00) 37 | #define CAM_PREVIEW_HINT_ID (0x1000) 38 | 39 | struct hint_data { 40 | unsigned long hint_id; /* This is our key. */ 41 | unsigned long perflock_handle; 42 | }; 43 | 44 | int hint_compare(struct hint_data *first_hint, 45 | struct hint_data *other_hint); 46 | void hint_dump(struct hint_data *hint); 47 | -------------------------------------------------------------------------------- /power/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "list.h" 35 | #include 36 | 37 | int init_list_head(struct list_node *head) 38 | { 39 | if (head == NULL) 40 | return -1; 41 | 42 | memset(head, 0, sizeof(*head)); 43 | 44 | return 0; 45 | } 46 | 47 | struct list_node *add_list_node(struct list_node *head, void *data) 48 | { 49 | /* Create a new list_node. And put 'data' into it. */ 50 | struct list_node *new_node; 51 | 52 | if (head == NULL) { 53 | return NULL; 54 | } 55 | 56 | if (!(new_node = malloc(sizeof(struct list_node)))) { 57 | return NULL; 58 | } 59 | 60 | new_node->data = data; 61 | new_node->next = head->next; 62 | new_node->compare = head->compare; 63 | new_node->dump = head->dump; 64 | head->next = new_node; 65 | 66 | return new_node; 67 | } 68 | 69 | int is_list_empty(struct list_node *head) 70 | { 71 | return (head == NULL || head->next == NULL); 72 | } 73 | 74 | /* 75 | * Delink and de-allocate 'node'. 76 | */ 77 | int remove_list_node(struct list_node *head, struct list_node *del_node) 78 | { 79 | struct list_node *current_node; 80 | struct list_node *saved_node; 81 | 82 | if (head == NULL || head->next == NULL) { 83 | return -1; 84 | } 85 | 86 | current_node = head->next; 87 | saved_node = head; 88 | 89 | while (current_node && current_node != del_node) { 90 | saved_node = current_node; 91 | current_node = current_node->next; 92 | } 93 | 94 | if (saved_node) { 95 | if (current_node) { 96 | saved_node->next = current_node->next; 97 | } else { 98 | /* Node not found. */ 99 | return -1; 100 | } 101 | } 102 | 103 | if (del_node) { 104 | free(del_node); 105 | } 106 | 107 | return 0; 108 | } 109 | 110 | void dump_list(struct list_node *head) 111 | { 112 | struct list_node *current_node = head; 113 | 114 | if (head == NULL) 115 | return; 116 | 117 | printf("List:\n"); 118 | 119 | while ((current_node = current_node->next)) { 120 | if (current_node->dump) { 121 | current_node->dump(current_node->data); 122 | } 123 | } 124 | } 125 | 126 | struct list_node *find_node(struct list_node *head, void *comparison_data) 127 | { 128 | struct list_node *current_node = head; 129 | 130 | if (head == NULL) 131 | return NULL; 132 | 133 | while ((current_node = current_node->next)) { 134 | if (current_node->compare) { 135 | if (current_node->compare(current_node->data, 136 | comparison_data) == 0) { 137 | /* Match found. Return current_node. */ 138 | return current_node; 139 | } 140 | } 141 | } 142 | 143 | /* No match found. */ 144 | return NULL; 145 | } 146 | -------------------------------------------------------------------------------- /power/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | struct list_node { 31 | struct list_node *next; 32 | void *data; 33 | int (*compare)(void *data1, void *data2); 34 | void (*dump)(void *data); 35 | }; 36 | 37 | int init_list_head(struct list_node *head); 38 | struct list_node * add_list_node(struct list_node *head, void *data); 39 | int remove_list_node(struct list_node *head, struct list_node *del_node); 40 | void dump_list(struct list_node *head); 41 | struct list_node *find_node(struct list_node *head, void *comparison_data); 42 | -------------------------------------------------------------------------------- /power/metadata-defs.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012, The Linux Foundation. All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions are 5 | * met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above 9 | * copyright notice, this list of conditions and the following 10 | * disclaimer in the documentation and/or other materials provided 11 | * with the distribution. 12 | * * Neither the name of The Linux Foundation nor the names of its 13 | * contributors may be used to endorse or promote products derived 14 | * from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #define ATTRIBUTE_VALUE_DELIM ('=') 31 | #define ATTRIBUTE_STRING_DELIM (";") 32 | 33 | #define METADATA_PARSING_ERR (-1) 34 | #define METADATA_PARSING_CONTINUE (0) 35 | #define METADATA_PARSING_DONE (1) 36 | 37 | #define MIN(x,y) (((x)>(y))?(y):(x)) 38 | 39 | struct video_encode_metadata_t { 40 | int hint_id; 41 | int state; 42 | }; 43 | 44 | struct video_decode_metadata_t { 45 | int hint_id; 46 | int state; 47 | }; 48 | 49 | struct audio_metadata_t { 50 | int hint_id; 51 | int state; 52 | }; 53 | 54 | struct cam_preview_metadata_t { 55 | int hint_id; 56 | int state; 57 | }; 58 | 59 | int parse_metadata(char *metadata, char **metadata_saveptr, 60 | char *attribute, int attribute_size, char *value, 61 | unsigned int value_size); 62 | int parse_video_encode_metadata(char *metadata, 63 | struct video_encode_metadata_t *video_encode_metadata); 64 | int parse_video_decode_metadata(char *metadata, 65 | struct video_decode_metadata_t *video_decode_metadata); 66 | int parse_audio_metadata(char *metadata, 67 | struct audio_metadata_t *audio_metadata); 68 | int parse_cam_preview_metadata(char *metadata, 69 | struct cam_preview_metadata_t *video_decode_metadata); 70 | -------------------------------------------------------------------------------- /power/metadata-parser.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012, The Linux Foundation. All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions are 5 | * met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above 9 | * copyright notice, this list of conditions and the following 10 | * disclaimer in the documentation and/or other materials provided 11 | * with the distribution. 12 | * * Neither the name of The Linux Foundation nor the names of its 13 | * contributors may be used to endorse or promote products derived 14 | * from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "metadata-defs.h" 35 | 36 | int parse_metadata(char *metadata, char **metadata_saveptr, 37 | char *attribute, int attribute_size, char *value, 38 | unsigned int value_size) 39 | { 40 | char *attribute_string; 41 | char *attribute_value_delim; 42 | unsigned int bytes_to_copy; 43 | 44 | attribute_string = strtok_r(metadata, ATTRIBUTE_STRING_DELIM, 45 | metadata_saveptr); 46 | 47 | if (attribute_string == NULL) 48 | return METADATA_PARSING_DONE; 49 | 50 | attribute[0] = value[0] = '\0'; 51 | 52 | if ((attribute_value_delim = strchr(attribute_string, 53 | ATTRIBUTE_VALUE_DELIM)) != NULL) { 54 | bytes_to_copy = MIN((attribute_value_delim - attribute_string), 55 | attribute_size - 1); 56 | strncpy(attribute, attribute_string, 57 | bytes_to_copy); 58 | attribute[bytes_to_copy] = '\0'; 59 | 60 | bytes_to_copy = MIN(strlen(attribute_string) - strlen(attribute) - 1, 61 | value_size - 1); 62 | strncpy(value, attribute_value_delim + 1, 63 | bytes_to_copy); 64 | value[bytes_to_copy] = '\0'; 65 | } 66 | 67 | return METADATA_PARSING_CONTINUE; 68 | } 69 | 70 | int parse_cam_preview_metadata(char *metadata, 71 | struct cam_preview_metadata_t *cam_preview_metadata) 72 | { 73 | char attribute[1024], value[1024], *saveptr; 74 | char *temp_metadata = metadata; 75 | int parsing_status; 76 | 77 | while ((parsing_status = parse_metadata(temp_metadata, &saveptr, 78 | attribute, sizeof(attribute), value, sizeof(value))) == METADATA_PARSING_CONTINUE) { 79 | if (strlen(attribute) == strlen("hint_id") && 80 | (strncmp(attribute, "hint_id", strlen("hint_id")) == 0)) { 81 | if (strlen(value) > 0) { 82 | cam_preview_metadata->hint_id = atoi(value); 83 | } 84 | } 85 | 86 | if (strlen(attribute) == strlen("state") && 87 | (strncmp(attribute, "state", strlen("state")) == 0)) { 88 | if (strlen(value) > 0) { 89 | cam_preview_metadata->state = atoi(value); 90 | } 91 | } 92 | 93 | temp_metadata = NULL; 94 | } 95 | 96 | if (parsing_status == METADATA_PARSING_ERR) 97 | return -1; 98 | 99 | return 0; 100 | } 101 | 102 | int parse_video_encode_metadata(char *metadata, 103 | struct video_encode_metadata_t *video_encode_metadata) 104 | { 105 | char attribute[1024], value[1024], *saveptr; 106 | char *temp_metadata = metadata; 107 | int parsing_status; 108 | 109 | while ((parsing_status = parse_metadata(temp_metadata, &saveptr, 110 | attribute, sizeof(attribute), value, sizeof(value))) == METADATA_PARSING_CONTINUE) { 111 | if (strlen(attribute) == strlen("hint_id") && 112 | (strncmp(attribute, "hint_id", strlen("hint_id")) == 0)) { 113 | if (strlen(value) > 0) { 114 | video_encode_metadata->hint_id = atoi(value); 115 | } 116 | } 117 | 118 | if (strlen(attribute) == strlen("state") && 119 | (strncmp(attribute, "state", strlen("state")) == 0)) { 120 | if (strlen(value) > 0) { 121 | video_encode_metadata->state = atoi(value); 122 | } 123 | } 124 | 125 | temp_metadata = NULL; 126 | } 127 | 128 | if (parsing_status == METADATA_PARSING_ERR) 129 | return -1; 130 | 131 | return 0; 132 | } 133 | 134 | int parse_video_decode_metadata(char *metadata, 135 | struct video_decode_metadata_t *video_decode_metadata) 136 | { 137 | char attribute[1024], value[1024], *saveptr; 138 | char *temp_metadata = metadata; 139 | int parsing_status; 140 | 141 | while ((parsing_status = parse_metadata(temp_metadata, &saveptr, 142 | attribute, sizeof(attribute), value, sizeof(value))) == METADATA_PARSING_CONTINUE) { 143 | if (strlen(attribute) == strlen("hint_id") && 144 | (strncmp(attribute, "hint_id", strlen("hint_id")) == 0)) { 145 | if (strlen(value) > 0) { 146 | video_decode_metadata->hint_id = atoi(value); 147 | } 148 | } 149 | 150 | if (strlen(attribute) == strlen("state") && 151 | (strncmp(attribute, "state", strlen("state")) == 0)) { 152 | if (strlen(value) > 0) { 153 | video_decode_metadata->state = atoi(value); 154 | } 155 | } 156 | 157 | temp_metadata = NULL; 158 | } 159 | 160 | if (parsing_status == METADATA_PARSING_ERR) 161 | return -1; 162 | 163 | return 0; 164 | } 165 | 166 | int parse_audio_metadata(char *metadata, 167 | struct audio_metadata_t *audio_metadata) 168 | { 169 | char attribute[1024], value[1024], *saveptr; 170 | char *temp_metadata = metadata; 171 | int parsing_status; 172 | 173 | while ((parsing_status = parse_metadata(temp_metadata, &saveptr, 174 | attribute, sizeof(attribute), value, sizeof(value))) == METADATA_PARSING_CONTINUE) { 175 | if (strlen(attribute) == strlen("hint_id") && 176 | (strncmp(attribute, "hint_id", strlen("hint_id")) == 0)) { 177 | if (strlen(value) > 0) { 178 | audio_metadata->hint_id = atoi(value); 179 | } 180 | } 181 | 182 | if (strlen(attribute) == strlen("state") && 183 | (strncmp(attribute, "state", strlen("state")) == 0)) { 184 | if (strlen(value) > 0) { 185 | audio_metadata->state = atoi(value); 186 | } 187 | } 188 | 189 | temp_metadata = NULL; 190 | } 191 | 192 | if (parsing_status == METADATA_PARSING_ERR) 193 | return -1; 194 | 195 | return 0; 196 | } 197 | -------------------------------------------------------------------------------- /power/performance.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions are 5 | * met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above 9 | * copyright notice, this list of conditions and the following 10 | * disclaimer in the documentation and/or other materials provided 11 | * with the distribution. 12 | * * Neither the name of The Linux Foundation nor the names of its 13 | * contributors may be used to endorse or promote products derived 14 | * from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #define FAILED -1 35 | #define SUCCESS 0 36 | #define INDEFINITE_DURATION 0 37 | 38 | enum SCREEN_DISPLAY_TYPE { 39 | DISPLAY_OFF = 0x00FF, 40 | }; 41 | 42 | enum PWR_CLSP_TYPE { 43 | #ifdef MPCTLV3 44 | ALL_CPUS_PWR_CLPS_DIS_V3 = 0x40400000, /* v3 resource */ 45 | #endif 46 | ALL_CPUS_PWR_CLPS_DIS = 0x101, 47 | }; 48 | 49 | /* For CPUx min freq, the leftmost byte 50 | * represents the CPU and the 51 | * rightmost byte represents the frequency 52 | * All intermediate frequencies on the 53 | * device are supported. The hex value 54 | * passed into PerfLock will be multiplied 55 | * by 10^5. This frequency or the next 56 | * highest frequency available will be set 57 | * 58 | * For example, if 1.4 Ghz is required on 59 | * CPU0, use 0x20E 60 | * 61 | * If the highest available frequency 62 | * on the device is required, use 63 | * CPUx_MIN_FREQ_TURBO_MAX 64 | * where x represents the CPU 65 | */ 66 | enum CPU0_MIN_FREQ_LVL { 67 | CPU0_MIN_FREQ_NONTURBO_MAX = 0x20A, 68 | CPU0_MIN_FREQ_TURBO_MAX = 0x2FE, 69 | }; 70 | 71 | enum CPU1_MIN_FREQ_LVL { 72 | CPU1_MIN_FREQ_NONTURBO_MAX = 0x30A, 73 | CPU1_MIN_FREQ_TURBO_MAX = 0x3FE, 74 | }; 75 | 76 | enum CPU2_MIN_FREQ_LVL { 77 | CPU2_MIN_FREQ_NONTURBO_MAX = 0x40A, 78 | CPU2_MIN_FREQ_TURBO_MAX = 0x4FE, 79 | }; 80 | 81 | enum CPU3_MIN_FREQ_LVL { 82 | CPU3_MIN_FREQ_NONTURBO_MAX = 0x50A, 83 | CPU3_MIN_FREQ_TURBO_MAX = 0x5FE, 84 | }; 85 | 86 | enum CPU0_MAX_FREQ_LVL { 87 | CPU0_MAX_FREQ_NONTURBO_MAX = 0x150A, 88 | }; 89 | 90 | enum CPU1_MAX_FREQ_LVL { 91 | CPU1_MAX_FREQ_NONTURBO_MAX = 0x160A, 92 | }; 93 | 94 | enum CPU2_MAX_FREQ_LVL { 95 | CPU2_MAX_FREQ_NONTURBO_MAX = 0x170A, 96 | }; 97 | 98 | enum CPU3_MAX_FREQ_LVL { 99 | CPU3_MAX_FREQ_NONTURBO_MAX = 0x180A, 100 | }; 101 | 102 | enum MIN_CPUS_ONLINE_LVL { 103 | #ifdef MPCTLV3 104 | CPUS_ONLINE_MIN_BIG = 0x41000000, /* v3 resource */ 105 | CPUS_ONLINE_MIN_LITTLE = 0x41000100, /* v3 resource */ 106 | #endif 107 | CPUS_ONLINE_MIN_2 = 0x702, 108 | CPUS_ONLINE_MIN_3 = 0x703, 109 | CPUS_ONLINE_MIN_4 = 0x704, 110 | CPUS_ONLINE_MPD_OVERRIDE = 0x777, 111 | CPUS_ONLINE_MAX = 0x7FF, 112 | }; 113 | 114 | enum MAX_CPUS_ONLINE_LVL { 115 | #ifdef MPCTLV3 116 | CPUS_ONLINE_MAX_LIMIT_BIG = 0x41004000, /* v3 resource */ 117 | CPUS_ONLINE_MAX_LIMIT_LITTLE = 0x41004100, /* v3 resource */ 118 | #endif 119 | CPUS_ONLINE_MAX_LIMIT_1 = 0x8FE, 120 | CPUS_ONLINE_MAX_LIMIT_2 = 0x8FD, 121 | CPUS_ONLINE_MAX_LIMIT_3 = 0x8FC, 122 | CPUS_ONLINE_MAX_LIMIT_4 = 0x8FB, 123 | CPUS_ONLINE_MAX_LIMIT_MAX = 0x8FB, 124 | }; 125 | 126 | enum SAMPLING_RATE_LVL { 127 | MS_500 = 0xBCD, 128 | MS_50 = 0xBFA, 129 | MS_20 = 0xBFD, 130 | }; 131 | 132 | enum ONDEMAND_IO_BUSY_LVL { 133 | IO_BUSY_OFF = 0xC00, 134 | IO_BUSY_ON = 0xC01, 135 | }; 136 | 137 | enum ONDEMAND_SAMPLING_DOWN_FACTOR_LVL { 138 | SAMPLING_DOWN_FACTOR_1 = 0xD01, 139 | SAMPLING_DOWN_FACTOR_4 = 0xD04, 140 | }; 141 | 142 | 143 | enum INTERACTIVE_TIMER_RATE_LVL { 144 | TR_MS_500 = 0xECD, 145 | TR_MS_100 = 0xEF5, 146 | TR_MS_50 = 0xEFA, 147 | TR_MS_30 = 0xEFC, 148 | TR_MS_20 = 0xEFD, 149 | }; 150 | 151 | /* This timer rate applicable to cpu0 152 | across 8939 series chipset */ 153 | enum INTERACTIVE_TIMER_RATE_LVL_CPU0_8939 { 154 | TR_MS_CPU0_500 = 0x30CD, 155 | TR_MS_CPU0_100 = 0x30F5, 156 | TR_MS_CPU0_50 = 0x30FA, 157 | TR_MS_CPU0_30 = 0x30FC, 158 | TR_MS_CPU0_20 = 0x30FD, 159 | }; 160 | 161 | /* This timer rate applicable to cpu4 162 | across 8939 series chipset */ 163 | enum INTERACTIVE_TIMER_RATE_LVL_CPU4_8939 { 164 | TR_MS_CPU4_500 = 0x3BCD, 165 | TR_MS_CPU4_100 = 0x3BF5, 166 | TR_MS_CPU4_50 = 0x3BFA, 167 | TR_MS_CPU4_30 = 0x3BFC, 168 | TR_MS_CPU4_20 = 0x3BFD, 169 | }; 170 | 171 | enum INTERACTIVE_HISPEED_FREQ_LVL { 172 | HS_FREQ_1026 = 0xF0A, 173 | HS_FREQ_800 = 0xF08, 174 | }; 175 | 176 | enum INTERACTIVE_HISPEED_LOAD_LVL { 177 | HISPEED_LOAD_90 = 0x105A, 178 | }; 179 | 180 | enum SYNC_FREQ_LVL { 181 | SYNC_FREQ_300 = 0x1103, 182 | SYNC_FREQ_600 = 0X1106, 183 | SYNC_FREQ_384 = 0x1103, 184 | SYNC_FREQ_NONTURBO_MAX = 0x110A, 185 | SYNC_FREQ_TURBO = 0x110F, 186 | }; 187 | 188 | enum OPTIMAL_FREQ_LVL { 189 | OPTIMAL_FREQ_300 = 0x1203, 190 | OPTIMAL_FREQ_600 = 0x1206, 191 | OPTIMAL_FREQ_384 = 0x1203, 192 | OPTIMAL_FREQ_NONTURBO_MAX = 0x120A, 193 | OPTIMAL_FREQ_TURBO = 0x120F, 194 | }; 195 | 196 | enum SCREEN_PWR_CLPS_LVL { 197 | PWR_CLPS_DIS = 0x1300, 198 | PWR_CLPS_ENA = 0x1301, 199 | }; 200 | 201 | enum THREAD_MIGRATION_LVL { 202 | THREAD_MIGRATION_SYNC_OFF = 0x1400, 203 | #ifdef MPCTLV3 204 | THREAD_MIGRATION_SYNC_ON_V3 = 0x4241C000 205 | #endif 206 | }; 207 | 208 | enum INTERACTIVE_IO_BUSY_LVL { 209 | INTERACTIVE_IO_BUSY_OFF = 0x1B00, 210 | INTERACTIVE_IO_BUSY_ON = 0x1B01, 211 | }; 212 | 213 | enum SCHED_BOOST_LVL { 214 | #ifdef MPCTLV3 215 | SCHED_BOOST_ON_V3 = 0x40C00000, /* v3 resource */ 216 | #endif 217 | SCHED_BOOST_ON = 0x1E01, 218 | }; 219 | 220 | enum CPU4_MIN_FREQ_LVL { 221 | CPU4_MIN_FREQ_NONTURBO_MAX = 0x1F0A, 222 | CPU4_MIN_FREQ_TURBO_MAX = 0x1FFE, 223 | }; 224 | 225 | enum CPU5_MIN_FREQ_LVL { 226 | CPU5_MIN_FREQ_NONTURBO_MAX = 0x200A, 227 | CPU5_MIN_FREQ_TURBO_MAX = 0x20FE, 228 | }; 229 | 230 | enum CPU6_MIN_FREQ_LVL { 231 | CPU6_MIN_FREQ_NONTURBO_MAX = 0x210A, 232 | CPU6_MIN_FREQ_TURBO_MAX = 0x21FE, 233 | }; 234 | 235 | enum CPU7_MIN_FREQ_LVL { 236 | CPU7_MIN_FREQ_NONTURBO_MAX = 0x220A, 237 | CPU7_MIN_FREQ_TURBO_MAX = 0x22FE, 238 | }; 239 | 240 | enum CPU4_MAX_FREQ_LVL { 241 | CPU4_MAX_FREQ_NONTURBO_MAX = 0x230A, 242 | }; 243 | 244 | enum CPU5_MAX_FREQ_LVL { 245 | CPU5_MAX_FREQ_NONTURBO_MAX = 0x240A, 246 | }; 247 | 248 | enum CPU6_MAX_FREQ_LVL { 249 | CPU6_MAX_FREQ_NONTURBO_MAX = 0x250A, 250 | }; 251 | 252 | enum CPU7_MAX_FREQ_LVL { 253 | CPU7_MAX_FREQ_NONTURBO_MAX = 0x260A, 254 | }; 255 | 256 | enum SCHED_PREFER_IDLE { 257 | #ifdef MPCTLV3 258 | SCHED_PREFER_IDLE_DIS_V3 = 0x40C04000, 259 | #endif 260 | SCHED_PREFER_IDLE_DIS = 0x3E01, 261 | }; 262 | 263 | enum SCHED_MIGRATE_COST_CHNG { 264 | SCHED_MIGRATE_COST_SET = 0x3F01, 265 | }; 266 | 267 | #ifdef MPCTLV3 268 | /** 269 | * MPCTL v3 opcodes 270 | */ 271 | enum MAX_FREQ_CLUSTER_BIG { 272 | MAX_FREQ_BIG_CORE_0 = 0x40804000, 273 | }; 274 | 275 | enum MAX_FREQ_CLUSTER_LITTLE { 276 | MAX_FREQ_LITTLE_CORE_0 = 0x40804100, 277 | }; 278 | 279 | enum MIN_FREQ_CLUSTER_BIG { 280 | MIN_FREQ_BIG_CORE_0 = 0x40800000, 281 | }; 282 | 283 | enum MIN_FREQ_CLUSTER_LITTLE { 284 | MIN_FREQ_LITTLE_CORE_0 = 0x40800100, 285 | }; 286 | 287 | enum INTERACTIVE_CLUSTER_BIG { 288 | ABOVE_HISPEED_DELAY_BIG = 0x41400000, 289 | GO_HISPEED_LOAD_BIG = 0x41410000, 290 | HISPEED_FREQ_BIG = 0x41414000, 291 | TARGET_LOADS_BIG = 0x41420000, 292 | TIMER_RATE_BIG = 0x41424000, 293 | USE_SCHED_LOAD_BIG = 0x41430000, 294 | USE_MIGRATION_NOTIF_BIG = 0x41434000, 295 | IGNORE_HISPEED_NOTIF_BIG = 0x41438000, 296 | }; 297 | 298 | enum INTERACTIVE_CLUSTER_LITTLE { 299 | ABOVE_HISPEED_DELAY_LITTLE = 0x41400100, 300 | GO_HISPEED_LOAD_LITTLE = 0x41410100, 301 | HISPEED_FREQ_LITTLE = 0x41414100, 302 | TARGET_LOADS_LITTLE = 0x41420100, 303 | TIMER_RATE_LITTLE = 0x41424100, 304 | USE_SCHED_LOAD_LITTLE = 0x41430100, 305 | USE_MIGRATION_NOTIF_LITTLE = 0x41434100, 306 | IGNORE_HISPEED_NOTIF_LITTLE = 0x41438100, 307 | }; 308 | 309 | enum CPUBW_HWMON { 310 | CPUBW_HWMON_MIN_FREQ = 0x41800000, 311 | CPUBW_HWMON_V1 = 0x4180C000, 312 | LOW_POWER_CEIL_MBPS = 0x41810000, 313 | LOW_POWER_IO_PERCENT = 0x41814000, 314 | CPUBW_HWMON_SAMPLE_MS = 0x41820000, 315 | }; 316 | 317 | enum SCHEDULER { 318 | SCHED_SMALL_TASK_DIS = 0x40C0C000, 319 | SCHED_IDLE_LOAD_DIS = 0x40C10000, 320 | SCHED_IDLE_NR_RUN_DIS = 0x40C14000, 321 | SCHED_GROUP_ON = 0x40C28000, 322 | }; 323 | 324 | enum STORAGE { 325 | STOR_CLK_SCALE_DIS = 0x42C0C000, 326 | }; 327 | 328 | enum GPU { 329 | GPU_MIN_PWRLVL_BOOST = 0x42804000, 330 | }; 331 | #endif 332 | 333 | #ifdef __cplusplus 334 | } 335 | #endif 336 | -------------------------------------------------------------------------------- /power/power-8084.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #define LOG_NIDEBUG 0 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define LOG_TAG "QCOM PowerHAL" 40 | #include 41 | #include 42 | #include 43 | 44 | #include "utils.h" 45 | #include "metadata-defs.h" 46 | #include "hint-data.h" 47 | #include "performance.h" 48 | #include "power-common.h" 49 | 50 | static int first_display_off_hint; 51 | 52 | int get_number_of_profiles() { 53 | return 3; 54 | } 55 | 56 | static int current_power_profile = PROFILE_BALANCED; 57 | 58 | static void set_power_profile(int profile) { 59 | 60 | if (profile == current_power_profile) 61 | return; 62 | 63 | ALOGV("%s: profile=%d", __func__, profile); 64 | 65 | if (current_power_profile != PROFILE_BALANCED) { 66 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 67 | ALOGV("%s: hint undone", __func__); 68 | } 69 | 70 | if (profile == PROFILE_HIGH_PERFORMANCE) { 71 | int resource_values[] = { CPUS_ONLINE_MIN_4, 72 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, 73 | CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX }; 74 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 75 | resource_values, ARRAY_SIZE(resource_values)); 76 | ALOGD("%s: set performance mode", __func__); 77 | 78 | } else if (profile == PROFILE_POWER_SAVE) { 79 | int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_2, 80 | CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, 81 | CPU2_MAX_FREQ_NONTURBO_MAX, CPU3_MAX_FREQ_NONTURBO_MAX }; 82 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 83 | resource_values, ARRAY_SIZE(resource_values)); 84 | ALOGD("%s: set powersave", __func__); 85 | } 86 | 87 | current_power_profile = profile; 88 | } 89 | 90 | extern void interaction(int duration, int num_args, int opt_list[]); 91 | 92 | int power_hint_override(__attribute__((unused)) struct power_module *module, 93 | power_hint_t hint, void *data) 94 | { 95 | if (hint == POWER_HINT_SET_PROFILE) { 96 | set_power_profile(*(int32_t *)data); 97 | return HINT_HANDLED; 98 | } 99 | 100 | // Skip other hints in custom power modes 101 | if (current_power_profile != PROFILE_BALANCED) { 102 | return HINT_HANDLED; 103 | } 104 | 105 | if (hint == POWER_HINT_CPU_BOOST) { 106 | int duration = *(int32_t *)data / 1000; 107 | int resources[] = { CPUS_ONLINE_MIN_2, 0x20B, 0x30B, 0x1C00}; 108 | 109 | if (duration > 0) 110 | interaction(duration, ARRAY_SIZE(resources), resources); 111 | 112 | return HINT_HANDLED; 113 | } 114 | 115 | return HINT_NONE; 116 | } 117 | 118 | int set_interactive_override(struct power_module *module, int on) 119 | { 120 | char governor[80]; 121 | 122 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 123 | ALOGE("Can't obtain scaling governor."); 124 | 125 | return HINT_NONE; 126 | } 127 | 128 | if (!on) { 129 | /* Display off. */ 130 | /* 131 | * We need to be able to identify the first display off hint 132 | * and release the current lock holder 133 | */ 134 | if (!first_display_off_hint) { 135 | undo_initial_hint_action(); 136 | first_display_off_hint = 1; 137 | } 138 | /* Used for all subsequent toggles to the display */ 139 | undo_hint_action(DISPLAY_STATE_HINT_ID_2); 140 | 141 | if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && 142 | (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { 143 | int resource_values[] = {MS_500, SYNC_FREQ_600, OPTIMAL_FREQ_600, THREAD_MIGRATION_SYNC_OFF}; 144 | 145 | perform_hint_action(DISPLAY_STATE_HINT_ID, 146 | resource_values, ARRAY_SIZE(resource_values)); 147 | 148 | return HINT_HANDLED; 149 | } 150 | } else { 151 | /* Display on */ 152 | int resource_values2[] = { CPUS_ONLINE_MIN_2 }; 153 | perform_hint_action(DISPLAY_STATE_HINT_ID_2, 154 | resource_values2, ARRAY_SIZE(resource_values2)); 155 | 156 | if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && 157 | (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { 158 | undo_hint_action(DISPLAY_STATE_HINT_ID); 159 | 160 | return HINT_HANDLED; 161 | } 162 | } 163 | 164 | return HINT_NONE; 165 | } 166 | -------------------------------------------------------------------------------- /power/power-8226.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * Copyright (c) 2014, The CyanogenMod Project 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following 12 | * disclaimer in the documentation and/or other materials provided 13 | * with the distribution. 14 | * * Neither the name of The Linux Foundation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 28 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #define LOG_NIDEBUG 0 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define LOG_TAG "QCOM PowerHAL" 41 | #include 42 | #include 43 | #include 44 | 45 | #include "utils.h" 46 | #include "metadata-defs.h" 47 | #include "hint-data.h" 48 | #include "performance.h" 49 | #include "power-common.h" 50 | 51 | int get_number_of_profiles() { 52 | return 3; 53 | } 54 | 55 | static int current_power_profile = PROFILE_BALANCED; 56 | 57 | static void set_power_profile(int profile) { 58 | 59 | if (profile == current_power_profile) 60 | return; 61 | 62 | ALOGV("%s: profile=%d", __func__, profile); 63 | 64 | if (current_power_profile != PROFILE_BALANCED) { 65 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 66 | ALOGV("%s: hint undone", __func__); 67 | } 68 | 69 | if (profile == PROFILE_HIGH_PERFORMANCE) { 70 | int resource_values[] = { CPUS_ONLINE_MIN_4, 71 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, 72 | CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX }; 73 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 74 | resource_values, ARRAY_SIZE(resource_values)); 75 | ALOGD("%s: set performance mode", __func__); 76 | } else if (profile == PROFILE_POWER_SAVE) { 77 | int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_2, 78 | CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, 79 | CPU2_MAX_FREQ_NONTURBO_MAX, CPU3_MAX_FREQ_NONTURBO_MAX }; 80 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 81 | resource_values, ARRAY_SIZE(resource_values)); 82 | ALOGD("%s: set powersave", __func__); 83 | } 84 | 85 | current_power_profile = profile; 86 | } 87 | 88 | extern void interaction(int duration, int num_args, int opt_list[]); 89 | 90 | int power_hint_override(__attribute__((unused)) struct power_module *module, 91 | power_hint_t hint, void *data) 92 | { 93 | if (hint == POWER_HINT_SET_PROFILE) { 94 | set_power_profile(*(int32_t *)data); 95 | return HINT_HANDLED; 96 | } 97 | 98 | // Skip other hints in custom power modes 99 | if (current_power_profile != PROFILE_BALANCED) { 100 | return HINT_HANDLED; 101 | } 102 | 103 | if (hint == POWER_HINT_CPU_BOOST) { 104 | int duration = *(int32_t *)data / 1000; 105 | int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F}; 106 | 107 | if (duration > 0) 108 | interaction(duration, ARRAY_SIZE(resources), resources); 109 | return HINT_HANDLED; 110 | } else if (hint == POWER_HINT_INTERACTION) { 111 | int resources[] = {0x702, 0x20B, 0x30B}; 112 | int duration = 3000; 113 | 114 | interaction(duration, ARRAY_SIZE(resources), resources); 115 | return HINT_HANDLED; 116 | } 117 | 118 | return HINT_NONE; 119 | } 120 | -------------------------------------------------------------------------------- /power/power-8610.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * Copyright (c) 2014, The CyanogenMod Project 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following 12 | * disclaimer in the documentation and/or other materials provided 13 | * with the distribution. 14 | * * Neither the name of The Linux Foundation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 28 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #define LOG_NIDEBUG 0 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define LOG_TAG "QCOM PowerHAL" 41 | #include 42 | #include 43 | #include 44 | 45 | #include "utils.h" 46 | #include "metadata-defs.h" 47 | #include "hint-data.h" 48 | #include "performance.h" 49 | #include "power-common.h" 50 | 51 | int get_number_of_profiles() { 52 | return 3; 53 | } 54 | 55 | static int current_power_profile = PROFILE_BALANCED; 56 | 57 | static void set_power_profile(int profile) { 58 | 59 | if (profile == current_power_profile) 60 | return; 61 | 62 | ALOGV("%s: profile=%d", __func__, profile); 63 | 64 | if (current_power_profile != PROFILE_BALANCED) { 65 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 66 | ALOGV("%s: hint undone", __func__); 67 | } 68 | 69 | if (profile == PROFILE_HIGH_PERFORMANCE) { 70 | int resource_values[] = { CPUS_ONLINE_MIN_2, 71 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX }; 72 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 73 | resource_values, ARRAY_SIZE(resource_values)); 74 | ALOGD("%s: set performance mode", __func__); 75 | } else if (profile == PROFILE_POWER_SAVE) { 76 | int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_2, 77 | CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX }; 78 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 79 | resource_values, ARRAY_SIZE(resource_values)); 80 | ALOGD("%s: set powersave", __func__); 81 | } 82 | 83 | current_power_profile = profile; 84 | } 85 | 86 | extern void interaction(int duration, int num_args, int opt_list[]); 87 | 88 | int power_hint_override(__attribute__((unused)) struct power_module *module, 89 | power_hint_t hint, void *data) 90 | { 91 | if (hint == POWER_HINT_SET_PROFILE) { 92 | set_power_profile(*(int32_t *)data); 93 | return HINT_HANDLED; 94 | } 95 | 96 | // Skip other hints in custom power modes 97 | if (current_power_profile != PROFILE_BALANCED) { 98 | return HINT_HANDLED; 99 | } 100 | 101 | if (hint == POWER_HINT_CPU_BOOST) { 102 | int duration = *(int32_t *)data / 1000; 103 | int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F}; 104 | 105 | if (duration > 0) 106 | interaction(duration, ARRAY_SIZE(resources), resources); 107 | return HINT_HANDLED; 108 | } else if (hint == POWER_HINT_INTERACTION) { 109 | int resources[] = {0x702, 0x20B, 0x30B}; 110 | int duration = 3000; 111 | 112 | interaction(duration, ARRAY_SIZE(resources), resources); 113 | return HINT_HANDLED; 114 | } 115 | 116 | return HINT_NONE; 117 | } 118 | -------------------------------------------------------------------------------- /power/power-8909.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #define LOG_NIDEBUG 0 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define LOG_TAG "QTI PowerHAL" 40 | #include 41 | #include 42 | #include 43 | 44 | #include "utils.h" 45 | #include "metadata-defs.h" 46 | #include "hint-data.h" 47 | #include "performance.h" 48 | #include "power-common.h" 49 | 50 | 51 | static void process_video_encode_hint(void *metadata) 52 | { 53 | char governor[80]; 54 | struct video_encode_metadata_t video_encode_metadata; 55 | char tmp_str[NODE_MAX]; 56 | 57 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 58 | ALOGE("Can't obtain scaling governor."); 59 | 60 | return; 61 | } 62 | 63 | /* Initialize encode metadata struct fields. */ 64 | memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); 65 | video_encode_metadata.state = -1; 66 | video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; 67 | 68 | if (metadata) { 69 | if (parse_video_encode_metadata((char *)metadata, &video_encode_metadata) == 70 | -1) { 71 | ALOGE("Error occurred while parsing metadata."); 72 | return; 73 | } 74 | } else { 75 | return; 76 | } 77 | 78 | if (video_encode_metadata.state == 1) { 79 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 80 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 81 | int resource_values[] = {HS_FREQ_800, THREAD_MIGRATION_SYNC_OFF}; 82 | perform_hint_action(video_encode_metadata.hint_id, 83 | resource_values, ARRAY_SIZE(resource_values)); 84 | } 85 | } else if (video_encode_metadata.state == 0) { 86 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 87 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 88 | undo_hint_action(video_encode_metadata.hint_id); 89 | } 90 | } 91 | } 92 | 93 | int power_hint_override(struct power_module *module, power_hint_t hint, void *data) 94 | { 95 | switch(hint) { 96 | case POWER_HINT_VIDEO_ENCODE: 97 | { 98 | process_video_encode_hint(data); 99 | return HINT_HANDLED; 100 | } 101 | default: 102 | { 103 | break; 104 | } 105 | } 106 | return HINT_NONE; 107 | } 108 | -------------------------------------------------------------------------------- /power/power-8937.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #define LOG_NIDEBUG 0 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define LOG_TAG "QTI PowerHAL" 41 | #include 42 | #include 43 | #include 44 | 45 | #include "utils.h" 46 | #include "metadata-defs.h" 47 | #include "hint-data.h" 48 | #include "performance.h" 49 | #include "power-common.h" 50 | 51 | static int video_encode_hint_sent; 52 | static int current_power_profile = PROFILE_BALANCED; 53 | 54 | static void process_video_encode_hint(void *metadata); 55 | 56 | extern void interaction(int duration, int num_args, int opt_list[]); 57 | 58 | static int profile_high_performance[] = { 59 | SCHED_BOOST_ON_V3, 0x1, 60 | ALL_CPUS_PWR_CLPS_DIS_V3, 0x1, 61 | CPUS_ONLINE_MIN_BIG, 0x4, 62 | MIN_FREQ_BIG_CORE_0, 0xFFF, 63 | MIN_FREQ_LITTLE_CORE_0, 0xFFF, 64 | GPU_MIN_PWRLVL_BOOST, 0x1, 65 | SCHED_PREFER_IDLE_DIS_V3, 0x1, 66 | SCHED_SMALL_TASK_DIS, 0x1, 67 | SCHED_IDLE_NR_RUN_DIS, 0x1, 68 | SCHED_IDLE_LOAD_DIS, 0x1, 69 | }; 70 | 71 | static int profile_power_save[] = { 72 | CPUS_ONLINE_MAX_LIMIT_BIG, 0x1, 73 | MAX_FREQ_BIG_CORE_0, 0x3bf, 74 | MAX_FREQ_LITTLE_CORE_0, 0x300, 75 | }; 76 | 77 | static int profile_bias_power[] = { 78 | MAX_FREQ_BIG_CORE_0, 0x4B0, 79 | MAX_FREQ_LITTLE_CORE_0, 0x300, 80 | }; 81 | 82 | static int profile_bias_performance[] = { 83 | CPUS_ONLINE_MAX_LIMIT_BIG, 0x4, 84 | MIN_FREQ_BIG_CORE_0, 0x540, 85 | }; 86 | 87 | int get_number_of_profiles() { 88 | return 5; 89 | } 90 | 91 | static void set_power_profile(int profile) { 92 | 93 | if (profile == current_power_profile) 94 | return; 95 | 96 | ALOGV("%s: profile=%d", __func__, profile); 97 | 98 | if (current_power_profile != PROFILE_BALANCED) { 99 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 100 | ALOGV("%s: hint undone", __func__); 101 | } 102 | 103 | if (profile == PROFILE_HIGH_PERFORMANCE) { 104 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_high_performance, 105 | ARRAY_SIZE(profile_high_performance)); 106 | ALOGD("%s: set performance mode", __func__); 107 | 108 | } else if (profile == PROFILE_POWER_SAVE) { 109 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_power_save, 110 | ARRAY_SIZE(profile_power_save)); 111 | ALOGD("%s: set powersave", __func__); 112 | } else if (profile == PROFILE_BIAS_POWER) { 113 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_bias_power, 114 | ARRAY_SIZE(profile_bias_power)); 115 | ALOGD("%s: Set bias power mode", __func__); 116 | 117 | } else if (profile == PROFILE_BIAS_PERFORMANCE) { 118 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_bias_performance, 119 | ARRAY_SIZE(profile_bias_performance)); 120 | ALOGD("%s: Set bias perf mode", __func__); 121 | } 122 | 123 | current_power_profile = profile; 124 | } 125 | 126 | int power_hint_override(__unused struct power_module *module, power_hint_t hint, 127 | void *data) 128 | { 129 | int duration, duration_hint; 130 | static struct timespec s_previous_boost_timespec; 131 | struct timespec cur_boost_timespec; 132 | long long elapsed_time; 133 | int resources_launch_boost[] = { 134 | SCHED_BOOST_ON_V3, 0x1, 135 | MIN_FREQ_BIG_CORE_0, 0x5DC, 136 | ALL_CPUS_PWR_CLPS_DIS_V3, 0x1, 137 | CPUS_ONLINE_MIN_BIG, 0x4, 138 | GPU_MIN_PWRLVL_BOOST, 0x1, 139 | SCHED_PREFER_IDLE_DIS_V3, 0x1, 140 | SCHED_SMALL_TASK_DIS, 0x1, 141 | SCHED_IDLE_NR_RUN_DIS, 0x1, 142 | SCHED_IDLE_LOAD_DIS, 0x1, 143 | }; 144 | 145 | int resources_cpu_boost[] = { 146 | SCHED_BOOST_ON_V3, 0x1, 147 | MIN_FREQ_BIG_CORE_0, 0x44C, 148 | }; 149 | 150 | int resources_interaction_fling_boost[] = { 151 | MIN_FREQ_BIG_CORE_0, 0x514, 152 | SCHED_BOOST_ON_V3, 0x1, 153 | }; 154 | 155 | if (hint == POWER_HINT_SET_PROFILE) { 156 | set_power_profile(*(int32_t *)data); 157 | return HINT_HANDLED; 158 | } 159 | 160 | // Skip other hints in power save mode 161 | if (current_power_profile == PROFILE_POWER_SAVE) { 162 | return HINT_HANDLED; 163 | } 164 | 165 | switch (hint) { 166 | case POWER_HINT_INTERACTION: 167 | duration = 500; 168 | duration_hint = 0; 169 | 170 | if (data) { 171 | duration_hint = *((int *)data); 172 | } 173 | 174 | duration = duration_hint > 0 ? duration_hint : 500; 175 | 176 | clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); 177 | elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); 178 | if (elapsed_time > 750000) 179 | elapsed_time = 750000; 180 | // don't hint if it's been less than 250ms since last boost 181 | // also detect if we're doing anything resembling a fling 182 | // support additional boosting in case of flings 183 | else if (elapsed_time < 250000 && duration <= 750) 184 | return HINT_HANDLED; 185 | 186 | s_previous_boost_timespec = cur_boost_timespec; 187 | 188 | if (duration >= 1500) { 189 | interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost), 190 | resources_interaction_fling_boost); 191 | } 192 | return HINT_HANDLED; 193 | case POWER_HINT_LAUNCH_BOOST: 194 | duration = 2000; 195 | interaction(duration, ARRAY_SIZE(resources_launch_boost), 196 | resources_launch_boost); 197 | return HINT_HANDLED; 198 | case POWER_HINT_CPU_BOOST: 199 | duration = *(int32_t *)data / 1000; 200 | if (duration > 0) { 201 | interaction(duration, ARRAY_SIZE(resources_cpu_boost), 202 | resources_cpu_boost); 203 | } 204 | return HINT_HANDLED; 205 | case POWER_HINT_VIDEO_ENCODE: 206 | process_video_encode_hint(data); 207 | return HINT_HANDLED; 208 | default: 209 | break; 210 | } 211 | return HINT_NONE; 212 | } 213 | 214 | int set_interactive_override(__unused struct power_module *module, int on) 215 | { 216 | char governor[80]; 217 | 218 | ALOGI("Got set_interactive hint"); 219 | 220 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU0) == -1) { 221 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU1) == -1) { 222 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU2) == -1) { 223 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU3) == -1) { 224 | ALOGE("Can't obtain scaling governor."); 225 | return HINT_HANDLED; 226 | } 227 | } 228 | } 229 | } 230 | 231 | if (!on) { 232 | /* Display off. */ 233 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 234 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 235 | int resource_values[] = { 236 | TIMER_RATE_BIG, 0x32, 237 | TIMER_RATE_LITTLE, 0x32, 238 | THREAD_MIGRATION_SYNC_ON_V3, 0x0, 239 | }; 240 | 241 | perform_hint_action(DISPLAY_STATE_HINT_ID, 242 | resource_values, ARRAY_SIZE(resource_values)); 243 | } /* Perf time rate set for CORE0,CORE4 8952 target*/ 244 | 245 | } else { 246 | /* Display on. */ 247 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 248 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 249 | 250 | undo_hint_action(DISPLAY_STATE_HINT_ID); 251 | } 252 | } 253 | return HINT_HANDLED; 254 | } 255 | 256 | /* Video Encode Hint */ 257 | static void process_video_encode_hint(void *metadata) 258 | { 259 | char governor[80]; 260 | struct video_encode_metadata_t video_encode_metadata; 261 | 262 | ALOGI("Got process_video_encode_hint"); 263 | 264 | if (get_scaling_governor_check_cores(governor, 265 | sizeof(governor),CPU0) == -1) { 266 | if (get_scaling_governor_check_cores(governor, 267 | sizeof(governor),CPU1) == -1) { 268 | if (get_scaling_governor_check_cores(governor, 269 | sizeof(governor),CPU2) == -1) { 270 | if (get_scaling_governor_check_cores(governor, 271 | sizeof(governor),CPU3) == -1) { 272 | ALOGE("Can't obtain scaling governor."); 273 | return; 274 | } 275 | } 276 | } 277 | } 278 | 279 | /* Initialize encode metadata struct fields. */ 280 | memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); 281 | video_encode_metadata.state = -1; 282 | video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; 283 | 284 | if (metadata) { 285 | if (parse_video_encode_metadata((char *)metadata, 286 | &video_encode_metadata) == -1) { 287 | ALOGE("Error occurred while parsing metadata."); 288 | return; 289 | } 290 | } else { 291 | return; 292 | } 293 | 294 | if (video_encode_metadata.state == 1) { 295 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, 296 | strlen(INTERACTIVE_GOVERNOR)) == 0) && 297 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 298 | int resource_values[] = { 299 | USE_SCHED_LOAD_BIG, 0x1, 300 | USE_SCHED_LOAD_LITTLE, 0x1, 301 | USE_MIGRATION_NOTIF_BIG, 0x1, 302 | USE_MIGRATION_NOTIF_LITTLE, 0x1, 303 | TIMER_RATE_BIG, 0x28, 304 | TIMER_RATE_LITTLE, 0x28, 305 | }; 306 | if (!video_encode_hint_sent) { 307 | perform_hint_action(video_encode_metadata.hint_id, 308 | resource_values, 309 | ARRAY_SIZE(resource_values)); 310 | video_encode_hint_sent = 1; 311 | } 312 | } 313 | } else if (video_encode_metadata.state == 0) { 314 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, 315 | strlen(INTERACTIVE_GOVERNOR)) == 0) && 316 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 317 | undo_hint_action(video_encode_metadata.hint_id); 318 | video_encode_hint_sent = 0; 319 | return ; 320 | } 321 | } 322 | return; 323 | } 324 | -------------------------------------------------------------------------------- /power/power-8952.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #define LOG_NIDEBUG 0 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define LOG_TAG "QTI PowerHAL" 41 | #include 42 | #include 43 | #include 44 | 45 | #include "utils.h" 46 | #include "metadata-defs.h" 47 | #include "hint-data.h" 48 | #include "performance.h" 49 | #include "power-common.h" 50 | 51 | static int video_encode_hint_sent; 52 | static int current_power_profile = PROFILE_BALANCED; 53 | 54 | static void process_video_encode_hint(void *metadata); 55 | 56 | extern void interaction(int duration, int num_args, int opt_list[]); 57 | 58 | static int profile_high_performance_8952[11] = { 59 | SCHED_BOOST_ON, 60 | 0x704, 0x4d04, /* Enable all CPUs */ 61 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, 62 | CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX, 63 | CPU4_MIN_FREQ_TURBO_MAX, CPU5_MIN_FREQ_TURBO_MAX, 64 | CPU6_MIN_FREQ_TURBO_MAX, CPU7_MIN_FREQ_TURBO_MAX, 65 | }; 66 | 67 | static int profile_power_save_8952[] = { 68 | 0x8fe, 0x3dfd, /* 1 big core, 2 little cores*/ 69 | CPUS_ONLINE_MAX_LIMIT_2, 70 | CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, 71 | CPU2_MAX_FREQ_NONTURBO_MAX, CPU3_MAX_FREQ_NONTURBO_MAX, 72 | }; 73 | 74 | int get_number_of_profiles() { 75 | return 3; 76 | } 77 | 78 | static void set_power_profile(int profile) { 79 | 80 | if (profile == current_power_profile) 81 | return; 82 | 83 | ALOGV("%s: profile=%d", __func__, profile); 84 | 85 | if (current_power_profile != PROFILE_BALANCED) { 86 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 87 | ALOGV("%s: hint undone", __func__); 88 | } 89 | 90 | if (profile == PROFILE_HIGH_PERFORMANCE) { 91 | int *resource_values = profile_high_performance_8952; 92 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, resource_values, 93 | ARRAY_SIZE(resource_values)); 94 | ALOGD("%s: set performance mode", __func__); 95 | 96 | } else if (profile == PROFILE_POWER_SAVE) { 97 | int *resource_values = profile_power_save_8952; 98 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, resource_values, 99 | ARRAY_SIZE(resource_values)); 100 | ALOGD("%s: set powersave", __func__); 101 | } 102 | 103 | current_power_profile = profile; 104 | } 105 | 106 | int power_hint_override(struct power_module *module, power_hint_t hint, 107 | void *data) 108 | { 109 | int duration, duration_hint; 110 | static struct timespec s_previous_boost_timespec; 111 | struct timespec cur_boost_timespec; 112 | long long elapsed_time; 113 | int resources_launch_boost[] = { 114 | ALL_CPUS_PWR_CLPS_DIS, 115 | SCHED_BOOST_ON, 116 | SCHED_PREFER_IDLE_DIS, 117 | 0x20f, 118 | 0x4001, 119 | 0x4101, 120 | 0x4201, 121 | }; 122 | int resources_cpu_boost[] = { 123 | ALL_CPUS_PWR_CLPS_DIS, 124 | SCHED_BOOST_ON, 125 | SCHED_PREFER_IDLE_DIS, 126 | 0x20d, 127 | }; 128 | int resources_interaction_boost[] = { 129 | SCHED_PREFER_IDLE_DIS, 130 | 0x20d, 131 | 0x3d01, 132 | }; 133 | 134 | if (hint == POWER_HINT_SET_PROFILE) { 135 | set_power_profile(*(int32_t *)data); 136 | return HINT_HANDLED; 137 | } 138 | 139 | // Skip other hints in custom power modes 140 | if (current_power_profile != PROFILE_BALANCED) { 141 | return HINT_HANDLED; 142 | } 143 | 144 | switch (hint) { 145 | case POWER_HINT_INTERACTION: 146 | duration = 500; 147 | duration_hint = 0; 148 | 149 | if (data) { 150 | duration_hint = *((int *)data); 151 | } 152 | 153 | duration = duration_hint > 0 ? duration_hint : 500; 154 | 155 | clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); 156 | elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); 157 | if (elapsed_time > 750000) 158 | elapsed_time = 750000; 159 | // don't hint if it's been less than 250ms since last boost 160 | // also detect if we're doing anything resembling a fling 161 | // support additional boosting in case of flings 162 | else if (elapsed_time < 250000 && duration <= 750) 163 | return HINT_HANDLED; 164 | 165 | s_previous_boost_timespec = cur_boost_timespec; 166 | 167 | if (duration >= 1500) { 168 | interaction(duration, ARRAY_SIZE(resources_cpu_boost), 169 | resources_cpu_boost); 170 | } else { 171 | interaction(duration, ARRAY_SIZE(resources_interaction_boost), 172 | resources_interaction_boost); 173 | } 174 | return HINT_HANDLED; 175 | case POWER_HINT_LAUNCH_BOOST: 176 | duration = 2000; 177 | interaction(duration, ARRAY_SIZE(resources_launch_boost), 178 | resources_launch_boost); 179 | return HINT_HANDLED; 180 | case POWER_HINT_CPU_BOOST: 181 | duration = *(int32_t *)data / 1000; 182 | if (duration > 0) { 183 | interaction(duration, ARRAY_SIZE(resources_cpu_boost), 184 | resources_cpu_boost); 185 | } 186 | return HINT_HANDLED; 187 | case POWER_HINT_VIDEO_ENCODE: 188 | process_video_encode_hint(data); 189 | return HINT_HANDLED; 190 | } 191 | return HINT_NONE; 192 | } 193 | 194 | int set_interactive_override(struct power_module *module, int on) 195 | { 196 | char governor[80]; 197 | 198 | ALOGI("Got set_interactive hint"); 199 | 200 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU0) == -1) { 201 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU1) == -1) { 202 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU2) == -1) { 203 | if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU3) == -1) { 204 | ALOGE("Can't obtain scaling governor."); 205 | return HINT_HANDLED; 206 | } 207 | } 208 | } 209 | } 210 | 211 | if (!on) { 212 | /* Display off. */ 213 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 214 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 215 | int resource_values[] = {TR_MS_CPU0_50, TR_MS_CPU4_50}; 216 | 217 | perform_hint_action(DISPLAY_STATE_HINT_ID, 218 | resource_values, ARRAY_SIZE(resource_values)); 219 | } /* Perf time rate set for CORE0,CORE4 8952 target*/ 220 | 221 | } else { 222 | /* Display on. */ 223 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 224 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 225 | 226 | undo_hint_action(DISPLAY_STATE_HINT_ID); 227 | } 228 | } 229 | return HINT_HANDLED; 230 | } 231 | 232 | /* Video Encode Hint */ 233 | static void process_video_encode_hint(void *metadata) 234 | { 235 | char governor[80]; 236 | struct video_encode_metadata_t video_encode_metadata; 237 | 238 | ALOGI("Got process_video_encode_hint"); 239 | 240 | if (get_scaling_governor_check_cores(governor, 241 | sizeof(governor),CPU0) == -1) { 242 | if (get_scaling_governor_check_cores(governor, 243 | sizeof(governor),CPU1) == -1) { 244 | if (get_scaling_governor_check_cores(governor, 245 | sizeof(governor),CPU2) == -1) { 246 | if (get_scaling_governor_check_cores(governor, 247 | sizeof(governor),CPU3) == -1) { 248 | ALOGE("Can't obtain scaling governor."); 249 | return; 250 | } 251 | } 252 | } 253 | } 254 | 255 | /* Initialize encode metadata struct fields. */ 256 | memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); 257 | video_encode_metadata.state = -1; 258 | video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; 259 | 260 | if (metadata) { 261 | if (parse_video_encode_metadata((char *)metadata, 262 | &video_encode_metadata) == -1) { 263 | ALOGE("Error occurred while parsing metadata."); 264 | return; 265 | } 266 | } else { 267 | return; 268 | } 269 | 270 | if (video_encode_metadata.state == 1) { 271 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, 272 | strlen(INTERACTIVE_GOVERNOR)) == 0) && 273 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 274 | int resource_values[] = {TR_MS_CPU0_30, TR_MS_CPU4_30}; 275 | if (!video_encode_hint_sent) { 276 | perform_hint_action(video_encode_metadata.hint_id, 277 | resource_values, 278 | ARRAY_SIZE(resource_values)); 279 | video_encode_hint_sent = 1; 280 | } 281 | } 282 | } else if (video_encode_metadata.state == 0) { 283 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, 284 | strlen(INTERACTIVE_GOVERNOR)) == 0) && 285 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 286 | undo_hint_action(video_encode_metadata.hint_id); 287 | video_encode_hint_sent = 0; 288 | return ; 289 | } 290 | } 291 | return; 292 | } 293 | -------------------------------------------------------------------------------- /power/power-8960.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * Copyright (c) 2015, The CyanogenMod Project 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following 12 | * disclaimer in the documentation and/or other materials provided 13 | * with the distribution. 14 | * * Neither the name of The Linux Foundation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 28 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #define LOG_NIDEBUG 0 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define LOG_TAG "QCOM PowerHAL" 41 | #include 42 | #include 43 | #include 44 | 45 | #include "utils.h" 46 | #include "metadata-defs.h" 47 | #include "hint-data.h" 48 | #include "performance.h" 49 | #include "power-common.h" 50 | 51 | static int current_power_profile = PROFILE_BALANCED; 52 | 53 | int get_number_of_profiles() { 54 | return 3; 55 | } 56 | 57 | /** 58 | * If target is 8064: 59 | * return 1 60 | * else: 61 | * return 0 62 | */ 63 | static int is_target_8064(void) 64 | { 65 | static int is_8064 = -1; 66 | int soc_id; 67 | 68 | if (is_8064 >= 0) 69 | return is_8064; 70 | 71 | soc_id = get_soc_id(); 72 | if (soc_id == 153) 73 | is_8064 = 1; 74 | else 75 | is_8064 = 0; 76 | 77 | return is_8064; 78 | } 79 | 80 | static int profile_high_performance_8960[] = { 81 | CPUS_ONLINE_MIN_2, 82 | }; 83 | 84 | static int profile_high_performance_8064[] = { 85 | CPUS_ONLINE_MIN_4, 86 | }; 87 | 88 | static int profile_power_save_8960[] = { 89 | /* Don't do anything for now */ 90 | }; 91 | 92 | static int profile_power_save_8064[] = { 93 | CPUS_ONLINE_MAX_LIMIT_2, 94 | }; 95 | 96 | static void set_power_profile(int profile) { 97 | 98 | if (profile == current_power_profile) 99 | return; 100 | 101 | ALOGV("%s: profile=%d", __func__, profile); 102 | 103 | if (current_power_profile != PROFILE_BALANCED) { 104 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 105 | ALOGV("%s: hint undone", __func__); 106 | } 107 | 108 | if (profile == PROFILE_HIGH_PERFORMANCE) { 109 | int *resource_values = is_target_8064() ? 110 | profile_high_performance_8064 : profile_high_performance_8960; 111 | 112 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 113 | resource_values, ARRAY_SIZE(resource_values)); 114 | ALOGD("%s: set performance mode", __func__); 115 | } else if (profile == PROFILE_POWER_SAVE) { 116 | int* resource_values = is_target_8064() ? 117 | profile_power_save_8064 : profile_power_save_8960; 118 | 119 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 120 | resource_values, ARRAY_SIZE(resource_values)); 121 | ALOGD("%s: set powersave", __func__); 122 | } 123 | 124 | current_power_profile = profile; 125 | } 126 | 127 | int power_hint_override(__attribute__((unused)) struct power_module *module, 128 | power_hint_t hint, void *data) 129 | { 130 | if (hint == POWER_HINT_SET_PROFILE) { 131 | set_power_profile(*(int32_t *)data); 132 | return HINT_HANDLED; 133 | } 134 | 135 | /* Skip other hints in power save mode */ 136 | if (current_power_profile == PROFILE_POWER_SAVE) { 137 | return HINT_HANDLED; 138 | } 139 | 140 | return HINT_NONE; 141 | } 142 | -------------------------------------------------------------------------------- /power/power-8974.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * Copyright (c) 2014, The CyanogenMod Project 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following 12 | * disclaimer in the documentation and/or other materials provided 13 | * with the distribution. 14 | * * Neither the name of The Linux Foundation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 28 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #define LOG_NIDEBUG 0 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define LOG_TAG "QCOM PowerHAL" 41 | #include 42 | #include 43 | #include 44 | 45 | #include "utils.h" 46 | #include "metadata-defs.h" 47 | #include "hint-data.h" 48 | #include "performance.h" 49 | #include "power-common.h" 50 | 51 | static int first_display_off_hint; 52 | 53 | static int current_power_profile = PROFILE_BALANCED; 54 | 55 | int get_number_of_profiles() { 56 | return 5; 57 | } 58 | 59 | /** 60 | * If target is 8974pro: 61 | * return 1 62 | * else: 63 | * return 0 64 | */ 65 | static int is_target_8974pro(void) 66 | { 67 | static int is_8974pro = -1; 68 | int soc_id; 69 | 70 | if (is_8974pro >= 0) 71 | return is_8974pro; 72 | 73 | soc_id = get_soc_id(); 74 | if (soc_id == 194 || (soc_id >= 208 && soc_id <= 218)) 75 | is_8974pro = 1; 76 | else 77 | is_8974pro = 0; 78 | 79 | return is_8974pro; 80 | } 81 | 82 | static void set_power_profile(int profile) { 83 | 84 | if (profile == current_power_profile) 85 | return; 86 | 87 | ALOGV("%s: profile=%d", __func__, profile); 88 | 89 | if (current_power_profile != PROFILE_BALANCED) { 90 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 91 | ALOGV("%s: hint undone", __func__); 92 | } 93 | 94 | if (profile == PROFILE_HIGH_PERFORMANCE) { 95 | int resource_values[] = { CPUS_ONLINE_MIN_4, 0x0901, 96 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, 97 | CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX }; 98 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 99 | resource_values, ARRAY_SIZE(resource_values)); 100 | ALOGD("%s: set performance mode", __func__); 101 | } else if (profile == PROFILE_BIAS_PERFORMANCE) { 102 | int resource_values[] = { 103 | CPU0_MIN_FREQ_NONTURBO_MAX + 1, CPU1_MIN_FREQ_NONTURBO_MAX + 1, 104 | CPU2_MIN_FREQ_NONTURBO_MAX + 1, CPU2_MIN_FREQ_NONTURBO_MAX + 1 }; 105 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 106 | resource_values, ARRAY_SIZE(resource_values)); 107 | ALOGD("%s: set bias perf mode", __func__); 108 | } else if (profile == PROFILE_BIAS_POWER) { 109 | int resource_values[] = { 0x0A03, 110 | CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, 111 | CPU1_MAX_FREQ_NONTURBO_MAX, CPU2_MAX_FREQ_NONTURBO_MAX }; 112 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 113 | resource_values, ARRAY_SIZE(resource_values)); 114 | ALOGD("%s: set bias power mode", __func__); 115 | } else if (profile == PROFILE_POWER_SAVE) { 116 | int resource_values[] = { 0x0A03, CPUS_ONLINE_MAX_LIMIT_2, 117 | CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, 118 | CPU2_MAX_FREQ_NONTURBO_MAX, CPU3_MAX_FREQ_NONTURBO_MAX }; 119 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 120 | resource_values, ARRAY_SIZE(resource_values)); 121 | ALOGD("%s: set powersave", __func__); 122 | } 123 | 124 | current_power_profile = profile; 125 | } 126 | 127 | extern void interaction(int duration, int num_args, int opt_list[]); 128 | 129 | int power_hint_override(__attribute__((unused)) struct power_module *module, 130 | power_hint_t hint, void *data) 131 | { 132 | if (hint == POWER_HINT_SET_PROFILE) { 133 | set_power_profile(*(int32_t *)data); 134 | return HINT_HANDLED; 135 | } 136 | 137 | // Skip other hints in high/low power modes 138 | if (current_power_profile == PROFILE_POWER_SAVE || 139 | current_power_profile == PROFILE_HIGH_PERFORMANCE) { 140 | return HINT_HANDLED; 141 | } 142 | 143 | if (hint == POWER_HINT_LAUNCH_BOOST) { 144 | int duration = 2000; 145 | int resources[] = { CPUS_ONLINE_MIN_3, 146 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, 147 | CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX }; 148 | 149 | interaction(duration, ARRAY_SIZE(resources), resources); 150 | 151 | return HINT_HANDLED; 152 | } 153 | 154 | if (hint == POWER_HINT_CPU_BOOST) { 155 | int duration = *(int32_t *)data / 1000; 156 | int resources[] = { CPUS_ONLINE_MIN_2, 157 | 0x20F, 0x30F, 0x40F, 0x50F }; 158 | 159 | if (duration) 160 | interaction(duration, ARRAY_SIZE(resources), resources); 161 | 162 | return HINT_HANDLED; 163 | } 164 | 165 | if (hint == POWER_HINT_INTERACTION) { 166 | int duration = 500, duration_hint = 0; 167 | static struct timespec s_previous_boost_timespec; 168 | struct timespec cur_boost_timespec; 169 | long long elapsed_time; 170 | 171 | if (data) { 172 | duration_hint = *((int *)data); 173 | } 174 | 175 | duration = duration_hint > 0 ? duration_hint : 500; 176 | 177 | clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); 178 | elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); 179 | if (elapsed_time > 750000) 180 | elapsed_time = 750000; 181 | // don't hint if it's been less than 250ms since last boost 182 | // also detect if we're doing anything resembling a fling 183 | // support additional boosting in case of flings 184 | else if (elapsed_time < 250000 && duration <= 750) 185 | return HINT_HANDLED; 186 | 187 | s_previous_boost_timespec = cur_boost_timespec; 188 | 189 | int resources[] = { (duration >= 2000 ? CPUS_ONLINE_MIN_3 : CPUS_ONLINE_MIN_2), 190 | 0x20F, 0x30F, 0x40F, 0x50F }; 191 | 192 | if (duration) 193 | interaction(duration, ARRAY_SIZE(resources), resources); 194 | 195 | return HINT_HANDLED; 196 | } 197 | 198 | 199 | return HINT_NONE; 200 | } 201 | 202 | int set_interactive_override(struct power_module *module __unused, int on) 203 | { 204 | char governor[80]; 205 | 206 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 207 | ALOGE("Can't obtain scaling governor."); 208 | 209 | return HINT_NONE; 210 | } 211 | 212 | if (!on) { 213 | /* Display off. */ 214 | /* 215 | * We need to be able to identify the first display off hint 216 | * and release the current lock holder 217 | */ 218 | if (is_target_8974pro()) { 219 | if (!first_display_off_hint) { 220 | undo_initial_hint_action(); 221 | first_display_off_hint = 1; 222 | } 223 | /* used for all subsequent toggles to the display */ 224 | undo_hint_action(DISPLAY_STATE_HINT_ID_2); 225 | } 226 | 227 | if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && 228 | (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { 229 | int resource_values[] = {MS_500, SYNC_FREQ_600, OPTIMAL_FREQ_600, THREAD_MIGRATION_SYNC_OFF}; 230 | 231 | perform_hint_action(DISPLAY_STATE_HINT_ID, 232 | resource_values, ARRAY_SIZE(resource_values)); 233 | 234 | return HINT_HANDLED; 235 | } 236 | } else { 237 | /* Display on */ 238 | if (is_target_8974pro()) { 239 | int resource_values2[] = {CPUS_ONLINE_MIN_2}; 240 | perform_hint_action(DISPLAY_STATE_HINT_ID_2, 241 | resource_values2, ARRAY_SIZE(resource_values2)); 242 | } 243 | 244 | if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && 245 | (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { 246 | undo_hint_action(DISPLAY_STATE_HINT_ID); 247 | 248 | return HINT_HANDLED; 249 | } 250 | } 251 | 252 | return HINT_NONE; 253 | } 254 | -------------------------------------------------------------------------------- /power/power-8992.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #define LOG_NIDEBUG 0 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define LOG_TAG "QCOM PowerHAL" 40 | #include 41 | #include 42 | #include 43 | 44 | #include "utils.h" 45 | #include "metadata-defs.h" 46 | #include "hint-data.h" 47 | #include "performance.h" 48 | #include "power-common.h" 49 | 50 | int get_number_of_profiles() { 51 | return 5; 52 | } 53 | 54 | static int current_power_profile = PROFILE_BALANCED; 55 | 56 | static void set_power_profile(int profile) { 57 | 58 | if (profile == current_power_profile) 59 | return; 60 | 61 | ALOGV("%s: profile=%d", __func__, profile); 62 | 63 | if (current_power_profile != PROFILE_BALANCED) { 64 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 65 | ALOGV("%s: hint undone", __func__); 66 | } 67 | 68 | if (profile == PROFILE_POWER_SAVE) { 69 | int resource_values[] = { CPUS_ONLINE_MPD_OVERRIDE, 0x0A03, 70 | CPU0_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, 71 | CPU2_MAX_FREQ_NONTURBO_MAX - 2, CPU3_MAX_FREQ_NONTURBO_MAX - 2, 72 | CPU4_MAX_FREQ_NONTURBO_MAX - 2, CPU5_MAX_FREQ_NONTURBO_MAX - 2 }; 73 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 74 | resource_values, ARRAY_SIZE(resource_values)); 75 | ALOGD("%s: set powersave", __func__); 76 | } else if (profile == PROFILE_HIGH_PERFORMANCE) { 77 | int resource_values[] = { SCHED_BOOST_ON, CPUS_ONLINE_MAX, 78 | ALL_CPUS_PWR_CLPS_DIS, 0x0901, 79 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, 80 | CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX, 81 | CPU4_MIN_FREQ_TURBO_MAX, CPU5_MIN_FREQ_TURBO_MAX }; 82 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 83 | resource_values, ARRAY_SIZE(resource_values)); 84 | ALOGD("%s: set performance mode", __func__); 85 | } else if (profile == PROFILE_BIAS_POWER) { 86 | int resource_values[] = { 0x0A03, 0x0902, 87 | CPU0_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, 88 | CPU1_MAX_FREQ_NONTURBO_MAX - 2, CPU2_MAX_FREQ_NONTURBO_MAX - 2, 89 | CPU4_MAX_FREQ_NONTURBO_MAX, CPU5_MAX_FREQ_NONTURBO_MAX }; 90 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 91 | resource_values, ARRAY_SIZE(resource_values)); 92 | ALOGD("%s: set bias power mode", __func__); 93 | } else if (profile == PROFILE_BIAS_PERFORMANCE) { 94 | int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_MAX, 95 | CPU4_MIN_FREQ_NONTURBO_MAX + 1, CPU5_MIN_FREQ_NONTURBO_MAX + 1 }; 96 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 97 | resource_values, ARRAY_SIZE(resource_values)); 98 | ALOGD("%s: set bias perf mode", __func__); 99 | } 100 | 101 | current_power_profile = profile; 102 | } 103 | 104 | extern void interaction(int duration, int num_args, int opt_list[]); 105 | 106 | static int process_video_encode_hint(void *metadata) 107 | { 108 | char governor[80]; 109 | struct video_encode_metadata_t video_encode_metadata; 110 | 111 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 112 | ALOGE("Can't obtain scaling governor."); 113 | 114 | return HINT_NONE; 115 | } 116 | 117 | /* Initialize encode metadata struct fields */ 118 | memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); 119 | video_encode_metadata.state = -1; 120 | video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; 121 | 122 | if (metadata) { 123 | if (parse_video_encode_metadata((char *)metadata, &video_encode_metadata) == 124 | -1) { 125 | ALOGE("Error occurred while parsing metadata."); 126 | return HINT_NONE; 127 | } 128 | } else { 129 | return HINT_NONE; 130 | } 131 | 132 | if (video_encode_metadata.state == 1) { 133 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 134 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 135 | /* sched and cpufreq params 136 | * hispeed freq - 768 MHz 137 | * target load - 90 138 | * above_hispeed_delay - 40ms 139 | * sched_small_tsk - 50 140 | */ 141 | int resource_values[] = {0x2C07, 0x2F5A, 0x2704, 0x4032}; 142 | 143 | perform_hint_action(video_encode_metadata.hint_id, 144 | resource_values, ARRAY_SIZE(resource_values)); 145 | return HINT_HANDLED; 146 | } 147 | } else if (video_encode_metadata.state == 0) { 148 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 149 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 150 | undo_hint_action(video_encode_metadata.hint_id); 151 | return HINT_HANDLED; 152 | } 153 | } 154 | return HINT_NONE; 155 | } 156 | 157 | int power_hint_override(__attribute__((unused)) struct power_module *module, 158 | power_hint_t hint, void *data) 159 | { 160 | if (hint == POWER_HINT_SET_PROFILE) { 161 | set_power_profile(*(int32_t *)data); 162 | return HINT_HANDLED; 163 | } 164 | 165 | // Skip other hints in custom power modes 166 | if (current_power_profile == PROFILE_POWER_SAVE) { 167 | return HINT_HANDLED; 168 | } 169 | 170 | if (hint == POWER_HINT_INTERACTION) { 171 | int duration = 500, duration_hint = 0; 172 | static struct timespec s_previous_boost_timespec; 173 | struct timespec cur_boost_timespec; 174 | long long elapsed_time; 175 | 176 | if (data) { 177 | duration_hint = *((int *)data); 178 | } 179 | 180 | duration = duration_hint > 0 ? duration_hint : 500; 181 | 182 | clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); 183 | elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); 184 | if (elapsed_time > 750000) 185 | elapsed_time = 750000; 186 | // don't hint if it's been less than 250ms since last boost 187 | // also detect if we're doing anything resembling a fling 188 | // support additional boosting in case of flings 189 | else if (elapsed_time < 250000 && duration <= 750) 190 | return HINT_HANDLED; 191 | 192 | s_previous_boost_timespec = cur_boost_timespec; 193 | 194 | if (duration >= 1500) { 195 | int resources[] = { 196 | ALL_CPUS_PWR_CLPS_DIS, 197 | SCHED_BOOST_ON, 198 | SCHED_PREFER_IDLE_DIS 199 | }; 200 | interaction(duration, ARRAY_SIZE(resources), resources); 201 | } else { 202 | int resources[] = { 203 | ALL_CPUS_PWR_CLPS_DIS, 204 | SCHED_PREFER_IDLE_DIS 205 | }; 206 | interaction(duration, ARRAY_SIZE(resources), resources); 207 | } 208 | return HINT_HANDLED; 209 | } 210 | 211 | if (hint == POWER_HINT_LAUNCH_BOOST) { 212 | launch_boost_info_t *info = (launch_boost_info_t *)data; 213 | if (info == NULL) { 214 | ALOGE("Invalid argument for launch boost"); 215 | return HINT_HANDLED; 216 | } 217 | 218 | ALOGV("LAUNCH_BOOST: %s (pid=%d)", info->packageName, info->pid); 219 | 220 | int duration = 2000; 221 | int resources[] = { SCHED_BOOST_ON, 0x20C }; 222 | 223 | start_prefetch(info->pid, info->packageName); 224 | interaction(duration, ARRAY_SIZE(resources), resources); 225 | 226 | return HINT_HANDLED; 227 | } 228 | 229 | if (hint == POWER_HINT_CPU_BOOST) { 230 | int duration = *(int32_t *)data / 1000; 231 | int resources[] = { SCHED_BOOST_ON }; 232 | 233 | if (duration > 0) 234 | interaction(duration, ARRAY_SIZE(resources), resources); 235 | 236 | return HINT_HANDLED; 237 | } 238 | 239 | if (hint == POWER_HINT_VIDEO_ENCODE) { 240 | return process_video_encode_hint(data); 241 | } 242 | 243 | return HINT_NONE; 244 | } 245 | 246 | int set_interactive_override(__attribute__((unused)) struct power_module *module, int on) 247 | { 248 | char governor[80]; 249 | 250 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 251 | ALOGE("Can't obtain scaling governor."); 252 | 253 | return HINT_NONE; 254 | } 255 | 256 | if (!on) { 257 | /* Display off */ 258 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 259 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 260 | // sched upmigrate = 99, sched downmigrate = 95 261 | // keep the big cores around, but make them very hard to use 262 | int resource_values[] = { 0x4E63, 0x4F5F }; 263 | perform_hint_action(DISPLAY_STATE_HINT_ID, 264 | resource_values, ARRAY_SIZE(resource_values)); 265 | return HINT_HANDLED; 266 | } 267 | } else { 268 | /* Display on */ 269 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 270 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 271 | undo_hint_action(DISPLAY_STATE_HINT_ID); 272 | return HINT_HANDLED; 273 | } 274 | } 275 | return HINT_NONE; 276 | } 277 | -------------------------------------------------------------------------------- /power/power-8994.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #define LOG_NIDEBUG 0 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define LOG_TAG "QCOM PowerHAL" 40 | #include 41 | #include 42 | #include 43 | 44 | #include "utils.h" 45 | #include "metadata-defs.h" 46 | #include "hint-data.h" 47 | #include "performance.h" 48 | #include "power-common.h" 49 | 50 | int get_number_of_profiles() { 51 | return 5; 52 | } 53 | 54 | static int current_power_profile = PROFILE_BALANCED; 55 | 56 | static void set_power_profile(int profile) { 57 | 58 | if (profile == current_power_profile) 59 | return; 60 | 61 | ALOGV("%s: profile=%d", __func__, profile); 62 | 63 | if (current_power_profile != PROFILE_BALANCED) { 64 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 65 | ALOGV("%s: hint undone", __func__); 66 | } 67 | 68 | if (profile == PROFILE_POWER_SAVE) { 69 | int resource_values[] = { CPUS_ONLINE_MPD_OVERRIDE, 0x0A03, 70 | CPU0_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, 71 | CPU2_MAX_FREQ_NONTURBO_MAX - 2, CPU3_MAX_FREQ_NONTURBO_MAX - 2, 72 | CPU4_MAX_FREQ_NONTURBO_MAX - 2, CPU5_MAX_FREQ_NONTURBO_MAX - 2, 73 | CPU6_MAX_FREQ_NONTURBO_MAX - 2, CPU7_MAX_FREQ_NONTURBO_MAX - 2 }; 74 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 75 | resource_values, ARRAY_SIZE(resource_values)); 76 | ALOGD("%s: set powersave", __func__); 77 | } else if (profile == PROFILE_HIGH_PERFORMANCE) { 78 | int resource_values[] = { SCHED_BOOST_ON, CPUS_ONLINE_MAX, 79 | ALL_CPUS_PWR_CLPS_DIS, 0x0901, 80 | CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, 81 | CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX, 82 | CPU4_MIN_FREQ_TURBO_MAX, CPU5_MIN_FREQ_TURBO_MAX, 83 | CPU6_MIN_FREQ_TURBO_MAX, CPU7_MIN_FREQ_TURBO_MAX }; 84 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 85 | resource_values, ARRAY_SIZE(resource_values)); 86 | ALOGD("%s: set performance mode", __func__); 87 | } else if (profile == PROFILE_BIAS_POWER) { 88 | int resource_values[] = { 0x0A03, 0x0902, 89 | CPU0_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, 90 | CPU1_MAX_FREQ_NONTURBO_MAX - 2, CPU2_MAX_FREQ_NONTURBO_MAX - 2, 91 | CPU4_MAX_FREQ_NONTURBO_MAX, CPU5_MAX_FREQ_NONTURBO_MAX, 92 | CPU6_MAX_FREQ_NONTURBO_MAX, CPU7_MAX_FREQ_NONTURBO_MAX }; 93 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 94 | resource_values, ARRAY_SIZE(resource_values)); 95 | ALOGD("%s: set bias power mode", __func__); 96 | } else if (profile == PROFILE_BIAS_PERFORMANCE) { 97 | int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_MAX, 98 | CPU4_MIN_FREQ_NONTURBO_MAX + 1, CPU5_MIN_FREQ_NONTURBO_MAX + 1, 99 | CPU6_MIN_FREQ_NONTURBO_MAX + 1, CPU7_MIN_FREQ_NONTURBO_MAX + 1 }; 100 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, 101 | resource_values, ARRAY_SIZE(resource_values)); 102 | ALOGD("%s: set bias perf mode", __func__); 103 | } 104 | 105 | current_power_profile = profile; 106 | } 107 | 108 | extern void interaction(int duration, int num_args, int opt_list[]); 109 | 110 | #ifdef __LP64__ 111 | typedef int64_t hintdata; 112 | #else 113 | typedef int hintdata; 114 | #endif 115 | 116 | static int process_video_encode_hint(void *metadata) 117 | { 118 | char governor[80]; 119 | struct video_encode_metadata_t video_encode_metadata; 120 | 121 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 122 | ALOGE("Can't obtain scaling governor."); 123 | 124 | return HINT_NONE; 125 | } 126 | 127 | /* Initialize encode metadata struct fields */ 128 | memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); 129 | video_encode_metadata.state = -1; 130 | video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; 131 | 132 | if (metadata) { 133 | if (parse_video_encode_metadata((char *)metadata, &video_encode_metadata) == 134 | -1) { 135 | ALOGE("Error occurred while parsing metadata."); 136 | return HINT_NONE; 137 | } 138 | } else { 139 | return HINT_NONE; 140 | } 141 | 142 | if (video_encode_metadata.state == 1) { 143 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 144 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 145 | /* sched and cpufreq params 146 | * hispeed freq - 768 MHz 147 | * target load - 90 148 | * above_hispeed_delay - 40ms 149 | * sched_small_tsk - 50 150 | */ 151 | int resource_values[] = {0x2C07, 0x2F5A, 0x2704, 0x4032}; 152 | 153 | perform_hint_action(video_encode_metadata.hint_id, 154 | resource_values, ARRAY_SIZE(resource_values)); 155 | return HINT_HANDLED; 156 | } 157 | } else if (video_encode_metadata.state == 0) { 158 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 159 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 160 | undo_hint_action(video_encode_metadata.hint_id); 161 | return HINT_HANDLED; 162 | } 163 | } 164 | return HINT_NONE; 165 | } 166 | 167 | int power_hint_override(__attribute__((unused)) struct power_module *module, 168 | power_hint_t hint, void *data) 169 | { 170 | if (hint == POWER_HINT_SET_PROFILE) { 171 | set_power_profile(*(int32_t *)data); 172 | return HINT_HANDLED; 173 | } 174 | 175 | // Skip other hints in custom power modes 176 | if (current_power_profile == PROFILE_POWER_SAVE) { 177 | return HINT_HANDLED; 178 | } 179 | 180 | if (hint == POWER_HINT_INTERACTION) { 181 | int duration = 500, duration_hint = 0; 182 | static struct timespec s_previous_boost_timespec; 183 | struct timespec cur_boost_timespec; 184 | long long elapsed_time; 185 | 186 | if (data) { 187 | duration_hint = *((int *)data); 188 | } 189 | 190 | duration = duration_hint > 0 ? duration_hint : 500; 191 | 192 | clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); 193 | elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); 194 | if (elapsed_time > 750000) 195 | elapsed_time = 750000; 196 | // don't hint if it's been less than 250ms since last boost 197 | // also detect if we're doing anything resembling a fling 198 | // support additional boosting in case of flings 199 | else if (elapsed_time < 250000 && duration <= 750) 200 | return HINT_HANDLED; 201 | 202 | s_previous_boost_timespec = cur_boost_timespec; 203 | 204 | if (duration >= 1500) { 205 | int resources[] = { 206 | ALL_CPUS_PWR_CLPS_DIS, 207 | SCHED_BOOST_ON, 208 | SCHED_PREFER_IDLE_DIS 209 | }; 210 | interaction(duration, ARRAY_SIZE(resources), resources); 211 | } else { 212 | int resources[] = { 213 | ALL_CPUS_PWR_CLPS_DIS, 214 | SCHED_PREFER_IDLE_DIS 215 | }; 216 | interaction(duration, ARRAY_SIZE(resources), resources); 217 | } 218 | return HINT_HANDLED; 219 | } 220 | 221 | if (hint == POWER_HINT_LAUNCH_BOOST) { 222 | launch_boost_info_t *info = (launch_boost_info_t *)data; 223 | if (info == NULL) { 224 | ALOGE("Invalid argument for launch boost"); 225 | return HINT_HANDLED; 226 | } 227 | 228 | ALOGV("LAUNCH_BOOST: %s (pid=%d)", info->packageName, info->pid); 229 | 230 | int duration = 2000; 231 | int resources[] = { SCHED_BOOST_ON, 0x20C }; 232 | 233 | start_prefetch(info->pid, info->packageName); 234 | interaction(duration, ARRAY_SIZE(resources), resources); 235 | 236 | return HINT_HANDLED; 237 | } 238 | 239 | if (hint == POWER_HINT_CPU_BOOST) { 240 | int duration = *(int32_t *)data / 1000; 241 | int resources[] = { SCHED_BOOST_ON }; 242 | 243 | if (duration > 0) 244 | interaction(duration, ARRAY_SIZE(resources), resources); 245 | 246 | return HINT_HANDLED; 247 | } 248 | 249 | if (hint == POWER_HINT_VIDEO_ENCODE) { 250 | return process_video_encode_hint(data); 251 | } 252 | 253 | return HINT_NONE; 254 | } 255 | 256 | int set_interactive_override(__attribute__((unused)) struct power_module *module, int on) 257 | { 258 | char governor[80]; 259 | 260 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 261 | ALOGE("Can't obtain scaling governor."); 262 | 263 | return HINT_NONE; 264 | } 265 | 266 | if (!on) { 267 | /* Display off */ 268 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 269 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 270 | // sched upmigrate = 99, sched downmigrate = 95 271 | // keep the big cores around, but make them very hard to use 272 | int resource_values[] = { 0x4E63, 0x4F5F }; 273 | perform_hint_action(DISPLAY_STATE_HINT_ID, 274 | resource_values, ARRAY_SIZE(resource_values)); 275 | return HINT_HANDLED; 276 | } 277 | } else { 278 | /* Display on */ 279 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 280 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 281 | undo_hint_action(DISPLAY_STATE_HINT_ID); 282 | return HINT_HANDLED; 283 | } 284 | } 285 | return HINT_NONE; 286 | } 287 | -------------------------------------------------------------------------------- /power/power-8996.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #define LOG_NIDEBUG 0 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define LOG_TAG "QCOM PowerHAL" 40 | #include 41 | #include 42 | #include 43 | 44 | #include "utils.h" 45 | #include "metadata-defs.h" 46 | #include "hint-data.h" 47 | #include "performance.h" 48 | #include "power-common.h" 49 | 50 | static int current_power_profile = PROFILE_BALANCED; 51 | 52 | extern void interaction(int duration, int num_args, int opt_list[]); 53 | 54 | int get_number_of_profiles() { 55 | return 5; 56 | } 57 | 58 | static int profile_high_performance[] = { 59 | SCHED_BOOST_ON_V3, 0x1, 60 | ALL_CPUS_PWR_CLPS_DIS_V3, 0x1, 61 | CPUS_ONLINE_MIN_BIG, 0x2, 62 | CPUS_ONLINE_MIN_LITTLE, 0x2, 63 | MIN_FREQ_BIG_CORE_0, 0xFFF, 64 | MIN_FREQ_LITTLE_CORE_0, 0xFFF, 65 | }; 66 | 67 | static int profile_power_save[] = { 68 | CPUS_ONLINE_MAX_LIMIT_BIG, 0x1, 69 | MAX_FREQ_BIG_CORE_0, 0x3E8, 70 | MAX_FREQ_LITTLE_CORE_0, 0x3E8, 71 | }; 72 | 73 | static int profile_bias_power[] = { 74 | MAX_FREQ_BIG_CORE_0, 0x514, 75 | MAX_FREQ_LITTLE_CORE_0, 0x3E8, 76 | }; 77 | 78 | static int profile_bias_performance[] = { 79 | CPUS_ONLINE_MAX_LIMIT_BIG, 0x2, 80 | CPUS_ONLINE_MAX_LIMIT_LITTLE, 0x2, 81 | MIN_FREQ_BIG_CORE_0, 0x578, 82 | }; 83 | 84 | static void set_power_profile(int profile) { 85 | 86 | if (profile == current_power_profile) 87 | return; 88 | 89 | ALOGV("%s: Profile=%d", __func__, profile); 90 | 91 | if (current_power_profile != PROFILE_BALANCED) { 92 | undo_hint_action(DEFAULT_PROFILE_HINT_ID); 93 | ALOGV("%s: Hint undone", __func__); 94 | } 95 | 96 | if (profile == PROFILE_POWER_SAVE) { 97 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_power_save, 98 | ARRAY_SIZE(profile_power_save)); 99 | ALOGD("%s: Set powersave mode", __func__); 100 | 101 | } else if (profile == PROFILE_HIGH_PERFORMANCE) { 102 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_high_performance, 103 | ARRAY_SIZE(profile_high_performance)); 104 | ALOGD("%s: Set performance mode", __func__); 105 | 106 | } else if (profile == PROFILE_BIAS_POWER) { 107 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_bias_power, 108 | ARRAY_SIZE(profile_bias_power)); 109 | ALOGD("%s: Set bias power mode", __func__); 110 | 111 | } else if (profile == PROFILE_BIAS_PERFORMANCE) { 112 | perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_bias_performance, 113 | ARRAY_SIZE(profile_bias_performance)); 114 | ALOGD("%s: Set bias perf mode", __func__); 115 | 116 | } 117 | 118 | current_power_profile = profile; 119 | } 120 | 121 | static int process_video_encode_hint(void *metadata) 122 | { 123 | char governor[80]; 124 | struct video_encode_metadata_t video_encode_metadata; 125 | 126 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 127 | ALOGE("Can't obtain scaling governor."); 128 | 129 | return HINT_NONE; 130 | } 131 | 132 | /* Initialize encode metadata struct fields */ 133 | memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); 134 | video_encode_metadata.state = -1; 135 | video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; 136 | 137 | if (metadata) { 138 | if (parse_video_encode_metadata((char *)metadata, &video_encode_metadata) == 139 | -1) { 140 | ALOGE("Error occurred while parsing metadata."); 141 | return HINT_NONE; 142 | } 143 | } else { 144 | return HINT_NONE; 145 | } 146 | 147 | if (video_encode_metadata.state == 1) { 148 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 149 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 150 | /* 1. cpufreq params 151 | * -above_hispeed_delay for LVT - 40ms 152 | * -go hispeed load for LVT - 95 153 | * -hispeed freq for LVT - 556 MHz 154 | * -target load for LVT - 90 155 | * -above hispeed delay for sLVT - 40ms 156 | * -go hispeed load for sLVT - 95 157 | * -hispeed freq for sLVT - 806 MHz 158 | * -target load for sLVT - 90 159 | * 2. bus DCVS set to V2 config: 160 | * -low power ceil mpbs - 2500 161 | * -low power io percent - 50 162 | * 3. hysteresis optimization 163 | * -bus dcvs hysteresis tuning 164 | * -sample_ms of 10 ms 165 | */ 166 | int resource_values[] = { 167 | ABOVE_HISPEED_DELAY_BIG, 0x4, 168 | GO_HISPEED_LOAD_BIG, 0x5F, 169 | HISPEED_FREQ_BIG, 0x326, 170 | TARGET_LOADS_BIG, 0x5A, 171 | ABOVE_HISPEED_DELAY_LITTLE, 0x4, 172 | GO_HISPEED_LOAD_LITTLE, 0x5F, 173 | HISPEED_FREQ_LITTLE, 0x22C, 174 | TARGET_LOADS_LITTLE, 0x5A, 175 | LOW_POWER_CEIL_MBPS, 0x9C4, 176 | LOW_POWER_IO_PERCENT, 0x32, 177 | CPUBW_HWMON_V1, 0x0, 178 | CPUBW_HWMON_SAMPLE_MS, 0xA, 179 | }; 180 | 181 | perform_hint_action(video_encode_metadata.hint_id, 182 | resource_values, ARRAY_SIZE(resource_values)); 183 | ALOGI("Video Encode hint start"); 184 | return HINT_HANDLED; 185 | } 186 | } else if (video_encode_metadata.state == 0) { 187 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 188 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 189 | undo_hint_action(video_encode_metadata.hint_id); 190 | ALOGI("Video Encode hint stop"); 191 | return HINT_HANDLED; 192 | } 193 | } 194 | return HINT_NONE; 195 | } 196 | 197 | int power_hint_override(__unused struct power_module *module, 198 | power_hint_t hint, void *data) 199 | { 200 | static struct timespec s_previous_boost_timespec; 201 | struct timespec cur_boost_timespec; 202 | long long elapsed_time; 203 | int duration; 204 | 205 | int resources_launch_boost[] = { 206 | SCHED_BOOST_ON_V3, 0x1, 207 | MAX_FREQ_BIG_CORE_0, 0xFFF, 208 | MAX_FREQ_LITTLE_CORE_0, 0xFFF, 209 | MIN_FREQ_BIG_CORE_0, 0xFFF, 210 | MIN_FREQ_LITTLE_CORE_0, 0xFFF, 211 | CPUBW_HWMON_MIN_FREQ, 0x8C, 212 | ALL_CPUS_PWR_CLPS_DIS_V3, 0x1, 213 | STOR_CLK_SCALE_DIS, 0x1, 214 | }; 215 | 216 | int resources_cpu_boost[] = { 217 | SCHED_BOOST_ON_V3, 0x1, 218 | MIN_FREQ_BIG_CORE_0, 0x3E8, 219 | }; 220 | 221 | int resources_interaction_fling_boost[] = { 222 | CPUBW_HWMON_MIN_FREQ, 0x33, 223 | MIN_FREQ_BIG_CORE_0, 0x3E8, 224 | MIN_FREQ_LITTLE_CORE_0, 0x3E8, 225 | SCHED_BOOST_ON_V3, 0x1, 226 | // SCHED_GROUP_ON, 0x1, 227 | }; 228 | 229 | int resources_interaction_boost[] = { 230 | MIN_FREQ_BIG_CORE_0, 0x3E8, 231 | }; 232 | 233 | if (hint == POWER_HINT_SET_PROFILE) { 234 | set_power_profile(*(int32_t *)data); 235 | return HINT_HANDLED; 236 | } 237 | 238 | /* Skip other hints in power save mode */ 239 | if (current_power_profile == PROFILE_POWER_SAVE) 240 | return HINT_HANDLED; 241 | 242 | if (hint == POWER_HINT_INTERACTION) { 243 | duration = data ? *((int *)data) : 500; 244 | 245 | clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); 246 | elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); 247 | if (elapsed_time > 750000) 248 | elapsed_time = 750000; 249 | /** 250 | * Don't hint if it's been less than 250ms since last boost 251 | * also detect if we're doing anything resembling a fling 252 | * support additional boosting in case of flings 253 | */ 254 | else if (elapsed_time < 250000 && duration <= 750) 255 | return HINT_HANDLED; 256 | 257 | s_previous_boost_timespec = cur_boost_timespec; 258 | 259 | if (duration >= 1500) { 260 | interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost), 261 | resources_interaction_fling_boost); 262 | } else { 263 | interaction(duration, ARRAY_SIZE(resources_interaction_boost), 264 | resources_interaction_boost); 265 | } 266 | return HINT_HANDLED; 267 | } 268 | 269 | if (hint == POWER_HINT_LAUNCH_BOOST) { 270 | launch_boost_info_t *info = (launch_boost_info_t *)data; 271 | if (info == NULL) { 272 | ALOGE("Invalid argument for launch boost"); 273 | return HINT_HANDLED; 274 | } 275 | 276 | duration = 2000; 277 | 278 | ALOGV("LAUNCH_BOOST: %s (pid=%d)", info->packageName, info->pid); 279 | 280 | start_prefetch(info->pid, info->packageName); 281 | interaction(duration, ARRAY_SIZE(resources_launch_boost), 282 | resources_launch_boost); 283 | return HINT_HANDLED; 284 | } 285 | 286 | if (hint == POWER_HINT_CPU_BOOST) { 287 | duration = *(int32_t *)data / 1000; 288 | if (duration > 0) { 289 | interaction(duration, ARRAY_SIZE(resources_cpu_boost), 290 | resources_cpu_boost); 291 | return HINT_HANDLED; 292 | } 293 | } 294 | 295 | if (hint == POWER_HINT_VIDEO_ENCODE) 296 | return process_video_encode_hint(data); 297 | 298 | return HINT_NONE; 299 | } 300 | 301 | int set_interactive_override(__unused struct power_module *module, int on) 302 | { 303 | return HINT_HANDLED; /* Don't excecute this code path, not in use */ 304 | char governor[80]; 305 | 306 | if (get_scaling_governor(governor, sizeof(governor)) == -1) { 307 | ALOGE("Can't obtain scaling governor."); 308 | 309 | return HINT_NONE; 310 | } 311 | 312 | if (!on) { 313 | /* Display off */ 314 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 315 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 316 | int resource_values[] = {}; /* dummy node */ 317 | perform_hint_action(DISPLAY_STATE_HINT_ID, 318 | resource_values, ARRAY_SIZE(resource_values)); 319 | ALOGI("Display Off hint start"); 320 | return HINT_HANDLED; 321 | } 322 | } else { 323 | /* Display on */ 324 | if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && 325 | (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { 326 | undo_hint_action(DISPLAY_STATE_HINT_ID); 327 | ALOGI("Display Off hint stop"); 328 | return HINT_HANDLED; 329 | } 330 | } 331 | return HINT_NONE; 332 | } 333 | -------------------------------------------------------------------------------- /power/power-common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #define NODE_MAX (64) 30 | 31 | #define SCALING_GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" 32 | #define DCVS_CPU0_SLACK_MAX_NODE "/sys/module/msm_dcvs/cores/cpu0/slack_time_max_us" 33 | #define DCVS_CPU0_SLACK_MIN_NODE "/sys/module/msm_dcvs/cores/cpu0/slack_time_min_us" 34 | #define MPDECISION_SLACK_MAX_NODE "/sys/module/msm_mpdecision/slack_time_max_us" 35 | #define MPDECISION_SLACK_MIN_NODE "/sys/module/msm_mpdecision/slack_time_min_us" 36 | #define SCALING_MIN_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq" 37 | 38 | #define ONDEMAND_GOVERNOR "ondemand" 39 | #define INTERACTIVE_GOVERNOR "interactive" 40 | #define MSMDCVS_GOVERNOR "msm-dcvs" 41 | 42 | #define HINT_HANDLED (0) 43 | #define HINT_NONE (-1) 44 | 45 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) 46 | 47 | enum CPU_GOV_CHECK { 48 | CPU0 = 0, 49 | CPU1 = 1, 50 | CPU2 = 2, 51 | CPU3 = 3 52 | }; 53 | 54 | enum { 55 | PROFILE_POWER_SAVE = 0, 56 | PROFILE_BALANCED, 57 | PROFILE_HIGH_PERFORMANCE, 58 | PROFILE_BIAS_POWER, 59 | PROFILE_BIAS_PERFORMANCE 60 | }; 61 | -------------------------------------------------------------------------------- /power/power-feature-default.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "power-feature.h" 19 | 20 | void set_device_specific_feature(struct power_module *module __unused, 21 | feature_t feature __unused, int state __unused) 22 | { 23 | } 24 | 25 | -------------------------------------------------------------------------------- /power/power-feature.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _QCOM_POWER_FEATURE_H 18 | #define _QCOM_POWER_FEATURE_H 19 | 20 | #include 21 | 22 | void set_device_specific_feature(struct power_module *module, feature_t feature, int state); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /power/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | 32 | int sysfs_read(char *path, char *s, int num_bytes); 33 | int sysfs_write(char *path, char *s); 34 | int get_scaling_governor(char governor[], int size); 35 | int get_scaling_governor_check_cores(char governor[], int size,int core_num); 36 | 37 | void vote_ondemand_io_busy_off(); 38 | void unvote_ondemand_io_busy_off(); 39 | void vote_ondemand_sdf_low(); 40 | void unvote_ondemand_sdf_low(); 41 | void perform_hint_action(int hint_id, int resource_values[], 42 | int num_resources); 43 | void undo_hint_action(int hint_id); 44 | void undo_initial_hint_action(); 45 | void set_profile(int profile); 46 | void start_prefetch(int pid, const char *packageName); 47 | 48 | long long calc_timespan_us(struct timespec start, struct timespec end); 49 | int get_soc_id(void); 50 | -------------------------------------------------------------------------------- /recovery/Android.mk: -------------------------------------------------------------------------------- 1 | include $(all-subdir-makefiles) 2 | -------------------------------------------------------------------------------- /recovery/miniui/Android.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(TARGET_RECOVERY_UI_LIB),librecovery_ui_msm) 2 | ifneq ($(TARGET_SIMULATOR),true) 3 | ifneq ($(filter arm arm64, $(TARGET_ARCH)),) 4 | 5 | LOCAL_PATH := $(call my-dir) 6 | include $(CLEAR_VARS) 7 | 8 | LOCAL_MODULE := librecovery_ui_msm 9 | 10 | LOCAL_MODULE_TAGS := optional 11 | 12 | LOCAL_C_INCLUDES += bootable/recovery 13 | 14 | LOCAL_SRC_FILES += msm_recovery_ui.cpp 15 | 16 | include $(BUILD_STATIC_LIBRARY) 17 | endif # TARGET_ARCH == arm 18 | endif # !TARGET_SIMULATOR 19 | endif 20 | -------------------------------------------------------------------------------- /recovery/miniui/msm_recovery_ui.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following 11 | disclaimer in the documentation and/or other materials provided 12 | with the distribution. 13 | * Neither the name of The Linux Foundation nor the names of its 14 | contributors may be used to endorse or promote products derived 15 | from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "device.h" 31 | #include "screen_ui.h" 32 | 33 | 34 | class MSM_Device : public Device 35 | { 36 | public: 37 | MSM_Device(ScreenRecoveryUI* ui) : Device(ui) {} 38 | 39 | bool PostWipeDevice() { 40 | clear_keys_required = true; 41 | return true; 42 | } 43 | 44 | char const* GetRebootReason() { 45 | if (clear_keys_required) 46 | return "keys clear"; 47 | return ""; 48 | } 49 | 50 | private: 51 | bool clear_keys_required = false; 52 | }; 53 | 54 | Device* make_device() { 55 | return new MSM_Device(new ScreenRecoveryUI); 56 | } 57 | -------------------------------------------------------------------------------- /recovery/oem-recovery/Android.mk: -------------------------------------------------------------------------------- 1 | ifneq ($(filter librecovery_updater_msm,$(TARGET_RECOVERY_UPDATER_LIBS)),) 2 | LOCAL_PATH := $(call my-dir) 3 | include $(CLEAR_VARS) 4 | LOCAL_MODULE_TAGS := optional 5 | LOCAL_C_INCLUDES := bootable/recovery \ 6 | system/core/libsparse \ 7 | $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include 8 | LOCAL_SRC_FILES := gpt-utils.cpp dec.cpp oem-updater.cpp 9 | LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr 10 | LOCAL_MODULE := librecovery_updater_msm 11 | include $(BUILD_STATIC_LIBRARY) 12 | endif 13 | -------------------------------------------------------------------------------- /recovery/oem-recovery/dec.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | /* Service IDs */ 41 | #define SCM_SVC_SSD 0x07 42 | 43 | /* Service specific command IDs */ 44 | #define SSD_PARSE_MD_ID 0x06 45 | #define SSD_DECRYPT_IMG_FRAG_ID 0x07 46 | 47 | /* SSD parsing status messages from TZ */ 48 | #define SSD_PMD_ENCRYPTED 0 49 | #define SSD_PMD_NOT_ENCRYPTED 1 50 | #define SSD_PMD_PARSING_INCOMPLETE 6 51 | 52 | #define SSD_HEADER_MIN_SIZE 128 53 | #define MULTIPLICATION_FACTOR 2 54 | 55 | #define SMCMOD_DECRYPT_REQ_OP_METADATA 1 56 | #define SMCMOD_DECRYPT_REQ_OP_IMG_FRAG 2 57 | 58 | struct smcmod_decrypt_req { 59 | uint32_t service_id; /* in */ 60 | uint32_t command_id; /* in */ 61 | uint32_t operation; /* in */ 62 | 63 | union { 64 | struct { 65 | uint32_t len; 66 | uint32_t ion_fd; 67 | } metadata; 68 | struct { 69 | uint32_t ctx_id; 70 | uint32_t last_frag; 71 | uint32_t frag_len; 72 | uint32_t ion_fd; 73 | uint32_t offset; 74 | } img_frag; 75 | } request; 76 | 77 | union { 78 | struct { 79 | uint32_t status; 80 | uint32_t ctx_id; 81 | uint32_t end_offset; 82 | } metadata; 83 | struct { 84 | uint32_t status; 85 | } img_frag; 86 | } response; 87 | }; 88 | 89 | #define SMCMOD_IOC_MAGIC 0x97 90 | #define SMCMOD_IOCTL_DECRYPT_CMD \ 91 | _IOWR(SMCMOD_IOC_MAGIC, 37, struct smcmod_decrypt_req) 92 | 93 | struct ion_buf_handle { 94 | unsigned char *buffer; 95 | uint32_t buffer_len; 96 | int ion_fd; 97 | int ifd_data_fd; 98 | struct ion_handle_data ion_alloc_handle; 99 | }; 100 | 101 | static int 102 | ion_memalloc(struct ion_buf_handle *buf, uint32_t size, uint32_t heap) 103 | { 104 | struct ion_allocation_data alloc_data; 105 | struct ion_fd_data fd_data; 106 | unsigned char *va; 107 | struct ion_handle_data handle_data; 108 | int ion_fd; 109 | int rc; 110 | 111 | ion_fd = open("/dev/ion", O_RDONLY); 112 | if (ion_fd < 0) { 113 | fprintf(stderr, "Cannot open ION device (%s)\n", strerror(errno)); 114 | return -1; 115 | } 116 | 117 | alloc_data.len = (size + 4095) & ~4095; 118 | alloc_data.align = 4096; 119 | 120 | alloc_data.flags = 0; 121 | alloc_data.heap_id_mask = ION_HEAP(heap); 122 | 123 | /* Set the buffers to be uncached */ 124 | alloc_data.flags = 0; 125 | 126 | rc = ioctl(ion_fd, ION_IOC_ALLOC, &alloc_data); 127 | if (rc) { 128 | fprintf(stderr, "ION buffer allocation failed (%s)\n", 129 | strerror(errno)); 130 | goto alloc_fail; 131 | } 132 | 133 | if (alloc_data.handle) { 134 | fd_data.handle = alloc_data.handle; 135 | } else { 136 | fprintf(stderr, "ION alloc data returned NULL\n"); 137 | rc = -1; 138 | goto alloc_fail; 139 | } 140 | 141 | rc = ioctl(ion_fd, ION_IOC_MAP, &fd_data); 142 | if (rc) { 143 | fprintf(stderr, "ION map call failed(%s)\n", strerror(errno)); 144 | goto ioctl_fail; 145 | } 146 | 147 | va = (unsigned char*)mmap(NULL, alloc_data.len, PROT_READ | PROT_WRITE, 148 | MAP_SHARED, fd_data.fd, 0); 149 | if (va == MAP_FAILED) { 150 | fprintf(stderr, "ION memory map failed (%s)\n", strerror(errno)); 151 | rc = -1; 152 | goto map_fail; 153 | } 154 | 155 | buf->ion_fd = ion_fd; 156 | buf->ifd_data_fd = fd_data.fd; 157 | buf->buffer = va; 158 | buf->ion_alloc_handle.handle = alloc_data.handle; 159 | buf->buffer_len = alloc_data.len; 160 | 161 | memset(buf->buffer, 0, buf->buffer_len); 162 | return 0; 163 | 164 | map_fail: 165 | ioctl_fail: 166 | handle_data.handle = alloc_data.handle; 167 | if (buf->ifd_data_fd) 168 | close(buf->ifd_data_fd); 169 | rc = ioctl(ion_fd, ION_IOC_FREE, &handle_data); 170 | if (rc) 171 | fprintf(stderr, "ION free failed (%s)\n", strerror(errno)); 172 | alloc_fail: 173 | if (ion_fd >= 0) 174 | close(ion_fd); 175 | buf->ion_fd = -1; 176 | return rc; 177 | } 178 | 179 | static int ion_memfree(struct ion_buf_handle *handle) 180 | { 181 | struct ion_handle_data handle_data; 182 | int ret; 183 | 184 | ret = munmap(handle->buffer, (handle->buffer_len + 4095) & ~4095); 185 | if (ret) 186 | fprintf(stderr, "munmap failed (%s)\n", strerror(errno)); 187 | 188 | handle_data.handle = handle->ion_alloc_handle.handle; 189 | close(handle->ifd_data_fd); 190 | ret = ioctl(handle->ion_fd, ION_IOC_FREE, &handle_data); 191 | if (ret) 192 | fprintf(stderr, "ION free failed (%s)\n", strerror(errno)); 193 | close(handle->ion_fd); 194 | 195 | return ret; 196 | } 197 | 198 | static int ion_buffer_clean_inval(struct ion_buf_handle *buf, uint32_t cmd) 199 | { 200 | struct ion_flush_data data; 201 | int rc; 202 | 203 | data.fd = buf->ifd_data_fd; 204 | data.vaddr = buf->buffer; 205 | data.length = buf->buffer_len; 206 | data.offset = 0; 207 | data.handle = buf->ion_alloc_handle.handle; 208 | 209 | rc = ioctl(buf->ion_fd, cmd, &data); 210 | if (rc < 0) 211 | fprintf(stderr, "clean_inval cache failed (%s)\n", strerror(errno)); 212 | 213 | return rc; 214 | } 215 | 216 | static int is_encrypted(int smcmod_fd, struct ion_buf_handle *buf, 217 | uint32_t len, uint32_t *ctx_id, uint32_t *end_offset) 218 | { 219 | struct smcmod_decrypt_req req; 220 | uint32_t status; 221 | int ret; 222 | 223 | req.service_id = SCM_SVC_SSD; 224 | req.command_id = SSD_PARSE_MD_ID; 225 | req.operation = SMCMOD_DECRYPT_REQ_OP_METADATA; 226 | req.request.metadata.len = 227 | (len >= SSD_HEADER_MIN_SIZE) ? SSD_HEADER_MIN_SIZE : len; 228 | req.request.metadata.ion_fd = buf->ifd_data_fd; 229 | 230 | do { 231 | ret = ioctl(smcmod_fd, SMCMOD_IOCTL_DECRYPT_CMD, &req); 232 | if (ret < 0) 233 | fprintf(stderr, "%s: ioctl ret=%d, %s\n", __func__, ret, 234 | strerror(errno)); 235 | 236 | status = req.response.metadata.status; 237 | 238 | if (!ret && (status == SSD_PMD_PARSING_INCOMPLETE)) { 239 | req.request.metadata.len *= MULTIPLICATION_FACTOR; 240 | continue; 241 | } else { 242 | break; 243 | } 244 | } while (1); 245 | 246 | if (!ret) { 247 | if (status == SSD_PMD_ENCRYPTED) { 248 | *ctx_id = req.response.metadata.ctx_id; 249 | *end_offset = req.response.metadata.end_offset; 250 | ret = 1; 251 | } else { 252 | fprintf(stderr, "Image is not encrypted (response status %d)\n", 253 | status); 254 | } 255 | } else { 256 | fprintf(stderr, "%s: call failed\n", __func__); 257 | } 258 | 259 | return ret; 260 | } 261 | 262 | static int decrypt(int smcmod_fd, struct ion_buf_handle *buf, uint32_t len, 263 | uint32_t md_ctx, uint32_t offset) 264 | { 265 | struct smcmod_decrypt_req req; 266 | int ret; 267 | 268 | req.service_id = SCM_SVC_SSD; 269 | req.command_id = SSD_DECRYPT_IMG_FRAG_ID; 270 | req.operation = SMCMOD_DECRYPT_REQ_OP_IMG_FRAG; 271 | req.request.img_frag.ctx_id = md_ctx; 272 | req.request.img_frag.last_frag = 1; 273 | req.request.img_frag.ion_fd = buf->ifd_data_fd; 274 | req.request.img_frag.frag_len = len - offset; 275 | req.request.img_frag.offset = offset; 276 | 277 | ret = ioctl(smcmod_fd, SMCMOD_IOCTL_DECRYPT_CMD, &req); 278 | if (ret < 0) { 279 | fprintf(stderr, "decrypt ioctl failed (%s)\n", strerror(errno)); 280 | return ret; 281 | } 282 | 283 | return 0; 284 | } 285 | 286 | static int save_file(const char *fname, unsigned char *buf, size_t len) 287 | { 288 | FILE *file; 289 | size_t written; 290 | 291 | file = fopen(fname, "wb"); 292 | if (!file) { 293 | fprintf(stderr, "Failed to open %s (%s)\n", fname, strerror(errno)); 294 | return -errno; 295 | } 296 | 297 | written = fwrite(buf, len, 1, file); 298 | if (written != 1) { 299 | fclose(file); 300 | fprintf(stderr, "Failed to write %s (%s)\n", fname, strerror(errno)); 301 | return -errno; 302 | } 303 | fflush(file); 304 | fclose(file); 305 | fprintf(stdout, "%s written %d bytes\n", fname, len); 306 | return 0; 307 | } 308 | 309 | int decrypt_image(const char *src_file, const char *dst_file) 310 | { 311 | int ret = -1; 312 | uint32_t md_ctx = 0, offset = 0; 313 | uint32_t fsize = 0; 314 | FILE *file = NULL; 315 | struct ion_buf_handle ionbuf; 316 | int smcmod_fd = -1; 317 | int qseecom_fd = -1; 318 | size_t read; 319 | 320 | memset(&ionbuf, 0, sizeof(ionbuf)); 321 | ionbuf.ion_fd = -1; 322 | 323 | qseecom_fd = open("/dev/qseecom", O_RDWR); 324 | if (qseecom_fd < 0) { 325 | fprintf(stderr, "Failed to open /dev/qseecom device (%s)\n", 326 | strerror(errno)); 327 | goto exit; 328 | } 329 | 330 | smcmod_fd = open("/dev/smcmod", O_RDWR); 331 | if (smcmod_fd < 0) { 332 | fprintf(stderr, "Failed to open /dev/smcmod device (%s)\n", 333 | strerror(errno)); 334 | goto exit; 335 | } 336 | 337 | file = fopen(src_file, "rb"); 338 | if (!file) { 339 | fprintf(stderr, "Failed to open %s (%s)\n", src_file, strerror(errno)); 340 | goto exit; 341 | } 342 | 343 | fseek(file, 0, SEEK_END); 344 | fsize = ftell(file); 345 | fseek(file, 0, SEEK_SET); 346 | 347 | ret = ion_memalloc(&ionbuf, fsize, ION_PIL1_HEAP_ID); 348 | if (ret) 349 | goto exit; 350 | 351 | read = fread(ionbuf.buffer, fsize, 1, file); 352 | if (read != 1) { 353 | fprintf(stderr, "Failed to read %s (%s)\n", src_file, strerror(errno)); 354 | ret = -errno; 355 | goto exit; 356 | } 357 | 358 | ret = ion_buffer_clean_inval(&ionbuf, ION_IOC_CLEAN_INV_CACHES); 359 | if (ret < 0) 360 | goto exit; 361 | 362 | ret = ioctl(qseecom_fd, QSEECOM_IOCTL_PERF_ENABLE_REQ); 363 | if (ret < 0) 364 | goto exit; 365 | 366 | ret = is_encrypted(smcmod_fd, &ionbuf, fsize, &md_ctx, &offset); 367 | if (ret < 0) 368 | goto exit; 369 | 370 | if (ret == 1) { 371 | fprintf(stdout, "decrypting %s ...\n", src_file); 372 | ret = decrypt(smcmod_fd, &ionbuf, fsize, md_ctx, offset); 373 | if (ret < 0) 374 | goto exit; 375 | 376 | ion_buffer_clean_inval(&ionbuf, ION_IOC_INV_CACHES); 377 | 378 | ret = save_file(dst_file, ionbuf.buffer + offset, fsize - offset); 379 | if (ret < 0) 380 | goto exit; 381 | 382 | fprintf(stdout, "decrypting done!\n"); 383 | } 384 | 385 | exit: 386 | if (ionbuf.ion_fd >= 0) 387 | ion_memfree(&ionbuf); 388 | 389 | if (qseecom_fd >= 0) { 390 | ioctl(qseecom_fd, QSEECOM_IOCTL_PERF_DISABLE_REQ); 391 | close(qseecom_fd); 392 | } 393 | 394 | if (smcmod_fd >= 0) 395 | close(smcmod_fd); 396 | 397 | if (file) 398 | fclose(file); 399 | 400 | return ret; 401 | } 402 | -------------------------------------------------------------------------------- /recovery/oem-recovery/dec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef __DEC_H__ 31 | #define __DEC_H__ 32 | int decrypt_image(const char *src_file, const char *dst_file); 33 | #endif 34 | -------------------------------------------------------------------------------- /recovery/oem-recovery/gpt-utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef __GPT_UTILS_H__ 31 | #define __GPT_UTILS_H__ 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | #include 36 | #include 37 | /****************************************************************************** 38 | * TYPES 39 | ******************************************************************************/ 40 | enum boot_update_stage { 41 | UPDATE_MAIN = 1, 42 | UPDATE_BACKUP, 43 | UPDATE_FINALIZE 44 | }; 45 | 46 | 47 | 48 | /****************************************************************************** 49 | * FUNCTION PROTOTYPES 50 | ******************************************************************************/ 51 | int prepare_boot_update(enum boot_update_stage stage); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | #endif /* __GPT_UTILS_H__ */ 57 | -------------------------------------------------------------------------------- /recovery/oem-recovery/oem-updater.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include "edify/expr.h" 34 | #include "dec.h" 35 | #include "gpt-utils.h" 36 | 37 | Value* DecryptFn(const char* name, State* state, int argc, Expr* argv[]) { 38 | int rc = -1; 39 | char *src_file, *dst_file; 40 | 41 | if (argc != 2) 42 | return ErrorAbort(state, "%s expects 2 args, got %d", name, argc); 43 | 44 | if (ReadArgs(state, argv, 2, &src_file, &dst_file)) 45 | return NULL; 46 | 47 | rc = decrypt_image(src_file, dst_file); 48 | 49 | free(src_file); 50 | free(dst_file); 51 | 52 | return StringValue(strdup(rc >= 0 ? "t" : "")); 53 | } 54 | 55 | Value* BootUpdateFn(const char* name, State* state, int argc, Expr* argv[]) 56 | { 57 | int rc = 0; 58 | char *stageStr; 59 | enum boot_update_stage stage; 60 | 61 | if (argc != 1) 62 | return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc); 63 | 64 | if (ReadArgs(state, argv, 1, &stageStr)) 65 | return NULL; 66 | 67 | if (!strcmp(stageStr, "main")) 68 | stage = UPDATE_MAIN; 69 | else if (!strcmp(stageStr, "backup")) 70 | stage = UPDATE_BACKUP; 71 | else if (!strcmp(stageStr, "finalize")) 72 | stage = UPDATE_FINALIZE; 73 | else { 74 | fprintf(stderr, "Unrecognized boot update stage, exitting\n"); 75 | rc = -1; 76 | } 77 | 78 | free(stageStr); 79 | 80 | if (!rc) 81 | rc = prepare_boot_update(stage); 82 | 83 | return StringValue(strdup(rc ? "" : "t")); 84 | } 85 | 86 | void Register_librecovery_updater_msm() { 87 | RegisterFunction("msm.decrypt", DecryptFn); 88 | RegisterFunction("msm.boot_update", BootUpdateFn); 89 | } 90 | -------------------------------------------------------------------------------- /releasetools.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2009 The Android Open Source Project 2 | # Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """Emit commands needed for QCOM devices during OTA installation 17 | (installing the radio image).""" 18 | 19 | import common 20 | import re 21 | 22 | 23 | bootImages = {} 24 | binImages = {} 25 | fwImages = {} 26 | imgImages = {} 27 | 28 | # Parse filesmap file containing firmware residing places 29 | def LoadFilesMap(zip, name="RADIO/filesmap"): 30 | try: 31 | data = zip.read(name) 32 | except KeyError: 33 | print "Warning: could not find %s in %s." % (name, zip) 34 | data = "" 35 | d = {} 36 | for line in data.split("\n"): 37 | line = line.strip() 38 | if not line or line.startswith("#"): 39 | continue 40 | pieces = line.split() 41 | if not (len(pieces) == 2): 42 | raise ValueError("malformed filesmap line: \"%s\"" % (line,)) 43 | d[pieces[0]] = pieces[1] 44 | return d 45 | 46 | 47 | # Read firmware images from target files zip 48 | def GetRadioFiles(z): 49 | out = {} 50 | for info in z.infolist(): 51 | f = info.filename 52 | if f.startswith("RADIO/") and (f.__len__() > len("RADIO/")): 53 | fn = f[6:] 54 | if fn.startswith("filesmap"): 55 | continue 56 | data = z.read(f) 57 | out[fn] = common.File(f, data) 58 | return out 59 | 60 | 61 | # Get firmware residing place from filesmap 62 | def GetFileDestination(fn, filesmap): 63 | # if file is encoded disregard the .enc extention 64 | if fn.endswith('.enc'): 65 | fn = fn[:-4] 66 | 67 | # get backup destination as well if present 68 | backup = None 69 | if fn + ".bak" in filesmap: 70 | backup = filesmap[fn + ".bak"] 71 | 72 | # If full filename is not specified in filesmap get only the name part 73 | # and look for this token 74 | if fn not in filesmap: 75 | fn = fn.split(".")[0] + ".*" 76 | if fn not in filesmap: 77 | print "warning radio-update: '%s' not found in filesmap" % (fn) 78 | return None, backup 79 | return filesmap[fn], backup 80 | 81 | 82 | # Separate image types as each type needs different handling 83 | def SplitFwTypes(files): 84 | boot = {} 85 | bin = {} 86 | fw = {} 87 | img = {} 88 | 89 | for f in files: 90 | extIdx = -1 91 | dotSeparated = f.split(".") 92 | while True: 93 | if dotSeparated[extIdx] != 'p' and dotSeparated[extIdx] != 'enc': 94 | break 95 | extIdx -= 1 96 | 97 | if dotSeparated[extIdx] == 'mbn' or dotSeparated[extIdx] == 'elf': 98 | boot[f] = files[f] 99 | elif dotSeparated[extIdx] == 'bin': 100 | bin[f] = files[f] 101 | elif dotSeparated[extIdx] == 'img': 102 | img[f] = files[f] 103 | else: 104 | fw[f] = files[f] 105 | return boot, bin, fw, img 106 | 107 | 108 | # Prepare radio-update files and verify them 109 | def OTA_VerifyEnd(info, api_version, target_zip, source_zip=None): 110 | if api_version < 3: 111 | print "warning radio-update: no support for api_version less than 3" 112 | return False 113 | 114 | print "Loading radio filesmap..." 115 | filesmap = LoadFilesMap(target_zip) 116 | if filesmap == {}: 117 | print "warning radio-update: no or invalid filesmap file found" 118 | return False 119 | 120 | print "Loading radio target..." 121 | tgt_files = GetRadioFiles(target_zip) 122 | if tgt_files == {}: 123 | print "warning radio-update: no radio images in input target_files" 124 | return False 125 | 126 | src_files = None 127 | if source_zip is not None: 128 | print "Loading radio source..." 129 | src_files = GetRadioFiles(source_zip) 130 | 131 | update_list = {} 132 | largest_source_size = 0 133 | 134 | print "Preparing radio-update files..." 135 | for fn in tgt_files: 136 | dest, destBak = GetFileDestination(fn, filesmap) 137 | if dest is None: 138 | continue 139 | 140 | tf = tgt_files[fn] 141 | sf = None 142 | if src_files is not None: 143 | sf = src_files.get(fn, None) 144 | 145 | full = sf is None or fn.endswith('.enc') 146 | if not full: 147 | # no difference - skip this file 148 | if tf.sha1 == sf.sha1: 149 | continue 150 | d = common.Difference(tf, sf) 151 | _, _, d = d.ComputePatch() 152 | # no difference - skip this file 153 | if d is None: 154 | continue 155 | # if patch is almost as big as the file - don't bother patching 156 | full = len(d) > tf.size * common.OPTIONS.patch_threshold 157 | if not full: 158 | f = "patch/firmware-update/" + fn + ".p" 159 | common.ZipWriteStr(info.output_zip, f, d) 160 | update_list[f] = (dest, destBak, tf, sf) 161 | largest_source_size = max(largest_source_size, sf.size) 162 | if full: 163 | f = "firmware-update/" + fn 164 | common.ZipWriteStr(info.output_zip, f, tf.data) 165 | update_list[f] = (dest, destBak, None, None) 166 | 167 | global bootImages 168 | global binImages 169 | global fwImages 170 | global imgImages 171 | bootImages, binImages, fwImages, imgImages = SplitFwTypes(update_list) 172 | 173 | # If there are incremental patches verify them 174 | if largest_source_size != 0: 175 | info.script.Comment("---- radio update verification ----") 176 | info.script.Print("Verifying radio-update...") 177 | 178 | for f in bootImages: 179 | dest, destBak, tf, sf = bootImages[f] 180 | # Not incremental 181 | if sf is None: 182 | continue 183 | info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % 184 | (dest, sf.size, sf.sha1, tf.size, tf.sha1)) 185 | if destBak is not None: 186 | info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % 187 | (destBak, sf.size, sf.sha1, tf.size, tf.sha1)) 188 | for f in binImages: 189 | dest, destBak, tf, sf = binImages[f] 190 | # Not incremental 191 | if sf is None: 192 | continue 193 | info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % 194 | (dest, sf.size, sf.sha1, tf.size, tf.sha1)) 195 | last_mounted = "" 196 | for f in fwImages: 197 | dest, destBak, tf, sf = fwImages[f] 198 | # Not incremental 199 | if sf is None: 200 | continue 201 | # Get the filename without the path and the patch (.p) extention 202 | f = f.split("/")[-1][:-2] 203 | # Parse filesmap destination paths for "/dev/" pattern in the beginng. 204 | # This would mean that the file must be written to block device - 205 | # fs mount needed 206 | if dest.startswith("/dev/"): 207 | if last_mounted != dest: 208 | info.script.AppendExtra('unmount("/firmware");') 209 | info.script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' % 210 | (dest)) 211 | last_mounted = dest 212 | dest = "/firmware/image/" + f 213 | else: 214 | dest = dest + "/" + f 215 | info.script.PatchCheck(dest, tf.sha1, sf.sha1) 216 | for f in imgImages: 217 | dest, tf, sf = imgImages[f] 218 | # Not incremental 219 | if sf is None: 220 | continue 221 | info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % 222 | (dest, sf.size, sf.sha1, tf.size, tf.sha1)) 223 | last_mounted = "" 224 | 225 | info.script.CacheFreeSpaceCheck(largest_source_size) 226 | return True 227 | 228 | 229 | def FullOTA_Assertions(info): 230 | #TODO: Implement device specific asserstions. 231 | return 232 | 233 | 234 | def IncrementalOTA_Assertions(info): 235 | #TODO: Implement device specific asserstions. 236 | return 237 | 238 | 239 | def IncrementalOTA_VerifyEnd(info): 240 | OTA_VerifyEnd(info, info.target_version, info.target_zip, info.source_zip) 241 | return 242 | 243 | 244 | # This function handles only non-HLOS whole partition images 245 | def InstallRawImage(script, f, dest, tf, sf): 246 | if f.endswith('.p'): 247 | script.ApplyPatch("EMMC:%s:%d:%s:%d:%s" % 248 | (dest, sf.size, sf.sha1, tf.size, tf.sha1), 249 | "-", tf.size, tf.sha1, sf.sha1, f) 250 | elif f.endswith('.enc'): 251 | # Get the filename without the path 252 | fn = f.split("/")[-1] 253 | script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (f, fn)) 254 | script.AppendExtra('msm.decrypt("/tmp/%s", "%s");' % (fn, dest)) 255 | else: 256 | script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest)) 257 | return 258 | 259 | 260 | # This function handles only non-HLOS boot images - files list must contain 261 | # only such images (aboot, tz, etc) 262 | def InstallBootImages(script, files): 263 | bakExists = False 264 | # update main partitions 265 | script.AppendExtra('ifelse(msm.boot_update("main"), (') 266 | for f in files: 267 | dest, destBak, tf, sf = files[f] 268 | if destBak is not None: 269 | bakExists = True 270 | InstallRawImage(script, f, dest, tf, sf) 271 | script.AppendExtra('), "");') 272 | 273 | # update backup partitions 274 | if bakExists: 275 | script.AppendExtra('ifelse(msm.boot_update("backup"), (') 276 | for f in files: 277 | dest, destBak, tf, sf = files[f] 278 | if destBak is not None: 279 | InstallRawImage(script, f, destBak, tf, sf) 280 | script.AppendExtra('), "");') 281 | # just finalize primary update stage 282 | else: 283 | script.AppendExtra('msm.boot_update("backup");') 284 | 285 | # finalize partitions update 286 | script.AppendExtra('msm.boot_update("finalize");') 287 | return 288 | 289 | 290 | # This function handles only non-HLOS bin images 291 | def InstallBinImages(script, files): 292 | for f in files: 293 | dest, _, tf, sf = files[f] 294 | InstallRawImage(script, f, dest, tf, sf) 295 | return 296 | 297 | 298 | # This function handles only non-HLOS firmware files that are not whole 299 | # partition images (modem, dsp, etc) 300 | def InstallFwImages(script, files): 301 | last_mounted = "" 302 | 303 | for f in files: 304 | dest, _, tf, sf = files[f] 305 | # Get the filename without the path 306 | fn = f.split("/")[-1] 307 | # Parse filesmap destination paths for "/dev/" pattern in the beginng. 308 | # This would mean that the file must be written to block device - 309 | # fs mount needed 310 | if dest.startswith("/dev/"): 311 | if last_mounted != dest: 312 | script.AppendExtra('unmount("/firmware");') 313 | script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' % 314 | (dest)) 315 | last_mounted = dest 316 | dest = "/firmware/image/" + fn 317 | else: 318 | dest = dest + "/" + fn 319 | 320 | if f.endswith('.p'): 321 | script.ApplyPatch(dest[:-2], "-", tf.size, tf.sha1, sf.sha1, f) 322 | elif f.endswith('.enc'): 323 | script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (f, fn)) 324 | script.AppendExtra('msm.decrypt("/tmp/%s", "%s");' % (fn, dest[:-4])) 325 | else: 326 | script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest)) 327 | 328 | if last_mounted != "": 329 | script.AppendExtra('unmount("/firmware");') 330 | return 331 | 332 | # This function handles *.img images 333 | def InstallImgImages(script, files): 334 | for f in files: 335 | dest, _, tf, sf = files[f] 336 | InstallRawImage(script, f, dest, tf, sf) 337 | return 338 | 339 | 340 | def OTA_InstallEnd(info): 341 | print "Applying radio-update script modifications..." 342 | info.script.Comment("---- radio update tasks ----") 343 | info.script.Print("Patching firmware images...") 344 | 345 | if bootImages != {}: 346 | InstallBootImages(info.script, bootImages) 347 | if binImages != {}: 348 | InstallBinImages(info.script, binImages) 349 | if fwImages != {}: 350 | InstallFwImages(info.script, fwImages) 351 | if imgImages != {}: 352 | InstallImgImages(info.script, imgImages) 353 | return 354 | 355 | 356 | def FullOTA_InstallEnd_MMC(info): 357 | if OTA_VerifyEnd(info, info.input_version, info.input_zip): 358 | OTA_InstallEnd(info) 359 | return 360 | 361 | 362 | def FullOTA_InstallEnd_MTD(info): 363 | print "warning radio-update: radio update for NAND devices not supported" 364 | return 365 | 366 | 367 | def FullOTA_InstallEnd(info): 368 | FullOTA_InstallEnd_MMC(info) 369 | return 370 | 371 | def IncrementalOTA_InstallEnd_MMC(info): 372 | OTA_InstallEnd(info) 373 | return 374 | 375 | 376 | def IncrementalOTA_InstallEnd_MTD(info): 377 | print "warning radio-update: radio update for NAND devices not supported" 378 | return 379 | 380 | def IncrementalOTA_InstallEnd(info): 381 | IncrementalOTA_InstallEnd_MMC(info) 382 | return 383 | -------------------------------------------------------------------------------- /sdllvm-lto-defs.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(LOCAL_MODULE_CLASS), STATIC_LIBRARIES) 2 | # For STATIC_LIBRARIES we need to use SD LLVM's archiver and archiver flags. 3 | 4 | AR := $(SDCLANG_PATH)/llvm-ar 5 | ARFLAGS := crsD 6 | 7 | # For 32 bit 8 | $(LOCAL_BUILT_MODULE) : $(combo_2nd_arch_prefix)TARGET_AR := $(AR) 9 | $(LOCAL_BUILT_MODULE) : $(combo_var_prefix)GLOBAL_ARFLAGS := $(ARFLAGS) 10 | 11 | # For 64 bit 12 | intermediates := $(call local-intermediates-dir,,$(LOCAL_2ND_ARCH_VAR_PREFIX)) 13 | LOCAL_BUILT_MODULE_64 := $(intermediates)/$(my_built_module_stem) 14 | 15 | $(LOCAL_BUILT_MODULE_64) : TARGET_AR := $(AR) 16 | $(LOCAL_BUILT_MODULE_64) : TARGET_GLOBAL_ARFLAGS := $(ARFLAGS) 17 | 18 | else 19 | # For SHARED_LIBRARIES and EXECUTABLES we need to filter out flags not 20 | # needed/understood by SD LLVM's Linker. 21 | 22 | linked_module_32 := $(intermediates)/LINKED/$(my_built_module_stem) 23 | intermediates := $(call local-intermediates-dir,,$(LOCAL_2ND_ARCH_VAR_PREFIX)) 24 | linked_module_64 := $(intermediates)/LINKED/$(my_built_module_stem) 25 | 26 | FLAGS_TO_BE_FILTERED := -Wl,--icf=safe -Wl,--no-undefined-version -Wl,--fix-cortex-a53-843419 -fuse-ld=gold 27 | $(linked_module_32) : PRIVATE_TARGET_GLOBAL_LDFLAGS := $(filter-out $(FLAGS_TO_BE_FILTERED),$(PRIVATE_TARGET_GLOBAL_LDFLAGS)) 28 | $(linked_module_64) : PRIVATE_TARGET_GLOBAL_LDFLAGS := $(filter-out $(FLAGS_TO_BE_FILTERED),$(PRIVATE_TARGET_GLOBAL_LDFLAGS)) 29 | 30 | endif 31 | --------------------------------------------------------------------------------