| /* Copyright (c) 2012, The Linux Foundation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| */ |
| #ifndef _ARCH_ARM_MACH_MSM_MSM_DCVS_H |
| #define _ARCH_ARM_MACH_MSM_MSM_DCVS_H |
| |
| #include <mach/msm_dcvs_scm.h> |
| |
| #define CORE_NAME_MAX (32) |
| #define CORES_MAX (10) |
| |
| #define CPU_OFFSET 1 /* used to notify TZ the core number */ |
| #define GPU_OFFSET (CORES_MAX * 2/3) /* there will be more cpus than gpus, |
| * let the GPU be assigned fewer core |
| * elements and start later |
| */ |
| |
| enum msm_core_idle_state { |
| MSM_DCVS_IDLE_ENTER, |
| MSM_DCVS_IDLE_EXIT, |
| }; |
| |
| enum msm_core_control_event { |
| MSM_DCVS_ENABLE_IDLE_PULSE, |
| MSM_DCVS_DISABLE_IDLE_PULSE, |
| MSM_DCVS_ENABLE_HIGH_LATENCY_MODES, |
| MSM_DCVS_DISABLE_HIGH_LATENCY_MODES, |
| }; |
| |
| struct msm_dcvs_sync_rule { |
| unsigned long cpu_khz; |
| unsigned long gpu_floor_khz; |
| }; |
| |
| struct msm_dcvs_platform_data { |
| struct msm_dcvs_sync_rule *sync_rules; |
| unsigned num_sync_rules; |
| unsigned long gpu_max_nom_khz; |
| }; |
| |
| struct msm_gov_platform_data { |
| struct msm_dcvs_core_info *info; |
| int latency; |
| }; |
| |
| /** |
| * msm_dcvs_register_cpu_freq |
| * @freq: the frequency value to register |
| * @voltage: the operating voltage (in mV) associated with the above frequency |
| * |
| * Register a cpu frequency and its operating voltage with dcvs. |
| */ |
| #ifdef CONFIG_MSM_DCVS |
| void msm_dcvs_register_cpu_freq(uint32_t freq, uint32_t voltage); |
| #else |
| static inline void msm_dcvs_register_cpu_freq(uint32_t freq, uint32_t voltage) |
| {} |
| #endif |
| |
| /** |
| * msm_dcvs_idle |
| * @dcvs_core_id: The id returned by msm_dcvs_register_core |
| * @state: The enter/exit idle state the core is in |
| * @iowaited: iowait in us |
| * on iMSM_DCVS_IDLE_EXIT. |
| * @return: |
| * 0 on success, |
| * -ENOSYS, |
| * -EINVAL, |
| * SCM return values |
| * |
| * Send idle state notifications to the msm_dcvs driver |
| */ |
| int msm_dcvs_idle(int dcvs_core_id, enum msm_core_idle_state state, |
| uint32_t iowaited); |
| |
| /** |
| * struct msm_dcvs_core_info |
| * |
| * Core specific information used by algorithm. Need to provide this |
| * before the sink driver can be registered. |
| */ |
| struct msm_dcvs_core_info { |
| int num_cores; |
| int *sensors; |
| int thermal_poll_ms; |
| struct msm_dcvs_freq_entry *freq_tbl; |
| struct msm_dcvs_core_param core_param; |
| struct msm_dcvs_algo_param algo_param; |
| struct msm_dcvs_energy_curve_coeffs energy_coeffs; |
| struct msm_dcvs_power_params power_param; |
| }; |
| |
| /** |
| * msm_dcvs_register_core |
| * @type: whether this is a CPU or a GPU |
| * @type_core_num: The number of the core for a type |
| * @info: The core specific algorithm parameters. |
| * @sensor: The thermal sensor number of the core in question |
| * @return : |
| * 0 on success, |
| * -ENOSYS, |
| * -ENOMEM |
| * |
| * Register the core with msm_dcvs driver. Done once at init before calling |
| * msm_dcvs_freq_sink_register |
| * Cores that need to run synchronously must share the same group id. |
| */ |
| extern int msm_dcvs_register_core( |
| enum msm_dcvs_core_type type, |
| int type_core_num, |
| struct msm_dcvs_core_info *info, |
| int (*set_frequency)(int type_core_num, unsigned int freq), |
| unsigned int (*get_frequency)(int type_core_num), |
| int (*idle_enable)(int type_core_num, |
| enum msm_core_control_event event), |
| int (*set_floor_frequency)(int type_core_num, unsigned int freq), |
| int sensor); |
| |
| /** |
| * msm_dcvs_freq_sink_start |
| * @drv: The sink driver |
| * @return: Handle unique to the core. |
| * |
| * Register the clock driver code with the msm_dvs driver to get notified about |
| * frequency change requests. |
| */ |
| extern int msm_dcvs_freq_sink_start(int dcvs_core_id); |
| |
| /** |
| * msm_dcvs_freq_sink_stop |
| * @drv: The sink driver |
| * @return: |
| * 0 on success, |
| * -EINVAL |
| * |
| * Unregister the sink driver for the core. This will cause the source driver |
| * for the core to stop sending idle pulses. |
| */ |
| extern int msm_dcvs_freq_sink_stop(int dcvs_core_id); |
| |
| /** |
| * msm_dcvs_update_limits |
| * @drv: The sink driver |
| * |
| * Update the frequency known to dcvs when the limits are changed. |
| */ |
| extern void msm_dcvs_update_limits(int dcvs_core_id); |
| |
| /** |
| * msm_dcvs_apply_gpu_floor |
| * @cpu_freq: CPU frequency to compare to GPU sync rules |
| * |
| * Apply a GPU floor frequency if the corresponding CPU frequency, |
| * or the number of CPUs online, requires it. |
| */ |
| extern void msm_dcvs_apply_gpu_floor(unsigned long cpu_freq); |
| |
| /** |
| * msm_dcvs_update_algo_params |
| * @return: |
| * 0 on success, < 0 on error |
| * |
| * Updates the DCVS algorithm with parameters depending on the |
| * number of CPUs online. |
| */ |
| extern int msm_dcvs_update_algo_params(void); |
| #endif |