0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "dm_services.h"
0027 #include "dcn10_hubp.h"
0028 #include "dcn10_hubbub.h"
0029 #include "reg_helper.h"
0030
0031 #define CTX \
0032 hubbub1->base.ctx
0033 #define DC_LOGGER \
0034 hubbub1->base.ctx->logger
0035 #define REG(reg)\
0036 hubbub1->regs->reg
0037
0038 #undef FN
0039 #define FN(reg_name, field_name) \
0040 hubbub1->shifts->field_name, hubbub1->masks->field_name
0041
0042 void hubbub1_wm_read_state(struct hubbub *hubbub,
0043 struct dcn_hubbub_wm *wm)
0044 {
0045 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0046 struct dcn_hubbub_wm_set *s;
0047
0048 memset(wm, 0, sizeof(struct dcn_hubbub_wm));
0049
0050 s = &wm->sets[0];
0051 s->wm_set = 0;
0052 s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
0053 s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A);
0054 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
0055 s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);
0056 s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);
0057 }
0058 s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A);
0059
0060 s = &wm->sets[1];
0061 s->wm_set = 1;
0062 s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B);
0063 s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B);
0064 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
0065 s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B);
0066 s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B);
0067 }
0068 s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B);
0069
0070 s = &wm->sets[2];
0071 s->wm_set = 2;
0072 s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C);
0073 s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C);
0074 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
0075 s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C);
0076 s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C);
0077 }
0078 s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C);
0079
0080 s = &wm->sets[3];
0081 s->wm_set = 3;
0082 s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D);
0083 s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D);
0084 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
0085 s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D);
0086 s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D);
0087 }
0088 s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D);
0089 }
0090
0091 void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
0092 {
0093 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0094
0095
0096
0097
0098
0099 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
0100 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
0101 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
0102 }
0103
0104 bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
0105 {
0106 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0107 uint32_t enable = 0;
0108
0109 REG_GET(DCHUBBUB_ARB_DRAM_STATE_CNTL,
0110 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, &enable);
0111
0112 return enable ? true : false;
0113 }
0114
0115
0116 bool hubbub1_verify_allow_pstate_change_high(
0117 struct hubbub *hubbub)
0118 {
0119 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0120
0121
0122
0123
0124
0125
0126
0127
0128 const unsigned int pstate_wait_timeout_us = 200;
0129 const unsigned int pstate_wait_expected_timeout_us = 180;
0130 static unsigned int max_sampled_pstate_wait_us;
0131 static bool forced_pstate_allow;
0132
0133 unsigned int debug_data;
0134 unsigned int i;
0135
0136 if (forced_pstate_allow) {
0137
0138
0139
0140
0141 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
0142 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
0143 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
0144 forced_pstate_allow = false;
0145 }
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub1->debug_test_index_pstate);
0186
0187 for (i = 0; i < pstate_wait_timeout_us; i++) {
0188 debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
0189
0190 if (debug_data & (1 << 30)) {
0191
0192 if (i > pstate_wait_expected_timeout_us)
0193 DC_LOG_WARNING("pstate took longer than expected ~%dus\n",
0194 i);
0195
0196 return true;
0197 }
0198 if (max_sampled_pstate_wait_us < i)
0199 max_sampled_pstate_wait_us = i;
0200
0201 udelay(1);
0202 }
0203
0204
0205
0206
0207 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
0208 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
0209 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
0210 forced_pstate_allow = true;
0211
0212 DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
0213 debug_data);
0214
0215 return false;
0216 }
0217
0218 static uint32_t convert_and_clamp(
0219 uint32_t wm_ns,
0220 uint32_t refclk_mhz,
0221 uint32_t clamp_value)
0222 {
0223 uint32_t ret_val = 0;
0224 ret_val = wm_ns * refclk_mhz;
0225 ret_val /= 1000;
0226
0227 if (ret_val > clamp_value)
0228 ret_val = clamp_value;
0229
0230 return ret_val;
0231 }
0232
0233
0234 void hubbub1_wm_change_req_wa(struct hubbub *hubbub)
0235 {
0236 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0237
0238 REG_UPDATE_SEQ_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
0239 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0,
0240 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
0241 }
0242
0243 bool hubbub1_program_urgent_watermarks(
0244 struct hubbub *hubbub,
0245 struct dcn_watermark_set *watermarks,
0246 unsigned int refclk_mhz,
0247 bool safe_to_lower)
0248 {
0249 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0250 uint32_t prog_wm_value;
0251 bool wm_pending = false;
0252
0253
0254
0255 if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) {
0256 hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
0257 prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
0258 refclk_mhz, 0x1fffff);
0259 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
0260 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
0261
0262 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
0263 "HW register value = 0x%x\n",
0264 watermarks->a.urgent_ns, prog_wm_value);
0265 } else if (watermarks->a.urgent_ns < hubbub1->watermarks.a.urgent_ns)
0266 wm_pending = true;
0267
0268 if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub1->watermarks.a.pte_meta_urgent_ns) {
0269 hubbub1->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns;
0270 prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
0271 refclk_mhz, 0x1fffff);
0272 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
0273 DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
0274 "HW register value = 0x%x\n",
0275 watermarks->a.pte_meta_urgent_ns, prog_wm_value);
0276 } else if (watermarks->a.pte_meta_urgent_ns < hubbub1->watermarks.a.pte_meta_urgent_ns)
0277 wm_pending = true;
0278
0279
0280 if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
0281 hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
0282 prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
0283 refclk_mhz, 0x1fffff);
0284 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
0285 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
0286
0287 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
0288 "HW register value = 0x%x\n",
0289 watermarks->b.urgent_ns, prog_wm_value);
0290 } else if (watermarks->b.urgent_ns < hubbub1->watermarks.b.urgent_ns)
0291 wm_pending = true;
0292
0293 if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub1->watermarks.b.pte_meta_urgent_ns) {
0294 hubbub1->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns;
0295 prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns,
0296 refclk_mhz, 0x1fffff);
0297 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
0298 DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
0299 "HW register value = 0x%x\n",
0300 watermarks->b.pte_meta_urgent_ns, prog_wm_value);
0301 } else if (watermarks->b.pte_meta_urgent_ns < hubbub1->watermarks.b.pte_meta_urgent_ns)
0302 wm_pending = true;
0303
0304
0305 if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
0306 hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
0307 prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
0308 refclk_mhz, 0x1fffff);
0309 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
0310 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
0311
0312 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
0313 "HW register value = 0x%x\n",
0314 watermarks->c.urgent_ns, prog_wm_value);
0315 } else if (watermarks->c.urgent_ns < hubbub1->watermarks.c.urgent_ns)
0316 wm_pending = true;
0317
0318 if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub1->watermarks.c.pte_meta_urgent_ns) {
0319 hubbub1->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns;
0320 prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns,
0321 refclk_mhz, 0x1fffff);
0322 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
0323 DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
0324 "HW register value = 0x%x\n",
0325 watermarks->c.pte_meta_urgent_ns, prog_wm_value);
0326 } else if (watermarks->c.pte_meta_urgent_ns < hubbub1->watermarks.c.pte_meta_urgent_ns)
0327 wm_pending = true;
0328
0329
0330 if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
0331 hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
0332 prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
0333 refclk_mhz, 0x1fffff);
0334 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
0335 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
0336
0337 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
0338 "HW register value = 0x%x\n",
0339 watermarks->d.urgent_ns, prog_wm_value);
0340 } else if (watermarks->d.urgent_ns < hubbub1->watermarks.d.urgent_ns)
0341 wm_pending = true;
0342
0343 if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub1->watermarks.d.pte_meta_urgent_ns) {
0344 hubbub1->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns;
0345 prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns,
0346 refclk_mhz, 0x1fffff);
0347 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
0348 DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
0349 "HW register value = 0x%x\n",
0350 watermarks->d.pte_meta_urgent_ns, prog_wm_value);
0351 } else if (watermarks->d.pte_meta_urgent_ns < hubbub1->watermarks.d.pte_meta_urgent_ns)
0352 wm_pending = true;
0353
0354 return wm_pending;
0355 }
0356
0357 bool hubbub1_program_stutter_watermarks(
0358 struct hubbub *hubbub,
0359 struct dcn_watermark_set *watermarks,
0360 unsigned int refclk_mhz,
0361 bool safe_to_lower)
0362 {
0363 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0364 uint32_t prog_wm_value;
0365 bool wm_pending = false;
0366
0367
0368 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
0369 > hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
0370 hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
0371 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
0372 prog_wm_value = convert_and_clamp(
0373 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
0374 refclk_mhz, 0x1fffff);
0375 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
0376 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
0377 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
0378 "HW register value = 0x%x\n",
0379 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
0380 } else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
0381 < hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns)
0382 wm_pending = true;
0383
0384 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
0385 > hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) {
0386 hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns =
0387 watermarks->a.cstate_pstate.cstate_exit_ns;
0388 prog_wm_value = convert_and_clamp(
0389 watermarks->a.cstate_pstate.cstate_exit_ns,
0390 refclk_mhz, 0x1fffff);
0391 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
0392 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
0393 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
0394 "HW register value = 0x%x\n",
0395 watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
0396 } else if (watermarks->a.cstate_pstate.cstate_exit_ns
0397 < hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns)
0398 wm_pending = true;
0399
0400
0401 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
0402 > hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
0403 hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
0404 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
0405 prog_wm_value = convert_and_clamp(
0406 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
0407 refclk_mhz, 0x1fffff);
0408 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
0409 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
0410 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
0411 "HW register value = 0x%x\n",
0412 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
0413 } else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
0414 < hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns)
0415 wm_pending = true;
0416
0417 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
0418 > hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) {
0419 hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns =
0420 watermarks->b.cstate_pstate.cstate_exit_ns;
0421 prog_wm_value = convert_and_clamp(
0422 watermarks->b.cstate_pstate.cstate_exit_ns,
0423 refclk_mhz, 0x1fffff);
0424 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
0425 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
0426 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
0427 "HW register value = 0x%x\n",
0428 watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
0429 } else if (watermarks->b.cstate_pstate.cstate_exit_ns
0430 < hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns)
0431 wm_pending = true;
0432
0433
0434 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
0435 > hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
0436 hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
0437 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
0438 prog_wm_value = convert_and_clamp(
0439 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
0440 refclk_mhz, 0x1fffff);
0441 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
0442 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
0443 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
0444 "HW register value = 0x%x\n",
0445 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
0446 } else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
0447 < hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns)
0448 wm_pending = true;
0449
0450 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
0451 > hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) {
0452 hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns =
0453 watermarks->c.cstate_pstate.cstate_exit_ns;
0454 prog_wm_value = convert_and_clamp(
0455 watermarks->c.cstate_pstate.cstate_exit_ns,
0456 refclk_mhz, 0x1fffff);
0457 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
0458 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
0459 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
0460 "HW register value = 0x%x\n",
0461 watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
0462 } else if (watermarks->c.cstate_pstate.cstate_exit_ns
0463 < hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns)
0464 wm_pending = true;
0465
0466
0467 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
0468 > hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
0469 hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
0470 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
0471 prog_wm_value = convert_and_clamp(
0472 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
0473 refclk_mhz, 0x1fffff);
0474 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
0475 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
0476 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
0477 "HW register value = 0x%x\n",
0478 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
0479 } else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
0480 < hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns)
0481 wm_pending = true;
0482
0483 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
0484 > hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) {
0485 hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns =
0486 watermarks->d.cstate_pstate.cstate_exit_ns;
0487 prog_wm_value = convert_and_clamp(
0488 watermarks->d.cstate_pstate.cstate_exit_ns,
0489 refclk_mhz, 0x1fffff);
0490 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
0491 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
0492 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
0493 "HW register value = 0x%x\n",
0494 watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
0495 } else if (watermarks->d.cstate_pstate.cstate_exit_ns
0496 < hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns)
0497 wm_pending = true;
0498
0499 return wm_pending;
0500 }
0501
0502 bool hubbub1_program_pstate_watermarks(
0503 struct hubbub *hubbub,
0504 struct dcn_watermark_set *watermarks,
0505 unsigned int refclk_mhz,
0506 bool safe_to_lower)
0507 {
0508 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0509 uint32_t prog_wm_value;
0510 bool wm_pending = false;
0511
0512
0513 if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
0514 > hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) {
0515 hubbub1->watermarks.a.cstate_pstate.pstate_change_ns =
0516 watermarks->a.cstate_pstate.pstate_change_ns;
0517 prog_wm_value = convert_and_clamp(
0518 watermarks->a.cstate_pstate.pstate_change_ns,
0519 refclk_mhz, 0x1fffff);
0520 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
0521 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
0522 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
0523 "HW register value = 0x%x\n\n",
0524 watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
0525 } else if (watermarks->a.cstate_pstate.pstate_change_ns
0526 < hubbub1->watermarks.a.cstate_pstate.pstate_change_ns)
0527 wm_pending = true;
0528
0529
0530 if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
0531 > hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) {
0532 hubbub1->watermarks.b.cstate_pstate.pstate_change_ns =
0533 watermarks->b.cstate_pstate.pstate_change_ns;
0534 prog_wm_value = convert_and_clamp(
0535 watermarks->b.cstate_pstate.pstate_change_ns,
0536 refclk_mhz, 0x1fffff);
0537 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
0538 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
0539 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
0540 "HW register value = 0x%x\n\n",
0541 watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
0542 } else if (watermarks->b.cstate_pstate.pstate_change_ns
0543 < hubbub1->watermarks.b.cstate_pstate.pstate_change_ns)
0544 wm_pending = true;
0545
0546
0547 if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
0548 > hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) {
0549 hubbub1->watermarks.c.cstate_pstate.pstate_change_ns =
0550 watermarks->c.cstate_pstate.pstate_change_ns;
0551 prog_wm_value = convert_and_clamp(
0552 watermarks->c.cstate_pstate.pstate_change_ns,
0553 refclk_mhz, 0x1fffff);
0554 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
0555 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
0556 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
0557 "HW register value = 0x%x\n\n",
0558 watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
0559 } else if (watermarks->c.cstate_pstate.pstate_change_ns
0560 < hubbub1->watermarks.c.cstate_pstate.pstate_change_ns)
0561 wm_pending = true;
0562
0563
0564 if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
0565 > hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) {
0566 hubbub1->watermarks.d.cstate_pstate.pstate_change_ns =
0567 watermarks->d.cstate_pstate.pstate_change_ns;
0568 prog_wm_value = convert_and_clamp(
0569 watermarks->d.cstate_pstate.pstate_change_ns,
0570 refclk_mhz, 0x1fffff);
0571 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
0572 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
0573 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
0574 "HW register value = 0x%x\n\n",
0575 watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
0576 } else if (watermarks->d.cstate_pstate.pstate_change_ns
0577 < hubbub1->watermarks.d.cstate_pstate.pstate_change_ns)
0578 wm_pending = true;
0579
0580 return wm_pending;
0581 }
0582
0583 bool hubbub1_program_watermarks(
0584 struct hubbub *hubbub,
0585 struct dcn_watermark_set *watermarks,
0586 unsigned int refclk_mhz,
0587 bool safe_to_lower)
0588 {
0589 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0590 bool wm_pending = false;
0591
0592
0593
0594
0595 if (hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
0596 wm_pending = true;
0597
0598 if (hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
0599 wm_pending = true;
0600
0601 if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
0602 wm_pending = true;
0603
0604 REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
0605 DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
0606 REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
0607 DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
0608
0609 hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
0610
0611 #if 0
0612 REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
0613 DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
0614 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
0615 #endif
0616 return wm_pending;
0617 }
0618
0619 void hubbub1_update_dchub(
0620 struct hubbub *hubbub,
0621 struct dchub_init_data *dh_data)
0622 {
0623 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0624
0625 if (REG(DCHUBBUB_SDPIF_FB_TOP) == 0) {
0626 ASSERT(false);
0627
0628 return;
0629 }
0630
0631 switch (dh_data->fb_mode) {
0632 case FRAME_BUFFER_MODE_ZFB_ONLY:
0633
0634 REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP,
0635 SDPIF_FB_TOP, 0);
0636
0637 REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
0638 SDPIF_FB_BASE, 0x0FFFF);
0639
0640 REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
0641 SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
0642
0643 REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
0644 SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
0645
0646 REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
0647 SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
0648 dh_data->zfb_size_in_byte - 1) >> 22);
0649 break;
0650 case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
0651
0652
0653 REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
0654 SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
0655
0656 REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
0657 SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
0658
0659 REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
0660 SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
0661 dh_data->zfb_size_in_byte - 1) >> 22);
0662 break;
0663 case FRAME_BUFFER_MODE_LOCAL_ONLY:
0664
0665 REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
0666 SDPIF_AGP_BASE, 0);
0667
0668 REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
0669 SDPIF_AGP_BOT, 0X03FFFF);
0670
0671 REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
0672 SDPIF_AGP_TOP, 0);
0673 break;
0674 default:
0675 break;
0676 }
0677
0678 dh_data->dchub_initialzied = true;
0679 dh_data->dchub_info_valid = false;
0680 }
0681
0682 void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub)
0683 {
0684 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0685
0686 uint32_t watermark_change_req;
0687
0688 REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
0689 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req);
0690
0691 if (watermark_change_req)
0692 watermark_change_req = 0;
0693 else
0694 watermark_change_req = 1;
0695
0696 REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
0697 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req);
0698 }
0699
0700 void hubbub1_soft_reset(struct hubbub *hubbub, bool reset)
0701 {
0702 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0703
0704 uint32_t reset_en = reset ? 1 : 0;
0705
0706 REG_UPDATE(DCHUBBUB_SOFT_RESET,
0707 DCHUBBUB_GLOBAL_SOFT_RESET, reset_en);
0708 }
0709
0710 static bool hubbub1_dcc_support_swizzle(
0711 enum swizzle_mode_values swizzle,
0712 unsigned int bytes_per_element,
0713 enum segment_order *segment_order_horz,
0714 enum segment_order *segment_order_vert)
0715 {
0716 bool standard_swizzle = false;
0717 bool display_swizzle = false;
0718
0719 switch (swizzle) {
0720 case DC_SW_4KB_S:
0721 case DC_SW_64KB_S:
0722 case DC_SW_VAR_S:
0723 case DC_SW_4KB_S_X:
0724 case DC_SW_64KB_S_X:
0725 case DC_SW_VAR_S_X:
0726 standard_swizzle = true;
0727 break;
0728 case DC_SW_4KB_D:
0729 case DC_SW_64KB_D:
0730 case DC_SW_VAR_D:
0731 case DC_SW_4KB_D_X:
0732 case DC_SW_64KB_D_X:
0733 case DC_SW_VAR_D_X:
0734 display_swizzle = true;
0735 break;
0736 default:
0737 break;
0738 }
0739
0740 if (bytes_per_element == 1 && standard_swizzle) {
0741 *segment_order_horz = segment_order__contiguous;
0742 *segment_order_vert = segment_order__na;
0743 return true;
0744 }
0745 if (bytes_per_element == 2 && standard_swizzle) {
0746 *segment_order_horz = segment_order__non_contiguous;
0747 *segment_order_vert = segment_order__contiguous;
0748 return true;
0749 }
0750 if (bytes_per_element == 4 && standard_swizzle) {
0751 *segment_order_horz = segment_order__non_contiguous;
0752 *segment_order_vert = segment_order__contiguous;
0753 return true;
0754 }
0755 if (bytes_per_element == 8 && standard_swizzle) {
0756 *segment_order_horz = segment_order__na;
0757 *segment_order_vert = segment_order__contiguous;
0758 return true;
0759 }
0760 if (bytes_per_element == 8 && display_swizzle) {
0761 *segment_order_horz = segment_order__contiguous;
0762 *segment_order_vert = segment_order__non_contiguous;
0763 return true;
0764 }
0765
0766 return false;
0767 }
0768
0769 static bool hubbub1_dcc_support_pixel_format(
0770 enum surface_pixel_format format,
0771 unsigned int *bytes_per_element)
0772 {
0773
0774 switch (format) {
0775 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
0776 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
0777 *bytes_per_element = 2;
0778 return true;
0779 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
0780 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
0781 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
0782 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
0783 *bytes_per_element = 4;
0784 return true;
0785 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
0786 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
0787 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
0788 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
0789 *bytes_per_element = 8;
0790 return true;
0791 default:
0792 return false;
0793 }
0794 }
0795
0796 static void hubbub1_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
0797 unsigned int bytes_per_element)
0798 {
0799
0800
0801 if (bytes_per_element == 1) {
0802 *blk256_width = 16;
0803 *blk256_height = 16;
0804 } else if (bytes_per_element == 2) {
0805 *blk256_width = 16;
0806 *blk256_height = 8;
0807 } else if (bytes_per_element == 4) {
0808 *blk256_width = 8;
0809 *blk256_height = 8;
0810 } else if (bytes_per_element == 8) {
0811 *blk256_width = 8;
0812 *blk256_height = 4;
0813 }
0814 }
0815
0816 static void hubbub1_det_request_size(
0817 unsigned int height,
0818 unsigned int width,
0819 unsigned int bpe,
0820 bool *req128_horz_wc,
0821 bool *req128_vert_wc)
0822 {
0823 unsigned int detile_buf_size = 164 * 1024;
0824
0825 unsigned int blk256_height = 0;
0826 unsigned int blk256_width = 0;
0827 unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
0828
0829 hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe);
0830
0831 swath_bytes_horz_wc = width * blk256_height * bpe;
0832 swath_bytes_vert_wc = height * blk256_width * bpe;
0833
0834 *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
0835 false :
0836 true;
0837
0838 *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
0839 false :
0840 true;
0841 }
0842
0843 static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
0844 const struct dc_dcc_surface_param *input,
0845 struct dc_surface_dcc_cap *output)
0846 {
0847 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0848 struct dc *dc = hubbub1->base.ctx->dc;
0849
0850
0851 enum dcc_control dcc_control;
0852 unsigned int bpe;
0853 enum segment_order segment_order_horz, segment_order_vert;
0854 bool req128_horz_wc, req128_vert_wc;
0855
0856 memset(output, 0, sizeof(*output));
0857
0858 if (dc->debug.disable_dcc == DCC_DISABLE)
0859 return false;
0860
0861 if (!hubbub1->base.funcs->dcc_support_pixel_format(input->format, &bpe))
0862 return false;
0863
0864 if (!hubbub1->base.funcs->dcc_support_swizzle(input->swizzle_mode, bpe,
0865 &segment_order_horz, &segment_order_vert))
0866 return false;
0867
0868 hubbub1_det_request_size(input->surface_size.height, input->surface_size.width,
0869 bpe, &req128_horz_wc, &req128_vert_wc);
0870
0871 if (!req128_horz_wc && !req128_vert_wc) {
0872 dcc_control = dcc_control__256_256_xxx;
0873 } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
0874 if (!req128_horz_wc)
0875 dcc_control = dcc_control__256_256_xxx;
0876 else if (segment_order_horz == segment_order__contiguous)
0877 dcc_control = dcc_control__128_128_xxx;
0878 else
0879 dcc_control = dcc_control__256_64_64;
0880 } else if (input->scan == SCAN_DIRECTION_VERTICAL) {
0881 if (!req128_vert_wc)
0882 dcc_control = dcc_control__256_256_xxx;
0883 else if (segment_order_vert == segment_order__contiguous)
0884 dcc_control = dcc_control__128_128_xxx;
0885 else
0886 dcc_control = dcc_control__256_64_64;
0887 } else {
0888 if ((req128_horz_wc &&
0889 segment_order_horz == segment_order__non_contiguous) ||
0890 (req128_vert_wc &&
0891 segment_order_vert == segment_order__non_contiguous))
0892
0893 dcc_control = dcc_control__256_64_64;
0894 else
0895
0896
0897
0898 dcc_control = dcc_control__128_128_xxx;
0899 }
0900
0901 if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
0902 dcc_control != dcc_control__256_256_xxx)
0903 return false;
0904
0905 switch (dcc_control) {
0906 case dcc_control__256_256_xxx:
0907 output->grph.rgb.max_uncompressed_blk_size = 256;
0908 output->grph.rgb.max_compressed_blk_size = 256;
0909 output->grph.rgb.independent_64b_blks = false;
0910 break;
0911 case dcc_control__128_128_xxx:
0912 output->grph.rgb.max_uncompressed_blk_size = 128;
0913 output->grph.rgb.max_compressed_blk_size = 128;
0914 output->grph.rgb.independent_64b_blks = false;
0915 break;
0916 case dcc_control__256_64_64:
0917 output->grph.rgb.max_uncompressed_blk_size = 256;
0918 output->grph.rgb.max_compressed_blk_size = 64;
0919 output->grph.rgb.independent_64b_blks = true;
0920 break;
0921 default:
0922 ASSERT(false);
0923 break;
0924 }
0925
0926 output->capable = true;
0927 output->const_color_support = false;
0928
0929 return true;
0930 }
0931
0932 static const struct hubbub_funcs hubbub1_funcs = {
0933 .update_dchub = hubbub1_update_dchub,
0934 .dcc_support_swizzle = hubbub1_dcc_support_swizzle,
0935 .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format,
0936 .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
0937 .wm_read_state = hubbub1_wm_read_state,
0938 .program_watermarks = hubbub1_program_watermarks,
0939 .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
0940 .allow_self_refresh_control = hubbub1_allow_self_refresh_control,
0941 .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
0942 };
0943
0944 void hubbub1_construct(struct hubbub *hubbub,
0945 struct dc_context *ctx,
0946 const struct dcn_hubbub_registers *hubbub_regs,
0947 const struct dcn_hubbub_shift *hubbub_shift,
0948 const struct dcn_hubbub_mask *hubbub_mask)
0949 {
0950 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
0951
0952 hubbub1->base.ctx = ctx;
0953
0954 hubbub1->base.funcs = &hubbub1_funcs;
0955
0956 hubbub1->regs = hubbub_regs;
0957 hubbub1->shifts = hubbub_shift;
0958 hubbub1->masks = hubbub_mask;
0959
0960 hubbub1->debug_test_index_pstate = 0x7;
0961 if (ctx->dce_version == DCN_VERSION_1_01)
0962 hubbub1->debug_test_index_pstate = 0xB;
0963 }
0964