Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270/* SPDX-License-Identifier: GPL-2.0 *//* * Data types and headers for RAPL support * * Copyright (C) 2019 Intel Corporation. * * Author: Zhang Rui <rui.zhang@intel.com> */
#ifndef __INTEL_RAPL_H__#define __INTEL_RAPL_H__
#include <linux/types.h>#include <linux/powercap.h>#include <linux/cpuhotplug.h>
enum rapl_if_type { RAPL_IF_MSR, /* RAPL I/F using MSR registers */ RAPL_IF_MMIO, /* RAPL I/F using MMIO registers */ RAPL_IF_TPMI, /* RAPL I/F using TPMI registers */};
enum rapl_domain_type { RAPL_DOMAIN_PACKAGE, /* entire package/socket */ RAPL_DOMAIN_PP0, /* core power plane */ RAPL_DOMAIN_PP1, /* graphics uncore */ RAPL_DOMAIN_DRAM, /* DRAM control_type */ RAPL_DOMAIN_PLATFORM, /* PSys control_type */ RAPL_DOMAIN_MAX,};
enum rapl_domain_reg_id { RAPL_DOMAIN_REG_LIMIT, RAPL_DOMAIN_REG_STATUS, RAPL_DOMAIN_REG_PERF, RAPL_DOMAIN_REG_POLICY, RAPL_DOMAIN_REG_INFO, RAPL_DOMAIN_REG_PL4, RAPL_DOMAIN_REG_UNIT, RAPL_DOMAIN_REG_PL2, RAPL_DOMAIN_REG_MAX,};
struct rapl_domain;
enum rapl_primitives { POWER_LIMIT1, POWER_LIMIT2, POWER_LIMIT4, ENERGY_COUNTER, FW_LOCK, FW_HIGH_LOCK, PL1_LOCK, PL2_LOCK, PL4_LOCK,
PL1_ENABLE, /* power limit 1, aka long term */ PL1_CLAMP, /* allow frequency to go below OS request */ PL2_ENABLE, /* power limit 2, aka short term, instantaneous */ PL2_CLAMP, PL4_ENABLE, /* power limit 4, aka max peak power */
TIME_WINDOW1, /* long term */ TIME_WINDOW2, /* short term */ THERMAL_SPEC_POWER, MAX_POWER,
MIN_POWER, MAX_TIME_WINDOW, THROTTLED_TIME, PRIORITY_LEVEL,
PSYS_POWER_LIMIT1, PSYS_POWER_LIMIT2, PSYS_PL1_ENABLE, PSYS_PL2_ENABLE, PSYS_TIME_WINDOW1, PSYS_TIME_WINDOW2, /* below are not raw primitive data */ NR_RAPL_PRIMITIVES,};
struct rapl_domain_data { u64 primitives[NR_RAPL_PRIMITIVES]; unsigned long timestamp;};
#define NR_POWER_LIMITS (POWER_LIMIT4 + 1)
struct rapl_power_limit { struct powercap_zone_constraint *constraint; struct rapl_domain *domain; const char *name; bool locked; u64 last_power_limit;};
struct rapl_package;
#define RAPL_DOMAIN_NAME_LENGTH 16
union rapl_reg { void __iomem *mmio; u32 msr; u64 val;};
struct rapl_domain { char name[RAPL_DOMAIN_NAME_LENGTH]; enum rapl_domain_type id; union rapl_reg regs[RAPL_DOMAIN_REG_MAX]; struct powercap_zone power_zone; struct rapl_domain_data rdd; struct rapl_power_limit rpl[NR_POWER_LIMITS]; u64 attr_map; /* track capabilities */ unsigned int state; unsigned int power_unit; unsigned int energy_unit; unsigned int time_unit; struct rapl_package *rp;};
struct reg_action { union rapl_reg reg; u64 mask; u64 value; int err;};
struct rapl_defaults { u8 floor_freq_reg_addr; int (*check_unit)(struct rapl_domain *rd); void (*set_floor_freq)(struct rapl_domain *rd, bool mode); u64 (*compute_time_window)(struct rapl_domain *rd, u64 val, bool to_raw); unsigned int dram_domain_energy_unit; unsigned int psys_domain_energy_unit; bool spr_psys_bits; bool msr_pl4_support; bool msr_pmu_support;};
#define PRIMITIVE_INFO_INIT(p, m, s, i, u, f) { \ .name = #p, \ .mask = m, \ .shift = s, \ .id = i, \ .unit = u, \ .flag = f \ }
enum unit_type { ARBITRARY_UNIT, /* no translation */ POWER_UNIT, ENERGY_UNIT, TIME_UNIT,};
/* per domain data. used to describe individual knobs such that access function * can be consolidated into one instead of many inline functions. */struct rapl_primitive_info { const char *name; u64 mask; int shift; enum rapl_domain_reg_id id; enum unit_type unit; u32 flag;};
/** * struct rapl_if_priv: private data for different RAPL interfaces * @control_type: Each RAPL interface must have its own powercap * control type. * @platform_rapl_domain: Optional. Some RAPL interface may have platform * level RAPL control. * @pcap_rapl_online: CPU hotplug state for each RAPL interface. * @reg_unit: Register for getting energy/power/time unit. * @regs: Register sets for different RAPL Domains. * @limits: Number of power limits supported by each domain. * @read_raw: Callback for reading RAPL interface specific * registers. * @write_raw: Callback for writing RAPL interface specific * registers. * @defaults: pointer to default settings * @rpi: pointer to interface primitive info */struct rapl_if_priv { enum rapl_if_type type; struct powercap_control_type *control_type; enum cpuhp_state pcap_rapl_online; union rapl_reg reg_unit; union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; int limits[RAPL_DOMAIN_MAX]; int (*read_raw)(int id, struct reg_action *ra, bool pmu_ctx); int (*write_raw)(int id, struct reg_action *ra); const struct rapl_defaults *defaults; struct rapl_primitive_info *rpi;};
#ifdef CONFIG_PERF_EVENTS/** * struct rapl_package_pmu_data: Per package data for PMU support * @scale: Scale of 2^-32 Joules for each energy counter increase. * @lock: Lock to protect n_active and active_list. * @n_active: Number of active events. * @active_list: List of active events. * @timer_interval: Maximum timer expiration time before counter overflow. * @hrtimer: Periodically update the counter to prevent overflow. */struct rapl_package_pmu_data { u64 scale[RAPL_DOMAIN_MAX]; raw_spinlock_t lock; int n_active; struct list_head active_list; ktime_t timer_interval; struct hrtimer hrtimer;};#endif
/* maximum rapl package domain name: package-%d-die-%d */#define PACKAGE_DOMAIN_NAME_LENGTH 30
struct rapl_package { unsigned int id; /* logical die id, equals physical 1-die systems */ unsigned int nr_domains; unsigned long domain_map; /* bit map of active domains */ struct rapl_domain *domains; /* array of domains, sized at runtime */ struct powercap_zone *power_zone; /* keep track of parent zone */ unsigned long power_limit_irq; /* keep track of package power limit * notify interrupt enable status. */ struct list_head plist; int lead_cpu; /* one active cpu per package for access */ /* Track active cpus */ struct cpumask cpumask; char name[PACKAGE_DOMAIN_NAME_LENGTH]; struct rapl_if_priv *priv;#ifdef CONFIG_PERF_EVENTS bool has_pmu; struct rapl_package_pmu_data pmu_data;#endif};
struct rapl_package *rapl_find_package_domain_cpuslocked(int id, struct rapl_if_priv *priv, bool id_is_cpu);struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *priv, bool id_is_cpu);void rapl_remove_package_cpuslocked(struct rapl_package *rp);
struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu);struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu);void rapl_remove_package(struct rapl_package *rp);int rapl_default_check_unit(struct rapl_domain *rd);void rapl_default_set_floor_freq(struct rapl_domain *rd, bool mode);u64 rapl_default_compute_time_window(struct rapl_domain *rd, u64 value, bool to_raw);
#ifdef CONFIG_PERF_EVENTSint rapl_package_add_pmu(struct rapl_package *rp);int rapl_package_add_pmu_locked(struct rapl_package *rp);void rapl_package_remove_pmu(struct rapl_package *rp);void rapl_package_remove_pmu_locked(struct rapl_package *rp);#elsestatic inline int rapl_package_add_pmu(struct rapl_package *rp) { return 0; }static inline int rapl_package_add_pmu_locked(struct rapl_package *rp) { return 0; }static inline void rapl_package_remove_pmu(struct rapl_package *rp) { }static inline void rapl_package_remove_pmu_locked(struct rapl_package *rp) { }#endif
#endif /* __INTEL_RAPL_H__ */