178 lines
4.8 KiB
C
178 lines
4.8 KiB
C
![]() |
/* 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
|