aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
blob: 36ed035d4d421db3ad5b6dc10b563cf46e0280e6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifndef __NOUVEAU_CLOCK_H__
#define __NOUVEAU_CLOCK_H__

#include <core/device.h>
#include <core/subdev.h>

struct nouveau_pll_vals;
struct nvbios_pll;

enum nv_clk_src {
	nv_clk_src_crystal,
	nv_clk_src_href,

	nv_clk_src_hclk,
	nv_clk_src_hclkm3,
	nv_clk_src_hclkm3d2,
	nv_clk_src_hclkm2d3, /* NVAA */
	nv_clk_src_hclkm4, /* NVAA */
	nv_clk_src_cclk, /* NVAA */

	nv_clk_src_host,

	nv_clk_src_sppll0,
	nv_clk_src_sppll1,

	nv_clk_src_mpllsrcref,
	nv_clk_src_mpllsrc,
	nv_clk_src_mpll,
	nv_clk_src_mdiv,

	nv_clk_src_core,
	nv_clk_src_core_intm,
	nv_clk_src_shader,

	nv_clk_src_mem,

	nv_clk_src_gpc,
	nv_clk_src_rop,
	nv_clk_src_hubk01,
	nv_clk_src_hubk06,
	nv_clk_src_hubk07,
	nv_clk_src_copy,
	nv_clk_src_daemon,
	nv_clk_src_disp,
	nv_clk_src_vdec,

	nv_clk_src_dom6,

	nv_clk_src_max,
};

struct nouveau_cstate {
	struct list_head head;
	u8  voltage;
	u32 domain[nv_clk_src_max];
};

struct nouveau_pstate {
	struct list_head head;
	struct list_head list; /* c-states */
	struct nouveau_cstate base;
	u8 pstate;
	u8 fanspeed;
};

struct nouveau_clock {
	struct nouveau_subdev base;

	struct nouveau_clocks *domains;
	struct nouveau_pstate bstate;

	struct list_head states;
	int state_nr;

	struct work_struct work;
	wait_queue_head_t wait;
	atomic_t waiting;

	struct nvkm_notify pwrsrc_ntfy;
	int pwrsrc;
	int pstate; /* current */
	int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
	int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
	int astate; /* perfmon adjustment (base) */
	int tstate; /* thermal adjustment (max-) */
	int dstate; /* display adjustment (min+) */

	bool allow_reclock;

	int  (*read)(struct nouveau_clock *, enum nv_clk_src);
	int  (*calc)(struct nouveau_clock *, struct nouveau_cstate *);
	int  (*prog)(struct nouveau_clock *);
	void (*tidy)(struct nouveau_clock *);

	/*XXX: die, these are here *only* to support the completely
	 *     bat-shit insane what-was-nouveau_hw.c code
	 */
	int (*pll_calc)(struct nouveau_clock *, struct nvbios_pll *,
			int clk, struct nouveau_pll_vals *pv);
	int (*pll_prog)(struct nouveau_clock *, u32 reg1,
			struct nouveau_pll_vals *pv);
};

static inline struct nouveau_clock *
nouveau_clock(void *obj)
{
	return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_CLOCK];
}

struct nouveau_clocks {
	enum nv_clk_src name;
	u8 bios; /* 0xff for none */
#define NVKM_CLK_DOM_FLAG_CORE 0x01
	u8 flags;
	const char *mname;
	int mdiv;
};

#define nouveau_clock_create(p,e,o,i,r,s,n,d)                                  \
	nouveau_clock_create_((p), (e), (o), (i), (r), (s), (n), sizeof(**d),  \
			      (void **)d)
#define nouveau_clock_destroy(p) ({                                            \
	struct nouveau_clock *clk = (p);                                       \
	_nouveau_clock_dtor(nv_object(clk));                                   \
})
#define nouveau_clock_init(p) ({                                               \
	struct nouveau_clock *clk = (p);                                       \
	_nouveau_clock_init(nv_object(clk));                                   \
})
#define nouveau_clock_fini(p,s) ({                                             \
	struct nouveau_clock *clk = (p);                                       \
	_nouveau_clock_fini(nv_object(clk), (s));                              \
})

int  nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
			   struct nouveau_oclass *,
			   struct nouveau_clocks *, struct nouveau_pstate *,
			   int, bool, int, void **);
void _nouveau_clock_dtor(struct nouveau_object *);
int  _nouveau_clock_init(struct nouveau_object *);
int  _nouveau_clock_fini(struct nouveau_object *, bool);

extern struct nouveau_oclass nv04_clock_oclass;
extern struct nouveau_oclass nv40_clock_oclass;
extern struct nouveau_oclass *nv50_clock_oclass;
extern struct nouveau_oclass *nv84_clock_oclass;
extern struct nouveau_oclass *nvaa_clock_oclass;
extern struct nouveau_oclass nva3_clock_oclass;
extern struct nouveau_oclass nvc0_clock_oclass;
extern struct nouveau_oclass nve0_clock_oclass;
extern struct nouveau_oclass gk20a_clock_oclass;

int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq);
int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
			int clk, struct nouveau_pll_vals *);
int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
			struct nouveau_pll_vals *);
int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
			int clk, struct nouveau_pll_vals *);

int nouveau_clock_ustate(struct nouveau_clock *, int req, int pwr);
int nouveau_clock_astate(struct nouveau_clock *, int req, int rel);
int nouveau_clock_dstate(struct nouveau_clock *, int req, int rel);
int nouveau_clock_tstate(struct nouveau_clock *, int req, int rel);

#endif