39
39
#define POWER_HIGH_LOCK BIT_ULL(63)
40
40
#define POWER_LOW_LOCK BIT(31)
41
41
42
+ #define POWER_LIMIT4_MASK 0x1FFF
43
+
42
44
#define TIME_WINDOW1_MASK (0x7FULL<<17)
43
45
#define TIME_WINDOW2_MASK (0x7FULL<<49)
44
46
@@ -82,6 +84,7 @@ enum unit_type {
82
84
83
85
static const char pl1_name [] = "long_term" ;
84
86
static const char pl2_name [] = "short_term" ;
87
+ static const char pl4_name [] = "peak_power" ;
85
88
86
89
#define power_zone_to_rapl_domain (_zone ) \
87
90
container_of(_zone, struct rapl_domain, power_zone)
@@ -338,6 +341,9 @@ static int set_power_limit(struct powercap_zone *power_zone, int cid,
338
341
case PL2_ENABLE :
339
342
rapl_write_data_raw (rd , POWER_LIMIT2 , power_limit );
340
343
break ;
344
+ case PL4_ENABLE :
345
+ rapl_write_data_raw (rd , POWER_LIMIT4 , power_limit );
346
+ break ;
341
347
default :
342
348
ret = - EINVAL ;
343
349
}
@@ -372,6 +378,9 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
372
378
case PL2_ENABLE :
373
379
prim = POWER_LIMIT2 ;
374
380
break ;
381
+ case PL4_ENABLE :
382
+ prim = POWER_LIMIT4 ;
383
+ break ;
375
384
default :
376
385
put_online_cpus ();
377
386
return - EINVAL ;
@@ -441,6 +450,13 @@ static int get_time_window(struct powercap_zone *power_zone, int cid,
441
450
case PL2_ENABLE :
442
451
ret = rapl_read_data_raw (rd , TIME_WINDOW2 , true, & val );
443
452
break ;
453
+ case PL4_ENABLE :
454
+ /*
455
+ * Time window parameter is not applicable for PL4 entry
456
+ * so assigining '0' as default value.
457
+ */
458
+ val = 0 ;
459
+ break ;
444
460
default :
445
461
put_online_cpus ();
446
462
return - EINVAL ;
@@ -484,6 +500,9 @@ static int get_max_power(struct powercap_zone *power_zone, int id, u64 *data)
484
500
case PL2_ENABLE :
485
501
prim = MAX_POWER ;
486
502
break ;
503
+ case PL4_ENABLE :
504
+ prim = MAX_POWER ;
505
+ break ;
487
506
default :
488
507
put_online_cpus ();
489
508
return - EINVAL ;
@@ -493,6 +512,10 @@ static int get_max_power(struct powercap_zone *power_zone, int id, u64 *data)
493
512
else
494
513
* data = val ;
495
514
515
+ /* As a generalization rule, PL4 would be around two times PL2. */
516
+ if (rd -> rpl [id ].prim_id == PL4_ENABLE )
517
+ * data = * data * 2 ;
518
+
496
519
put_online_cpus ();
497
520
498
521
return ret ;
@@ -525,12 +548,22 @@ static void rapl_init_domains(struct rapl_package *rp)
525
548
rd -> id = i ;
526
549
rd -> rpl [0 ].prim_id = PL1_ENABLE ;
527
550
rd -> rpl [0 ].name = pl1_name ;
528
- /* some domain may support two power limits */
529
- if (rp -> priv -> limits [i ] == 2 ) {
551
+
552
+ /*
553
+ * The PL2 power domain is applicable for limits two
554
+ * and limits three
555
+ */
556
+ if (rp -> priv -> limits [i ] >= 2 ) {
530
557
rd -> rpl [1 ].prim_id = PL2_ENABLE ;
531
558
rd -> rpl [1 ].name = pl2_name ;
532
559
}
533
560
561
+ /* Enable PL4 domain if the total power limits are three */
562
+ if (rp -> priv -> limits [i ] == 3 ) {
563
+ rd -> rpl [2 ].prim_id = PL4_ENABLE ;
564
+ rd -> rpl [2 ].name = pl4_name ;
565
+ }
566
+
534
567
for (j = 0 ; j < RAPL_DOMAIN_REG_MAX ; j ++ )
535
568
rd -> regs [j ] = rp -> priv -> regs [i ][j ];
536
569
@@ -599,6 +632,8 @@ static struct rapl_primitive_info rpi[] = {
599
632
RAPL_DOMAIN_REG_LIMIT , POWER_UNIT , 0 ),
600
633
PRIMITIVE_INFO_INIT (POWER_LIMIT2 , POWER_LIMIT2_MASK , 32 ,
601
634
RAPL_DOMAIN_REG_LIMIT , POWER_UNIT , 0 ),
635
+ PRIMITIVE_INFO_INIT (POWER_LIMIT4 , POWER_LIMIT4_MASK , 0 ,
636
+ RAPL_DOMAIN_REG_PL4 , POWER_UNIT , 0 ),
602
637
PRIMITIVE_INFO_INIT (FW_LOCK , POWER_LOW_LOCK , 31 ,
603
638
RAPL_DOMAIN_REG_LIMIT , ARBITRARY_UNIT , 0 ),
604
639
PRIMITIVE_INFO_INIT (PL1_ENABLE , POWER_LIMIT1_ENABLE , 15 ,
@@ -609,6 +644,8 @@ static struct rapl_primitive_info rpi[] = {
609
644
RAPL_DOMAIN_REG_LIMIT , ARBITRARY_UNIT , 0 ),
610
645
PRIMITIVE_INFO_INIT (PL2_CLAMP , POWER_LIMIT2_CLAMP , 48 ,
611
646
RAPL_DOMAIN_REG_LIMIT , ARBITRARY_UNIT , 0 ),
647
+ PRIMITIVE_INFO_INIT (PL4_ENABLE , POWER_LIMIT4_MASK , 0 ,
648
+ RAPL_DOMAIN_REG_PL4 , ARBITRARY_UNIT , 0 ),
612
649
PRIMITIVE_INFO_INIT (TIME_WINDOW1 , TIME_WINDOW1_MASK , 17 ,
613
650
RAPL_DOMAIN_REG_LIMIT , TIME_UNIT , 0 ),
614
651
PRIMITIVE_INFO_INIT (TIME_WINDOW2 , TIME_WINDOW2_MASK , 49 ,
@@ -1273,6 +1310,7 @@ void rapl_remove_package(struct rapl_package *rp)
1273
1310
if (find_nr_power_limit (rd ) > 1 ) {
1274
1311
rapl_write_data_raw (rd , PL2_ENABLE , 0 );
1275
1312
rapl_write_data_raw (rd , PL2_CLAMP , 0 );
1313
+ rapl_write_data_raw (rd , PL4_ENABLE , 0 );
1276
1314
}
1277
1315
if (rd -> id == RAPL_DOMAIN_PACKAGE ) {
1278
1316
rd_package = rd ;
@@ -1381,6 +1419,13 @@ static void power_limit_state_save(void)
1381
1419
if (ret )
1382
1420
rd -> rpl [i ].last_power_limit = 0 ;
1383
1421
break ;
1422
+ case PL4_ENABLE :
1423
+ ret = rapl_read_data_raw (rd ,
1424
+ POWER_LIMIT4 , true,
1425
+ & rd -> rpl [i ].last_power_limit );
1426
+ if (ret )
1427
+ rd -> rpl [i ].last_power_limit = 0 ;
1428
+ break ;
1384
1429
}
1385
1430
}
1386
1431
}
@@ -1411,6 +1456,11 @@ static void power_limit_state_restore(void)
1411
1456
rapl_write_data_raw (rd , POWER_LIMIT2 ,
1412
1457
rd -> rpl [i ].last_power_limit );
1413
1458
break ;
1459
+ case PL4_ENABLE :
1460
+ if (rd -> rpl [i ].last_power_limit )
1461
+ rapl_write_data_raw (rd , POWER_LIMIT4 ,
1462
+ rd -> rpl [i ].last_power_limit );
1463
+ break ;
1414
1464
}
1415
1465
}
1416
1466
}
0 commit comments