Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure TOD for up to two CPUs #97

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/include/cpu/power/istep_10.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ struct pci_info;
void istep_10_1(uint8_t chips);
void istep_10_10(uint8_t chips, struct pci_info *pci_info);
void istep_10_12(uint8_t chips);
void istep_10_13(void);
void istep_10_13(uint8_t chips);

#endif /* CPU_PPC64_ISTEP10_H */
14 changes: 11 additions & 3 deletions src/include/cpu/power/istep_18.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef CPU_PPC64_ISTEP18_H
#define CPU_PPC64_ISTEP18_H

#include <cpu/power/scom.h>
#include <stdint.h>

void istep_18_11(void);
void istep_18_12(void);
void istep_18_11(uint8_t chips, uint8_t *mdmt);
void istep_18_12(uint8_t chips, uint8_t mdmt);

/* TODO: everything is used internally only, don't define it in public header */
/* TODO: check again if all bits are using PPC_BIT numbering */
Expand All @@ -16,7 +22,7 @@ void istep_18_12(void);
#define PERV_TOD_TX_TTYPE_REG_TRIGGER (0)

#define MDMT_TOD_GRID_CYCLE_STAGING_DELAY (6)
#define FREQ_X_MHZ (1800)
#define FREQ_X_MHZ (2000)
#define TOD_GRID_PS (400)

/* FIXME: P9A?! */
Expand Down Expand Up @@ -163,3 +169,5 @@ void istep_18_12(void);
// [28:31] RW S_PATH_REMOTE_SYNC_CHECK_CPS_DEVIATION: Slave path-01: remote sync: sync-step check: CPS deviation.
// [32:39] RW S_PATH_REMOTE_SYNC_MISS_COUNT_MAX: Slave path-01: remote sync: maximum of SYNC miss counts: 0 - 255 syncs.
#define PERV_TOD_S_PATH_CTRL_REG (0x00040005)

#endif /* CPU_PPC64_ISTEP18_H */
80 changes: 44 additions & 36 deletions src/soc/ibm/power9/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,44 +429,51 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup,
return 0;
}

static void rng_init(void)
static void rng_init(uint8_t chips)
{
/*
* RNG is allowed to run for M cycles (M = enough time to complete init;
* recommend 1 second of time).
*
* The only thing that ensures this is delay between istep 10.13 and now.
* 14.1 is the most time-consuming istep, its duration depends on the amount
* of installed RAM under the bigger of MCBISTs (i.e. sides of CPU on the
* board). This is more than enough in Hostboot.
*
* TODO: test if this is enough for coreboot with initial ECC scrubbing
* skipped, low amount of RAM and no debug output.
*/
/* NX.PBI.PBI_RNG.NX_RNG_CFG
* [0-9] FAIL_REG - abort if any of these bits is set
* [17] BIST_COMPLETE - should be 1 at this point
*/
uint64_t rng_status = read_scom(0x020110E0);
assert(rng_status & PPC_BIT(17));
while (!((rng_status = read_scom(0x020110E0)) & PPC_BIT(17)));
uint8_t chip;

if (rng_status & PPC_BITMASK(0, 9))
die("RNG initialization failed, NX_RNG_CFG = %#16.16llx\n", rng_status);
for (chip = 0; chip < MAX_CHIPS; chip++) {
if (!(chips & (1 << chip)))
continue;

/*
* Hostboot sets 'enable' bit again even though it was already set.
* Following that behavior just in case.
*/
write_scom(0x020110E0, rng_status | PPC_BIT(63));
/*
* RNG is allowed to run for M cycles (M = enough time to complete init;
* recommend 1 second of time).
*
* The only thing that ensures this is delay between istep 10.13 and now.
* 14.1 is the most time-consuming istep, its duration depends on the amount
* of installed RAM under the bigger of MCBISTs (i.e. sides of CPU on the
* board). This is more than enough in Hostboot.
*
* TODO: test if this is enough for coreboot with initial ECC scrubbing
* skipped, low amount of RAM and no debug output.
*/
/* NX.PBI.PBI_RNG.NX_RNG_CFG
* [0-9] FAIL_REG - abort if any of these bits is set
* [17] BIST_COMPLETE - should be 1 at this point
*/
uint64_t rng_status = read_rscom(chip, 0x020110E0);
assert(rng_status & PPC_BIT(17));
while (!((rng_status = read_rscom(chip, 0x020110E0)) & PPC_BIT(17)));

/*
* This would be the place to set BARs, but it is done as part of quad SCOM
* restore.
*/
if (rng_status & PPC_BITMASK(0, 9))
die("RNG initialization failed, NX_RNG_CFG = %#16.16llx\n", rng_status);

/* Lock NX RNG configuration */
scom_or(0x00010005, PPC_BIT(9));
/*
* Hostboot sets 'enable' bit again even though it was already set.
* Following that behavior just in case.
*/
write_rscom(chip, 0x020110E0, rng_status | PPC_BIT(63));

/*
* This would be the place to set BARs, but it is done as part of quad SCOM
* restore.
*/

/* Lock NX RNG configuration */
rscom_or(chip, 0x00010005, PPC_BIT(9));
}
}

#define SIZE_MASK PPC_BITMASK(13,23)
Expand All @@ -492,6 +499,7 @@ static void enable_soc_dev(struct device *dev)
int chip, idx = 0;
unsigned long reserved_size, homers_size, occ_area, top = 0;
uint8_t chips = fsi_get_present_chips();
uint8_t tod_mdmt;

for (chip = 0; chip < MAX_CHIPS; chip++) {
int mcs_i;
Expand Down Expand Up @@ -551,9 +559,9 @@ static void enable_soc_dev(struct device *dev)
&device_tree_fixups);
}
}
rng_init();
istep_18_11();
istep_18_12();
rng_init(chips);
istep_18_11(chips, &tod_mdmt);
istep_18_12(chips, tod_mdmt);
}

static void activate_slave_cores(void)
Expand Down
65 changes: 39 additions & 26 deletions src/soc/ibm/power9/istep_10_13.c
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <cpu/power/istep_10.h>

#include <console/console.h>
#include <cpu/power/scom.h>
#include <cpu/power/proc.h>

void istep_10_13(void);
/*
* 10.13 host_rng_bist: Trigger Built In Self Test for RNG
*
* a) p9_rng_init_phase1.C
* - Trigger the Random Number Generator Built In Self Test (BIST). Results
* are checked later in step 16 when RNG is secured
*/
void istep_10_13(void)
{
printk(BIOS_EMERG, "starting istep 10.13\n");

report_istep(10,13);

static void host_rng_bist(uint8_t chip)
{
/* Assume DD2.0 or newer */

/* PU_NX_RNG_CFG
[44] COND_STARTUP_TEST_FAIL
*/
if (read_scom_for_chiplet(N0_CHIPLET_ID, 0x020110E0) & PPC_BIT(44))
if (read_rscom_for_chiplet(chip, N0_CHIPLET_ID, 0x020110E0) & PPC_BIT(44))
die("RNG Conditioner startup test failed\n");

/* PU_NX_RNG_ST0
Expand All @@ -34,37 +33,37 @@ void istep_10_13(void)
[36-47] ADAPTEST_CRN_RNG0_MATCH_TH = 0x32 (50; Assuming H = 5)
[48-59] ADAPTEST_CRN_RNG1_MATCH_TH = 0x32 (50; Assuming H = 5)
*/
scom_and_or_for_chiplet(N0_CHIPLET_ID, 0x020110E1,
~(PPC_BITMASK(0, 1) | PPC_BITMASK(7, 63)),
PPC_PLACE(1, 0, 2) | PPC_PLACE(2, 7, 2) | PPC_PLACE(1, 9, 3)
| PPC_PLACE(0x32, 12, 12) | PPC_PLACE(0x32, 24, 12)
| PPC_PLACE(0x32, 36, 12) | PPC_PLACE(0x32, 48, 12));
rscom_and_or_for_chiplet(chip, N0_CHIPLET_ID, 0x020110E1,
~(PPC_BITMASK(0, 1) | PPC_BITMASK(7, 63)),
PPC_PLACE(1, 0, 2) | PPC_PLACE(2, 7, 2) | PPC_PLACE(1, 9, 3)
| PPC_PLACE(0x32, 12, 12) | PPC_PLACE(0x32, 24, 12)
| PPC_PLACE(0x32, 36, 12) | PPC_PLACE(0x32, 48, 12));

/* PU_NX_RNG_ST1
[0-6] ADAPTEST_SOFT_FAIL_TH = 2
[7-22] ADAPTEST_1BIT_MATCH_TH_MIN = 100
[23-38] ADAPTEST_1BIT_MATCH_TH_MAX = 415
*/
scom_and_or_for_chiplet(N0_CHIPLET_ID, 0x020110E2, ~PPC_BITMASK(0, 38),
PPC_PLACE(2, 0, 7) | PPC_PLACE(100, 7, 16)
| PPC_PLACE(415, 23, 16));
rscom_and_or_for_chiplet(chip, N0_CHIPLET_ID, 0x020110E2, ~PPC_BITMASK(0, 38),
PPC_PLACE(2, 0, 7) | PPC_PLACE(100, 7, 16)
| PPC_PLACE(415, 23, 16));

/* PU_NX_RNG_ST3
[0] SAMPTEST_RRN_ENABLE = 1
[1-3] SAMPTEST_WINDOW_SIZE = 7 (64k -1 size)
[4-19] SAMPTEST_MATCH_TH_MIN = 0x6D60 (28,000)
[20-35] SAMPTEST_MATCH_TH_MAX = 0x988A (39,050)
*/
scom_and_or_for_chiplet(N0_CHIPLET_ID, 0x020110E8, ~PPC_BITMASK(0, 35),
PPC_BIT(0) | PPC_PLACE(7, 1, 3) | PPC_PLACE(0x6D60, 4, 16)
| PPC_PLACE(0x988A, 20, 16));
rscom_and_or_for_chiplet(chip, N0_CHIPLET_ID, 0x020110E8, ~PPC_BITMASK(0, 35),
PPC_BIT(0) | PPC_PLACE(7, 1, 3) | PPC_PLACE(0x6D60, 4, 16)
| PPC_PLACE(0x988A, 20, 16));

/* PU_NX_RNG_RDELAY
[6] LFSR_RESEED_EN = 1
[7-11] READ_RTY_RATIO = 0x1D (1/16)
*/
scom_and_or_for_chiplet(N0_CHIPLET_ID, 0x020110E5, ~PPC_BITMASK(6, 11),
PPC_BIT(6) | PPC_PLACE(0x1D, 7, 5));
rscom_and_or_for_chiplet(chip, N0_CHIPLET_ID, 0x020110E5, ~PPC_BITMASK(6, 11),
PPC_BIT(6) | PPC_PLACE(0x1D, 7, 5));

/* PU_NX_RNG_CFG
[30-37] ST2_RESET_PERIOD = 0x1B
Expand All @@ -76,12 +75,26 @@ void istep_10_13(void)
[46-61] PACE_RATE = 0x07D0 (2000)
[63] ENABLE = 1
*/
scom_and_or_for_chiplet(N0_CHIPLET_ID, 0x020110E0,
~(PPC_BITMASK(30, 37) | PPC_BITMASK(39, 43)
| PPC_BITMASK(46, 61) | PPC_BIT(63)),
PPC_PLACE(0x1B, 30, 8) | PPC_BIT(40) | PPC_BIT(41)
| PPC_BIT(42) | PPC_BIT(43) | PPC_PLACE(0x07D0, 46, 16)
| PPC_BIT(63));
rscom_and_or_for_chiplet(chip, N0_CHIPLET_ID, 0x020110E0,
~(PPC_BITMASK(30, 37) | PPC_BITMASK(39, 43)
| PPC_BITMASK(46, 61) | PPC_BIT(63)),
PPC_PLACE(0x1B, 30, 8) | PPC_BIT(40) | PPC_BIT(41)
| PPC_BIT(42) | PPC_BIT(43) | PPC_PLACE(0x07D0, 46, 16)
| PPC_BIT(63));
}

void istep_10_13(uint8_t chips)
{
uint8_t chip;

printk(BIOS_EMERG, "starting istep 10.13\n");

report_istep(10,13);

for (chip = 0; chip < MAX_CHIPS; chip++) {
if (chips & (1 << chip))
host_rng_bist(chip);
}

printk(BIOS_EMERG, "ending istep 10.13\n");
}
Loading