idle.c (8747bf36f312356f8a295a0c39ff092d65ce75ae) idle.c (dcbbfa6b05daca94ebcdbce80a7cf05c717d2942)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * PowerNV cpuidle code
4 *
5 * Copyright 2015 IBM Corp.
6 */
7
8#include <linux/types.h>

--- 34 unchanged lines hidden (view full) ---

43static u64 pnv_default_stop_val;
44static u64 pnv_default_stop_mask;
45static bool default_stop_found;
46
47/*
48 * First stop state levels when SPR and TB loss can occur.
49 */
50static u64 pnv_first_tb_loss_level = MAX_STOP_STATE + 1;
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * PowerNV cpuidle code
4 *
5 * Copyright 2015 IBM Corp.
6 */
7
8#include <linux/types.h>

--- 34 unchanged lines hidden (view full) ---

43static u64 pnv_default_stop_val;
44static u64 pnv_default_stop_mask;
45static bool default_stop_found;
46
47/*
48 * First stop state levels when SPR and TB loss can occur.
49 */
50static u64 pnv_first_tb_loss_level = MAX_STOP_STATE + 1;
51static u64 pnv_first_spr_loss_level = MAX_STOP_STATE + 1;
51static u64 deep_spr_loss_state = MAX_STOP_STATE + 1;
52
53/*
54 * psscr value and mask of the deepest stop idle state.
55 * Used when a cpu is offlined.
56 */
57static u64 pnv_deepest_stop_psscr_val;
58static u64 pnv_deepest_stop_psscr_mask;
59static u64 pnv_deepest_stop_flag;

--- 608 unchanged lines hidden (view full) ---

668 * since it is previleged resource and will be lost.
669 * Thus, if we do not save and restore the MMCRA[BHRBD],
670 * hardware will be needlessly writing to the BHRB
671 * in problem mode.
672 */
673 mmcra = mfspr(SPRN_MMCRA);
674 }
675
52
53/*
54 * psscr value and mask of the deepest stop idle state.
55 * Used when a cpu is offlined.
56 */
57static u64 pnv_deepest_stop_psscr_val;
58static u64 pnv_deepest_stop_psscr_mask;
59static u64 pnv_deepest_stop_flag;

--- 608 unchanged lines hidden (view full) ---

668 * since it is previleged resource and will be lost.
669 * Thus, if we do not save and restore the MMCRA[BHRBD],
670 * hardware will be needlessly writing to the BHRB
671 * in problem mode.
672 */
673 mmcra = mfspr(SPRN_MMCRA);
674 }
675
676 if ((psscr & PSSCR_RL_MASK) >= pnv_first_spr_loss_level) {
676 if ((psscr & PSSCR_RL_MASK) >= deep_spr_loss_state) {
677 sprs.lpcr = mfspr(SPRN_LPCR);
678 sprs.hfscr = mfspr(SPRN_HFSCR);
679 sprs.fscr = mfspr(SPRN_FSCR);
680 sprs.pid = mfspr(SPRN_PID);
681 sprs.purr = mfspr(SPRN_PURR);
682 sprs.spurr = mfspr(SPRN_SPURR);
683 sprs.dscr = mfspr(SPRN_DSCR);
684 sprs.wort = mfspr(SPRN_WORT);

--- 69 unchanged lines hidden (view full) ---

754 hmi_exception_realmode(NULL);
755
756 /*
757 * On POWER9, SRR1 bits do not match exactly as expected.
758 * SRR1_WS_GPRLOSS (10b) can also result in SPR loss, so
759 * just always test PSSCR for SPR/TB state loss.
760 */
761 pls = (psscr & PSSCR_PLS) >> PSSCR_PLS_SHIFT;
677 sprs.lpcr = mfspr(SPRN_LPCR);
678 sprs.hfscr = mfspr(SPRN_HFSCR);
679 sprs.fscr = mfspr(SPRN_FSCR);
680 sprs.pid = mfspr(SPRN_PID);
681 sprs.purr = mfspr(SPRN_PURR);
682 sprs.spurr = mfspr(SPRN_SPURR);
683 sprs.dscr = mfspr(SPRN_DSCR);
684 sprs.wort = mfspr(SPRN_WORT);

--- 69 unchanged lines hidden (view full) ---

754 hmi_exception_realmode(NULL);
755
756 /*
757 * On POWER9, SRR1 bits do not match exactly as expected.
758 * SRR1_WS_GPRLOSS (10b) can also result in SPR loss, so
759 * just always test PSSCR for SPR/TB state loss.
760 */
761 pls = (psscr & PSSCR_PLS) >> PSSCR_PLS_SHIFT;
762 if (likely(pls < pnv_first_spr_loss_level)) {
762 if (likely(pls < deep_spr_loss_state)) {
763 if (sprs_saved)
764 atomic_stop_thread_idle();
765 goto out;
766 }
767
768 /* HV state loss */
769 BUG_ON(!sprs_saved);
770

--- 330 unchanged lines hidden (view full) ---

1101 /*
1102 * pnv_deepest_stop_{val,mask} should be set to values corresponding to
1103 * the deepest stop state.
1104 *
1105 * pnv_default_stop_{val,mask} should be set to values corresponding to
1106 * the deepest loss-less (OPAL_PM_STOP_INST_FAST) stop state.
1107 */
1108 pnv_first_tb_loss_level = MAX_STOP_STATE + 1;
763 if (sprs_saved)
764 atomic_stop_thread_idle();
765 goto out;
766 }
767
768 /* HV state loss */
769 BUG_ON(!sprs_saved);
770

--- 330 unchanged lines hidden (view full) ---

1101 /*
1102 * pnv_deepest_stop_{val,mask} should be set to values corresponding to
1103 * the deepest stop state.
1104 *
1105 * pnv_default_stop_{val,mask} should be set to values corresponding to
1106 * the deepest loss-less (OPAL_PM_STOP_INST_FAST) stop state.
1107 */
1108 pnv_first_tb_loss_level = MAX_STOP_STATE + 1;
1109 pnv_first_spr_loss_level = MAX_STOP_STATE + 1;
1109 deep_spr_loss_state = MAX_STOP_STATE + 1;
1110 for (i = 0; i < nr_pnv_idle_states; i++) {
1111 int err;
1112 struct pnv_idle_states_t *state = &pnv_idle_states[i];
1113 u64 psscr_rl = state->psscr_val & PSSCR_RL_MASK;
1114
1115 if ((state->flags & OPAL_PM_TIMEBASE_STOP) &&
1116 (pnv_first_tb_loss_level > psscr_rl))
1117 pnv_first_tb_loss_level = psscr_rl;
1118
1119 if ((state->flags & OPAL_PM_LOSE_FULL_CONTEXT) &&
1110 for (i = 0; i < nr_pnv_idle_states; i++) {
1111 int err;
1112 struct pnv_idle_states_t *state = &pnv_idle_states[i];
1113 u64 psscr_rl = state->psscr_val & PSSCR_RL_MASK;
1114
1115 if ((state->flags & OPAL_PM_TIMEBASE_STOP) &&
1116 (pnv_first_tb_loss_level > psscr_rl))
1117 pnv_first_tb_loss_level = psscr_rl;
1118
1119 if ((state->flags & OPAL_PM_LOSE_FULL_CONTEXT) &&
1120 (pnv_first_spr_loss_level > psscr_rl))
1121 pnv_first_spr_loss_level = psscr_rl;
1120 (deep_spr_loss_state > psscr_rl))
1121 deep_spr_loss_state = psscr_rl;
1122
1123 /*
1124 * The idle code does not deal with TB loss occurring
1125 * in a shallower state than SPR loss, so force it to
1126 * behave like SPRs are lost if TB is lost. POWER9 would
1127 * never encouter this, but a POWER8 core would if it
1128 * implemented the stop instruction. So this is for forward
1129 * compatibility.
1130 */
1131 if ((state->flags & OPAL_PM_TIMEBASE_STOP) &&
1122
1123 /*
1124 * The idle code does not deal with TB loss occurring
1125 * in a shallower state than SPR loss, so force it to
1126 * behave like SPRs are lost if TB is lost. POWER9 would
1127 * never encouter this, but a POWER8 core would if it
1128 * implemented the stop instruction. So this is for forward
1129 * compatibility.
1130 */
1131 if ((state->flags & OPAL_PM_TIMEBASE_STOP) &&
1132 (pnv_first_spr_loss_level > psscr_rl))
1133 pnv_first_spr_loss_level = psscr_rl;
1132 (deep_spr_loss_state > psscr_rl))
1133 deep_spr_loss_state = psscr_rl;
1134
1135 err = validate_psscr_val_mask(&state->psscr_val,
1136 &state->psscr_mask,
1137 state->flags);
1138 if (err) {
1139 report_invalid_psscr_val(state->psscr_val, err);
1140 continue;
1141 }

--- 29 unchanged lines hidden (view full) ---

1171 pr_warn("cpuidle-powernv: No suitable stop state for CPU-Hotplug. Offlined CPUs will busy wait");
1172 } else {
1173 pr_info("cpuidle-powernv: Deepest stop: psscr = 0x%016llx,mask=0x%016llx\n",
1174 pnv_deepest_stop_psscr_val,
1175 pnv_deepest_stop_psscr_mask);
1176 }
1177
1178 pr_info("cpuidle-powernv: First stop level that may lose SPRs = 0x%llx\n",
1134
1135 err = validate_psscr_val_mask(&state->psscr_val,
1136 &state->psscr_mask,
1137 state->flags);
1138 if (err) {
1139 report_invalid_psscr_val(state->psscr_val, err);
1140 continue;
1141 }

--- 29 unchanged lines hidden (view full) ---

1171 pr_warn("cpuidle-powernv: No suitable stop state for CPU-Hotplug. Offlined CPUs will busy wait");
1172 } else {
1173 pr_info("cpuidle-powernv: Deepest stop: psscr = 0x%016llx,mask=0x%016llx\n",
1174 pnv_deepest_stop_psscr_val,
1175 pnv_deepest_stop_psscr_mask);
1176 }
1177
1178 pr_info("cpuidle-powernv: First stop level that may lose SPRs = 0x%llx\n",
1179 pnv_first_spr_loss_level);
1179 deep_spr_loss_state);
1180
1181 pr_info("cpuidle-powernv: First stop level that may lose timebase = 0x%llx\n",
1182 pnv_first_tb_loss_level);
1183}
1184
1185static void __init pnv_disable_deep_states(void)
1186{
1187 /*

--- 232 unchanged lines hidden ---
1180
1181 pr_info("cpuidle-powernv: First stop level that may lose timebase = 0x%llx\n",
1182 pnv_first_tb_loss_level);
1183}
1184
1185static void __init pnv_disable_deep_states(void)
1186{
1187 /*

--- 232 unchanged lines hidden ---