summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/include/nvrm_power.h
blob: 34b3b335d40f920eeadf41e26b658ff356211c29 (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
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
/*
 * Copyright (c) 2009 NVIDIA Corporation.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the NVIDIA Corporation nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef INCLUDED_nvrm_power_H
#define INCLUDED_nvrm_power_H


#if defined(__cplusplus)
extern "C"
{
#endif

#include "nvrm_module.h"
#include "nvrm_init.h"

#include "nvos.h"

/**
 * Frequency data type, expressed in KHz.
 */

typedef NvU32 NvRmFreqKHz;

/**
 * Special value for an unspecified or default frequency.
 */
static const NvRmFreqKHz NvRmFreqUnspecified = 0xFFFFFFFF;

/**
 * Special value for the maximum possible frequency.
 */
static const NvRmFreqKHz NvRmFreqMaximum = 0xFFFFFFFD;

/**
 * Voltage data type, expressed in millivolts.
 */

typedef NvU32 NvRmMilliVolts;

/**
 * Special value for an unspecified or default voltage.
 */
static const NvRmMilliVolts NvRmVoltsUnspecified = 0xFFFFFFFF;

/**
 * Special value for the maximum possible voltage.
 */
static const NvRmMilliVolts NvRmVoltsMaximum = 0xFFFFFFFD;

/**
 * Special value for voltage / power disable.
 */
static const NvRmMilliVolts NvRmVoltsCycled = 0xFFFFFFFC;

/**
 * Special value for voltage / power disable.
 */
static const NvRmMilliVolts NvRmVoltsOff = 0;

/**
 * Defines possible power management events
 */

typedef enum
{

    /// Specifies no outstanding events
        NvRmPowerEvent_NoEvent = 1,

    /// Specifies wake from LP0
        NvRmPowerEvent_WakeLP0,

    /// Specifies wake from LP1
        NvRmPowerEvent_WakeLP1,
    NvRmPowerEvent_Num,
    NvRmPowerEvent_Force32 = 0x7FFFFFFF
} NvRmPowerEvent;

/**
 * Defines combined RM clients power state
 */

typedef enum
{

    /// Specifies boot state ("RM is not open, yet")
        NvRmPowerState_Boot = 1,

    /// Specifies active state ("not ready-to-suspend")
    /// This state is entered if any client enables power to any module, other
    /// than NvRmPrivModuleID_System, via NvRmPowerVoltageControl() API
        NvRmPowerState_Active,

    /// Specifies h/w autonomous state ("ready-to-core-power-on-suspend")
    /// This state is entered if all RM clients enable power only for
    /// NvRmPrivModuleID_System, via NvRmPowerVoltageControl() API
        NvRmPowerState_AutoHw,

    /// Specifies idle state ("ready-to-core-power-off-suspend")
    /// This state is entered if none of the RM clients enables power
    /// to any module.
        NvRmPowerState_Idle,

    /// Specifies LP0 state ("main power-off suspend")
        NvRmPowerState_LP0,

    /// Specifies LP1 state ("main power-on suspend")
        NvRmPowerState_LP1,

    /// Specifies Skipped LP0 state (set when LP0 entry error is
    /// detected, SoC resumes operations without entering LP0 state)
        NvRmPowerState_SkippedLP0,
    NvRmPowerState_Num,
    NvRmPowerState_Force32 = 0x7FFFFFFF
} NvRmPowerState;

/** Defines the clock configuration flags which are applicable for some modules.
 * Multiple flags can be OR'ed and passed to the NvRmPowerModuleClockConfig API.
*/

typedef enum
{

    /// Use external clock for the pads of the module.
        NvRmClockConfig_ExternalClockForPads = 0x1,

    /// Use internal clock for the pads of the module
        NvRmClockConfig_InternalClockForPads = 0x2,

    /// Use external clock for the core of the module, or
    /// module is in slave mode
        NvRmClockConfig_ExternalClockForCore = 0x4,

    /// Use Internal clock for the core of the module, or
    /// module is in master mode.
        NvRmClockConfig_InternalClockForCore = 0x8,
 
    /// Use inverted clock for the module. i.e the polarity of the clock used is
    /// inverted with respect to the source clock.
        NvRmClockConfig_InvertedClock = 0x10,
 
    /// Configure target module sub-clock
    /// - Target Display: configure Display and TVDAC
    /// - Target TVO: configure CVE and TVDAC only
    /// - Target VI: configure VI_SENSOR only
    /// - Target SPDIF: configure SPDIFIN only
        NvRmClockConfig_SubConfig = 0x20,
 
    /// Select MIPI PLL as clock source
    /// - Target Display:
    ///  (a) NvRmClockConfig_InternalClockForPads is also specified -
    ///      use MIPI PLL for pixel clock source, preserve PLL configuration
    ///  (b) NvRmClockConfig_InternalClockForPads is not specified -
    ///      use MIPI PLL for pixel clock source, re-configure it if necessary
    /// - Target HDMI: use MIPI PLL as HDMI clock source
        NvRmClockConfig_MipiSync = 0x40,
 
    /// Adjust Audio PLL to match requested I2S or SPDIF frequency
        NvRmClockConfig_AudioAdjust = 0x80,
 
    /// Disable TVDAC along with Display configuration
        NvRmClockConfig_DisableTvDAC = 0x100,
 
    /// Do not fail clock configuration request with specific target frequency
    /// above Hw limit - just configure clock at Hw limit. (Note that caller
    /// can request NvRmFreqMaximum to configure clock at Hw limit, regardless
    /// of this flag presence).
        NvRmClockConfig_QuietOverClock = 0x200,
    NvRmClockConfigFlags_Num,
    NvRmClockConfigFlags_Force32 = 0x7FFFFFFF
} NvRmClockConfigFlags;

/**
 * Defines SOC-wide clocks controlled by Dynamic Frequency Scaling (DFS)
 * that can be targeted by Starvation and Busy hints
 */

typedef enum
{

    /// Specifies CPU clock
        NvRmDfsClockId_Cpu = 1,

    /// Specifies AVP clock
        NvRmDfsClockId_Avp,

    /// Specifies System bus clock
        NvRmDfsClockId_System,

    /// Specifies AHB bus clock
        NvRmDfsClockId_Ahb,

    /// Specifies APB bus clock
        NvRmDfsClockId_Apb,

    /// Specifies video pipe clock
        NvRmDfsClockId_Vpipe,

    /// Specifies external memory controller clock
        NvRmDfsClockId_Emc,
    NvRmDfsClockId_Num,
    NvRmDfsClockId_Force32 = 0x7FFFFFFF
} NvRmDfsClockId;

/**
 * Defines DFS manager run states
 */

typedef enum
{

    /// DFS is in invalid, not initialized state
        NvRmDfsRunState_Invalid = 0,

    /// DFS is disabled / not supported (terminal state)
        NvRmDfsRunState_Disabled = 1,

    /// DFS is stopped - no automatic clock control. Starvation and Busy hints
    /// are recorded but have no affect.
        NvRmDfsRunState_Stopped,

    /// DFS is running in closed loop - full automatic control of SoC-wide
    /// clocks based on clock activity measuremnets. Starvation and Busy hints
    /// are functional as well.
        NvRmDfsRunState_ClosedLoop,

    /// DFS is running in closed loop with profiling (can not be set on non
    /// profiling build).
        NvRmDfsRunState_ProfiledLoop,
    NvRmDfsRunState_Num,
    NvRmDfsRunState_Force32 = 0x7FFFFFFF
} NvRmDfsRunState;

/**
 * Defines DFS profile targets
 */

typedef enum
{

    /// DFS algorithm within ISR
        NvRmDfsProfileId_Algorithm = 1,

    /// DFS Interrupt service - includes algorithm plus OS locking and
    ///  signaling calls; hence, includes blocking time (if any) as well
        NvRmDfsProfileId_Isr,

    /// DFS clock control time - includes PLL stabilazation time, OS locking
    /// and signalling calls; hence, includes blocking time (if any) as well 
        NvRmDfsProfileId_Control,
    NvRmDfsProfileId_Num,
    NvRmDfsProfileId_Force32 = 0x7FFFFFFF
} NvRmDfsProfileId;

/**
 * Defines voltage rails that are controlled in conjunction with dynamic
 * frequency scaling.
 */

typedef enum
{

    /// SoC core rail
        NvRmDfsVoltageRailId_Core = 1,

    /// Dedicated CPU rail
        NvRmDfsVoltageRailId_Cpu,
    NvRmDfsVoltageRailId_Num,
    NvRmDfsVoltageRailId_Force32 = 0x7FFFFFFF
} NvRmDfsVoltageRailId;

/**
 * Defines busy hint API synchronization modes.
 */

typedef enum
{

    /// Asynchronous mode (non-blocking API)
        NvRmDfsBusyHintSyncMode_Async = 1,

    /// Synchronous mode (blocking API)
        NvRmDfsBusyHintSyncMode_Sync,
    NvRmDfsBusyHintSyncMode_Num,
    NvRmDfsBusyHintSyncMode_Force32 = 0x7FFFFFFF
} NvRmDfsBusyHintSyncMode;

/**
 * Holds information on DFS clock domain utilization
 */

typedef struct NvRmDfsClockUsageRec
{

    /// Minimum clock domain frequency
        NvRmFreqKHz MinKHz;

    /// Maximum clock domain frequency
        NvRmFreqKHz MaxKHz;

    /// Low corner frequency - current low boundary for DFS control algorithm.
    /// Can be dynamically adjusted via APIs: NvRmDfsSetLowCorner() for all DFS
    /// domains, NvRmDfsSetCpuEnvelope() for CPU, and NvRmDfsSetEmcEnvelope()
    /// for EMC. When all DFS domains hit low corner, DFS stops waking up CPU
    ///  from low power state.
        NvRmFreqKHz LowCornerKHz;

    /// High corner frequency - current high boundary for DFS control algorithm.
    /// Can be dynamically adjusted via APIs: NvRmDfsSetCpuEnvelope() for Cpu,
    /// NvRmDfsSetEmcEnvelope() for Emc, and NvRmDfsSetAvHighCorner() for other
    //  DFS domains.
        NvRmFreqKHz HighCornerKHz;

    /// Current clock domain frequency
        NvRmFreqKHz CurrentKHz;

    /// Average frequency of domain *activity* (not average frequency). For
    /// domains that do not have activity monitors reported as unspecified.
        NvRmFreqKHz AverageKHz;
} NvRmDfsClockUsage;

/**
 * Holds information on DFS busy hint
 */

typedef struct NvRmDfsBusyHintRec
{

    /// Target clock domain ID
        NvRmDfsClockId ClockId;

    /// Requested boost duration in milliseconds
        NvU32 BoostDurationMs;

    /// Requested clock frequency level in kHz
        NvRmFreqKHz BoostKHz;

    /// Busy pulse mode indicator - if true, busy boost is completely removed
    /// after busy time has expired; if false, DFS will gradually lower domain
    /// frequency after busy boost.
        NvBool BusyAttribute;
} NvRmDfsBusyHint;

/**
 * Holds information on DFS starvation hint
 */

typedef struct NvRmDfsStarvationHintRec
{

    /// Target clock domain ID
        NvRmDfsClockId ClockId;

    /// The starvation indicator for the target domain
        NvBool Starving;
} NvRmDfsStarvationHint;

/**
 * The NVRM_POWER_CLIENT_TAG macro is used to convert ASCII 4-character codes
 * into the 32-bit tag that can be used to identify power manager clients for
 * logging purposes.
 */
#define NVRM_POWER_CLIENT_TAG(a,b,c,d) \
    ((NvU32) ((((a)&0xffUL)<<24UL) |  \
              (((b)&0xffUL)<<16UL) |  \
              (((c)&0xffUL)<< 8UL) |  \
              (((d)&0xffUL))))

/**
 * Registers RM power client.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param hEventSemaphore The client semaphore for power management event
 *  signaling. If null, no events will be signaled to the particular client.
 * @param pClientId A pointer to the storage that on entry contains client
 *  tag (optional), and on exit returns client ID, assigned by power manager.
 *
 * @retval NvSuccess if registration was successful.
 * @retval NvError_InsufficientMemory if failed to allocate memory for client
 *  registration.
 */

 NvError NvRmPowerRegister( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvOsSemaphoreHandle hEventSemaphore,
    NvU32 * pClientId );

/**
 * Unregisters RM power client. Power and clock for the modules enabled by this
 * client are disabled and any starvation or busy requests are cancelled during
 * the unregistration.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ClientId The client ID obtained during registration.
 */

 void NvRmPowerUnRegister( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 ClientId );

/**
 * Gets last detected and not yet retrieved power management event.
 * Returns no outstanding event if no events has been detected since the
 * client registration or the last call to this function.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ClientId The client ID obtained during registration.
 * @param pEvent Output storage pointer for power event identifier.
 *
 * @retval NvSuccess if event identifier was retrieved successfully.
 * @retval NvError_BadValue if specified client ID is not registered.
 */

 NvError NvRmPowerGetEvent( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 ClientId,
    NvRmPowerEvent * pEvent );

/**
 * Notifies RM about power management event. Provides an interface for
 * OS power manager to report system power events to RM.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param Event The event RM power manager is to be aware of.
 */

 void NvRmPowerEventNotify( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmPowerEvent Event );

/**
 * Gets combined RM clients power state.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param pState Output storage pointer for combined RM clients power state.
 *
 * @retval NvSuccess if power state was retrieved successfully.
 */

 NvError NvRmPowerGetState( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmPowerState * pState );

/**
 * Gets SoC primary oscillator/input frequency.
 *
 * @param hRmDeviceHandle The RM device handle.
 *
 * @retval Primary frequency in KHz.
 */

 NvRmFreqKHz NvRmPowerGetPrimaryFrequency( 
    NvRmDeviceHandle hRmDeviceHandle );

/**
 * Gets maximum frequency limit for the module clock.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ModuleId The combined module ID and instance of the target module.
 * 
 * @retval Module clock maximum frequency in KHz.
 */

 NvRmFreqKHz NvRmPowerModuleGetMaxFrequency( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmModuleID ModuleId );

/**
 *  This API is used to set the clock configuration of the module clock.
 *  This API can also be used to query the existing configuration.
 * 
 *  Usage example:
 * 
 *  NvError Error;
 *  NvRmFreqKHz MyFreqKHz = 0;
 *  ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, 0);
 * 
 *  // Get current frequency settings
 *  Error = NvRmPowerModuleClockConfig(RmHandle, ModuleId, ClientId,
 *                                      0, 0, NULL, 0, &MyFreqKHz, 0);
 * 
 * // Set target frequency within HW defined limits
 * MyFreqKHz = TARGET_FREQ;
 * Error = NvRmPowerModuleClockConfig(RmHandle, ModuleId, ClientId,
 *                                    NvRmFreqUnspecified, NvRmFreqUnspecified,
 *                                    &MyFreqKHz, 1, &MyFreqKHz);
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param ModuleId The combined module ID and instance of the target module.
 * @param ClientId The client ID obtained during registration.
 * @param MinFreq Requested minimum frequency for hardware module operation.
 *      If the value is NvRmFreqUnspecified, RM uses the the min freq that this
 *      module can operate. 
 *      If the value specified is more than the Hw minimum, passed value is used.
 *      If the value specified is less than the Hw minimum, it will be clipped to
 *      the HW minimum value.
 * @param MaxFreq Requested maximum frequency for hardware module operation.
 *      If the value is NvRmFreqUnspecified, RM uses the the max freq that this
 *      module can run.
 *      If the value specified is less than the Hw maximum, that value is used.
 *      If the value specified is more than the Hw limit, it will be clipped to
 *      the HW maximum.
 * @param PrefFreqList Pointer to a list of preferred frequencies, sorted in the
 *      decresing order of priority. Use NvRmFreqMaximum to request Hw maximum.
 * @param PrefFreqListCount Number of entries in the PrefFreqList array.
 * @param CurrentFreq Returns the current clock frequency of that module. NULL
 *      is a valid value for this parameter.
 * @param flags Module specific flags. Thse flags are valid only for some
 *      modules. See @NvRmClockConfigFlags
 * 
 * @retval NvSuccess if clock control request completed successfully.
 * @retval NvError_ModuleNotPresent if the module ID or instance is invalid.
 * @retval NvError_NotSupported if failed to configure requested frequency (e.g.,
 *  output frequency for possible divider settings is outside specified range).
 */

 NvError NvRmPowerModuleClockConfig( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmModuleID ModuleId,
    NvU32 ClientId,
    NvRmFreqKHz MinFreq,
    NvRmFreqKHz MaxFreq,
    const NvRmFreqKHz * PrefFreqList,
    NvU32 PrefFreqListCount,
    NvRmFreqKHz * CurrentFreq,
    NvU32 flags );

/**
 *  This API is used to enable and disable the module clock.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ModuleId The combined module ID and instance of the target module.
 * @param ClientId The client ID obtained during registration.
 * @param Enable Enables/diables the module clock.
 * 
 * @retval NvSuccess if the module is enabled.
 * @retval NvError_ModuleNotPresent if the module ID or instance is invalid.
 */

 NvError NvRmPowerModuleClockControl( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmModuleID ModuleId,
    NvU32 ClientId,
    NvBool Enable );

/**
 * Request the voltage range for a hardware module. As power planes are shared
 * between different modules, in the majority of cases the RM will choose the
 * appropriate voltage, and module owners only need to enable or disable power
 * for a module. Enable request is always completed (i.e., voltage is applied
 * to the module) before this function returns. Disable request just means that
 * the client is ready for module power down. Actually the power may be removed
 * within the call or any time later, depending on other client needs and power
 * plane dependencies with other modules.
 * 
 * Assert encountered in debug mode if the module ID or instance is invalid.
 *
 * Usage example:
 * 
 * NvError Error;
 * ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, 0);
 * 
 * // Enable module power
 * Error = NvRmPowerVoltageControl(RmHandle, ModuleId, ClientId,
 *          NvRmVoltsUnspecified, NvRmVoltsUnspecified,
 *          NULL, 0, NULL);
 * 
 * // Disable module power
 * Error = NvRmPowerVoltageControl(RmHandle, ModuleId, ClientId,
 *          NvRmVoltsOff, NvRmVoltsOff,
 *          NULL, 0, NULL);
 * 
 * @param hRmDeviceHandle The RM device handle
 * @param ModuleId The combined module ID and instance of the target module
 * @param ClientId The client ID obtained during registration
 * @param MinVolts Requested minimum voltage for hardware module operation
 * @param MaxVolts Requested maximum voltage for hardware module operation
 *  Set to NvRmVoltsUnspecified when enabling power for a module, or to
 *  NvRmVoltsOff when disabling.
 * @param PrefVoltageList Pointer to a list of preferred voltages, ordered from
 *  lowest to highest, and terminated with a voltage of NvRmVoltsUnspecified.
 *  This parameter is optional - ignored if null.
 * @param PrefVoltageListCount Number of entries in the PrefVoltageList array.
 * @param CurrentVolts Output storage pointer for resulting module voltage.
 *  NvRmVoltsUnspecified is returned if module power is On and was not cycled,
 *   since the last voltage request with the same ClientId and ModuleId;
 *  NvRmVoltsCycled is returned if module power is On but was powered down,
 *   since the last voltage request with the same ClientId and ModuleId;
 *  NvRmVoltsOff  is returned if module power is Off.
 *  This parameter is optional - ignored  if null.
 * 
 * @retval NvSuccess if voltage control request completed successfully.
 * @retval NvError_BadValue if specified client ID is not registered.
 * @retval NvError_InsufficientMemory if failed to allocate memory for
 *  voltage request.
 */

 NvError NvRmPowerVoltageControl( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmModuleID ModuleId,
    NvU32 ClientId,
    NvRmMilliVolts MinVolts,
    NvRmMilliVolts MaxVolts,
    const NvRmMilliVolts * PrefVoltageList,
    NvU32 PrefVoltageListCount,
    NvRmMilliVolts * CurrentVolts );

/**
 * Lists modules registered by power clients for voltage control.
 * 
 * @param pListSize Pointer to the list size. On entry specifies list size
 *  allocated by the caller, on exit - actual number of Ids returned. If
 *  entry size is 0, maximum list size is returned. 
 * @param pIdList Pointer to the list of combined module Id/Instance values
 *  to be filled in by this function. Ignored if input list size is 0.
 * @param pActiveList Pointer to the list of modules Active attributes
 *  to be filled in by this function. Ignored if input list size is 0.
 */                               

 void NvRmListPowerAwareModules( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 * pListSize,
    NvRmModuleID * pIdList,
    NvBool * pActiveList );

/**
 * Requests immediate frequency boost for SOC-wide clocks. In general, the RM
 * DFS manages SOC-wide clocks by measuring the average use of clock cycles,
 * and adjusting clock rates to minimize wasted clocks. It is preferable and
 * expected that modules consume clock cycles at a more-or-less constant rate.
 * Under some circumstances this will not be the case. For example, many cycles
 * may be consumed to prime a new media processing activity. If power client
 * anticipates such circumstances, it may sparingly use this API to alert the RM
 * that a temporary spike in clock usage is about to occur.
 *
 * Usage example:
 * 
 * // Busy hint for CPU clock
 * NvError Error;
 * Error = NvRmPowerBusyHint(RmHandle, NvRmDfsClockId_Cpu, ClientId,
 *          BoostDurationMs, BoostFreqKHz);
 *
 * Clients should not call this API in an attempt to micro-manage a particular
 * clock frequency as that is the responsibility of the RM.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ClockId The DFS ID of the clock targeted by this hint.
 * @param ClientId The client ID obtained during registration.
 * @param BoostDurationMs The estimate of the boost duration in milliseconds.
 *  Use NV_WAIT_INFINITE to specify busy until canceled. Use 0 to request
 *  instantaneous spike in frequency and let DFS to scale down. 
 * @param BoostKHz The requirements for the boosted clock frequency in kHz.
 *  Use NvRmFreqMaximum to request maximum domain frequency. Use 0 to cancel
 *  all busy hints reported by the specified client for the specified domain.
 *
 * @retval NvSuccess if busy request completed successfully.
 * @retval NvError_BadValue if specified client ID is not registered.
 * @retval NvError_InsufficientMemory if failed to allocate memory for
 *  busy hint.
 */

 NvError NvRmPowerBusyHint( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmDfsClockId ClockId,
    NvU32 ClientId,
    NvU32 BoostDurationMs,
    NvRmFreqKHz BoostKHz );

/**
 * Requests immediate frequency boost for multiple SOC-wide clock domains. 
 * @sa NvRmPowerBusyHint() for detailed explanation of busy hint effects. 
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ClientId The client ID obtained during registration.
 * @param pMultiHint Pointer to a list of busy hint records for
 *  targeted clocks.
 * @param NumHints Number of entries in pMultiHint array.
 * @param Mode Synchronization mode. In asynchronous mode this API returns to
 *  the caller after request is signaled to power manager (non-blocking call).
 *  In synchronous mode the API returns after busy hints are processed by power
 *  manager (blocking call).
 * 
 * @note It is recommended to use synchronous mode only when low frequency
 *  may result in functional failure. Otherwise, use asynchronous mode or
 *  NvRmPowerBusyHint API, which is always executed as non-blocking request.
 *  Synchronous mode must not be used by PMU transport.
 * 
 *
 * @retval NvSuccess if busy hint request completed successfully.
 * @retval NvError_BadValue if specified client ID is not registered.
 * @retval NvError_InsufficientMemory if failed to allocate memory for
 *  busy hints.
 */

 NvError NvRmPowerBusyHintMulti( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 ClientId,
    const NvRmDfsBusyHint * pMultiHint,
    NvU32 NumHints,
    NvRmDfsBusyHintSyncMode Mode );

/**
 * Request frequency increase for SOC-wide clock to avoid real-time starvation
 * conditions. Allows modules to contribute to the detection and avoidance of
 * clock starvation for DFS controlled clocks.
 * 
 * This API should be called to indicate starvation threat and also to cancel
 * request when a starvation condition has eased.
 * 
 * @note Although the RM DFS does its best to manage clocks without starving
 * the system for clock cycles, bursty clock usage can occasionally cause
 * short-term clock starvation. One solution is to leave a large enough clock
 * rate guard band such that any possible burst in clock usage will be absorbed.
 * This approach tends to waste clock cycles, and worsen power management.
 * 
 * By allowing power clients to participate in the avoidance of system clock
 * starvation situations, detection responsibility can be moved closer to the
 * hardware buffers and processors where starvation occurs, while leaving the
 * overall dynamic clocking policy to the RM. A typical client would be a module
 * that manages media processing and is able to determine when it is falling
 * behind by watching buffer levels or some other module-specific indicator. In
 * response to the starvation request the RM increases gradually the respective
 * clock frequency until the request vis cancelled by the client.
 * 
 * Usage example:
 * 
 * NvError Error;
 * 
 * // Request CPU clock frequency increase to avoid starvation
 * Error = NvRmPowerStarvationHint(
 *          RmHandle, NvRmDfsClockId_Cpu, ClientId, NV_TRUE);
 * 
 * // Cancel starvation request for CPU clock frequency
 * Error = NvRmPowerStarvationHint(
 *          RmHandle, NvRmDfsClockId_Cpu, ClientId, NV_FALSE);
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param ClockId The DFS ID of the clock targeted by this hint.
 * @param ClientId The client ID obtained during registration.
 * @param Starving The starvation indicator for the target module. If true,
 *  the client is requesting target frequency increase to avoid starvation
 *  If false, the indication is that the imminent starvation is no longer a
 *  concern for this particular client.
 * 
 * @retval NvSuccess if starvation request completed successfully.
 * @retval NvError_BadValue if specified client ID is not registered.
 * @retval NvError_InsufficientMemory if failed to allocate memory for
 *  starvation hint.
 */

 NvError NvRmPowerStarvationHint( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmDfsClockId ClockId,
    NvU32 ClientId,
    NvBool Starving );

/**
 * Request frequency increase for multiple SOC-wide clock domains to avoid
 * real-time starvation conditions.
 * @sa NvRmPowerStarvationHint() for detailed explanation of starvation hint
 * effects.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ClientId The client ID obtained during registration.
 * @param pMultiHint Pointer to a list of starvation hint records for
 *  targeted clocks.
 * @param NumHints Number of entries in pMultiHint array.
 *
 * @retval NvSuccess if starvation hint request completed successfully.
 * @retval NvError_BadValue if specified client ID is not registered.
 * @retval NvError_InsufficientMemory if failed to allocate memory for
 *  starvation hints.
 */

 NvError NvRmPowerStarvationHintMulti( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 ClientId,
    const NvRmDfsStarvationHint * pMultiHint,
    NvU32 NumHints );

/**
 * Notifies the RM about DDK module activity.
 * 
 * @note This function lets DDK modules notify the RM about interesting system
 * activities. Not all modules will need to make this indication, typically only
 * modules involved in user input or output activities. However, with current
 * SOC power management architecture such activities will be detected by the OS
 * adaptation layer, not RM. This API is not removed, just in case, we will find
 * out that RM still need to participate in user activity detection. In general,
 * modules should call this interface sparingly, no more than once every few
 * seconds.
 * 
 * In current power management architecture user activity is handled by OS
 * (nor RM) power manager, and activity API is not used at all.
 * 
 * Assert encountered in debug mode if the module ID or instance is invalid.
 *
 * TODO: Remove this API?
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param ModuleId The combined module ID and instance of the target module.
 * @param ClientId The client ID obtained during registration.
 * @param ActivityDurationMs The duration of the module activity.
 * 
 * For cases when activity is a series of discontinuous events (keypresses, for
 * example), this parameter should simply be set to 1.
 * 
 * For lengthy, continuous activities, this parameter is set to the estimated
 * length of the activity in milliseconds. This can reduce the number of calls
 * made to this API.
 * 
 * A value of 0 in this parameter indicates that the module is not active and
 * can be used to signal the end of a previously estimated continuous activity.
 * 
 * @retval NvSuccess if clock control request completed successfully.
 */

 NvError NvRmPowerActivityHint( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmModuleID ModuleId,
    NvU32 ClientId,
    NvU32 ActivityDurationMs );

/**
 * Gets DFS run sate.
 * 
 * @param hRmDeviceHandle The RM device handle.
 * 
 * @return Current DFS run state.
 */

 NvRmDfsRunState NvRmDfsGetState( 
    NvRmDeviceHandle hRmDeviceHandle );

/**
 * Gets information on DFS controlled clock utilization. If DFS is stopped
 * or disabled the average frequency is always equal to current frequency.
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param ClockId The DFS ID of the clock targeted by this request.
 * @param pClockInfo Output storage pointer for clock utilization information.
 * 
 * @return NvSuccess if clock usage information is returned successfully.
 */

 NvError NvRmDfsGetClockUtilization( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmDfsClockId ClockId,
    NvRmDfsClockUsage * pClockUsage );

/**
 * Sets DFS run state. Allows to stop or re-start DFS as well as switch
 * between open and closed loop operations.
 * 
 * On transition to the DFS stopped state, the DFS clocks are just kept at
 * current frequencies. On transition to DFS run states, DFS sampling data
 * is re-initialized only if originally DFS was stopped. Transition between
 * running states has no additional effects, besides operation mode changes.
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param NewDfsRunState The DFS run state to be set.
 * 
 * @retval NvSuccess if DFS state was set successfully.
 * @retval NvError_NotSupported if DFS was disabled initially, in attempt
 * to disable initially enabled DFS, or in attempt to run profiled loop
 * on non profiling build.
 */

 NvError NvRmDfsSetState( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmDfsRunState NewDfsRunState );

/**
 * Sets DFS low corner frequencies - low boundaries for DFS clocks when DFS.
 * is running. If all DFS domains hit low corner, DFS will no longer wake
 * CPU from low power state.  
 *
 * @note When CPU envelope is set via NvRmDfsSetCpuEnvelope() API the CPU
 *  low corner boundary can not be changed by this function.
 * @note When EMC envelope is set via NvRmDfsSetEmcEnvelope() API the EMC
 *  low corner boundary can not be changed by this function.
 * 
 * Usage example:
 * 
 * NvError Error;
 * NvRmFreqKHz LowCorner[NvRmDfsClockId_Num];
 * 
 * // Fill in low corner array
 * LowCorner[NvRmDfsClockId_Cpu] = NvRmFreqUnspecified;
 * LowCorner[NvRmDfsClockId_Avp] = ... ;
 * LowCorner[NvRmDfsClockId_System] = ...;
 * LowCorner[NvRmDfsClockId_Ahb] = ...;
 * LowCorner[NvRmDfsClockId_Apb] = ...;
 * LowCorner[NvRmDfsClockId_Vpipe] = ...;
 * LowCorner[NvRmDfsClockId_Emc] = ...;
 * 
 * // Set new low corner for domains other than CPU, and preserve CPU boundary
 * Error = NvRmDfsSetLowCorner(RmHandle, NvRmDfsClockId_Num, LowCorner);
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param DfsFreqListCount Number of entries in the pDfsLowFreqList array.
 *  Must be always equal to NvRmDfsClockId_Num.
 * @param pDfsLowFreqList Pointer to a list of low corner frequencies, ordered
 *  according to NvRmDfsClockId enumeration. If the list entry is set to
 *  NvRmFreqUnspecified, the respective low corner boundary is not modified.
 * 
 * @retval NvSuccess if low corner frequencies were updated successfully.
 * @retval NvError_NotSupported if DFS is disabled.
 */

 NvError NvRmDfsSetLowCorner( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 DfsFreqListCount,
    const NvRmFreqKHz * pDfsLowFreqList );

/**
 * Sets DFS target frequencies. If DFS is stopped clocks for the DFS domains
 * will be targeted with the specified frequencies. In any other DFS state
 * this function has no effect.
 *
 * Usage example:
 * 
 * NvError Error;
 * NvRmFreqKHz Target[NvRmDfsClockId_Num];
 * 
 * // Fill in target frequencies array
 * Target[NvRmDfsClockId_Cpu] = ... ;
 * Target[NvRmDfsClockId_Avp] = ... ;
 * Target[NvRmDfsClockId_System] = ...;
 * Target[NvRmDfsClockId_Ahb] = ...;
 * Target[NvRmDfsClockId_Apb] = ...;
 * Target[NvRmDfsClockId_Vpipe] = ...;
 * Target[NvRmDfsClockId_Emc] = ...;
 * 
 * // Set new target
 * Error = NvRmDfsSetTarget(RmHandle, NvRmDfsClockId_Num, Target);
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param DfsFreqListCount Number of entries in the pDfsTargetFreqList array.
 *  Must be always equal to NvRmDfsClockId_Num.
 * @param pDfsTargetFreqList Pointer to a list of target frequencies, ordered
 *  according to NvRmDfsClockId enumeration. If the list entry is set to
 *  NvRmFreqUnspecified, the current domain frequency is used as a target.
 * 
 * @retval NvSuccess if target frequencies were updated successfully.
 * @retval NvError_NotSupported if DFS is not stopped (disabled, or running).
 */

 NvError NvRmDfsSetTarget( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 DfsFreqListCount,
    const NvRmFreqKHz * pDfsTargetFreqList );

/**
 * Sets DFS high and low boundaries for CPU domain clock frequency.
 * 
 * Usage example:
 *
 * NvError Error;
 * 
 * // Set CPU envelope boundaries to LowKHz : HighKHz
 * Error = NvRmDfsSetCpuEnvelope(RmHandle, LowKHz, HighKHz);
 * 
 * // Change CPU envelope high boundary to HighKHz
 * Error = NvRmDfsSetCpuEnvelope(RmHandle, NvRmFreqUnspecified, HighKHz);
 *
 * // Release CPU envelope back to HW limits
 * Error = NvRmDfsSetCpuEnvelope(RmHandle, 0, NvRmFreqMaximum);
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param DfsCpuEnvelopeLowKHz Requested low boundary in kHz.
 * @param DfsCpuEnvelopeHighKHz Requested high limit in kHz.
 * 
 * Envelope parameters are clipped to the HW defined CPU domain range.
 * If envelope parameter is set to NvRmFreqUnspecified, the respective
 * CPU boundary is not modified, unless it violates the new setting for
 * the other boundary; in the latter case both boundaries are set to the
 * new specified value.
 * 
 * @retval NvSuccess if DFS envelope for for CPU domain was updated
 *  successfully.
 * @retval NvError_BadValue if reversed boundaries are specified.
 * @retval NvError_NotSupported if DFS is disabled.
 */

 NvError NvRmDfsSetCpuEnvelope( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmFreqKHz DfsCpuLowCornerKHz,
    NvRmFreqKHz DfsCpuHighCornerKHz );

/**
 * Sets DFS high and low boundaries for EMC domain clock frequency.
 * 
 * Usage example:
 *
 * NvError Error;
 * 
 * // Set EMC envelope boundaries to LowKHz : HighKHz
 * Error = NvRmDfsSetEmcEnvelope(RmHandle, LowKHz, HighKHz);
 * 
 * // Change EMC envelope high boundary to HighKHz
 * Error = NvRmDfsSetEmcEnvelope(RmHandle, NvRmFreqUnspecified, HighKHz);
 *
 * // Release EMC envelope back to HW limits
 * Error = NvRmDfsSetEmcEnvelope(RmHandle, 0, NvRmFreqMaximum);
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param DfsEmcEnvelopeLowKHz Requested low boundary in kHz.
 * @param DfsEmcEnvelopeHighKHz Requested high limit in kHz.
 * 
 * Envelope parameters are clipped to the ODM defined EMC configurations
 * within HW defined EMC domain range. If envelope parameter is set to
 * NvRmFreqUnspecified, the respective EMC boundary is not modified, unless
 * it violates the new setting for the other boundary; in the latter case
 * both boundaries are set to the new specified value.
 * 
 * @retval NvSuccess if DFS envelope for for EMC domain was updated
 *  successfully.
 * @retval NvError_BadValue if reversed boundaries are specified.
 * @retval NvError_NotSupported if DFS is disabled.
 */

 NvError NvRmDfsSetEmcEnvelope( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmFreqKHz DfsEmcLowCornerKHz,
    NvRmFreqKHz DfsEmcHighCornerKHz );

/**
 * Sets DFS high boundaries for CPU and EMC.
 * 
 * @note When either CPU or EMC envelope is set via NvRmDfsSetXxxEnvelope()
 * API, neither CPU nor EMC boundary is changed by this function.
 * 
 * Usage example:
 *
 * NvError Error;
 * 
 * // Set CPU subsystem clock limit to CpuHighKHz and Emc clock limit
 * // to EmcHighKHz
 * Error = NvRmDfsSetCpuEmcHighCorner(RmHandle, CpuHighKHz, EmcHighKHz);
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param DfsCpuHighKHz Requested high boundary in kHz for CPU.
 * @param DfsEmcHighKHz Requested high limit in kHz for EMC.
 * 
 * Requested parameters are clipped to the respective HW defined domain
 * ranges, as well as to ODM defined EMC configurations. If any parameter
 * is set to NvRmFreqUnspecified, the respective boundary is not modified.
 * 
 * @retval NvSuccess if high corner for AV subsystem was updated successfully.
 * @retval NvError_NotSupported if DFS is disabled.
 */

 NvError NvRmDfsSetCpuEmcHighCorner( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmFreqKHz DfsCpuHighKHz,
    NvRmFreqKHz DfsEmcHighKHz );

/**
 * Sets DFS high boundaries for AV subsystem clocks.
 * 
 * Usage example:
 *
 * NvError Error;
 * 
 * // Set AVP clock limit to AvpHighKHz, Vde clock limit to VpipeHighKHz,
 * // and preserve System bus clock limit provided it is above requested
 * // AVP and Vpipe levels.
 * Error = NvRmDfsSetAvHighCorner(
 *          RmHandle, NvRmFreqUnspecified, AvpHighKHz, VpipeHighKHz);
 * 
 *@note System bus clock limit must be always above AvpHighKHz, and above
 * VpipeHighKHz. Therefore it may be adjusted up, as a result of this call,
 * even though, it is marked unspecified.
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param DfsSysHighKHz Requested high boundary in kHz for System bus.
 * @param DfsAvpHighKHz Requested high boundary in kHz for AVP.
 * @param DfsVdeHighCornerKHz Requested high limit in kHz for Vde pipe.
 * 
 * Requested parameter is clipped to the respective HW defined domain
 * range. If  parameter is set to NvRmFreqUnspecified, the respective
 * boundary is not modified.
 * 
 * @retval NvSuccess if high corner for AV subsystem was updated successfully.
 * @retval NvError_NotSupported if DFS is disabled.
 */

 NvError NvRmDfsSetAvHighCorner( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmFreqKHz DfsSystemHighKHz,
    NvRmFreqKHz DfsAvpHighKHz,
    NvRmFreqKHz DfsVpipeHighKHz );

/**
 * Gets DFS profiling information.
 * 
 * DFS profiling starts/re-starts every time NvRmDfsRunState_ProfiledLoop
 * state is set via NvRmDfsSetState(). DFS profiling stops when any other
 * sate is set.
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param DfsProfileCount Number of DFS profiles. Must be always equal to
 *  NvRmDfsProfileId_Num.
 * @param pSamplesNoList Output storage pointer to an array of sample counts
 *  for each profile target ordered according to NvRmDfsProfileId enumeration.
 * @param pProfileTimeUsList Output storage pointer to an array of cummulative
 *  execution time in microseconds for each profile target ordered according
 *  to NvRmDfsProfileId enumeration.
 * @param pDfsPeriodUs Output storage pointer for average DFS sample
 *  period in microseconds.
 * 
 * @retval NvSuccess if profile information is returned successfully.
 * @retval NvError_NotSupported if DFS is not ruuning in profiled loop.
 */

 NvError NvRmDfsGetProfileData( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 DfsProfileCount,
    NvU32 * pSamplesNoList,
    NvU32 * pProfileTimeUsList,
    NvU32 * pDfsPeriodUs );

/**
 * Starts/Re-starts NV DFS logging.
 * 
 * @param hRmDeviceHandle The RM device handle.
 */

 void NvRmDfsLogStart( 
    NvRmDeviceHandle hRmDeviceHandle );

/**
 * Stops DFS logging and gets cumulative mean values of DFS domains frequencies
 *  over logging time.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param LogMeanFreqListCount Number of entries in the pLogMeanFreqList array.
 *  Must be always equal to NvRmDfsClockId_Num.
 * @param pLogMeanFreqList Pointer to a list filled with mean values of DFS
 *  frequencies, ordered according to NvRmDfsClockId enumeration.
 * @param pLogLp2TimeMs Pointer to a variable filled with cumulative time spent
 *  in LP2 in milliseconds.
 * @param pLogLp2Entries Pointer to a variable filled with cumulative number of
 *  LP2 mode entries.
 * 
 * @retval NvSuccess if mean values are returned successfully.
 * @retval NvError_NotSupported if DFS is disabled.
 */

 NvError NvRmDfsLogGetMeanFrequencies( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 LogMeanFreqListCount,
    NvRmFreqKHz * pLogMeanFreqList,
    NvU32 * pLogLp2TimeMs,
    NvU32 * pLogLp2Entries );

/**
 * Gets specified entry of the detailed DFS activity log.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param EntryIndex Log entrty index.
 * @param LogDomainsCount The size of activity arrays.
 *  Must be always equal to NvRmDfsClockId_Num.
 * @param pIntervalMs Pointer to a variable filled with sample interval time
 *  in milliseconds.
 * @param pLp2TimeMs Pointer to a variable filled with time spent in LP2
 *  in milliseconds.
 * @param pActiveCyclesList Pointer to a list filled with domain active cycles
 *  within sample interval.
 * @param pAveragesList Pointer to a list filled with average domain activity
 *  over DFS moving window.
 * @param pFrequenciesList Pointer to a list filled with instantaneous domains
 *  frequencies.
 *  All lists are ordered according to NvRmDfsClockId enumeration.
 * 
 * @retval NvSuccess if log entry is retrieved successfully.
 * @retval NvError_InvalidAddress if requetsed entry is empty.
 * @retval NvError_NotSupported if DFS is disabled, or detailed logging
 *  is not supported.
 */

 NvError NvRmDfsLogActivityGetEntry( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 EntryIndex,
    NvU32 LogDomainsCount,
    NvU32 * pIntervalMs,
    NvU32 * pLp2TimeMs,
    NvU32 * pActiveCyclesList,
    NvRmFreqKHz * pAveragesList,
    NvRmFreqKHz * pFrequenciesList );

/**
 * Gets specified entry of the detailed DFS starvation hints log.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param EntryIndex Log entrty index.
 * @param pSampleIndex Pointer to a variable filled with sample interval
 *  index in the activity log when this hint is associated with.
 * @param pStarvationHint Pointer to a variable filled with starvation
 *  hint record.
 * 
 * @retval NvSuccess if next entry is retrieved successfully.
 * @retval NvError_InvalidAddress if requetsed entry is empty.
 * @retval NvError_NotSupported if DFS is disabled, or detailed logging
 *  is not supported.
 */

 NvError NvRmDfsLogStarvationGetEntry( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 EntryIndex,
    NvU32 * pSampleIndex,
    NvU32 * pClientId,
    NvU32 * pClientTag,
    NvRmDfsStarvationHint * pStarvationHint );

/**
 * Gets specified entry of the detailed DFS busy hints log.
 *
 * @param hRmDeviceHandle The RM device handle.
 * @param EntryIndex Log entrty index.
 * @param pSampleIndex Pointer to a variable filled with sample interval
 *  index in the activity log when this hint is associated with.
 * @param pBusyHint Pointer to a variable filled with busy
 *  hint record.
 * 
 * @retval NvSuccess if next entry is retrieved successfully.
 * @retval NvError_InvalidAddress if requetsed entry is empty.
 * @retval NvError_NotSupported if DFS is disabled, or detailed logging
 *  is not supported.
 */

 NvError NvRmDfsLogBusyGetEntry( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvU32 EntryIndex,
    NvU32 * pSampleIndex,
    NvU32 * pClientId,
    NvU32 * pClientTag,
    NvRmDfsBusyHint * pBusyHint );

/**
 * Gets low threshold and present voltage on the given rail.
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param RailId The targeted voltage rail ID.
 * @param pLowMv Output storage pointer for low voltage threshold (in 
 *  millivolt). NvRmVoltsUnspecified is returned if targeted rail does
 *  not exist on SoC.
 * @param pPresentMv Output storage pointer for present rail voltage (in 
 *  millivolt). NvRmVoltsUnspecified is returned if targeted rail does
 *  not exist on SoC.
 */

 void NvRmDfsGetLowVoltageThreshold( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmDfsVoltageRailId RailId,
    NvRmMilliVolts * pLowMv,
    NvRmMilliVolts * pPresentMv );

/**
 * Sets low threshold for the given rail. The actual rail voltage is scaled
 *  to match SoC clock frequencies, but not below the specified threshold.
 * 
 * @param hRmDeviceHandle The RM device handle.
 * @param RailId The targeted voltage rail ID.
 * @param LowMv Low voltage threshold (in millivolts) for the targeted rail.
 *  Ignored if targeted rail does not exist on SoC.
 */

 void NvRmDfsSetLowVoltageThreshold( 
    NvRmDeviceHandle hRmDeviceHandle,
    NvRmDfsVoltageRailId RailId,
    NvRmMilliVolts LowMv );

/**
 * Notifies RM Kernel about entering Suspend state.
 * 
 * @param hRmDeviceHandle The RM device handle.
 *
 * @retval NvSuccess if notifying RM entering Suspend state successfully.
 */

 NvError NvRmKernelPowerSuspend( 
    NvRmDeviceHandle hRmDeviceHandle );

/**
 * Notifies RM kernel about entering Resume state.
 * 
 * @param hRmDeviceHandle The RM device handle.
 *
 * @retval NvSuccess if notifying RM entering Resume state successfully.
 */

 NvError NvRmKernelPowerResume( 
    NvRmDeviceHandle hRmDeviceHandle );

/** @} */

#if defined(__cplusplus)
}
#endif

#endif