1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 1999-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef _NV_PRIV_H_
25 #define _NV_PRIV_H_
26 
27 #include <nv.h>
28 #include <os/os.h>
29 #include <ctrl/ctrl402c.h>
30 #include <gpu/disp/kern_disp_max.h>
31 #include <gpu/disp/kern_disp_type.h>
32 
33 #define NV_PRIV_REG_WR08(b,o,d)   (*((volatile NvV8*)&(b)->Reg008[(o)/1])=(NvV8)(d))
34 #define NV_PRIV_REG_WR16(b,o,d)   (*((volatile NvV16*)&(b)->Reg016[(o)/2])=(NvV16)(d))
35 #define NV_PRIV_REG_WR32(b,o,d)   (*((volatile NvV32*)&(b)->Reg032[(o)/4])=(NvV32)(d))
36 
37 #define NV_PRIV_REG_RD08(b,o)     ((b)->Reg008[(o)/1])
38 #define NV_PRIV_REG_RD16(b,o)     ((b)->Reg016[(o)/2])
39 #define NV_PRIV_REG_RD32(b,o)     ((b)->Reg032[(o)/4])
40 
41 struct OBJGPU;
42 
43 typedef struct
44 {
45     NvBool              baseValid;
46     VGAADDRDESC         base;
47     NvBool              workspaceBaseValid;
48     VGAADDRDESC         workspaceBase;
49     NvU32               vesaMode;
50 } nv_vga_t;
51 
52 /*
53 * device state during Power Management
54 */
55 typedef struct nv_pm_state_s
56 {
57     NvU32  IntrEn;
58     NvBool InHibernate;
59 } nv_pm_state_t;
60 
61 /*
62 * data structure for the UNIX workqueues
63 */
64 typedef struct nv_work_item_s
65 {
66     NvU32   flags;
67     NvU32   gpuInstance;
68     union
69     {
70         OSWorkItemFunction *pGpuFunction;
71         OSSystemWorkItemFunction *pSystemFunction;
72     } func;
73     void *pData;
74 } nv_work_item_t;
75 
76 #define NV_WORK_ITEM_FLAGS_NONE             0x0
77 #define NV_WORK_ITEM_FLAGS_REQUIRES_GPU     0x1
78 #define NV_WORK_ITEM_FLAGS_DONT_FREE_DATA   0x2
79 
80 #define INVALID_DISP_ID 0xFFFFFFFF
81 #define MAX_DISP_ID_PER_ADAPTER 0x2
82 
83 typedef struct nv_i2c_adapter_entry_s
84 {
85     void  *pOsAdapter;
86     NvU32  port;
87     NvU32  displayId[MAX_DISP_ID_PER_ADAPTER];
88 } nv_i2c_adapter_entry_t;
89 
90 #define NV_INIT_FLAG_HAL                  0x0001
91 #define NV_INIT_FLAG_HAL_COMPONENTS       0x0002
92 #define NV_INIT_FLAG_GPU_STATE            0x0004
93 #define NV_INIT_FLAG_GPU_STATE_LOAD       0x0008
94 #define NV_INIT_FLAG_FIFO_WATCHDOG        0x0010
95 #define NV_INIT_FLAG_CORE_LOGIC           0x0020
96 #define NV_INIT_FLAG_GPUMGR_ATTACH        0x0040
97 #define NV_INIT_FLAG_PUBLIC_I2C           0x0080
98 #define NV_INIT_FLAG_SCALABILITY          0x0100
99 #define NV_INIT_FLAG_DMA                  0x0200
100 
101 #define MAX_I2C_ADAPTERS    NV402C_CTRL_NUM_I2C_PORTS
102 
103 /*
104  * GPU dynamic power state machine.
105  *
106  * The GPU is in exactly one of these states at at time.  Only certain state
107  * transitions are valid, as documented by the DAGs below.
108  *
109  * When in "instant idle" or COARSE mode:
110  *
111  *                   +----------------------+
112  *                   v                      |
113  * +---------+     +----------------+     +--------+
114  * | UNKNOWN | --> | IDLE_INDICATED | --> | IN_USE |
115  * +---------+     +----------------+     +--------+
116  *
117  * The transition from UNKNOWN to IDLE_INDICATED happens in
118  * rm_init_dynamic_power_management().
119  *
120  * Thereafter, transitions from IDLE_INDICATED to IN_USE happen when
121  * os_ref_dynamic_power() is called and the refcount transitions from 0 to 1;
122  * transitions from IN_USE to IDLE_INDICATED happen when
123  * os_unref_dynamic_power() is called and the refcount transitions from 1 to 0.
124  * Note that only calls to os_(un)ref_dynamic_power() with the mode == COARSE
125  * are considered in this mode; calls with mode == FINE are ignored.  Since
126  * COARSE calls are placed only in rm_init_adapter/rm_shutdown_adapter, the GPU
127  * effectively stays in the IN_USE state any time any client has initialized
128  * it.
129  *
130  *
131  * When in "deferred idle" or FINE mode:
132  *
133  *  +----------------------------------------------------------------+
134  *  |                                                                |
135  *  |                                                                |
136  *  |                    +-------------------------------------------+----------------------+
137  *  |                    |                                           |                      v
138  *  |  +---------+     +----------------+     +--------------+     +----------------+     +--------+
139  *  |  | UNKNOWN | --> | IDLE_INDICATED | --> |              | --> | IDLE_SUSTAINED | --> | IN_USE | -+
140  *  |  +---------+     +----------------+     |              |     +----------------+     +--------+  |
141  *  |                    ^                    |              |       |                      ^         |
142  *  +--------------------+                    | IDLE_INSTANT | ------+----------------------+         |
143  *                                            |              |       |                                |
144  *                                            |              |       |                                |
145  *                                            |              | <-----+                                |
146  *                                            +--------------+                                        |
147  *                                              ^                                                     |
148  *                                              +-----------------------------------------------------+
149  *
150  * As before, the transition from UNKNOWN to IDLE_INDICATED happens in
151  * rm_init_dynamic_power_management().  This is not ideal: it means the GPU may
152  * be powered down immediately upon loading the RM module, even if
153  * rm_init_adapter() is going to be called soon thereafter.  However, we can't
154  * rely on deferred idle callbacks yet, since those currently rely on core RM
155  * being initialized.
156  *
157  * At the beginning of rm_init_adapter(), the GPU transitions to the IN_USE
158  * state; during the rm_init_adapter() sequence,
159  * RmInitDeferredDynamicPowerManagement() will be called which will schedule
160  * timer callbacks and set the "deferred_idle_enabled" boolean.
161  *
162  * While in "deferred idle" mode, one of the callbacks
163  * timerCallbackForIdlePreConditions(), timerCallbackToIndicateIdle(), or
164  * RmIndicateIdle() should be scheduled when in the states:
165  * - IN_USE
166  * - IDLE_INSTANT
167  * - IDLE_SUSTAINED
168  * Note that since we may transition from IN_USE to IDLE_INSTANT rapidly (e.g.,
169  * for a series of RM calls), we don't attempt to schedule the callbacks and
170  * cancel them on each of these transitions.  The
171  * timerCallbackForIdlePreConditions() callback will simply exit early if in
172  * the IN_USE state.
173  *
174  * As before, the GPU will remain in the IN_USE state until
175  * os_unref_dynamic_power() is called and the count transitions from 1 to 0
176  * (calls with mode == FINE are honored, in this mode, and these transitions
177  * can happen frequently).  When the refcount reaches 0, rather than going
178  * directly to the IDLE_INDICATED state, it transitions to the IDLE_INSTANT
179  * state.
180  *
181  * Then, when the next timerCallbackForIdlePreConditions() callback executes,
182  * if all preconditions are met, the state will transition to IDLE_SUSTAINED.
183  *
184  * If, when in the IDLE_SUSTAINED state, os_ref_dynamic_power() is called, the
185  * GPU will transition back to the IN_USE state and return to the IDLE_INSTANT
186  * state.  This ensures that there is a suitable delay between any activity
187  * that requires bumping the refcount and indicating idleness.
188  *
189  * If the timerCallbackForIdlePreConditions() callback executes again and the
190  * GPU is still in the IDLE_SUSTAINED state, userspace mappings will be revoked
191  * and the timerCallbackToIndicateIdle() callback will be scheduled.
192  *
193  * If, before the timerCallbackToIndicateIdle() callback executes, either
194  * os_ref_dynamic_power() is called or a mapping which has been revoked is
195  * accessed (which triggers the RmForceGpuNotIdle() callback), the GPU will
196  * transition back to the IN_USE or IDLE_INSTANT state, respectively.
197  *
198  * Then, when the timerCallbackToIndicateIdle() callback executes, if all
199  * mappings are still revoked, and the GPU is still in the IDLE_SUSTAINED
200  * state, and all GPU idleness preconditions remain satisfied, the
201  * RmIndicateIdle() work item will be enqueued.  (Else, the GPU will transition
202  * back to the IDLE_INSTANT state and the callback for preconditions is
203  * scheduled again.)
204  *
205  * Finally, once the RmIndicateIdle() work item is called, if all of the same
206  * conditions still hold, the state will transition to IDLE_INDICATED.  No
207  * callbacks will be scheduled from here; the callbacks for preconditions
208  * should be re-scheduled when transitioning out of the IDLE_INDICATED state.
209  *
210  * Once in the IDLE_INDICATED state, the kernel is free to call the RM to
211  * perform the GC6 entry sequence then turn off power to the GPU (although it
212  * may not, if the audio function is being used for example).
213  *
214  * There are two paths to exit the IDLE_INDICATED state:
215  * (a) If os_ref_dynamic_power() is called, in which case it transitions
216  *     directly to the IN_USE state;
217  * (b) If RmForceGpuNotIdle() is called, in which case it transitions back to
218  *     the IDLE_INSTANT state.
219  */
220 typedef enum
221 {
222     NV_DYNAMIC_POWER_STATE_UNKNOWN = 0,
223 
224     NV_DYNAMIC_POWER_STATE_IN_USE,
225 
226     NV_DYNAMIC_POWER_STATE_IDLE_INSTANT,
227     NV_DYNAMIC_POWER_STATE_IDLE_SUSTAINED,
228     NV_DYNAMIC_POWER_STATE_IDLE_INDICATED,
229 } nv_dynamic_power_state_t;
230 
231 typedef struct nv_dynamic_power_s
232 {
233     /*
234      * mode is read without the mutex -- should be read-only outside of
235      * rm_init_dynamic_power_management, called during probe only.
236      */
237     nv_dynamic_power_mode_t mode;
238     /*
239      * Whether to indicate idle immediately when the refcount reaches 0, or
240      * only go to the IDLE_INSTANT state, and expect timer callbacks to
241      * transition through IDLE_SUSTAINED -> IDLE_INDICATED.
242      */
243     NvBool deferred_idle_enabled;
244 
245     nv_dynamic_power_state_t state;
246     NvS32 refcount;
247 
248     /*
249      * A word on lock ordering.  These locks must be taken in the order:
250      *
251      *      RM API lock > this dynamic_power mutex > RM GPUs lock
252      *
253      * Skipping any of those locks is fine (if they aren't required to protect
254      * whatever state is being accessed or modified), so long as the order is
255      * not violated.
256      */
257     PORT_MUTEX *mutex;
258 
259     /*
260      * callback handles for deferred dynamic power management.
261      */
262     NvP64 idle_precondition_check_event;
263     NvP64 indicate_idle_event;
264     NvBool idle_precondition_check_callback_scheduled;
265 
266     /*
267      * callback handle for kernel initiated gc6 entry/exit.
268      * these will be protected by the gpu lock.
269      */
270     NvP64 remove_idle_holdoff;
271     NvBool b_idle_holdoff;
272 
273     /*
274      * flag set if the platform does not support fine grain dynamic power
275      * management.
276      */
277     NvBool b_fine_not_supported;
278 
279     /*
280      * This flag is used to check if a workitem is queued for
281      * RmQueueIdleSustainedWorkitem().
282      */
283     NvBool b_idle_sustained_workitem_queued;
284 
285     /*
286      * Counter to track clients disallowing GCOFF.
287      */
288     NvU32 clients_gcoff_disallow_refcount;
289 
290     /*
291      * Maximum FB allocation size which can be saved in system memory
292      * while doing GCOFF based dynamic PM.
293      */
294     NvU64 gcoff_max_fb_size;
295 
296     /*
297      * NVreg_DynamicPowerManagement regkey value set by the user
298      */
299     NvU32 dynamic_power_regkey;
300 } nv_dynamic_power_t;
301 
302 typedef struct
303 {
304     OBJGPU *pGpu;
305 
306     NvU32 pmc_boot_0;
307 
308     nv_vga_t vga;
309 
310     NvU32 flags;
311     NvU32 status;
312 
313     nv_i2c_adapter_entry_t i2c_adapters[MAX_I2C_ADAPTERS];
314 
315     void *pVbiosCopy;
316     NvU32 vbiosSize;
317 
318     nv_pm_state_t pm_state;
319 
320     nv_reg_entry_t *pRegistry;
321 
322     nv_dynamic_power_t dynamic_power;
323 
324     /* Flag to check if the GPU needs 4K page isolation. */
325     NvBool b_4k_page_isolation_required;
326 
327     /* Flag to check if GPU mobile config is enabled */
328     NvBool b_mobile_config_enabled;
329 
330     /* Flag to check if S0ix-based power management is enabled. */
331     NvBool s0ix_pm_enabled;
332 
333     /*
334      * Maximum FB allocation size which can be saved in system memory
335      * during system supened with S0ix-based power management.
336      */
337     NvU64 s0ix_gcoff_max_fb_size;
338 
339     NvU32 pmc_boot_1;
340     NvU32 pmc_boot_42;
341 } nv_priv_t;
342 
343 #define NV_SET_NV_PRIV(nv,p) ((nv)->priv = (p))
344 #define NV_GET_NV_PRIV(nv)   ((nv) ? (nv)->priv : NULL)
345 
346 /*
347  * Make sure that your stack has taken API Lock before using this macro.
348  */
349 #define NV_GET_NV_PRIV_PGPU(nv) \
350     (NV_GET_NV_PRIV(nv) ? ((nv_priv_t *)NV_GET_NV_PRIV(nv))->pGpu : NULL)
351 
352 #endif // _NV_PRIV_H_
353