3333#include <htmgt/htmgt_reasoncodes.H>
3434
3535
36+
3637using namespace TARGETING ;
3738
3839
3940//for unit testing
4041//#define TRACUCOMP(args...) TMGT_INF(args)
4142#define TRACUCOMP (args ...)
4243
43- #define FRAC (f ) ( int((f - int(f)) * 100.0) )
44-
4544namespace HTMGT
4645{
46+ void getWofCoreFrequencyData (const TargetHandle_t i_occ ,
47+ uint8_t * o_data ,
48+ uint64_t & o_size );
49+ void getWofVrmEfficiencyData (uint8_t * o_data ,
50+ uint64_t & o_size );
51+
52+ bool G_wofSupported = true;
53+
4754 // Send config format data to all OCCs
4855 void sendOccConfigData (const occCfgDataFormat i_requestedFormat )
4956 {
@@ -179,6 +186,15 @@ namespace HTMGT
179186 cmdDataLen );
180187 break ;
181188
189+ case OCC_CFGDATA_WOF_CORE_FREQ :
190+ getWofCoreFrequencyData (occ -> getTarget (),
191+ cmdData , cmdDataLen );
192+ break ;
193+
194+ case OCC_CFGDATA_WOF_VRM_EFF :
195+ getWofVrmEfficiencyData (cmdData , cmdDataLen );
196+ break ;
197+
182198 default :
183199 TMGT_ERR ("send_occ_config_data: Unsupported"
184200 " format type 0x%02X" ,
@@ -235,13 +251,15 @@ namespace HTMGT
235251enum occCfgDataVersion
236252{
237253 OCC_CFGDATA_PSTATE_VERSION = 0x10 ,
238- OCC_CFGDATA_FREQ_POINT_VERSION = 0x10 ,
254+ OCC_CFGDATA_FREQ_POINT_VERSION = 0x11 ,
239255 OCC_CFGDATA_APSS_VERSION = 0x10 ,
240256 OCC_CFGDATA_MEM_CONFIG_VERSION = 0x10 ,
241257 OCC_CFGDATA_PCAP_CONFIG_VERSION = 0x10 ,
242258 OCC_CFGDATA_SYS_CONFIG_VERSION = 0x10 ,
243259 OCC_CFGDATA_MEM_THROTTLE_VERSION = 0x10 ,
244- OCC_CFGDATA_TCT_CONFIG_VERSION = 0x10
260+ OCC_CFGDATA_TCT_CONFIG_VERSION = 0x10 ,
261+ OCC_CFGDATA_WOF_CORE_FREQ_VERSION = 0x10 ,
262+ OCC_CFGDATA_WOF_VRM_EFF_VERSION = 0x10
245263};
246264
247265void getMemConfigMessageData (const TargetHandle_t i_occ ,
@@ -659,7 +677,8 @@ void getFrequencyPointMessageData(uint8_t* o_data,
659677{
660678 uint64_t index = 0 ;
661679 uint16_t min = 0 ;
662- uint16_t max = 0 ;
680+ uint16_t turbo = 0 ;
681+ uint16_t ultra = 0 ;
663682 uint16_t nominal = 0 ;
664683 Target * sys = NULL ;
665684
@@ -679,7 +698,7 @@ void getFrequencyPointMessageData(uint8_t* o_data,
679698 ConstTargetHandle_t procTarget = getParentChip (occTarget );
680699 assert (procTarget != NULL );
681700 const fapi ::Target fapiTarget (fapi ::TARGET_TYPE_PROC_CHIP ,
682- & procTarget );
701+ ( const_cast < TARGETING :: Target * > ( procTarget )) );
683702 uint32_t biasUp = 0 ;
684703 uint32_t biasDown = 0 ;
685704 int rc = FAPI_ATTR_GET (ATTR_FREQ_EXT_BIAS_UP ,& fapiTarget ,biasUp );
@@ -688,13 +707,13 @@ void getFrequencyPointMessageData(uint8_t* o_data,
688707 {
689708 if ((biasDown > 0 ) && (biasUp == 0 ))
690709 {
691- TMGT_INF ("FREQ_EXT_BIAS_DOWN=%d (in 0.5% units)" , biasDown );
710+ TMGT_INF ("FREQ_EXT_BIAS_DOWN=%d (in 0.5%% units)" ,biasDown );
692711 biasFactor = - (biasDown );
693712 }
694713 else if ((biasUp > 0 ) && (biasDown == 0 ))
695714 {
696715 biasFactor = biasUp ;
697- TMGT_INF ("FREQ_EXT_BIAS_UP=%d (in 0.5% units)" , biasUp );
716+ TMGT_INF ("FREQ_EXT_BIAS_UP=%d (in 0.5%% units)" , biasUp );
698717 }
699718 else if ((biasUp > 0 ) && (biasDown > 0 ))
700719 {
@@ -750,31 +769,57 @@ void getFrequencyPointMessageData(uint8_t* o_data,
750769 memcpy (& o_data [index ], & nominal , 2 );
751770 index += 2 ;
752771
753- //Maximum Frequency in MHz
754772 uint8_t turboAllowed =
755773 sys -> getAttr < ATTR_OPEN_POWER_TURBO_MODE_SUPPORTED > ( );
756-
757- //If Turbo isn't allowed, then we send up the
758- //nominal frequency for this value.
759774 if (turboAllowed )
760775 {
761- max = sys -> getAttr < ATTR_FREQ_CORE_MAX > ( );
776+ turbo = sys -> getAttr < ATTR_FREQ_CORE_MAX > ( );
777+
778+ //Ultra Turbo Frequency in MHz
779+ const uint16_t wofSupported = sys -> getAttr < ATTR_WOF_ENABLED > ( );
780+ if (0 != wofSupported )
781+ {
782+ ultra = sys -> getAttr < ATTR_ULTRA_TURBO_FREQ_MHZ > ( );
783+ if (0 != ultra )
784+ {
785+ if (biasFactor )
786+ {
787+ TMGT_INF ("Pre-biased Ultra=%dMhz" , ultra );
788+ // % change = (biasFactor/2) / 100
789+ ultra += ((ultra * biasFactor ) / 200 );
790+ }
791+ }
792+ else
793+ {
794+ TMGT_INF ("getFrequencyPoint: WOF enabled, but freq is 0" );
795+ G_wofSupported = false;
796+ }
797+ }
798+ else
799+ {
800+ TMGT_INF ("getFrequencyPoint: WOF not enabled" );
801+ G_wofSupported = false;
802+ }
762803 }
763804 else
764805 {
765- max = nominal ;
806+ // If turbo not supported, send nominal for turbo
807+ // and 0 for ultra-turbo (no WOF support)
808+ TMGT_INF ("getFrequencyPoint: Turbo/WOF not supported" );
809+ turbo = nominal ;
810+ G_wofSupported = false;
766811 }
767812 if (biasFactor )
768813 {
769- TMGT_INF ("Pre-biased Max =%dMhz" , max );
814+ TMGT_INF ("Pre-biased Turbo =%dMhz" , turbo );
770815 // % change = (biasFactor/2) / 100
771- max += ((max * biasFactor ) / 200 );
816+ turbo += ((turbo * biasFactor ) / 200 );
772817 }
773818
774- memcpy (& o_data [index ], & max , 2 );
819+ //Turbo Frequency in MHz
820+ memcpy (& o_data [index ], & turbo , 2 );
775821 index += 2 ;
776822
777-
778823 //Minimum Frequency in MHz
779824 min = sys -> getAttr < ATTR_MIN_FREQ_MHZ > ( );
780825 if (biasFactor )
@@ -786,8 +831,12 @@ void getFrequencyPointMessageData(uint8_t* o_data,
786831 memcpy (& o_data [index ], & min , 2 );
787832 index += 2 ;
788833
789- TMGT_INF ("Frequency Points: Nominal %d, Max %d, Min %d" ,
790- (uint32_t )nominal , (uint32_t )max , (uint32_t )min );
834+ //Ultra Turbo Frequency in MHz
835+ memcpy (& o_data [index ], & ultra , 2 );
836+ index += 2 ;
837+
838+ TMGT_INF ("Frequency Points: Min %d, Nominal %d, Turbo %d, Ultra %d MHz" ,
839+ min , nominal , turbo , ultra );
791840
792841 o_size = index ;
793842}
@@ -923,4 +972,122 @@ void getApssMessageData(uint8_t* o_data,
923972
924973 o_size = idx ;
925974}
975+
976+ void getWofCoreFrequencyData (const TargetHandle_t i_occ ,
977+ uint8_t * o_data ,
978+ uint64_t & o_size )
979+ {
980+ assert (o_data != NULL );
981+ uint64_t index = 0 ;
982+ Target * sys = NULL ;
983+ targetService ().getTopLevelTarget (sys );
984+ assert (sys != NULL );
985+ ConstTargetHandle_t proc = getParentChip (i_occ );
986+ assert (proc != NULL );
987+
988+ // Count the number of cores that are good on each chip without
989+ // regard to being GARDED. Cores that are deconfigured do not
990+ // affect this number. This is the number of present cores
991+ // (max - partial bad).
992+ TARGETING ::TargetHandleList l_presCoreList ;
993+ getChildAffinityTargetsByState (l_presCoreList ,
994+ proc ,
995+ TARGETING ::CLASS_UNIT ,
996+ TARGETING ::TYPE_CORE ,
997+ TARGETING ::UTIL_FILTER_PRESENT );
998+ const uint8_t maxCoresPerChip = l_presCoreList .size ();
999+
1000+ o_data [index ++ ] = OCC_CFGDATA_WOF_CORE_FREQ ;
1001+ o_data [index ++ ] = OCC_CFGDATA_WOF_CORE_FREQ_VERSION ;
1002+ o_data [index ++ ] = maxCoresPerChip ;
1003+ memset (& o_data [index ], 0 , 3 ); // reserved
1004+ index += 3 ;
1005+
1006+ uint8_t numRows = 0 ;
1007+ uint8_t numColumns = 0 ;
1008+ const uint16_t tablesize = sizeof (ATTR_WOF_FREQUENCY_UPLIFT_SELECTED_type );
1009+ if (G_wofSupported )
1010+ {
1011+ numRows = 22 ;
1012+ numColumns = 13 ;
1013+ TMGT_INF ("getWofCoreFrequencyData: %d rows, %d cols (0x%04X bytes)" ,
1014+ numRows , numColumns , tablesize );
1015+ assert (tablesize == numRows * numColumns * 2 );
1016+ }
1017+ o_data [index ++ ] = numRows ;
1018+ o_data [index ++ ] = numColumns ;
1019+
1020+ if (G_wofSupported )
1021+ {
1022+ // Host Boot will determine correct chip sort and pick correct
1023+ // frequncy uplift table
1024+ ATTR_WOF_FREQUENCY_UPLIFT_SELECTED_type * upliftTable =
1025+ reinterpret_cast < ATTR_WOF_FREQUENCY_UPLIFT_SELECTED_type * >
1026+ (& o_data [index ]);
1027+
1028+ proc -> tryGetAttr < ATTR_WOF_FREQUENCY_UPLIFT_SELECTED > (* upliftTable );
1029+ TMGT_BIN ("WOF CoreFrequency Data" , upliftTable , tablesize );
1030+
1031+ // first table entry must be 0s
1032+ memset (& o_data [index ], 0 , 2 );
1033+
1034+ index += tablesize ;
1035+ }
1036+
1037+ o_size = index ;
1038+
1039+ } // end getWofCoreFrequencyData()
1040+
1041+
1042+ void getWofVrmEfficiencyData (uint8_t * o_data ,
1043+ uint64_t & o_size )
1044+ {
1045+ assert (o_data != NULL );
1046+ uint64_t index = 0 ;
1047+ Target * sys = NULL ;
1048+ targetService ().getTopLevelTarget (sys );
1049+ assert (sys != NULL );
1050+
1051+ o_data [index ++ ] = OCC_CFGDATA_WOF_VRM_EFF ;
1052+ o_data [index ++ ] = OCC_CFGDATA_WOF_VRM_EFF_VERSION ;
1053+ memset (& o_data [index ], 0 , 4 ); // reserved
1054+ index += 4 ;
1055+
1056+ uint8_t numRows = 0 ;
1057+ uint8_t numColumns = 0 ;
1058+ const uint16_t tablesize = sizeof (ATTR_WOF_REGULATOR_EFFICIENCIES_type );
1059+ if (G_wofSupported )
1060+ {
1061+ numRows = 3 ;
1062+ numColumns = 14 ;
1063+ TMGT_INF ("getWofVrmEfficiencyData: %d rows, %d cols (0x%04X bytes)" ,
1064+ numRows , numColumns , tablesize );
1065+ assert (tablesize == numRows * numColumns * 2 );
1066+ }
1067+ o_data [index ++ ] = numRows ;
1068+ o_data [index ++ ] = numColumns ;
1069+
1070+ if (G_wofSupported )
1071+ {
1072+ // VRM efficiency table is unique per system
1073+
1074+ ATTR_WOF_REGULATOR_EFFICIENCIES_type * regEffDataPtr =
1075+ reinterpret_cast < ATTR_WOF_REGULATOR_EFFICIENCIES_type * >
1076+ (& o_data [index ]);
1077+
1078+ sys -> tryGetAttr < ATTR_WOF_REGULATOR_EFFICIENCIES > (* regEffDataPtr );
1079+ TMGT_BIN ("WOF VRM Efficiency Data" , regEffDataPtr , tablesize );
1080+
1081+ // first table entry must be 0s
1082+ memset (& o_data [index ], 0 , 2 );
1083+
1084+ index += tablesize ;
1085+ }
1086+
1087+ o_size = index ;
1088+
1089+ } // end getWofVrmEfficiencyData()
1090+
1091+
1092+
9261093}
0 commit comments