diff --git a/src/include/cpu/power/istep8.h b/src/include/cpu/power/istep8.h new file mode 100644 index 00000000000..6e1ac194116 --- /dev/null +++ b/src/include/cpu/power/istep8.h @@ -0,0 +1,354 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_ISTEP8_H +#define SOC_ISTEP8_H + +enum FABRIC_ASYNC_MODE +{ + FABRIC_ASYNC_PERFORMANCE_MODE = 0x0, + FABRIC_ASYNC_SAFE_MODE = 0x1, +}; + +enum FABRIC_CORE_FLOOR_RATIO +{ + FABRIC_CORE_FLOOR_RATIO_RATIO_8_8 = 0x0, + FABRIC_CORE_FLOOR_RATIO_RATIO_7_8 = 0x1, + FABRIC_CORE_FLOOR_RATIO_RATIO_6_8 = 0x2, + FABRIC_CORE_FLOOR_RATIO_RATIO_5_8 = 0x3, + FABRIC_CORE_FLOOR_RATIO_RATIO_4_8 = 0x4, + FABRIC_CORE_FLOOR_RATIO_RATIO_2_8 = 0x5, +}; + +enum FABRIC_CORE_CEILING_RATIO +{ + FABRIC_CORE_CEILING_RATIO_RATIO_8_8 = 0x0, + FABRIC_CORE_CEILING_RATIO_RATIO_7_8 = 0x1, + FABRIC_CORE_CEILING_RATIO_RATIO_6_8 = 0x2, + FABRIC_CORE_CEILING_RATIO_RATIO_5_8 = 0x3, + FABRIC_CORE_CEILING_RATIO_RATIO_4_8 = 0x4, + FABRIC_CORE_CEILING_RATIO_RATIO_2_8 = 0x5, +}; + +#define EPSILON_MIN_VALUE 0x1; +#define EPSILON_MAX_VALUE 0xFFFFFFFF; + +#define NUM_EPSILON_READ_TIERS 3; +#define NUM_EPSILON_WRITE_TIERS 2; + +#define CHIP_IS_NODE 0x01 +#define CHIP_IS_GROUP 0x02 + +/* From src/import/chips/p9/procedures/xml/attribute_info/nest_attributes.xml */ +#define EPS_TYPE_LE 0x01 +#define EPS_TYPE_HE 0x02 +#define EPS_TYPE_HE_F8 0x03 + +/*--------------ISTEP_8_7-------------------------*/ + +#define ENUM_ATTR_LINK_TRAIN_BOTH 0x0 +#define ENUM_ATTR_LINK_TRAIN_EVEN_ONLY 0x1 +#define ENUM_ATTR_LINK_TRAIN_ODD_ONLY 0x2 +/*#define ENUM_ATTR_LINK_TRAIN_NONE 0x3*/ + +#define ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_FALSE 0x0 +#define ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_TRUE 0x1 +#define ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_EVEN_ONLY 0x2 +#define ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_ODD_ONLY 0x3 + +#define ENUM_ATTR_PROC_FABRIC_LINK_ACTIVE_FALSE 0x0 +#define ENUM_ATTR_PROC_FABRIC_LINK_ACTIVE_TRUE 0x1 + +#define ENUM_ATTR_OPTICS_CONFIG_MODE_SMP 0x0 + + +#define P9_FBC_UTILS_MAX_X_LINKS 7 +#define P9_FBC_UTILS_MAX_A_LINKS 4 + + +#define OBUS_LL0_LL0_LL0_PB_IOOL_FIR_REG 0x9010800 +#define OBUS_0_LL0_IOOL_CONTROL 0x901080B +#define OBUS_0_LL0_IOOL_DLL_STATUS 0x9010828 +#define OBUS_1_LL1_LL1_LL1_PB_IOOL_FIR_REG 0xA010800 +#define OBUS_1_LL1_IOOL_CONTROL 0xA01080B +#define OBUS_1_LL1_IOOL_DLL_STATUS 0xB010828 +#define OBUS_2_LL2_LL2_LL2_PB_IOOL_FIR_REG 0xB010800 +#define OBUS_2_LL2_IOOL_CONTROL 0xB01080B +#define OBUS_2_LL2_IOOL_DLL_STATUS 0xB010828 +#define OBUS_3_LL3_LL3_LL3_PB_IOOL_FIR_REG 0xC010800 +#define OBUS_3_LL3_IOOL_CONTROL 0xC01080B +#define OBUS_3_LL3_IOOL_DLL_STATUS 0xC010828 + +#define PERV_XB_CPLT_CONF1_OR 0x6000019 +#define PERV_XB_CPLT_CONF1_CLEAR 0x6000029 +#define PERV_1_CPLT_CONF1_IOVALID_4D 4 +#define PERV_1_CPLT_CONF1_IOVALID_6D 6 +#define PERV_1_CPLT_CONF1_IOVALID_8D 8 +#define PERV_OB0_CPLT_CONF1_OR 0x9000019 +#define PERV_OB0_CPLT_CONF1_CLEAR 0x9000029 +#define PERV_OB1_CPLT_CONF1_OR 0xA000019 +#define PERV_OB1_CPLT_CONF1_CLEAR 0xA000029 +#define PERV_OB2_CPLT_CONF1_OR 0xB000019 +#define PERV_OB2_CPLT_CONF1_CLEAR 0xB000029 +#define PERV_OB3_CPLT_CONF1_OR 0xC000019 +#define PERV_OB3_CPLT_CONF1_CLEAR 0xC000029 + +#define PU_PB_IOE_FIR_REG 0x5013400 +#define PU_PB_ELINK_DLY_0123_REG 0x501340E +#define PU_PB_ELINK_DLY_45_REG 0x501340F +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X0_FIR_ERR 0 +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X1_FIR_ERR 1 +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X2_FIR_ERR 2 +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X4_FIR_ERR 4 +#define PU_PB_IOE_FIR_REG_FMR00_TRAINED 0 +#define PU_PB_IOE_FIR_REG_FMR02_TRAINED 2 +#define PU_PB_IOE_FIR_REG_FMR04_TRAINED 4 +#define PU_IOE_PB_IOO_FIR_REG 0x5013800 +#define PU_IOE_PB_OLINK_DLY_0123_REG 0x501380E +#define PU-IOE_PB_PLINK_DLY_4567_REG 0x501380F +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X3_FIR_ERR 3 +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X4_FIR_ERR 4 +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X5_FIR_ERR 5 +#define PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X6_FIR_ERR 6 +#define PU_IOE_PB_IOO_FIR_REG_FMR00_TRAINED 0 +#define PU_IOE_PB_IOO_FIR_REG_FMR02_TRAINED 2 +#define PU_IOE_PB_IOO_FIR_REG_FMR04_TRAINED 4 +#define PU_IOE_PB_IOO_FIR_REG_FMR06_TRAINED 6 + +#define XBUS_LL0_LL0_LL0_IOEL_FIR_REG 0x6011800 +#define XBUS_0_LL0_IOEL_CONTROL 0x601180B +#define XBUS_LL0_IOEL_DLL_STATUS 0x6011828 +#define XBUS_1_LL1_LL1_LL1_IOEL_FIR_REG 0x6011C00 +#define XBUS_1_LL1_IOEL_CONTROl 0x6011C0B +#define XBUS_1_LL1_IOEL_DLL_STATUS 0x6011C28 +#define XBUS_2_LL2_LL2_LL2_IOEL_FIR_REG 0x6012000 +#define XBUS_2_LL2_IOEL_CONTROL 0x601200B +#define XBUS_2_LL2_IOEL_DLL_STATUS 0x6012028 + + + + + +/*-src/import/chips/p9/procedures/hwp/nest/p9_fbc_smp_utils.H*/ +// link types +enum p9_fbc_link_t +{ + ELECTRICAL = TARGET_TYPE_XBUS + OPTICAL = TARGET_TYPE_OBUS +}; + +// XBUS/ABUS link control structure +struct p9_fbc_link_ctl_t +{ + // associated endpoint target type & unit target number + p9_fbc_link_t endp_type; + uint8_t endp_unit_id; + // iovalid SCOM addresses/control field + uint64_t iovalid_or_addr; + uint64_t iovalid_clear_addr; + uint8_t iovalid_field_start_bit; + // EXTFIR/RAS control field + uint8_t ras_fir_field_bit; + // DL layer SCOM addresses + uint64_t dl_fir_addr; + uint64_t dl_control_addr; + uint64_t dl_status_addr; + // TL layer SCOM addresses + uint64_t tl_fir_addr; + uint8_t tl_fir_trained_field_start_bit; + uint64_t tl_link_delay_addr; + uint32_t tl_link_delay_hi_start_bit; + uint32_t tl_link_delay_lo_start_bit; +}; + +const p9_fbc_link_ctl_t P9_FBC_XBUS_LINK_CTL_ARR[P9_FBC_UTILS_MAX_X_LINKS] = +{ + { + ELECTRICAL, + 0, + PERV_XB_CPLT_CONF1_OR, + PERV_XB_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X0_FIR_ERR, + XBUS_LL0_LL0_LL0_IOEL_FIR_REG, + XBUS_0_LL0_IOEL_CONTROL, + XBUS_LL0_IOEL_DLL_STATUS, + PU_PB_IOE_FIR_REG, + PU_PB_IOE_FIR_REG_FMR00_TRAINED, + PU_PB_ELINK_DLY_0123_REG, + 4, + 20 + }, + { + ELECTRICAL, + 1, + PERV_XB_CPLT_CONF1_OR, + PERV_XB_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_6D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X1_FIR_ERR, + XBUS_1_LL1_LL1_LL1_IOEL_FIR_REG, + XBUS_1_LL1_IOEL_CONTROL, + XBUS_1_LL1_IOEL_DLL_STATUS, + PU_PB_IOE_FIR_REG, + PU_PB_IOE_FIR_REG_FMR02_TRAINED, + PU_PB_ELINK_DLY_0123_REG, + 36, + 52 + }, + { + ELECTRICAL, + 2, + PERV_XB_CPLT_CONF1_OR, + PERV_XB_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_8D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X2_FIR_ERR, + XBUS_2_LL2_LL2_LL2_IOEL_FIR_REG, + XBUS_2_LL2_IOEL_CONTROL, + XBUS_2_LL2_IOEL_DLL_STATUS, + PU_PB_IOE_FIR_REG, + PU_PB_IOE_FIR_REG_FMR04_TRAINED, + PU_PB_ELINK_DLY_45_REG, + 4, + 20 + }, + { + OPTICAL, + 0, + PERV_OB0_CPLT_CONF1_OR, + PERV_OB0_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X3_FIR_ERR, + OBUS_LL0_LL0_LL0_PB_IOOL_FIR_REG, + OBUS_0_LL0_IOOL_CONTROL, + OBUS_0_LL0_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR00_TRAINED, + PU_IOE_PB_OLINK_DLY_0123_REG, + 4, + 20 + }, + { + OPTICAL, + 1, + PERV_OB1_CPLT_CONF1_OR, + PERV_OB1_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X4_FIR_ERR, + OBUS_1_LL1_LL1_LL1_PB_IOOL_FIR_REG, + OBUS_1_LL1_IOOL_CONTROL, + OBUS_1_LL1_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR02_TRAINED, + PU_IOE_PB_OLINK_DLY_0123_REG, + 36, + 52 + }, + { + OPTICAL, + 2, + PERV_OB2_CPLT_CONF1_OR, + PERV_OB2_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X5_FIR_ERR, + OBUS_2_LL2_LL2_LL2_PB_IOOL_FIR_REG, + OBUS_2_LL2_IOOL_CONTROL, + OBUS_2_LL2_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR04_TRAINED, + PU_IOE_PB_OLINK_DLY_4567_REG, + 4, + 20 + }, + { + OPTICAL, + 3, + PERV_OB3_CPLT_CONF1_OR, + PERV_OB3_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X6_FIR_ERR, + OBUS_3_LL3_LL3_LL3_PB_IOOL_FIR_REG, + OBUS_3_LL3_IOOL_CONTROL, + OBUS_3_LL3_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR06_TRAINED, + PU_IOE_PB_OLINK_DLY_4567_REG, + 36, + 52 + } +}; + +const p9_fbc_link_ctl_t P9_FBC_ABUS_LINK_CTL_ARR[P9_FBC_UTILS_MAX_A_LINKS] = +{ + { + OPTICAL, + 0, + PERV_OB0_CPLT_CONF1_OR, + PERV_OB0_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X3_FIR_ERR, + OBUS_LL0_LL0_LL0_PB_IOOL_FIR_REG, + OBUS_0_LL0_IOOL_CONTROL, + OBUS_0_LL0_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR00_TRAINED, + PU_IOE_PB_OLINK_DLY_0123_REG, + 4, + 20 + }, + { + OPTICAL, + 1, + PERV_OB1_CPLT_CONF1_OR, + PERV_OB1_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X4_FIR_ERR, + OBUS_1_LL1_LL1_LL1_PB_IOOL_FIR_REG, + OBUS_1_LL1_IOOL_CONTROL, + OBUS_1_LL1_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR02_TRAINED, + PU_IOE_PB_OLINK_DLY_0123_REG, + 36, + 52 + }, + { + OPTICAL, + 2, + PERV_OB2_CPLT_CONF1_OR, + PERV_OB2_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X5_FIR_ERR, + OBUS_2_LL2_LL2_LL2_PB_IOOL_FIR_REG, + OBUS_2_LL2_IOOL_CONTROL, + OBUS_2_LL2_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR04_TRAINED, + PU_IOE_PB_OLINK_DLY_4567_REG, + 4, + 20 + }, + { + OPTICAL, + 3, + PERV_OB3_CPLT_CONF1_OR, + PERV_OB3_CPLT_CONF1_CLEAR, + PERV_1_CPLT_CONF1_IOVALID_4D, + PU_PB_CENT_SM1_EXTFIR_MASK_REG_PB_X6_FIR_ERR, + OBUS_3_LL3_LL3_LL3_PB_IOOL_FIR_REG, + OBUS_3_LL3_IOOL_CONTROL, + OBUS_3_LL3_IOOL_DLL_STATUS, + PU_IOE_PB_IOO_FIR_REG, + PU_IOE_PB_IOO_FIR_REG_FMR06_TRAINED, + PU_IOE_PB_OLINK_DLY_4567_REG, + 36, + 52 + } +}; + +//P9_FBC_XBUS_LINK_CTL_ARR ok +//P9_FBC_ABUS_LINK_CTL_ARR ok +//SMP_ACTIVATE_PHASE1 +//SMP_ACTIVATE_PHASE2 +// p9_fbc_utils_get_chip_id_attr +// p9_fbc_utils_get_group_id_attr + +#endif diff --git a/src/soc/ibm/power9/Makefile.inc b/src/soc/ibm/power9/Makefile.inc index 14ee650584f..700656687bd 100644 --- a/src/soc/ibm/power9/Makefile.inc +++ b/src/soc/ibm/power9/Makefile.inc @@ -5,7 +5,8 @@ ifeq ($(CPU_IBM_POWER9),y) bootblock-y += bootblock.c postcar-y += exit_car.S romstage-y += romstage.c - +romstage-y += istep_8_6.c +romstage-y += istep_8_7.c ramstage-y += chip.c ramstage-y += timer.c diff --git a/src/soc/ibm/power9/istep_8_6.c b/src/soc/ibm/power9/istep_8_6.c new file mode 100644 index 00000000000..5c45e7919ef --- /dev/null +++ b/src/soc/ibm/power9/istep_8_6.c @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +/* From src/import/chips/p9/procedures/hwp/nest/p9_fbc_eff_config.C */ +/* LE epsilon (2 chips per-group) */ +static const uint32_t EPSILON_R_T0_LE[] = { 7, 7, 8, 8, 10, 22 }; +static const uint32_t EPSILON_R_T1_LE[] = { 7, 7, 8, 8, 10, 22 }; +static const uint32_t EPSILON_R_T2_LE[] = { 67, 69, 71, 74, 79, 103 }; +static const uint32_t EPSILON_W_T0_LE[] = { 0, 0, 0, 0, 0, 5 }; +static const uint32_t EPSILON_W_T1_LE[] = { 15, 16, 17, 19, 21, 33 }; + +/* HE epsilon (4 chips per-group) */ +static const uint32_t EPSILON_R_T0_HE[] = { 7, 7, 8, 8, 10, 22 }; +static const uint32_t EPSILON_R_T1_HE[] = { 92, 94, 96, 99, 104, 128 }; +static const uint32_t EPSILON_R_T2_HE[] = { 209, 210, 213, 216, 221, 245 }; +static const uint32_t EPSILON_W_T0_HE[] = { 28, 29, 30, 32, 34, 46 }; +static const uint32_t EPSILON_W_T1_HE[] = { 117, 118, 119, 121, 123, 135 }; + +/* HE epsilon (flat 4 Zeppelin) */ +static const uint32_t EPSILON_R_T0_F4[] = { 7, 7, 8, 8, 10, 22 }; +static const uint32_t EPSILON_R_T1_F4[] = { 7, 7, 8, 8, 10, 22 }; +static const uint32_t EPSILON_R_T2_F4[] = { 83, 84, 87, 90, 95, 119 }; +static const uint32_t EPSILON_W_T0_F4[] = { 0, 0, 0, 0, 0, 5 }; +static const uint32_t EPSILON_W_T1_F4[] = { 18, 19, 20, 22, 24, 36 }; + +/* HE epsilon (flat 8 configuration) */ +static const uint32_t EPSILON_R_T0_F8[] = { 7, 7, 8, 8, 10, 22 }; +static const uint32_t EPSILON_R_T1_F8[] = { 7, 7, 8, 8, 10, 22 }; +static const uint32_t EPSILON_R_T2_F8[] = { 148, 149, 152, 155, 160, 184 }; +static const uint32_t EPSILON_W_T0_F8[] = { 0, 0, 0, 0, 0, 5 }; +static const uint32_t EPSILON_W_T1_F8[] = { 76, 77, 78, 80, 82, 94 }; + + +/* Keep them global and later we can use function to retrieve the values set here */ + +uint32_t eps_r[NUM_EPSILON_READ_TIERS]; +uint32_t eps_w[NUM_EPSILON_WRITE_TIERS]; +int8_t eps_guardband; +uint8_t core_floor_ratio; +uint8_t core_ceiling_ratio; +uint32_t freq_fbc; +uint32_t freq_core_ceiling; + +static int p9_calculate_frequencies(uint8_t *floor_ratio, uint8_t *ceiling_ratio, + uint32_t *fbc_freq, uint32_t *freq_ceiling) +{ + /* Default 4800 from src/usr/targeting/common/xmltohb/hb_customized_attrs.xml */ + uint32_t freq_core_floor = 4800; + /* According to src/usr/targeting/common/xmltohb/attribute_types.xml + ATTR_FREQ_CORE_NOMINAL_MHZ maps to NOMINAL_FREQ_MHZ present in talos.xml */ + uint32_t freq_core_nom = 4800; + uint8_t async_safe_mode = FABRIC_ASYNC_PERFORMANCE_MODE; + *freq_ceiling = 4800; + + /* breakpoint ratio: core floor 4.0, pb 2.0 (cache floor :: pb = 8/8) */ + if ((freq_core_floor) >= (2 * (*fbc_freq))) { + *floor_ratio = FABRIC_CORE_FLOOR_RATIO_RATIO_8_8; + } + /* breakpoint ratio: core floor 3.5, pb 2.0 (cache floor :: pb = 7/8) */ + else if ((4 * freq_core_floor) >= (7 * (*fbc_freq))) { + *floor_ratio = FABRIC_CORE_FLOOR_RATIO_RATIO_7_8; + } + /* breakpoint ratio: core floor 3.0, pb 2.0 (cache floor :: pb = 6/8) */ + else if ((2 * freq_core_floor) >= (3 * (*fbc_freq))) { + *floor_ratio = FABRIC_CORE_FLOOR_RATIO_RATIO_6_8; + } + /* breakpoint ratio: core floor 2.5, pb 2.0 (cache floor :: pb = 5/8) */ + else if ((4 * freq_core_floor) >= (5 * (*fbc_freq))) { + *floor_ratio = FABRIC_CORE_FLOOR_RATIO_RATIO_5_8; + } + /* breakpoint ratio: core floor 2.0, pb 2.0 (cache floor :: pb = 4/8) */ + else if (freq_core_floor >= (*fbc_freq)) { + *floor_ratio = FABRIC_CORE_FLOOR_RATIO_RATIO_4_8; + } + /* breakpoint ratio: core floor 1.0, pb 2.0 (cache floor :: pb = 2/8) */ + else if ((2 * freq_core_floor) >= (*fbc_freq)) { + *floor_ratio = FABRIC_CORE_FLOOR_RATIO_RATIO_2_8; + } + else { + printk (BIOS_ERR, "Unsupported core ceiling/PB frequency ratio = (%d/%d)", + freq_core_floor, *fbc_freq); + return -1; + } + + /* breakpoint ratio: core ceiling 4.0, pb 2.0 (cache ceiling :: pb = 8/8) */ + if (*freq_ceiling >= (2 * (*fbc_freq))) { + *ceiling_ratio = FABRIC_CORE_CEILING_RATIO_RATIO_8_8; + } + /* breakpoint ratio: core ceiling 3.5, pb 2.0 (cache ceiling :: pb = 7/8) */ + else if ((4 * (*freq_ceiling)) >= (7 * (*fbc_freq))) { + *ceiling_ratio = FABRIC_CORE_CEILING_RATIO_RATIO_7_8; + } + /* breakpoint ratio: core ceiling 3.0, pb 2.0 (cache ceiling :: pb = 6/8) */ + else if ((2 * (*freq_ceiling)) >= (3 * (*fbc_freq))) { + *ceiling_ratio = FABRIC_CORE_CEILING_RATIO_RATIO_6_8; + } + /* breakpoint ratio: core ceiling 2.5, pb 2.0 (cache ceiling :: pb = 5/8) */ + else if ((4 * (*freq_ceiling)) >= (5 * (*fbc_freq))) { + *ceiling_ratio = FABRIC_CORE_CEILING_RATIO_RATIO_5_8; + } + /* breakpoint ratio: core ceiling 2.0, pb 2.0 (cache ceiling :: pb = 4/8) */ + else if ((*freq_ceiling) >= (*fbc_freq)) { + *ceiling_ratio = FABRIC_CORE_CEILING_RATIO_RATIO_4_8; + } + /* breakpoint ratio: core ceiling 1.0, pb 2.0 (cache ceiling :: pb = 2/8) */ + else if ((2 * (*freq_ceiling)) >= (*fbc_freq)) { + *ceiling_ratio = FABRIC_CORE_CEILING_RATIO_RATIO_2_8; + } + else { + printk (BIOS_ERR, "Unsupported core ceiling/PB frequency ratio = (%d/%d)", + *freq_ceiling, *fbc_freq); + return -1; + } + + return 0; +} + +static void config_guardband_epsilon(const uint8_t gb_percentage, uint32_t *target_value) +{ + uint32_t delta = (*target_value * gb_percentage) / 100; + delta += ((*target_value * gb_percentage) % 100) ? 1 : 0; + + printk(BIOS_DEBUG, "%s\n", __func__); + + /* Apply guardband */ + if (gb_percentage >= 0) + { + /* Clamp to maximum value if necessary */ + if (delta > (EPSILON_MAX_VALUE - target_value)) { + printk(BIOS_DEBUG, "Guardband application generated out-of-range target value," + " clamping to maximum value!\n"); + *target_value = EPSILON_MAX_VALUE; + } else { + *target_value += delta; + } + } + else + { + /* Clamp to minimum value if necessary */ + if (delta >= *target_value) { + printk(BIOS_DEBUG, "Guardband application generated out-of-range target value," + " clamping to minimum value!\n"); + *target_value = EPSILON_MIN_VALUE; + } else { + *target_value -= delta; + } + } + +} + +static void dump_epsilons(void) +{ + uint32_t i; + + for (i = 0; i < NUM_EPSILON_READ_TIERS; i++) + { + printk(BIOS_DEBUG, " R_T[%d] = %d\n", i, eps_r[i]); + } + + for (i = 0; i < NUM_EPSILON_WRITE_TIERS; i++) + { + printk(BIOS_DEBUG, " W_T[%d] = %d\n", i, eps_w[i]); + } +} + +static int p9_calculate_epsilons(uint8_t *floor_ratio, uint8_t *ceiling_ratio, + uint32_t *fbc_freq, uint32_t *freq_ceiling) +{ + uint8_t eps_table_type = EPS_TYPE_LE; /* ATTR_PROC_EPS_TABLE_TYPE from talos.xml */ + uint32_t i; + + /* Processor SMP Fabric broadcast scope configuration. + * CHIP_IS_NODE = MODE1 = default + * CHIP_IS_GROUP = MODE2 + */ + uint8_t pump_mode = CHIP_IS_GROUP; /* ATTR_PROC_FABRIC_PUMP_MODE MODE2 from talos.xml */ + + switch(eps_table_type) + { + case EPS_TYPE_HE: + if (pump_mode == CHIP_IS_NODE) { + eps_r[0] = EPSILON_R_T0_HE[*floor_ratio]; + eps_r[1] = EPSILON_R_T1_HE[*floor_ratio]; + eps_r[2] = EPSILON_R_T2_HE[*floor_ratio]; + + eps_w[0] = EPSILON_W_T0_HE[*floor_ratio]; + eps_w[1] = EPSILON_W_T1_HE[*floor_ratio]; + } else { + eps_r[0] = EPSILON_R_T0_F4[*floor_ratio]; + eps_r[1] = EPSILON_R_T1_F4[*floor_ratio]; + eps_r[2] = EPSILON_R_T2_F4[*floor_ratio]; + + eps_w[0] = EPSILON_W_T0_F4[*floor_ratio]; + eps_w[1] = EPSILON_W_T1_F4[*floor_ratio]; + } + + break; + case EPS_TYPE_HE_F8: + eps_r[0] = EPSILON_R_T0_F8[*floor_ratio]; + + if (pump_mode == CHIP_IS_NODE) + eps_r[1] = EPSILON_R_T1_F8[*floor_ratio]; + else + eps_r[1] = EPSILON_R_T0_F8[*floor_ratio]; + + eps_r[2] = EPSILON_R_T2_F8[*floor_ratio]; + + eps_w[0] = EPSILON_W_T0_F8[*floor_ratio]; + eps_w[1] = EPSILON_W_T1_F8[*floor_ratio]; + break; + case EPS_TYPE_LE: + eps_r[0] = EPSILON_R_T0_LE[*floor_ratio]; + + if (pump_mode == CHIP_IS_NODE) + eps_r[1] = EPSILON_R_T1_LE[*floor_ratio]; + else + eps_r[1] = EPSILON_R_T0_LE[*floor_ratio]; + + eps_r[2] = EPSILON_R_T2_LE[*floor_ratio]; + + eps_w[0] = EPSILON_W_T0_LE[*floor_ratio]; + eps_w[1] = EPSILON_W_T1_LE[*floor_ratio]; + break; + default: + printk(BIOS_WARNING, "Invalid epsilon table type 0x%.8X", eps_table_type); + break; + } + + /* dump base epsilon values */ + printk(BIOS_DEBUG, "Base epsilon values read from table:\n"); + dump_eplisons(); + + eps_guardband = 20; + + /* scale base epsilon values if core is running 2x nest frequency */ + if (*ceiling_ratio == FABRIC_CORE_CEILING_RATIO_RATIO_8_8) + { + printk(BIOS_DEBUG, "Scaling based on ceiling frequency"); + uint8_t scale_percentage = 100 * (*freq_ceiling) / (2 * (*fbc_freq)); + scale_percentage -= 100; + + /* scale/apply guardband read epsilons */ + for (i = 0; i < NUM_EPSILON_READ_TIERS; i++) + config_guardband_epsilon(scale_percentage, &eps_r[i]); + + /* Scale write epsilons */ + for (i = 0; i < NUM_EPSILON_WRITE_TIERS; i++) + config_guardband_epsilon(scale_percentage, &eps_w[i]); + } + + printk(BIOS_DEBUG, "Scaled epsilon values based on %s%d percent guardband:\n", + (eps_guardband >= 0) ? ("+") : ("-"), eps_guardband); + dump_eplisons(); + + /* + * check relationship of epsilon counters: + * read tier values are strictly increasing + * write tier values are strictly increaing + */ + if ((eps_r[0] > eps_r[1]) || (eps_r[1] > eps_r[2]) || (eps_w[0] > eps_w[1])) + printk(BIOS_WARNING, "Invalid relationship between base epsilon values\n"); +} + +void configure_powerbus_link (void) +{ + + if (!p9_calculate_frequencies(&core_floor_ratio, &core_ceiling_ratio, + &freq_fbc, &freq_core_ceiling)) { + die("Incorrect core or PowerBus frequency"); + } + + p9_calculate_epsilons(&core_floor_ratio, &core_ceiling_ratio, + &freq_fbc, &freq_core_ceiling); + + /* Do we need to create variables for the fabric link activity and + disable them as in p9_fbc_eff_config_reset_attrs? */ +} diff --git a/src/soc/ibm/power9/istep_8_7.c b/src/soc/ibm/power9/istep_8_7.c new file mode 100644 index 00000000000..ca17dcf9010 --- /dev/null +++ b/src/soc/ibm/power9/istep_8_7.c @@ -0,0 +1,298 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +static int p9_query_config_links(const uint8_t *i_target, + uint8_t *o_link_is_enabled) +{ + + switch(*i_target) + { + case TARGET_TYPE_XBUS: + ATTR_LINK_TRAIN_TARGET_TYPE_XBUS l_link_train; + if (l_link_train == ENUM_ATTR_LINK_TRAIN_BOTH) + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_TRUE; + } + else if (l_link_train == ENUM_ATTR_LINK_TRAIN_EVEN_ONLY) + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_EVEN_ONLY; + } + else if (l_link_train == ENUM_ATTR_LINK_TRAIN_ODD_ONLY) + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_ODD_ONLY; + } + else + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_FALSE; + return -1; + } + break; + case TARGET_TYPE_OBUS: + ATTR_OPTICS_CONFIG_MODE_TARGET_TYPE_OBUS l_link_config_mode; + if (l_link_config_mode != ENUM_ATTR_OPTICS_CONFIG_MODE_SMP) + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_FALSE; + } + else + { + ATTR_LINK_TRAIN_TARGET_TYPE_OBUS l_link_train; + if (l_link_train = ENUM_ATTR_LINK_TRAIN_BOTH) + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_TRUE; + } + else if (l_link_train == ENUM_ATTR_LINK_TRAIN_EVEN_ONLY) + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_EVEN_ONLY; + } + else if (l_link_train == ENUM_ATTR_LINK_TRAIN_ODD_ONLY) + { + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNFG_ODD_ONLY; + } + else + { + + *o_link_is_enabled = ENUM_ATTR_PROC_FABRIC_X_ATTACHED_CHIP_CNG_FALSE; + return -1; + } + } + break; + default: + printk(BIOS_WARNING, "Invalid Endpoint target type"); + break; + } + return 0; + +} + +static int p9_cfg_links_set_link_active_attr(const uint64_t* i_target, + const bool i_enable) +{ + if (*i_target == TARGET_TYPE_XBUS || *i_target == TARGET_TYPE_OBUS) + { + uint8_t l_active = (i_enable) ? + ENUM_ATTR_PROC_FABRIC_LINK_ACTIVE_TRUE: + ENUM_ATTR_PROC_FABRIC_LINK_ACTIVE_FALSE; + } + else + { + printk (BIOS_ERR, "Invalid Target Type"); + return -1; + } + + return 0; +} + +static int p9_config_links_map_endp(const uint64_t* i_target, + const p9_fbc_link_ctl_t* i_link_ctl_arr, + const uint8_t i_link_ctl_arr_size, + uint8_t* o_link_id) +{ + uint8_t l_loc_unit_id; + bool l_found = false; + + l_loc_unit_id = *i_target; + + for (uint8_t l_link_id = 0; (l_link_id < i_link_ctl_arr_size) && !l_found; l_link_id++) + { + if ((((i_link_ctl_arr + l_link_id)->endp_type == ELECTRICAL ) || ((i_link_ctl_arr + l_link_id)->endp_type == OPTICAL )) && + ((i_link_ctl_arr + l_link_id)->endp_unit_id == l_loc_unit_id)) + { + o_link_id = l_link_id; + l_found = true; + } + } + return 0; +} + +static int p9_config_links_query_endp(const uint64_t* i_loc_target, + const uint8_t i_loc_fbc_chip_id, + const uint8_t i_loc_fbc_group_id, + const p9_fbc_link_ctl_t i_link_ctl_arr*, + const uint8_t i_link_ctl_arr_size, + bool i_rem_fbc_id_is_chip, + uint8_t o_loc_link_en*, + uint8_t o_rem_link_id*, + uint8_t o_rem_fbc_id*) +{ + + uint8_t l_loc_link_id = 0; + // l_rem_target; + p9_config_links_map_endp(i_loc_target, + i_link_ctl_arr, + i_link_ctl_arr_size, + l_loc_link_id); + + p9_config_links_query_link_en(i_loc_target, o_lock_link_en + l_lock_link_id); + + if (o_loc_link_en[l_loc_link_id]) + { + // + // + if(//) + { + + o_loc_link_en[l_loc_link_id] = 0; + } + else + { + p9_fbc_eff_config_links_query_link_en(l_rem_target, + o_loc_link_en + l_loc_link_id); + } + } + + if (o_loc_link_en[l_loc_link_id]) + { + uint8_t l_rem_fbc_group_id; + uint8_t l_rem_fbc_chip_id; + + p9_fbc_eff_config_links_map_endp(l_rem_target, + i_link_ctl_arr, + i_link_ctl_arr_size, + o_rem_link_id + l_loc_link_id); + + if (i_rem_fbc_id_is_chip) + { + // + o_rem_fbc_id[l_loc_link_id] = l_rem_fbc_chip_id; + } + else + { + o_rem_fbc_id[l_loc_link_id] = l_rem_fbc_group_id; + } + } + + p9_fbc_eff_config_links_set_link_active_attr(i_loc_target, + o_loc_link_en + l_loc_link_id); + return 0; +} + + +static int p9_fbc_eff_config_links(const uint64_t* i_target, + p9_build_smp_operation i_op, + bool i_process_electrical, + bool i_process_optical) + +{ + + uint8_t l_loc_fbc_chip_id; + uint8_t l_loc_fbc_group_id; + + uint8_t l_x_en[P9_FBC_UTILS_MAX_X_LINKS] = { 0 }; + uint8_t l_x_num = 0; + uint8_t l_a_en[P9_FBC_UTILS_MAX_A_LINKS] = { 0 }; + uint8_t l_a_num = 0; + + uint8_t l_x_rem_link_id[P9_FBC_UTILS_MAX_X_LINKS] = { 0 }; + uint8_t l_x_rem_fbc_chip_id[P9_FBC_UTILS_MAX_X_LINKS] = { 0 }; + uint8_t l_a_rem_link_id[P9_FBC_UTILS_MAX_A_LINKS] = { 0 }; + uint8_t l_a_rem_fbc_group_id[P9_FBC_UTILS_MAX_A_LINKS] = { 0 }; + + if (i_op == SMP_ACTIVATE_PHASE2) + { + // + // + } + + p9_fbc_utils_get_chip_id_attr(i_target, l_loc_fbc_chip_id); + p9_fbc_utils_get_group_id_attr(i_target, l_loc_fbc_group_id); + // + + if (i_process_electrical) + { + + // + for( ; ; ) // + { + p9_fbc_eff_config_links_query_endp(*l_iter, + l_loc_fbc_chip_id, + l_loc_fbc_group_id, + P9_FBC_XBUS_LINK_CTL_ARR, + P9_FBC_UTILS_MAX_X_LINKS, + (l_pump_mode == ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_NODE), + l_x_en, + l_x_rem_link_id, + l_x_rem_fbc_chip_id); + + } + + + } + + if (i_process_optical) + { + // + for( ; ; ) + { + if (l_smp_optics_mode == ENUM_ATTR_PROC_FABRIC_SMP_OPTICS_MODE_OPTICS_IS_X_BUS) + { + p9_fbc_eff_config_links_query_endp(*l_iter, + l_loc_fbc_chip_id, + l_loc_fbc_group_id, + P9_FBC_XBUS_LINK_CTL_ARR, + P9_FBC_UTILS_MAX_X_LINKS, + (l_pump_mode == ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_NODE), + l_x_en, + l_x_rem_link_id, + l_x_rem_fbc_chip_id); + } + else + { + p9_fbc_eff_config_links_query_endp(*l_iter, + l_loc_fbc_chip_id, + l_loc_fbc_group_id, + P9_FBC_ABUS_LINK_CTL_ARR, + P9_FBC_UTILS_MAX_A_LINKS, + false, + l_a_en, + l_a_rem_link_id, + l_a_rem_fbc_group_id); + } + } + + } + + l_x_num = 0; + l_a_num = 0; + + for (uint8_t l_link_id = 0; l_link_id < P9_FBC_UTILS_MAX_X_LINKS; l_link_id++) + { + if (l_x_en[l_link_id]) + { + l_x_num++; + } + + } + + for (uint8_t l_link_id = 0; l_link_id < P9_FBC_UTILS_MAX_A_LINKS; l_link_id++) + { + if (l_a_en[l_link_id]) + { + l_a_num++; + } + + } + + if (i_op == SMP_ACTIVATE_PHASE1) + { + uint32_t l_x_agg_link_delay[P9_FBC_UTILS_MAX_X_LINKS]; + uint32_t l_a_agg_link_delay[P9_FBC_UTILS_MAX_A_LINKS]; + + for (uint8_t i = 0; i < P9_FBC_UTILS_MAX_X_LINKS; i++) + { + l_x_agg_link_delay[i] = 0xFFFFFFFF; + } + for (uint8_t i = 0; i < P9_FBC_UTILS_MAX_A_LINKS; i++) + { + l_a_agg_link_delay[i] = 0xFFFFFFFF; + } + + uint8_t l_x_addr_dis[P9_FBC_UTILS_MAX_X_LINKS] = { 0 }; + uint8_t l_x_aggregate = 0; + uint8_t l_a_addr_dis[P9_FBC_UTILS_MAX_A_LINKS] = { 0 }; + uint8_t l_a_aggregate = 0; + + +} diff --git a/src/soc/ibm/power9/romstage.c b/src/soc/ibm/power9/romstage.c index 91074b20125..2431869c811 100644 --- a/src/soc/ibm/power9/romstage.c +++ b/src/soc/ibm/power9/romstage.c @@ -4,4 +4,5 @@ asmlinkage void car_stage_entry(void) { + }