/* * This file is part of the coreboot project. * * Copyright 2015 Google Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include #include #include #include #include #define KBLY_ICCMAX_SA VR_CFG_AMP(4.1) #define KBLY_ICCMAX_CORE VR_CFG_AMP(24) #define AMLY_ICCMAX_CORE VR_CFG_AMP(28) #define KBLY_ICCMAX_GTS_GTUS VR_CFG_AMP(24) #define KBLR_ICCMAX_SA_U42 VR_CFG_AMP(6) #define KBLU_ICCMAX_SA_U22 VR_CFG_AMP(4.5) #define KBLR_ICCMAX_CORE_U42 VR_CFG_AMP(64) #define KBLU_ICCMAX_CORE_U22_PREMIUM VR_CFG_AMP(32) #define KBLU_ICCMAX_CORE_U22_BASE VR_CFG_AMP(29) #define KBLUR_ICCMAX_GTS_GTUS VR_CFG_AMP(31) enum kbl_sku { KBL_Y_SKU, KBL_R_SKU, KBL_U_BASE_SKU, KBL_U_PREMIUM_SKU, AML_Y_SKU, }; /* * Iccmax table from Doc #559100 Section 7.2 DC Specifications, the * Iccmax is the same among KBL-Y but KBL-U/R. * Addendum for AML-Y #594883, IccMax for IA core is 28A. * +----------------+-------------+---------------+------+-----+ * | Domain/Setting | SA | IA | GTUS | GTS | * +----------------+-------------+---------------+------+-----+ * | IccMax(KBL-U/R)| 6A(U42) | 64A(U42) | 31A | 31A | * | | 4.5A(Others)| 29A(P/C) | | | * | | | 32A(i3/i5) | | | * +----------------+-------------+---------------+------+-----+ * | IccMax(KBL-Y) | 4.1A | 24A | 24A | 24A | * +----------------+-------------+---------------+------+-----+ * | IccMax(AML-Y) | 4.1A | 28A | 24A | 24A | * +----------------+-------------+---------------+------+-----+ */ static const struct { uint16_t icc_max[NUM_VR_DOMAINS]; }sku_icc_max_mapping[] = { [KBL_Y_SKU] = { .icc_max = { KBLY_ICCMAX_SA, KBLY_ICCMAX_CORE, KBLY_ICCMAX_GTS_GTUS, KBLY_ICCMAX_GTS_GTUS } }, [KBL_R_SKU] = { .icc_max = { KBLR_ICCMAX_SA_U42, KBLR_ICCMAX_CORE_U42, KBLUR_ICCMAX_GTS_GTUS, KBLUR_ICCMAX_GTS_GTUS } }, [KBL_U_BASE_SKU] = { .icc_max = { KBLU_ICCMAX_SA_U22, KBLU_ICCMAX_CORE_U22_BASE, KBLUR_ICCMAX_GTS_GTUS, KBLUR_ICCMAX_GTS_GTUS } }, [KBL_U_PREMIUM_SKU] = { .icc_max = { KBLU_ICCMAX_SA_U22, KBLU_ICCMAX_CORE_U22_PREMIUM, KBLUR_ICCMAX_GTS_GTUS, KBLUR_ICCMAX_GTS_GTUS } }, [AML_Y_SKU] = { .icc_max = { KBLY_ICCMAX_SA, AMLY_ICCMAX_CORE, KBLY_ICCMAX_GTS_GTUS, KBLY_ICCMAX_GTS_GTUS } }, }; /* Default values for domain configuration. PSI3 and PSI4 are disabled. */ static const struct vr_config default_configs[NUM_VR_DOMAINS] = { [VR_SYSTEM_AGENT] = { .vr_config_enable = 1, .psi1threshold = VR_CFG_AMP(20), .psi2threshold = VR_CFG_AMP(4), .psi3threshold = VR_CFG_AMP(1), .psi3enable = 0, .psi4enable = 0, .imon_slope = 0x0, .imon_offset = 0x0, .icc_max = VR_CFG_AMP(7), .voltage_limit = 1520, }, [VR_IA_CORE] = { .vr_config_enable = 1, .psi1threshold = VR_CFG_AMP(20), .psi2threshold = VR_CFG_AMP(5), .psi3threshold = VR_CFG_AMP(1), .psi3enable = 0, .psi4enable = 0, .imon_slope = 0x0, .imon_offset = 0x0, .icc_max = VR_CFG_AMP(34), .voltage_limit = 1520, }, #if CONFIG(PLATFORM_USES_FSP1_1) [VR_RING] = { .vr_config_enable = 1, .psi1threshold = VR_CFG_AMP(20), .psi2threshold = VR_CFG_AMP(5), .psi3threshold = VR_CFG_AMP(1), .psi3enable = 0, .psi4enable = 0, .imon_slope = 0x0, .imon_offset = 0x0, .icc_max = VR_CFG_AMP(34), .voltage_limit = 1520, }, #endif [VR_GT_UNSLICED] = { .vr_config_enable = 1, .psi1threshold = VR_CFG_AMP(20), .psi2threshold = VR_CFG_AMP(5), .psi3threshold = VR_CFG_AMP(1), .psi3enable = 0, .psi4enable = 0, .imon_slope = 0x0, .imon_offset = 0x0, .icc_max = VR_CFG_AMP(35), .voltage_limit = 1520, }, [VR_GT_SLICED] = { .vr_config_enable = 1, .psi1threshold = VR_CFG_AMP(20), .psi2threshold = VR_CFG_AMP(5), .psi3threshold = VR_CFG_AMP(1), .psi3enable = 0, .psi4enable = 0, .imon_slope = 0x0, .imon_offset = 0x0, .icc_max = VR_CFG_AMP(35), .voltage_limit = 1520, }, }; static uint16_t get_dev_id(struct device *dev) { return pci_read_config16(dev, PCI_DEVICE_ID); } static int get_kbl_sku(void) { struct device *sa_dev = pcidev_path_on_root(SA_DEVFN_ROOT); static int sku = -1; uint16_t id; if (sku != -1) return sku; id = get_dev_id(sa_dev); if (id == PCI_DEVICE_ID_INTEL_KBL_U_R) sku = KBL_R_SKU; else if (id == PCI_DEVICE_ID_INTEL_KBL_ID_Y) { struct device *igd_dev = pcidev_path_on_root(SA_DEVFN_IGD); id = get_dev_id(igd_dev); if (id == PCI_DEVICE_ID_INTEL_AML_GT2_ULX) sku = AML_Y_SKU; else sku = KBL_Y_SKU; } else if (id == PCI_DEVICE_ID_INTEL_KBL_ID_U) { id = get_dev_id(PCH_DEV_LPC); if (id == PCI_DEVICE_ID_INTEL_SPT_LP_U_BASE_HDCP22) sku = KBL_U_BASE_SKU; else sku = KBL_U_PREMIUM_SKU; } else /* Not one of the skus with available Icc max mapping. */ sku = -2; return sku; } static uint16_t get_sku_icc_max(int domain, uint16_t board_icc_max) { /* If board provided non-zero value, use it. */ if (board_icc_max) return board_icc_max; /* Check if this SKU has a mapping table entry. */ int sku_id = get_kbl_sku(); if (sku_id < 0) return 0; return sku_icc_max_mapping[sku_id].icc_max[domain]; } void fill_vr_domain_config(void *params, int domain, const struct vr_config *chip_cfg) { FSP_SIL_UPD *vr_params = (FSP_SIL_UPD *)params; const struct vr_config *cfg; if (domain < 0 || domain >= NUM_VR_DOMAINS) return; /* Use device tree override if requested. */ if (chip_cfg->vr_config_enable) cfg = chip_cfg; else cfg = &default_configs[domain]; vr_params->VrConfigEnable[domain] = cfg->vr_config_enable; vr_params->Psi1Threshold[domain] = cfg->psi1threshold; vr_params->Psi2Threshold[domain] = cfg->psi2threshold; vr_params->Psi3Threshold[domain] = cfg->psi3threshold; vr_params->Psi3Enable[domain] = cfg->psi3enable; vr_params->Psi4Enable[domain] = cfg->psi4enable; vr_params->ImonSlope[domain] = cfg->imon_slope; vr_params->ImonOffset[domain] = cfg->imon_offset; vr_params->IccMax[domain] = get_sku_icc_max(domain, cfg->icc_max); vr_params->VrVoltageLimit[domain] = cfg->voltage_limit; #if CONFIG(PLATFORM_USES_FSP2_0) vr_params->AcLoadline[domain] = cfg->ac_loadline; vr_params->DcLoadline[domain] = cfg->dc_loadline; #endif }