| /* |
| * Copyright (c) 2016 Park Bumgyu, Samsung Electronics Co., Ltd <bumgyu.park@samsung.com> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| * |
| * Exynos ACME(A Cpufreq that Meets Every chipset) driver implementation |
| */ |
| |
| #include <linux/pm_qos.h> |
| #include <soc/samsung/exynos-dm.h> |
| #include "exynos-ufc.h" |
| |
| struct exynos_cpufreq_dm { |
| struct list_head list; |
| struct exynos_dm_constraint c; |
| }; |
| |
| struct exynos_ufc { |
| struct list_head list; |
| struct exynos_ufc_info info; |
| }; |
| |
| typedef int (*target_fn)(struct cpufreq_policy *policy, |
| unsigned int target_freq, |
| unsigned int relation); |
| |
| struct exynos_cpufreq_ready_block { |
| struct list_head list; |
| |
| /* callback function to update policy-dependant data */ |
| int (*update)(struct cpufreq_policy *policy); |
| int (*get_target)(struct cpufreq_policy *policy, target_fn target); |
| }; |
| |
| struct exynos_cpufreq_domain { |
| /* list of domain */ |
| struct list_head list; |
| |
| /* lock */ |
| struct mutex lock; |
| |
| /* dt node */ |
| struct device_node *dn; |
| |
| /* domain identity */ |
| unsigned int id; |
| struct cpumask cpus; |
| unsigned int cal_id; |
| int dm_type; |
| |
| /* frequency scaling */ |
| bool enabled; |
| |
| unsigned int table_size; |
| struct cpufreq_frequency_table *freq_table; |
| |
| unsigned int max_freq; |
| unsigned int min_freq; |
| unsigned int boot_freq; |
| unsigned int resume_freq; |
| unsigned int old; |
| |
| /* PM QoS class */ |
| unsigned int pm_qos_min_class; |
| unsigned int pm_qos_max_class; |
| struct pm_qos_request min_qos_req; |
| struct pm_qos_request max_qos_req; |
| struct pm_qos_request user_min_qos_req; |
| struct pm_qos_request user_max_qos_req; |
| struct pm_qos_request user_min_qos_wo_boost_req; |
| struct notifier_block pm_qos_min_notifier; |
| struct notifier_block pm_qos_max_notifier; |
| |
| /* for sysfs */ |
| int user_boost; |
| unsigned int user_default_qos; |
| |
| /* freq boost */ |
| bool boost_supported; |
| unsigned int *boost_max_freqs; |
| struct cpumask online_cpus; |
| |
| /* list head of DVFS Manager constraints */ |
| struct list_head dm_list; |
| |
| /* list head of User cpuFreq Ctrl (UFC) */ |
| struct list_head ufc_list; |
| |
| bool need_awake; |
| |
| struct thermal_cooling_device *cdev; |
| }; |
| |
| /* |
| * list head of cpufreq domain |
| */ |
| |
| extern struct exynos_cpufreq_domain |
| *find_domain_cpumask(const struct cpumask *mask); |
| extern struct list_head *get_domain_list(void); |
| extern struct exynos_cpufreq_domain *first_domain(void); |
| extern struct exynos_cpufreq_domain *last_domain(void); |
| extern int exynos_cpufreq_domain_count(void); |
| |
| /* |
| * the time it takes on this CPU to switch between |
| * two frequencies in nanoseconds |
| */ |
| #define TRANSITION_LATENCY 5000000 |
| |
| /* |
| * Exynos CPUFreq API |
| */ |
| extern void exynos_cpufreq_ready_list_add(struct exynos_cpufreq_ready_block *rb); |
| extern unsigned int exynos_pstate_get_boost_freq(int cpu); |
| #ifdef CONFIG_ARM_EXYNOS_UFC |
| extern int ufc_domain_init(struct exynos_cpufreq_domain *domain); |
| #else |
| static inline int ufc_domain_init(struct exynos_cpufreq_domain *domain) |
| { |
| return 0; |
| } |
| #endif |