nb/intel/sandybridge: Use arrays to program IOSAV

Instead of programming subsequences one-by-one, we might as well take
the whole sequence as an array and program all subsequences in one go.

Since the number of subsequences is now known in advance, handling of
global state can be simplified, which allows reusing the last sequence.

Change-Id: Ica1b2b20e04ae368f10aa236ca24d12f69464430
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47492
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Angel Pons 2020-11-11 23:03:36 +01:00
parent 1c505f8277
commit 8f0757ea94
3 changed files with 386 additions and 569 deletions

File diff suppressed because it is too large Load Diff

View File

@ -98,7 +98,7 @@ struct iosav_ssq {
} addr_update;
};
void iosav_write_ssq(const int ch, const struct iosav_ssq *ssq);
void iosav_write_sequence(const int ch, const struct iosav_ssq *seq, const unsigned int length);
void iosav_run_queue(const int ch, const u8 loops, const u8 as_timer);
void iosav_run_once(const int ch);
void wait_for_iosav(int channel);

View File

@ -15,21 +15,25 @@
/* Number of programmed IOSAV subsequences. */
static unsigned int ssq_count = 0;
void iosav_write_ssq(const int ch, const struct iosav_ssq *ssq)
void iosav_write_sequence(const int ch, const struct iosav_ssq *seq, const unsigned int length)
{
MCHBAR32(IOSAV_n_SP_CMD_CTRL_ch(ch, ssq_count)) = ssq->sp_cmd_ctrl.raw;
MCHBAR32(IOSAV_n_SUBSEQ_CTRL_ch(ch, ssq_count)) = ssq->subseq_ctrl.raw;
MCHBAR32(IOSAV_n_SP_CMD_ADDR_ch(ch, ssq_count)) = ssq->sp_cmd_addr.raw;
MCHBAR32(IOSAV_n_ADDR_UPDATE_ch(ch, ssq_count)) = ssq->addr_update.raw;
for (unsigned int i = 0; i < length; i++) {
MCHBAR32(IOSAV_n_SP_CMD_CTRL_ch(ch, i)) = seq[i].sp_cmd_ctrl.raw;
MCHBAR32(IOSAV_n_SUBSEQ_CTRL_ch(ch, i)) = seq[i].subseq_ctrl.raw;
MCHBAR32(IOSAV_n_SP_CMD_ADDR_ch(ch, i)) = seq[i].sp_cmd_addr.raw;
MCHBAR32(IOSAV_n_ADDR_UPDATE_ch(ch, i)) = seq[i].addr_update.raw;
}
ssq_count++;
ssq_count = length;
}
void iosav_run_queue(const int ch, const u8 loops, const u8 as_timer)
{
MCHBAR32(IOSAV_SEQ_CTL_ch(ch)) = loops | ((ssq_count - 1) << 18) | (as_timer << 22);
/* Should never happen */
if (ssq_count == 0)
return;
ssq_count = 0;
MCHBAR32(IOSAV_SEQ_CTL_ch(ch)) = loops | ((ssq_count - 1) << 18) | (as_timer << 22);
}
void iosav_run_once(const int ch)