Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / nouveau / core / include / subdev / clock.h
1 #ifndef __NOUVEAU_CLOCK_H__
2 #define __NOUVEAU_CLOCK_H__
3
4 #include <core/device.h>
5 #include <core/subdev.h>
6
7 struct nouveau_pll_vals;
8 struct nvbios_pll;
9
10 enum nv_clk_src {
11         nv_clk_src_crystal,
12         nv_clk_src_href,
13
14         nv_clk_src_hclk,
15         nv_clk_src_hclkm3,
16         nv_clk_src_hclkm3d2,
17         nv_clk_src_hclkm2d3, /* NVAA */
18         nv_clk_src_hclkm4, /* NVAA */
19         nv_clk_src_cclk, /* NVAA */
20
21         nv_clk_src_host,
22
23         nv_clk_src_sppll0,
24         nv_clk_src_sppll1,
25
26         nv_clk_src_mpllsrcref,
27         nv_clk_src_mpllsrc,
28         nv_clk_src_mpll,
29         nv_clk_src_mdiv,
30
31         nv_clk_src_core,
32         nv_clk_src_shader,
33
34         nv_clk_src_mem,
35
36         nv_clk_src_gpc,
37         nv_clk_src_rop,
38         nv_clk_src_hubk01,
39         nv_clk_src_hubk06,
40         nv_clk_src_hubk07,
41         nv_clk_src_copy,
42         nv_clk_src_daemon,
43         nv_clk_src_disp,
44         nv_clk_src_vdec,
45
46         nv_clk_src_dom6,
47
48         nv_clk_src_max,
49 };
50
51 struct nouveau_cstate {
52         struct list_head head;
53         u8  voltage;
54         u32 domain[nv_clk_src_max];
55 };
56
57 struct nouveau_pstate {
58         struct list_head head;
59         struct list_head list; /* c-states */
60         struct nouveau_cstate base;
61         u8 pstate;
62         u8 fanspeed;
63 };
64
65 struct nouveau_clock {
66         struct nouveau_subdev base;
67
68         struct nouveau_clocks *domains;
69         struct nouveau_pstate bstate;
70
71         struct list_head states;
72         int state_nr;
73
74         struct work_struct work;
75         wait_queue_head_t wait;
76         atomic_t waiting;
77
78         struct nvkm_notify pwrsrc_ntfy;
79         int pwrsrc;
80         int pstate; /* current */
81         int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
82         int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
83         int astate; /* perfmon adjustment (base) */
84         int tstate; /* thermal adjustment (max-) */
85         int dstate; /* display adjustment (min+) */
86
87         bool allow_reclock;
88
89         int  (*read)(struct nouveau_clock *, enum nv_clk_src);
90         int  (*calc)(struct nouveau_clock *, struct nouveau_cstate *);
91         int  (*prog)(struct nouveau_clock *);
92         void (*tidy)(struct nouveau_clock *);
93
94         /*XXX: die, these are here *only* to support the completely
95          *     bat-shit insane what-was-nouveau_hw.c code
96          */
97         int (*pll_calc)(struct nouveau_clock *, struct nvbios_pll *,
98                         int clk, struct nouveau_pll_vals *pv);
99         int (*pll_prog)(struct nouveau_clock *, u32 reg1,
100                         struct nouveau_pll_vals *pv);
101 };
102
103 static inline struct nouveau_clock *
104 nouveau_clock(void *obj)
105 {
106         return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_CLOCK];
107 }
108
109 struct nouveau_clocks {
110         enum nv_clk_src name;
111         u8 bios; /* 0xff for none */
112 #define NVKM_CLK_DOM_FLAG_CORE 0x01
113         u8 flags;
114         const char *mname;
115         int mdiv;
116 };
117
118 #define nouveau_clock_create(p,e,o,i,r,s,n,d)                                  \
119         nouveau_clock_create_((p), (e), (o), (i), (r), (s), (n), sizeof(**d),  \
120                               (void **)d)
121 #define nouveau_clock_destroy(p) ({                                            \
122         struct nouveau_clock *clk = (p);                                       \
123         _nouveau_clock_dtor(nv_object(clk));                                   \
124 })
125 #define nouveau_clock_init(p) ({                                               \
126         struct nouveau_clock *clk = (p);                                       \
127         _nouveau_clock_init(nv_object(clk));                                   \
128 })
129 #define nouveau_clock_fini(p,s) ({                                             \
130         struct nouveau_clock *clk = (p);                                       \
131         _nouveau_clock_fini(nv_object(clk), (s));                              \
132 })
133
134 int  nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
135                            struct nouveau_oclass *,
136                            struct nouveau_clocks *, struct nouveau_pstate *,
137                            int, bool, int, void **);
138 void _nouveau_clock_dtor(struct nouveau_object *);
139 int  _nouveau_clock_init(struct nouveau_object *);
140 int  _nouveau_clock_fini(struct nouveau_object *, bool);
141
142 extern struct nouveau_oclass nv04_clock_oclass;
143 extern struct nouveau_oclass nv40_clock_oclass;
144 extern struct nouveau_oclass *nv50_clock_oclass;
145 extern struct nouveau_oclass *nv84_clock_oclass;
146 extern struct nouveau_oclass *nvaa_clock_oclass;
147 extern struct nouveau_oclass nva3_clock_oclass;
148 extern struct nouveau_oclass nvc0_clock_oclass;
149 extern struct nouveau_oclass nve0_clock_oclass;
150 extern struct nouveau_oclass gk20a_clock_oclass;
151
152 int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq);
153 int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
154                         int clk, struct nouveau_pll_vals *);
155 int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
156                         struct nouveau_pll_vals *);
157 int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
158                         int clk, struct nouveau_pll_vals *);
159
160 int nouveau_clock_ustate(struct nouveau_clock *, int req, int pwr);
161 int nouveau_clock_astate(struct nouveau_clock *, int req, int rel);
162 int nouveau_clock_dstate(struct nouveau_clock *, int req, int rel);
163 int nouveau_clock_tstate(struct nouveau_clock *, int req, int rel);
164
165 #endif