1/*	$NetBSD: therm.h,v 1.3 2021/12/18 23:45:33 riastradh Exp $	*/
2
3/* SPDX-License-Identifier: MIT */
4#ifndef __NVKM_THERM_H__
5#define __NVKM_THERM_H__
6#include <core/subdev.h>
7
8#include <subdev/bios.h>
9#include <subdev/bios/therm.h>
10#include <subdev/timer.h>
11
12enum nvkm_therm_thrs_direction {
13	NVKM_THERM_THRS_FALLING = 0,
14	NVKM_THERM_THRS_RISING = 1
15};
16
17enum nvkm_therm_thrs_state {
18	NVKM_THERM_THRS_LOWER = 0,
19	NVKM_THERM_THRS_HIGHER = 1
20};
21
22enum nvkm_therm_thrs {
23	NVKM_THERM_THRS_FANBOOST = 0,
24	NVKM_THERM_THRS_DOWNCLOCK = 1,
25	NVKM_THERM_THRS_CRITICAL = 2,
26	NVKM_THERM_THRS_SHUTDOWN = 3,
27	NVKM_THERM_THRS_NR
28};
29
30enum nvkm_therm_fan_mode {
31	NVKM_THERM_CTRL_NONE = 0,
32	NVKM_THERM_CTRL_MANUAL = 1,
33	NVKM_THERM_CTRL_AUTO = 2,
34};
35
36enum nvkm_therm_attr_type {
37	NVKM_THERM_ATTR_FAN_MIN_DUTY = 0,
38	NVKM_THERM_ATTR_FAN_MAX_DUTY = 1,
39	NVKM_THERM_ATTR_FAN_MODE = 2,
40
41	NVKM_THERM_ATTR_THRS_FAN_BOOST = 10,
42	NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST = 11,
43	NVKM_THERM_ATTR_THRS_DOWN_CLK = 12,
44	NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST = 13,
45	NVKM_THERM_ATTR_THRS_CRITICAL = 14,
46	NVKM_THERM_ATTR_THRS_CRITICAL_HYST = 15,
47	NVKM_THERM_ATTR_THRS_SHUTDOWN = 16,
48	NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
49};
50
51struct nvkm_therm_clkgate_init {
52	u32 addr;
53	u8  count;
54	u32 data;
55};
56
57struct nvkm_therm_clkgate_pack {
58	const struct nvkm_therm_clkgate_init *init;
59};
60
61struct nvkm_therm {
62	const struct nvkm_therm_func *func;
63	struct nvkm_subdev subdev;
64
65	/* automatic thermal management */
66	struct nvkm_alarm alarm;
67	spinlock_t lock;
68	struct nvbios_therm_trip_point *last_trip;
69	int mode;
70	int cstate;
71	int suspend;
72
73	/* bios */
74	struct nvbios_therm_sensor bios_sensor;
75
76	/* fan priv */
77	struct nvkm_fan *fan;
78
79	/* alarms priv */
80	struct {
81		spinlock_t alarm_program_lock;
82		struct nvkm_alarm therm_poll_alarm;
83		enum nvkm_therm_thrs_state alarm_state[NVKM_THERM_THRS_NR];
84	} sensor;
85
86	/* what should be done if the card overheats */
87	struct {
88		void (*downclock)(struct nvkm_therm *, bool active);
89		void (*pause)(struct nvkm_therm *, bool active);
90	} emergency;
91
92	/* ic */
93	struct i2c_client *ic;
94
95	int (*fan_get)(struct nvkm_therm *);
96	int (*fan_set)(struct nvkm_therm *, int);
97
98	int (*attr_get)(struct nvkm_therm *, enum nvkm_therm_attr_type);
99	int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
100
101	bool clkgating_enabled;
102};
103
104int nvkm_therm_temp_get(struct nvkm_therm *);
105int nvkm_therm_fan_sense(struct nvkm_therm *);
106int nvkm_therm_cstate(struct nvkm_therm *, int, int);
107void nvkm_therm_clkgate_init(struct nvkm_therm *,
108			     const struct nvkm_therm_clkgate_pack *);
109void nvkm_therm_clkgate_enable(struct nvkm_therm *);
110void nvkm_therm_clkgate_fini(struct nvkm_therm *, bool);
111
112int nv40_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
113int nv50_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
114int g84_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
115int gt215_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
116int gf119_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
117int gk104_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
118int gm107_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
119int gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
120int gp100_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
121#endif
122