|  | /* 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_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_MAX, | 
|  | }; | 
|  |  | 
|  | struct rapl_package; | 
|  |  | 
|  | enum rapl_primitives { | 
|  | ENERGY_COUNTER, | 
|  | POWER_LIMIT1, | 
|  | POWER_LIMIT2, | 
|  | FW_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, | 
|  |  | 
|  | TIME_WINDOW1,		/* long term */ | 
|  | TIME_WINDOW2,		/* short term */ | 
|  | THERMAL_SPEC_POWER, | 
|  | MAX_POWER, | 
|  |  | 
|  | MIN_POWER, | 
|  | MAX_TIME_WINDOW, | 
|  | THROTTLED_TIME, | 
|  | PRIORITY_LEVEL, | 
|  |  | 
|  | /* below are not raw primitive data */ | 
|  | AVERAGE_POWER, | 
|  | NR_RAPL_PRIMITIVES, | 
|  | }; | 
|  |  | 
|  | struct rapl_domain_data { | 
|  | u64 primitives[NR_RAPL_PRIMITIVES]; | 
|  | unsigned long timestamp; | 
|  | }; | 
|  |  | 
|  | #define NR_POWER_LIMITS (2) | 
|  | struct rapl_power_limit { | 
|  | struct powercap_zone_constraint *constraint; | 
|  | int prim_id;		/* primitive ID used to enable */ | 
|  | struct rapl_domain *domain; | 
|  | const char *name; | 
|  | u64 last_power_limit; | 
|  | }; | 
|  |  | 
|  | struct rapl_package; | 
|  |  | 
|  | struct rapl_domain { | 
|  | const char *name; | 
|  | enum rapl_domain_type id; | 
|  | u64 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 domain_energy_unit; | 
|  | struct rapl_package *rp; | 
|  | }; | 
|  |  | 
|  | struct reg_action { | 
|  | u64 reg; | 
|  | u64 mask; | 
|  | u64 value; | 
|  | int err; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * 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. | 
|  | */ | 
|  | struct rapl_if_priv { | 
|  | struct powercap_control_type *control_type; | 
|  | struct rapl_domain *platform_rapl_domain; | 
|  | enum cpuhp_state pcap_rapl_online; | 
|  | u64 reg_unit; | 
|  | u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; | 
|  | int limits[RAPL_DOMAIN_MAX]; | 
|  | int (*read_raw)(int cpu, struct reg_action *ra); | 
|  | int (*write_raw)(int cpu, struct reg_action *ra); | 
|  | }; | 
|  |  | 
|  | /* 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 */ | 
|  | unsigned int power_unit; | 
|  | unsigned int energy_unit; | 
|  | unsigned int time_unit; | 
|  | 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; | 
|  | }; | 
|  |  | 
|  | struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv); | 
|  | struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv); | 
|  | void rapl_remove_package(struct rapl_package *rp); | 
|  |  | 
|  | int rapl_add_platform_domain(struct rapl_if_priv *priv); | 
|  | void rapl_remove_platform_domain(struct rapl_if_priv *priv); | 
|  |  | 
|  | #endif /* __INTEL_RAPL_H__ */ |