summaryrefslogtreecommitdiff
path: root/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h
blob: 58f615db4333969115b30c09ec43ec104d89c9e7 (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
/*
 *
 * (C) COPYRIGHT 2010-2016 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */





/*
 * Power management API definitions used internally by GPU backend
 */

#ifndef _KBASE_BACKEND_PM_INTERNAL_H_
#define _KBASE_BACKEND_PM_INTERNAL_H_

#include <mali_kbase_hwaccess_pm.h>

#include "mali_kbase_pm_ca.h"
#include "mali_kbase_pm_policy.h"


/**
 * kbase_pm_dev_idle - The GPU is idle.
 *
 * The OS may choose to turn off idle devices
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_dev_idle(struct kbase_device *kbdev);

/**
 * kbase_pm_dev_activate - The GPU is active.
 *
 * The OS should avoid opportunistically turning off the GPU while it is active
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_dev_activate(struct kbase_device *kbdev);

/**
 * kbase_pm_get_present_cores - Get details of the cores that are present in
 *                              the device.
 *
 * This function can be called by the active power policy to return a bitmask of
 * the cores (of a specified type) present in the GPU device and also a count of
 * the number of cores.
 *
 * @kbdev: The kbase device structure for the device (must be a valid
 *         pointer)
 * @type:  The type of core (see the enum kbase_pm_core_type enumeration)
 *
 * Return: The bit mask of cores present
 */
u64 kbase_pm_get_present_cores(struct kbase_device *kbdev,
						enum kbase_pm_core_type type);

/**
 * kbase_pm_get_active_cores - Get details of the cores that are currently
 *                             active in the device.
 *
 * This function can be called by the active power policy to return a bitmask of
 * the cores (of a specified type) that are actively processing work (i.e.
 * turned on *and* busy).
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 * @type:  The type of core (see the enum kbase_pm_core_type enumeration)
 *
 * Return: The bit mask of active cores
 */
u64 kbase_pm_get_active_cores(struct kbase_device *kbdev,
						enum kbase_pm_core_type type);

/**
 * kbase_pm_get_trans_cores - Get details of the cores that are currently
 *                            transitioning between power states.
 *
 * This function can be called by the active power policy to return a bitmask of
 * the cores (of a specified type) that are currently transitioning between
 * power states.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 * @type:  The type of core (see the enum kbase_pm_core_type enumeration)
 *
 * Return: The bit mask of transitioning cores
 */
u64 kbase_pm_get_trans_cores(struct kbase_device *kbdev,
						enum kbase_pm_core_type type);

/**
 * kbase_pm_get_ready_cores - Get details of the cores that are currently
 *                            powered and ready for jobs.
 *
 * This function can be called by the active power policy to return a bitmask of
 * the cores (of a specified type) that are powered and ready for jobs (they may
 * or may not be currently executing jobs).
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 * @type:  The type of core (see the enum kbase_pm_core_type enumeration)
 *
 * Return: The bit mask of ready cores
 */
u64 kbase_pm_get_ready_cores(struct kbase_device *kbdev,
						enum kbase_pm_core_type type);

/**
 * kbase_pm_clock_on - Turn the clock for the device on, and enable device
 *                     interrupts.
 *
 * This function can be used by a power policy to turn the clock for the GPU on.
 * It should be modified during integration to perform the necessary actions to
 * ensure that the GPU is fully powered and clocked.
 *
 * @kbdev:     The kbase device structure for the device (must be a valid
 *             pointer)
 * @is_resume: true if clock on due to resume after suspend, false otherwise
 */
void kbase_pm_clock_on(struct kbase_device *kbdev, bool is_resume);

/**
 * kbase_pm_clock_off - Disable device interrupts, and turn the clock for the
 *                      device off.
 *
 * This function can be used by a power policy to turn the clock for the GPU
 * off. It should be modified during integration to perform the necessary
 * actions to turn the clock off (if this is possible in the integration).
 *
 * @kbdev:      The kbase device structure for the device (must be a valid
 *              pointer)
 * @is_suspend: true if clock off due to suspend, false otherwise
 *
 * Return: true  if clock was turned off, or
 *         false if clock can not be turned off due to pending page/bus fault
 *               workers. Caller must flush MMU workqueues and retry
 */
bool kbase_pm_clock_off(struct kbase_device *kbdev, bool is_suspend);

/**
 * kbase_pm_enable_interrupts - Enable interrupts on the device.
 *
 * Interrupts are also enabled after a call to kbase_pm_clock_on().
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_enable_interrupts(struct kbase_device *kbdev);

/**
 * kbase_pm_disable_interrupts - Disable interrupts on the device.
 *
 * This prevents delivery of Power Management interrupts to the CPU so that
 * kbase_pm_check_transitions_nolock() will not be called from the IRQ handler
 * until kbase_pm_enable_interrupts() or kbase_pm_clock_on() is called.
 *
 * Interrupts are also disabled after a call to kbase_pm_clock_off().
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_disable_interrupts(struct kbase_device *kbdev);

/**
 * kbase_pm_disable_interrupts_nolock - Version of kbase_pm_disable_interrupts()
 *                                      that does not take the hwaccess_lock
 *
 * Caller must hold the hwaccess_lock.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_disable_interrupts_nolock(struct kbase_device *kbdev);

/**
 * kbase_pm_init_hw - Initialize the hardware.
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 * @flags: Flags specifying the type of PM init
 *
 * This function checks the GPU ID register to ensure that the GPU is supported
 * by the driver and performs a reset on the device so that it is in a known
 * state before the device is used.
 *
 * Return: 0 if the device is supported and successfully reset.
 */
int kbase_pm_init_hw(struct kbase_device *kbdev, unsigned int flags);

/**
 * kbase_pm_reset_done - The GPU has been reset successfully.
 *
 * This function must be called by the GPU interrupt handler when the
 * RESET_COMPLETED bit is set. It signals to the power management initialization
 * code that the GPU has been successfully reset.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_reset_done(struct kbase_device *kbdev);


/**
 * kbase_pm_check_transitions_nolock - Check if there are any power transitions
 *                                     to make, and if so start them.
 *
 * This function will check the desired_xx_state members of
 * struct kbase_pm_device_data and the actual status of the hardware to see if
 * any power transitions can be made at this time to make the hardware state
 * closer to the state desired by the power policy.
 *
 * The return value can be used to check whether all the desired cores are
 * available, and so whether it's worth submitting a job (e.g. from a Power
 * Management IRQ).
 *
 * Note that this still returns true when desired_xx_state has no
 * cores. That is: of the no cores desired, none were *un*available. In
 * this case, the caller may still need to try submitting jobs. This is because
 * the Core Availability Policy might have taken us to an intermediate state
 * where no cores are powered, before powering on more cores (e.g. for core
 * rotation)
 *
 * The caller must hold kbase_device.pm.power_change_lock
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 *
 * Return:      non-zero when all desired cores are available. That is,
 *              it's worthwhile for the caller to submit a job.
 *              false otherwise
 */
bool kbase_pm_check_transitions_nolock(struct kbase_device *kbdev);

/**
 * kbase_pm_check_transitions_sync - Synchronous and locking variant of
 *                                   kbase_pm_check_transitions_nolock()
 *
 * On returning, the desired state at the time of the call will have been met.
 *
 * There is nothing to stop the core being switched off by calls to
 * kbase_pm_release_cores() or kbase_pm_unrequest_cores(). Therefore, the
 * caller must have already made a call to
 * kbase_pm_request_cores()/kbase_pm_request_cores_sync() previously.
 *
 * The usual use-case for this is to ensure cores are 'READY' after performing
 * a GPU Reset.
 *
 * Unlike kbase_pm_check_transitions_nolock(), the caller must not hold
 * kbase_device.pm.power_change_lock, because this function will take that
 * lock itself.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_check_transitions_sync(struct kbase_device *kbdev);

/**
 * kbase_pm_update_cores_state_nolock - Variant of kbase_pm_update_cores_state()
 *                                      where the caller must hold
 *                                      kbase_device.pm.power_change_lock
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_update_cores_state_nolock(struct kbase_device *kbdev);

/**
 * kbase_pm_update_cores_state - Update the desired state of shader cores from
 *                               the Power Policy, and begin any power
 *                               transitions.
 *
 * This function will update the desired_xx_state members of
 * struct kbase_pm_device_data by calling into the current Power Policy. It will
 * then begin power transitions to make the hardware acheive the desired shader
 * core state.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_update_cores_state(struct kbase_device *kbdev);

/**
 * kbase_pm_cancel_deferred_poweroff - Cancel any pending requests to power off
 *                                     the GPU and/or shader cores.
 *
 * This should be called by any functions which directly power off the GPU.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_cancel_deferred_poweroff(struct kbase_device *kbdev);

/**
 * kbasep_pm_init_core_use_bitmaps - Initialise data tracking the required
 *                                   and used cores.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbasep_pm_init_core_use_bitmaps(struct kbase_device *kbdev);

/**
 * kbasep_pm_metrics_init - Initialize the metrics gathering framework.
 *
 * This must be called before other metric gathering APIs are called.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 *
 * Return: 0 on success, error code on error
 */
int kbasep_pm_metrics_init(struct kbase_device *kbdev);

/**
 * kbasep_pm_metrics_term - Terminate the metrics gathering framework.
 *
 * This must be called when metric gathering is no longer required. It is an
 * error to call any metrics gathering function (other than
 * kbasep_pm_metrics_init()) after calling this function.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbasep_pm_metrics_term(struct kbase_device *kbdev);

/**
 * kbase_pm_report_vsync - Function to be called by the frame buffer driver to
 *                         update the vsync metric.
 *
 * This function should be called by the frame buffer driver to update whether
 * the system is hitting the vsync target or not. buffer_updated should be true
 * if the vsync corresponded with a new frame being displayed, otherwise it
 * should be false. This function does not need to be called every vsync, but
 * only when the value of @buffer_updated differs from a previous call.
 *
 * @kbdev:          The kbase device structure for the device (must be a
 *                  valid pointer)
 * @buffer_updated: True if the buffer has been updated on this VSync,
 *                  false otherwise
 */
void kbase_pm_report_vsync(struct kbase_device *kbdev, int buffer_updated);

/**
 * kbase_pm_get_dvfs_action - Determine whether the DVFS system should change
 *                            the clock speed of the GPU.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 *
 * This function should be called regularly by the DVFS system to check whether
 * the clock speed of the GPU needs updating.
 */
void kbase_pm_get_dvfs_action(struct kbase_device *kbdev);

/**
 * kbase_pm_request_gpu_cycle_counter - Mark that the GPU cycle counter is
 *                                      needed
 *
 * If the caller is the first caller then the GPU cycle counters will be enabled
 * along with the l2 cache
 *
 * The GPU must be powered when calling this function (i.e.
 * kbase_pm_context_active() must have been called).
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_request_gpu_cycle_counter(struct kbase_device *kbdev);

/**
 * kbase_pm_request_gpu_cycle_counter_l2_is_on - Mark GPU cycle counter is
 *                                               needed (l2 cache already on)
 *
 * This is a version of the above function
 * (kbase_pm_request_gpu_cycle_counter()) suitable for being called when the
 * l2 cache is known to be on and assured to be on until the subsequent call of
 * kbase_pm_release_gpu_cycle_counter() such as when a job is submitted. It does
 * not sleep and can be called from atomic functions.
 *
 * The GPU must be powered when calling this function (i.e.
 * kbase_pm_context_active() must have been called) and the l2 cache must be
 * powered on.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_request_gpu_cycle_counter_l2_is_on(struct kbase_device *kbdev);

/**
 * kbase_pm_release_gpu_cycle_counter - Mark that the GPU cycle counter is no
 *                                      longer in use
 *
 * If the caller is the last caller then the GPU cycle counters will be
 * disabled. A request must have been made before a call to this.
 *
 * Caller must not hold the hwaccess_lock, as it will be taken in this function.
 * If the caller is already holding this lock then
 * kbase_pm_release_gpu_cycle_counter_nolock() must be used instead.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_release_gpu_cycle_counter(struct kbase_device *kbdev);

/**
 * kbase_pm_release_gpu_cycle_counter_nolock - Version of kbase_pm_release_gpu_cycle_counter()
 *                                             that does not take hwaccess_lock
 *
 * Caller must hold the hwaccess_lock.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_release_gpu_cycle_counter_nolock(struct kbase_device *kbdev);

/**
 * kbase_pm_wait_for_poweroff_complete - Wait for the poweroff workqueue to
 *                                       complete
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_wait_for_poweroff_complete(struct kbase_device *kbdev);

/**
 * kbase_pm_register_access_enable - Enable access to GPU registers
 *
 * Enables access to the GPU registers before power management has powered up
 * the GPU with kbase_pm_powerup().
 *
 * Access to registers should be done using kbase_os_reg_read()/write() at this
 * stage, not kbase_reg_read()/write().
 *
 * This results in the power management callbacks provided in the driver
 * configuration to get called to turn on power and/or clocks to the GPU. See
 * kbase_pm_callback_conf.
 *
 * This should only be used before power management is powered up with
 * kbase_pm_powerup()
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_register_access_enable(struct kbase_device *kbdev);

/**
 * kbase_pm_register_access_disable - Disable early register access
 *
 * Disables access to the GPU registers enabled earlier by a call to
 * kbase_pm_register_access_enable().
 *
 * This results in the power management callbacks provided in the driver
 * configuration to get called to turn off power and/or clocks to the GPU. See
 * kbase_pm_callback_conf
 *
 * This should only be used before power management is powered up with
 * kbase_pm_powerup()
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 */
void kbase_pm_register_access_disable(struct kbase_device *kbdev);

/* NOTE: kbase_pm_is_suspending is in mali_kbase.h, because it is an inline
 * function */

/**
 * kbase_pm_metrics_is_active - Check if the power management metrics
 *                              collection is active.
 *
 * Note that this returns if the power management metrics collection was
 * active at the time of calling, it is possible that after the call the metrics
 * collection enable may have changed state.
 *
 * The caller must handle the consequence that the state may have changed.
 *
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 * Return: true if metrics collection was active else false.
 */
bool kbase_pm_metrics_is_active(struct kbase_device *kbdev);

/**
 * kbase_pm_do_poweron - Power on the GPU, and any cores that are requested.
 *
 * @kbdev:     The kbase device structure for the device (must be a valid
 *             pointer)
 * @is_resume: true if power on due to resume after suspend,
 *             false otherwise
 */
void kbase_pm_do_poweron(struct kbase_device *kbdev, bool is_resume);

/**
 * kbase_pm_do_poweroff - Power off the GPU, and any cores that have been
 *                        requested.
 *
 * @kbdev:      The kbase device structure for the device (must be a valid
 *              pointer)
 * @is_suspend: true if power off due to suspend,
 *              false otherwise
 */
void kbase_pm_do_poweroff(struct kbase_device *kbdev, bool is_suspend);

#ifdef CONFIG_PM_DEVFREQ
void kbase_pm_get_dvfs_utilisation(struct kbase_device *kbdev,
		unsigned long *total, unsigned long *busy);
void kbase_pm_reset_dvfs_utilisation(struct kbase_device *kbdev);
#endif

#ifdef CONFIG_MALI_MIDGARD_DVFS

/**
 * kbase_platform_dvfs_event - Report utilisation to DVFS code
 *
 * Function provided by platform specific code when DVFS is enabled to allow
 * the power management metrics system to report utilisation.
 *
 * @kbdev:         The kbase device structure for the device (must be a
 *                 valid pointer)
 * @utilisation:   The current calculated utilisation by the metrics system.
 * @util_gl_share: The current calculated gl share of utilisation.
 * @util_cl_share: The current calculated cl share of utilisation per core
 *                 group.
 * Return:         Returns 0 on failure and non zero on success.
 */

int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation,
	u32 util_gl_share, u32 util_cl_share[2]);
#endif

void kbase_pm_power_changed(struct kbase_device *kbdev);

/**
 * kbase_pm_metrics_update - Inform the metrics system that an atom is either
 *                           about to be run or has just completed.
 * @kbdev: The kbase device structure for the device (must be a valid pointer)
 * @now:   Pointer to the timestamp of the change, or NULL to use current time
 *
 * Caller must hold hwaccess_lock
 */
void kbase_pm_metrics_update(struct kbase_device *kbdev,
				ktime_t *now);

/**
 * kbase_pm_cache_snoop_enable - Allow CPU snoops on the GPU
 * If the GPU does not have coherency this is a no-op
 * @kbdev:	Device pointer
 *
 * This function should be called after L2 power up.
 */

void kbase_pm_cache_snoop_enable(struct kbase_device *kbdev);

/**
 * kbase_pm_cache_snoop_disable - Prevent CPU snoops on the GPU
 * If the GPU does not have coherency this is a no-op
 * @kbdev:	Device pointer
 *
 * This function should be called before L2 power off.
 */
void kbase_pm_cache_snoop_disable(struct kbase_device *kbdev);

#endif /* _KBASE_BACKEND_PM_INTERNAL_H_ */